feat: collect row page collabs (#6215)

* fix: invalid value when inserting image

* feat: collect row document collabs

* fix: code review

* fix: invalid value when inserting image

* chore: remove database_row_metas
This commit is contained in:
Lucas.Xu 2024-09-09 19:40:52 +08:00 committed by GitHub
parent 5d42d03e15
commit 2f3c9c11b1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 89 additions and 39 deletions

View File

@ -2227,6 +2227,7 @@ dependencies = [
"collab-folder",
"lib-infra",
"serde",
"serde_json",
"tokio",
"uuid",
]

View File

@ -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::<Vec<_>>();
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::<Result<HashMap<_, _>, 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::<HashMap<_, _>>();
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::<Result<HashMap<_, _>, 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::<HashMap<_, _>>();
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::<Result<HashMap<_, _>, 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<Bytes, FlowyError> {

View File

@ -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<RowId>,
) -> FlowyResult<Vec<RowMetaPB>> {
let database = self.get_database_editor_with_view_id(view_id).await?;
let view_id = view_id.to_string();
let mut row_metas: Vec<RowMetaPB> = 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,

View File

@ -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

View File

@ -80,7 +80,6 @@ pub struct PublishDatabaseData {
pub database_row_collabs: HashMap<String, Vec<u8>>,
/// The encoded collab data for the documents inside the database rows
/// It's not used for now
pub database_row_document_collabs: HashMap<String, Vec<u8>>,
/// Visible view ids

View File

@ -1290,11 +1290,17 @@ impl FolderManager {
.into_iter()
.map(|v| (v.0, v.1.doc_state.to_vec())) // Convert to HashMap
.collect::<HashMap<String, Vec<u8>>>();
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::<HashMap<String, Vec<u8>>>();
let data = PublishDatabaseData {
database_collab,
database_row_collabs,
database_relations,
database_row_document_collabs,
..Default::default()
};
PublishPayload::Database(PublishDatabasePayload { meta, data })

View File

@ -35,6 +35,7 @@ pub struct DocumentEncodedCollab {
pub struct DatabaseEncodedCollab {
pub database_encoded_collab: EncodedCollab,
pub database_row_encoded_collabs: HashMap<String, EncodedCollab>,
pub database_row_document_encoded_collabs: HashMap<String, EncodedCollab>,
pub database_relations: HashMap<String, String>,
}