grid_revision_pad.rs 20 KB

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