diff options
| -rw-r--r-- | .sqlx/query-18f5f8a76476205ec485398a7cdbca5582dde4a67c06d2134f33efcde194dcfe.json | 20 | ||||
| -rw-r--r-- | .sqlx/query-2722ea4a4c5134c209771211a01d9a530898094b2cb7a1fa03ff2393e044cb1d.json (renamed from .sqlx/query-77cd8ff4b3617d74cba5303bbcf03ef4e3e8105580591fee89c9e26f4839c4d1.json) | 4 | ||||
| -rw-r--r-- | .sqlx/query-8be5e4fd9a27f27efc9a45de63396990a8cadb7dd6ac84cfeb7fc8770f125190.json | 26 | ||||
| -rw-r--r-- | .sqlx/query-8c78f7bbfb5522afa15c412b3d9939d4edb10e0e654e2a1b19949c3427522a08.json (renamed from .sqlx/query-0e1323c097df563e78e6758dcbc711af986a8ad2228c309c9c2d085cc23faf87.json) | 6 | ||||
| -rw-r--r-- | .sqlx/query-dbe468d2a7f64a45e70dfbd76f0c34c759006d269ccccd6299c66b672076449d.json | 26 | ||||
| -rw-r--r-- | migrations/20240911230415_no_channel_membership.sql | 1 | ||||
| -rw-r--r-- | src/channel/repo.rs | 76 | ||||
| -rw-r--r-- | src/channel/routes.rs | 43 | ||||
| -rw-r--r-- | src/index.rs | 47 |
9 files changed, 23 insertions, 226 deletions
diff --git a/.sqlx/query-18f5f8a76476205ec485398a7cdbca5582dde4a67c06d2134f33efcde194dcfe.json b/.sqlx/query-18f5f8a76476205ec485398a7cdbca5582dde4a67c06d2134f33efcde194dcfe.json deleted file mode 100644 index 1411ea6..0000000 --- a/.sqlx/query-18f5f8a76476205ec485398a7cdbca5582dde4a67c06d2134f33efcde194dcfe.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "db_name": "SQLite", - "query": "\n delete\n from channel_member\n where channel = $1\n and login = $2\n returning 1 as \"deleted: bool\"\n ", - "describe": { - "columns": [ - { - "name": "deleted: bool", - "ordinal": 0, - "type_info": "Null" - } - ], - "parameters": { - "Right": 2 - }, - "nullable": [ - null - ] - }, - "hash": "18f5f8a76476205ec485398a7cdbca5582dde4a67c06d2134f33efcde194dcfe" -} diff --git a/.sqlx/query-77cd8ff4b3617d74cba5303bbcf03ef4e3e8105580591fee89c9e26f4839c4d1.json b/.sqlx/query-2722ea4a4c5134c209771211a01d9a530898094b2cb7a1fa03ff2393e044cb1d.json index 925340d..704e480 100644 --- a/.sqlx/query-77cd8ff4b3617d74cba5303bbcf03ef4e3e8105580591fee89c9e26f4839c4d1.json +++ b/.sqlx/query-2722ea4a4c5134c209771211a01d9a530898094b2cb7a1fa03ff2393e044cb1d.json @@ -1,6 +1,6 @@ { "db_name": "SQLite", - "query": "\n insert\n into channel_member (channel, login)\n values ($1, $2)\n ", + "query": "\n insert\n into channel (id, name)\n values ($1, $2)\n ", "describe": { "columns": [], "parameters": { @@ -8,5 +8,5 @@ }, "nullable": [] }, - "hash": "77cd8ff4b3617d74cba5303bbcf03ef4e3e8105580591fee89c9e26f4839c4d1" + "hash": "2722ea4a4c5134c209771211a01d9a530898094b2cb7a1fa03ff2393e044cb1d" } diff --git a/.sqlx/query-8be5e4fd9a27f27efc9a45de63396990a8cadb7dd6ac84cfeb7fc8770f125190.json b/.sqlx/query-8be5e4fd9a27f27efc9a45de63396990a8cadb7dd6ac84cfeb7fc8770f125190.json deleted file mode 100644 index 9d75dac..0000000 --- a/.sqlx/query-8be5e4fd9a27f27efc9a45de63396990a8cadb7dd6ac84cfeb7fc8770f125190.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "db_name": "SQLite", - "query": "\n select\n channel.id as \"id: Id\",\n channel.name\n from channel\n except\n select\n channel.id as \"id: Id\",\n channel.name\n from channel\n join channel_member\n on (channel.id = channel_member.channel)\n where channel_member.login = $1\n order by channel.name\n ", - "describe": { - "columns": [ - { - "name": "id: Id", - "ordinal": 0, - "type_info": "Text" - }, - { - "name": "name", - "ordinal": 1, - "type_info": "Text" - } - ], - "parameters": { - "Right": 1 - }, - "nullable": [ - false, - false - ] - }, - "hash": "8be5e4fd9a27f27efc9a45de63396990a8cadb7dd6ac84cfeb7fc8770f125190" -} diff --git a/.sqlx/query-0e1323c097df563e78e6758dcbc711af986a8ad2228c309c9c2d085cc23faf87.json b/.sqlx/query-8c78f7bbfb5522afa15c412b3d9939d4edb10e0e654e2a1b19949c3427522a08.json index 8dcd39f..4d9051d 100644 --- a/.sqlx/query-0e1323c097df563e78e6758dcbc711af986a8ad2228c309c9c2d085cc23faf87.json +++ b/.sqlx/query-8c78f7bbfb5522afa15c412b3d9939d4edb10e0e654e2a1b19949c3427522a08.json @@ -1,6 +1,6 @@ { "db_name": "SQLite", - "query": "\n select\n channel.id as \"id: Id\",\n channel.name\n from channel\n join channel_member\n on (channel.id = channel_member.channel)\n where channel_member.login = $1\n order by channel.name\n ", + "query": "\n select\n channel.id as \"id: Id\",\n channel.name\n from channel\n order by channel.name\n ", "describe": { "columns": [ { @@ -15,12 +15,12 @@ } ], "parameters": { - "Right": 1 + "Right": 0 }, "nullable": [ false, false ] }, - "hash": "0e1323c097df563e78e6758dcbc711af986a8ad2228c309c9c2d085cc23faf87" + "hash": "8c78f7bbfb5522afa15c412b3d9939d4edb10e0e654e2a1b19949c3427522a08" } diff --git a/.sqlx/query-dbe468d2a7f64a45e70dfbd76f0c34c759006d269ccccd6299c66b672076449d.json b/.sqlx/query-dbe468d2a7f64a45e70dfbd76f0c34c759006d269ccccd6299c66b672076449d.json deleted file mode 100644 index 3db94ca..0000000 --- a/.sqlx/query-dbe468d2a7f64a45e70dfbd76f0c34c759006d269ccccd6299c66b672076449d.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "db_name": "SQLite", - "query": "\n insert\n into channel (id, name)\n values ($1, $2)\n returning id as \"id: Id\", name\n ", - "describe": { - "columns": [ - { - "name": "id: Id", - "ordinal": 0, - "type_info": "Text" - }, - { - "name": "name", - "ordinal": 1, - "type_info": "Text" - } - ], - "parameters": { - "Right": 2 - }, - "nullable": [ - false, - false - ] - }, - "hash": "dbe468d2a7f64a45e70dfbd76f0c34c759006d269ccccd6299c66b672076449d" -} diff --git a/migrations/20240911230415_no_channel_membership.sql b/migrations/20240911230415_no_channel_membership.sql new file mode 100644 index 0000000..db5a054 --- /dev/null +++ b/migrations/20240911230415_no_channel_membership.sql @@ -0,0 +1 @@ +drop table channel_member; diff --git a/src/channel/repo.rs b/src/channel/repo.rs index a255305..a04cac5 100644 --- a/src/channel/repo.rs +++ b/src/channel/repo.rs @@ -2,8 +2,8 @@ use std::fmt; use sqlx::{sqlite::Sqlite, SqliteConnection, Transaction}; +use crate::error::BoxedError; use crate::id::Id as BaseId; -use crate::{error::BoxedError, login::repo::logins::Id as LoginId}; pub trait Provider { fn channels(&mut self) -> Channels; @@ -25,65 +25,25 @@ pub struct Channel { impl<'c> Channels<'c> { /// Create a new channel. - pub async fn create(&mut self, name: &str) -> Result<Channel, BoxedError> { + pub async fn create(&mut self, name: &str) -> Result<(), BoxedError> { let id = Id::generate(); - let channel = sqlx::query_as!( - Channel, + sqlx::query!( r#" insert into channel (id, name) values ($1, $2) - returning id as "id: Id", name "#, id, name, ) - .fetch_one(&mut *self.0) - .await?; - - Ok(channel) - } - - /// Enrol a login in a channel. - pub async fn join(&mut self, channel: &Id, login: &LoginId) -> Result<(), BoxedError> { - sqlx::query!( - r#" - insert - into channel_member (channel, login) - values ($1, $2) - "#, - channel, - login, - ) .execute(&mut *self.0) .await?; Ok(()) } - pub async fn joined(&mut self, login: &LoginId) -> Result<Vec<Channel>, BoxedError> { - let channels = sqlx::query_as!( - Channel, - r#" - select - channel.id as "id: Id", - channel.name - from channel - join channel_member - on (channel.id = channel_member.channel) - where channel_member.login = $1 - order by channel.name - "#, - login, - ) - .fetch_all(&mut *self.0) - .await?; - - Ok(channels) - } - - pub async fn unjoined(&mut self, login: &LoginId) -> Result<Vec<Channel>, BoxedError> { + pub async fn all(&mut self) -> Result<Vec<Channel>, BoxedError> { let channels = sqlx::query_as!( Channel, r#" @@ -91,42 +51,14 @@ impl<'c> Channels<'c> { channel.id as "id: Id", channel.name from channel - except - select - channel.id as "id: Id", - channel.name - from channel - join channel_member - on (channel.id = channel_member.channel) - where channel_member.login = $1 order by channel.name "#, - login, ) .fetch_all(&mut *self.0) .await?; Ok(channels) } - - /// Unenrol a login from a channel. - pub async fn leave(&mut self, channel: &Id, login: &LoginId) -> Result<(), BoxedError> { - sqlx::query_scalar!( - r#" - delete - from channel_member - where channel = $1 - and login = $2 - returning 1 as "deleted: bool" - "#, - channel, - login, - ) - .fetch_one(&mut *self.0) - .await?; - - Ok(()) - } } /// Stable identifier for a [Channel]. Prefixed with `C`. diff --git a/src/channel/routes.rs b/src/channel/routes.rs index 3dc2b1a..014a57b 100644 --- a/src/channel/routes.rs +++ b/src/channel/routes.rs @@ -1,19 +1,16 @@ use axum::{ - extract::{Form, Path, State}, + extract::{Form, State}, response::{IntoResponse, Redirect}, routing::post, Router, }; use sqlx::sqlite::SqlitePool; -use super::repo::{Id as ChannelId, Provider as _}; +use super::repo::Provider as _; use crate::{error::InternalError, login::repo::logins::Login}; pub fn router() -> Router<SqlitePool> { - Router::new() - .route("/create", post(on_create)) - .route("/join", post(on_join)) - .route("/:channel/leave", post(on_leave)) + Router::new().route("/create", post(on_create)) } #[derive(serde::Deserialize)] @@ -23,41 +20,11 @@ struct CreateRequest { async fn on_create( State(db): State<SqlitePool>, - login: Login, + _: Login, // requires auth, but doesn't actually care who you are Form(form): Form<CreateRequest>, ) -> Result<impl IntoResponse, InternalError> { let mut tx = db.begin().await?; - let channel = tx.channels().create(&form.name).await?; - tx.channels().join(&channel.id, &login.id).await?; - tx.commit().await?; - - Ok(Redirect::to("/")) -} - -#[derive(serde::Deserialize)] -struct JoinRequest { - channel: ChannelId, -} - -async fn on_join( - State(db): State<SqlitePool>, - login: Login, - Form(req): Form<JoinRequest>, -) -> Result<impl IntoResponse, InternalError> { - let mut tx = db.begin().await?; - tx.channels().join(&req.channel, &login.id).await?; - tx.commit().await?; - - Ok(Redirect::to("/")) -} - -async fn on_leave( - State(db): State<SqlitePool>, - login: Login, - Path(channel): Path<ChannelId>, -) -> Result<impl IntoResponse, InternalError> { - let mut tx = db.begin().await?; - tx.channels().leave(&channel, &login.id).await?; + tx.channels().create(&form.name).await?; tx.commit().await?; Ok(Redirect::to("/")) diff --git a/src/index.rs b/src/index.rs index 9de91d5..9efd7cc 100644 --- a/src/index.rs +++ b/src/index.rs @@ -16,15 +16,10 @@ async fn index( async fn index_authenticated(db: SqlitePool, login: Login) -> Result<Markup, InternalError> { let mut tx = db.begin().await?; - let joined_channels = tx.channels().joined(&login.id).await?; - let unjoined_channels = tx.channels().unjoined(&login.id).await?; + let channels = tx.channels().all().await?; tx.commit().await?; - Ok(templates::authenticated( - login, - &joined_channels, - &unjoined_channels, - )) + Ok(templates::authenticated(login, &channels)) } pub fn router() -> Router<SqlitePool> { @@ -38,8 +33,7 @@ mod templates { pub fn authenticated<'c>( login: Login, - joined_channels: impl IntoIterator<Item = &'c Channel>, - unjoined_channels: impl IntoIterator<Item = &'c Channel>, + channels: impl IntoIterator<Item = &'c Channel>, ) -> Markup { html! { (DOCTYPE) @@ -48,8 +42,7 @@ mod templates { } body { section { - (channel_list(joined_channels)) - (join_channel(unjoined_channels)) + (channel_list(channels)) (create_channel()) } section { @@ -59,44 +52,20 @@ mod templates { } } - fn channel_list<'c>(joined_channels: impl IntoIterator<Item = &'c Channel>) -> Markup { + fn channel_list<'c>(channels: impl IntoIterator<Item = &'c Channel>) -> Markup { html! { ul { - @for channel in joined_channels { - (joined_channel_entry(&channel)) + @for channel in channels { + (channel_list_entry(&channel)) } } } } - fn joined_channel_entry(channel: &Channel) -> Markup { - let leave_url = format!("/{}/leave", channel.id); + fn channel_list_entry(channel: &Channel) -> Markup { html! { li { (channel.name) " (" (channel.id) ")" - form action=(leave_url) method="post" { - button { - "leave" - } - } - } - } - } - - fn join_channel<'c>(unjoined_channels: impl IntoIterator<Item = &'c Channel>) -> Markup { - html! { - form action="join" method="post" { - select name="channel" required { - option value="" { "channel" } - @for channel in unjoined_channels { - option value=(channel.id) { - (channel.name) " (" (channel.id) ")" - } - } - } - button { - "join" - } } } } |
