use sqlx::{SqliteConnection, Transaction, sqlite::Sqlite}; use web_push::SubscriptionInfo; use super::Id; use crate::user::{self, User}; pub trait Provider { fn subscriptions(&mut self) -> Subscriptions; } impl Provider for Transaction<'_, Sqlite> { fn subscriptions(&mut self) -> Subscriptions { Subscriptions(self) } } pub struct Subscriptions<'t>(&'t mut SqliteConnection); impl Subscriptions<'_> { pub async fn create( &mut self, user: &User, info: &SubscriptionInfo, ) -> Result { let id = Id::generate(); sqlx::query!( r#" insert into subscription (id, user, endpoint, key_p256dh, key_auth) values ($1, $2, $3, $4, $5) "#, id, user.id, info.endpoint, info.keys.p256dh, info.keys.auth, ) .execute(&mut *self.0) .await?; Ok(id) } pub async fn all(&mut self) -> Result, sqlx::Error> { let subscriptions = sqlx::query!( r#" select id as "id: Id", user as "user: user::Id", endpoint, key_p256dh, key_auth from subscription "# ) .map(|row| Subscription { id: row.id, user: row.user, info: SubscriptionInfo::new(row.endpoint, row.key_p256dh, row.key_auth), }) .fetch_all(&mut *self.0) .await?; Ok(subscriptions) } pub async fn by_endpoint(&mut self, endpoint: &String) -> Result { let subscription = sqlx::query!( r#" select id as "id: Id", user as "user: user::Id", endpoint, key_p256dh, key_auth from subscription where endpoint = $1 "#, endpoint, ) .map(|row| Subscription { id: row.id, user: row.user, info: SubscriptionInfo::new(row.endpoint, row.key_p256dh, row.key_auth), }) .fetch_one(&mut *self.0) .await?; Ok(subscription) } pub async fn delete(&mut self, subscription: &Subscription) -> Result<(), sqlx::Error> { sqlx::query!( r#" delete from subscription where endpoint = $1 "#, subscription.info.endpoint, ) .execute(&mut *self.0) .await?; Ok(()) } } pub struct Subscription { pub id: Id, pub user: user::Id, pub info: SubscriptionInfo, }