mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
Feat/restore revision (#1549)
* chore: write snapshot * chore: add tests * chore: sync close * chore: restore from snapshot * chore: delete invalid revisions after restored from snapshot * chore: create default view if it fail to deserialize view's revisions when there is no snapshot * chore: auto generate snapshot Co-authored-by: nathan <nathan@appflowy.io>
This commit is contained in:
@ -1,6 +1,6 @@
|
||||
use crate::entities::view::ViewDataFormatPB;
|
||||
use crate::entities::{ViewLayoutTypePB, ViewPB};
|
||||
use crate::services::folder_editor::FolderRevisionCompress;
|
||||
use crate::services::folder_editor::FolderRevisionMergeable;
|
||||
use crate::{
|
||||
dart_notification::{send_dart_notification, FolderNotification},
|
||||
entities::workspace::RepeatedWorkspacePB,
|
||||
@ -15,8 +15,8 @@ use bytes::Bytes;
|
||||
use flowy_document::editor::initial_read_me;
|
||||
use flowy_error::FlowyError;
|
||||
use flowy_revision::{
|
||||
RevisionManager, RevisionPersistence, RevisionPersistenceConfiguration, RevisionWebSocket,
|
||||
SQLiteRevisionSnapshotPersistence,
|
||||
PhantomSnapshotPersistence, RevisionManager, RevisionPersistence, RevisionPersistenceConfiguration,
|
||||
RevisionWebSocket,
|
||||
};
|
||||
use folder_rev_model::user_default;
|
||||
use lazy_static::lazy_static;
|
||||
@ -171,16 +171,13 @@ impl FolderManager {
|
||||
let disk_cache = SQLiteFolderRevisionPersistence::new(user_id, pool.clone());
|
||||
let configuration = RevisionPersistenceConfiguration::new(100, false);
|
||||
let rev_persistence = RevisionPersistence::new(user_id, object_id, disk_cache, configuration);
|
||||
let rev_compactor = FolderRevisionCompress();
|
||||
// let history_persistence = SQLiteRevisionHistoryPersistence::new(object_id, pool.clone());
|
||||
let snapshot_persistence = SQLiteRevisionSnapshotPersistence::new(object_id, pool);
|
||||
let rev_compactor = FolderRevisionMergeable();
|
||||
let rev_manager = RevisionManager::new(
|
||||
user_id,
|
||||
folder_id.as_ref(),
|
||||
rev_persistence,
|
||||
rev_compactor,
|
||||
// history_persistence,
|
||||
snapshot_persistence,
|
||||
PhantomSnapshotPersistence(),
|
||||
);
|
||||
|
||||
let folder_editor = FolderEditor::new(user_id, &folder_id, token, rev_manager, self.web_socket.clone()).await?;
|
||||
|
@ -82,10 +82,11 @@ impl FolderEditor {
|
||||
|
||||
pub(crate) fn apply_change(&self, change: FolderChangeset) -> FlowyResult<()> {
|
||||
let FolderChangeset { operations: delta, md5 } = change;
|
||||
let (base_rev_id, rev_id) = self.rev_manager.next_rev_id_pair();
|
||||
let delta_data = delta.json_bytes();
|
||||
let revision = Revision::new(&self.rev_manager.object_id, base_rev_id, rev_id, delta_data, md5);
|
||||
let _ = futures::executor::block_on(async { self.rev_manager.add_local_revision(&revision).await })?;
|
||||
let rev_manager = self.rev_manager.clone();
|
||||
tokio::spawn(async move {
|
||||
let _ = rev_manager.add_local_revision(delta_data, md5).await;
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -113,8 +114,8 @@ impl RevisionObjectSerializer for FolderRevisionSerde {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct FolderRevisionCompress();
|
||||
impl RevisionMergeable for FolderRevisionCompress {
|
||||
pub struct FolderRevisionMergeable();
|
||||
impl RevisionMergeable for FolderRevisionMergeable {
|
||||
fn combine_revisions(&self, revisions: Vec<Revision>) -> FlowyResult<Bytes> {
|
||||
FolderRevisionSerde::combine_revisions(revisions)
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ impl AppTableSql {
|
||||
pub(crate) fn create_app(app_rev: AppRevision, conn: &SqliteConnection) -> Result<(), FlowyError> {
|
||||
let app_table = AppTable::new(app_rev);
|
||||
match diesel_record_count!(app_table, &app_table.id, conn) {
|
||||
0 => diesel_insert_table!(app_table, &app_table, conn),
|
||||
0 => diesel_insert_table!(app_table, app_table.clone(), conn),
|
||||
_ => {
|
||||
let changeset = AppChangeset::from_table(app_table);
|
||||
diesel_update_table!(app_table, changeset, conn)
|
||||
|
@ -13,7 +13,7 @@ impl TrashTableSql {
|
||||
for trash_rev in trashes {
|
||||
let trash_table: TrashTable = trash_rev.into();
|
||||
match diesel_record_count!(trash_table, &trash_table.id, conn) {
|
||||
0 => diesel_insert_table!(trash_table, &trash_table, conn),
|
||||
0 => diesel_insert_table!(trash_table, trash_table.clone(), conn),
|
||||
_ => {
|
||||
let changeset = TrashChangeset::from(trash_table);
|
||||
diesel_update_table!(trash_table, changeset, conn)
|
||||
|
@ -21,7 +21,7 @@ impl ViewTableSql {
|
||||
pub(crate) fn create_view(view_rev: ViewRevision, conn: &SqliteConnection) -> Result<(), FlowyError> {
|
||||
let view_table = ViewTable::new(view_rev);
|
||||
match diesel_record_count!(view_table, &view_table.id, conn) {
|
||||
0 => diesel_insert_table!(view_table, &view_table, conn),
|
||||
0 => diesel_insert_table!(view_table, view_table.clone(), conn),
|
||||
_ => {
|
||||
let changeset = ViewChangeset::from_table(view_table);
|
||||
diesel_update_table!(view_table, changeset, conn)
|
||||
|
@ -15,7 +15,7 @@ impl WorkspaceTableSql {
|
||||
) -> Result<(), FlowyError> {
|
||||
let table = WorkspaceTable::new(workspace_rev, user_id);
|
||||
match diesel_record_count!(workspace_table, &table.id, conn) {
|
||||
0 => diesel_insert_table!(workspace_table, &table, conn),
|
||||
0 => diesel_insert_table!(workspace_table, table.clone(), conn),
|
||||
_ => {
|
||||
let changeset = WorkspaceChangeset::from_table(table);
|
||||
diesel_update_table!(workspace_table, changeset, conn);
|
||||
|
Reference in New Issue
Block a user