Skip to content

Commit

Permalink
Merge pull request AppFlowy-IO#832 from AppFlowy-IO/fix/dup-view-id
Browse files Browse the repository at this point in the history
Fix/dup view
  • Loading branch information
speed2exe authored Sep 17, 2024
2 parents 4908cea + a08b325 commit 44d76bb
Show file tree
Hide file tree
Showing 6 changed files with 442 additions and 199 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions libs/client-api-test/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ client-websocket.workspace = true
futures = "0.3.30"
anyhow = "1.0.80"
serde = { version = "1.0.199", features = ["derive"] }
hex = "0.4.3"

[target.'cfg(target_arch = "wasm32")'.dependencies]
web-sys = { version = "0.3", features = ["console"] }
Expand Down
28 changes: 27 additions & 1 deletion libs/client-api-test/src/test_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use collab_user::core::UserAwareness;
use mime::Mime;
use serde::Deserialize;
use serde_json::{json, Value};
use shared_entity::dto::publish_dto::PublishViewMetaData;
use tokio::time::{sleep, timeout, Duration};
use tokio_stream::StreamExt;
use tracing::trace;
Expand All @@ -28,7 +29,7 @@ use uuid::Uuid;
#[cfg(feature = "collab-sync")]
use client_api::collab_sync::{SinkConfig, SyncObject, SyncPlugin};
use client_api::entity::id::user_awareness_object_id;
use client_api::entity::QueryWorkspaceMember;
use client_api::entity::{PublishCollabItem, PublishCollabMetadata, QueryWorkspaceMember};
use client_api::ws::{WSClient, WSClientConfig};
use database_entity::dto::{
AFAccessLevel, AFRole, AFSnapshotMeta, AFSnapshotMetas, AFUserProfile, AFUserWorkspaceInfo,
Expand Down Expand Up @@ -830,6 +831,31 @@ impl TestClient {
let collab = (*lock).borrow();
collab.to_json_value()
}

/// data: [(view_id, meta_json, blob_hex)]
pub async fn publish_collabs(&self, workspace_id: &str, data: Vec<(Uuid, &str, &str)>) {
let pub_items = data
.into_iter()
.map(|(view_id, meta_json, blob_hex)| {
let meta: PublishViewMetaData = serde_json::from_str(meta_json).unwrap();
let blob = hex::decode(blob_hex).unwrap();
PublishCollabItem {
meta: PublishCollabMetadata {
view_id,
publish_name: uuid::Uuid::new_v4().to_string(),
metadata: meta,
},
data: blob,
}
})
.collect();

self
.api_client
.publish_collabs(workspace_id, pub_items)
.await
.unwrap();
}
}

