WIP: Channel CRUD

Mikayla Maki created

Change summary

crates/collab/migrations.sqlite/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(-)

Detailed changes

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");

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<Vec<ChannelId>> {
-        self.transaction(|tx| async move {
+    pub async fn create_channel(&self, name: &str) -> Result<ChannelId> {
+        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<ChannelId> {
+        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<F, Fut, T>(&self, f: F) -> Result<T>

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<RoomId>,
     // pub id_path: String,
 }

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<AppState>,