Make all tests pass again after migration to sea-orm

Antonio Scandurra created

Change summary

crates/collab/migrations/20221111092550_reconnection_support.sql |  10 
crates/collab/src/db.rs                                          | 150 +
2 files changed, 89 insertions(+), 71 deletions(-)

Detailed changes

crates/collab/migrations/20221111092550_reconnection_support.sql 🔗

@@ -10,7 +10,7 @@ ALTER TABLE "projects"
 
 CREATE TABLE "worktrees" (
     "project_id" INTEGER NOT NULL REFERENCES projects (id) ON DELETE CASCADE,
-    "id" INTEGER NOT NULL,
+    "id" INT8 NOT NULL,
     "root_name" VARCHAR NOT NULL,
     "abs_path" VARCHAR NOT NULL,
     "visible" BOOL NOT NULL,
@@ -23,7 +23,7 @@ CREATE INDEX "index_worktrees_on_project_id" ON "worktrees" ("project_id");
 CREATE TABLE "worktree_entries" (
     "project_id" INTEGER NOT NULL,
     "worktree_id" INT8 NOT NULL,
-    "id" INTEGER NOT NULL,
+    "id" INT8 NOT NULL,
     "is_dir" BOOL NOT NULL,
     "path" VARCHAR NOT NULL,
     "inode" INT8 NOT NULL,
@@ -39,9 +39,9 @@ CREATE INDEX "index_worktree_entries_on_project_id_and_worktree_id" ON "worktree
 
 CREATE TABLE "worktree_diagnostic_summaries" (
     "project_id" INTEGER NOT NULL,
-    "worktree_id" INTEGER NOT NULL,
+    "worktree_id" INT8 NOT NULL,
     "path" VARCHAR NOT NULL,
-    "language_server_id" INTEGER NOT NULL,
+    "language_server_id" INT8 NOT NULL,
     "error_count" INTEGER NOT NULL,
     "warning_count" INTEGER NOT NULL,
     PRIMARY KEY(project_id, worktree_id, path),
@@ -52,7 +52,7 @@ CREATE INDEX "index_worktree_diagnostic_summaries_on_project_id_and_worktree_id"
 
 CREATE TABLE "language_servers" (
     "project_id" INTEGER NOT NULL REFERENCES projects (id) ON DELETE CASCADE,
-    "id" INTEGER NOT NULL,
+    "id" INT8 NOT NULL,
     "name" VARCHAR NOT NULL,
     PRIMARY KEY(project_id, id)
 );

crates/collab/src/db.rs 🔗

@@ -1494,17 +1494,21 @@ impl Database {
             .insert(&tx)
             .await?;
 
-            worktree::Entity::insert_many(worktrees.iter().map(|worktree| worktree::ActiveModel {
-                id: ActiveValue::set(worktree.id as i64),
-                project_id: ActiveValue::set(project.id),
-                abs_path: ActiveValue::set(worktree.abs_path.clone()),
-                root_name: ActiveValue::set(worktree.root_name.clone()),
-                visible: ActiveValue::set(worktree.visible),
-                scan_id: ActiveValue::set(0),
-                is_complete: ActiveValue::set(false),
-            }))
-            .exec(&tx)
-            .await?;
+            if !worktrees.is_empty() {
+                worktree::Entity::insert_many(worktrees.iter().map(|worktree| {
+                    worktree::ActiveModel {
+                        id: ActiveValue::set(worktree.id as i64),
+                        project_id: ActiveValue::set(project.id),
+                        abs_path: ActiveValue::set(worktree.abs_path.clone()),
+                        root_name: ActiveValue::set(worktree.root_name.clone()),
+                        visible: ActiveValue::set(worktree.visible),
+                        scan_id: ActiveValue::set(0),
+                        is_complete: ActiveValue::set(false),
+                    }
+                }))
+                .exec(&tx)
+                .await?;
+            }
 
             project_collaborator::ActiveModel {
                 project_id: ActiveValue::set(project.id),
@@ -1564,17 +1568,27 @@ impl Database {
                 .await?
                 .ok_or_else(|| anyhow!("no such project"))?;
 
-            worktree::Entity::insert_many(worktrees.iter().map(|worktree| worktree::ActiveModel {
-                id: ActiveValue::set(worktree.id as i64),
-                project_id: ActiveValue::set(project.id),
-                abs_path: ActiveValue::set(worktree.abs_path.clone()),
-                root_name: ActiveValue::set(worktree.root_name.clone()),
-                visible: ActiveValue::set(worktree.visible),
-                scan_id: ActiveValue::set(0),
-                is_complete: ActiveValue::set(false),
-            }))
-            .exec(&tx)
-            .await?;
+            if !worktrees.is_empty() {
+                worktree::Entity::insert_many(worktrees.iter().map(|worktree| {
+                    worktree::ActiveModel {
+                        id: ActiveValue::set(worktree.id as i64),
+                        project_id: ActiveValue::set(project.id),
+                        abs_path: ActiveValue::set(worktree.abs_path.clone()),
+                        root_name: ActiveValue::set(worktree.root_name.clone()),
+                        visible: ActiveValue::set(worktree.visible),
+                        scan_id: ActiveValue::set(0),
+                        is_complete: ActiveValue::set(false),
+                    }
+                }))
+                .on_conflict(
+                    OnConflict::columns([worktree::Column::ProjectId, worktree::Column::Id])
+                        .update_column(worktree::Column::RootName)
+                        .to_owned(),
+                )
+                .exec(&tx)
+                .await?;
+            }
+
             worktree::Entity::delete_many()
                 .filter(
                     worktree::Column::ProjectId.eq(project.id).and(
@@ -1623,53 +1637,57 @@ impl Database {
             .exec(&tx)
             .await?;
 
-            worktree_entry::Entity::insert_many(update.updated_entries.iter().map(|entry| {
-                let mtime = entry.mtime.clone().unwrap_or_default();
-                worktree_entry::ActiveModel {
-                    project_id: ActiveValue::set(project_id),
-                    worktree_id: ActiveValue::set(worktree_id),
-                    id: ActiveValue::set(entry.id as i64),
-                    is_dir: ActiveValue::set(entry.is_dir),
-                    path: ActiveValue::set(entry.path.clone()),
-                    inode: ActiveValue::set(entry.inode as i64),
-                    mtime_seconds: ActiveValue::set(mtime.seconds as i64),
-                    mtime_nanos: ActiveValue::set(mtime.nanos as i32),
-                    is_symlink: ActiveValue::set(entry.is_symlink),
-                    is_ignored: ActiveValue::set(entry.is_ignored),
-                }
-            }))
-            .on_conflict(
-                OnConflict::columns([
-                    worktree_entry::Column::ProjectId,
-                    worktree_entry::Column::WorktreeId,
-                    worktree_entry::Column::Id,
-                ])
-                .update_columns([
-                    worktree_entry::Column::IsDir,
-                    worktree_entry::Column::Path,
-                    worktree_entry::Column::Inode,
-                    worktree_entry::Column::MtimeSeconds,
-                    worktree_entry::Column::MtimeNanos,
-                    worktree_entry::Column::IsSymlink,
-                    worktree_entry::Column::IsIgnored,
-                ])
-                .to_owned(),
-            )
-            .exec(&tx)
-            .await?;
-
-            worktree_entry::Entity::delete_many()
-                .filter(
-                    worktree_entry::Column::ProjectId
-                        .eq(project_id)
-                        .and(worktree_entry::Column::WorktreeId.eq(worktree_id))
-                        .and(
-                            worktree_entry::Column::Id
-                                .is_in(update.removed_entries.iter().map(|id| *id as i64)),
-                        ),
+            if !update.updated_entries.is_empty() {
+                worktree_entry::Entity::insert_many(update.updated_entries.iter().map(|entry| {
+                    let mtime = entry.mtime.clone().unwrap_or_default();
+                    worktree_entry::ActiveModel {
+                        project_id: ActiveValue::set(project_id),
+                        worktree_id: ActiveValue::set(worktree_id),
+                        id: ActiveValue::set(entry.id as i64),
+                        is_dir: ActiveValue::set(entry.is_dir),
+                        path: ActiveValue::set(entry.path.clone()),
+                        inode: ActiveValue::set(entry.inode as i64),
+                        mtime_seconds: ActiveValue::set(mtime.seconds as i64),
+                        mtime_nanos: ActiveValue::set(mtime.nanos as i32),
+                        is_symlink: ActiveValue::set(entry.is_symlink),
+                        is_ignored: ActiveValue::set(entry.is_ignored),
+                    }
+                }))
+                .on_conflict(
+                    OnConflict::columns([
+                        worktree_entry::Column::ProjectId,
+                        worktree_entry::Column::WorktreeId,
+                        worktree_entry::Column::Id,
+                    ])
+                    .update_columns([
+                        worktree_entry::Column::IsDir,
+                        worktree_entry::Column::Path,
+                        worktree_entry::Column::Inode,
+                        worktree_entry::Column::MtimeSeconds,
+                        worktree_entry::Column::MtimeNanos,
+                        worktree_entry::Column::IsSymlink,
+                        worktree_entry::Column::IsIgnored,
+                    ])
+                    .to_owned(),
                 )
                 .exec(&tx)
                 .await?;
+            }
+
+            if !update.removed_entries.is_empty() {
+                worktree_entry::Entity::delete_many()
+                    .filter(
+                        worktree_entry::Column::ProjectId
+                            .eq(project_id)
+                            .and(worktree_entry::Column::WorktreeId.eq(worktree_id))
+                            .and(
+                                worktree_entry::Column::Id
+                                    .is_in(update.removed_entries.iter().map(|id| *id as i64)),
+                            ),
+                    )
+                    .exec(&tx)
+                    .await?;
+            }
 
             let connection_ids = self.project_guest_connection_ids(project_id, &tx).await?;
             self.commit_room_transaction(room_id, tx, connection_ids)