pub async fn assert_server_snapshot(
Expand Down
45 changes: 27 additions & 18 deletions src/biz/workspace/publish_dup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -478,15 +478,17 @@ impl PublishCollabDuplicator {
Ok(())
}

/// attempts to deep copy a view using `view_id`. returns a new_view_id of the duplicated view.
/// if view is already duplicated, returns duplicated view's view_id (parent_view_id is not set
/// Attempts to deep copy a view using `pub_view_id`.
/// Returns None if view is not published else
/// returns the view id of the duplicated view.
/// If view is already duplicated, returns duplicated view's view_id (parent_view_id is not set
/// from param `parent_view_id`)
async fn deep_copy_view(
&mut self,
view_id: &str,
pub_view_id: &str,
parent_view_id: &String,
) -> Result<Option<String>, AppError> {
match self.duplicated_refs.get(view_id) {
match self.duplicated_refs.get(pub_view_id) {
Some(new_view_id) => {
if let Some(vid) = new_view_id {
Ok(Some(vid.clone()))
Expand All @@ -496,19 +498,19 @@ impl PublishCollabDuplicator {
},
None => {
// Call deep_copy and await the result
if let Some(mut new_view) = Box::pin(self.deep_copy(gen_view_id(), view_id)).await? {
if let Some(mut new_view) = Box::pin(self.deep_copy(gen_view_id(), pub_view_id)).await? {
if new_view.parent_view_id.is_empty() {
new_view.parent_view_id.clone_from(parent_view_id);
}
self
.duplicated_refs
.insert(view_id.to_string(), Some(new_view.id.clone()));
.insert(pub_view_id.to_string(), Some(new_view.id.clone()));
let ret_view_id = new_view.id.clone();
self.views_to_add.insert(new_view.id.clone(), new_view);
Ok(Some(ret_view_id))
} else {
tracing::warn!("view not found in deep_copy: {}", view_id);
self.duplicated_refs.insert(view_id.to_string(), None);
tracing::warn!("view not found in deep_copy: {}", pub_view_id);
self.duplicated_refs.insert(pub_view_id.to_string(), None);
Ok(None)
}
},
Expand Down Expand Up @@ -675,7 +677,7 @@ impl PublishCollabDuplicator {
async fn deep_copy_database<'a>(
&mut self,
published_db: &PublishDatabaseData,
publish_view_id: &str,
pub_view_id: &str,
new_view_id: String,
) -> Result<(String, String, bool), AppError> {
// collab of database
Expand All @@ -700,7 +702,7 @@ impl PublishCollabDuplicator {
let mut db_views = db_body.views.get_all_views(&txn);
let mut new_db_view_ids: Vec<String> = Vec::with_capacity(db_views.len());
for db_view in db_views.iter_mut() {
let new_db_view_id = if db_view.id == publish_view_id {
let new_db_view_id = if db_view.id == pub_view_id {
self
.duplicated_db_main_view
.insert(pub_db_id.clone(), new_view_id.clone());
Expand All @@ -714,6 +716,12 @@ impl PublishCollabDuplicator {

new_db_view_ids.push(new_db_view_id);
}
// if there is no main view id, use the inline view id
if !self.duplicated_db_main_view.contains_key(&pub_db_id) {
self
.duplicated_db_main_view
.insert(pub_db_id.clone(), db_body.get_inline_view_id(&txn));
};

// Add this database as linked view
self
Expand All @@ -740,11 +748,11 @@ impl PublishCollabDuplicator {
if *key == FieldType::Relation.type_id() {
if let Some(pub_db_id) = type_option_value.get_mut("database_id") {
if let Any::String(pub_db_id_str) = pub_db_id {
if let Some(related_db_view) =
if let Some(pub_rel_db_view) =
published_db.database_relations.get(pub_db_id_str.as_ref())
{
if let Some(_dup_view_id) = self
.deep_copy_view(related_db_view, &self.dest_view_id.to_string())
.deep_copy_view(pub_rel_db_view, &self.dest_view_id.to_string())
.await?
{
if let Some(dup_db_id) = self
Expand Down Expand Up @@ -970,14 +978,14 @@ impl PublishCollabDuplicator {
.await?;

if db_alr_duplicated {
let duplicated_view_id = self
let dup_view_id = self
.duplicated_db_view
.get(pub_view_id)
.cloned()
.ok_or_else(|| AppError::RecordNotFound(format!("view not found: {}", pub_view_id)))?;

// db_view_id found but may not have been created due to visibility
match self.views_to_add.get(&duplicated_view_id) {
match self.views_to_add.get(&dup_view_id) {
Some(v) => return Ok(v.clone()),
None => {
let main_view_id = self
Expand All @@ -987,13 +995,14 @@ impl PublishCollabDuplicator {
AppError::RecordNotFound(format!("main view not found: {}", pub_view_id))
})?;

let view_info = view_info_by_id.get(main_view_id).ok_or_else(|| {
let view_info = view_info_by_id.get(pub_view_id).ok_or_else(|| {
AppError::RecordNotFound(format!("metadata not found for view: {}", main_view_id))
})?;

let mut view =
self.new_folder_view(duplicated_view_id, view_info, view_info.layout.clone());
view.parent_view_id.clone_from(main_view_id);
let mut view = self.new_folder_view(dup_view_id, view_info, view_info.layout.clone());
if *main_view_id != view.id {
view.parent_view_id.clone_from(main_view_id);
}
return Ok(view);
},
};
Expand Down
Loading

0 comments on commit 44d76bb

Please sign in to comment.