From 4a81fed6e48d19c5659d3fa7c0771385cafe9441 Mon Sep 17 00:00:00 2001 From: "Nathan.fooo" <86001920+appflowy@users.noreply.github.com> Date: Mon, 27 Feb 2023 19:00:00 +0800 Subject: [PATCH] fix: group with not support field test (#1890) --- frontend/.vscode/launch.json | 4 +- frontend/Makefile.toml | 3 +- .../application/database_service.dart | 2 +- .../application/board_data_controller.dart | 2 +- .../application/calendar_data_controller.dart | 2 +- .../application/grid_data_controller.dart | 2 +- .../group_by_unsupport_field_test.dart | 2 +- frontend/appflowy_tauri/src-tauri/Cargo.lock | 2 + .../effects/database/cell/backend_service.ts | 4 +- .../effects/database/cell/data_persistence.ts | 2 +- .../effects/database/field/backend_service.ts | 2 +- .../stores/effects/database/row/cache.ts | 8 +-- .../effects/database/view/row_observer.ts | 12 ++-- .../effects/folder/app/backend_service.ts | 1 - .../client_database/database_revision_pad.rs | 8 +-- .../src/entities/field_entities.rs | 2 +- .../flowy-database/src/event_handler.rs | 2 +- .../rust-lib/flowy-database/src/manager.rs | 34 ++++++----- .../src/services/database/block_editor.rs | 5 +- .../src/services/database/database_editor.rs | 8 +-- .../src/services/database_view/editor.rs | 61 ++++++++++--------- .../services/database_view/editor_manager.rs | 55 +++++++++-------- .../src/services/group/group_util.rs | 35 +++++++++-- frontend/rust-lib/flowy-sqlite/src/schema.rs | 34 +++++------ frontend/scripts/makefile/desktop.toml | 40 ++++++------ frontend/scripts/makefile/tests.toml | 14 ++--- shared-lib/database-model/src/database_rev.rs | 4 +- 27 files changed, 192 insertions(+), 158 deletions(-) diff --git a/frontend/.vscode/launch.json b/frontend/.vscode/launch.json index 0501207968..657f42fdd9 100644 --- a/frontend/.vscode/launch.json +++ b/frontend/.vscode/launch.json @@ -12,8 +12,8 @@ "type": "dart", "preLaunchTask": "AF: Build Appflowy Core", "env": { - "RUST_LOG": "trace", - // "RUST_LOG": "debug" + // "RUST_LOG": "trace", + "RUST_LOG": "debug" }, "cwd": "${workspaceRoot}/appflowy_flutter" }, diff --git a/frontend/Makefile.toml b/frontend/Makefile.toml index 94ec0b3648..8ca63bfa72 100644 --- a/frontend/Makefile.toml +++ b/frontend/Makefile.toml @@ -18,7 +18,7 @@ on_error_task = "catch" run_task = { name = ["restore-crate-type"] } [env] -RUST_LOG = "debug" +RUST_LOG = "info" CARGO_MAKE_EXTEND_WORKSPACE_MAKEFILE = true CARGO_MAKE_CRATE_FS_NAME = "dart_ffi" CARGO_MAKE_CRATE_NAME = "dart-ffi" @@ -48,7 +48,6 @@ TAURI_BACKEND_SERVICE_PATH = "appflowy_tauri/src/services/backend" # Test default config TEST_CRATE_TYPE = "cdylib" TEST_LIB_EXT = "dylib" -TEST_RUST_LOG = "info" TEST_BUILD_FLAG = "debug" TEST_COMPILE_TARGET = "x86_64-apple-darwin" diff --git a/frontend/appflowy_flutter/lib/plugins/database_view/application/database_service.dart b/frontend/appflowy_flutter/lib/plugins/database_view/application/database_service.dart index 289acbebfc..9f56d1f443 100644 --- a/frontend/appflowy_flutter/lib/plugins/database_view/application/database_service.dart +++ b/frontend/appflowy_flutter/lib/plugins/database_view/application/database_service.dart @@ -53,7 +53,7 @@ class DatabaseBackendService { }); } - Future> closeGrid() { + Future> closeView() { final request = ViewIdPB(value: viewId); return FolderEventCloseView(request).send(); } diff --git a/frontend/appflowy_flutter/lib/plugins/database_view/board/application/board_data_controller.dart b/frontend/appflowy_flutter/lib/plugins/database_view/board/application/board_data_controller.dart index b54073b17b..ba801ea90d 100644 --- a/frontend/appflowy_flutter/lib/plugins/database_view/board/application/board_data_controller.dart +++ b/frontend/appflowy_flutter/lib/plugins/database_view/board/application/board_data_controller.dart @@ -126,7 +126,7 @@ class BoardDataController { Future dispose() async { await _viewCache.dispose(); - await _databaseFFIService.closeGrid(); + await _databaseFFIService.closeView(); await fieldController.dispose(); } diff --git a/frontend/appflowy_flutter/lib/plugins/database_view/calendar/application/calendar_data_controller.dart b/frontend/appflowy_flutter/lib/plugins/database_view/calendar/application/calendar_data_controller.dart index e037be073d..6ba517fbd2 100644 --- a/frontend/appflowy_flutter/lib/plugins/database_view/calendar/application/calendar_data_controller.dart +++ b/frontend/appflowy_flutter/lib/plugins/database_view/calendar/application/calendar_data_controller.dart @@ -109,7 +109,7 @@ class CalendarDataController { Future dispose() async { await _viewCache.dispose(); - await _databaseBackendSvc.closeGrid(); + await _databaseBackendSvc.closeView(); await fieldController.dispose(); } } diff --git a/frontend/appflowy_flutter/lib/plugins/database_view/grid/application/grid_data_controller.dart b/frontend/appflowy_flutter/lib/plugins/database_view/grid/application/grid_data_controller.dart index f9a9ac9049..4a6499edf2 100644 --- a/frontend/appflowy_flutter/lib/plugins/database_view/grid/application/grid_data_controller.dart +++ b/frontend/appflowy_flutter/lib/plugins/database_view/grid/application/grid_data_controller.dart @@ -77,7 +77,7 @@ class DatabaseController { } Future dispose() async { - await _databaseBackendSvc.closeGrid(); + await _databaseBackendSvc.closeView(); await fieldController.dispose(); } } diff --git a/frontend/appflowy_flutter/test/bloc_test/board_test/group_by_unsupport_field_test.dart b/frontend/appflowy_flutter/test/bloc_test/board_test/group_by_unsupport_field_test.dart index 8f4a4c9263..a6e1cbb85a 100644 --- a/frontend/appflowy_flutter/test/bloc_test/board_test/group_by_unsupport_field_test.dart +++ b/frontend/appflowy_flutter/test/bloc_test/board_test/group_by_unsupport_field_test.dart @@ -22,7 +22,7 @@ void main() { await boardResponseFuture(); }); - group('Group with not support grouping field:', () { + group('Group with not support grouping field', () { blocTest( "switch to text field", build: () => editorBloc, diff --git a/frontend/appflowy_tauri/src-tauri/Cargo.lock b/frontend/appflowy_tauri/src-tauri/Cargo.lock index 4d20bc28b5..f38f5bc6a2 100644 --- a/frontend/appflowy_tauri/src-tauri/Cargo.lock +++ b/frontend/appflowy_tauri/src-tauri/Cargo.lock @@ -1225,6 +1225,8 @@ dependencies = [ "lib-ws", "parking_lot", "revision-model", + "serde", + "serde_json", "tokio", "tracing", "user-model", diff --git a/frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/cell/backend_service.ts b/frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/cell/backend_service.ts index aeae587faf..03f22277bd 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/cell/backend_service.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/cell/backend_service.ts @@ -14,7 +14,7 @@ class CellIdentifier { class CellBackendService { static updateCell = async (cellId: CellIdentifier, data: string) => { const payload = CellChangesetPB.fromObject({ - database_id: cellId.viewId, + view_id: cellId.viewId, field_id: cellId.fieldId, row_id: cellId.rowId, type_cell_data: data, @@ -24,7 +24,7 @@ class CellBackendService { getCell = async (cellId: CellIdentifier) => { const payload = CellIdPB.fromObject({ - database_id: cellId.viewId, + view_id: cellId.viewId, field_id: cellId.fieldId, row_id: cellId.rowId, }); diff --git a/frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/cell/data_persistence.ts b/frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/cell/data_persistence.ts index 17c8b366a2..c023d5e864 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/cell/data_persistence.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/cell/data_persistence.ts @@ -39,7 +39,7 @@ export class DateCellDataPersistence extends CellDataPersistence { function _makeCellPath(cellIdentifier: CellIdentifier): CellIdPB { return CellIdPB.fromObject({ - database_id: cellIdentifier.viewId, + view_id: cellIdentifier.viewId, field_id: cellIdentifier.fieldId, row_id: cellIdentifier.rowId, }); diff --git a/frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/field/backend_service.ts b/frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/field/backend_service.ts index 62e20dbf27..1f9c878e42 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/field/backend_service.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/field/backend_service.ts @@ -28,7 +28,7 @@ export class FieldBackendService { visibility?: boolean; width?: number; }) => { - const payload = FieldChangesetPB.fromObject({ database_id: this.viewId, field_id: this.fieldId }); + const payload = FieldChangesetPB.fromObject({ view_id: this.viewId, field_id: this.fieldId }); if (data.name !== undefined) { payload.name = data.name; diff --git a/frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/row/cache.ts b/frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/row/cache.ts index 95660e9387..b7e037a43d 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/row/cache.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/row/cache.ts @@ -3,8 +3,8 @@ import { ChangeNotifier } from '../../../../utils/change_notifier'; import { FieldInfo } from '../field/controller'; import { CellCache, CellCacheKey } from '../cell/cache'; import { - ViewRowsChangesetPB, - ViewRowsVisibilityChangesetPB, + RowsChangesetPB, + RowsVisibilityChangesetPB, } from '../../../../../services/backend/models/flowy-database/view_entities'; import { CellIdentifier } from '../cell/backend_service'; import { ReorderSingleRowPB } from '../../../../../services/backend/models/flowy-database/sort_entities'; @@ -49,13 +49,13 @@ export class RowCache { }); }; - applyRowsChanged = (changeset: ViewRowsChangesetPB) => { + applyRowsChanged = (changeset: RowsChangesetPB) => { this._deleteRows(changeset.deleted_rows); this._insertRows(changeset.inserted_rows); this._updateRows(changeset.updated_rows); }; - applyRowsVisibility = (changeset: ViewRowsVisibilityChangesetPB) => { + applyRowsVisibility = (changeset: RowsVisibilityChangesetPB) => { this._hideRows(changeset.invisible_rows); this._displayRows(changeset.visible_rows); }; diff --git a/frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/view/row_observer.ts b/frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/view/row_observer.ts index c44c740bc8..0bc25e0e57 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/view/row_observer.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/view/row_observer.ts @@ -5,15 +5,15 @@ import { ReorderSingleRowPB, } from '../../../../../services/backend/events/flowy-database'; import { - ViewRowsChangesetPB, - ViewRowsVisibilityChangesetPB, + RowsChangesetPB, + RowsVisibilityChangesetPB, } from '../../../../../services/backend/models/flowy-database/view_entities'; import { FlowyError } from '../../../../../services/backend/models/flowy-error/errors'; import { ChangeNotifier } from '../../../../utils/change_notifier'; import { DatabaseNotificationObserver } from '../notifications/observer'; -export type RowsVisibilityNotifyValue = Result; -export type RowsNotifyValue = Result; +export type RowsVisibilityNotifyValue = Result; +export type RowsNotifyValue = Result; export type ReorderRowsNotifyValue = Result; export type ReorderSingleRowNotifyValue = Result; @@ -43,10 +43,10 @@ export class DatabaseViewRowsObserver { parserHandler: (notification, payload) => { switch (notification) { case DatabaseNotification.DidUpdateViewRowsVisibility: - this._rowsVisibilityNotifier.notify(Ok(ViewRowsVisibilityChangesetPB.deserializeBinary(payload))); + this._rowsVisibilityNotifier.notify(Ok(RowsVisibilityChangesetPB.deserializeBinary(payload))); break; case DatabaseNotification.DidUpdateViewRows: - this._rowsNotifier.notify(Ok(ViewRowsChangesetPB.deserializeBinary(payload))); + this._rowsNotifier.notify(Ok(RowsChangesetPB.deserializeBinary(payload))); break; case DatabaseNotification.DidReorderRows: this._reorderRowsNotifier.notify(Ok(ReorderAllRowsPB.deserializeBinary(payload).row_orders)); diff --git a/frontend/appflowy_tauri/src/appflowy_app/stores/effects/folder/app/backend_service.ts b/frontend/appflowy_tauri/src/appflowy_app/stores/effects/folder/app/backend_service.ts index 54e0a4c6f9..d1d8fd1aa3 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/stores/effects/folder/app/backend_service.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/stores/effects/folder/app/backend_service.ts @@ -41,7 +41,6 @@ export class AppBackendService { belong_to_id: this.appId, name: params.name, desc: params.desc || '', - data_format: params.dataFormatType, layout: params.layoutType, initial_data: encoder.encode(params.initialData || ''), }); diff --git a/frontend/rust-lib/flowy-client-sync/src/client_database/database_revision_pad.rs b/frontend/rust-lib/flowy-client-sync/src/client_database/database_revision_pad.rs index c9741b0200..6fab22ea5a 100644 --- a/frontend/rust-lib/flowy-client-sync/src/client_database/database_revision_pad.rs +++ b/frontend/rust-lib/flowy-client-sync/src/client_database/database_revision_pad.rs @@ -109,18 +109,18 @@ impl DatabaseRevisionPad { &mut self, field_id: &str, ) -> SyncResult> { - self.modify_database(|grid_meta| { - match grid_meta + self.modify_database(|database| { + match database .fields .iter() .position(|field| field.id == field_id) { None => Ok(None), Some(index) => { - if grid_meta.fields[index].is_primary { + if database.fields[index].is_primary { Err(SyncError::can_not_delete_primary_field()) } else { - grid_meta.fields.remove(index); + database.fields.remove(index); Ok(Some(())) } }, diff --git a/frontend/rust-lib/flowy-database/src/entities/field_entities.rs b/frontend/rust-lib/flowy-database/src/entities/field_entities.rs index 0610afa092..d8ef22cb38 100644 --- a/frontend/rust-lib/flowy-database/src/entities/field_entities.rs +++ b/frontend/rust-lib/flowy-database/src/entities/field_entities.rs @@ -572,7 +572,7 @@ impl FieldType { } pub fn can_be_group(&self) -> bool { - self.is_select_option() || self.is_checkbox() + self.is_select_option() || self.is_checkbox() || self.is_url() } } diff --git a/frontend/rust-lib/flowy-database/src/event_handler.rs b/frontend/rust-lib/flowy-database/src/event_handler.rs index b0ad0ae5a4..fdf08123dd 100644 --- a/frontend/rust-lib/flowy-database/src/event_handler.rs +++ b/frontend/rust-lib/flowy-database/src/event_handler.rs @@ -162,7 +162,7 @@ pub(crate) async fn delete_field_handler( Ok(()) } -#[tracing::instrument(level = "trace", skip(data, manager), err)] +#[tracing::instrument(level = "debug", skip(data, manager), err)] pub(crate) async fn switch_to_field_handler( data: AFPluginData, manager: AFPluginState>, diff --git a/frontend/rust-lib/flowy-database/src/manager.rs b/frontend/rust-lib/flowy-database/src/manager.rs index 1c26c9baa8..2fb1ad316a 100644 --- a/frontend/rust-lib/flowy-database/src/manager.rs +++ b/frontend/rust-lib/flowy-database/src/manager.rs @@ -40,7 +40,7 @@ pub trait DatabaseUser: Send + Sync { } pub struct DatabaseManager { - database_editors: RwLock>>, + editors_by_database_id: RwLock>>, database_user: Arc, block_indexer: Arc, database_ref_indexer: Arc, @@ -58,7 +58,7 @@ impl DatabaseManager { task_scheduler: Arc>, database_db: Arc, ) -> Self { - let database_editors = RwLock::new(HashMap::new()); + let editors_by_database_id = RwLock::new(HashMap::new()); let kv_persistence = Arc::new(DatabaseKVPersistence::new(database_db.clone())); let block_indexer = Arc::new(BlockRowIndexer::new(database_db.clone())); let database_ref_indexer = Arc::new(DatabaseRefIndexer::new(database_db.clone())); @@ -68,7 +68,7 @@ impl DatabaseManager { database_ref_indexer.clone(), ); Self { - database_editors, + editors_by_database_id, database_user, kv_persistence, block_indexer, @@ -141,7 +141,6 @@ impl DatabaseManager { .await } - #[tracing::instrument(level = "debug", skip_all, fields(view_id), err)] pub async fn close_database_view>(&self, view_id: T) -> FlowyResult<()> { let view_id = view_id.as_ref(); let database_info = self.database_ref_indexer.get_database_with_view(view_id)?; @@ -149,7 +148,7 @@ impl DatabaseManager { let mut should_remove_editor = false; if let Some(database_editor) = self - .database_editors + .editors_by_database_id .write() .await .get(&database_info.database_id) @@ -162,8 +161,9 @@ impl DatabaseManager { } if should_remove_editor { + tracing::debug!("Close database base editor: {}", database_info.database_id); self - .database_editors + .editors_by_database_id .write() .await .remove(&database_info.database_id); @@ -173,15 +173,19 @@ impl DatabaseManager { // #[tracing::instrument(level = "debug", skip(self), err)] pub async fn get_database_editor(&self, view_id: &str) -> FlowyResult> { - let read_guard = self.database_editors.read().await; - let editor = read_guard.get(view_id); - match editor { + let database_info = self.database_ref_indexer.get_database_with_view(view_id)?; + let database_editor = self + .editors_by_database_id + .read() + .await + .get(&database_info.database_id) + .cloned(); + match database_editor { None => { // Drop the read_guard ASAP in case of the following read/write lock - drop(read_guard); self.open_database_view(view_id).await }, - Some(editor) => Ok(editor.clone()), + Some(editor) => Ok(editor), } } @@ -200,7 +204,7 @@ impl DatabaseManager { database_id: &str, view_id: &str, ) -> FlowyResult> { - if let Some(database_editor) = self.database_editors.read().await.get(database_id) { + if let Some(database_editor) = self.editors_by_database_id.read().await.get(database_id) { let user_id = self.database_user.user_id()?; let (view_pad, view_rev_manager) = make_database_view_revision_pad(view_id, self.database_user.clone()).await?; @@ -217,10 +221,10 @@ impl DatabaseManager { return Ok(database_editor.clone()); } // Lock the database_editors - let mut database_editors = self.database_editors.write().await; + let mut editors_by_database_id = self.editors_by_database_id.write().await; let db_pool = self.database_user.db_pool()?; let editor = self.make_database_rev_editor(view_id, db_pool).await?; - database_editors.insert(database_id.to_string(), editor.clone()); + editors_by_database_id.insert(database_id.to_string(), editor.clone()); Ok(editor) } @@ -236,7 +240,7 @@ impl DatabaseManager { make_database_view_revision_pad(view_id, user.clone()).await?; let mut database_id = base_view_pad.database_id.clone(); - tracing::debug!("Open database:{}", database_id); + tracing::debug!("Open database: {}", database_id); if database_id.is_empty() { // Before the database_id concept comes up, we used the view_id directly. So if // the database_id is empty, which means we can used the view_id. After the version 0.1.1, diff --git a/frontend/rust-lib/flowy-database/src/services/database/block_editor.rs b/frontend/rust-lib/flowy-database/src/services/database/block_editor.rs index dafc43047c..ffcadf1e2f 100644 --- a/frontend/rust-lib/flowy-database/src/services/database/block_editor.rs +++ b/frontend/rust-lib/flowy-database/src/services/database/block_editor.rs @@ -129,15 +129,14 @@ impl DatabaseBlockEditor { if let Ok(pad) = self.pad.try_read() { Ok(pad.get_row_rev(row_id)) } else { - tracing::error!("Required grid block read lock failed, retrying"); let retry = GetRowDataRetryAction { row_id: row_id.to_owned(), pad: self.pad.clone(), }; match spawn_retry(3, 300, retry).await { Ok(value) => Ok(value), - Err(err) => { - tracing::error!("Read row revision failed with: {}", err); + Err(_) => { + tracing::error!("Required database block read lock failed"); Ok(None) }, } diff --git a/frontend/rust-lib/flowy-database/src/services/database/database_editor.rs b/frontend/rust-lib/flowy-database/src/services/database/database_editor.rs index 09fcfe6e24..f497051afb 100644 --- a/frontend/rust-lib/flowy-database/src/services/database/database_editor.rs +++ b/frontend/rust-lib/flowy-database/src/services/database/database_editor.rs @@ -116,7 +116,7 @@ impl DatabaseEditor { self.database_views.open(view_editor).await } - #[tracing::instrument(name = "close database editor view", level = "trace", skip_all)] + #[tracing::instrument(name = "Close database editor view", level = "debug", skip_all)] pub async fn close_view_editor(&self, view_id: &str) { self.rev_manager.generate_snapshot().await; self.database_views.close(view_id).await; @@ -175,7 +175,7 @@ impl DatabaseEditor { self .database_views - .did_update_view_field_type_option(view_id, field_id, old_field_rev) + .did_update_field_type_option(view_id, field_id, old_field_rev) .await?; self.notify_did_update_database_field(field_id).await?; Ok(()) @@ -275,7 +275,7 @@ impl DatabaseEditor { if is_changed { match self .database_views - .did_update_view_field_type_option(view_id, field_id, old_field_rev) + .did_update_field_type_option(view_id, field_id, old_field_rev) .await { Ok(_) => {}, @@ -600,7 +600,7 @@ impl DatabaseEditor { field_id: &str, ) -> FlowyResult> { let view_editor = self.database_views.get_view_editor(view_id).await?; - view_editor.get_cells_for_field(field_id).await + view_editor.v_get_cells_for_field(field_id).await } #[tracing::instrument(level = "trace", skip_all, err)] diff --git a/frontend/rust-lib/flowy-database/src/services/database_view/editor.rs b/frontend/rust-lib/flowy-database/src/services/database_view/editor.rs index 400d768a98..3454290ce4 100644 --- a/frontend/rust-lib/flowy-database/src/services/database_view/editor.rs +++ b/frontend/rust-lib/flowy-database/src/services/database_view/editor.rs @@ -222,20 +222,20 @@ impl DatabaseViewEditor { .send(); } - pub async fn sort_rows(&self, rows: &mut Vec>) { + pub async fn v_sort_rows(&self, rows: &mut Vec>) { self.sort_controller.write().await.sort_rows(rows).await } - pub async fn filter_rows(&self, _block_id: &str, rows: &mut Vec>) { + pub async fn v_filter_rows(&self, _block_id: &str, rows: &mut Vec>) { self.filter_controller.filter_row_revs(rows).await; } - pub async fn duplicate_view_data(&self) -> FlowyResult { + pub async fn v_duplicate_data(&self) -> FlowyResult { let json_str = self.pad.read().await.json_str()?; Ok(json_str) } - pub async fn will_create_view_row(&self, row_rev: &mut RowRevision, params: &CreateRowParams) { + pub async fn v_will_create_row(&self, row_rev: &mut RowRevision, params: &CreateRowParams) { if params.group_id.is_none() { return; } @@ -248,7 +248,7 @@ impl DatabaseViewEditor { .await; } - pub async fn did_create_view_row(&self, row_pb: &RowPB, params: &CreateRowParams) { + pub async fn v_did_create_row(&self, row_pb: &RowPB, params: &CreateRowParams) { // Send the group notification if the current view has groups match params.group_id.as_ref() { None => {}, @@ -275,7 +275,7 @@ impl DatabaseViewEditor { } #[tracing::instrument(level = "trace", skip_all)] - pub async fn did_delete_view_row(&self, row_rev: &RowRevision) { + pub async fn v_did_delete_row(&self, row_rev: &RowRevision) { // Send the group notification if the current view has groups; let result = self .mut_group_controller(|group_controller, field_rev| { @@ -291,7 +291,7 @@ impl DatabaseViewEditor { } } - pub async fn did_update_view_row( + pub async fn v_did_update_row( &self, old_row_rev: Option>, row_rev: &RowRevision, @@ -339,7 +339,7 @@ impl DatabaseViewEditor { }); } - pub async fn move_view_group_row( + pub async fn v_move_group_row( &self, row_rev: &RowRevision, row_changeset: &mut RowChangeset, @@ -377,7 +377,7 @@ impl DatabaseViewEditor { } /// Only call once after grid view editor initialized #[tracing::instrument(level = "trace", skip(self))] - pub async fn load_view_groups(&self) -> FlowyResult> { + pub async fn v_load_groups(&self) -> FlowyResult> { let groups = self .group_controller .read() @@ -391,7 +391,7 @@ impl DatabaseViewEditor { } #[tracing::instrument(level = "trace", skip(self), err)] - pub async fn move_view_group(&self, params: MoveGroupParams) -> FlowyResult<()> { + pub async fn v_move_group(&self, params: MoveGroupParams) -> FlowyResult<()> { self .group_controller .write() @@ -430,7 +430,7 @@ impl DatabaseViewEditor { /// Initialize new group when grouping by a new field /// - pub async fn initialize_new_group(&self, params: InsertGroupParams) -> FlowyResult<()> { + pub async fn v_initialize_new_group(&self, params: InsertGroupParams) -> FlowyResult<()> { if let Some(field_rev) = self.delegate.get_field_rev(¶ms.field_id).await { self .modify(|pad| { @@ -445,13 +445,13 @@ impl DatabaseViewEditor { .await?; } if self.group_controller.read().await.field_id() != params.field_id { - self.group_by_view_field(¶ms.field_id).await?; + self.v_update_group_setting(¶ms.field_id).await?; self.notify_did_update_setting().await; } Ok(()) } - pub async fn delete_view_group(&self, params: DeleteGroupParams) -> FlowyResult<()> { + pub async fn v_delete_group(&self, params: DeleteGroupParams) -> FlowyResult<()> { self .modify(|pad| { let changeset = @@ -461,18 +461,18 @@ impl DatabaseViewEditor { .await } - pub async fn get_view_setting(&self) -> DatabaseViewSettingPB { + pub async fn v_get_setting(&self) -> DatabaseViewSettingPB { let field_revs = self.delegate.get_field_revs(None).await; make_database_view_setting(&*self.pad.read().await, &field_revs) } - pub async fn get_all_view_sorts(&self) -> Vec> { + pub async fn v_get_all_sorts(&self) -> Vec> { let field_revs = self.delegate.get_field_revs(None).await; self.pad.read().await.get_all_sorts(&field_revs) } #[tracing::instrument(level = "trace", skip(self), err)] - pub async fn insert_view_sort(&self, params: AlterSortParams) -> FlowyResult { + pub async fn v_insert_sort(&self, params: AlterSortParams) -> FlowyResult { let sort_type = SortType::from(¶ms); let is_exist = params.sort_id.is_some(); let sort_id = match params.sort_id { @@ -514,7 +514,7 @@ impl DatabaseViewEditor { Ok(sort_rev) } - pub async fn delete_view_sort(&self, params: DeleteSortParams) -> FlowyResult<()> { + pub async fn v_delete_sort(&self, params: DeleteSortParams) -> FlowyResult<()> { let notification = self .sort_controller .write() @@ -537,8 +537,8 @@ impl DatabaseViewEditor { Ok(()) } - pub async fn delete_all_view_sorts(&self) -> FlowyResult<()> { - let all_sorts = self.get_all_view_sorts().await; + pub async fn v_delete_all_sorts(&self) -> FlowyResult<()> { + let all_sorts = self.v_get_all_sorts().await; self.sort_controller.write().await.delete_all_sorts().await; self .modify(|pad| { @@ -556,12 +556,12 @@ impl DatabaseViewEditor { Ok(()) } - pub async fn get_all_view_filters(&self) -> Vec> { + pub async fn v_get_all_filters(&self) -> Vec> { let field_revs = self.delegate.get_field_revs(None).await; self.pad.read().await.get_all_filters(&field_revs) } - pub async fn get_view_filters(&self, filter_type: &FilterType) -> Vec> { + pub async fn v_get_filters(&self, filter_type: &FilterType) -> Vec> { let field_type_rev: FieldTypeRevision = filter_type.field_type.clone().into(); self .pad @@ -571,7 +571,7 @@ impl DatabaseViewEditor { } #[tracing::instrument(level = "trace", skip(self), err)] - pub async fn insert_view_filter(&self, params: AlterFilterParams) -> FlowyResult<()> { + pub async fn v_insert_filter(&self, params: AlterFilterParams) -> FlowyResult<()> { let filter_type = FilterType::from(¶ms); let is_exist = params.filter_id.is_some(); let filter_id = match params.filter_id { @@ -624,7 +624,7 @@ impl DatabaseViewEditor { } #[tracing::instrument(level = "trace", skip(self), err)] - pub async fn delete_view_filter(&self, params: DeleteFilterParams) -> FlowyResult<()> { + pub async fn v_delete_filter(&self, params: DeleteFilterParams) -> FlowyResult<()> { let filter_type = params.filter_type; let changeset = self .filter_controller @@ -649,7 +649,7 @@ impl DatabaseViewEditor { } /// Returns the current calendar settings - pub async fn get_calendar_settings(&self) -> FlowyResult { + pub async fn v_get_calendar_settings(&self) -> FlowyResult { let settings = self .pad .read() @@ -660,7 +660,10 @@ impl DatabaseViewEditor { } /// Update the calendar settings and send the notification to refresh the UI - pub async fn update_calendar_settings(&self, params: CalendarSettingsParams) -> FlowyResult<()> { + pub async fn v_update_calendar_settings( + &self, + params: CalendarSettingsParams, + ) -> FlowyResult<()> { // Maybe it needs no send notification to refresh the UI self .modify(|pad| Ok(pad.update_layout_setting(&LayoutRevision::Calendar, ¶ms)?)) @@ -669,7 +672,7 @@ impl DatabaseViewEditor { } #[tracing::instrument(level = "trace", skip_all, err)] - pub async fn did_update_view_field_type_option( + pub async fn v_did_update_field_type_option( &self, field_id: &str, old_field_rev: Option>, @@ -709,7 +712,7 @@ impl DatabaseViewEditor { /// * `field_id`: /// #[tracing::instrument(level = "debug", skip_all, err)] - pub async fn group_by_view_field(&self, field_id: &str) -> FlowyResult<()> { + pub async fn v_update_group_setting(&self, field_id: &str) -> FlowyResult<()> { if let Some(field_rev) = self.delegate.get_field_rev(field_id).await { let row_revs = self.delegate.get_row_revs(None).await; let configuration_reader = GroupConfigurationReaderImpl { @@ -750,7 +753,7 @@ impl DatabaseViewEditor { Ok(()) } - pub(crate) async fn get_cells_for_field( + pub(crate) async fn v_get_cells_for_field( &self, field_id: &str, ) -> FlowyResult> { @@ -758,7 +761,7 @@ impl DatabaseViewEditor { } async fn notify_did_update_setting(&self) { - let setting = self.get_view_setting().await; + let setting = self.v_get_setting().await; send_notification(&self.view_id, DatabaseNotification::DidUpdateSettings) .payload(setting) .send(); diff --git a/frontend/rust-lib/flowy-database/src/services/database_view/editor_manager.rs b/frontend/rust-lib/flowy-database/src/services/database_view/editor_manager.rs index ac7745d06e..854d94f676 100644 --- a/frontend/rust-lib/flowy-database/src/services/database_view/editor_manager.rs +++ b/frontend/rust-lib/flowy-database/src/services/database_view/editor_manager.rs @@ -84,8 +84,8 @@ impl DatabaseViews { .get_row_revs(Some(vec![block_id.to_owned()])) .await; if let Ok(view_editor) = self.get_view_editor(view_id).await { - view_editor.filter_rows(block_id, &mut row_revs).await; - view_editor.sort_rows(&mut row_revs).await; + view_editor.v_filter_rows(block_id, &mut row_revs).await; + view_editor.v_sort_rows(&mut row_revs).await; } Ok(row_revs) @@ -93,21 +93,21 @@ impl DatabaseViews { pub async fn duplicate_database_view(&self, view_id: &str) -> FlowyResult { let editor = self.get_view_editor(view_id).await?; - let view_data = editor.duplicate_view_data().await?; + let view_data = editor.v_duplicate_data().await?; Ok(view_data) } /// When the row was created, we may need to modify the [RowRevision] according to the [CreateRowParams]. pub async fn will_create_row(&self, row_rev: &mut RowRevision, params: &CreateRowParams) { for view_editor in self.view_editors.read().await.values() { - view_editor.will_create_view_row(row_rev, params).await; + view_editor.v_will_create_row(row_rev, params).await; } } /// Notify the view that the row was created. For the moment, the view is just sending notifications. pub async fn did_create_row(&self, row_pb: &RowPB, params: &CreateRowParams) { for view_editor in self.view_editors.read().await.values() { - view_editor.did_create_view_row(row_pb, params).await; + view_editor.v_did_create_row(row_pb, params).await; } } @@ -120,7 +120,7 @@ impl DatabaseViews { Some((_, row_rev)) => { for view_editor in self.view_editors.read().await.values() { view_editor - .did_update_view_row(old_row_rev.clone(), &row_rev) + .v_did_update_row(old_row_rev.clone(), &row_rev) .await; } }, @@ -129,24 +129,24 @@ impl DatabaseViews { pub async fn group_by_field(&self, view_id: &str, field_id: &str) -> FlowyResult<()> { let view_editor = self.get_view_editor(view_id).await?; - view_editor.group_by_view_field(field_id).await?; + view_editor.v_update_group_setting(field_id).await?; Ok(()) } pub async fn did_delete_row(&self, row_rev: Arc) { for view_editor in self.view_editors.read().await.values() { - view_editor.did_delete_view_row(&row_rev).await; + view_editor.v_did_delete_row(&row_rev).await; } } pub async fn get_setting(&self, view_id: &str) -> FlowyResult { let view_editor = self.get_view_editor(view_id).await?; - Ok(view_editor.get_view_setting().await) + Ok(view_editor.v_get_setting().await) } pub async fn get_all_filters(&self, view_id: &str) -> FlowyResult>> { let view_editor = self.get_view_editor(view_id).await?; - Ok(view_editor.get_all_view_filters().await) + Ok(view_editor.v_get_all_filters().await) } pub async fn get_filters( @@ -155,58 +155,58 @@ impl DatabaseViews { filter_id: &FilterType, ) -> FlowyResult>> { let view_editor = self.get_view_editor(view_id).await?; - Ok(view_editor.get_view_filters(filter_id).await) + Ok(view_editor.v_get_filters(filter_id).await) } pub async fn create_or_update_filter(&self, params: AlterFilterParams) -> FlowyResult<()> { let view_editor = self.get_view_editor(¶ms.view_id).await?; - view_editor.insert_view_filter(params).await + view_editor.v_insert_filter(params).await } pub async fn delete_filter(&self, params: DeleteFilterParams) -> FlowyResult<()> { let view_editor = self.get_view_editor(¶ms.view_id).await?; - view_editor.delete_view_filter(params).await + view_editor.v_delete_filter(params).await } pub async fn get_all_sorts(&self, view_id: &str) -> FlowyResult>> { let view_editor = self.get_view_editor(view_id).await?; - Ok(view_editor.get_all_view_sorts().await) + Ok(view_editor.v_get_all_sorts().await) } pub async fn create_or_update_sort(&self, params: AlterSortParams) -> FlowyResult { let view_editor = self.get_view_editor(¶ms.view_id).await?; - view_editor.insert_view_sort(params).await + view_editor.v_insert_sort(params).await } pub async fn delete_all_sorts(&self, view_id: &str) -> FlowyResult<()> { let view_editor = self.get_view_editor(view_id).await?; - view_editor.delete_all_view_sorts().await + view_editor.v_delete_all_sorts().await } pub async fn delete_sort(&self, params: DeleteSortParams) -> FlowyResult<()> { let view_editor = self.get_view_editor(¶ms.view_id).await?; - view_editor.delete_view_sort(params).await + view_editor.v_delete_sort(params).await } pub async fn load_groups(&self, view_id: &str) -> FlowyResult { let view_editor = self.get_view_editor(view_id).await?; - let groups = view_editor.load_view_groups().await?; + let groups = view_editor.v_load_groups().await?; Ok(RepeatedGroupPB { items: groups }) } pub async fn insert_or_update_group(&self, params: InsertGroupParams) -> FlowyResult<()> { let view_editor = self.get_view_editor(¶ms.view_id).await?; - view_editor.initialize_new_group(params).await + view_editor.v_initialize_new_group(params).await } pub async fn delete_group(&self, params: DeleteGroupParams) -> FlowyResult<()> { let view_editor = self.get_view_editor(¶ms.view_id).await?; - view_editor.delete_view_group(params).await + view_editor.v_delete_group(params).await } pub async fn move_group(&self, params: MoveGroupParams) -> FlowyResult<()> { let view_editor = self.get_view_editor(¶ms.view_id).await?; - view_editor.move_view_group(params).await?; + view_editor.v_move_group(params).await?; Ok(()) } @@ -224,7 +224,7 @@ impl DatabaseViews { let mut row_changeset = RowChangeset::new(row_rev.id.clone()); let view_editor = self.get_view_editor(view_id).await?; view_editor - .move_view_group_row( + .v_move_group_row( &row_rev, &mut row_changeset, &to_group_id, @@ -246,20 +246,22 @@ impl DatabaseViews { /// /// * `field_id`: the id of the field in current view /// - #[tracing::instrument(level = "trace", skip(self), err)] - pub async fn did_update_view_field_type_option( + #[tracing::instrument(level = "debug", skip(self, old_field_rev), err)] + pub async fn did_update_field_type_option( &self, view_id: &str, field_id: &str, old_field_rev: Option>, ) -> FlowyResult<()> { let view_editor = self.get_view_editor(view_id).await?; + // If the id of the grouping field is equal to the updated field's id, then we need to + // update the group setting if view_editor.group_id().await == field_id { - view_editor.group_by_view_field(field_id).await?; + view_editor.v_update_group_setting(field_id).await?; } view_editor - .did_update_view_field_type_option(field_id, old_field_rev) + .v_did_update_field_type_option(field_id, old_field_rev) .await?; Ok(()) } @@ -269,6 +271,7 @@ impl DatabaseViews { if let Some(editor) = self.view_editors.read().await.get(view_id) { return Ok(editor); } + tracing::trace!("{:p} create view:{} editor", self, view_id); let mut view_editors = self.view_editors.write().await; let editor = Arc::new(self.make_view_editor(view_id).await?); diff --git a/frontend/rust-lib/flowy-database/src/services/group/group_util.rs b/frontend/rust-lib/flowy-database/src/services/group/group_util.rs index 9caa39a70b..98197ad394 100644 --- a/frontend/rust-lib/flowy-database/src/services/group/group_util.rs +++ b/frontend/rust-lib/flowy-database/src/services/group/group_util.rs @@ -26,7 +26,17 @@ use std::sync::Arc; /// * `configuration_reader`: a reader used to read the group configuration from disk /// * `configuration_writer`: as writer used to write the group configuration to disk /// -#[tracing::instrument(level = "trace", skip_all, err)] +#[tracing::instrument( + level = "debug", + skip( + row_revs, + configuration_reader, + configuration_writer, + grouping_field_rev + ), + fields(grouping_field_id=%grouping_field_rev.id, grouping_field_type) + err +)] pub async fn make_group_controller( view_id: String, grouping_field_rev: Arc, @@ -39,6 +49,7 @@ where W: GroupConfigurationWriter, { let grouping_field_type: FieldType = grouping_field_rev.ty.into(); + tracing::Span::current().record("grouping_field_type", &format!("{}", grouping_field_type)); let mut group_controller: Box; let configuration_reader = Arc::new(configuration_reader); @@ -99,17 +110,31 @@ where Ok(group_controller) } +#[tracing::instrument(level = "debug", skip_all)] pub fn find_grouping_field( field_revs: &[Arc], _layout: &LayoutRevision, ) -> Option> { - field_revs + let mut groupable_field_revs = field_revs .iter() - .find(|field_rev| { + .flat_map(|field_rev| { let field_type: FieldType = field_rev.ty.into(); - field_type.can_be_group() + match field_type.can_be_group() { + true => Some(field_rev.clone()), + false => None, + } }) - .cloned() + .collect::>>(); + + if groupable_field_revs.is_empty() { + // If there is not groupable fields then we use the primary field. + field_revs + .iter() + .find(|field_rev| field_rev.is_primary) + .cloned() + } else { + Some(groupable_field_revs.remove(0)) + } } /// Returns a `default` group configuration for the [FieldRevision] diff --git a/frontend/rust-lib/flowy-sqlite/src/schema.rs b/frontend/rust-lib/flowy-sqlite/src/schema.rs index 643c6cabd6..5b70cf9164 100644 --- a/frontend/rust-lib/flowy-sqlite/src/schema.rs +++ b/frontend/rust-lib/flowy-sqlite/src/schema.rs @@ -189,21 +189,21 @@ diesel::table! { } diesel::allow_tables_to_appear_in_same_query!( - app_table, - database_refs, - document_rev_snapshot, - document_rev_table, - folder_rev_snapshot, - grid_block_index_table, - grid_meta_rev_table, - grid_rev_snapshot, - grid_rev_table, - grid_view_rev_table, - kv_table, - rev_snapshot, - rev_table, - trash_table, - user_table, - view_table, - workspace_table, + app_table, + database_refs, + document_rev_snapshot, + document_rev_table, + folder_rev_snapshot, + grid_block_index_table, + grid_meta_rev_table, + grid_rev_snapshot, + grid_rev_table, + grid_view_rev_table, + kv_table, + rev_snapshot, + rev_table, + trash_table, + user_table, + view_table, + workspace_table, ); diff --git a/frontend/scripts/makefile/desktop.toml b/frontend/scripts/makefile/desktop.toml index e4bc71b7b3..0d94d2d549 100644 --- a/frontend/scripts/makefile/desktop.toml +++ b/frontend/scripts/makefile/desktop.toml @@ -189,22 +189,35 @@ script = [ ] script_runner = "@duckscript" -[tasks.build-test-lib] +[tasks.build_test_backend] category = "Build" dependencies = ["env_check"] run_task = { name = [ "setup-test-crate-type", - "build-test-backend", + "compile_test_backend", "copy-to-sandbox-folder", "restore-test-crate-type", ] } -[tasks.build-test-backend] -mac_alias = "build-test-backend-default" -windows_alias = "build-test-backend-widnows" -linux_alias = "build-test-backend-default" +[tasks.compile_test_backend] +mac_alias = "compile_test_backend_default" +windows_alias = "compile_test_backend_widnows" +linux_alias = "compile_test_backend_default" -[tasks.build-test-backend-default] +[tasks.compile_test_backend_default] +private = true +script = [ + """ + cd rust-lib/ + rustup show + echo RUST_LOG=${RUST_LOG} cargo build --package=dart-ffi --target ${TEST_COMPILE_TARGET} --features "${FLUTTER_DESKTOP_FEATURES}" + RUST_LOG=${RUST_LOG} cargo build --package=dart-ffi --target ${TEST_COMPILE_TARGET} --features "${FLUTTER_DESKTOP_FEATURES}" + cd ../ + """, +] +script_runner = "@shell" + +[tasks.compile_test_backend_widnows] private = true script = [ """ @@ -217,19 +230,6 @@ script = [ ] script_runner = "@shell" -[tasks.build-test-backend-widnows] -private = true -script = [ - """ - cd rust-lib/ - rustup show - echo cargo build --package=dart-ffi --target ${TEST_COMPILE_TARGET} --features "${FLUTTER_DESKTOP_FEATURES}" - RUST_LOG=${TEST_RUST_LOG} cargo build --package=dart-ffi --target ${TEST_COMPILE_TARGET} --features "${FLUTTER_DESKTOP_FEATURES}" - cd ../ - """, -] -script_runner = "@shell" - [tasks.copy-to-sandbox-folder] mac_alias = "copy-to-sandbox-folder-default" windows_alias = "copy-to-sandbox-folder-windows" diff --git a/frontend/scripts/makefile/tests.toml b/frontend/scripts/makefile/tests.toml index e0d913f8c3..146ee481b0 100644 --- a/frontend/scripts/makefile/tests.toml +++ b/frontend/scripts/makefile/tests.toml @@ -1,29 +1,29 @@ [tasks.dart_unit_test] script = ''' -cargo make --profile test-macos dart_unit_test_inner +cargo make --profile test-macos dart_unit_test_impl ''' script_runner = "@shell" [tasks.dart_unit_test.windows] script = ''' -cargo make --profile test-windows dart_unit_test_inner +cargo make --profile test-windows dart_unit_test_impl ''' script_runner = "@shell" [tasks.dart_unit_test.linux] script = ''' -cargo make --profile test-linux dart_unit_test_inner +cargo make --profile test-linux dart_unit_test_impl ''' script_runner = "@shell" -[tasks.dart_unit_test_inner] -env = { RUST_LOG = "info", TEST_RUST_LOG = "info" } -dependencies = ["build-test-lib"] +[tasks.dart_unit_test_impl] +env = { RUST_LOG = "info" } +dependencies = ["build_test_backend"] description = "Run flutter unit tests" script = ''' cd appflowy_flutter -flutter test --dart-define=RUST_LOG=${TEST_RUST_LOG} -j, --concurrency=1 +flutter test --dart-define=RUST_LOG=${RUST_LOG} -j, --concurrency=1 ''' [tasks.rust_unit_test] diff --git a/shared-lib/database-model/src/database_rev.rs b/shared-lib/database-model/src/database_rev.rs index 53211ceb6c..e92abf83a8 100644 --- a/shared-lib/database-model/src/database_rev.rs +++ b/shared-lib/database-model/src/database_rev.rs @@ -115,7 +115,7 @@ pub struct FieldRevision { #[serde(with = "indexmap::serde_seq")] pub type_options: IndexMap, - #[serde(default = "DEFAULT_IS_PRIMARY")] + #[serde(default = "DEFAULT_IS_PRIMARY_VALUE")] pub is_primary: bool, } @@ -125,7 +125,7 @@ impl AsRef for FieldRevision { } } -const DEFAULT_IS_PRIMARY: fn() -> bool = || false; +const DEFAULT_IS_PRIMARY_VALUE: fn() -> bool = || false; impl FieldRevision { pub fn new>(