grid_editor.rs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. use crate::manager::GridUser;
  2. use crate::services::block_meta_editor::GridBlockMetaEditorManager;
  3. use bytes::Bytes;
  4. use flowy_collaboration::client_grid::{GridChange, GridMetaPad};
  5. use flowy_collaboration::entities::revision::Revision;
  6. use flowy_collaboration::util::make_delta_from_revisions;
  7. use flowy_error::{FlowyError, FlowyResult};
  8. use flowy_grid_data_model::entities::{
  9. CellMetaChangeset, FieldChangeset, FieldMeta, Grid, GridBlock, GridBlockChangeset, RepeatedFieldOrder,
  10. RepeatedRowOrder, Row, RowMeta, RowMetaChangeset,
  11. };
  12. use std::collections::HashMap;
  13. use crate::services::row::{
  14. make_row_by_row_id, make_rows, row_meta_from_context, serialize_cell_data, RowMetaContext, RowMetaContextBuilder,
  15. };
  16. use flowy_sync::{RevisionCloudService, RevisionCompactor, RevisionManager, RevisionObjectBuilder};
  17. use lib_infra::future::FutureResult;
  18. use lib_ot::core::PlainTextAttributes;
  19. use std::sync::Arc;
  20. use tokio::sync::RwLock;
  21. pub struct ClientGridEditor {
  22. grid_id: String,
  23. user: Arc<dyn GridUser>,
  24. grid_meta_pad: Arc<RwLock<GridMetaPad>>,
  25. rev_manager: Arc<RevisionManager>,
  26. block_meta_manager: Arc<GridBlockMetaEditorManager>,
  27. }
  28. impl ClientGridEditor {
  29. pub async fn new(
  30. grid_id: &str,
  31. user: Arc<dyn GridUser>,
  32. mut rev_manager: RevisionManager,
  33. ) -> FlowyResult<Arc<Self>> {
  34. let token = user.token()?;
  35. let cloud = Arc::new(GridRevisionCloudService { token });
  36. let grid_pad = rev_manager.load::<GridPadBuilder>(Some(cloud)).await?;
  37. let rev_manager = Arc::new(rev_manager);
  38. let grid_meta_pad = Arc::new(RwLock::new(grid_pad));
  39. let block_meta_manager =
  40. Arc::new(GridBlockMetaEditorManager::new(&user, grid_meta_pad.read().await.get_blocks().clone()).await?);
  41. Ok(Arc::new(Self {
  42. grid_id: grid_id.to_owned(),
  43. user,
  44. grid_meta_pad,
  45. rev_manager,
  46. block_meta_manager,
  47. }))
  48. }
  49. pub async fn create_field(&self, field_meta: FieldMeta) -> FlowyResult<()> {
  50. let _ = self.modify(|grid| Ok(grid.create_field(field_meta)?)).await?;
  51. Ok(())
  52. }
  53. pub async fn contain_field(&self, field_meta: &FieldMeta) -> bool {
  54. self.grid_meta_pad.read().await.contain_field(&field_meta.id)
  55. }
  56. pub async fn update_field(&self, change: FieldChangeset) -> FlowyResult<()> {
  57. let _ = self.modify(|grid| Ok(grid.update_field(change)?)).await?;
  58. Ok(())
  59. }
  60. pub async fn delete_field(&self, field_id: &str) -> FlowyResult<()> {
  61. let _ = self.modify(|grid| Ok(grid.delete_field(field_id)?)).await?;
  62. Ok(())
  63. }
  64. pub async fn create_block(&self, grid_block: GridBlock) -> FlowyResult<()> {
  65. let _ = self.modify(|grid| Ok(grid.create_block(grid_block)?)).await?;
  66. Ok(())
  67. }
  68. pub async fn update_block(&self, changeset: GridBlockChangeset) -> FlowyResult<()> {
  69. let _ = self.modify(|grid| Ok(grid.update_block(changeset)?)).await?;
  70. Ok(())
  71. }
  72. pub async fn create_row(&self, upper_row_id: Option<String>) -> FlowyResult<Row> {
  73. let field_metas = self.grid_meta_pad.read().await.get_field_metas(None)?;
  74. let block_id = self.last_block_id().await?;
  75. // insert empty row below the row whose id is upper_row_id
  76. let row_meta_ctx = RowMetaContextBuilder::new(&field_metas).build();
  77. let row_meta = row_meta_from_context(&block_id, row_meta_ctx);
  78. // insert the row
  79. let row_count = self
  80. .block_meta_manager
  81. .create_row(row_meta.clone(), upper_row_id)
  82. .await?;
  83. let row = make_rows(&field_metas, vec![row_meta.into()]).pop().unwrap();
  84. // update block row count
  85. let changeset = GridBlockChangeset::from_row_count(&block_id, row_count);
  86. let _ = self.update_block(changeset).await?;
  87. Ok(row)
  88. }
  89. pub async fn insert_rows(&self, contexts: Vec<RowMetaContext>) -> FlowyResult<()> {
  90. let block_id = self.last_block_id().await?;
  91. let mut rows_by_block_id: HashMap<String, Vec<RowMeta>> = HashMap::new();
  92. for ctx in contexts {
  93. let row_meta = row_meta_from_context(&block_id, ctx);
  94. rows_by_block_id
  95. .entry(block_id.clone())
  96. .or_insert_with(Vec::new)
  97. .push(row_meta);
  98. }
  99. let changesets = self.block_meta_manager.insert_row(rows_by_block_id).await?;
  100. for changeset in changesets {
  101. let _ = self.update_block(changeset).await?;
  102. }
  103. Ok(())
  104. }
  105. pub async fn update_row(&self, changeset: RowMetaChangeset) -> FlowyResult<()> {
  106. self.block_meta_manager.update_row(changeset).await
  107. }
  108. pub async fn update_cell(&self, changeset: CellMetaChangeset) -> FlowyResult<()> {
  109. if let Some(cell_data) = changeset.data.as_ref() {
  110. match self.grid_meta_pad.read().await.get_field(&changeset.field_id) {
  111. None => {
  112. return Err(FlowyError::internal()
  113. .context(format!("Can not find the field with id: {}", &changeset.field_id)));
  114. }
  115. Some(field_meta) => {
  116. let _ = serialize_cell_data(cell_data, field_meta)?;
  117. }
  118. }
  119. }
  120. let row_changeset: RowMetaChangeset = changeset.into();
  121. self.update_row(row_changeset).await
  122. }
  123. pub async fn get_rows(&self, row_orders: Option<RepeatedRowOrder>) -> FlowyResult<Vec<Row>> {
  124. let row_metas = self.get_row_metas(row_orders.as_ref()).await?;
  125. let field_meta = self.grid_meta_pad.read().await.get_field_metas(None)?;
  126. match row_orders {
  127. None => Ok(make_rows(&field_meta, row_metas)),
  128. Some(row_orders) => {
  129. let mut row_map: HashMap<String, Row> = make_row_by_row_id(&field_meta, row_metas);
  130. let rows = row_orders
  131. .iter()
  132. .flat_map(|row_order| row_map.remove(&row_order.row_id))
  133. .collect::<Vec<_>>();
  134. Ok(rows)
  135. }
  136. }
  137. }
  138. pub async fn get_row_metas(&self, row_orders: Option<&RepeatedRowOrder>) -> FlowyResult<Vec<Arc<RowMeta>>> {
  139. match row_orders {
  140. None => {
  141. let grid_blocks = self.grid_meta_pad.read().await.get_blocks();
  142. let row_metas = self.block_meta_manager.get_all_rows(grid_blocks).await?;
  143. Ok(row_metas)
  144. }
  145. Some(row_orders) => {
  146. let row_metas = self.block_meta_manager.get_rows(row_orders).await?;
  147. Ok(row_metas)
  148. }
  149. }
  150. }
  151. pub async fn delete_rows(&self, row_ids: Vec<String>) -> FlowyResult<()> {
  152. let changesets = self.block_meta_manager.delete_rows(row_ids).await?;
  153. for changeset in changesets {
  154. let _ = self.update_block(changeset).await?;
  155. }
  156. Ok(())
  157. }
  158. pub async fn grid_data(&self) -> FlowyResult<Grid> {
  159. let field_orders = self.grid_meta_pad.read().await.get_field_orders();
  160. let grid_blocks = self.grid_meta_pad.read().await.get_blocks();
  161. let row_orders = self.block_meta_manager.get_row_orders(grid_blocks).await?;
  162. Ok(Grid {
  163. id: self.grid_id.clone(),
  164. field_orders,
  165. row_orders,
  166. })
  167. }
  168. pub async fn get_field_metas(&self, field_orders: Option<RepeatedFieldOrder>) -> FlowyResult<Vec<FieldMeta>> {
  169. let field_meta = self.grid_meta_pad.read().await.get_field_metas(field_orders)?;
  170. Ok(field_meta)
  171. }
  172. pub async fn get_blocks(&self) -> FlowyResult<Vec<GridBlock>> {
  173. let grid_blocks = self.grid_meta_pad.read().await.get_blocks();
  174. Ok(grid_blocks)
  175. }
  176. pub async fn delta_bytes(&self) -> Bytes {
  177. self.grid_meta_pad.read().await.delta_bytes()
  178. }
  179. async fn modify<F>(&self, f: F) -> FlowyResult<()>
  180. where
  181. F: for<'a> FnOnce(&'a mut GridMetaPad) -> FlowyResult<Option<GridChange>>,
  182. {
  183. let mut write_guard = self.grid_meta_pad.write().await;
  184. match f(&mut *write_guard)? {
  185. None => {}
  186. Some(change) => {
  187. let _ = self.apply_change(change).await?;
  188. }
  189. }
  190. Ok(())
  191. }
  192. async fn apply_change(&self, change: GridChange) -> FlowyResult<()> {
  193. let GridChange { delta, md5 } = change;
  194. let user_id = self.user.user_id()?;
  195. let (base_rev_id, rev_id) = self.rev_manager.next_rev_id_pair();
  196. let delta_data = delta.to_delta_bytes();
  197. let revision = Revision::new(
  198. &self.rev_manager.object_id,
  199. base_rev_id,
  200. rev_id,
  201. delta_data,
  202. &user_id,
  203. md5,
  204. );
  205. let _ = self
  206. .rev_manager
  207. .add_local_revision(&revision, Box::new(GridRevisionCompactor()))
  208. .await?;
  209. Ok(())
  210. }
  211. async fn last_block_id(&self) -> FlowyResult<String> {
  212. match self.grid_meta_pad.read().await.get_blocks().last() {
  213. None => Err(FlowyError::internal().context("There is no grid block in this grid")),
  214. Some(grid_block) => Ok(grid_block.id.clone()),
  215. }
  216. }
  217. }
  218. #[cfg(feature = "flowy_unit_test")]
  219. impl ClientGridEditor {
  220. pub fn rev_manager(&self) -> Arc<RevisionManager> {
  221. self.rev_manager.clone()
  222. }
  223. }
  224. pub struct GridPadBuilder();
  225. impl RevisionObjectBuilder for GridPadBuilder {
  226. type Output = GridMetaPad;
  227. fn build_object(object_id: &str, revisions: Vec<Revision>) -> FlowyResult<Self::Output> {
  228. let pad = GridMetaPad::from_revisions(object_id, revisions)?;
  229. Ok(pad)
  230. }
  231. }
  232. struct GridRevisionCloudService {
  233. #[allow(dead_code)]
  234. token: String,
  235. }
  236. impl RevisionCloudService for GridRevisionCloudService {
  237. #[tracing::instrument(level = "trace", skip(self))]
  238. fn fetch_object(&self, _user_id: &str, _object_id: &str) -> FutureResult<Vec<Revision>, FlowyError> {
  239. FutureResult::new(async move { Ok(vec![]) })
  240. }
  241. }
  242. struct GridRevisionCompactor();
  243. impl RevisionCompactor for GridRevisionCompactor {
  244. fn bytes_from_revisions(&self, revisions: Vec<Revision>) -> FlowyResult<Bytes> {
  245. let delta = make_delta_from_revisions::<PlainTextAttributes>(revisions)?;
  246. Ok(delta.to_delta_bytes())
  247. }
  248. }