From a69ff66ee1ac5154de578a3c9d5e59fce75a7573 Mon Sep 17 00:00:00 2001 From: Richard Shiue <71320345+richardshiue@users.noreply.github.com> Date: Sun, 24 Dec 2023 01:37:42 +0800 Subject: [PATCH] refactor: create database view --- collab-database/src/database.rs | 86 ++++++++++++------- collab-database/src/user/db_record.rs | 10 ++- collab-database/src/user/user_db.rs | 5 +- collab-database/src/views/view.rs | 66 +++++--------- collab-database/tests/database_test/helper.rs | 40 +++++---- .../tests/user_test/async_test/script.rs | 21 ++--- collab-database/tests/user_test/cell_test.rs | 15 +++- .../tests/user_test/database_test.rs | 48 +++++++++-- collab-database/tests/user_test/helper.rs | 41 ++++----- .../tests/user_test/type_option_test.rs | 8 +- 10 files changed, 201 insertions(+), 139 deletions(-) diff --git a/collab-database/src/database.rs b/collab-database/src/database.rs index b79757f6f..36072aff2 100644 --- a/collab-database/src/database.rs +++ b/collab-database/src/database.rs @@ -71,24 +71,40 @@ impl Database { ) -> Result { // Get or create a empty database with the given database_id let this = Self::get_or_create(¶ms.database_id, context)?; - let (rows, fields, params) = params.split(); - if !params.deps_fields.is_empty() { - tracing::warn!("The deps_fields should be empty when creating a database with inline view."); - } + let CreateDatabaseParams { + database_id, + rows, + fields, + inline_view_id, + linked_views, + } = params; + + let inline_view = CreateViewParams::new( + database_id.clone(), + inline_view_id.clone(), + "".to_owned(), // WTF + DatabaseLayout::Grid, + ); let row_orders = this.block.create_rows(rows); - let field_orders = fields.iter().map(FieldOrder::from).collect(); + let field_orders: Vec = fields.iter().map(FieldOrder::from).collect(); this.root.with_transact_mut(|txn| { // Set the inline view id. The inline view id should not be // empty if the current database exists. - this.set_inline_view_with_txn(txn, ¶ms.view_id); + this.set_inline_view_with_txn(txn, &inline_view_id); // Insert the given fields into the database for field in fields { this.fields.insert_field_with_txn(txn, field); } - // Create a inline view - this.create_view_with_txn(txn, params, field_orders, row_orders)?; + // Create the inline view + this.create_view_with_txn(txn, inline_view, field_orders.clone(), row_orders.clone())?; + + // create the linked views + for linked_view in linked_views { + this.create_linked_view_with_txn(txn, linked_view, field_orders.clone(), row_orders.clone())?; + } + Ok::<(), DatabaseError>(()) })?; Ok(this) @@ -976,36 +992,48 @@ impl Database { /// Create a linked view to existing database pub fn create_linked_view(&self, params: CreateViewParams) -> Result<(), DatabaseError> { - let mut params = CreateViewParamsValidator::validate(params)?; self.root.with_transact_mut(|txn| { let inline_view_id = self.get_inline_view_id_with_txn(txn); let row_orders = self.views.get_row_orders_with_txn(txn, &inline_view_id); let field_orders = self.views.get_field_orders_with_txn(txn, &inline_view_id); - let (deps_fields, deps_field_settings) = params.take_deps_fields(); - - self.create_view_with_txn(txn, params, field_orders, row_orders)?; - - // After creating the view, we need to create the fields that are used in the view. - if !deps_fields.is_empty() { - tracing::trace!("create linked view with deps fields: {:?}", deps_fields); - deps_fields - .into_iter() - .zip(deps_field_settings.into_iter()) - .for_each(|(field, field_settings)| { - self.create_field_with_txn( - txn, - None, - field, - &OrderObjectPosition::default(), - &field_settings, - ); - }) - } + + self.create_linked_view_with_txn(txn, params, field_orders, row_orders)?; Ok::<(), DatabaseError>(()) })?; Ok(()) } + pub fn create_linked_view_with_txn( + &self, + txn: &mut TransactionMut, + params: CreateViewParams, + field_orders: Vec, + row_orders: Vec, + ) -> Result<(), DatabaseError> { + let mut params = CreateViewParamsValidator::validate(params)?; + let (deps_fields, deps_field_settings) = params.take_deps_fields(); + + self.create_view_with_txn(txn, params, field_orders, row_orders)?; + + // After creating the view, we need to create the fields that are used in the view. + if !deps_fields.is_empty() { + tracing::trace!("create linked view with deps fields: {:?}", deps_fields); + deps_fields + .into_iter() + .zip(deps_field_settings.into_iter()) + .for_each(|(field, field_settings)| { + self.create_field_with_txn( + txn, + None, + field, + &OrderObjectPosition::default(), + &field_settings, + ); + }); + } + Ok(()) + } + /// Create a [DatabaseView] for the current database. pub fn create_view_with_txn( &self, diff --git a/collab-database/src/user/db_record.rs b/collab-database/src/user/db_record.rs index f3ee7cef3..af53313e5 100644 --- a/collab-database/src/user/db_record.rs +++ b/collab-database/src/user/db_record.rs @@ -8,6 +8,7 @@ use collab::preclude::{ }; use crate::database::timestamp; +use crate::views::CreateDatabaseParams; const DATABASES: &str = "databases"; @@ -39,13 +40,14 @@ impl DatabaseWithViewsArray { } /// Create a new [DatabaseWithViews] for the given database id and view id - pub fn add_database(&self, database_id: &str, view_id: &str, name: &str) { + pub fn add_database(&self, params: &CreateDatabaseParams) { self.array_ref.with_transact_mut(|txn| { let mut linked_views = HashSet::new(); - linked_views.insert(view_id.to_string()); + linked_views.insert(params.inline_view_id.to_string()); + linked_views.extend(params.linked_views.iter().map(|view| view.view_id.clone())); let record = DatabaseWithViews { - database_id: database_id.to_string(), - name: name.to_string(), + database_id: params.database_id.to_string(), + name: "".to_owned(), // WTF created_at: timestamp(), linked_views, }; diff --git a/collab-database/src/user/user_db.rs b/collab-database/src/user/user_db.rs index f7a75c38d..0963652a1 100644 --- a/collab-database/src/user/user_db.rs +++ b/collab-database/src/user/user_db.rs @@ -178,7 +178,6 @@ impl WorkspaceDatabase { params: CreateDatabaseParams, ) -> Result, DatabaseError> { debug_assert!(!params.database_id.is_empty()); - debug_assert!(!params.view_id.is_empty()); // Create a [Collab] for the given database id. let collab = self.collab_for_database(¶ms.database_id, CollabRawData::default()); @@ -192,9 +191,7 @@ impl WorkspaceDatabase { }; // Add a new database record. - self - .database_array() - .add_database(¶ms.database_id, ¶ms.view_id, ¶ms.name); + self.database_array().add_database(¶ms); let database_id = params.database_id.clone(); let mutex_database = MutexDatabase::new(Database::create_with_inline_view(params, context)?); let database = Arc::new(mutex_database); diff --git a/collab-database/src/views/view.rs b/collab-database/src/views/view.rs index d09c23f6b..aebb7a82f 100644 --- a/collab-database/src/views/view.rs +++ b/collab-database/src/views/view.rs @@ -136,61 +136,41 @@ impl CreateViewParamsValidator { #[derive(Debug, Clone, Default, Serialize, Deserialize)] pub struct CreateDatabaseParams { pub database_id: String, - pub view_id: String, - pub name: String, - pub layout: DatabaseLayout, - pub layout_settings: LayoutSettings, - pub filters: Vec, - pub groups: Vec, - pub sorts: Vec, - pub field_settings: FieldSettingsByFieldIdMap, - pub created_rows: Vec, pub fields: Vec, + pub rows: Vec, + pub inline_view_id: String, + pub linked_views: Vec, } impl CreateDatabaseParams { pub fn from_view(view: DatabaseView, fields: Vec, rows: Vec) -> Self { - let mut params: Self = view.into(); - params.fields = fields; - params.created_rows = rows; - params - } - - pub fn split(self) -> (Vec, Vec, CreateViewParams) { - ( - self.created_rows, - self.fields, - CreateViewParams { - database_id: self.database_id, - view_id: self.view_id, - name: self.name, - layout: self.layout, - layout_settings: self.layout_settings, - filters: self.filters, - groups: self.groups, - sorts: self.sorts, - field_settings: self.field_settings, - deps_fields: vec![], - deps_field_setting: vec![], - }, - ) + Self { + fields, + rows, + ..view.into() + } } } impl From for CreateDatabaseParams { fn from(view: DatabaseView) -> Self { Self { - database_id: view.database_id, - view_id: view.id, - name: view.name, - layout: view.layout, - layout_settings: view.layout_settings, - filters: view.filters, - groups: view.group_settings, - sorts: view.sorts, - field_settings: view.field_settings, - created_rows: vec![], + database_id: view.database_id.clone(), + inline_view_id: "".to_owned(), // WTF + rows: vec![], fields: vec![], + linked_views: vec![CreateViewParams { + database_id: view.database_id, + view_id: view.id, + name: view.name, + layout: view.layout, + layout_settings: view.layout_settings, + filters: view.filters, + groups: view.group_settings, + sorts: view.sorts, + field_settings: view.field_settings, + ..Default::default() + }], } } } diff --git a/collab-database/tests/database_test/helper.rs b/collab-database/tests/database_test/helper.rs index d5f556cd6..b00700371 100644 --- a/collab-database/tests/database_test/helper.rs +++ b/collab-database/tests/database_test/helper.rs @@ -10,8 +10,8 @@ use collab_database::fields::Field; use collab_database::rows::{CellsBuilder, CreateRowParams}; use collab_database::user::DatabaseCollabService; use collab_database::views::{ - CreateDatabaseParams, DatabaseLayout, FieldSettingsByFieldIdMap, FieldSettingsMap, LayoutSetting, - LayoutSettings, OrderObjectPosition, + CreateDatabaseParams, CreateViewParams, DatabaseLayout, FieldSettingsByFieldIdMap, + FieldSettingsMap, LayoutSetting, LayoutSettings, OrderObjectPosition, }; use collab_entity::CollabType; use collab_persistence::kv::rocks_kv::RocksCollabDB; @@ -66,8 +66,12 @@ pub async fn create_database(uid: i64, database_id: &str) -> DatabaseTest { }; let params = CreateDatabaseParams { database_id: database_id.to_string(), - view_id: "v1".to_string(), - name: "my first database view".to_string(), + inline_view_id: "inline_view_id".to_string(), + linked_views: vec![CreateViewParams { + view_id: database_id.to_string(), + name: "my first database view".to_string(), + ..Default::default() + }], ..Default::default() }; let database = Database::create_with_inline_view(params, context).unwrap(); @@ -100,9 +104,12 @@ pub async fn create_database_with_db( notifier: Some(DatabaseNotify::default()), }; let params = CreateDatabaseParams { - view_id: "v1".to_string(), - name: "my first grid".to_string(), - database_id: database_id.to_string(), + inline_view_id: "inline_view_id".to_string(), + linked_views: vec![CreateViewParams { + view_id: database_id.to_string(), + name: "my first grid".to_string(), + ..Default::default() + }], ..Default::default() }; let database = Database::create_with_inline_view(params, context).unwrap(); @@ -207,15 +214,16 @@ impl DatabaseTestBuilder { }; let params = CreateDatabaseParams { database_id: self.database_id.clone(), - view_id: self.view_id, - name: "my first database view".to_string(), - layout: self.layout, - layout_settings: self.layout_settings, - filters: vec![], - groups: vec![], - sorts: vec![], - field_settings: self.field_settings, - created_rows: self.rows, + inline_view_id: "inline_view_id".to_string(), + linked_views: vec![CreateViewParams { + view_id: self.view_id, + name: "my first database view".to_string(), + layout: self.layout, + layout_settings: self.layout_settings, + field_settings: self.field_settings, + ..Default::default() + }], + rows: self.rows, fields: self.fields, }; let database = Database::create_with_inline_view(params, context).unwrap(); diff --git a/collab-database/tests/user_test/async_test/script.rs b/collab-database/tests/user_test/async_test/script.rs index 54050fa91..2d2cf7847 100644 --- a/collab-database/tests/user_test/async_test/script.rs +++ b/collab-database/tests/user_test/async_test/script.rs @@ -8,7 +8,7 @@ use collab_database::fields::Field; use collab_database::rows::CreateRowParams; use collab_database::rows::{Cells, CellsBuilder, RowId}; use collab_database::user::WorkspaceDatabase; -use collab_database::views::{CreateDatabaseParams, OrderObjectPosition}; +use collab_database::views::{CreateDatabaseParams, CreateViewParams, OrderObjectPosition}; use collab_persistence::doc::YrsDocAction; use collab_persistence::kv::rocks_kv::RocksCollabDB; use collab_plugins::local_storage::CollabPersistenceConfig; @@ -233,15 +233,16 @@ pub fn create_database(database_id: &str) -> CreateDatabaseParams { CreateDatabaseParams { database_id: database_id.to_string(), - view_id: "v1".to_string(), - name: "my first database".to_string(), - layout: Default::default(), - layout_settings: Default::default(), - filters: vec![], - groups: vec![], - sorts: vec![], - field_settings: field_settings_map.into(), - created_rows: vec![row_1, row_2, row_3], + inline_view_id: "inline_view_id".to_string(), + linked_views: vec![CreateViewParams { + view_id: "v1".to_string(), + name: "my first database".to_string(), + layout: Default::default(), + layout_settings: Default::default(), + field_settings: field_settings_map.into(), + ..Default::default() + }], + rows: vec![row_1, row_2, row_3], fields: vec![field_1, field_2, field_3], } } diff --git a/collab-database/tests/user_test/cell_test.rs b/collab-database/tests/user_test/cell_test.rs index eba6a4f98..7ded815c7 100644 --- a/collab-database/tests/user_test/cell_test.rs +++ b/collab-database/tests/user_test/cell_test.rs @@ -1,7 +1,7 @@ use collab::core::any_map::AnyMapExtension; use collab_database::rows::{new_cell_builder, CREATED_AT}; use collab_database::rows::{CreateRowParams, LAST_MODIFIED}; -use collab_database::views::CreateDatabaseParams; +use collab_database::views::{CreateDatabaseParams, CreateViewParams}; use crate::user_test::helper::{workspace_database_test, WorkspaceDatabaseTest}; @@ -64,7 +64,11 @@ async fn update_not_exist_row_test() { let database = test .create_database(CreateDatabaseParams { database_id: "d1".to_string(), - view_id: "v1".to_string(), + inline_view_id: "inline_view_id".to_string(), + linked_views: vec![CreateViewParams { + view_id: "v1".to_string(), + ..Default::default() + }], ..Default::default() }) .unwrap(); @@ -80,7 +84,12 @@ async fn user_database_with_default_row() -> WorkspaceDatabaseTest { let database = test .create_database(CreateDatabaseParams { database_id: "d1".to_string(), - view_id: "v1".to_string(), + inline_view_id: "inline_view_id".to_string(), + linked_views: vec![CreateViewParams { + database_id: "d1".to_string(), + view_id: "v1".to_string(), + ..Default::default() + }], ..Default::default() }) .unwrap(); diff --git a/collab-database/tests/user_test/database_test.rs b/collab-database/tests/user_test/database_test.rs index f579aaf4d..ca65834c3 100644 --- a/collab-database/tests/user_test/database_test.rs +++ b/collab-database/tests/user_test/database_test.rs @@ -19,14 +19,22 @@ async fn create_multiple_database_test() { test .create_database(CreateDatabaseParams { database_id: "d1".to_string(), - view_id: "v1".to_string(), + inline_view_id: "i1".to_string(), + linked_views: vec![CreateViewParams { + view_id: "v1".to_string(), + ..Default::default() + }], ..Default::default() }) .unwrap(); test .create_database(CreateDatabaseParams { database_id: "d2".to_string(), - view_id: "v1".to_string(), + inline_view_id: "i2".to_string(), + linked_views: vec![CreateViewParams { + view_id: "v2".to_string(), + ..Default::default() + }], ..Default::default() }) .unwrap(); @@ -43,14 +51,22 @@ async fn delete_database_test() { test .create_database(CreateDatabaseParams { database_id: "d1".to_string(), - view_id: "v1".to_string(), + inline_view_id: "i1".to_string(), + linked_views: vec![CreateViewParams { + view_id: "v1".to_string(), + ..Default::default() + }], ..Default::default() }) .unwrap(); test .create_database(CreateDatabaseParams { database_id: "d2".to_string(), - view_id: "v1".to_string(), + inline_view_id: "i2".to_string(), + linked_views: vec![CreateViewParams { + view_id: "v2".to_string(), + ..Default::default() + }], ..Default::default() }) .unwrap(); @@ -67,7 +83,11 @@ async fn duplicate_database_inline_view_test() { let database = test .create_database(CreateDatabaseParams { database_id: "d1".to_string(), - view_id: "v1".to_string(), + inline_view_id: "i1".to_string(), + linked_views: vec![CreateViewParams { + view_id: "v1".to_string(), + ..Default::default() + }], ..Default::default() }) .unwrap(); @@ -100,7 +120,11 @@ async fn duplicate_database_view_test() { let database = test .create_database(CreateDatabaseParams { database_id: "d1".to_string(), - view_id: "v1".to_string(), + inline_view_id: "i1".to_string(), + linked_views: vec![CreateViewParams { + view_id: "v1".to_string(), + ..Default::default() + }], ..Default::default() }) .unwrap(); @@ -138,7 +162,11 @@ async fn delete_database_inline_view_test() { let database = test .create_database(CreateDatabaseParams { database_id: "d1".to_string(), - view_id: "v1".to_string(), + inline_view_id: "i1".to_string(), + linked_views: vec![CreateViewParams { + view_id: "v1".to_string(), + ..Default::default() + }], ..Default::default() }) .unwrap(); @@ -216,7 +244,11 @@ async fn get_database_by_view_id_test() { let _database = test .create_database(CreateDatabaseParams { database_id: "d1".to_string(), - view_id: "v1".to_string(), + inline_view_id: "i1".to_string(), + linked_views: vec![CreateViewParams { + view_id: "v1".to_string(), + ..Default::default() + }], ..Default::default() }) .unwrap(); diff --git a/collab-database/tests/user_test/helper.rs b/collab-database/tests/user_test/helper.rs index 5858e39f3..044239330 100644 --- a/collab-database/tests/user_test/helper.rs +++ b/collab-database/tests/user_test/helper.rs @@ -6,7 +6,7 @@ use std::time::Duration; use async_trait::async_trait; use collab::core::collab::{CollabRawData, MutexCollab}; use collab::preclude::CollabBuilder; -use collab_database::database::{gen_database_id, gen_field_id, gen_row_id}; +use collab_database::database::{gen_database_id, gen_database_view_id, gen_field_id, gen_row_id}; use collab_database::error::DatabaseError; use collab_database::fields::Field; use collab_database::rows::CellsBuilder; @@ -15,7 +15,9 @@ use collab_database::user::{ CollabFuture, CollabObjectUpdate, CollabObjectUpdateByOid, DatabaseCollabService, RowRelationChange, RowRelationUpdateReceiver, WorkspaceDatabase, }; -use collab_database::views::{CreateDatabaseParams, DatabaseLayout, OrderObjectPosition}; +use collab_database::views::{ + CreateDatabaseParams, CreateViewParams, DatabaseLayout, OrderObjectPosition, +}; use collab_entity::CollabType; use collab_persistence::kv::rocks_kv::RocksCollabDB; use collab_plugins::local_storage::rocksdb::RocksdbDiskPlugin; @@ -213,15 +215,14 @@ fn create_database_params(database_id: &str) -> CreateDatabaseParams { CreateDatabaseParams { database_id: database_id.to_string(), - view_id: "v1".to_string(), - name: "my first database".to_string(), - layout: Default::default(), - layout_settings: Default::default(), - filters: vec![], - groups: vec![], - sorts: vec![], - field_settings: field_settings_map, - created_rows: vec![row_1, row_2, row_3], + inline_view_id: gen_database_view_id(), + linked_views: vec![CreateViewParams { + view_id: "v1".to_string(), + name: "my first database".to_string(), + field_settings: field_settings_map, + ..Default::default() + }], + rows: vec![row_1, row_2, row_3], fields: vec![field_1, field_2, field_3], } } @@ -278,15 +279,15 @@ pub fn make_default_grid(view_id: &str, name: &str) -> CreateDatabaseParams { CreateDatabaseParams { database_id: gen_database_id(), - view_id: view_id.to_string(), - name: name.to_string(), - layout: DatabaseLayout::Grid, - layout_settings: Default::default(), - filters: vec![], - groups: vec![], - sorts: vec![], - field_settings: field_settings_map, - created_rows: vec![ + inline_view_id: gen_database_view_id(), + linked_views: vec![CreateViewParams { + view_id: view_id.to_string(), + name: name.to_string(), + layout: DatabaseLayout::Grid, + field_settings: field_settings_map, + ..Default::default() + }], + rows: vec![ CreateRowParams::new(gen_row_id()), CreateRowParams::new(gen_row_id()), CreateRowParams::new(gen_row_id()), diff --git a/collab-database/tests/user_test/type_option_test.rs b/collab-database/tests/user_test/type_option_test.rs index 29c7aca6a..2c4b879c2 100644 --- a/collab-database/tests/user_test/type_option_test.rs +++ b/collab-database/tests/user_test/type_option_test.rs @@ -1,6 +1,6 @@ use collab::core::any_map::AnyMapExtension; use collab_database::fields::{Field, TypeOptionDataBuilder, TypeOptions}; -use collab_database::views::{CreateDatabaseParams, OrderObjectPosition}; +use collab_database::views::{CreateDatabaseParams, CreateViewParams, OrderObjectPosition}; use crate::database_test::helper::default_field_settings_by_layout; use crate::user_test::helper::{workspace_database_test, WorkspaceDatabaseTest}; @@ -72,7 +72,11 @@ async fn user_database_with_default_field() -> WorkspaceDatabaseTest { let database = test .create_database(CreateDatabaseParams { database_id: "d1".to_string(), - view_id: "v1".to_string(), + inline_view_id: "inline_view_id".to_string(), + linked_views: vec![CreateViewParams { + view_id: "v1".to_string(), + ..Default::default() + }], ..Default::default() }) .unwrap();