From d86431dfbcf711d444b25240eeec03f715d326a9 Mon Sep 17 00:00:00 2001 From: "Nathan.fooo" <86001920+appflowy@users.noreply.github.com> Date: Wed, 6 Dec 2023 09:14:02 -0800 Subject: [PATCH] =?UTF-8?q?fix:=20migrate=20cloud=20document=20when=20the?= =?UTF-8?q?=20document=20content=20is=20not=20sync=20to=20=E2=80=A6=20(#41?= =?UTF-8?q?08)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: migrate cloud document when the document content is not sync to local * chore: clippy --- .../tests/database/local_test/group_test.rs | 2 +- .../user/migration_test/collab_db_restore.rs | 2 +- .../src/entities/field_entities.rs | 12 ++++----- .../src/entities/filter_entities/util.rs | 2 +- .../src/entities/sort_entities.rs | 2 +- .../src/services/cell/type_cell_data.rs | 2 +- .../src/services/database/database_editor.rs | 6 ++--- .../src/services/database_view/layout_deps.rs | 4 +-- .../src/services/database_view/view_group.rs | 4 +-- .../src/services/field/field_builder.rs | 2 +- .../checkbox_type_option/checkbox_tests.rs | 2 +- .../number_type_option/number_tests.rs | 10 +++---- .../text_type_option/text_tests.rs | 6 ++--- .../field/type_options/type_option.rs | 2 +- .../field/type_options/type_option_cell.rs | 4 +-- .../src/services/filter/entities.rs | 4 +-- .../src/services/share/csv/import.rs | 2 +- .../src/services/sort/controller.rs | 2 +- .../src/services/sort/entities.rs | 2 +- .../tests/database/database_editor.rs | 8 +++--- .../tests/database/field_test/util.rs | 19 +++++++------- .../database/mock_data/board_mock_data.rs | 24 ++++++++--------- .../database/mock_data/grid_mock_data.rs | 26 +++++++++---------- frontend/rust-lib/flowy-user/src/manager.rs | 3 ++- .../src/migrations/document_empty_content.rs | 18 ++++++++++--- .../flowy-user/src/migrations/migration.rs | 16 +++++++++--- .../migrations/workspace_and_favorite_v1.rs | 15 ++++++++++- 27 files changed, 118 insertions(+), 83 deletions(-) diff --git a/frontend/rust-lib/event-integration/tests/database/local_test/group_test.rs b/frontend/rust-lib/event-integration/tests/database/local_test/group_test.rs index 3d1280fbbe..e9ed09813a 100644 --- a/frontend/rust-lib/event-integration/tests/database/local_test/group_test.rs +++ b/frontend/rust-lib/event-integration/tests/database/local_test/group_test.rs @@ -131,7 +131,7 @@ async fn hide_group_event_test() { let groups = test.get_groups(&board_view.id).await; assert_eq!(groups.len(), 4); - assert_eq!(groups[0].is_visible, false); + assert!(!groups[0].is_visible); } #[tokio::test] diff --git a/frontend/rust-lib/event-integration/tests/user/migration_test/collab_db_restore.rs b/frontend/rust-lib/event-integration/tests/user/migration_test/collab_db_restore.rs index 75d47f8b50..363cce2af2 100644 --- a/frontend/rust-lib/event-integration/tests/user/migration_test/collab_db_restore.rs +++ b/frontend/rust-lib/event-integration/tests/user/migration_test/collab_db_restore.rs @@ -4,7 +4,7 @@ use flowy_core::DEFAULT_NAME; use crate::util::unzip_history_user_db; #[tokio::test] -async fn migrate_historical_empty_document_test() { +async fn collab_db_restore_test() { let (cleaner, user_db_path) = unzip_history_user_db( "./tests/user/migration_test/history_user_db", "038_collab_db_corrupt_restore", diff --git a/frontend/rust-lib/flowy-database2/src/entities/field_entities.rs b/frontend/rust-lib/flowy-database2/src/entities/field_entities.rs index 3f4f521e9b..f8cc886258 100644 --- a/frontend/rust-lib/flowy-database2/src/entities/field_entities.rs +++ b/frontend/rust-lib/flowy-database2/src/entities/field_entities.rs @@ -220,7 +220,7 @@ impl TryInto for CreateFieldPayloadPB { CreateFieldPosition::Before => { let field_id = self .target_field_id - .ok_or_else(|| ErrorCode::InvalidParams)?; + .ok_or(ErrorCode::InvalidParams)?; let field_id = NotEmptyStr::parse(field_id) .map_err(|_| ErrorCode::InvalidParams)? .0; @@ -229,7 +229,7 @@ impl TryInto for CreateFieldPayloadPB { CreateFieldPosition::After => { let field_id = self .target_field_id - .ok_or_else(|| ErrorCode::InvalidParams)?; + .ok_or(ErrorCode::InvalidParams)?; let field_id = NotEmptyStr::parse(field_id) .map_err(|_| ErrorCode::InvalidParams)? .0; @@ -564,7 +564,7 @@ pub enum FieldType { impl Display for FieldType { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - let value: i64 = self.clone().into(); + let value: i64 = (*self).into(); f.write_fmt(format_args!("{}", value)) } } @@ -577,13 +577,13 @@ impl AsRef for FieldType { impl From<&FieldType> for FieldType { fn from(field_type: &FieldType) -> Self { - field_type.clone() + *field_type } } impl FieldType { pub fn value(&self) -> i64 { - self.clone().into() + (*self).into() } pub fn default_name(&self) -> String { @@ -666,7 +666,7 @@ impl From for i64 { impl From<&FieldType> for i64 { fn from(ty: &FieldType) -> Self { - i64::from(ty.clone()) + i64::from(*ty) } } diff --git a/frontend/rust-lib/flowy-database2/src/entities/filter_entities/util.rs b/frontend/rust-lib/flowy-database2/src/entities/filter_entities/util.rs index cdc43c796b..9426fb0620 100644 --- a/frontend/rust-lib/flowy-database2/src/entities/filter_entities/util.rs +++ b/frontend/rust-lib/flowy-database2/src/entities/filter_entities/util.rs @@ -47,7 +47,7 @@ impl std::convert::From<&Filter> for FilterPB { Self { id: filter.id.clone(), field_id: filter.field_id.clone(), - field_type: filter.field_type.clone(), + field_type: filter.field_type, data: bytes.to_vec(), } } diff --git a/frontend/rust-lib/flowy-database2/src/entities/sort_entities.rs b/frontend/rust-lib/flowy-database2/src/entities/sort_entities.rs index c306273895..e177b83209 100644 --- a/frontend/rust-lib/flowy-database2/src/entities/sort_entities.rs +++ b/frontend/rust-lib/flowy-database2/src/entities/sort_entities.rs @@ -25,7 +25,7 @@ impl std::convert::From<&Sort> for SortPB { Self { id: sort.id.clone(), field_id: sort.field_id.clone(), - field_type: sort.field_type.clone(), + field_type: sort.field_type, condition: sort.condition.into(), } } diff --git a/frontend/rust-lib/flowy-database2/src/services/cell/type_cell_data.rs b/frontend/rust-lib/flowy-database2/src/services/cell/type_cell_data.rs index 07ebd91bf1..4d6e9cd080 100644 --- a/frontend/rust-lib/flowy-database2/src/services/cell/type_cell_data.rs +++ b/frontend/rust-lib/flowy-database2/src/services/cell/type_cell_data.rs @@ -25,7 +25,7 @@ impl TypeCellData { pub fn from_field_type(field_type: &FieldType) -> TypeCellData { Self { cell_str: "".to_string(), - field_type: field_type.clone(), + field_type: *field_type, } } diff --git a/frontend/rust-lib/flowy-database2/src/services/database/database_editor.rs b/frontend/rust-lib/flowy-database2/src/services/database/database_editor.rs index 2e8c30981d..1fc39b3ddf 100644 --- a/frontend/rust-lib/flowy-database2/src/services/database/database_editor.rs +++ b/frontend/rust-lib/flowy-database2/src/services/database/database_editor.rs @@ -346,7 +346,7 @@ impl DatabaseEditor { } let old_field_type = FieldType::from(field.field_type); - let old_type_option = field.get_any_type_option(old_field_type.clone()); + let old_type_option = field.get_any_type_option(old_field_type); let new_type_option = field .get_any_type_option(new_field_type) .unwrap_or_else(|| default_type_option_data_from_type(new_field_type)); @@ -464,7 +464,7 @@ impl DatabaseEditor { field.map(|field| { let field_type = FieldType::from(field.field_type); let type_option = field - .get_any_type_option(field_type.clone()) + .get_any_type_option(field_type) .unwrap_or_else(|| default_type_option_data_from_type(&field_type)); (field, type_option_to_pb(type_option, &field_type)) }) @@ -1265,7 +1265,7 @@ impl DatabaseViewOperation for DatabaseViewOperationImpl { let (_, field) = self.database.lock().create_field_with_mut( view_id, name.to_string(), - field_type.clone().into(), + field_type.into(), &OrderObjectPosition::default(), |field| { field diff --git a/frontend/rust-lib/flowy-database2/src/services/database_view/layout_deps.rs b/frontend/rust-lib/flowy-database2/src/services/database_view/layout_deps.rs index e3087096c0..6c01322b7d 100644 --- a/frontend/rust-lib/flowy-database2/src/services/database_view/layout_deps.rs +++ b/frontend/rust-lib/flowy-database2/src/services/database_view/layout_deps.rs @@ -139,7 +139,7 @@ impl DatabaseLayoutDepsResolver { Field::new( field_id, "Date".to_string(), - field_type.clone().into(), + field_type.into(), false, ) .with_type_option_data(field_type, default_date_type_option.into()) @@ -152,7 +152,7 @@ impl DatabaseLayoutDepsResolver { Field::new( field_id, "Status".to_string(), - field_type.clone().into(), + field_type.into(), false, ) .with_type_option_data(field_type, default_select_type_option.into()) diff --git a/frontend/rust-lib/flowy-database2/src/services/database_view/view_group.rs b/frontend/rust-lib/flowy-database2/src/services/database_view/view_group.rs index 2fb903b061..963e8a45dd 100644 --- a/frontend/rust-lib/flowy-database2/src/services/database_view/view_group.rs +++ b/frontend/rust-lib/flowy-database2/src/services/database_view/view_group.rs @@ -118,7 +118,7 @@ pub(crate) async fn get_cell_for_row( Some(RowSingleCellData { row_id: row_cell.row_id.clone(), field_id: field.id.clone(), - field_type: field_type.clone(), + field_type, cell_data, }) } @@ -143,7 +143,7 @@ pub(crate) async fn get_cells_for_field( RowSingleCellData { row_id: row_cell.row_id.clone(), field_id: field.id.clone(), - field_type: field_type.clone(), + field_type, cell_data, } }) diff --git a/frontend/rust-lib/flowy-database2/src/services/field/field_builder.rs b/frontend/rust-lib/flowy-database2/src/services/field/field_builder.rs index 7a2009de91..8db9628b75 100644 --- a/frontend/rust-lib/flowy-database2/src/services/field/field_builder.rs +++ b/frontend/rust-lib/flowy-database2/src/services/field/field_builder.rs @@ -12,7 +12,7 @@ impl FieldBuilder { let mut field = Field::new( gen_field_id(), "".to_string(), - field_type.clone().into(), + field_type.into(), false, ); field.width = 150; diff --git a/frontend/rust-lib/flowy-database2/src/services/field/type_options/checkbox_type_option/checkbox_tests.rs b/frontend/rust-lib/flowy-database2/src/services/field/type_options/checkbox_type_option/checkbox_tests.rs index 8035f9f5ad..9445689f53 100644 --- a/frontend/rust-lib/flowy-database2/src/services/field/type_options/checkbox_type_option/checkbox_tests.rs +++ b/frontend/rust-lib/flowy-database2/src/services/field/type_options/checkbox_type_option/checkbox_tests.rs @@ -12,7 +12,7 @@ mod tests { fn checkout_box_description_test() { let type_option = CheckboxTypeOption::default(); let field_type = FieldType::Checkbox; - let field_rev = FieldBuilder::from_field_type(field_type.clone()).build(); + let field_rev = FieldBuilder::from_field_type(field_type).build(); // the checkout value will be checked if the value is "1", "true" or "yes" assert_checkbox(&type_option, "1", CHECK, &field_type, &field_rev); diff --git a/frontend/rust-lib/flowy-database2/src/services/field/type_options/number_type_option/number_tests.rs b/frontend/rust-lib/flowy-database2/src/services/field/type_options/number_type_option/number_tests.rs index 3209c44ffe..b594e15940 100644 --- a/frontend/rust-lib/flowy-database2/src/services/field/type_options/number_type_option/number_tests.rs +++ b/frontend/rust-lib/flowy-database2/src/services/field/type_options/number_type_option/number_tests.rs @@ -12,7 +12,7 @@ mod tests { fn number_type_option_input_test() { let type_option = NumberTypeOption::default(); let field_type = FieldType::Number; - let field = FieldBuilder::from_field_type(field_type.clone()).build(); + let field = FieldBuilder::from_field_type(field_type).build(); // Input is empty String assert_number(&type_option, "", "", &field_type, &field); @@ -31,7 +31,7 @@ mod tests { let field_type = FieldType::Number; let mut type_option = NumberTypeOption::new(); type_option.format = NumberFormat::USD; - let field = FieldBuilder::new(field_type.clone(), type_option.clone()).build(); + let field = FieldBuilder::new(field_type, type_option.clone()).build(); assert_number(&type_option, "", "", &field_type, &field); assert_number(&type_option, "abc", "", &field_type, &field); @@ -49,7 +49,7 @@ mod tests { let field_type = FieldType::Number; let mut type_option = NumberTypeOption::new(); type_option.format = NumberFormat::USD; - let field = FieldBuilder::new(field_type.clone(), type_option.clone()).build(); + let field = FieldBuilder::new(field_type, type_option.clone()).build(); assert_number( &type_option, @@ -71,7 +71,7 @@ mod tests { let field_type = FieldType::Number; let mut type_option = NumberTypeOption::new(); type_option.format = NumberFormat::USD; - let field = FieldBuilder::new(field_type.clone(), type_option.clone()).build(); + let field = FieldBuilder::new(field_type, type_option.clone()).build(); assert_number(&type_option, "€0.2", "$0.2", &field_type, &field); assert_number(&type_option, "-€0.2", "-$0.2", &field_type, &field); @@ -85,7 +85,7 @@ mod tests { let field_type = FieldType::Number; let mut type_option = NumberTypeOption::new(); type_option.format = NumberFormat::EUR; - let field = FieldBuilder::new(field_type.clone(), type_option.clone()).build(); + let field = FieldBuilder::new(field_type, type_option.clone()).build(); assert_number(&type_option, "0.2", "€0,2", &field_type, &field); assert_number(&type_option, "1000", "€1.000", &field_type, &field); diff --git a/frontend/rust-lib/flowy-database2/src/services/field/type_options/text_type_option/text_tests.rs b/frontend/rust-lib/flowy-database2/src/services/field/type_options/text_type_option/text_tests.rs index 60e956c98a..98f4d90b77 100644 --- a/frontend/rust-lib/flowy-database2/src/services/field/type_options/text_type_option/text_tests.rs +++ b/frontend/rust-lib/flowy-database2/src/services/field/type_options/text_type_option/text_tests.rs @@ -12,7 +12,7 @@ mod tests { #[test] fn date_type_to_text_type() { let field_type = FieldType::DateTime; - let field = FieldBuilder::new(field_type.clone(), DateTypeOption::test()).build(); + let field = FieldBuilder::new(field_type, DateTypeOption::test()).build(); assert_eq!( stringify_cell_data( @@ -77,7 +77,7 @@ mod tests { options: vec![done_option.clone()], disable_color: false, }; - let field = FieldBuilder::new(field_type.clone(), single_select).build(); + let field = FieldBuilder::new(field_type, single_select).build(); assert_eq!( stringify_cell_data( @@ -107,7 +107,7 @@ mod tests { let france_option_id = france.id; let argentina_option_id = argentina.id; - let field_rev = FieldBuilder::new(field_type.clone(), multi_select).build(); + let field_rev = FieldBuilder::new(field_type, multi_select).build(); assert_eq!( stringify_cell_data( diff --git a/frontend/rust-lib/flowy-database2/src/services/field/type_options/type_option.rs b/frontend/rust-lib/flowy-database2/src/services/field/type_options/type_option.rs index 7a5429076f..e3b4f0f7a0 100644 --- a/frontend/rust-lib/flowy-database2/src/services/field/type_options/type_option.rs +++ b/frontend/rust-lib/flowy-database2/src/services/field/type_options/type_option.rs @@ -272,7 +272,7 @@ pub fn default_type_option_data_from_type(field_type: &FieldType) -> TypeOptionD FieldType::Number => NumberTypeOption::default().into(), FieldType::DateTime => DateTypeOption::default().into(), FieldType::LastEditedTime | FieldType::CreatedTime => TimestampTypeOption { - field_type: field_type.clone(), + field_type: *field_type, date_format: DateFormat::Friendly, time_format: TimeFormat::TwelveHour, include_time: true, diff --git a/frontend/rust-lib/flowy-database2/src/services/field/type_options/type_option_cell.rs b/frontend/rust-lib/flowy-database2/src/services/field/type_options/type_option_cell.rs index c07f8ff79f..2b69b74130 100644 --- a/frontend/rust-lib/flowy-database2/src/services/field/type_options/type_option_cell.rs +++ b/frontend/rust-lib/flowy-database2/src/services/field/type_options/type_option_cell.rs @@ -78,7 +78,7 @@ struct CellDataCacheKey(u64); impl CellDataCacheKey { pub fn new(field_rev: &Field, decoded_field_type: FieldType, cell: &Cell) -> Self { let mut hasher = DefaultHasher::new(); - if let Some(type_option_data) = field_rev.get_any_type_option(&decoded_field_type) { + if let Some(type_option_data) = field_rev.get_any_type_option(decoded_field_type) { type_option_data.hash(&mut hasher); } hasher.write(field_rev.id.as_bytes()); @@ -141,7 +141,7 @@ where decoded_field_type: &FieldType, field: &Field, ) -> FlowyResult<::CellData> { - let key = CellDataCacheKey::new(field, decoded_field_type.clone(), cell); + let key = CellDataCacheKey::new(field, *decoded_field_type, cell); if let Some(cell_data_cache) = self.cell_data_cache.as_ref() { let read_guard = cell_data_cache.read(); if let Some(cell_data) = read_guard.get(key.as_ref()).cloned() { diff --git a/frontend/rust-lib/flowy-database2/src/services/filter/entities.rs b/frontend/rust-lib/flowy-database2/src/services/filter/entities.rs index a5ec5ed8ea..f1a5dcd44a 100644 --- a/frontend/rust-lib/flowy-database2/src/services/filter/entities.rs +++ b/frontend/rust-lib/flowy-database2/src/services/filter/entities.rs @@ -117,7 +117,7 @@ impl std::convert::From<&Filter> for FilterType { Self { filter_id: filter.id.clone(), field_id: filter.field_id.clone(), - field_type: filter.field_type.clone(), + field_type: filter.field_type, } } } @@ -127,7 +127,7 @@ impl std::convert::From<&FilterPB> for FilterType { Self { filter_id: filter.id.clone(), field_id: filter.field_id.clone(), - field_type: filter.field_type.clone(), + field_type: filter.field_type, } } } diff --git a/frontend/rust-lib/flowy-database2/src/services/share/csv/import.rs b/frontend/rust-lib/flowy-database2/src/services/share/csv/import.rs index 037c53597d..8ff901065f 100644 --- a/frontend/rust-lib/flowy-database2/src/services/share/csv/import.rs +++ b/frontend/rust-lib/flowy-database2/src/services/share/csv/import.rs @@ -147,7 +147,7 @@ fn default_field(field_str: String, is_primary: bool) -> Field { Field::new( gen_field_id(), field_str, - field_type.clone().into(), + field_type.into(), is_primary, ) .with_type_option_data(field_type, type_option_data) diff --git a/frontend/rust-lib/flowy-database2/src/services/sort/controller.rs b/frontend/rust-lib/flowy-database2/src/services/sort/controller.rs index fe4cf2d55c..50bad3eb45 100644 --- a/frontend/rust-lib/flowy-database2/src/services/sort/controller.rs +++ b/frontend/rust-lib/flowy-database2/src/services/sort/controller.rs @@ -240,7 +240,7 @@ fn cmp_row( fields: &[Arc], cell_data_cache: &CellCache, ) -> Ordering { - let field_type = sort.field_type.clone(); + let field_type = sort.field_type; match fields .iter() .find(|field_rev| field_rev.id == sort.field_id) diff --git a/frontend/rust-lib/flowy-database2/src/services/sort/entities.rs b/frontend/rust-lib/flowy-database2/src/services/sort/entities.rs index bfc550841c..ef45126e53 100644 --- a/frontend/rust-lib/flowy-database2/src/services/sort/entities.rs +++ b/frontend/rust-lib/flowy-database2/src/services/sort/entities.rs @@ -109,7 +109,7 @@ impl From<&Sort> for SortType { Self { sort_id: data.id.clone(), field_id: data.field_id.clone(), - field_type: data.field_type.clone(), + field_type: data.field_type, } } } diff --git a/frontend/rust-lib/flowy-database2/tests/database/database_editor.rs b/frontend/rust-lib/flowy-database2/tests/database/database_editor.rs index a437cad658..daf576ef13 100644 --- a/frontend/rust-lib/flowy-database2/tests/database/database_editor.rs +++ b/frontend/rust-lib/flowy-database2/tests/database/database_editor.rs @@ -147,7 +147,7 @@ impl DatabaseEditorTest { pub fn get_multi_select_type_option(&self, field_id: &str) -> Vec { let field_type = FieldType::MultiSelect; - let field = self.get_field(field_id, field_type.clone()); + let field = self.get_field(field_id, field_type); let type_option = field .get_type_option::(field_type) .unwrap(); @@ -156,7 +156,7 @@ impl DatabaseEditorTest { pub fn get_single_select_type_option(&self, field_id: &str) -> SingleSelectTypeOption { let field_type = FieldType::SingleSelect; - let field = self.get_field(field_id, field_type.clone()); + let field = self.get_field(field_id, field_type); field .get_type_option::(field_type) .unwrap() @@ -165,7 +165,7 @@ impl DatabaseEditorTest { #[allow(dead_code)] pub fn get_checklist_type_option(&self, field_id: &str) -> ChecklistTypeOption { let field_type = FieldType::Checklist; - let field = self.get_field(field_id, field_type.clone()); + let field = self.get_field(field_id, field_type); field .get_type_option::(field_type) .unwrap() @@ -174,7 +174,7 @@ impl DatabaseEditorTest { #[allow(dead_code)] pub fn get_checkbox_type_option(&self, field_id: &str) -> CheckboxTypeOption { let field_type = FieldType::Checkbox; - let field = self.get_field(field_id, field_type.clone()); + let field = self.get_field(field_id, field_type); field .get_type_option::(field_type) .unwrap() diff --git a/frontend/rust-lib/flowy-database2/tests/database/field_test/util.rs b/frontend/rust-lib/flowy-database2/tests/database/field_test/util.rs index d6bede2dce..d4482a5e4c 100644 --- a/frontend/rust-lib/flowy-database2/tests/database/field_test/util.rs +++ b/frontend/rust-lib/flowy-database2/tests/database/field_test/util.rs @@ -1,5 +1,6 @@ use collab_database::fields::Field; use collab_database::views::OrderObjectPosition; + use flowy_database2::entities::{CreateFieldParams, FieldType}; use flowy_database2::services::field::{ type_option_to_pb, DateCellChangeset, DateFormat, DateTypeOption, FieldBuilder, @@ -9,7 +10,7 @@ use flowy_database2::services::field::{ pub fn create_text_field(grid_id: &str) -> (CreateFieldParams, Field) { let field_type = FieldType::RichText; let type_option = RichTextTypeOption::default(); - let text_field = FieldBuilder::new(field_type.clone(), type_option.clone()) + let text_field = FieldBuilder::new(field_type, type_option.clone()) .name("Name") .visibility(true) .primary(true) @@ -31,7 +32,7 @@ pub fn create_single_select_field(grid_id: &str) -> (CreateFieldParams, Field) { let mut type_option = SingleSelectTypeOption::default(); type_option.options.push(SelectOption::new("Done")); type_option.options.push(SelectOption::new("Progress")); - let single_select_field = FieldBuilder::new(field_type.clone(), type_option.clone()) + let single_select_field = FieldBuilder::new(field_type, type_option.clone()) .name("Name") .visibility(true) .build(); @@ -76,17 +77,15 @@ pub fn create_timestamp_field(grid_id: &str, field_type: FieldType) -> (CreateFi date_format: DateFormat::US, time_format: TimeFormat::TwentyFourHour, include_time: true, - field_type: field_type.clone(), + field_type, }; let field: Field = match field_type { - FieldType::LastEditedTime => { - FieldBuilder::new(field_type.clone(), timestamp_type_option.clone()) - .name("Updated At") - .visibility(true) - .build() - }, - FieldType::CreatedTime => FieldBuilder::new(field_type.clone(), timestamp_type_option.clone()) + FieldType::LastEditedTime => FieldBuilder::new(field_type, timestamp_type_option.clone()) + .name("Updated At") + .visibility(true) + .build(), + FieldType::CreatedTime => FieldBuilder::new(field_type, timestamp_type_option.clone()) .name("Created At") .visibility(true) .build(), diff --git a/frontend/rust-lib/flowy-database2/tests/database/mock_data/board_mock_data.rs b/frontend/rust-lib/flowy-database2/tests/database/mock_data/board_mock_data.rs index 1e21cb9474..9183f3a5d0 100644 --- a/frontend/rust-lib/flowy-database2/tests/database/mock_data/board_mock_data.rs +++ b/frontend/rust-lib/flowy-database2/tests/database/mock_data/board_mock_data.rs @@ -1,7 +1,5 @@ use collab_database::database::{gen_database_id, gen_database_view_id, gen_row_id, DatabaseData}; use collab_database::views::{DatabaseLayout, DatabaseView, LayoutSetting, LayoutSettings}; -use flowy_database2::services::field_settings::default_field_settings_for_fields; -use flowy_database2::services::setting::BoardLayoutSetting; use strum::IntoEnumIterator; use flowy_database2::entities::FieldType; @@ -10,6 +8,8 @@ use flowy_database2::services::field::{ DateFormat, DateTypeOption, FieldBuilder, MultiSelectTypeOption, SelectOption, SelectOptionColor, SingleSelectTypeOption, TimeFormat, TimestampTypeOption, }; +use flowy_database2::services::field_settings::default_field_settings_for_fields; +use flowy_database2::services::setting::BoardLayoutSetting; use crate::database::database_editor::TestRowBuilder; use crate::database::mock_data::{COMPLETED, FACEBOOK, GOOGLE, PAUSED, PLANNED, TWITTER}; @@ -22,7 +22,7 @@ pub fn make_test_board() -> DatabaseData { for field_type in FieldType::iter() { match field_type { FieldType::RichText => { - let text_field = FieldBuilder::from_field_type(field_type.clone()) + let text_field = FieldBuilder::from_field_type(field_type) .name("Name") .visibility(true) .primary(true) @@ -31,7 +31,7 @@ pub fn make_test_board() -> DatabaseData { }, FieldType::Number => { // Number - let number_field = FieldBuilder::from_field_type(field_type.clone()) + let number_field = FieldBuilder::from_field_type(field_type) .name("Price") .visibility(true) .build(); @@ -45,7 +45,7 @@ pub fn make_test_board() -> DatabaseData { timezone_id: "Etc/UTC".to_owned(), }; let name = "Time"; - let date_field = FieldBuilder::new(field_type.clone(), date_type_option) + let date_field = FieldBuilder::new(field_type, date_type_option) .name(name) .visibility(true) .build(); @@ -57,14 +57,14 @@ pub fn make_test_board() -> DatabaseData { date_format: DateFormat::US, time_format: TimeFormat::TwentyFourHour, include_time: true, - field_type: field_type.clone(), + field_type, }; let name = match field_type { FieldType::LastEditedTime => "Last Modified", FieldType::CreatedTime => "Created At", _ => "", }; - let date_field = FieldBuilder::new(field_type.clone(), date_type_option) + let date_field = FieldBuilder::new(field_type, date_type_option) .name(name) .visibility(true) .build(); @@ -79,7 +79,7 @@ pub fn make_test_board() -> DatabaseData { single_select_type_option .options .extend(vec![option1, option2, option3]); - let single_select_field = FieldBuilder::new(field_type.clone(), single_select_type_option) + let single_select_field = FieldBuilder::new(field_type, single_select_type_option) .name("Status") .visibility(true) .build(); @@ -92,7 +92,7 @@ pub fn make_test_board() -> DatabaseData { let option3 = SelectOption::with_color(TWITTER, SelectOptionColor::Yellow); let mut type_option = MultiSelectTypeOption::default(); type_option.options.extend(vec![option1, option2, option3]); - let multi_select_field = FieldBuilder::new(field_type.clone(), type_option) + let multi_select_field = FieldBuilder::new(field_type, type_option) .name("Platform") .visibility(true) .build(); @@ -100,7 +100,7 @@ pub fn make_test_board() -> DatabaseData { }, FieldType::Checkbox => { // Checkbox - let checkbox_field = FieldBuilder::from_field_type(field_type.clone()) + let checkbox_field = FieldBuilder::from_field_type(field_type) .name("is urgent") .visibility(true) .build(); @@ -108,7 +108,7 @@ pub fn make_test_board() -> DatabaseData { }, FieldType::URL => { // URL - let url = FieldBuilder::from_field_type(field_type.clone()) + let url = FieldBuilder::from_field_type(field_type) .name("link") .visibility(true) .build(); @@ -120,7 +120,7 @@ pub fn make_test_board() -> DatabaseData { // let option3 = SelectOption::with_color(THIRD_THING, SelectOptionColor::Yellow); let type_option = ChecklistTypeOption::default(); // type_option.options.extend(vec![option1, option2, option3]); - let checklist_field = FieldBuilder::new(field_type.clone(), type_option) + let checklist_field = FieldBuilder::new(field_type, type_option) .name("TODO") .visibility(true) .build(); diff --git a/frontend/rust-lib/flowy-database2/tests/database/mock_data/grid_mock_data.rs b/frontend/rust-lib/flowy-database2/tests/database/mock_data/grid_mock_data.rs index 52790c2b27..9ccedd60ea 100644 --- a/frontend/rust-lib/flowy-database2/tests/database/mock_data/grid_mock_data.rs +++ b/frontend/rust-lib/flowy-database2/tests/database/mock_data/grid_mock_data.rs @@ -1,6 +1,5 @@ use collab_database::database::{gen_database_id, gen_database_view_id, gen_row_id, DatabaseData}; use collab_database::views::{DatabaseLayout, DatabaseView}; -use flowy_database2::services::field_settings::default_field_settings_for_fields; use strum::IntoEnumIterator; use flowy_database2::entities::FieldType; @@ -9,6 +8,7 @@ use flowy_database2::services::field::{ DateFormat, DateTypeOption, FieldBuilder, MultiSelectTypeOption, NumberFormat, NumberTypeOption, SelectOption, SelectOptionColor, SingleSelectTypeOption, TimeFormat, TimestampTypeOption, }; +use flowy_database2::services::field_settings::default_field_settings_for_fields; use crate::database::database_editor::TestRowBuilder; use crate::database::mock_data::{COMPLETED, FACEBOOK, GOOGLE, PAUSED, PLANNED, TWITTER}; @@ -21,7 +21,7 @@ pub fn make_test_grid() -> DatabaseData { for field_type in FieldType::iter() { match field_type { FieldType::RichText => { - let text_field = FieldBuilder::from_field_type(field_type.clone()) + let text_field = FieldBuilder::from_field_type(field_type) .name("Name") .visibility(true) .primary(true) @@ -33,7 +33,7 @@ pub fn make_test_grid() -> DatabaseData { let mut type_option = NumberTypeOption::default(); type_option.set_format(NumberFormat::USD); - let number_field = FieldBuilder::new(field_type.clone(), type_option) + let number_field = FieldBuilder::new(field_type, type_option) .name("Price") .visibility(true) .build(); @@ -47,7 +47,7 @@ pub fn make_test_grid() -> DatabaseData { timezone_id: "Etc/UTC".to_owned(), }; let name = "Time"; - let date_field = FieldBuilder::new(field_type.clone(), date_type_option) + let date_field = FieldBuilder::new(field_type, date_type_option) .name(name) .visibility(true) .build(); @@ -59,14 +59,14 @@ pub fn make_test_grid() -> DatabaseData { date_format: DateFormat::US, time_format: TimeFormat::TwentyFourHour, include_time: true, - field_type: field_type.clone(), + field_type, }; let name = match field_type { FieldType::LastEditedTime => "Last Modified", FieldType::CreatedTime => "Created At", _ => "", }; - let timestamp_field = FieldBuilder::new(field_type.clone(), timestamp_type_option) + let timestamp_field = FieldBuilder::new(field_type, timestamp_type_option) .name(name) .visibility(true) .build(); @@ -81,7 +81,7 @@ pub fn make_test_grid() -> DatabaseData { single_select_type_option .options .extend(vec![option1, option2, option3]); - let single_select_field = FieldBuilder::new(field_type.clone(), single_select_type_option) + let single_select_field = FieldBuilder::new(field_type, single_select_type_option) .name("Status") .visibility(true) .build(); @@ -94,7 +94,7 @@ pub fn make_test_grid() -> DatabaseData { let option3 = SelectOption::with_color(TWITTER, SelectOptionColor::Yellow); let mut type_option = MultiSelectTypeOption::default(); type_option.options.extend(vec![option1, option2, option3]); - let multi_select_field = FieldBuilder::new(field_type.clone(), type_option) + let multi_select_field = FieldBuilder::new(field_type, type_option) .name("Platform") .visibility(true) .build(); @@ -102,7 +102,7 @@ pub fn make_test_grid() -> DatabaseData { }, FieldType::Checkbox => { // Checkbox - let checkbox_field = FieldBuilder::from_field_type(field_type.clone()) + let checkbox_field = FieldBuilder::from_field_type(field_type) .name("is urgent") .visibility(true) .build(); @@ -110,7 +110,7 @@ pub fn make_test_grid() -> DatabaseData { }, FieldType::URL => { // URL - let url = FieldBuilder::from_field_type(field_type.clone()) + let url = FieldBuilder::from_field_type(field_type) .name("link") .visibility(true) .build(); @@ -122,7 +122,7 @@ pub fn make_test_grid() -> DatabaseData { // let option3 = SelectOption::with_color(THIRD_THING, SelectOptionColor::Yellow); let type_option = ChecklistTypeOption::default(); // type_option.options.extend(vec![option1, option2, option3]); - let checklist_field = FieldBuilder::new(field_type.clone(), type_option) + let checklist_field = FieldBuilder::new(field_type, type_option) .name("TODO") .visibility(true) .build(); @@ -274,7 +274,7 @@ pub fn make_no_date_test_grid() -> DatabaseData { for field_type in FieldType::iter() { match field_type { FieldType::RichText => { - let text_field = FieldBuilder::from_field_type(field_type.clone()) + let text_field = FieldBuilder::from_field_type(field_type) .name("Name") .visibility(true) .primary(true) @@ -286,7 +286,7 @@ pub fn make_no_date_test_grid() -> DatabaseData { let mut type_option = NumberTypeOption::default(); type_option.set_format(NumberFormat::USD); - let number_field = FieldBuilder::new(field_type.clone(), type_option) + let number_field = FieldBuilder::new(field_type, type_option) .name("Price") .visibility(true) .build(); diff --git a/frontend/rust-lib/flowy-user/src/manager.rs b/frontend/rust-lib/flowy-user/src/manager.rs index e85286af00..b0d671ab32 100644 --- a/frontend/rust-lib/flowy-user/src/manager.rs +++ b/frontend/rust-lib/flowy-user/src/manager.rs @@ -234,7 +234,8 @@ impl UserManager { Box::new(HistoricalEmptyDocumentMigration), Box::new(FavoriteV1AndWorkspaceArrayMigration), ]; - match UserLocalDataMigration::new(session.clone(), collab_db, sqlite_pool).run(migrations) + match UserLocalDataMigration::new(session.clone(), collab_db, sqlite_pool) + .run(migrations, ¤t_authenticator) { Ok(applied_migrations) => { if !applied_migrations.is_empty() { diff --git a/frontend/rust-lib/flowy-user/src/migrations/document_empty_content.rs b/frontend/rust-lib/flowy-user/src/migrations/document_empty_content.rs index ffa7e007d4..bd4e0fb1c6 100644 --- a/frontend/rust-lib/flowy-user/src/migrations/document_empty_content.rs +++ b/frontend/rust-lib/flowy-user/src/migrations/document_empty_content.rs @@ -9,6 +9,7 @@ use tracing::{event, instrument}; use collab_integrate::{PersistenceError, RocksCollabDB, YrsDocAction}; use flowy_error::{internal_error, FlowyError, FlowyResult}; +use flowy_user_deps::entities::Authenticator; use crate::migrations::migration::UserDataMigration; use crate::migrations::util::load_collab; @@ -23,7 +24,18 @@ impl UserDataMigration for HistoricalEmptyDocumentMigration { } #[instrument(name = "HistoricalEmptyDocumentMigration", skip_all, err)] - fn run(&self, session: &Session, collab_db: &Arc) -> FlowyResult<()> { + fn run( + &self, + session: &Session, + collab_db: &Arc, + authenticator: &Authenticator, + ) -> FlowyResult<()> { + // - The `empty document` struct has already undergone refactoring prior to the launch of the AppFlowy cloud version. + // - Consequently, if a user is utilizing the AppFlowy cloud version, there is no need to perform any migration for the `empty document` struct. + // - This migration step is only necessary for users who are transitioning from a local version of AppFlowy to the cloud version. + if !matches!(authenticator, Authenticator::Local) { + return Ok(()); + } let write_txn = collab_db.write_txn(); let origin = CollabOrigin::Client(CollabClient::new(session.user_id, "phantom")); let folder_collab = match load_collab(session.user_id, &write_txn, &session.user_workspace.id) { @@ -37,7 +49,7 @@ impl UserDataMigration for HistoricalEmptyDocumentMigration { // For historical reasons, the first level documents are empty. So migrate them by inserting // the default document data. for view in migration_views { - if let Err(_) = migrate_empty_document(&write_txn, &origin, &view, session.user_id) { + if migrate_empty_document(&write_txn, &origin, &view, session.user_id).is_err() { event!( tracing::Level::ERROR, "Failed to migrate document {}", @@ -46,7 +58,6 @@ impl UserDataMigration for HistoricalEmptyDocumentMigration { } } - event!(tracing::Level::INFO, "Save all migrated documents"); write_txn.commit_transaction().map_err(internal_error)?; Ok(()) } @@ -62,6 +73,7 @@ where W: YrsDocAction<'a>, PersistenceError: From, { + // If the document is not exist, we don't need to migrate it. if load_collab(user_id, write_txn, &view.id).is_err() { let collab = Arc::new(MutexCollab::new(origin.clone(), &view.id, vec![])); let document = Document::create_with_data(collab, default_document_data())?; diff --git a/frontend/rust-lib/flowy-user/src/migrations/migration.rs b/frontend/rust-lib/flowy-user/src/migrations/migration.rs index e874c39946..dee59f58c5 100644 --- a/frontend/rust-lib/flowy-user/src/migrations/migration.rs +++ b/frontend/rust-lib/flowy-user/src/migrations/migration.rs @@ -7,6 +7,7 @@ use collab_integrate::RocksCollabDB; use flowy_error::FlowyResult; use flowy_sqlite::schema::user_data_migration_records; use flowy_sqlite::ConnectionPool; +use flowy_user_deps::entities::Authenticator; use crate::services::entities::Session; @@ -42,7 +43,11 @@ impl UserLocalDataMigration { /// /// * `migrations` - A vector of boxed dynamic `UserDataMigration` objects representing the migrations to be applied. /// - pub fn run(self, migrations: Vec>) -> FlowyResult> { + pub fn run( + self, + migrations: Vec>, + authenticator: &Authenticator, + ) -> FlowyResult> { let mut applied_migrations = vec![]; let conn = self.sqlite_pool.get()?; let record = get_all_records(&conn)?; @@ -54,7 +59,7 @@ impl UserLocalDataMigration { { let migration_name = migration.name().to_string(); if !duplicated_names.contains(&migration_name) { - migration.run(&self.session, &self.collab_db)?; + migration.run(&self.session, &self.collab_db, authenticator)?; applied_migrations.push(migration.name().to_string()); save_record(&conn, &migration_name); duplicated_names.push(migration_name); @@ -70,7 +75,12 @@ impl UserLocalDataMigration { pub trait UserDataMigration { /// Migration with the same name will be skipped fn name(&self) -> &str; - fn run(&self, user: &Session, collab_db: &Arc) -> FlowyResult<()>; + fn run( + &self, + user: &Session, + collab_db: &Arc, + authenticator: &Authenticator, + ) -> FlowyResult<()>; } fn save_record(conn: &SqliteConnection, migration_name: &str) { diff --git a/frontend/rust-lib/flowy-user/src/migrations/workspace_and_favorite_v1.rs b/frontend/rust-lib/flowy-user/src/migrations/workspace_and_favorite_v1.rs index 8429e07b85..3d5016f0da 100644 --- a/frontend/rust-lib/flowy-user/src/migrations/workspace_and_favorite_v1.rs +++ b/frontend/rust-lib/flowy-user/src/migrations/workspace_and_favorite_v1.rs @@ -5,6 +5,7 @@ use tracing::instrument; use collab_integrate::{RocksCollabDB, YrsDocAction}; use flowy_error::{internal_error, FlowyResult}; +use flowy_user_deps::entities::Authenticator; use crate::migrations::migration::UserDataMigration; use crate::migrations::util::load_collab; @@ -21,7 +22,19 @@ impl UserDataMigration for FavoriteV1AndWorkspaceArrayMigration { } #[instrument(name = "FavoriteV1AndWorkspaceArrayMigration", skip_all, err)] - fn run(&self, session: &Session, collab_db: &Arc) -> FlowyResult<()> { + fn run( + &self, + session: &Session, + collab_db: &Arc, + authenticator: &Authenticator, + ) -> FlowyResult<()> { + // Note on `favorite` Struct Refactoring and Migration: + // - The `favorite` struct has already undergone refactoring prior to the launch of the AppFlowy cloud version. + // - Consequently, if a user is utilizing the AppFlowy cloud version, there is no need to perform any migration for the `favorite` struct. + // - This migration step is only necessary for users who are transitioning from a local version of AppFlowy to the cloud version. + if !matches!(authenticator, Authenticator::Local) { + return Ok(()); + } let write_txn = collab_db.write_txn(); if let Ok(collab) = load_collab(session.user_id, &write_txn, &session.user_workspace.id) { let folder = Folder::open(session.user_id, collab, None)?;