|
@@ -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)
|
|
|
+ fn target_reset_rev_str(&self, revisions: Vec<Revision>) -> FlowyResult<String> {
|
|
|
+ let pad = GridRevisionPad::from_revisions(revisions)?;
|
|
|
+ let json = pad.json_str()?;
|
|
|
+ Ok(json)
|
|
|
}
|
|
|
-}
|
|
|
|
|
|
-impl ToString for MigrationGridRecord {
|
|
|
- fn to_string(&self) -> String {
|
|
|
- serde_json::to_string(self).unwrap_or_else(|_| "".to_string())
|
|
|
+ fn default_target_rev_str(&self) -> FlowyResult<String> {
|
|
|
+ let grid_rev = GridRevision::default();
|
|
|
+ let json = make_grid_rev_json_str(&grid_rev)?;
|
|
|
+ Ok(json)
|
|
|
}
|
|
|
}
|