Skip to content

Commit

Permalink
refactor: create database view
Browse files Browse the repository at this point in the history
  • Loading branch information
richardshiue committed Dec 24, 2023
1 parent 2da4ad4 commit 9b61c20
Show file tree
Hide file tree
Showing 10 changed files with 223 additions and 141 deletions.
91 changes: 62 additions & 29 deletions collab-database/src/database.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,24 +71,45 @@ impl Database {
) -> Result<Self, DatabaseError> {
// Get or create a empty database with the given database_id
let this = Self::get_or_create(&params.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<FieldOrder> = 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, &params.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)
Expand Down Expand Up @@ -976,36 +997,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<FieldOrder>,
row_orders: Vec<RowOrder>,
) -> 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,
Expand Down
10 changes: 6 additions & 4 deletions collab-database/src/user/db_record.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use collab::preclude::{
};

use crate::database::timestamp;
use crate::views::CreateDatabaseParams;

const DATABASES: &str = "databases";

Expand Down Expand Up @@ -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,
};
Expand Down
5 changes: 1 addition & 4 deletions collab-database/src/user/user_db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,6 @@ impl WorkspaceDatabase {
params: CreateDatabaseParams,
) -> Result<Arc<MutexDatabase>, 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(&params.database_id, CollabRawData::default());
Expand All @@ -192,9 +191,7 @@ impl WorkspaceDatabase {
};

// Add a new database record.
self
.database_array()
.add_database(&params.database_id, &params.view_id, &params.name);
self.database_array().add_database(&params);
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);
Expand Down
67 changes: 24 additions & 43 deletions collab-database/src/views/view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use collab::preclude::{
};
use serde::{Deserialize, Serialize};

use crate::database::gen_database_view_id;
use crate::error::DatabaseError;
use crate::fields::Field;
use crate::rows::CreateRowParams;
Expand Down Expand Up @@ -136,61 +137,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<FilterMap>,
pub groups: Vec<GroupSettingMap>,
pub sorts: Vec<SortMap>,
pub field_settings: FieldSettingsByFieldIdMap,
pub created_rows: Vec<CreateRowParams>,
pub fields: Vec<Field>,
pub rows: Vec<CreateRowParams>,
pub inline_view_id: String,
pub linked_views: Vec<CreateViewParams>,
}

impl CreateDatabaseParams {
pub fn from_view(view: DatabaseView, fields: Vec<Field>, rows: Vec<CreateRowParams>) -> Self {
let mut params: Self = view.into();
params.fields = fields;
params.created_rows = rows;
params
}

pub fn split(self) -> (Vec<CreateRowParams>, Vec<Field>, 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<DatabaseView> 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: gen_database_view_id(),
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()
}],
}
}
}
Expand Down
41 changes: 25 additions & 16 deletions collab-database/tests/database_test/helper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -66,8 +66,13 @@ 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 {
database_id: database_id.to_string(),
view_id: "v1".to_string(),
name: "my first database view".to_string(),
..Default::default()
}],
..Default::default()
};
let database = Database::create_with_inline_view(params, context).unwrap();
Expand Down Expand Up @@ -100,9 +105,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();
Expand Down Expand Up @@ -207,15 +215,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();
Expand Down
21 changes: 11 additions & 10 deletions collab-database/tests/user_test/async_test/script.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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],
}
}
Loading

0 comments on commit 9b61c20

Please sign in to comment.