persistence.rs 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. use flowy_sync::{
  2. entities::{folder_info::FolderInfo, text_block_info::TextBlockInfo},
  3. errors::CollaborateError,
  4. protobuf::{RepeatedRevision as RepeatedRevisionPB, Revision as RevisionPB},
  5. server_document::*,
  6. server_folder::FolderCloudPersistence,
  7. util::{make_document_info_from_revisions_pb, make_folder_from_revisions_pb},
  8. };
  9. use lib_infra::future::BoxResultFuture;
  10. use std::{
  11. fmt::{Debug, Formatter},
  12. sync::Arc,
  13. };
  14. // For the moment, we use memory to cache the data, it will be implemented with
  15. // other storage. Like the Firestore,Dropbox.etc.
  16. pub trait RevisionCloudStorage: Send + Sync {
  17. fn set_revisions(&self, repeated_revision: RepeatedRevisionPB) -> BoxResultFuture<(), CollaborateError>;
  18. fn get_revisions(
  19. &self,
  20. object_id: &str,
  21. rev_ids: Option<Vec<i64>>,
  22. ) -> BoxResultFuture<RepeatedRevisionPB, CollaborateError>;
  23. fn reset_object(
  24. &self,
  25. object_id: &str,
  26. repeated_revision: RepeatedRevisionPB,
  27. ) -> BoxResultFuture<(), CollaborateError>;
  28. }
  29. pub(crate) struct LocalTextBlockCloudPersistence {
  30. storage: Arc<dyn RevisionCloudStorage>,
  31. }
  32. impl Debug for LocalTextBlockCloudPersistence {
  33. fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
  34. f.write_str("LocalRevisionCloudPersistence")
  35. }
  36. }
  37. impl std::default::Default for LocalTextBlockCloudPersistence {
  38. fn default() -> Self {
  39. LocalTextBlockCloudPersistence {
  40. storage: Arc::new(MemoryDocumentCloudStorage::default()),
  41. }
  42. }
  43. }
  44. impl FolderCloudPersistence for LocalTextBlockCloudPersistence {
  45. fn read_folder(&self, _user_id: &str, folder_id: &str) -> BoxResultFuture<FolderInfo, CollaborateError> {
  46. let storage = self.storage.clone();
  47. let folder_id = folder_id.to_owned();
  48. Box::pin(async move {
  49. let repeated_revision = storage.get_revisions(&folder_id, None).await?;
  50. match make_folder_from_revisions_pb(&folder_id, repeated_revision)? {
  51. Some(folder_info) => Ok(folder_info),
  52. None => Err(CollaborateError::record_not_found()),
  53. }
  54. })
  55. }
  56. fn create_folder(
  57. &self,
  58. _user_id: &str,
  59. folder_id: &str,
  60. repeated_revision: RepeatedRevisionPB,
  61. ) -> BoxResultFuture<Option<FolderInfo>, CollaborateError> {
  62. let folder_id = folder_id.to_owned();
  63. let storage = self.storage.clone();
  64. Box::pin(async move {
  65. let _ = storage.set_revisions(repeated_revision.clone()).await?;
  66. make_folder_from_revisions_pb(&folder_id, repeated_revision)
  67. })
  68. }
  69. fn save_folder_revisions(&self, repeated_revision: RepeatedRevisionPB) -> BoxResultFuture<(), CollaborateError> {
  70. let storage = self.storage.clone();
  71. Box::pin(async move {
  72. let _ = storage.set_revisions(repeated_revision).await?;
  73. Ok(())
  74. })
  75. }
  76. fn read_folder_revisions(
  77. &self,
  78. folder_id: &str,
  79. rev_ids: Option<Vec<i64>>,
  80. ) -> BoxResultFuture<Vec<RevisionPB>, CollaborateError> {
  81. let folder_id = folder_id.to_owned();
  82. let storage = self.storage.clone();
  83. Box::pin(async move {
  84. let mut repeated_revision = storage.get_revisions(&folder_id, rev_ids).await?;
  85. let revisions: Vec<RevisionPB> = repeated_revision.take_items().into();
  86. Ok(revisions)
  87. })
  88. }
  89. fn reset_folder(
  90. &self,
  91. folder_id: &str,
  92. repeated_revision: RepeatedRevisionPB,
  93. ) -> BoxResultFuture<(), CollaborateError> {
  94. let storage = self.storage.clone();
  95. let folder_id = folder_id.to_owned();
  96. Box::pin(async move {
  97. let _ = storage.reset_object(&folder_id, repeated_revision).await?;
  98. Ok(())
  99. })
  100. }
  101. }
  102. impl TextBlockCloudPersistence for LocalTextBlockCloudPersistence {
  103. fn read_text_block(&self, doc_id: &str) -> BoxResultFuture<TextBlockInfo, CollaborateError> {
  104. let storage = self.storage.clone();
  105. let doc_id = doc_id.to_owned();
  106. Box::pin(async move {
  107. let repeated_revision = storage.get_revisions(&doc_id, None).await?;
  108. match make_document_info_from_revisions_pb(&doc_id, repeated_revision)? {
  109. Some(document_info) => Ok(document_info),
  110. None => Err(CollaborateError::record_not_found()),
  111. }
  112. })
  113. }
  114. fn create_text_block(
  115. &self,
  116. doc_id: &str,
  117. repeated_revision: RepeatedRevisionPB,
  118. ) -> BoxResultFuture<Option<TextBlockInfo>, CollaborateError> {
  119. let doc_id = doc_id.to_owned();
  120. let storage = self.storage.clone();
  121. Box::pin(async move {
  122. let _ = storage.set_revisions(repeated_revision.clone()).await?;
  123. make_document_info_from_revisions_pb(&doc_id, repeated_revision)
  124. })
  125. }
  126. fn read_text_block_revisions(
  127. &self,
  128. doc_id: &str,
  129. rev_ids: Option<Vec<i64>>,
  130. ) -> BoxResultFuture<Vec<RevisionPB>, CollaborateError> {
  131. let doc_id = doc_id.to_owned();
  132. let storage = self.storage.clone();
  133. Box::pin(async move {
  134. let mut repeated_revision = storage.get_revisions(&doc_id, rev_ids).await?;
  135. let revisions: Vec<RevisionPB> = repeated_revision.take_items().into();
  136. Ok(revisions)
  137. })
  138. }
  139. fn save_text_block_revisions(
  140. &self,
  141. repeated_revision: RepeatedRevisionPB,
  142. ) -> BoxResultFuture<(), CollaborateError> {
  143. let storage = self.storage.clone();
  144. Box::pin(async move {
  145. let _ = storage.set_revisions(repeated_revision).await?;
  146. Ok(())
  147. })
  148. }
  149. fn reset_text_block(&self, doc_id: &str, revisions: RepeatedRevisionPB) -> BoxResultFuture<(), CollaborateError> {
  150. let storage = self.storage.clone();
  151. let doc_id = doc_id.to_owned();
  152. Box::pin(async move {
  153. let _ = storage.reset_object(&doc_id, revisions).await?;
  154. Ok(())
  155. })
  156. }
  157. }
  158. #[derive(Default)]
  159. struct MemoryDocumentCloudStorage {}
  160. impl RevisionCloudStorage for MemoryDocumentCloudStorage {
  161. fn set_revisions(&self, _repeated_revision: RepeatedRevisionPB) -> BoxResultFuture<(), CollaborateError> {
  162. Box::pin(async move { Ok(()) })
  163. }
  164. fn get_revisions(
  165. &self,
  166. _doc_id: &str,
  167. _rev_ids: Option<Vec<i64>>,
  168. ) -> BoxResultFuture<RepeatedRevisionPB, CollaborateError> {
  169. Box::pin(async move {
  170. let repeated_revisions = RepeatedRevisionPB::new();
  171. Ok(repeated_revisions)
  172. })
  173. }
  174. fn reset_object(
  175. &self,
  176. _doc_id: &str,
  177. _repeated_revision: RepeatedRevisionPB,
  178. ) -> BoxResultFuture<(), CollaborateError> {
  179. Box::pin(async move { Ok(()) })
  180. }
  181. }