205 lines
7.0 KiB
Rust
Raw Normal View History

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,
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 {
// 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.
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 }
}
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);
tracing::error!("parsing json: {}", s);
2022-08-14 23:01:53 +08:00
CollaborateError::internal().context(msg)
})?;
Ok(Self {
view: Arc::new(view),
delta,
})
}
pub fn from_revisions(view_id: &str, revisions: Vec<Revision>) -> CollaborateResult<Self> {
let delta: Delta = make_text_delta_from_revisions(revisions)?;
Self::from_delta(view_id, delta)
2022-08-14 23:01:53 +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
}
#[tracing::instrument(level = "trace", skip_all, err)]
pub fn insert_group(
&mut self,
field_id: &str,
field_type: &FieldTypeRevision,
group_configuration_rev: GroupConfigurationRevision,
) -> CollaborateResult<Option<GridViewRevisionChangeset>> {
self.modify(|view| {
2022-08-22 16:16:15 +08:00
// Only save one group
view.groups.clear();
view.groups.add_object(field_id, field_type, group_configuration_rev);
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,
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),
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| {
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> {
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>>> {
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| {
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 }))
}
}
}
}
}
}
#[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-09-12 10:44:33 +08:00
pub fn make_grid_view_delta(grid_view: &GridViewRevision) -> Delta {
let json = serde_json::to_string(grid_view).unwrap();
2022-09-12 10:44:33 +08:00
DeltaBuilder::new().insert(&json).build()
}