436 lines
16 KiB
Rust
Raw Normal View History

2023-01-30 11:11:19 +08:00
use crate::errors::{internal_sync_error, SyncError, SyncResult};
use crate::util::cal_diff;
use flowy_sync::util::make_operations_from_revisions;
use grid_model::{
gen_block_id, gen_grid_id, DatabaseRevision, FieldRevision, FieldTypeRevision, GridBlockMetaRevision,
GridBlockMetaRevisionChangeset,
2022-03-11 21:36:00 +08:00
};
2023-01-30 11:11:19 +08:00
use lib_infra::util::md5;
2022-04-28 16:54:04 +08:00
use lib_infra::util::move_vec_element;
2022-10-22 21:57:44 +08:00
use lib_ot::core::{DeltaOperationBuilder, DeltaOperations, EmptyAttributes, OperationTransform};
2023-01-30 11:11:19 +08:00
use revision_model::Revision;
2022-03-11 21:36:00 +08:00
use std::collections::HashMap;
2022-03-04 18:11:12 +08:00
use std::sync::Arc;
pub type DatabaseOperations = DeltaOperations<EmptyAttributes>;
pub type DatabaseOperationsBuilder = DeltaOperationBuilder<EmptyAttributes>;
2022-03-04 18:11:12 +08:00
#[derive(Clone)]
pub struct DatabaseRevisionPad {
grid_rev: Arc<DatabaseRevision>,
operations: DatabaseOperations,
2022-03-04 18:11:12 +08:00
}
2022-04-07 08:33:10 +08:00
pub trait JsonDeserializer {
2023-01-30 11:11:19 +08:00
fn deserialize(&self, type_option_data: Vec<u8>) -> SyncResult<String>;
}
impl DatabaseRevisionPad {
2022-06-30 23:00:03 +08:00
pub fn grid_id(&self) -> String {
self.grid_rev.grid_id.clone()
}
2022-06-26 15:14:24 +08:00
pub async fn duplicate_grid_block_meta(&self) -> (Vec<FieldRevision>, Vec<GridBlockMetaRevision>) {
2022-07-01 10:36:07 +08:00
let fields = self
.grid_rev
.fields
.iter()
.map(|field_rev| field_rev.as_ref().clone())
.collect();
2022-06-06 20:06:08 +08:00
let blocks = self
.grid_rev
2022-06-06 20:06:08 +08:00
.blocks
.iter()
.map(|block| {
let mut duplicated_block = (**block).clone();
2022-06-06 20:06:08 +08:00
duplicated_block.block_id = gen_block_id();
duplicated_block
})
2022-06-26 15:14:24 +08:00
.collect::<Vec<GridBlockMetaRevision>>();
2022-06-06 20:06:08 +08:00
(fields, blocks)
}
pub fn from_operations(operations: DatabaseOperations) -> SyncResult<Self> {
let content = operations.content()?;
let grid: DatabaseRevision = serde_json::from_str(&content).map_err(|e| {
let msg = format!("Deserialize operations to grid failed: {}", e);
tracing::error!("{}", msg);
2023-01-30 11:11:19 +08:00
SyncError::internal().context(msg)
})?;
2022-03-04 18:11:12 +08:00
Ok(Self {
grid_rev: Arc::new(grid),
operations,
2022-03-04 18:11:12 +08:00
})
}
2023-01-30 11:11:19 +08:00
pub fn from_revisions(revisions: Vec<Revision>) -> SyncResult<Self> {
let operations: DatabaseOperations = make_operations_from_revisions(revisions)?;
Self::from_operations(operations)
2022-03-04 18:11:12 +08:00
}
2022-04-05 14:25:07 +08:00
#[tracing::instrument(level = "debug", skip_all, err)]
pub fn create_field_rev(
2022-03-25 20:55:56 +08:00
&mut self,
new_field_rev: FieldRevision,
2022-03-25 20:55:56 +08:00
start_field_id: Option<String>,
) -> SyncResult<Option<DatabaseRevisionChangeset>> {
2022-04-07 08:33:10 +08:00
self.modify_grid(|grid_meta| {
2022-03-24 17:09:05 +08:00
// Check if the field exists or not
2022-04-07 08:33:10 +08:00
if grid_meta
.fields
.iter()
.any(|field_rev| field_rev.id == new_field_rev.id)
2022-04-07 08:33:10 +08:00
{
2022-03-31 22:51:46 +08:00
tracing::error!("Duplicate grid field");
return Ok(None);
}
let insert_index = match start_field_id {
None => None,
2022-04-07 08:33:10 +08:00
Some(start_field_id) => grid_meta.fields.iter().position(|field| field.id == start_field_id),
};
2022-07-01 10:36:07 +08:00
let new_field_rev = Arc::new(new_field_rev);
match insert_index {
None => grid_meta.fields.push(new_field_rev),
Some(index) => grid_meta.fields.insert(index, new_field_rev),
2022-03-13 11:06:28 +08:00
}
Ok(Some(()))
2022-03-04 18:11:12 +08:00
})
}
pub fn delete_field_rev(&mut self, field_id: &str) -> SyncResult<Option<DatabaseRevisionChangeset>> {
2022-04-07 08:33:10 +08:00
self.modify_grid(
|grid_meta| match grid_meta.fields.iter().position(|field| field.id == field_id) {
None => Ok(None),
Some(index) => {
2022-09-23 11:23:35 +08:00
if grid_meta.fields[index].is_primary {
2023-01-30 11:11:19 +08:00
Err(SyncError::can_not_delete_primary_field())
2022-09-23 11:23:35 +08:00
} else {
grid_meta.fields.remove(index);
Ok(Some(()))
}
2022-04-07 08:33:10 +08:00
}
},
)
2022-03-04 18:11:12 +08:00
}
pub fn duplicate_field_rev(
2022-04-14 13:29:42 +08:00
&mut self,
field_id: &str,
duplicated_field_id: &str,
) -> SyncResult<Option<DatabaseRevisionChangeset>> {
2022-04-14 13:29:42 +08:00
self.modify_grid(
|grid_meta| match grid_meta.fields.iter().position(|field| field.id == field_id) {
None => Ok(None),
Some(index) => {
2022-07-01 10:36:07 +08:00
let mut duplicate_field_rev = grid_meta.fields[index].as_ref().clone();
duplicate_field_rev.id = duplicated_field_id.to_string();
duplicate_field_rev.name = format!("{} (copy)", duplicate_field_rev.name);
2022-07-01 10:36:07 +08:00
grid_meta.fields.insert(index + 1, Arc::new(duplicate_field_rev));
2022-04-14 13:29:42 +08:00
Ok(Some(()))
}
},
)
2022-03-11 21:36:00 +08:00
}
2022-10-10 19:44:41 +08:00
/// Modifies the current field type of the [FieldTypeRevision]
///
/// # Arguments
///
/// * `field_id`: the id of the field
/// * `field_type`: the new field type of the field
/// * `make_default_type_option`: create the field type's type-option data
/// * `type_option_transform`: create the field type's type-option data
2022-10-10 19:44:41 +08:00
///
///
pub fn switch_to_field<DT, TT, T>(
2022-04-01 22:46:01 +08:00
&mut self,
field_id: &str,
new_field_type: T,
make_default_type_option: DT,
type_option_transform: TT,
) -> SyncResult<Option<DatabaseRevisionChangeset>>
2022-04-01 22:46:01 +08:00
where
DT: FnOnce() -> String,
TT: FnOnce(FieldTypeRevision, Option<String>, String) -> String,
T: Into<FieldTypeRevision>,
2022-04-01 22:46:01 +08:00
{
let new_field_type = new_field_type.into();
2022-04-07 08:33:10 +08:00
self.modify_grid(|grid_meta| {
match grid_meta.fields.iter_mut().find(|field_rev| field_rev.id == field_id) {
2022-04-01 22:46:01 +08:00
None => {
tracing::warn!("Can not find the field with id: {}", field_id);
Ok(None)
}
Some(field_rev) => {
2022-07-01 10:36:07 +08:00
let mut_field_rev = Arc::make_mut(field_rev);
let old_field_type_rev = mut_field_rev.ty;
let old_field_type_option = mut_field_rev
.get_type_option_str(mut_field_rev.ty)
.map(|value| value.to_owned());
match mut_field_rev.get_type_option_str(new_field_type) {
Some(new_field_type_option) => {
let transformed_type_option = type_option_transform(
old_field_type_rev,
old_field_type_option,
new_field_type_option.to_owned(),
);
mut_field_rev.insert_type_option_str(&new_field_type, transformed_type_option);
}
None => {
// If the type-option data isn't exist before, creating the default type-option data.
let new_field_type_option = make_default_type_option();
let transformed_type_option =
type_option_transform(old_field_type_rev, old_field_type_option, new_field_type_option);
mut_field_rev.insert_type_option_str(&new_field_type, transformed_type_option);
}
2022-04-01 22:46:01 +08:00
}
mut_field_rev.ty = new_field_type;
2022-04-01 22:46:01 +08:00
Ok(Some(()))
}
}
})
}
pub fn replace_field_rev(
&mut self,
field_rev: Arc<FieldRevision>,
) -> SyncResult<Option<DatabaseRevisionChangeset>> {
2022-04-07 08:33:10 +08:00
self.modify_grid(
|grid_meta| match grid_meta.fields.iter().position(|field| field.id == field_rev.id) {
2022-04-07 08:33:10 +08:00
None => Ok(None),
Some(index) => {
grid_meta.fields.remove(index);
grid_meta.fields.insert(index, field_rev);
2022-04-07 08:33:10 +08:00
Ok(Some(()))
}
},
)
}
2022-04-15 19:56:44 +08:00
pub fn move_field(
&mut self,
field_id: &str,
2022-04-28 16:54:04 +08:00
from_index: usize,
2022-04-15 19:56:44 +08:00
to_index: usize,
) -> SyncResult<Option<DatabaseRevisionChangeset>> {
2022-04-28 16:54:04 +08:00
self.modify_grid(|grid_meta| {
match move_vec_element(
&mut grid_meta.fields,
|field| field.id == field_id,
from_index,
to_index,
)
2023-01-30 11:11:19 +08:00
.map_err(internal_sync_error)?
2022-04-28 16:54:04 +08:00
{
true => Ok(Some(())),
false => Ok(None),
}
})
2022-04-15 19:56:44 +08:00
}
2022-03-27 11:14:21 +08:00
pub fn contain_field(&self, field_id: &str) -> bool {
self.grid_rev.fields.iter().any(|field| field.id == field_id)
2022-03-27 11:14:21 +08:00
}
pub fn get_field_rev(&self, field_id: &str) -> Option<(usize, &Arc<FieldRevision>)> {
self.grid_rev
.fields
.iter()
.enumerate()
.find(|(_, field)| field.id == field_id)
}
2023-01-30 11:11:19 +08:00
pub fn get_field_revs(&self, field_ids: Option<Vec<String>>) -> SyncResult<Vec<Arc<FieldRevision>>> {
match field_ids {
None => Ok(self.grid_rev.fields.clone()),
Some(field_ids) => {
2022-03-27 11:14:21 +08:00
let field_by_field_id = self
.grid_rev
2022-03-27 11:14:21 +08:00
.fields
.iter()
.map(|field| (&field.id, field))
2022-07-01 10:36:07 +08:00
.collect::<HashMap<&String, &Arc<FieldRevision>>>();
2022-03-27 11:14:21 +08:00
let fields = field_ids
2022-03-27 11:14:21 +08:00
.iter()
.flat_map(|field_id| match field_by_field_id.get(&field_id) {
2022-03-27 11:14:21 +08:00
None => {
tracing::error!("Can't find the field with id: {}", field_id);
2022-03-27 11:14:21 +08:00
None
}
Some(field) => Some((*field).clone()),
})
2022-07-01 10:36:07 +08:00
.collect::<Vec<Arc<FieldRevision>>>();
2022-03-27 11:14:21 +08:00
Ok(fields)
}
}
}
pub fn create_block_meta_rev(
&mut self,
block: GridBlockMetaRevision,
) -> SyncResult<Option<DatabaseRevisionChangeset>> {
2022-04-07 08:33:10 +08:00
self.modify_grid(|grid_meta| {
if grid_meta.blocks.iter().any(|b| b.block_id == block.block_id) {
2022-03-13 11:06:28 +08:00
tracing::warn!("Duplicate grid block");
Ok(None)
} else {
match grid_meta.blocks.last() {
2022-06-24 18:13:40 +08:00
None => grid_meta.blocks.push(Arc::new(block)),
2022-03-15 11:07:18 +08:00
Some(last_block) => {
if last_block.start_row_index > block.start_row_index
&& last_block.len() > block.start_row_index
{
2022-03-16 10:02:37 +08:00
let msg = "GridBlock's start_row_index should be greater than the last_block's start_row_index and its len".to_string();
2023-01-30 11:11:19 +08:00
return Err(SyncError::internal().context(msg))
2022-03-15 11:07:18 +08:00
}
2022-06-24 18:13:40 +08:00
grid_meta.blocks.push(Arc::new(block));
2022-03-15 11:07:18 +08:00
}
}
2022-03-13 11:06:28 +08:00
Ok(Some(()))
}
2022-03-11 21:36:00 +08:00
})
}
2022-06-26 15:14:24 +08:00
pub fn get_block_meta_revs(&self) -> Vec<Arc<GridBlockMetaRevision>> {
self.grid_rev.blocks.clone()
2022-03-12 09:30:13 +08:00
}
2022-06-20 09:37:52 +08:00
pub fn update_block_rev(
&mut self,
2022-06-26 15:14:24 +08:00
changeset: GridBlockMetaRevisionChangeset,
) -> SyncResult<Option<DatabaseRevisionChangeset>> {
2022-03-14 17:24:25 +08:00
let block_id = changeset.block_id.clone();
2022-03-11 21:36:00 +08:00
self.modify_block(&block_id, |block| {
let mut is_changed = None;
2022-03-14 17:24:25 +08:00
if let Some(row_count) = changeset.row_count {
2022-03-11 21:36:00 +08:00
block.row_count = row_count;
is_changed = Some(());
}
2022-03-14 17:24:25 +08:00
if let Some(start_row_index) = changeset.start_row_index {
2022-03-13 11:06:28 +08:00
block.start_row_index = start_row_index;
is_changed = Some(());
}
2022-03-11 21:36:00 +08:00
Ok(is_changed)
})
}
pub fn database_md5(&self) -> String {
md5(&self.operations.json_bytes())
2022-03-05 22:30:42 +08:00
}
pub fn operations_json_str(&self) -> String {
self.operations.json_str()
2022-03-15 19:00:28 +08:00
}
pub fn get_fields(&self) -> &[Arc<FieldRevision>] {
&self.grid_rev.fields
2022-03-05 17:52:25 +08:00
}
fn modify_grid<F>(&mut self, f: F) -> SyncResult<Option<DatabaseRevisionChangeset>>
2022-03-04 18:11:12 +08:00
where
F: FnOnce(&mut DatabaseRevision) -> SyncResult<Option<()>>,
2022-03-04 18:11:12 +08:00
{
let cloned_grid = self.grid_rev.clone();
match f(Arc::make_mut(&mut self.grid_rev))? {
2022-03-04 18:11:12 +08:00
None => Ok(None),
Some(_) => {
let old = make_database_rev_json_str(&cloned_grid)?;
2022-07-20 18:27:12 +08:00
let new = self.json_str()?;
2022-09-12 10:44:33 +08:00
match cal_diff::<EmptyAttributes>(old, new) {
2022-03-04 18:11:12 +08:00
None => Ok(None),
Some(operations) => {
self.operations = self.operations.compose(&operations)?;
Ok(Some(DatabaseRevisionChangeset {
operations,
md5: self.database_md5(),
}))
2022-03-04 18:11:12 +08:00
}
}
}
}
}
2022-03-11 21:36:00 +08:00
fn modify_block<F>(&mut self, block_id: &str, f: F) -> SyncResult<Option<DatabaseRevisionChangeset>>
2022-03-11 21:36:00 +08:00
where
2023-01-30 11:11:19 +08:00
F: FnOnce(&mut GridBlockMetaRevision) -> SyncResult<Option<()>>,
2022-03-11 21:36:00 +08:00
{
self.modify_grid(
2022-06-20 09:37:52 +08:00
|grid_rev| match grid_rev.blocks.iter().position(|block| block.block_id == block_id) {
2022-03-17 17:25:43 +08:00
None => {
tracing::warn!("[GridMetaPad]: Can't find any block with id: {}", block_id);
Ok(None)
}
2022-06-24 18:13:40 +08:00
Some(index) => {
let block_rev = Arc::make_mut(&mut grid_rev.blocks[index]);
f(block_rev)
}
},
)
2022-03-11 21:36:00 +08:00
}
pub fn modify_field<F>(&mut self, field_id: &str, f: F) -> SyncResult<Option<DatabaseRevisionChangeset>>
2022-03-11 21:36:00 +08:00
where
2023-01-30 11:11:19 +08:00
F: FnOnce(&mut FieldRevision) -> SyncResult<Option<()>>,
2022-03-11 21:36:00 +08:00
{
2022-04-07 08:33:10 +08:00
self.modify_grid(
2022-06-20 09:37:52 +08:00
|grid_rev| match grid_rev.fields.iter().position(|field| field.id == field_id) {
2022-04-07 08:33:10 +08:00
None => {
tracing::warn!("[GridMetaPad]: Can't find any field with id: {}", field_id);
Ok(None)
}
2022-07-01 10:36:07 +08:00
Some(index) => {
let mut_field_rev = Arc::make_mut(&mut grid_rev.fields[index]);
f(mut_field_rev)
}
2022-04-07 08:33:10 +08:00
},
)
2022-03-11 21:36:00 +08:00
}
2022-07-20 18:27:12 +08:00
2023-01-30 11:11:19 +08:00
pub fn json_str(&self) -> SyncResult<String> {
make_database_rev_json_str(&self.grid_rev)
2022-07-20 18:27:12 +08:00
}
2022-03-04 18:11:12 +08:00
}
pub fn make_database_rev_json_str(grid_revision: &DatabaseRevision) -> SyncResult<String> {
2022-08-14 23:01:53 +08:00
let json = serde_json::to_string(grid_revision)
2023-01-30 11:11:19 +08:00
.map_err(|err| internal_sync_error(format!("Serialize grid to json str failed. {:?}", err)))?;
2022-03-04 18:11:12 +08:00
Ok(json)
}
pub struct DatabaseRevisionChangeset {
pub operations: DatabaseOperations,
2022-03-04 18:11:12 +08:00
/// md5: the md5 of the grid after applying the change.
pub md5: String,
}
pub fn make_database_operations(grid_rev: &DatabaseRevision) -> DatabaseOperations {
let json = serde_json::to_string(&grid_rev).unwrap();
DatabaseOperationsBuilder::new().insert(&json).build()
2022-03-04 18:11:12 +08:00
}
pub fn make_database_revisions(_user_id: &str, grid_rev: &DatabaseRevision) -> Vec<Revision> {
let operations = make_database_operations(grid_rev);
let bytes = operations.json_bytes();
2022-11-02 17:15:27 +08:00
let revision = Revision::initial_revision(&grid_rev.grid_id, bytes);
vec![revision]
2022-03-05 10:59:44 +08:00
}
impl std::default::Default for DatabaseRevisionPad {
2022-03-04 18:11:12 +08:00
fn default() -> Self {
let grid = DatabaseRevision::new(&gen_grid_id());
let operations = make_database_operations(&grid);
DatabaseRevisionPad {
grid_rev: Arc::new(grid),
operations,
2022-03-04 18:11:12 +08:00
}
}
}