2022-08-14 23:01:53 +08:00
|
|
|
use crate::entities::revision::{md5, Revision};
|
|
|
|
use crate::errors::{internal_error, CollaborateError, CollaborateResult};
|
2022-08-14 23:11:30 +08:00
|
|
|
use crate::util::{cal_diff, make_text_delta_from_revisions};
|
2022-08-14 23:01:53 +08:00
|
|
|
use flowy_grid_data_model::revision::{
|
2022-08-19 23:11:05 +08:00
|
|
|
FieldRevision, FieldTypeRevision, FilterConfigurationRevision, FilterConfigurationsByFieldId, GridViewRevision,
|
2022-08-20 15:40:13 +08:00
|
|
|
GroupConfigurationRevision, GroupConfigurationsByFieldId,
|
2022-08-14 23:01:53 +08:00
|
|
|
};
|
2022-09-12 10:44:33 +08:00
|
|
|
use lib_ot::core::{Delta, DeltaBuilder, EmptyAttributes, OperationTransform};
|
2022-08-14 23:01:53 +08:00
|
|
|
use std::sync::Arc;
|
|
|
|
|
|
|
|
#[derive(Debug, Clone)]
|
|
|
|
pub struct GridViewRevisionPad {
|
|
|
|
view: Arc<GridViewRevision>,
|
2022-09-12 10:44:33 +08:00
|
|
|
delta: Delta,
|
2022-08-14 23:01:53 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
impl std::ops::Deref for GridViewRevisionPad {
|
|
|
|
type Target = GridViewRevision;
|
|
|
|
|
|
|
|
fn deref(&self) -> &Self::Target {
|
|
|
|
&self.view
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl GridViewRevisionPad {
|
2022-09-16 13:15:13 +08:00
|
|
|
// For the moment, the view_id is equal to grid_id. The grid_id represents the database id.
|
|
|
|
// A database can be referenced by multiple views.
|
2022-08-15 23:17:29 +08:00
|
|
|
pub fn new(grid_id: String, view_id: String) -> Self {
|
|
|
|
let view = Arc::new(GridViewRevision::new(grid_id, view_id));
|
2022-08-14 23:01:53 +08:00
|
|
|
let json = serde_json::to_string(&view).unwrap();
|
2022-09-12 10:44:33 +08:00
|
|
|
let delta = DeltaBuilder::new().insert(&json).build();
|
2022-08-14 23:01:53 +08:00
|
|
|
Self { view, delta }
|
|
|
|
}
|
|
|
|
|
2022-09-16 13:15:13 +08:00
|
|
|
pub fn from_delta(view_id: &str, delta: Delta) -> CollaborateResult<Self> {
|
|
|
|
if delta.is_empty() {
|
|
|
|
return Ok(GridViewRevisionPad::new(view_id.to_owned(), view_id.to_owned()));
|
|
|
|
}
|
2022-08-14 23:01:53 +08:00
|
|
|
let s = delta.content()?;
|
|
|
|
let view: GridViewRevision = serde_json::from_str(&s).map_err(|e| {
|
|
|
|
let msg = format!("Deserialize delta to GridViewRevision failed: {}", e);
|
2022-09-16 13:15:13 +08:00
|
|
|
tracing::error!("parsing json: {}", s);
|
2022-08-14 23:01:53 +08:00
|
|
|
CollaborateError::internal().context(msg)
|
|
|
|
})?;
|
|
|
|
Ok(Self {
|
|
|
|
view: Arc::new(view),
|
|
|
|
delta,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2022-09-16 13:15:13 +08:00
|
|
|
pub fn from_revisions(view_id: &str, revisions: Vec<Revision>) -> CollaborateResult<Self> {
|
2022-09-16 20:00:51 +08:00
|
|
|
let delta: Delta = make_text_delta_from_revisions(revisions)?;
|
2022-09-16 13:15:13 +08:00
|
|
|
Self::from_delta(view_id, delta)
|
2022-08-14 23:01:53 +08:00
|
|
|
}
|
|
|
|
|
2022-09-02 21:34:00 +08:00
|
|
|
pub fn get_groups_by_field_revs(&self, field_revs: &[Arc<FieldRevision>]) -> Option<GroupConfigurationsByFieldId> {
|
|
|
|
self.groups.get_objects_by_field_revs(field_revs)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_all_groups(&self) -> Vec<Arc<GroupConfigurationRevision>> {
|
|
|
|
self.groups.get_all_objects()
|
2022-08-14 23:01:53 +08:00
|
|
|
}
|
|
|
|
|
2022-08-21 22:47:24 +08:00
|
|
|
#[tracing::instrument(level = "trace", skip_all, err)]
|
|
|
|
pub fn insert_group(
|
|
|
|
&mut self,
|
|
|
|
field_id: &str,
|
|
|
|
field_type: &FieldTypeRevision,
|
2022-09-04 15:33:07 +08:00
|
|
|
group_configuration_rev: GroupConfigurationRevision,
|
2022-08-21 22:47:24 +08:00
|
|
|
) -> CollaborateResult<Option<GridViewRevisionChangeset>> {
|
|
|
|
self.modify(|view| {
|
2022-08-22 16:16:15 +08:00
|
|
|
// Only save one group
|
|
|
|
view.groups.clear();
|
2022-09-04 15:33:07 +08:00
|
|
|
view.groups.add_object(field_id, field_type, group_configuration_rev);
|
2022-08-21 22:47:24 +08:00
|
|
|
Ok(Some(()))
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
#[tracing::instrument(level = "trace", skip_all)]
|
|
|
|
pub fn contains_group(&self, field_id: &str, field_type: &FieldTypeRevision) -> bool {
|
|
|
|
self.view.groups.get_objects(field_id, field_type).is_some()
|
|
|
|
}
|
|
|
|
|
|
|
|
#[tracing::instrument(level = "trace", skip_all, err)]
|
|
|
|
pub fn with_mut_group<F: FnOnce(&mut GroupConfigurationRevision)>(
|
2022-08-20 17:10:34 +08:00
|
|
|
&mut self,
|
|
|
|
field_id: &str,
|
|
|
|
field_type: &FieldTypeRevision,
|
2022-08-20 23:54:51 +08:00
|
|
|
configuration_id: &str,
|
|
|
|
mut_configuration_fn: F,
|
2022-08-20 17:10:34 +08:00
|
|
|
) -> CollaborateResult<Option<GridViewRevisionChangeset>> {
|
|
|
|
self.modify(|view| match view.groups.get_mut_objects(field_id, field_type) {
|
|
|
|
None => Ok(None),
|
2022-08-20 23:54:51 +08:00
|
|
|
Some(configurations_revs) => {
|
|
|
|
for configuration_rev in configurations_revs {
|
|
|
|
if configuration_rev.id == configuration_id {
|
|
|
|
mut_configuration_fn(Arc::make_mut(configuration_rev));
|
2022-08-20 17:10:34 +08:00
|
|
|
return Ok(Some(()));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Ok(None)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2022-08-14 23:01:53 +08:00
|
|
|
pub fn delete_group(
|
|
|
|
&mut self,
|
|
|
|
field_id: &str,
|
|
|
|
field_type: &FieldTypeRevision,
|
|
|
|
group_id: &str,
|
|
|
|
) -> CollaborateResult<Option<GridViewRevisionChangeset>> {
|
|
|
|
self.modify(|view| {
|
2022-08-20 15:40:13 +08:00
|
|
|
if let Some(groups) = view.groups.get_mut_objects(field_id, field_type) {
|
2022-08-14 23:01:53 +08:00
|
|
|
groups.retain(|group| group.id != group_id);
|
|
|
|
Ok(Some(()))
|
|
|
|
} else {
|
|
|
|
Ok(None)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_all_filters(&self, field_revs: &[Arc<FieldRevision>]) -> Option<FilterConfigurationsByFieldId> {
|
2022-09-02 21:34:00 +08:00
|
|
|
self.filters.get_objects_by_field_revs(field_revs)
|
2022-08-14 23:01:53 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_filters(
|
|
|
|
&self,
|
|
|
|
field_id: &str,
|
|
|
|
field_type_rev: &FieldTypeRevision,
|
|
|
|
) -> Option<Vec<Arc<FilterConfigurationRevision>>> {
|
2022-08-20 15:40:13 +08:00
|
|
|
self.filters.get_objects(field_id, field_type_rev)
|
2022-08-14 23:01:53 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn insert_filter(
|
|
|
|
&mut self,
|
|
|
|
field_id: &str,
|
|
|
|
field_type: &FieldTypeRevision,
|
|
|
|
filter_rev: FilterConfigurationRevision,
|
|
|
|
) -> CollaborateResult<Option<GridViewRevisionChangeset>> {
|
|
|
|
self.modify(|view| {
|
2022-08-22 16:16:15 +08:00
|
|
|
view.filters.add_object(field_id, field_type, filter_rev);
|
2022-08-14 23:01:53 +08:00
|
|
|
Ok(Some(()))
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn delete_filter(
|
|
|
|
&mut self,
|
|
|
|
field_id: &str,
|
|
|
|
field_type: &FieldTypeRevision,
|
|
|
|
filter_id: &str,
|
|
|
|
) -> CollaborateResult<Option<GridViewRevisionChangeset>> {
|
|
|
|
self.modify(|view| {
|
2022-08-20 15:40:13 +08:00
|
|
|
if let Some(filters) = view.filters.get_mut_objects(field_id, field_type) {
|
2022-08-14 23:01:53 +08:00
|
|
|
filters.retain(|filter| filter.id != filter_id);
|
|
|
|
Ok(Some(()))
|
|
|
|
} else {
|
|
|
|
Ok(None)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn json_str(&self) -> CollaborateResult<String> {
|
|
|
|
make_grid_view_rev_json_str(&self.view)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn modify<F>(&mut self, f: F) -> CollaborateResult<Option<GridViewRevisionChangeset>>
|
|
|
|
where
|
|
|
|
F: FnOnce(&mut GridViewRevision) -> CollaborateResult<Option<()>>,
|
|
|
|
{
|
|
|
|
let cloned_view = self.view.clone();
|
|
|
|
match f(Arc::make_mut(&mut self.view))? {
|
|
|
|
None => Ok(None),
|
|
|
|
Some(_) => {
|
|
|
|
let old = make_grid_view_rev_json_str(&cloned_view)?;
|
|
|
|
let new = self.json_str()?;
|
2022-09-12 10:44:33 +08:00
|
|
|
match cal_diff::<EmptyAttributes>(old, new) {
|
2022-08-14 23:01:53 +08:00
|
|
|
None => Ok(None),
|
|
|
|
Some(delta) => {
|
|
|
|
self.delta = self.delta.compose(&delta)?;
|
|
|
|
let md5 = md5(&self.delta.json_bytes());
|
|
|
|
Ok(Some(GridViewRevisionChangeset { delta, md5 }))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-08-20 23:54:51 +08:00
|
|
|
#[derive(Debug)]
|
2022-08-14 23:01:53 +08:00
|
|
|
pub struct GridViewRevisionChangeset {
|
2022-09-12 10:44:33 +08:00
|
|
|
pub delta: Delta,
|
2022-08-14 23:01:53 +08:00
|
|
|
pub md5: String,
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn make_grid_view_rev_json_str(grid_revision: &GridViewRevision) -> CollaborateResult<String> {
|
|
|
|
let json = serde_json::to_string(grid_revision)
|
|
|
|
.map_err(|err| internal_error(format!("Serialize grid view to json str failed. {:?}", err)))?;
|
|
|
|
Ok(json)
|
|
|
|
}
|
2022-08-15 23:17:29 +08:00
|
|
|
|
2022-09-12 10:44:33 +08:00
|
|
|
pub fn make_grid_view_delta(grid_view: &GridViewRevision) -> Delta {
|
2022-08-15 23:17:29 +08:00
|
|
|
let json = serde_json::to_string(grid_view).unwrap();
|
2022-09-12 10:44:33 +08:00
|
|
|
DeltaBuilder::new().insert(&json).build()
|
2022-08-15 23:17:29 +08:00
|
|
|
}
|