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::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 flowy_sync::util::md5; use std::sync::Arc; const V1_MIGRATION: &str = "GRID_V1_MIGRATION"; pub(crate) struct GridMigration { user: Arc, database: Arc, } impl GridMigration { pub fn new(user: Arc, database: Arc) -> Self { Self { user, database } } pub async fn run_v1_migration(&self, grid_id: &str) -> FlowyResult<()> { let user_id = self.user.user_id()?; 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(()) } pub async fn migration_grid_rev_struct(&self, grid_id: &str) -> FlowyResult<()> { let object = GridRevisionResettable { grid_id: grid_id.to_owned(), }; let user_id = self.user.user_id()?; let pool = self.database.db_pool()?; let disk_cache = SQLiteGridRevisionPersistence::new(&user_id, pool); let reset = RevisionStructReset::new(&user_id, object, Arc::new(disk_cache)); reset.run().await } } 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, } impl RevisionResettable for GridRevisionResettable { fn target_id(&self) -> &str { &self.grid_id } fn target_reset_rev_str(&self, revisions: Vec) -> FlowyResult { let pad = GridRevisionPad::from_revisions(revisions)?; let json = pad.json_str()?; Ok(json) } fn default_target_rev_str(&self) -> FlowyResult { let grid_rev = GridRevision::default(); let json = make_grid_rev_json_str(&grid_rev)?; Ok(json) } }