Move to SQLite (#13)

This commit is contained in:
Natsu Kagami 2021-06-19 22:36:17 +09:00 committed by GitHub
parent 750ddb7762
commit 1799b70bc1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
50 changed files with 2122 additions and 394 deletions

View file

@ -62,11 +62,11 @@ impl MemberToChannels {
.into_iter()
.map(|(guild, channel)| {
member_cache
.query(http.clone(), u.into(), guild)
.query(http.clone(), u, guild)
.map(move |t| t.map(|_| channel))
})
.collect::<FuturesUnordered<_>>()
.filter_map(|v| ready(v))
.filter_map(ready)
.collect()
.await
}
@ -105,9 +105,10 @@ impl AnnouncerHandler {
key: &'static str,
announcer: impl Announcer + Send + Sync + 'static,
) -> &mut Self {
if let Some(_) = self
if self
.announcers
.insert(key, RwLock::new(Box::new(announcer)))
.is_some()
{
panic!(
"Announcer keys must be unique: another announcer with key `{}` was found",
@ -127,7 +128,7 @@ impl AnnouncerHandler {
.borrow()?
.get(key)
.map(|m| m.iter().map(|(a, b)| (*a, *b)).collect())
.unwrap_or_else(|| vec![]);
.unwrap_or_else(Vec::new);
Ok(data)
}
@ -149,7 +150,7 @@ impl AnnouncerHandler {
/// Start the AnnouncerHandler, looping forever.
///
/// It will run all the announcers in sequence every *cooldown* seconds.
pub async fn scan(self, cooldown: std::time::Duration) -> () {
pub async fn scan(self, cooldown: std::time::Duration) {
// First we store all the keys inside the database.
let keys = self.announcers.keys().cloned().collect::<Vec<_>>();
self.data.write().await.insert::<Self>(keys.clone());

View file

@ -11,7 +11,7 @@ mod duration {
/// Parse a single duration unit
fn parse_duration_string(s: &str) -> Result<StdDuration> {
// We reject the empty case
if s == "" {
if s.is_empty() {
return Err(Error::msg("empty strings are not valid durations"));
}
struct ParseStep {
@ -59,7 +59,7 @@ mod duration {
impl std::str::FromStr for Duration {
type Err = Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
parse_duration_string(s).map(|v| Duration(v))
parse_duration_string(s).map(Duration)
}
}

View file

@ -40,6 +40,13 @@ impl TypeMapKey for HTTPClient {
type Value = reqwest::Client;
}
/// The SQL client.
pub struct SQLClient;
impl TypeMapKey for SQLClient {
type Value = youmubot_db_sql::Pool;
}
pub mod prelude_commands {
use crate::announcer::ANNOUNCERCOMMANDS_GROUP;
use serenity::{

View file

@ -27,7 +27,7 @@ impl MemberCache {
let now = Utc::now();
// Check cache
if let Some(r) = self.0.get(&(user_id, guild_id)) {
if &r.1 > &now {
if r.1 > now {
return r.0.clone();
}
}

View file

@ -10,8 +10,8 @@ use serenity::{
use std::convert::TryFrom;
use tokio::time as tokio_time;
const ARROW_RIGHT: &'static str = "➡️";
const ARROW_LEFT: &'static str = "⬅️";
const ARROW_RIGHT: &str = "➡️";
const ARROW_LEFT: &str = "⬅️";
/// A trait that provides the implementation of a paginator.
#[async_trait::async_trait]

View file

@ -30,15 +30,15 @@ impl<T> Ratelimit<T> {
});
Self {
inner,
send,
recv,
send,
wait_time,
}
}
/// Borrow the inner `T`. You can only hol this reference `count` times in `wait_time`.
/// The clock counts from the moment the ref is dropped.
pub async fn borrow<'a>(&'a self) -> Result<impl Deref<Target = T> + 'a> {
pub async fn borrow(&self) -> Result<impl Deref<Target = T> + '_> {
self.recv.recv_async().await?;
Ok(RatelimitGuard {
inner: &self.inner,
@ -58,7 +58,7 @@ impl<'a, T> Deref for RatelimitGuard<'a, T> {
impl<'a, T> Drop for RatelimitGuard<'a, T> {
fn drop(&mut self) {
let send = self.send.clone();
let wait_time = self.wait_time.clone();
let wait_time = *self.wait_time;
tokio::spawn(async move {
tokio::time::sleep(wait_time).await;
send.send_async(()).await.ok();

View file

@ -4,14 +4,29 @@ use std::path::Path;
/// Set up the prelude libraries.
///
/// Panics on failure: Youmubot should *NOT* attempt to continue when this function fails.
pub fn setup_prelude(db_path: &Path, data: &mut TypeMap) {
pub async fn setup_prelude(
db_path: impl AsRef<Path>,
sql_path: impl AsRef<Path>,
data: &mut TypeMap,
) {
// Setup the announcer DB.
crate::announcer::AnnouncerChannels::insert_into(data, db_path.join("announcers.yaml"))
.expect("Announcers DB set up");
crate::announcer::AnnouncerChannels::insert_into(
data,
db_path.as_ref().join("announcers.yaml"),
)
.expect("Announcers DB set up");
// Set up the database
let sql_pool = youmubot_db_sql::connect(sql_path)
.await
.expect("SQL database set up");
// Set up the HTTP client.
data.insert::<crate::HTTPClient>(reqwest::Client::new());
// Set up the member cache.
data.insert::<crate::MemberCache>(std::sync::Arc::new(crate::MemberCache::default()));
// Set up the SQL client.
data.insert::<crate::SQLClient>(sql_pool);
}