|
@@ -6,14 +6,20 @@ use crate::{
|
|
|
use flowy_database::kv::KV;
|
|
|
use flowy_error::{FlowyError, FlowyResult};
|
|
|
|
|
|
-use flowy_folder_data_model::revision::{AppRevision, ViewRevision, WorkspaceRevision};
|
|
|
+use flowy_folder_data_model::revision::{AppRevision, FolderRevision, ViewRevision, WorkspaceRevision};
|
|
|
use flowy_revision::disk::SQLiteTextBlockRevisionPersistence;
|
|
|
-use flowy_revision::{RevisionLoader, RevisionPersistence};
|
|
|
+use flowy_revision::reset::{RevisionResettable, RevisionStructReset};
|
|
|
+
|
|
|
+use flowy_sync::client_folder::make_folder_rev_json_str;
|
|
|
+use flowy_sync::entities::revision::Revision;
|
|
|
use flowy_sync::{client_folder::FolderPad, entities::revision::md5};
|
|
|
+
|
|
|
use std::sync::Arc;
|
|
|
|
|
|
const V1_MIGRATION: &str = "FOLDER_V1_MIGRATION";
|
|
|
const V2_MIGRATION: &str = "FOLDER_V2_MIGRATION";
|
|
|
+#[allow(dead_code)]
|
|
|
+const V3_MIGRATION: &str = "FOLDER_V3_MIGRATION";
|
|
|
|
|
|
pub(crate) struct FolderMigration {
|
|
|
user_id: String,
|
|
@@ -79,32 +85,58 @@ impl FolderMigration {
|
|
|
Ok(Some(folder))
|
|
|
}
|
|
|
|
|
|
- pub async fn run_v2_migration(&self, user_id: &str, folder_id: &FolderId) -> FlowyResult<Option<FolderPad>> {
|
|
|
+ pub async fn run_v2_migration(&self, folder_id: &FolderId) -> FlowyResult<()> {
|
|
|
let key = md5(format!("{}{}", self.user_id, V2_MIGRATION));
|
|
|
if KV::get_bool(&key) {
|
|
|
- return Ok(None);
|
|
|
+ return Ok(());
|
|
|
}
|
|
|
- let pool = self.database.db_pool()?;
|
|
|
- let disk_cache = SQLiteTextBlockRevisionPersistence::new(user_id, pool);
|
|
|
- let rev_persistence = Arc::new(RevisionPersistence::new(user_id, folder_id.as_ref(), disk_cache));
|
|
|
- let (revisions, _) = RevisionLoader {
|
|
|
- object_id: folder_id.as_ref().to_owned(),
|
|
|
- user_id: self.user_id.clone(),
|
|
|
- cloud: None,
|
|
|
- rev_persistence,
|
|
|
+ let _ = self.migration_folder_rev_struct_if_need(folder_id).await?;
|
|
|
+ KV::set_bool(&key, true);
|
|
|
+ tracing::trace!("Run folder v2 migration");
|
|
|
+ Ok(())
|
|
|
+ }
|
|
|
+ #[allow(dead_code)]
|
|
|
+ pub async fn run_v3_migration(&self, folder_id: &FolderId) -> FlowyResult<()> {
|
|
|
+ let key = md5(format!("{}{}", self.user_id, V3_MIGRATION));
|
|
|
+ if KV::get_bool(&key) {
|
|
|
+ return Ok(());
|
|
|
}
|
|
|
- .load()
|
|
|
- .await?;
|
|
|
+ let _ = self.migration_folder_rev_struct_if_need(folder_id).await?;
|
|
|
+ KV::set_bool(&key, true);
|
|
|
+ tracing::trace!("Run folder v3 migration");
|
|
|
+ Ok(())
|
|
|
+ }
|
|
|
|
|
|
- if revisions.is_empty() {
|
|
|
- tracing::trace!("Run folder v2 migration, but revision is empty");
|
|
|
- KV::set_bool(&key, true);
|
|
|
- return Ok(None);
|
|
|
- }
|
|
|
+ pub async fn migration_folder_rev_struct_if_need(&self, folder_id: &FolderId) -> FlowyResult<()> {
|
|
|
+ let object = FolderRevisionResettable {
|
|
|
+ folder_id: folder_id.as_ref().to_owned(),
|
|
|
+ };
|
|
|
|
|
|
+ let pool = self.database.db_pool()?;
|
|
|
+ let disk_cache = SQLiteTextBlockRevisionPersistence::new(&self.user_id, pool);
|
|
|
+ let reset = RevisionStructReset::new(&self.user_id, object, Arc::new(disk_cache));
|
|
|
+ reset.run().await
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+pub struct FolderRevisionResettable {
|
|
|
+ folder_id: String,
|
|
|
+}
|
|
|
+
|
|
|
+impl RevisionResettable for FolderRevisionResettable {
|
|
|
+ fn target_id(&self) -> &str {
|
|
|
+ &self.folder_id
|
|
|
+ }
|
|
|
+
|
|
|
+ fn target_reset_rev_str(&self, revisions: Vec<Revision>) -> FlowyResult<String> {
|
|
|
let pad = FolderPad::from_revisions(revisions)?;
|
|
|
- KV::set_bool(&key, true);
|
|
|
- tracing::trace!("Run folder v2 migration");
|
|
|
- Ok(Some(pad))
|
|
|
+ let json = pad.to_json()?;
|
|
|
+ Ok(json)
|
|
|
+ }
|
|
|
+
|
|
|
+ fn default_target_rev_str(&self) -> FlowyResult<String> {
|
|
|
+ let folder = FolderRevision::default();
|
|
|
+ let json = make_folder_rev_json_str(&folder)?;
|
|
|
+ Ok(json)
|
|
|
}
|
|
|
}
|