diff --git a/frontend/rust-lib/Cargo.lock b/frontend/rust-lib/Cargo.lock index 76713383b0..eb19aa47f8 100644 --- a/frontend/rust-lib/Cargo.lock +++ b/frontend/rust-lib/Cargo.lock @@ -2227,6 +2227,7 @@ dependencies = [ "collab-folder", "lib-infra", "serde", + "serde_json", "tokio", "uuid", ] diff --git a/frontend/rust-lib/flowy-core/src/deps_resolve/folder_deps.rs b/frontend/rust-lib/flowy-core/src/deps_resolve/folder_deps.rs index 9f793e9501..cd387c3b1d 100644 --- a/frontend/rust-lib/flowy-core/src/deps_resolve/folder_deps.rs +++ b/frontend/rust-lib/flowy-core/src/deps_resolve/folder_deps.rs @@ -311,6 +311,14 @@ impl FolderOperationHandler for DatabaseFolderOperation { // we should use the view_id to get the database_id let oid = self.0.get_database_id_with_view_id(view_id).await?; let row_oids = self.0.get_database_row_ids_with_view_id(view_id).await?; + let row_metas = self + .0 + .get_database_row_metas_with_view_id(view_id, row_oids.clone()) + .await?; + let row_document_ids = row_metas + .iter() + .filter_map(|meta| meta.document_id.clone()) + .collect::>(); let row_oids = row_oids .into_iter() .map(|oid| oid.into_inner()) @@ -331,49 +339,67 @@ impl FolderOperationHandler for DatabaseFolderOperation { ) })?; - let collab_read_txn = collab_db.read_txn(); + tokio::task::spawn_blocking(move || { + let collab_read_txn = collab_db.read_txn(); - // read the database collab from the db - let database_collab = load_collab_by_object_id(uid, &collab_read_txn, &oid).map_err(|e| { - FlowyError::internal().with_context(format!("load database collab failed: {}", e)) - })?; + let database_collab = load_collab_by_object_id(uid, &collab_read_txn, &oid).map_err(|e| { + FlowyError::internal().with_context(format!("load database collab failed: {}", e)) + })?; - let database_encoded_collab = database_collab - // encode the collab and check the integrity of the collab - .encode_collab_v1(|collab| CollabType::Database.validate_require_data(collab)) - .map_err(|e| { - FlowyError::internal().with_context(format!("encode database collab failed: {}", e)) - })?; - - // read the database rows collab from the db - let database_row_collabs = load_collab_by_object_ids(uid, &collab_read_txn, &row_oids); - let database_row_encoded_collabs = database_row_collabs - .into_iter() - .map(|(oid, collab)| { - // encode the collab and check the integrity of the collab - let encoded_collab = collab - .encode_collab_v1(|collab| CollabType::DatabaseRow.validate_require_data(collab)) + let database_encoded_collab = database_collab + // encode the collab and check the integrity of the collab + .encode_collab_v1(|collab| CollabType::Database.validate_require_data(collab)) .map_err(|e| { - FlowyError::internal().with_context(format!("encode database row collab failed: {}", e)) + FlowyError::internal().with_context(format!("encode database collab failed: {}", e)) })?; - Ok((oid, encoded_collab)) - }) - .collect::, FlowyError>>()?; - // get the relation info from the database meta - let database_relations = database_metas - .into_iter() - .filter_map(|meta| { - let linked_views = meta.linked_views.into_iter().next()?; - Some((meta.database_id, linked_views)) - }) - .collect::>(); + let database_row_encoded_collabs = + load_collab_by_object_ids(uid, &collab_read_txn, &row_oids) + .into_iter() + .map(|(oid, collab)| { + collab + .encode_collab_v1(|c| CollabType::DatabaseRow.validate_require_data(c)) + .map(|encoded| (oid, encoded)) + .map_err(|e| { + FlowyError::internal().with_context(format!("Database row collab error: {}", e)) + }) + }) + .collect::, FlowyError>>()?; - Ok(EncodedCollabWrapper::Database(DatabaseEncodedCollab { - database_encoded_collab, - database_row_encoded_collabs, - database_relations, - })) + let database_relations = database_metas + .into_iter() + .filter_map(|meta| { + meta + .linked_views + .clone() + .into_iter() + .next() + .map(|lv| (meta.database_id, lv)) + }) + .collect::>(); + + let database_row_document_encoded_collabs = + load_collab_by_object_ids(uid, &collab_read_txn, &row_document_ids) + .into_iter() + .map(|(oid, collab)| { + collab + .encode_collab_v1(|c| CollabType::Document.validate_require_data(c)) + .map(|encoded| (oid, encoded)) + .map_err(|e| { + FlowyError::internal() + .with_context(format!("Database row document collab error: {}", e)) + }) + }) + .collect::, FlowyError>>()?; + + Ok(EncodedCollabWrapper::Database(DatabaseEncodedCollab { + database_encoded_collab, + database_row_encoded_collabs, + database_row_document_encoded_collabs, + database_relations, + })) + }) + .await? } async fn duplicate_view(&self, view_id: &str) -> Result { diff --git a/frontend/rust-lib/flowy-database2/src/manager.rs b/frontend/rust-lib/flowy-database2/src/manager.rs index c90853a93c..d5a8143918 100644 --- a/frontend/rust-lib/flowy-database2/src/manager.rs +++ b/frontend/rust-lib/flowy-database2/src/manager.rs @@ -34,7 +34,7 @@ use lib_dispatch::prelude::af_spawn; use lib_infra::box_any::BoxAny; use lib_infra::priority_task::TaskDispatcher; -use crate::entities::{DatabaseLayoutPB, DatabaseSnapshotPB, FieldType}; +use crate::entities::{DatabaseLayoutPB, DatabaseSnapshotPB, FieldType, RowMetaPB}; use crate::services::cell::stringify_cell; use crate::services::database::DatabaseEditor; use crate::services::database_view::DatabaseLayoutDepsResolver; @@ -201,6 +201,22 @@ impl DatabaseManager { Ok(database.get_row_ids().await) } + pub async fn get_database_row_metas_with_view_id( + &self, + view_id: &str, + row_ids: Vec, + ) -> FlowyResult> { + let database = self.get_database_editor_with_view_id(view_id).await?; + let view_id = view_id.to_string(); + let mut row_metas: Vec = vec![]; + for row_id in row_ids { + if let Some(row_meta) = database.get_row_meta(&view_id, &row_id).await { + row_metas.push(row_meta); + } + } + Ok(row_metas) + } + pub async fn get_database_editor_with_view_id( &self, view_id: &str, diff --git a/frontend/rust-lib/flowy-folder-pub/Cargo.toml b/frontend/rust-lib/flowy-folder-pub/Cargo.toml index fa1997aa9b..1eac1f5540 100644 --- a/frontend/rust-lib/flowy-folder-pub/Cargo.toml +++ b/frontend/rust-lib/flowy-folder-pub/Cargo.toml @@ -13,6 +13,7 @@ collab-entity = { workspace = true } uuid.workspace = true anyhow.workspace = true serde = { version = "1.0.202", features = ["derive"] } +serde_json.workspace = true [dev-dependencies] tokio.workspace = true diff --git a/frontend/rust-lib/flowy-folder-pub/src/entities.rs b/frontend/rust-lib/flowy-folder-pub/src/entities.rs index 9f6624b793..f3c337bb76 100644 --- a/frontend/rust-lib/flowy-folder-pub/src/entities.rs +++ b/frontend/rust-lib/flowy-folder-pub/src/entities.rs @@ -80,7 +80,6 @@ pub struct PublishDatabaseData { pub database_row_collabs: HashMap>, /// The encoded collab data for the documents inside the database rows - /// It's not used for now pub database_row_document_collabs: HashMap>, /// Visible view ids diff --git a/frontend/rust-lib/flowy-folder/src/manager.rs b/frontend/rust-lib/flowy-folder/src/manager.rs index e69127f5db..ffa203b9c3 100644 --- a/frontend/rust-lib/flowy-folder/src/manager.rs +++ b/frontend/rust-lib/flowy-folder/src/manager.rs @@ -1290,11 +1290,17 @@ impl FolderManager { .into_iter() .map(|v| (v.0, v.1.doc_state.to_vec())) // Convert to HashMap .collect::>>(); + let database_row_document_collabs = v + .database_row_document_encoded_collabs + .into_iter() + .map(|v| (v.0, v.1.doc_state.to_vec())) // Convert to HashMap + .collect::>>(); let data = PublishDatabaseData { database_collab, database_row_collabs, database_relations, + database_row_document_collabs, ..Default::default() }; PublishPayload::Database(PublishDatabasePayload { meta, data }) diff --git a/frontend/rust-lib/flowy-folder/src/view_operation.rs b/frontend/rust-lib/flowy-folder/src/view_operation.rs index 18560095b7..5a09b2bac4 100644 --- a/frontend/rust-lib/flowy-folder/src/view_operation.rs +++ b/frontend/rust-lib/flowy-folder/src/view_operation.rs @@ -35,6 +35,7 @@ pub struct DocumentEncodedCollab { pub struct DatabaseEncodedCollab { pub database_encoded_collab: EncodedCollab, pub database_row_encoded_collabs: HashMap, + pub database_row_document_encoded_collabs: HashMap, pub database_relations: HashMap, }