aboutsummaryrefslogtreecommitdiff
path: root/src/model.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/model.rs')
-rw-r--r--src/model.rs197
1 files changed, 196 insertions, 1 deletions
diff --git a/src/model.rs b/src/model.rs
index 37a855f..8f0e76f 100644
--- a/src/model.rs
+++ b/src/model.rs
@@ -347,19 +347,104 @@ impl SubscriptionQuery<'_> {
}
// TODO
+#[derive(Debug, PartialEq)]
pub struct Mail {
pub from: String,
pub recipient: Vec<String>,
pub data: String,
}
+enum MailQuery<'a> {
+ Insert(&'a Mail),
+ Next,
+ Delete(i64),
+ Count,
+}
+
+impl Query for MailQuery<'_> {
+ type T = MailResult;
+
+ fn callback(&self, tx: &rusqlite::Transaction) -> Result<QueryResult<Self::T>> {
+ match self {
+ MailQuery::Insert(mail) => self.insert_mail(tx, mail),
+ MailQuery::Next => self.get_next(tx),
+ MailQuery::Delete(id) => self.delete(tx, *id),
+ MailQuery::Count => self.count(tx),
+ }
+ }
+}
+
+impl MailQuery<'_> {
+ fn insert_mail(
+ &self,
+ tx: &rusqlite::Transaction,
+ mail: &Mail,
+ ) -> Result<QueryResult<MailResult>> {
+ let q = "INSERT INTO queue (from_, recipient, data) VALUES (?, ?, ?)";
+ tx.execute(
+ q,
+ (&mail.from, mail.recipient.join(","), mail.data.as_bytes()),
+ )?;
+ Ok(QueryResult::Empty)
+ }
+
+ fn get_next(&self, tx: &rusqlite::Transaction) -> Result<QueryResult<MailResult>> {
+ let q = "SELECT * FROM queue LIMIT 1";
+ let ris = tx
+ .prepare(q)?
+ .query(())?
+ .map(|row| {
+ let mail_data: Vec<u8> = row.get(3).unwrap();
+ let recp: String = row.get(2).unwrap();
+ let mail = Mail {
+ from: row.get(1).unwrap(),
+ recipient: recp
+ .split(',')
+ .map(|r| String::from(r))
+ .collect::<Vec<String>>(),
+ data: String::from_utf8(mail_data).unwrap(),
+ };
+ Ok(MailResult::Mail(row.get(0).unwrap(), mail))
+ })
+ .next()?;
+
+ if ris.is_some() {
+ Ok(QueryResult::Single(ris.unwrap()))
+ } else {
+ Ok(QueryResult::Empty)
+ }
+ }
+
+ fn delete(&self, tx: &rusqlite::Transaction, id: i64) -> Result<QueryResult<MailResult>> {
+ let q = "DELETE FROM queue WHERE id = ?";
+ tx.execute(q, [id])?;
+ Ok(QueryResult::Empty)
+ }
+
+ fn count(&self, tx: &rusqlite::Transaction) -> Result<QueryResult<MailResult>> {
+ let q = "SELECT COUNT(*) FROM queue";
+ let r = tx
+ .prepare(q)?
+ .query(())?
+ .map(|row| Ok(row.get(0).unwrap()))
+ .next()?
+ .unwrap();
+ Ok(QueryResult::Single(MailResult::Count(r)))
+ }
+}
+
+enum MailResult {
+ Mail(i64, Mail),
+ Count(i64),
+}
+
#[cfg(test)]
mod tests {
use anyhow::Result;
use crate::{
database::{DB_NAME, Database, QueryResult},
- model::{List, SubscriptionQuery, SubscriptionResult, User},
+ model::{List, Mail, MailQuery, SubscriptionQuery, SubscriptionResult, User},
};
fn setup() -> Result<Database> {
@@ -778,4 +863,114 @@ mod tests {
drop(database);
cleanup().expect("failed cleanup");
}
+
+ #[test]
+ fn mail_insert() {
+ let mut database = setup().expect("failed setup");
+
+ let mail = Mail {
+ from: String::from("mroik@delayed.space"),
+ recipient: vec![String::from("mroik@poul.org")],
+ data: String::from("Random data"),
+ };
+
+ database
+ .execute(MailQuery::Insert(&mail))
+ .expect("failed insert");
+
+ let c = database
+ .execute(MailQuery::Count)
+ .expect("failed count query");
+ match c {
+ QueryResult::Single(super::MailResult::Count(c)) => assert_eq!(c, 1),
+ _ => assert!(false),
+ }
+
+ drop(database);
+ cleanup().expect("failed cleanup");
+ }
+
+ #[test]
+ fn mail_get_next() {
+ let mut database = setup().expect("failed setup");
+
+ let mail = Mail {
+ from: String::from("mroik@delayed.space"),
+ recipient: vec![String::from("mroik@poul.org")],
+ data: String::from("Random data"),
+ };
+
+ database
+ .execute(MailQuery::Insert(&mail))
+ .expect("failed insert");
+
+ let c = database
+ .execute(MailQuery::Count)
+ .expect("failed count query");
+ match c {
+ QueryResult::Single(super::MailResult::Count(c)) => assert_eq!(c, 1),
+ _ => assert!(false),
+ }
+
+ match database
+ .execute(MailQuery::Next)
+ .expect("failed query get next")
+ {
+ QueryResult::Single(super::MailResult::Mail(_, m)) => assert_eq!(m, mail),
+ _ => assert!(false),
+ }
+
+ drop(database);
+ cleanup().expect("failed cleanup");
+ }
+
+ #[test]
+ fn mail_delete() {
+ let mut database = setup().expect("failed setup");
+
+ let mail = Mail {
+ from: String::from("mroik@delayed.space"),
+ recipient: vec![String::from("mroik@poul.org")],
+ data: String::from("Random data"),
+ };
+
+ database
+ .execute(MailQuery::Insert(&mail))
+ .expect("failed insert");
+
+ let mut c = database
+ .execute(MailQuery::Count)
+ .expect("failed count query");
+ match c {
+ QueryResult::Single(super::MailResult::Count(c)) => assert_eq!(c, 1),
+ _ => assert!(false),
+ }
+
+ let mut id = None;
+ match database
+ .execute(MailQuery::Next)
+ .expect("failed query get next")
+ {
+ QueryResult::Single(super::MailResult::Mail(id_, m)) => {
+ id = Some(id_);
+ assert_eq!(m, mail);
+ }
+ _ => assert!(false),
+ }
+
+ database
+ .execute(MailQuery::Delete(id.unwrap()))
+ .expect("failed delete");
+
+ c = database
+ .execute(MailQuery::Count)
+ .expect("failed count query");
+ match c {
+ QueryResult::Single(super::MailResult::Count(c)) => assert_eq!(c, 0),
+ _ => assert!(false),
+ }
+
+ drop(database);
+ cleanup().expect("failed cleanup");
+ }
}
XMR address: 854DmXNrxULU3ZFJVs4Wc8PFhbq29RhqHhY8W6cdWrtFN3qmooKyyeYPcDzZTNRxphhJ5UzASQfAdEMwSteVqymk28aLhqj