浏览代码

fix: group with not support field test (#1890)

Nathan.fooo 2 年之前
父节点
当前提交
4a81fed6e4
共有 27 个文件被更改,包括 182 次插入148 次删除
  1. 2 2
      frontend/.vscode/launch.json
  2. 1 2
      frontend/Makefile.toml
  3. 1 1
      frontend/appflowy_flutter/lib/plugins/database_view/application/database_service.dart
  4. 1 1
      frontend/appflowy_flutter/lib/plugins/database_view/board/application/board_data_controller.dart
  5. 1 1
      frontend/appflowy_flutter/lib/plugins/database_view/calendar/application/calendar_data_controller.dart
  6. 1 1
      frontend/appflowy_flutter/lib/plugins/database_view/grid/application/grid_data_controller.dart
  7. 1 1
      frontend/appflowy_flutter/test/bloc_test/board_test/group_by_unsupport_field_test.dart
  8. 2 0
      frontend/appflowy_tauri/src-tauri/Cargo.lock
  9. 2 2
      frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/cell/backend_service.ts
  10. 1 1
      frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/cell/data_persistence.ts
  11. 1 1
      frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/field/backend_service.ts
  12. 4 4
      frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/row/cache.ts
  13. 6 6
      frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/view/row_observer.ts
  14. 0 1
      frontend/appflowy_tauri/src/appflowy_app/stores/effects/folder/app/backend_service.ts
  15. 4 4
      frontend/rust-lib/flowy-client-sync/src/client_database/database_revision_pad.rs
  16. 1 1
      frontend/rust-lib/flowy-database/src/entities/field_entities.rs
  17. 1 1
      frontend/rust-lib/flowy-database/src/event_handler.rs
  18. 19 15
      frontend/rust-lib/flowy-database/src/manager.rs
  19. 2 3
      frontend/rust-lib/flowy-database/src/services/database/block_editor.rs
  20. 4 4
      frontend/rust-lib/flowy-database/src/services/database/database_editor.rs
  21. 32 29
      frontend/rust-lib/flowy-database/src/services/database_view/editor.rs
  22. 29 26
      frontend/rust-lib/flowy-database/src/services/database_view/editor_manager.rs
  23. 30 5
      frontend/rust-lib/flowy-database/src/services/group/group_util.rs
  24. 17 17
      frontend/rust-lib/flowy-sqlite/src/schema.rs
  25. 10 10
      frontend/scripts/makefile/desktop.toml
  26. 7 7
      frontend/scripts/makefile/tests.toml
  27. 2 2
      shared-lib/database-model/src/database_rev.rs

+ 2 - 2
frontend/.vscode/launch.json

@@ -12,8 +12,8 @@
             "type": "dart",
             "type": "dart",
             "preLaunchTask": "AF: Build Appflowy Core",
             "preLaunchTask": "AF: Build Appflowy Core",
             "env": {
             "env": {
-                "RUST_LOG": "trace",
-                // "RUST_LOG": "debug"
+                // "RUST_LOG": "trace",
+                "RUST_LOG": "debug"
             },
             },
             "cwd": "${workspaceRoot}/appflowy_flutter"
             "cwd": "${workspaceRoot}/appflowy_flutter"
         },
         },

+ 1 - 2
frontend/Makefile.toml

@@ -18,7 +18,7 @@ on_error_task = "catch"
 run_task = { name = ["restore-crate-type"] }
 run_task = { name = ["restore-crate-type"] }
 
 
 [env]
 [env]
-RUST_LOG = "debug"
+RUST_LOG = "info"
 CARGO_MAKE_EXTEND_WORKSPACE_MAKEFILE = true
 CARGO_MAKE_EXTEND_WORKSPACE_MAKEFILE = true
 CARGO_MAKE_CRATE_FS_NAME = "dart_ffi"
 CARGO_MAKE_CRATE_FS_NAME = "dart_ffi"
 CARGO_MAKE_CRATE_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 default config
 TEST_CRATE_TYPE = "cdylib"
 TEST_CRATE_TYPE = "cdylib"
 TEST_LIB_EXT = "dylib"
 TEST_LIB_EXT = "dylib"
-TEST_RUST_LOG = "info"
 TEST_BUILD_FLAG = "debug"
 TEST_BUILD_FLAG = "debug"
 TEST_COMPILE_TARGET = "x86_64-apple-darwin"
 TEST_COMPILE_TARGET = "x86_64-apple-darwin"
 
 

+ 1 - 1
frontend/appflowy_flutter/lib/plugins/database_view/application/database_service.dart

@@ -53,7 +53,7 @@ class DatabaseBackendService {
     });
     });
   }
   }
 
 
-  Future<Either<Unit, FlowyError>> closeGrid() {
+  Future<Either<Unit, FlowyError>> closeView() {
     final request = ViewIdPB(value: viewId);
     final request = ViewIdPB(value: viewId);
     return FolderEventCloseView(request).send();
     return FolderEventCloseView(request).send();
   }
   }

+ 1 - 1
frontend/appflowy_flutter/lib/plugins/database_view/board/application/board_data_controller.dart

@@ -126,7 +126,7 @@ class BoardDataController {
 
 
   Future<void> dispose() async {
   Future<void> dispose() async {
     await _viewCache.dispose();
     await _viewCache.dispose();
-    await _databaseFFIService.closeGrid();
+    await _databaseFFIService.closeView();
     await fieldController.dispose();
     await fieldController.dispose();
   }
   }
 
 

+ 1 - 1
frontend/appflowy_flutter/lib/plugins/database_view/calendar/application/calendar_data_controller.dart

@@ -109,7 +109,7 @@ class CalendarDataController {
 
 
   Future<void> dispose() async {
   Future<void> dispose() async {
     await _viewCache.dispose();
     await _viewCache.dispose();
-    await _databaseBackendSvc.closeGrid();
+    await _databaseBackendSvc.closeView();
     await fieldController.dispose();
     await fieldController.dispose();
   }
   }
 }
 }

