From 03a70bbdb953a46bb771e1f6962125ad6b969d58 Mon Sep 17 00:00:00 2001 From: appflowy <annie@appflowy.io> Date: Tue, 16 Aug 2022 11:37:34 +0800 Subject: [PATCH] chore: update grid migration --- .../src/services/persistence/migration.rs | 20 +-- frontend/rust-lib/flowy-grid/src/manager.rs | 2 +- .../src/services/persistence/migration.rs | 114 ++++++------------ 3 files changed, 49 insertions(+), 87 deletions(-) diff --git a/frontend/rust-lib/flowy-folder/src/services/persistence/migration.rs b/frontend/rust-lib/flowy-folder/src/services/persistence/migration.rs index b8be0b1e19..7b211fb54a 100644 --- a/frontend/rust-lib/flowy-folder/src/services/persistence/migration.rs +++ b/frontend/rust-lib/flowy-folder/src/services/persistence/migration.rs @@ -5,15 +5,12 @@ use crate::{ }; use flowy_database::kv::KV; use flowy_error::{FlowyError, FlowyResult}; - use flowy_folder_data_model::revision::{AppRevision, FolderRevision, ViewRevision, WorkspaceRevision}; use flowy_revision::disk::SQLiteTextBlockRevisionPersistence; 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"; @@ -35,7 +32,7 @@ impl FolderMigration { } pub fn run_v1_migration(&self) -> FlowyResult<Option<FolderPad>> { - let key = md5(format!("{}{}", self.user_id, V1_MIGRATION)); + let key = migration_flag_key(&self.user_id, V1_MIGRATION); if KV::get_bool(&key) { return Ok(None); } @@ -86,28 +83,29 @@ impl FolderMigration { } pub async fn run_v2_migration(&self, folder_id: &FolderId) -> FlowyResult<()> { - let key = md5(format!("{}{}", self.user_id, V2_MIGRATION)); + let key = migration_flag_key(&self.user_id, V2_MIGRATION); if KV::get_bool(&key) { return Ok(()); } - let _ = self.migration_folder_rev_struct_if_need(folder_id).await?; + let _ = self.migration_folder_rev_struct(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)); + let key = migration_flag_key(&self.user_id, V3_MIGRATION); if KV::get_bool(&key) { return Ok(()); } - let _ = self.migration_folder_rev_struct_if_need(folder_id).await?; + let _ = self.migration_folder_rev_struct(folder_id).await?; KV::set_bool(&key, true); tracing::trace!("Run folder v3 migration"); Ok(()) } - pub async fn migration_folder_rev_struct_if_need(&self, folder_id: &FolderId) -> FlowyResult<()> { + pub async fn migration_folder_rev_struct(&self, folder_id: &FolderId) -> FlowyResult<()> { let object = FolderRevisionResettable { folder_id: folder_id.as_ref().to_owned(), }; @@ -119,6 +117,10 @@ impl FolderMigration { } } +fn migration_flag_key(user_id: &str, version: &str) -> String { + md5(format!("{}{}", user_id, version,)) +} + pub struct FolderRevisionResettable { folder_id: String, } diff --git a/frontend/rust-lib/flowy-grid/src/manager.rs b/frontend/rust-lib/flowy-grid/src/manager.rs index 048fc58415..9e4556b793 100644 --- a/frontend/rust-lib/flowy-grid/src/manager.rs +++ b/frontend/rust-lib/flowy-grid/src/manager.rs @@ -96,7 +96,7 @@ impl GridManager { pub async fn open_grid<T: AsRef<str>>(&self, grid_id: T) -> FlowyResult<Arc<GridRevisionEditor>> { let grid_id = grid_id.as_ref(); tracing::Span::current().record("grid_id", &grid_id); - let _ = self.migration.migration_grid_if_need(grid_id).await; + let _ = self.migration.run_v1_migration(grid_id).await; self.get_or_create_grid_editor(grid_id).await } diff --git a/frontend/rust-lib/flowy-grid/src/services/persistence/migration.rs b/frontend/rust-lib/flowy-grid/src/services/persistence/migration.rs index bf3aa7adfb..cb99d8eb6d 100644 --- a/frontend/rust-lib/flowy-grid/src/services/persistence/migration.rs +++ b/frontend/rust-lib/flowy-grid/src/services/persistence/migration.rs @@ -1,19 +1,17 @@ use crate::manager::GridUser; - use crate::services::persistence::GridDatabase; use flowy_database::kv::KV; use flowy_error::FlowyResult; use flowy_grid_data_model::revision::GridRevision; -use flowy_revision::disk::{RevisionRecord, SQLiteGridRevisionPersistence}; -use flowy_revision::{mk_grid_block_revision_disk_cache, RevisionLoader, RevisionPersistence}; +use flowy_revision::disk::SQLiteGridRevisionPersistence; +use flowy_revision::reset::{RevisionResettable, RevisionStructReset}; use flowy_sync::client_grid::{make_grid_rev_json_str, GridRevisionPad}; use flowy_sync::entities::revision::Revision; - -use lib_ot::core::TextDeltaBuilder; -use serde::{Deserialize, Serialize}; -use std::str::FromStr; +use flowy_sync::util::md5; use std::sync::Arc; +const V1_MIGRATION: &str = "GRID_V1_MIGRATION"; + pub(crate) struct GridMigration { user: Arc<dyn GridUser>, database: Arc<dyn GridDatabase>, @@ -24,90 +22,52 @@ impl GridMigration { Self { user, database } } - pub async fn migration_grid_if_need(&self, grid_id: &str) -> FlowyResult<()> { - match KV::get_str(grid_id) { - None => { - let _ = self.reset_grid_rev(grid_id).await?; - let _ = self.save_migrate_record(grid_id)?; - } - Some(s) => { - let mut record = MigrationGridRecord::from_str(&s)?; - let empty_json = self.empty_grid_rev_json()?; - if record.len < empty_json.len() { - let _ = self.reset_grid_rev(grid_id).await?; - record.len = empty_json.len(); - KV::set_str(grid_id, record.to_string()); - } - } - } - Ok(()) - } - - async fn reset_grid_rev(&self, grid_id: &str) -> FlowyResult<()> { + pub async fn run_v1_migration(&self, grid_id: &str) -> FlowyResult<()> { let user_id = self.user.user_id()?; - let pool = self.database.db_pool()?; - let grid_rev_pad = self.get_grid_revision_pad(grid_id).await?; - let json = grid_rev_pad.json_str()?; - let delta_data = TextDeltaBuilder::new().insert(&json).build().json_bytes(); - let revision = Revision::initial_revision(&user_id, grid_id, delta_data); - let record = RevisionRecord::new(revision); - // - let disk_cache = mk_grid_block_revision_disk_cache(&user_id, pool); - let _ = disk_cache.delete_and_insert_records(grid_id, None, vec![record]); + let key = migration_flag_key(&user_id, V1_MIGRATION, grid_id); + if KV::get_bool(&key) { + return Ok(()); + } + let _ = self.migration_grid_rev_struct(grid_id).await?; + tracing::trace!("Run grid:{} v1 migration", grid_id); + KV::set_bool(&key, true); Ok(()) } - fn save_migrate_record(&self, grid_id: &str) -> FlowyResult<()> { - let empty_json_str = self.empty_grid_rev_json()?; - let record = MigrationGridRecord { + pub async fn migration_grid_rev_struct(&self, grid_id: &str) -> FlowyResult<()> { + let object = GridRevisionResettable { grid_id: grid_id.to_owned(), - len: empty_json_str.len(), }; - KV::set_str(grid_id, record.to_string()); - Ok(()) - } - - fn empty_grid_rev_json(&self) -> FlowyResult<String> { - let empty_grid_rev = GridRevision::default(); - let empty_json = make_grid_rev_json_str(&empty_grid_rev)?; - Ok(empty_json) - } - - async fn get_grid_revision_pad(&self, grid_id: &str) -> FlowyResult<GridRevisionPad> { - let pool = self.database.db_pool()?; let user_id = self.user.user_id()?; + let pool = self.database.db_pool()?; let disk_cache = SQLiteGridRevisionPersistence::new(&user_id, pool); - let rev_persistence = Arc::new(RevisionPersistence::new(&user_id, grid_id, disk_cache)); - let (revisions, _) = RevisionLoader { - object_id: grid_id.to_owned(), - user_id, - cloud: None, - rev_persistence, - } - .load() - .await?; - - let pad = GridRevisionPad::from_revisions(revisions)?; - Ok(pad) + let reset = RevisionStructReset::new(&user_id, object, Arc::new(disk_cache)); + reset.run().await } } -#[derive(Serialize, Deserialize)] -struct MigrationGridRecord { +fn migration_flag_key(user_id: &str, version: &str, grid_id: &str) -> String { + md5(format!("{}{}{}", user_id, version, grid_id,)) +} + +pub struct GridRevisionResettable { grid_id: String, - len: usize, } -impl FromStr for MigrationGridRecord { - type Err = serde_json::Error; +impl RevisionResettable for GridRevisionResettable { + fn target_id(&self) -> &str { + &self.grid_id + } - fn from_str(s: &str) -> Result<Self, Self::Err> { - serde_json::from_str::<MigrationGridRecord>(s) - } -} - -impl ToString for MigrationGridRecord { - fn to_string(&self) -> String { - serde_json::to_string(self).unwrap_or_else(|_| "".to_string()) + fn target_reset_rev_str(&self, revisions: Vec<Revision>) -> FlowyResult<String> { + let pad = GridRevisionPad::from_revisions(revisions)?; + let json = pad.json_str()?; + Ok(json) + } + + fn default_target_rev_str(&self) -> FlowyResult<String> { + let grid_rev = GridRevision::default(); + let json = make_grid_rev_json_str(&grid_rev)?; + Ok(json) } }