view_revision_pad.rs 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. use crate::entities::revision::{md5, Revision};
  2. use crate::errors::{internal_error, CollaborateError, CollaborateResult};
  3. use crate::util::{cal_diff, make_text_delta_from_revisions};
  4. use flowy_grid_data_model::revision::{
  5. FieldRevision, FieldTypeRevision, FilterConfigurationRevision, FilterConfigurationsByFieldId, GridViewRevision,
  6. GroupConfigurationRevision, GroupConfigurationsByFieldId, LayoutRevision,
  7. };
  8. use lib_ot::core::{Delta, DeltaBuilder, EmptyAttributes, OperationTransform};
  9. use std::sync::Arc;
  10. #[derive(Debug, Clone)]
  11. pub struct GridViewRevisionPad {
  12. view: Arc<GridViewRevision>,
  13. delta: Delta,
  14. }
  15. impl std::ops::Deref for GridViewRevisionPad {
  16. type Target = GridViewRevision;
  17. fn deref(&self) -> &Self::Target {
  18. &self.view
  19. }
  20. }
  21. impl GridViewRevisionPad {
  22. // For the moment, the view_id is equal to grid_id. The grid_id represents the database id.
  23. // A database can be referenced by multiple views.
  24. pub fn new(grid_id: String, view_id: String, layout: LayoutRevision) -> Self {
  25. let view = Arc::new(GridViewRevision::new(grid_id, view_id, layout));
  26. let json = serde_json::to_string(&view).unwrap();
  27. let delta = DeltaBuilder::new().insert(&json).build();
  28. Self { view, delta }
  29. }
  30. pub fn from_delta(view_id: &str, delta: Delta) -> CollaborateResult<Self> {
  31. if delta.is_empty() {
  32. return Ok(GridViewRevisionPad::new(
  33. view_id.to_owned(),
  34. view_id.to_owned(),
  35. LayoutRevision::Table,
  36. ));
  37. }
  38. let s = delta.content()?;
  39. let view: GridViewRevision = serde_json::from_str(&s).map_err(|e| {
  40. let msg = format!("Deserialize delta to GridViewRevision failed: {}", e);
  41. tracing::error!("parsing json: {}", s);
  42. CollaborateError::internal().context(msg)
  43. })?;
  44. Ok(Self {
  45. view: Arc::new(view),
  46. delta,
  47. })
  48. }
  49. pub fn from_revisions(view_id: &str, revisions: Vec<Revision>) -> CollaborateResult<Self> {
  50. let delta: Delta = make_text_delta_from_revisions(revisions)?;
  51. Self::from_delta(view_id, delta)
  52. }
  53. pub fn get_groups_by_field_revs(&self, field_revs: &[Arc<FieldRevision>]) -> Option<GroupConfigurationsByFieldId> {
  54. self.groups.get_objects_by_field_revs(field_revs)
  55. }
  56. pub fn get_all_groups(&self) -> Vec<Arc<GroupConfigurationRevision>> {
  57. self.groups.get_all_objects()
  58. }
  59. #[tracing::instrument(level = "trace", skip_all, err)]
  60. pub fn insert_or_update_group_configuration(
  61. &mut self,
  62. field_id: &str,
  63. field_type: &FieldTypeRevision,
  64. group_configuration_rev: GroupConfigurationRevision,
  65. ) -> CollaborateResult<Option<GridViewRevisionChangeset>> {
  66. self.modify(|view| {
  67. // Only save one group
  68. view.groups.clear();
  69. view.groups.add_object(field_id, field_type, group_configuration_rev);
  70. Ok(Some(()))
  71. })
  72. }
  73. #[tracing::instrument(level = "trace", skip_all)]
  74. pub fn contains_group(&self, field_id: &str, field_type: &FieldTypeRevision) -> bool {
  75. self.view.groups.get_objects(field_id, field_type).is_some()
  76. }
  77. #[tracing::instrument(level = "trace", skip_all, err)]
  78. pub fn with_mut_group<F: FnOnce(&mut GroupConfigurationRevision)>(
  79. &mut self,
  80. field_id: &str,
  81. field_type: &FieldTypeRevision,
  82. configuration_id: &str,
  83. mut_configuration_fn: F,
  84. ) -> CollaborateResult<Option<GridViewRevisionChangeset>> {
  85. self.modify(|view| match view.groups.get_mut_objects(field_id, field_type) {
  86. None => Ok(None),
  87. Some(configurations_revs) => {
  88. for configuration_rev in configurations_revs {
  89. if configuration_rev.id == configuration_id {
  90. mut_configuration_fn(Arc::make_mut(configuration_rev));
  91. return Ok(Some(()));
  92. }
  93. }
  94. Ok(None)
  95. }
  96. })
  97. }
  98. pub fn delete_group(
  99. &mut self,
  100. field_id: &str,
  101. field_type: &FieldTypeRevision,
  102. group_id: &str,
  103. ) -> CollaborateResult<Option<GridViewRevisionChangeset>> {
  104. self.modify(|view| {
  105. if let Some(groups) = view.groups.get_mut_objects(field_id, field_type) {
  106. groups.retain(|group| group.id != group_id);
  107. Ok(Some(()))
  108. } else {
  109. Ok(None)
  110. }
  111. })
  112. }
  113. pub fn get_all_filters(&self, field_revs: &[Arc<FieldRevision>]) -> Option<FilterConfigurationsByFieldId> {
  114. self.filters.get_objects_by_field_revs(field_revs)
  115. }
  116. pub fn get_filters(
  117. &self,
  118. field_id: &str,
  119. field_type_rev: &FieldTypeRevision,
  120. ) -> Option<Vec<Arc<FilterConfigurationRevision>>> {
  121. self.filters.get_objects(field_id, field_type_rev)
  122. }
  123. pub fn insert_filter(
  124. &mut self,
  125. field_id: &str,
  126. field_type: &FieldTypeRevision,
  127. filter_rev: FilterConfigurationRevision,
  128. ) -> CollaborateResult<Option<GridViewRevisionChangeset>> {
  129. self.modify(|view| {
  130. view.filters.add_object(field_id, field_type, filter_rev);
  131. Ok(Some(()))
  132. })
  133. }
  134. pub fn delete_filter(
  135. &mut self,
  136. field_id: &str,
  137. field_type: &FieldTypeRevision,
  138. filter_id: &str,
  139. ) -> CollaborateResult<Option<GridViewRevisionChangeset>> {
  140. self.modify(|view| {
  141. if let Some(filters) = view.filters.get_mut_objects(field_id, field_type) {
  142. filters.retain(|filter| filter.id != filter_id);
  143. Ok(Some(()))
  144. } else {
  145. Ok(None)
  146. }
  147. })
  148. }
  149. pub fn json_str(&self) -> CollaborateResult<String> {
  150. make_grid_view_rev_json_str(&self.view)
  151. }
  152. pub fn layout(&self) -> LayoutRevision {
  153. self.layout.clone()
  154. }
  155. fn modify<F>(&mut self, f: F) -> CollaborateResult<Option<GridViewRevisionChangeset>>
  156. where
  157. F: FnOnce(&mut GridViewRevision) -> CollaborateResult<Option<()>>,
  158. {
  159. let cloned_view = self.view.clone();
  160. match f(Arc::make_mut(&mut self.view))? {
  161. None => Ok(None),
  162. Some(_) => {
  163. let old = make_grid_view_rev_json_str(&cloned_view)?;
  164. let new = self.json_str()?;
  165. match cal_diff::<EmptyAttributes>(old, new) {
  166. None => Ok(None),
  167. Some(delta) => {
  168. self.delta = self.delta.compose(&delta)?;
  169. let md5 = md5(&self.delta.json_bytes());
  170. Ok(Some(GridViewRevisionChangeset { delta, md5 }))
  171. }
  172. }
  173. }
  174. }
  175. }
  176. }
  177. #[derive(Debug)]
  178. pub struct GridViewRevisionChangeset {
  179. pub delta: Delta,
  180. pub md5: String,
  181. }
  182. pub fn make_grid_view_rev_json_str(grid_revision: &GridViewRevision) -> CollaborateResult<String> {
  183. let json = serde_json::to_string(grid_revision)
  184. .map_err(|err| internal_error(format!("Serialize grid view to json str failed. {:?}", err)))?;
  185. Ok(json)
  186. }
  187. pub fn make_grid_view_delta(grid_view: &GridViewRevision) -> Delta {
  188. let json = serde_json::to_string(grid_view).unwrap();
  189. DeltaBuilder::new().insert(&json).build()
  190. }