+ 1 - 1
frontend/appflowy_flutter/lib/plugins/database_view/grid/application/grid_data_controller.dart

@@ -77,7 +77,7 @@ class DatabaseController {
   }
   }
 
 
   Future<void> dispose() async {
   Future<void> dispose() async {
-    await _databaseBackendSvc.closeGrid();
+    await _databaseBackendSvc.closeView();
     await fieldController.dispose();
     await fieldController.dispose();
   }
   }
 }
 }

+ 1 - 1
frontend/appflowy_flutter/test/bloc_test/board_test/group_by_unsupport_field_test.dart

@@ -22,7 +22,7 @@ void main() {
     await boardResponseFuture();
     await boardResponseFuture();
   });
   });
 
 
-  group('Group with not support grouping field:', () {
+  group('Group with not support grouping field', () {
     blocTest<FieldEditorBloc, FieldEditorState>(
     blocTest<FieldEditorBloc, FieldEditorState>(
       "switch to text field",
       "switch to text field",
       build: () => editorBloc,
       build: () => editorBloc,

+ 2 - 0
frontend/appflowy_tauri/src-tauri/Cargo.lock

@@ -1225,6 +1225,8 @@ dependencies = [
  "lib-ws",
  "lib-ws",
  "parking_lot",
  "parking_lot",
  "revision-model",
  "revision-model",
+ "serde",
+ "serde_json",
  "tokio",
  "tokio",
  "tracing",
  "tracing",
  "user-model",
  "user-model",

+ 2 - 2
frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/cell/backend_service.ts

@@ -14,7 +14,7 @@ class CellIdentifier {
 class CellBackendService {
 class CellBackendService {
   static updateCell = async (cellId: CellIdentifier, data: string) => {
   static updateCell = async (cellId: CellIdentifier, data: string) => {
     const payload = CellChangesetPB.fromObject({
     const payload = CellChangesetPB.fromObject({
-      database_id: cellId.viewId,
+      view_id: cellId.viewId,
       field_id: cellId.fieldId,
       field_id: cellId.fieldId,
       row_id: cellId.rowId,
       row_id: cellId.rowId,
       type_cell_data: data,
       type_cell_data: data,
@@ -24,7 +24,7 @@ class CellBackendService {
 
 
   getCell = async (cellId: CellIdentifier) => {
   getCell = async (cellId: CellIdentifier) => {
     const payload = CellIdPB.fromObject({
     const payload = CellIdPB.fromObject({
-      database_id: cellId.viewId,
+      view_id: cellId.viewId,
       field_id: cellId.fieldId,
       field_id: cellId.fieldId,
       row_id: cellId.rowId,
       row_id: cellId.rowId,
     });
     });

+ 1 - 1
frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/cell/data_persistence.ts

@@ -39,7 +39,7 @@ export class DateCellDataPersistence extends CellDataPersistence<CalendarData> {
 
 
 function _makeCellPath(cellIdentifier: CellIdentifier): CellIdPB {
 function _makeCellPath(cellIdentifier: CellIdentifier): CellIdPB {
   return CellIdPB.fromObject({
   return CellIdPB.fromObject({
-    database_id: cellIdentifier.viewId,
+    view_id: cellIdentifier.viewId,
     field_id: cellIdentifier.fieldId,
     field_id: cellIdentifier.fieldId,
     row_id: cellIdentifier.rowId,
     row_id: cellIdentifier.rowId,
   });
   });

+ 1 - 1
frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/field/backend_service.ts

@@ -28,7 +28,7 @@ export class FieldBackendService {
     visibility?: boolean;
     visibility?: boolean;
     width?: number;
     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) {
     if (data.name !== undefined) {
       payload.name = data.name;
       payload.name = data.name;

+ 4 - 4
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 { FieldInfo } from '../field/controller';
 import { CellCache, CellCacheKey } from '../cell/cache';
 import { CellCache, CellCacheKey } from '../cell/cache';
 import {
 import {
-  ViewRowsChangesetPB,
-  ViewRowsVisibilityChangesetPB,
+  RowsChangesetPB,
+  RowsVisibilityChangesetPB,
 } from '../../../../../services/backend/models/flowy-database/view_entities';
 } from '../../../../../services/backend/models/flowy-database/view_entities';
 import { CellIdentifier } from '../cell/backend_service';
 import { CellIdentifier } from '../cell/backend_service';
 import { ReorderSingleRowPB } from '../../../../../services/backend/models/flowy-database/sort_entities';
 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._deleteRows(changeset.deleted_rows);
     this._insertRows(changeset.inserted_rows);
     this._insertRows(changeset.inserted_rows);
     this._updateRows(changeset.updated_rows);
     this._updateRows(changeset.updated_rows);
   };
   };
 
 
-  applyRowsVisibility = (changeset: ViewRowsVisibilityChangesetPB) => {
+  applyRowsVisibility = (changeset: RowsVisibilityChangesetPB) => {
     this._hideRows(changeset.invisible_rows);
     this._hideRows(changeset.invisible_rows);
     this._displayRows(changeset.visible_rows);
     this._displayRows(changeset.visible_rows);
   };
   };

+ 6 - 6
frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/view/row_observer.ts

@@ -5,15 +5,15 @@ import {
   ReorderSingleRowPB,
   ReorderSingleRowPB,
 } from '../../../../../services/backend/events/flowy-database';
 } from '../../../../../services/backend/events/flowy-database';
 import {
 import {
-  ViewRowsChangesetPB,
-  ViewRowsVisibilityChangesetPB,
+  RowsChangesetPB,
+  RowsVisibilityChangesetPB,
 } from '../../../../../services/backend/models/flowy-database/view_entities';
 } from '../../../../../services/backend/models/flowy-database/view_entities';
 import { FlowyError } from '../../../../../services/backend/models/flowy-error/errors';
 import { FlowyError } from '../../../../../services/backend/models/flowy-error/errors';
 import { ChangeNotifier } from '../../../../utils/change_notifier';
 import { ChangeNotifier } from '../../../../utils/change_notifier';
 import { DatabaseNotificationObserver } from '../notifications/observer';
 import { DatabaseNotificationObserver } from '../notifications/observer';
 
 
-export type RowsVisibilityNotifyValue = Result<ViewRowsVisibilityChangesetPB, FlowyError>;
-export type RowsNotifyValue = Result<ViewRowsChangesetPB, FlowyError>;
+export type RowsVisibilityNotifyValue = Result<RowsVisibilityChangesetPB, FlowyError>;
+export type RowsNotifyValue = Result<RowsChangesetPB, FlowyError>;
 export type ReorderRowsNotifyValue = Result<string[], FlowyError>;
 export type ReorderRowsNotifyValue = Result<string[], FlowyError>;
 export type ReorderSingleRowNotifyValue = Result<ReorderSingleRowPB, FlowyError>;
 export type ReorderSingleRowNotifyValue = Result<ReorderSingleRowPB, FlowyError>;
 
 
@@ -43,10 +43,10 @@ export class DatabaseViewRowsObserver {
       parserHandler: (notification, payload) => {
       parserHandler: (notification, payload) => {
         switch (notification) {
         switch (notification) {
           case DatabaseNotification.DidUpdateViewRowsVisibility:
           case DatabaseNotification.DidUpdateViewRowsVisibility:
-            this._rowsVisibilityNotifier.notify(Ok(ViewRowsVisibilityChangesetPB.deserializeBinary(payload)));
+            this._rowsVisibilityNotifier.notify(Ok(RowsVisibilityChangesetPB.deserializeBinary(payload)));
             break;
             break;
           case DatabaseNotification.DidUpdateViewRows:
           case DatabaseNotification.DidUpdateViewRows:
-            this._rowsNotifier.notify(Ok(ViewRowsChangesetPB.deserializeBinary(payload)));
+            this._rowsNotifier.notify(Ok(RowsChangesetPB.deserializeBinary(payload)));
             break;
             break;
           case DatabaseNotification.DidReorderRows:
           case DatabaseNotification.DidReorderRows:
             this._reorderRowsNotifier.notify(Ok(ReorderAllRowsPB.deserializeBinary(payload).row_orders));
             this._reorderRowsNotifier.notify(Ok(ReorderAllRowsPB.deserializeBinary(payload).row_orders));

+ 0 - 1
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,
       belong_to_id: this.appId,
       name: params.name,
       name: params.name,
       desc: params.desc || '',
       desc: params.desc || '',
-      data_format: params.dataFormatType,
       layout: params.layoutType,
       layout: params.layoutType,
       initial_data: encoder.encode(params.initialData || ''),
       initial_data: encoder.encode(params.initialData || ''),
     });
     });

+ 4 - 4
frontend/rust-lib/flowy-client-sync/src/client_database/database_revision_pad.rs

@@ -109,18 +109,18 @@ impl DatabaseRevisionPad {
     &mut self,
     &mut self,
     field_id: &str,
     field_id: &str,
   ) -> SyncResult<Option<DatabaseRevisionChangeset>> {
   ) -> SyncResult<Option<DatabaseRevisionChangeset>> {
-    self.modify_database(|grid_meta| {
-      match grid_meta
+    self.modify_database(|database| {
+      match database
         .fields
         .fields
         .iter()
         .iter()
         .position(|field| field.id == field_id)
         .position(|field| field.id == field_id)
       {
       {
         None => Ok(None),
         None => Ok(None),
         Some(index) => {
         Some(index) => {
-          if grid_meta.fields[index].is_primary {
+          if database.fields[index].is_primary {
             Err(SyncError::can_not_delete_primary_field())
             Err(SyncError::can_not_delete_primary_field())
           } else {
           } else {
-            grid_meta.fields.remove(index);
+            database.fields.remove(index);
             Ok(Some(()))
             Ok(Some(()))
           }
           }
         },
         },

+ 1 - 1
frontend/rust-lib/flowy-database/src/entities/field_entities.rs

@@ -572,7 +572,7 @@ impl FieldType {
   }
   }
 
 
   pub fn can_be_group(&self) -> bool {
   pub fn can_be_group(&self) -> bool {
-    self.is_select_option() || self.is_checkbox()
+    self.is_select_option() || self.is_checkbox() || self.is_url()
   }
   }
 }
 }
 
 

+ 1 - 1
frontend/rust-lib/flowy-database/src/event_handler.rs

@@ -162,7 +162,7 @@ pub(crate) async fn delete_field_handler(
   Ok(())
   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(
 pub(crate) async fn switch_to_field_handler(
   data: AFPluginData<UpdateFieldTypePayloadPB>,
   data: AFPluginData<UpdateFieldTypePayloadPB>,
   manager: AFPluginState<Arc<DatabaseManager>>,
   manager: AFPluginState<Arc<DatabaseManager>>,

+ 19 - 15
frontend/rust-lib/flowy-database/src/manager.rs

@@ -40,7 +40,7 @@ pub trait DatabaseUser: Send + Sync {
 }
 }
 
 
 pub struct DatabaseManager {
 pub struct DatabaseManager {
-  database_editors: RwLock<HashMap<String, Arc<DatabaseEditor>>>,
+  editors_by_database_id: RwLock<HashMap<String, Arc<DatabaseEditor>>>,
   database_user: Arc<dyn DatabaseUser>,
   database_user: Arc<dyn DatabaseUser>,
   block_indexer: Arc<BlockRowIndexer>,
   block_indexer: Arc<BlockRowIndexer>,
   database_ref_indexer: Arc<DatabaseRefIndexer>,
   database_ref_indexer: Arc<DatabaseRefIndexer>,
@@ -58,7 +58,7 @@ impl DatabaseManager {
     task_scheduler: Arc<RwLock<TaskDispatcher>>,
     task_scheduler: Arc<RwLock<TaskDispatcher>>,
     database_db: Arc<dyn DatabaseDBConnection>,
     database_db: Arc<dyn DatabaseDBConnection>,
   ) -> Self {
   ) -> 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 kv_persistence = Arc::new(DatabaseKVPersistence::new(database_db.clone()));
     let block_indexer = Arc::new(BlockRowIndexer::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()));
     let database_ref_indexer = Arc::new(DatabaseRefIndexer::new(database_db.clone()));
@@ -68,7 +68,7 @@ impl DatabaseManager {
       database_ref_indexer.clone(),
       database_ref_indexer.clone(),
     );
     );
     Self {
     Self {
-      database_editors,
+      editors_by_database_id,
       database_user,
       database_user,
       kv_persistence,
       kv_persistence,
       block_indexer,
       block_indexer,
@@ -141,7 +141,6 @@ impl DatabaseManager {
       .await
       .await
   }
   }
 
 
-  #[tracing::instrument(level = "debug", skip_all, fields(view_id), err)]
   pub async fn close_database_view<T: AsRef<str>>(&self, view_id: T) -> FlowyResult<()> {
   pub async fn close_database_view<T: AsRef<str>>(&self, view_id: T) -> FlowyResult<()> {
     let view_id = view_id.as_ref();
     let view_id = view_id.as_ref();
     let database_info = self.database_ref_indexer.get_database_with_view(view_id)?;
     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;
     let mut should_remove_editor = false;
     if let Some(database_editor) = self
     if let Some(database_editor) = self
-      .database_editors
+      .editors_by_database_id
       .write()
       .write()
       .await
       .await
       .get(&database_info.database_id)
       .get(&database_info.database_id)
@@ -162,8 +161,9 @@ impl DatabaseManager {
     }
     }
 
 
     if should_remove_editor {
     if should_remove_editor {
+      tracing::debug!("Close database base editor: {}", database_info.database_id);
       self
       self
-        .database_editors
+        .editors_by_database_id
         .write()
         .write()
         .await
         .await
         .remove(&database_info.database_id);
         .remove(&database_info.database_id);
@@ -173,15 +173,19 @@ impl DatabaseManager {
 
 
   // #[tracing::instrument(level = "debug", skip(self), err)]
   // #[tracing::instrument(level = "debug", skip(self), err)]
   pub async fn get_database_editor(&self, view_id: &str) -> FlowyResult<Arc<DatabaseEditor>> {
   pub async fn get_database_editor(&self, view_id: &str) -> FlowyResult<Arc<DatabaseEditor>> {
-    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 => {
       None => {
         // Drop the read_guard ASAP in case of the following read/write lock
         // Drop the read_guard ASAP in case of the following read/write lock
-        drop(read_guard);
         self.open_database_view(view_id).await
         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,
     database_id: &str,
     view_id: &str,
     view_id: &str,
   ) -> FlowyResult<Arc<DatabaseEditor>> {
   ) -> FlowyResult<Arc<DatabaseEditor>> {
-    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 user_id = self.database_user.user_id()?;
       let (view_pad, view_rev_manager) =
       let (view_pad, view_rev_manager) =
         make_database_view_revision_pad(view_id, self.database_user.clone()).await?;
         make_database_view_revision_pad(view_id, self.database_user.clone()).await?;
@@ -217,10 +221,10 @@ impl DatabaseManager {
       return Ok(database_editor.clone());
       return Ok(database_editor.clone());
     }
     }
     // Lock the database_editors
     // 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 db_pool = self.database_user.db_pool()?;
     let editor = self.make_database_rev_editor(view_id, db_pool).await?;
     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)
     Ok(editor)
   }
   }
 
 
@@ -236,7 +240,7 @@ impl DatabaseManager {
       make_database_view_revision_pad(view_id, user.clone()).await?;
       make_database_view_revision_pad(view_id, user.clone()).await?;
     let mut database_id = base_view_pad.database_id.clone();
     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() {
     if database_id.is_empty() {
       // Before the database_id concept comes up, we used the view_id directly. So if
       // 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,
       // the database_id is empty, which means we can used the view_id. After the version 0.1.1,

+ 2 - 3
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() {
     if let Ok(pad) = self.pad.try_read() {
       Ok(pad.get_row_rev(row_id))
       Ok(pad.get_row_rev(row_id))
     } else {
     } else {
-      tracing::error!("Required grid block read lock failed, retrying");
       let retry = GetRowDataRetryAction {
       let retry = GetRowDataRetryAction {
         row_id: row_id.to_owned(),
         row_id: row_id.to_owned(),
         pad: self.pad.clone(),
         pad: self.pad.clone(),
       };
       };
       match spawn_retry(3, 300, retry).await {
       match spawn_retry(3, 300, retry).await {
         Ok(value) => Ok(value),
         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)
           Ok(None)
         },
         },
       }
       }

+ 4 - 4
frontend/rust-lib/flowy-database/src/services/database/database_editor.rs

@@ -116,7 +116,7 @@ impl DatabaseEditor {
     self.database_views.open(view_editor).await
     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) {
   pub async fn close_view_editor(&self, view_id: &str) {
     self.rev_manager.generate_snapshot().await;
     self.rev_manager.generate_snapshot().await;
     self.database_views.close(view_id).await;
     self.database_views.close(view_id).await;
@@ -175,7 +175,7 @@ impl DatabaseEditor {
 
 
     self
     self
       .database_views
       .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?;
       .await?;
     self.notify_did_update_database_field(field_id).await?;
     self.notify_did_update_database_field(field_id).await?;
     Ok(())
     Ok(())
@@ -275,7 +275,7 @@ impl DatabaseEditor {
     if is_changed {
     if is_changed {
       match self
       match self
         .database_views
         .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
         .await
       {
       {
         Ok(_) => {},
         Ok(_) => {},
@@ -600,7 +600,7 @@ impl DatabaseEditor {
     field_id: &str,
     field_id: &str,
   ) -> FlowyResult<Vec<RowSingleCellData>> {
   ) -> FlowyResult<Vec<RowSingleCellData>> {
     let view_editor = self.database_views.get_view_editor(view_id).await?;
     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)]
   #[tracing::instrument(level = "trace", skip_all, err)]

+ 32 - 29
frontend/rust-lib/flowy-database/src/services/database_view/editor.rs

@@ -222,20 +222,20 @@ impl DatabaseViewEditor {
       .send();
       .send();
   }
   }
 
 
-  pub async fn sort_rows(&self, rows: &mut Vec<Arc<RowRevision>>) {
+  pub async fn v_sort_rows(&self, rows: &mut Vec<Arc<RowRevision>>) {
     self.sort_controller.write().await.sort_rows(rows).await
     self.sort_controller.write().await.sort_rows(rows).await
   }
   }
 
 
-  pub async fn filter_rows(&self, _block_id: &str, rows: &mut Vec<Arc<RowRevision>>) {
+  pub async fn v_filter_rows(&self, _block_id: &str, rows: &mut Vec<Arc<RowRevision>>) {
     self.filter_controller.filter_row_revs(rows).await;
     self.filter_controller.filter_row_revs(rows).await;
   }
   }
 
 
-  pub async fn duplicate_view_data(&self) -> FlowyResult<String> {
+  pub async fn v_duplicate_data(&self) -> FlowyResult<String> {
     let json_str = self.pad.read().await.json_str()?;
     let json_str = self.pad.read().await.json_str()?;
     Ok(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() {
     if params.group_id.is_none() {
       return;
       return;
     }
     }
@@ -248,7 +248,7 @@ impl DatabaseViewEditor {
       .await;
       .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
     // Send the group notification if the current view has groups
     match params.group_id.as_ref() {
     match params.group_id.as_ref() {
       None => {},
       None => {},
@@ -275,7 +275,7 @@ impl DatabaseViewEditor {
   }
   }
 
 
   #[tracing::instrument(level = "trace", skip_all)]
   #[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;
     // Send the group notification if the current view has groups;
     let result = self
     let result = self
       .mut_group_controller(|group_controller, field_rev| {
       .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,
     &self,
     old_row_rev: Option<Arc<RowRevision>>,
     old_row_rev: Option<Arc<RowRevision>>,
     row_rev: &RowRevision,
     row_rev: &RowRevision,
@@ -339,7 +339,7 @@ impl DatabaseViewEditor {
     });
     });
   }
   }
 
 
-  pub async fn move_view_group_row(
+  pub async fn v_move_group_row(
     &self,
     &self,
     row_rev: &RowRevision,
     row_rev: &RowRevision,
     row_changeset: &mut RowChangeset,
     row_changeset: &mut RowChangeset,
@@ -377,7 +377,7 @@ impl DatabaseViewEditor {
   }
   }
   /// Only call once after grid view editor initialized
   /// Only call once after grid view editor initialized
   #[tracing::instrument(level = "trace", skip(self))]
   #[tracing::instrument(level = "trace", skip(self))]
-  pub async fn load_view_groups(&self) -> FlowyResult<Vec<GroupPB>> {
+  pub async fn v_load_groups(&self) -> FlowyResult<Vec<GroupPB>> {
     let groups = self
     let groups = self
       .group_controller
       .group_controller
       .read()
       .read()
@@ -391,7 +391,7 @@ impl DatabaseViewEditor {
   }
   }
 
 
   #[tracing::instrument(level = "trace", skip(self), err)]
   #[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
     self
       .group_controller
       .group_controller
       .write()
       .write()
@@ -430,7 +430,7 @@ impl DatabaseViewEditor {
 
 
   /// Initialize new group when grouping by a new field
   /// 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(&params.field_id).await {
     if let Some(field_rev) = self.delegate.get_field_rev(&params.field_id).await {
       self
       self
         .modify(|pad| {
         .modify(|pad| {
@@ -445,13 +445,13 @@ impl DatabaseViewEditor {
         .await?;
         .await?;
     }
     }
     if self.group_controller.read().await.field_id() != params.field_id {
     if self.group_controller.read().await.field_id() != params.field_id {
-      self.group_by_view_field(&params.field_id).await?;
+      self.v_update_group_setting(&params.field_id).await?;
       self.notify_did_update_setting().await;
       self.notify_did_update_setting().await;
     }
     }
     Ok(())
     Ok(())
   }
   }
 
 
-  pub async fn delete_view_group(&self, params: DeleteGroupParams) -> FlowyResult<()> {
+  pub async fn v_delete_group(&self, params: DeleteGroupParams) -> FlowyResult<()> {
     self
     self
       .modify(|pad| {
       .modify(|pad| {
         let changeset =
         let changeset =
@@ -461,18 +461,18 @@ impl DatabaseViewEditor {
       .await
       .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;
     let field_revs = self.delegate.get_field_revs(None).await;
     make_database_view_setting(&*self.pad.read().await, &field_revs)
     make_database_view_setting(&*self.pad.read().await, &field_revs)
   }
   }
 
 
-  pub async fn get_all_view_sorts(&self) -> Vec<Arc<SortRevision>> {
+  pub async fn v_get_all_sorts(&self) -> Vec<Arc<SortRevision>> {
     let field_revs = self.delegate.get_field_revs(None).await;
     let field_revs = self.delegate.get_field_revs(None).await;
     self.pad.read().await.get_all_sorts(&field_revs)
     self.pad.read().await.get_all_sorts(&field_revs)
   }
   }
 
 
   #[tracing::instrument(level = "trace", skip(self), err)]
   #[tracing::instrument(level = "trace", skip(self), err)]
-  pub async fn insert_view_sort(&self, params: AlterSortParams) -> FlowyResult<SortRevision> {
+  pub async fn v_insert_sort(&self, params: AlterSortParams) -> FlowyResult<SortRevision> {
     let sort_type = SortType::from(&params);
     let sort_type = SortType::from(&params);
     let is_exist = params.sort_id.is_some();
     let is_exist = params.sort_id.is_some();
     let sort_id = match params.sort_id {
     let sort_id = match params.sort_id {
@@ -514,7 +514,7 @@ impl DatabaseViewEditor {
     Ok(sort_rev)
     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
     let notification = self
       .sort_controller
       .sort_controller
       .write()
       .write()
@@ -537,8 +537,8 @@ impl DatabaseViewEditor {
     Ok(())
     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.sort_controller.write().await.delete_all_sorts().await;
     self
     self
       .modify(|pad| {
       .modify(|pad| {
@@ -556,12 +556,12 @@ impl DatabaseViewEditor {
     Ok(())
     Ok(())
   }
   }
 
 
-  pub async fn get_all_view_filters(&self) -> Vec<Arc<FilterRevision>> {
+  pub async fn v_get_all_filters(&self) -> Vec<Arc<FilterRevision>> {
     let field_revs = self.delegate.get_field_revs(None).await;
     let field_revs = self.delegate.get_field_revs(None).await;
     self.pad.read().await.get_all_filters(&field_revs)
     self.pad.read().await.get_all_filters(&field_revs)
   }
   }
 
 
-  pub async fn get_view_filters(&self, filter_type: &FilterType) -> Vec<Arc<FilterRevision>> {
+  pub async fn v_get_filters(&self, filter_type: &FilterType) -> Vec<Arc<FilterRevision>> {
     let field_type_rev: FieldTypeRevision = filter_type.field_type.clone().into();
     let field_type_rev: FieldTypeRevision = filter_type.field_type.clone().into();
     self
     self
       .pad
       .pad
@@ -571,7 +571,7 @@ impl DatabaseViewEditor {
   }
   }
 
 
   #[tracing::instrument(level = "trace", skip(self), err)]
   #[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(&params);
     let filter_type = FilterType::from(&params);
     let is_exist = params.filter_id.is_some();
     let is_exist = params.filter_id.is_some();
     let filter_id = match params.filter_id {
     let filter_id = match params.filter_id {
@@ -624,7 +624,7 @@ impl DatabaseViewEditor {
   }
   }
 
 
   #[tracing::instrument(level = "trace", skip(self), err)]
   #[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 filter_type = params.filter_type;
     let changeset = self
     let changeset = self
       .filter_controller
       .filter_controller
@@ -649,7 +649,7 @@ impl DatabaseViewEditor {
   }
   }
 
 
   /// Returns the current calendar settings
   /// Returns the current calendar settings
-  pub async fn get_calendar_settings(&self) -> FlowyResult<CalendarSettingsParams> {
+  pub async fn v_get_calendar_settings(&self) -> FlowyResult<CalendarSettingsParams> {
     let settings = self
     let settings = self
       .pad
       .pad
       .read()
       .read()
@@ -660,7 +660,10 @@ impl DatabaseViewEditor {
   }
   }
 
 
   /// Update the calendar settings and send the notification to refresh the UI
   /// 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
     // Maybe it needs no send notification to refresh the UI
     self
     self
       .modify(|pad| Ok(pad.update_layout_setting(&LayoutRevision::Calendar, &params)?))
       .modify(|pad| Ok(pad.update_layout_setting(&LayoutRevision::Calendar, &params)?))
@@ -669,7 +672,7 @@ impl DatabaseViewEditor {
   }
   }
 
 
   #[tracing::instrument(level = "trace", skip_all, err)]
   #[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,
     &self,
     field_id: &str,
     field_id: &str,
     old_field_rev: Option<Arc<FieldRevision>>,
     old_field_rev: Option<Arc<FieldRevision>>,
@@ -709,7 +712,7 @@ impl DatabaseViewEditor {
   /// * `field_id`:
   /// * `field_id`:
   ///
   ///
   #[tracing::instrument(level = "debug", skip_all, err)]
   #[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 {
     if let Some(field_rev) = self.delegate.get_field_rev(field_id).await {
       let row_revs = self.delegate.get_row_revs(None).await;
       let row_revs = self.delegate.get_row_revs(None).await;
       let configuration_reader = GroupConfigurationReaderImpl {
       let configuration_reader = GroupConfigurationReaderImpl {
@@ -750,7 +753,7 @@ impl DatabaseViewEditor {
     Ok(())
     Ok(())
   }
   }
 
 
-  pub(crate) async fn get_cells_for_field(
+  pub(crate) async fn v_get_cells_for_field(
     &self,
     &self,
     field_id: &str,
     field_id: &str,
   ) -> FlowyResult<Vec<RowSingleCellData>> {
   ) -> FlowyResult<Vec<RowSingleCellData>> {
@@ -758,7 +761,7 @@ impl DatabaseViewEditor {
   }
   }
 
 
   async fn notify_did_update_setting(&self) {
   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)
     send_notification(&self.view_id, DatabaseNotification::DidUpdateSettings)
       .payload(setting)
       .payload(setting)
       .send();
       .send();

+ 29 - 26
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()]))
       .get_row_revs(Some(vec![block_id.to_owned()]))
       .await;
       .await;
     if let Ok(view_editor) = self.get_view_editor(view_id).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)
     Ok(row_revs)
@@ -93,21 +93,21 @@ impl DatabaseViews {
 
 
   pub async fn duplicate_database_view(&self, view_id: &str) -> FlowyResult<String> {
   pub async fn duplicate_database_view(&self, view_id: &str) -> FlowyResult<String> {
     let editor = self.get_view_editor(view_id).await?;
     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)
     Ok(view_data)
   }
   }
 
 
   /// When the row was created, we may need to modify the [RowRevision] according to the [CreateRowParams].
   /// 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) {
   pub async fn will_create_row(&self, row_rev: &mut RowRevision, params: &CreateRowParams) {
     for view_editor in self.view_editors.read().await.values() {
     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.
   /// 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) {
   pub async fn did_create_row(&self, row_pb: &RowPB, params: &CreateRowParams) {
     for view_editor in self.view_editors.read().await.values() {
     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)) => {
       Some((_, row_rev)) => {
         for view_editor in self.view_editors.read().await.values() {
         for view_editor in self.view_editors.read().await.values() {
           view_editor
           view_editor
-            .did_update_view_row(old_row_rev.clone(), &row_rev)
+            .v_did_update_row(old_row_rev.clone(), &row_rev)
             .await;
             .await;
         }
         }
       },
       },
@@ -129,24 +129,24 @@ impl DatabaseViews {
 
 
   pub async fn group_by_field(&self, view_id: &str, field_id: &str) -> FlowyResult<()> {
   pub async fn group_by_field(&self, view_id: &str, field_id: &str) -> FlowyResult<()> {
     let view_editor = self.get_view_editor(view_id).await?;
     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(())
     Ok(())
   }
   }
 
 
   pub async fn did_delete_row(&self, row_rev: Arc<RowRevision>) {
   pub async fn did_delete_row(&self, row_rev: Arc<RowRevision>) {
     for view_editor in self.view_editors.read().await.values() {
     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<DatabaseViewSettingPB> {
   pub async fn get_setting(&self, view_id: &str) -> FlowyResult<DatabaseViewSettingPB> {
     let view_editor = self.get_view_editor(view_id).await?;
     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<Vec<Arc<FilterRevision>>> {
   pub async fn get_all_filters(&self, view_id: &str) -> FlowyResult<Vec<Arc<FilterRevision>>> {
     let view_editor = self.get_view_editor(view_id).await?;
     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(
   pub async fn get_filters(
@@ -155,58 +155,58 @@ impl DatabaseViews {
     filter_id: &FilterType,
     filter_id: &FilterType,
   ) -> FlowyResult<Vec<Arc<FilterRevision>>> {
   ) -> FlowyResult<Vec<Arc<FilterRevision>>> {
     let view_editor = self.get_view_editor(view_id).await?;
     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<()> {
   pub async fn create_or_update_filter(&self, params: AlterFilterParams) -> FlowyResult<()> {
     let view_editor = self.get_view_editor(&params.view_id).await?;
     let view_editor = self.get_view_editor(&params.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<()> {
   pub async fn delete_filter(&self, params: DeleteFilterParams) -> FlowyResult<()> {
     let view_editor = self.get_view_editor(&params.view_id).await?;
     let view_editor = self.get_view_editor(&params.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<Vec<Arc<SortRevision>>> {
   pub async fn get_all_sorts(&self, view_id: &str) -> FlowyResult<Vec<Arc<SortRevision>>> {
     let view_editor = self.get_view_editor(view_id).await?;
     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<SortRevision> {
   pub async fn create_or_update_sort(&self, params: AlterSortParams) -> FlowyResult<SortRevision> {
     let view_editor = self.get_view_editor(&params.view_id).await?;
     let view_editor = self.get_view_editor(&params.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<()> {
   pub async fn delete_all_sorts(&self, view_id: &str) -> FlowyResult<()> {
     let view_editor = self.get_view_editor(view_id).await?;
     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<()> {
   pub async fn delete_sort(&self, params: DeleteSortParams) -> FlowyResult<()> {
     let view_editor = self.get_view_editor(&params.view_id).await?;
     let view_editor = self.get_view_editor(&params.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<RepeatedGroupPB> {
   pub async fn load_groups(&self, view_id: &str) -> FlowyResult<RepeatedGroupPB> {
     let view_editor = self.get_view_editor(view_id).await?;
     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 })
     Ok(RepeatedGroupPB { items: groups })
   }
   }
 
 
   pub async fn insert_or_update_group(&self, params: InsertGroupParams) -> FlowyResult<()> {
   pub async fn insert_or_update_group(&self, params: InsertGroupParams) -> FlowyResult<()> {
     let view_editor = self.get_view_editor(&params.view_id).await?;
     let view_editor = self.get_view_editor(&params.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<()> {
   pub async fn delete_group(&self, params: DeleteGroupParams) -> FlowyResult<()> {
     let view_editor = self.get_view_editor(&params.view_id).await?;
     let view_editor = self.get_view_editor(&params.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<()> {
   pub async fn move_group(&self, params: MoveGroupParams) -> FlowyResult<()> {
     let view_editor = self.get_view_editor(&params.view_id).await?;
     let view_editor = self.get_view_editor(&params.view_id).await?;
-    view_editor.move_view_group(params).await?;
+    view_editor.v_move_group(params).await?;
     Ok(())
     Ok(())
   }
   }
 
 
@@ -224,7 +224,7 @@ impl DatabaseViews {
     let mut row_changeset = RowChangeset::new(row_rev.id.clone());
     let mut row_changeset = RowChangeset::new(row_rev.id.clone());
     let view_editor = self.get_view_editor(view_id).await?;
     let view_editor = self.get_view_editor(view_id).await?;
     view_editor
     view_editor
-      .move_view_group_row(
+      .v_move_group_row(
         &row_rev,
         &row_rev,
         &mut row_changeset,
         &mut row_changeset,
         &to_group_id,
         &to_group_id,
@@ -246,20 +246,22 @@ impl DatabaseViews {
   ///
   ///
   /// * `field_id`: the id of the field in current view
   /// * `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,
     &self,
     view_id: &str,
     view_id: &str,
     field_id: &str,
     field_id: &str,
     old_field_rev: Option<Arc<FieldRevision>>,
     old_field_rev: Option<Arc<FieldRevision>>,
   ) -> FlowyResult<()> {
   ) -> FlowyResult<()> {
     let view_editor = self.get_view_editor(view_id).await?;
     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 {
     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
     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?;
       .await?;
     Ok(())
     Ok(())
   }
   }
@@ -269,6 +271,7 @@ impl DatabaseViews {
     if let Some(editor) = self.view_editors.read().await.get(view_id) {
     if let Some(editor) = self.view_editors.read().await.get(view_id) {
       return Ok(editor);
       return Ok(editor);
     }
     }
+
     tracing::trace!("{:p} create view:{} editor", self, view_id);
     tracing::trace!("{:p} create view:{} editor", self, view_id);
     let mut view_editors = self.view_editors.write().await;
     let mut view_editors = self.view_editors.write().await;
     let editor = Arc::new(self.make_view_editor(view_id).await?);
     let editor = Arc::new(self.make_view_editor(view_id).await?);

+ 30 - 5
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_reader`: a reader used to read the group configuration from disk
 /// * `configuration_writer`: as writer used to write the group configuration to 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<R, W>(
 pub async fn make_group_controller<R, W>(
   view_id: String,
   view_id: String,
   grouping_field_rev: Arc<FieldRevision>,
   grouping_field_rev: Arc<FieldRevision>,
@@ -39,6 +49,7 @@ where
   W: GroupConfigurationWriter,
   W: GroupConfigurationWriter,
 {
 {
   let grouping_field_type: FieldType = grouping_field_rev.ty.into();
   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<dyn GroupController>;
   let mut group_controller: Box<dyn GroupController>;
   let configuration_reader = Arc::new(configuration_reader);
   let configuration_reader = Arc::new(configuration_reader);
@@ -99,17 +110,31 @@ where
   Ok(group_controller)
   Ok(group_controller)
 }
 }
 
 
+#[tracing::instrument(level = "debug", skip_all)]
 pub fn find_grouping_field(
 pub fn find_grouping_field(
   field_revs: &[Arc<FieldRevision>],
   field_revs: &[Arc<FieldRevision>],
   _layout: &LayoutRevision,
   _layout: &LayoutRevision,
 ) -> Option<Arc<FieldRevision>> {
 ) -> Option<Arc<FieldRevision>> {
-  field_revs
+  let mut groupable_field_revs = field_revs
     .iter()
     .iter()
-    .find(|field_rev| {
+    .flat_map(|field_rev| {
       let field_type: FieldType = field_rev.ty.into();
       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::<Vec<Arc<FieldRevision>>>();
+
+  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]
 /// Returns a `default` group configuration for the [FieldRevision]

+ 17 - 17
frontend/rust-lib/flowy-sqlite/src/schema.rs

@@ -189,21 +189,21 @@ diesel::table! {
 }
 }
 
 
 diesel::allow_tables_to_appear_in_same_query!(
 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,
 );
 );

+ 10 - 10
frontend/scripts/makefile/desktop.toml

@@ -189,42 +189,42 @@ script = [
 ]
 ]
 script_runner = "@duckscript"
 script_runner = "@duckscript"
 
 
-[tasks.build-test-lib]
+[tasks.build_test_backend]
 category = "Build"
 category = "Build"
 dependencies = ["env_check"]
 dependencies = ["env_check"]
 run_task = { name = [
 run_task = { name = [
   "setup-test-crate-type",
   "setup-test-crate-type",
-  "build-test-backend",
+  "compile_test_backend",
   "copy-to-sandbox-folder",
   "copy-to-sandbox-folder",
   "restore-test-crate-type",
   "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
 private = true
 script = [
 script = [
   """
   """
     cd rust-lib/
     cd rust-lib/
     rustup show
     rustup show
-    echo cargo build --package=dart-ffi --target ${TEST_COMPILE_TARGET} --features "${FLUTTER_DESKTOP_FEATURES}"
+    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}"
     RUST_LOG=${RUST_LOG} cargo build --package=dart-ffi --target ${TEST_COMPILE_TARGET} --features "${FLUTTER_DESKTOP_FEATURES}"
     cd ../
     cd ../
   """,
   """,
 ]
 ]
 script_runner = "@shell"
 script_runner = "@shell"
 
 
-[tasks.build-test-backend-widnows]
+[tasks.compile_test_backend_widnows]
 private = true
 private = true
 script = [
 script = [
   """
   """
     cd rust-lib/
     cd rust-lib/
     rustup show
     rustup show
     echo cargo build --package=dart-ffi --target ${TEST_COMPILE_TARGET} --features "${FLUTTER_DESKTOP_FEATURES}"
     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}"
+    RUST_LOG=${RUST_LOG} cargo build --package=dart-ffi --target ${TEST_COMPILE_TARGET} --features "${FLUTTER_DESKTOP_FEATURES}"
     cd ../
     cd ../
   """,
   """,
 ]
 ]

+ 7 - 7
frontend/scripts/makefile/tests.toml

@@ -1,29 +1,29 @@
 
 
 [tasks.dart_unit_test]
 [tasks.dart_unit_test]
 script = '''
 script = '''
-cargo make --profile test-macos dart_unit_test_inner
+cargo make --profile test-macos dart_unit_test_impl
 '''
 '''
 script_runner = "@shell"
 script_runner = "@shell"
 
 
 [tasks.dart_unit_test.windows]
 [tasks.dart_unit_test.windows]
 script = '''
 script = '''
-cargo make --profile test-windows dart_unit_test_inner
+cargo make --profile test-windows dart_unit_test_impl
 '''
 '''
 script_runner = "@shell"
 script_runner = "@shell"
 
 
 [tasks.dart_unit_test.linux]
 [tasks.dart_unit_test.linux]
 script = '''
 script = '''
-cargo make --profile test-linux dart_unit_test_inner
+cargo make --profile test-linux dart_unit_test_impl
 '''
 '''
 script_runner = "@shell"
 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"
 description = "Run flutter unit tests"
 script = '''
 script = '''
 cd appflowy_flutter
 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]
 [tasks.rust_unit_test]

+ 2 - 2
shared-lib/database-model/src/database_rev.rs

@@ -115,7 +115,7 @@ pub struct FieldRevision {
   #[serde(with = "indexmap::serde_seq")]
   #[serde(with = "indexmap::serde_seq")]
   pub type_options: IndexMap<String, String>,
   pub type_options: IndexMap<String, String>,
 
 
-  #[serde(default = "DEFAULT_IS_PRIMARY")]
+  #[serde(default = "DEFAULT_IS_PRIMARY_VALUE")]
   pub is_primary: bool,
   pub is_primary: bool,
 }
 }
 
 
@@ -125,7 +125,7 @@ impl AsRef<FieldRevision> for FieldRevision {
   }
   }
 }
 }
 
 
-const DEFAULT_IS_PRIMARY: fn() -> bool = || false;
+const DEFAULT_IS_PRIMARY_VALUE: fn() -> bool = || false;
 
 
 impl FieldRevision {
 impl FieldRevision {
   pub fn new<T: Into<FieldTypeRevision>>(
   pub fn new<T: Into<FieldTypeRevision>>(