aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/list.rs142
1 files changed, 55 insertions, 87 deletions
diff --git a/src/list.rs b/src/list.rs
index 4222cbf..8624650 100644
--- a/src/list.rs
+++ b/src/list.rs
@@ -58,22 +58,21 @@ impl DBExecutable for UserQuery<'_> {
type T = User;
fn execute(&self, tx: &rusqlite::Transaction) -> Result<QueryResult<Self::T>> {
match self {
- UserQuery::Insert(_, _) => self.db_insert(tx),
- UserQuery::Delete(_) => self.db_delete(tx),
- UserQuery::QueryByEmail(_) => self.db_query_by_email(tx),
+ UserQuery::Insert(name, email) => self.db_insert(tx, name, email),
+ UserQuery::Delete(email) => self.db_delete(tx, email),
+ UserQuery::QueryByEmail(email) => self.db_query_by_email(tx, email),
UserQuery::QueryAll => self.db_query_all(tx),
}
}
}
impl UserQuery<'_> {
- fn db_insert(&self, tx: &rusqlite::Transaction<'_>) -> Result<QueryResult<User>> {
- let (name, email) = if let UserQuery::Insert(name, email) = self {
- (name, email)
- } else {
- unreachable!("this should only be called by a UserQuery::Insert")
- };
-
+ fn db_insert(
+ &self,
+ tx: &rusqlite::Transaction<'_>,
+ name: &Option<&str>,
+ email: &str,
+ ) -> Result<QueryResult<User>> {
if let Some(name) = name {
let q = "INSERT INTO user (name, email) VALUES (?, ?)";
tx.execute(q, [name, email])?;
@@ -85,25 +84,17 @@ impl UserQuery<'_> {
Ok(QueryResult::Empty)
}
- fn db_delete(&self, tx: &rusqlite::Transaction<'_>) -> Result<QueryResult<User>> {
- let email = if let UserQuery::Delete(email) = self {
- email
- } else {
- unreachable!("this should only be called by a UserQuery::Delete")
- };
-
+ fn db_delete(&self, tx: &rusqlite::Transaction<'_>, email: &str) -> Result<QueryResult<User>> {
let q = "DELETE FROM user WHERE email = ?";
tx.execute(q, [email])?;
Ok(QueryResult::Empty)
}
- fn db_query_by_email(&self, tx: &rusqlite::Transaction<'_>) -> Result<QueryResult<User>> {
- let email = if let UserQuery::QueryByEmail(email) = self {
- email
- } else {
- unreachable!("this should only be called by a UserQuery::QueryByEmail")
- };
-
+ fn db_query_by_email(
+ &self,
+ tx: &rusqlite::Transaction<'_>,
+ email: &str,
+ ) -> Result<QueryResult<User>> {
let q = "SELECT * FROM user WHERE email LIKE ?";
let mut stmt = tx.prepare(q)?;
let ris = stmt
@@ -168,7 +159,7 @@ impl List {
enum ListQuery<'a> {
Insert(&'a str, Option<&'a str>),
Delete(&'a str),
- QueryByAddress(&'a str),
+ QueryByName(&'a str),
QueryAll,
}
@@ -177,22 +168,21 @@ impl DBExecutable for ListQuery<'_> {
fn execute(&self, tx: &rusqlite::Transaction) -> Result<QueryResult<Self::T>> {
match self {
- ListQuery::Insert(_, _) => self.db_insert(tx),
- ListQuery::Delete(_) => self.db_delete(tx),
- ListQuery::QueryByAddress(_) => self.db_query_by_address(tx),
+ ListQuery::Insert(name, desc) => self.db_insert(tx, name, desc),
+ ListQuery::Delete(name) => self.db_delete(tx, name),
+ ListQuery::QueryByName(name) => self.db_query_by_address(tx, name),
ListQuery::QueryAll => self.db_query_all(tx),
}
}
}
impl ListQuery<'_> {
- fn db_insert(&self, tx: &rusqlite::Transaction) -> Result<QueryResult<List>> {
- let (name, desc) = if let ListQuery::Insert(name, desc) = self {
- (name, desc)
- } else {
- unreachable!("this should only be called by ListQuery::Insert");
- };
-
+ fn db_insert(
+ &self,
+ tx: &rusqlite::Transaction,
+ name: &str,
+ desc: &Option<&str>,
+ ) -> Result<QueryResult<List>> {
if let Some(desc) = desc {
let q = "INSERT INTO list (name, description) VALUES (?, ?)";
tx.execute(q, [name, desc])?;
@@ -203,25 +193,17 @@ impl ListQuery<'_> {
Ok(QueryResult::Empty)
}
- fn db_delete(&self, tx: &rusqlite::Transaction) -> Result<QueryResult<List>> {
- let name = if let ListQuery::Delete(name) = self {
- name
- } else {
- unreachable!("this should only be called by ListQuery::Delete")
- };
-
+ fn db_delete(&self, tx: &rusqlite::Transaction, name: &str) -> Result<QueryResult<List>> {
let q = "DELETE FROM list WHERE name = ?";
tx.execute(q, [name])?;
Ok(QueryResult::Empty)
}
- fn db_query_by_address(&self, tx: &rusqlite::Transaction) -> Result<QueryResult<List>> {
- let name = if let ListQuery::QueryByAddress(name) = self {
- name
- } else {
- unreachable!("this should only be called by ListQuery::QueryByName")
- };
-
+ fn db_query_by_address(
+ &self,
+ tx: &rusqlite::Transaction,
+ name: &str,
+ ) -> Result<QueryResult<List>> {
let q = "SELECT * FROM list WHERE name = ?";
let mut stmt = tx.prepare(q)?;
let ris = stmt
@@ -272,23 +254,22 @@ impl DBExecutable for SubscriptionQuery<'_> {
fn execute(&self, tx: &rusqlite::Transaction) -> Result<QueryResult<Self::T>> {
match self {
- SubscriptionQuery::Insert(_, _) => self.db_insert(tx),
+ SubscriptionQuery::Insert(email, list_name) => self.db_insert(tx, email, list_name),
SubscriptionQuery::Count => self.db_query_all(tx),
- SubscriptionQuery::Delete(_, _) => self.db_delete(tx),
- SubscriptionQuery::Lists(_) => self.db_lists(tx),
- SubscriptionQuery::Subscribers(_) => self.db_subscribers(tx),
+ SubscriptionQuery::Delete(email, list_name) => self.db_delete(tx, email, list_name),
+ SubscriptionQuery::Lists(email) => self.db_lists(tx, email),
+ SubscriptionQuery::Subscribers(list_name) => self.db_subscribers(tx, list_name),
}
}
}
impl SubscriptionQuery<'_> {
- fn db_insert(&self, tx: &rusqlite::Transaction) -> Result<QueryResult<SubscriptionResult>> {
- let (email, list_name) = if let SubscriptionQuery::Insert(a, b) = self {
- (a, b)
- } else {
- unreachable!("this should only be called by SubscriptionQuery::Insert")
- };
-
+ fn db_insert(
+ &self,
+ tx: &rusqlite::Transaction,
+ email: &str,
+ list_name: &str,
+ ) -> Result<QueryResult<SubscriptionResult>> {
let q = "INSERT INTO subscription
SELECT user.id, list.id FROM user CROSS JOIN list
WHERE user.email = ? AND list.name = ?";
@@ -298,39 +279,31 @@ impl SubscriptionQuery<'_> {
}
fn db_query_all(&self, tx: &rusqlite::Transaction) -> Result<QueryResult<SubscriptionResult>> {
- match self {
- SubscriptionQuery::Count => (),
- _ => unreachable!("this should only be called by SubscriptionQuery::Count"),
- };
-
let q = "SELECT COUNT(*) FROM subscription";
let ris = tx.query_one(q, (), |row| Ok(row.get(0).unwrap()))?;
Ok(QueryResult::Single(SubscriptionResult::Count(ris)))
}
- fn db_delete(&self, tx: &rusqlite::Transaction) -> Result<QueryResult<SubscriptionResult>> {
- let (email, name) = if let SubscriptionQuery::Delete(e, n) = self {
- (e, n)
- } else {
- unreachable!("this should only be called by SubscriptionQuery::Delete")
- };
-
+ fn db_delete(
+ &self,
+ tx: &rusqlite::Transaction,
+ email: &str,
+ list_name: &str,
+ ) -> Result<QueryResult<SubscriptionResult>> {
let q = "WITH helper AS (SELECT user.id AS user_id, list.id AS list_id FROM user CROSS JOIN list
WHERE user.email = ? AND list.name = ?)
DELETE FROM subscription WHERE EXISTS (
SELECT 1 FROM helper
WHERE helper.user_id = subscription.user_id AND helper.list_id = subscription.list_id)";
- tx.execute(q, [email, name])?;
+ tx.execute(q, [email, list_name])?;
Ok(QueryResult::Empty)
}
- fn db_lists(&self, tx: &rusqlite::Transaction) -> Result<QueryResult<SubscriptionResult>> {
- let email = if let SubscriptionQuery::Lists(email) = self {
- email
- } else {
- unreachable!("this should only be called by SubscriptionQuery::Lists")
- };
-
+ fn db_lists(
+ &self,
+ tx: &rusqlite::Transaction,
+ email: &str,
+ ) -> Result<QueryResult<SubscriptionResult>> {
let q = "SELECT list.name, list.description
FROM subscription JOIN list ON list.id = subscription.list_id
JOIN user ON user.id = subscription.user_id
@@ -352,20 +325,15 @@ impl SubscriptionQuery<'_> {
fn db_subscribers(
&self,
tx: &rusqlite::Transaction,
+ list_name: &str,
) -> Result<QueryResult<SubscriptionResult>> {
- let name = if let SubscriptionQuery::Subscribers(name) = self {
- name
- } else {
- unreachable!("this should only be called by SubscriptionQuery::Subscribers")
- };
-
let q = "SELECT user.name, user.email
FROM subscription JOIN list ON list.id = subscription.list_id
JOIN user ON user.id = subscription.user_id
WHERE list.name = ?";
let ris = tx
.prepare(q)?
- .query([name])?
+ .query([list_name])?
.map(|row| {
Ok(SubscriptionResult::Subscriber(User {
name: row.get(0).unwrap(),
XMR address: 854DmXNrxULU3ZFJVs4Wc8PFhbq29RhqHhY8W6cdWrtFN3qmooKyyeYPcDzZTNRxphhJ5UzASQfAdEMwSteVqymk28aLhqj