diff --git a/Cargo.toml b/Cargo.toml index 6473565..d6cb4a3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,7 +5,7 @@ edition = "2021" [dependencies] argon2 = "0.5.3" -axum = "0.8.1" +axum = { version = "0.8.1" } axum-extra = { version = "0.10", features = ["cookie", "typed-header"] } clap = { version = "4.5.30", features = ["derive", "env"] } diesel = { version = "2.2.7", features = ["r2d2", "sqlite", "returning_clauses_for_sqlite_3_35"] } diff --git a/migrations/2025-02-24-133517_subscriptions/down.sql b/migrations/2025-02-24-133517_subscriptions/down.sql new file mode 100644 index 0000000..c0928a3 --- /dev/null +++ b/migrations/2025-02-24-133517_subscriptions/down.sql @@ -0,0 +1 @@ +drop table subscriptions; diff --git a/migrations/2025-02-24-133517_subscriptions/up.sql b/migrations/2025-02-24-133517_subscriptions/up.sql new file mode 100644 index 0000000..b70aa77 --- /dev/null +++ b/migrations/2025-02-24-133517_subscriptions/up.sql @@ -0,0 +1,9 @@ +create table subscriptions ( + id integer primary key not null, + device_id bigint not null + references devices (id) + on delete cascade, + url text not null, + + unique (device_id, url) +); diff --git a/src/db/models/mod.rs b/src/db/models/mod.rs index 538594b..5a36197 100644 --- a/src/db/models/mod.rs +++ b/src/db/models/mod.rs @@ -1,3 +1,4 @@ pub mod device; pub mod session; +pub mod subscription; pub mod user; diff --git a/src/db/models/subscription.rs b/src/db/models/subscription.rs new file mode 100644 index 0000000..ce1d6bd --- /dev/null +++ b/src/db/models/subscription.rs @@ -0,0 +1,39 @@ +use diesel::prelude::*; +use serde::{Deserialize, Serialize}; + +use crate::db::{schema::*, DbPool, DbResult}; + +#[derive(Serialize, Deserialize, Clone, Queryable, Selectable)] +#[diesel(table_name = subscriptions)] +#[diesel(check_for_backend(diesel::sqlite::Sqlite))] +pub struct Subscription { + pub id: i64, + pub device_id: i64, + pub url: String, +} + +#[derive(Deserialize, Insertable)] +#[diesel(table_name = subscriptions)] +#[diesel(check_for_backend(diesel::sqlite::Sqlite))] +pub struct NewSubscription { + pub device_id: i64, + pub url: String, +} + +impl Subscription { + pub fn for_device(pool: &DbPool, device_id: i64) -> DbResult> { + Ok(subscriptions::dsl::subscriptions + .select(subscriptions::url) + .filter(subscriptions::device_id.eq(device_id)) + .get_results(&mut pool.get()?)?) + } + + pub fn for_user(pool: &DbPool, user_id: i64) -> DbResult> { + Ok(subscriptions::table + .inner_join(devices::table) + .filter(devices::user_id.eq(user_id)) + .select(subscriptions::url) + .distinct() + .get_results(&mut pool.get()?)?) + } +} diff --git a/src/db/schema.rs b/src/db/schema.rs index 50ba51b..3f379c9 100644 --- a/src/db/schema.rs +++ b/src/db/schema.rs @@ -18,6 +18,14 @@ diesel::table! { } } +diesel::table! { + subscriptions (id) { + id -> BigInt, + device_id -> BigInt, + url -> Text, + } +} + diesel::table! { users (id) { id -> BigInt, @@ -28,9 +36,11 @@ diesel::table! { diesel::joinable!(devices -> users (user_id)); diesel::joinable!(sessions -> users (user_id)); +diesel::joinable!(subscriptions -> devices (device_id)); diesel::allow_tables_to_appear_in_same_query!( devices, sessions, + subscriptions, users, );