From 26a94b5244503b46539d4dd5ee632a289974388a Mon Sep 17 00:00:00 2001 From: Mikayla Maki Date: Thu, 27 Jul 2023 10:47:45 -0700 Subject: [PATCH] WIP: Channel CRUD --- .../20221109000000_test_schema.sql | 6 +- crates/collab/src/db.rs | 265 ++++++++++-------- crates/collab/src/db/channel.rs | 1 + crates/collab/src/tests.rs | 1 + 4 files changed, 154 insertions(+), 119 deletions(-) diff --git a/crates/collab/migrations.sqlite/20221109000000_test_schema.sql b/crates/collab/migrations.sqlite/20221109000000_test_schema.sql index a446f6b44025da5d3dda67cdf9c94ca5bb092697..ed7459e4a03ca1a9a3f38ee70b8d31b69fa8fc1d 100644 --- a/crates/collab/migrations.sqlite/20221109000000_test_schema.sql +++ b/crates/collab/migrations.sqlite/20221109000000_test_schema.sql @@ -191,13 +191,13 @@ CREATE TABLE "channels" ( "name" VARCHAR NOT NULL, "room_id" INTEGER REFERENCES rooms (id) ON DELETE SET NULL, "created_at" TIMESTAMP NOT NULL DEFAULT now -) +); CREATE TABLE "channel_parents" ( "child_id" INTEGER NOT NULL REFERENCES channels (id) ON DELETE CASCADE, "parent_id" INTEGER NOT NULL REFERENCES channels (id) ON DELETE CASCADE, PRIMARY KEY(child_id, parent_id) -) +); -- CREATE UNIQUE INDEX "index_channels_on_id_path" ON "channels" ("id_path"); @@ -207,6 +207,6 @@ CREATE TABLE "channel_members" ( "user_id" INTEGER NOT NULL REFERENCES users (id) ON DELETE CASCADE, "admin" BOOLEAN NOT NULL DEFAULT false, "updated_at" TIMESTAMP NOT NULL DEFAULT now -) +); CREATE UNIQUE INDEX "index_channel_members_on_channel_id_and_user_id" ON "channel_members" ("channel_id", "user_id"); diff --git a/crates/collab/src/db.rs b/crates/collab/src/db.rs index ca7227917ca0e4efdc526b3d07cd918a8766cde4..c8bec8a3f9dd61e9d4ade7c588158e28b81b8de5 100644 --- a/crates/collab/src/db.rs +++ b/crates/collab/src/db.rs @@ -1,7 +1,7 @@ mod access_token; mod channel; mod channel_member; -mod channel_parent; +// mod channel_parent; mod contact; mod follower; mod language_server; @@ -3032,134 +3032,167 @@ impl Database { // channels - pub async fn get_channels(&self, user_id: UserId) -> Result> { - self.transaction(|tx| async move { + pub async fn create_channel(&self, name: &str) -> Result { + self.transaction(move |tx| async move { let tx = tx; - let user = user::Model { - id: user_id, + let channel = channel::ActiveModel { + name: ActiveValue::Set(name.to_string()), ..Default::default() }; - let mut channel_ids = user - .find_related(channel_member::Entity) - .select_only() - .column(channel_member::Column::ChannelId) - .all(&*tx) - .await; - - let descendants = Alias::new("descendants"); - let cte_referencing = SelectStatement::new() - .column(channel_parent::Column::ChildId) - .from(channel::Entity) - .and_where( - Expr::col(channel_parent::Column::ParentId) - .in_subquery(SelectStatement::new().from(descendants).take()) - ); - - /* - WITH RECURSIVE descendant_ids(id) AS ( - $1 - UNION ALL - SELECT child_id as id FROM channel_parents WHERE parent_id IN descendants - ) - SELECT * from channels where id in descendant_ids - */ - - // WITH RECURSIVE descendants(id) AS ( - // // SQL QUERY FOR SELECTING Initial IDs - // UNION - // SELECT id FROM ancestors WHERE p.parent = id - // ) - // SELECT * FROM descendants; + let channel = channel.insert(&*tx).await?; + Ok(channel.id) + }).await + } + pub async fn add_channel_member(&self, channel_id: ChannelId, user_id: UserId) -> Result<()> { + self.transaction(move |tx| async move { + let tx = tx; - // let descendant_channel_ids = - - - - // let query = sea_query::Query::with().recursive(true); - - - for id_path in id_paths { - // - } - - - // zed/public/plugins - // zed/public/plugins/js - // zed/zed-livekit - // livekit/zed-livekit - // zed - 101 - // livekit - 500 - // zed-livekit - 510 - // public - 150 - // plugins - 200 - // js - 300 - // - // Channel, Parent - edges - // 510 - 500 - // 510 - 101 - // - // Given the channel 'Zed' (101) - // Select * from EDGES where parent = 101 => 510 - // - - - "SELECT * from channels where id_path like '$1?'" - - // https://www.postgresql.org/docs/current/queries-with.html - // https://www.sqlite.org/lang_with.html - - "SELECT channel_id from channel_ancestors where ancestor_id IN $()" - - // | channel_id | ancestor_ids | - // 150 150 - // 150 101 - // 200 101 - // 300 101 - // 200 150 - // 300 150 - // 300 200 - // - // // | channel_id | ancestor_ids | - // 150 101 - // 200 101 - // 300 101 - // 200 150 - // 300 [150, 200] - - channel::Entity::find() - .filter(channel::Column::IdPath.like(id_paths.unwrap())) - - dbg!(&id_paths.unwrap()[0].id_path); + let channel_membership = channel_member::ActiveModel { + channel_id: ActiveValue::Set(channel_id), + user_id: ActiveValue::Set(user_id), + ..Default::default() + }; - // let mut channel_members_by_channel_id = HashMap::new(); - // for channel_member in channel_members { - // channel_members_by_channel_id - // .entry(channel_member.channel_id) - // .or_insert_with(Vec::new) - // .push(channel_member); - // } + channel_membership.insert(&*tx).await?; - // let mut channel_messages = channel_message::Entity::find() - // .filter(channel_message::Column::ChannelId.in_selection(channel_ids)) - // .all(&*tx) - // .await?; + Ok(()) + }).await + } - // let mut channel_messages_by_channel_id = HashMap::new(); - // for channel_message in channel_messages { - // channel_messages_by_channel_id - // .entry(channel_message.channel_id) - // .or_insert_with(Vec::new) - // .push(channel_message); - // } + pub async fn get_channels(&self, user_id: UserId) -> Vec { + self.transaction(|tx| async move { + let tx = tx; - todo!(); - // Ok(channels) }) - .await + // let user = user::Model { + // id: user_id, + // ..Default::default() + // }; + // let mut channel_ids = user + // .find_related(channel_member::Entity) + // .select_only() + // .column(channel_member::Column::ChannelId) + // .all(&*tx) + // .await; + + // // let descendants = Alias::new("descendants"); + // // let cte_referencing = SelectStatement::new() + // // .column(channel_parent::Column::ChildId) + // // .from(channel::Entity) + // // .and_where( + // // Expr::col(channel_parent::Column::ParentId) + // // .in_subquery(SelectStatement::new().from(descendants).take()) + // // ); + + // // /* + // // WITH RECURSIVE descendant_ids(id) AS ( + // // $1 + // // UNION ALL + // // SELECT child_id as id FROM channel_parents WHERE parent_id IN descendants + // // ) + // // SELECT * from channels where id in descendant_ids + // // */ + + + // // // WITH RECURSIVE descendants(id) AS ( + // // // // SQL QUERY FOR SELECTING Initial IDs + // // // UNION + // // // SELECT id FROM ancestors WHERE p.parent = id + // // // ) + // // // SELECT * FROM descendants; + + + + // // // let descendant_channel_ids = + + + + // // // let query = sea_query::Query::with().recursive(true); + + + // // for id_path in id_paths { + // // // + // // } + + + // // // zed/public/plugins + // // // zed/public/plugins/js + // // // zed/zed-livekit + // // // livekit/zed-livekit + // // // zed - 101 + // // // livekit - 500 + // // // zed-livekit - 510 + // // // public - 150 + // // // plugins - 200 + // // // js - 300 + // // // + // // // Channel, Parent - edges + // // // 510 - 500 + // // // 510 - 101 + // // // + // // // Given the channel 'Zed' (101) + // // // Select * from EDGES where parent = 101 => 510 + // // // + + + // // "SELECT * from channels where id_path like '$1?'" + + // // // https://www.postgresql.org/docs/current/queries-with.html + // // // https://www.sqlite.org/lang_with.html + + // // "SELECT channel_id from channel_ancestors where ancestor_id IN $()" + + // // // | channel_id | ancestor_ids | + // // // 150 150 + // // // 150 101 + // // // 200 101 + // // // 300 101 + // // // 200 150 + // // // 300 150 + // // // 300 200 + // // // + // // // // | channel_id | ancestor_ids | + // // // 150 101 + // // // 200 101 + // // // 300 101 + // // // 200 150 + // // // 300 [150, 200] + + // // channel::Entity::find() + // // .filter(channel::Column::IdPath.like(id_paths.unwrap())) + + // // dbg!(&id_paths.unwrap()[0].id_path); + + // // // let mut channel_members_by_channel_id = HashMap::new(); + // // // for channel_member in channel_members { + // // // channel_members_by_channel_id + // // // .entry(channel_member.channel_id) + // // // .or_insert_with(Vec::new) + // // // .push(channel_member); + // // // } + + // // // let mut channel_messages = channel_message::Entity::find() + // // // .filter(channel_message::Column::ChannelId.in_selection(channel_ids)) + // // // .all(&*tx) + // // // .await?; + + // // // let mut channel_messages_by_channel_id = HashMap::new(); + // // // for channel_message in channel_messages { + // // // channel_messages_by_channel_id + // // // .entry(channel_message.channel_id) + // // // .or_insert_with(Vec::new) + // // // .push(channel_message); + // // // } + + // // todo!(); + // // // Ok(channels) + // Err(Error("not implemented")) + // }) + // .await } async fn transaction(&self, f: F) -> Result diff --git a/crates/collab/src/db/channel.rs b/crates/collab/src/db/channel.rs index ebf5c26ac87a3ccf9d380aa38a040a2ea6c78d9a..f8e2c3b85b944bf70f67fc32a475e878237ca19d 100644 --- a/crates/collab/src/db/channel.rs +++ b/crates/collab/src/db/channel.rs @@ -6,6 +6,7 @@ use sea_orm::entity::prelude::*; pub struct Model { #[sea_orm(primary_key)] pub id: ChannelId, + pub name: String, pub room_id: Option, // pub id_path: String, } diff --git a/crates/collab/src/tests.rs b/crates/collab/src/tests.rs index b1d0bedb2cf23c856f320aacabb8d2fb489f2e2a..2e98cd9b4d2eccdbf61dc005f87c8c27ce76d9d2 100644 --- a/crates/collab/src/tests.rs +++ b/crates/collab/src/tests.rs @@ -35,6 +35,7 @@ use workspace::Workspace; mod integration_tests; mod randomized_integration_tests; +mod channel_tests; struct TestServer { app_state: Arc,