aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/remind/database.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/remind/database.rs')
-rw-r--r--src/plugins/remind/database.rs128
1 files changed, 119 insertions, 9 deletions
diff --git a/src/plugins/remind/database.rs b/src/plugins/remind/database.rs
index c0c127e..e434ec0 100644
--- a/src/plugins/remind/database.rs
+++ b/src/plugins/remind/database.rs
@@ -1,14 +1,30 @@
-#[cfg(feature = "mysql")]
-extern crate dotenv;
-
use std::collections::HashMap;
use std::collections::hash_map::Entry;
use std::fmt;
+#[cfg(feature = "mysql")]
+use std::sync::Arc;
+
+#[cfg(feature = "mysql")]
+use diesel::mysql::MysqlConnection;
+#[cfg(feature = "mysql")]
+use diesel::prelude::*;
+#[cfg(feature = "mysql")]
+use r2d2::Pool;
+#[cfg(feature = "mysql")]
+use r2d2_diesel::ConnectionManager;
+
+#[cfg(feature = "mysql")]
+use failure::ResultExt;
+
use chrono::NaiveDateTime;
use super::error::*;
+#[cfg(feature = "mysql")]
+static LAST_ID_SQL: &'static str = "SELECT LAST_INSERT_ID()";
+
+#[cfg_attr(feature = "mysql", derive(Queryable))]
#[derive(Clone, Debug)]
pub struct Event {
pub id: i64,
@@ -16,7 +32,7 @@ pub struct Event {
pub content: String,
pub author: String,
pub time: NaiveDateTime,
- pub repeat: Option<u64>,
+ pub repeat: Option<i64>,
}
impl fmt::Display for Event {
@@ -29,18 +45,20 @@ impl fmt::Display for Event {
}
}
+#[cfg_attr(feature = "mysql", derive(Insertable))]
+#[cfg_attr(feature = "mysql", table_name = "events")]
#[derive(Debug)]
pub struct NewEvent<'a> {
pub receiver: &'a str,
pub content: &'a str,
pub author: &'a str,
pub time: &'a NaiveDateTime,
- pub repeat: Option<u64>,
+ pub repeat: Option<i64>,
}
pub trait Database: Send + Sync {
- fn insert_event(&mut self, event: &NewEvent) -> Result<(), RemindError>;
- fn update_event_time(&mut self, id: i64, &NaiveDateTime) -> Result<(), RemindError>;
+ fn insert_event(&mut self, event: &NewEvent) -> Result<i64, RemindError>;
+ fn update_event_time(&mut self, id: i64, time: &NaiveDateTime) -> Result<(), RemindError>;
fn get_events_before(&self, time: &NaiveDateTime) -> Result<Vec<Event>, RemindError>;
fn get_user_events(&self, user: &str) -> Result<Vec<Event>, RemindError>;
fn get_event(&self, id: i64) -> Result<Event, RemindError>;
@@ -49,7 +67,7 @@ pub trait Database: Send + Sync {
// HashMap
impl Database for HashMap<i64, Event> {
- fn insert_event(&mut self, event: &NewEvent) -> Result<(), RemindError> {
+ fn insert_event(&mut self, event: &NewEvent) -> Result<i64, RemindError> {
let mut id = 0;
while self.contains_key(&id) {
id += 1;
@@ -65,7 +83,7 @@ impl Database for HashMap<i64, Event> {
};
match self.insert(id, event) {
- None => Ok(()),
+ None => Ok(id),
Some(_) => Err(ErrorKind::Duplicate)?,
}
}
@@ -126,3 +144,95 @@ impl Database for HashMap<i64, Event> {
}
}
}
+
+#[cfg(feature = "mysql")]
+mod schema {
+ table! {
+ events (id) {
+ id -> Bigint,
+ receiver -> Varchar,
+ content -> Text,
+ author -> Varchar,
+ time -> Timestamp,
+ repeat -> Nullable<Bigint>,
+ }
+ }
+}
+
+#[cfg(feature = "mysql")]
+use self::schema::events;
+
+#[cfg(feature = "mysql")]
+impl Database for Arc<Pool<ConnectionManager<MysqlConnection>>> {
+ fn insert_event(&mut self, event: &NewEvent) -> Result<i64, RemindError> {
+ use diesel::{self, dsl::sql, types::Bigint};
+ let conn = &*self.get().context(ErrorKind::NoConnection)?;
+
+ diesel::insert_into(events::table)
+ .values(event)
+ .execute(conn)
+ .context(ErrorKind::MysqlError)?;
+
+ let id = sql::<Bigint>(LAST_ID_SQL)
+ .get_result(conn)
+ .context(ErrorKind::MysqlError)?;
+
+ Ok(id)
+ }
+
+ fn update_event_time(&mut self, id: i64, time: &NaiveDateTime) -> Result<(), RemindError> {
+ use self::events::columns;
+ use diesel;
+ let conn = &*self.get().context(ErrorKind::NoConnection)?;
+
+ match diesel::update(events::table.filter(columns::id.eq(id)))
+ .set(columns::time.eq(time))
+ .execute(conn)
+ {
+ Ok(0) => Err(ErrorKind::NotFound)?,
+ Ok(_) => Ok(()),
+ Err(e) => Err(e).context(ErrorKind::MysqlError)?,
+ }
+ }
+
+ fn get_events_before(&self, time: &NaiveDateTime) -> Result<Vec<Event>, RemindError> {
+ use self::events::columns;
+ let conn = &*self.get().context(ErrorKind::NoConnection)?;
+
+ Ok(events::table
+ .filter(columns::time.lt(time))
+ .load::<Event>(conn)
+ .context(ErrorKind::MysqlError)?)
+ }
+
+ fn get_user_events(&self, user: &str) -> Result<Vec<Event>, RemindError> {
+ use self::events::columns;
+ let conn = &*self.get().context(ErrorKind::NoConnection)?;
+
+ Ok(events::table
+ .filter(columns::receiver.eq(user))
+ .load::<Event>(conn)
+ .context(ErrorKind::MysqlError)?)
+ }
+
+ fn get_event(&self, id: i64) -> Result<Event, RemindError> {
+ let conn = &*self.get().context(ErrorKind::NoConnection)?;
+
+ Ok(events::table
+ .find(id)
+ .first(conn)
+ .context(ErrorKind::MysqlError)?)
+ }
+
+ fn delete_event(&mut self, id: i64) -> Result<(), RemindError> {
+ use self::events::columns;
+ use diesel;
+
+ let conn = &*self.get().context(ErrorKind::NoConnection)?;
+ match diesel::delete(events::table.filter(columns::id.eq(id))).execute(conn) {
+ Ok(0) => Err(ErrorKind::NotFound)?,
+ Ok(_) => Ok(()),
+ Err(e) => Err(e).context(ErrorKind::MysqlError)?,
+ }
+ }
+}