grid_revision_pad.rs 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570
  1. use crate::entities::grid::{FieldChangesetParams, GridSettingChangesetParams};
  2. use crate::entities::revision::{md5, RepeatedRevision, Revision};
  3. use crate::errors::{internal_error, CollaborateError, CollaborateResult};
  4. use crate::util::{cal_diff, make_delta_from_revisions};
  5. use bytes::Bytes;
  6. use flowy_grid_data_model::revision::{
  7. gen_block_id, gen_grid_filter_id, gen_grid_group_id, gen_grid_id, gen_grid_sort_id, FieldRevision,
  8. FieldTypeRevision, GridBlockMetaRevision, GridBlockMetaRevisionChangeset, GridFilterRevision, GridGroupRevision,
  9. GridLayoutRevision, GridRevision, GridSettingRevision, GridSortRevision,
  10. };
  11. use lib_infra::util::move_vec_element;
  12. use lib_ot::core::{OperationTransform, PhantomAttributes, PlainTextDelta, PlainTextDeltaBuilder};
  13. use std::collections::HashMap;
  14. use std::sync::Arc;
  15. pub type GridRevisionDelta = PlainTextDelta;
  16. pub type GridRevisionDeltaBuilder = PlainTextDeltaBuilder;
  17. pub struct GridRevisionPad {
  18. grid_rev: Arc<GridRevision>,
  19. delta: GridRevisionDelta,
  20. }
  21. pub trait JsonDeserializer {
  22. fn deserialize(&self, type_option_data: Vec<u8>) -> CollaborateResult<String>;
  23. }
  24. impl GridRevisionPad {
  25. pub fn grid_id(&self) -> String {
  26. self.grid_rev.grid_id.clone()
  27. }
  28. pub async fn duplicate_grid_block_meta(&self) -> (Vec<FieldRevision>, Vec<GridBlockMetaRevision>) {
  29. let fields = self
  30. .grid_rev
  31. .fields
  32. .iter()
  33. .map(|field_rev| field_rev.as_ref().clone())
  34. .collect();
  35. let blocks = self
  36. .grid_rev
  37. .blocks
  38. .iter()
  39. .map(|block| {
  40. let mut duplicated_block = (&*block.clone()).clone();
  41. duplicated_block.block_id = gen_block_id();
  42. duplicated_block
  43. })
  44. .collect::<Vec<GridBlockMetaRevision>>();
  45. (fields, blocks)
  46. }
  47. pub fn from_delta(delta: GridRevisionDelta) -> CollaborateResult<Self> {
  48. let content = delta.content_str()?;
  49. let grid: GridRevision = serde_json::from_str(&content)
  50. .map_err(|e| CollaborateError::internal().context(format!("Deserialize delta to grid failed: {}", e)))?;
  51. Ok(Self {
  52. grid_rev: Arc::new(grid),
  53. delta,
  54. })
  55. }
  56. pub fn from_revisions(revisions: Vec<Revision>) -> CollaborateResult<Self> {
  57. let grid_delta: GridRevisionDelta = make_delta_from_revisions::<PhantomAttributes>(revisions)?;
  58. Self::from_delta(grid_delta)
  59. }
  60. #[tracing::instrument(level = "debug", skip_all, err)]
  61. pub fn create_field_rev(
  62. &mut self,
  63. new_field_rev: FieldRevision,
  64. start_field_id: Option<String>,
  65. ) -> CollaborateResult<Option<GridChangeset>> {
  66. self.modify_grid(|grid_meta| {
  67. // Check if the field exists or not
  68. if grid_meta
  69. .fields
  70. .iter()
  71. .any(|field_rev| field_rev.id == new_field_rev.id)
  72. {
  73. tracing::error!("Duplicate grid field");
  74. return Ok(None);
  75. }
  76. let insert_index = match start_field_id {
  77. None => None,
  78. Some(start_field_id) => grid_meta.fields.iter().position(|field| field.id == start_field_id),
  79. };
  80. let new_field_rev = Arc::new(new_field_rev);
  81. match insert_index {
  82. None => grid_meta.fields.push(new_field_rev),
  83. Some(index) => grid_meta.fields.insert(index, new_field_rev),
  84. }
  85. Ok(Some(()))
  86. })
  87. }
  88. pub fn delete_field_rev(&mut self, field_id: &str) -> CollaborateResult<Option<GridChangeset>> {
  89. self.modify_grid(
  90. |grid_meta| match grid_meta.fields.iter().position(|field| field.id == field_id) {
  91. None => Ok(None),
  92. Some(index) => {
  93. grid_meta.fields.remove(index);
  94. Ok(Some(()))
  95. }
  96. },
  97. )
  98. }
  99. pub fn duplicate_field_rev(
  100. &mut self,
  101. field_id: &str,
  102. duplicated_field_id: &str,
  103. ) -> CollaborateResult<Option<GridChangeset>> {
  104. self.modify_grid(
  105. |grid_meta| match grid_meta.fields.iter().position(|field| field.id == field_id) {
  106. None => Ok(None),
  107. Some(index) => {
  108. let mut duplicate_field_rev = grid_meta.fields[index].as_ref().clone();
  109. duplicate_field_rev.id = duplicated_field_id.to_string();
  110. duplicate_field_rev.name = format!("{} (copy)", duplicate_field_rev.name);
  111. grid_meta.fields.insert(index + 1, Arc::new(duplicate_field_rev));
  112. Ok(Some(()))
  113. }
  114. },
  115. )
  116. }
  117. pub fn switch_to_field<B, T>(
  118. &mut self,
  119. field_id: &str,
  120. field_type: T,
  121. type_option_json_builder: B,
  122. ) -> CollaborateResult<Option<GridChangeset>>
  123. where
  124. B: FnOnce(&FieldTypeRevision) -> String,
  125. T: Into<FieldTypeRevision>,
  126. {
  127. let field_type = field_type.into();
  128. self.modify_grid(|grid_meta| {
  129. //
  130. match grid_meta.fields.iter_mut().find(|field_rev| field_rev.id == field_id) {
  131. None => {
  132. tracing::warn!("Can not find the field with id: {}", field_id);
  133. Ok(None)
  134. }
  135. Some(field_rev) => {
  136. let mut_field_rev = Arc::make_mut(field_rev);
  137. if mut_field_rev.get_type_option_str(field_type).is_none() {
  138. let type_option_json = type_option_json_builder(&field_type);
  139. mut_field_rev.insert_type_option_str(&field_type, type_option_json);
  140. }
  141. mut_field_rev.field_type_rev = field_type;
  142. Ok(Some(()))
  143. }
  144. }
  145. })
  146. }
  147. pub fn update_field_rev<T: JsonDeserializer>(
  148. &mut self,
  149. changeset: FieldChangesetParams,
  150. deserializer: T,
  151. ) -> CollaborateResult<Option<GridChangeset>> {
  152. let field_id = changeset.field_id.clone();
  153. self.modify_field(&field_id, |field| {
  154. let mut is_changed = None;
  155. if let Some(name) = changeset.name {
  156. field.name = name;
  157. is_changed = Some(())
  158. }
  159. if let Some(desc) = changeset.desc {
  160. field.desc = desc;
  161. is_changed = Some(())
  162. }
  163. if let Some(field_type) = changeset.field_type {
  164. field.field_type_rev = field_type;
  165. is_changed = Some(())
  166. }
  167. if let Some(frozen) = changeset.frozen {
  168. field.frozen = frozen;
  169. is_changed = Some(())
  170. }
  171. if let Some(visibility) = changeset.visibility {
  172. field.visibility = visibility;
  173. is_changed = Some(())
  174. }
  175. if let Some(width) = changeset.width {
  176. field.width = width;
  177. is_changed = Some(())
  178. }
  179. if let Some(type_option_data) = changeset.type_option_data {
  180. match deserializer.deserialize(type_option_data) {
  181. Ok(json_str) => {
  182. let field_type = field.field_type_rev;
  183. field.insert_type_option_str(&field_type, json_str);
  184. is_changed = Some(())
  185. }
  186. Err(err) => {
  187. tracing::error!("Deserialize data to type option json failed: {}", err);
  188. }
  189. }
  190. }
  191. Ok(is_changed)
  192. })
  193. }
  194. pub fn get_field_rev(&self, field_id: &str) -> Option<(usize, &Arc<FieldRevision>)> {
  195. self.grid_rev
  196. .fields
  197. .iter()
  198. .enumerate()
  199. .find(|(_, field)| field.id == field_id)
  200. }
  201. pub fn replace_field_rev(&mut self, field_rev: Arc<FieldRevision>) -> CollaborateResult<Option<GridChangeset>> {
  202. self.modify_grid(
  203. |grid_meta| match grid_meta.fields.iter().position(|field| field.id == field_rev.id) {
  204. None => Ok(None),
  205. Some(index) => {
  206. grid_meta.fields.remove(index);
  207. grid_meta.fields.insert(index, field_rev);
  208. Ok(Some(()))
  209. }
  210. },
  211. )
  212. }
  213. pub fn move_field(
  214. &mut self,
  215. field_id: &str,
  216. from_index: usize,
  217. to_index: usize,
  218. ) -> CollaborateResult<Option<GridChangeset>> {
  219. self.modify_grid(|grid_meta| {
  220. match move_vec_element(
  221. &mut grid_meta.fields,
  222. |field| field.id == field_id,
  223. from_index,
  224. to_index,
  225. )
  226. .map_err(internal_error)?
  227. {
  228. true => Ok(Some(())),
  229. false => Ok(None),
  230. }
  231. })
  232. }
  233. pub fn contain_field(&self, field_id: &str) -> bool {
  234. self.grid_rev.fields.iter().any(|field| field.id == field_id)
  235. }
  236. pub fn get_field_revs(&self, field_ids: Option<Vec<String>>) -> CollaborateResult<Vec<Arc<FieldRevision>>> {
  237. match field_ids {
  238. None => Ok(self.grid_rev.fields.clone()),
  239. Some(field_ids) => {
  240. let field_by_field_id = self
  241. .grid_rev
  242. .fields
  243. .iter()
  244. .map(|field| (&field.id, field))
  245. .collect::<HashMap<&String, &Arc<FieldRevision>>>();
  246. let fields = field_ids
  247. .iter()
  248. .flat_map(|field_id| match field_by_field_id.get(&field_id) {
  249. None => {
  250. tracing::error!("Can't find the field with id: {}", field_id);
  251. None
  252. }
  253. Some(field) => Some((*field).clone()),
  254. })
  255. .collect::<Vec<Arc<FieldRevision>>>();
  256. Ok(fields)
  257. }
  258. }
  259. }
  260. pub fn create_block_meta_rev(&mut self, block: GridBlockMetaRevision) -> CollaborateResult<Option<GridChangeset>> {
  261. self.modify_grid(|grid_meta| {
  262. if grid_meta.blocks.iter().any(|b| b.block_id == block.block_id) {
  263. tracing::warn!("Duplicate grid block");
  264. Ok(None)
  265. } else {
  266. match grid_meta.blocks.last() {
  267. None => grid_meta.blocks.push(Arc::new(block)),
  268. Some(last_block) => {
  269. if last_block.start_row_index > block.start_row_index
  270. && last_block.len() > block.start_row_index
  271. {
  272. let msg = "GridBlock's start_row_index should be greater than the last_block's start_row_index and its len".to_string();
  273. return Err(CollaborateError::internal().context(msg))
  274. }
  275. grid_meta.blocks.push(Arc::new(block));
  276. }
  277. }
  278. Ok(Some(()))
  279. }
  280. })
  281. }
  282. pub fn get_block_meta_revs(&self) -> Vec<Arc<GridBlockMetaRevision>> {
  283. self.grid_rev.blocks.clone()
  284. }
  285. pub fn update_block_rev(
  286. &mut self,
  287. changeset: GridBlockMetaRevisionChangeset,
  288. ) -> CollaborateResult<Option<GridChangeset>> {
  289. let block_id = changeset.block_id.clone();
  290. self.modify_block(&block_id, |block| {
  291. let mut is_changed = None;
  292. if let Some(row_count) = changeset.row_count {
  293. block.row_count = row_count;
  294. is_changed = Some(());
  295. }
  296. if let Some(start_row_index) = changeset.start_row_index {
  297. block.start_row_index = start_row_index;
  298. is_changed = Some(());
  299. }
  300. Ok(is_changed)
  301. })
  302. }
  303. pub fn get_grid_setting_rev(&self) -> &GridSettingRevision {
  304. &self.grid_rev.setting
  305. }
  306. /// If layout is None, then the default layout will be the read from GridSettingRevision
  307. pub fn get_filters(
  308. &self,
  309. layout: Option<&GridLayoutRevision>,
  310. field_ids: Option<Vec<String>>,
  311. ) -> Option<Vec<Arc<GridFilterRevision>>> {
  312. let mut filter_revs = vec![];
  313. let layout_ty = layout.unwrap_or(&self.grid_rev.setting.layout);
  314. let field_revs = self.get_field_revs(None).ok()?;
  315. field_revs.iter().for_each(|field_rev| {
  316. let mut is_contain = true;
  317. if let Some(field_ids) = &field_ids {
  318. is_contain = field_ids.contains(&field_rev.id);
  319. }
  320. if is_contain {
  321. // Only return the filters for the current fields' type.
  322. let field_id = &field_rev.id;
  323. let field_type_rev = &field_rev.field_type_rev;
  324. if let Some(mut t_filter_revs) = self.grid_rev.setting.get_filters(layout_ty, field_id, field_type_rev)
  325. {
  326. filter_revs.append(&mut t_filter_revs);
  327. }
  328. }
  329. });
  330. Some(filter_revs)
  331. }
  332. pub fn update_grid_setting_rev(
  333. &mut self,
  334. changeset: GridSettingChangesetParams,
  335. ) -> CollaborateResult<Option<GridChangeset>> {
  336. self.modify_grid(|grid_rev| {
  337. let mut is_changed = None;
  338. let layout_rev = changeset.layout_type;
  339. if let Some(params) = changeset.insert_filter {
  340. let filter_rev = GridFilterRevision {
  341. id: gen_grid_filter_id(),
  342. field_id: params.field_id.clone(),
  343. condition: params.condition,
  344. content: params.content,
  345. };
  346. grid_rev
  347. .setting
  348. .insert_filter(&layout_rev, &params.field_id, &params.field_type_rev, filter_rev);
  349. is_changed = Some(())
  350. }
  351. if let Some(params) = changeset.delete_filter {
  352. match grid_rev
  353. .setting
  354. .get_mut_filters(&layout_rev, &params.field_id, &params.field_type_rev)
  355. {
  356. Some(filters) => {
  357. filters.retain(|filter| filter.id != params.filter_id);
  358. }
  359. None => {
  360. tracing::warn!("Can't find the filter with {:?}", layout_rev);
  361. }
  362. }
  363. }
  364. if let Some(params) = changeset.insert_group {
  365. let rev = GridGroupRevision {
  366. id: gen_grid_group_id(),
  367. field_id: params.field_id,
  368. sub_field_id: params.sub_field_id,
  369. };
  370. grid_rev
  371. .setting
  372. .groups
  373. .entry(layout_rev.clone())
  374. .or_insert_with(std::vec::Vec::new)
  375. .push(rev);
  376. is_changed = Some(())
  377. }
  378. if let Some(delete_group_id) = changeset.delete_group {
  379. match grid_rev.setting.groups.get_mut(&layout_rev) {
  380. Some(groups) => groups.retain(|group| group.id != delete_group_id),
  381. None => {
  382. tracing::warn!("Can't find the group with {:?}", layout_rev);
  383. }
  384. }
  385. }
  386. if let Some(sort) = changeset.insert_sort {
  387. let rev = GridSortRevision {
  388. id: gen_grid_sort_id(),
  389. field_id: sort.field_id,
  390. };
  391. grid_rev
  392. .setting
  393. .sorts
  394. .entry(layout_rev.clone())
  395. .or_insert_with(std::vec::Vec::new)
  396. .push(rev);
  397. is_changed = Some(())
  398. }
  399. if let Some(delete_sort_id) = changeset.delete_sort {
  400. match grid_rev.setting.sorts.get_mut(&layout_rev) {
  401. Some(sorts) => sorts.retain(|sort| sort.id != delete_sort_id),
  402. None => {
  403. tracing::warn!("Can't find the sort with {:?}", layout_rev);
  404. }
  405. }
  406. }
  407. Ok(is_changed)
  408. })
  409. }
  410. pub fn md5(&self) -> String {
  411. md5(&self.delta.to_json_bytes())
  412. }
  413. pub fn delta_str(&self) -> String {
  414. self.delta.to_json_str()
  415. }
  416. pub fn delta_bytes(&self) -> Bytes {
  417. self.delta.to_json_bytes()
  418. }
  419. pub fn fields(&self) -> &[Arc<FieldRevision>] {
  420. &self.grid_rev.fields
  421. }
  422. fn modify_grid<F>(&mut self, f: F) -> CollaborateResult<Option<GridChangeset>>
  423. where
  424. F: FnOnce(&mut GridRevision) -> CollaborateResult<Option<()>>,
  425. {
  426. let cloned_grid = self.grid_rev.clone();
  427. match f(Arc::make_mut(&mut self.grid_rev))? {
  428. None => Ok(None),
  429. Some(_) => {
  430. let old = make_grid_rev_json_str(&cloned_grid)?;
  431. let new = self.json_str()?;
  432. match cal_diff::<PhantomAttributes>(old, new) {
  433. None => Ok(None),
  434. Some(delta) => {
  435. self.delta = self.delta.compose(&delta)?;
  436. Ok(Some(GridChangeset { delta, md5: self.md5() }))
  437. }
  438. }
  439. }
  440. }
  441. }
  442. fn modify_block<F>(&mut self, block_id: &str, f: F) -> CollaborateResult<Option<GridChangeset>>
  443. where
  444. F: FnOnce(&mut GridBlockMetaRevision) -> CollaborateResult<Option<()>>,
  445. {
  446. self.modify_grid(
  447. |grid_rev| match grid_rev.blocks.iter().position(|block| block.block_id == block_id) {
  448. None => {
  449. tracing::warn!("[GridMetaPad]: Can't find any block with id: {}", block_id);
  450. Ok(None)
  451. }
  452. Some(index) => {
  453. let block_rev = Arc::make_mut(&mut grid_rev.blocks[index]);
  454. f(block_rev)
  455. }
  456. },
  457. )
  458. }
  459. fn modify_field<F>(&mut self, field_id: &str, f: F) -> CollaborateResult<Option<GridChangeset>>
  460. where
  461. F: FnOnce(&mut FieldRevision) -> CollaborateResult<Option<()>>,
  462. {
  463. self.modify_grid(
  464. |grid_rev| match grid_rev.fields.iter().position(|field| field.id == field_id) {
  465. None => {
  466. tracing::warn!("[GridMetaPad]: Can't find any field with id: {}", field_id);
  467. Ok(None)
  468. }
  469. Some(index) => {
  470. let mut_field_rev = Arc::make_mut(&mut grid_rev.fields[index]);
  471. f(mut_field_rev)
  472. }
  473. },
  474. )
  475. }
  476. pub fn json_str(&self) -> CollaborateResult<String> {
  477. make_grid_rev_json_str(&self.grid_rev)
  478. }
  479. }
  480. pub fn make_grid_rev_json_str(grid: &GridRevision) -> CollaborateResult<String> {
  481. let json = serde_json::to_string(grid)
  482. .map_err(|err| internal_error(format!("Serialize grid to json str failed. {:?}", err)))?;
  483. Ok(json)
  484. }
  485. pub struct GridChangeset {
  486. pub delta: GridRevisionDelta,
  487. /// md5: the md5 of the grid after applying the change.
  488. pub md5: String,
  489. }
  490. pub fn make_grid_delta(grid_rev: &GridRevision) -> GridRevisionDelta {
  491. let json = serde_json::to_string(&grid_rev).unwrap();
  492. PlainTextDeltaBuilder::new().insert(&json).build()
  493. }
  494. pub fn make_grid_revisions(user_id: &str, grid_rev: &GridRevision) -> RepeatedRevision {
  495. let delta = make_grid_delta(grid_rev);
  496. let bytes = delta.to_json_bytes();
  497. let revision = Revision::initial_revision(user_id, &grid_rev.grid_id, bytes);
  498. revision.into()
  499. }
  500. impl std::default::Default for GridRevisionPad {
  501. fn default() -> Self {
  502. let grid = GridRevision::new(&gen_grid_id());
  503. let delta = make_grid_delta(&grid);
  504. GridRevisionPad {
  505. grid_rev: Arc::new(grid),
  506. delta,
  507. }
  508. }
  509. }