use crate::history::RevisionHistoryDiskCache; use flowy_database::{ prelude::*, schema::{rev_history, rev_history::dsl}, ConnectionPool, }; use flowy_error::{internal_error, FlowyResult}; use flowy_sync::entities::revision::Revision; use std::sync::Arc; pub struct SQLiteRevisionHistoryPersistence { object_id: String, pool: Arc, } impl SQLiteRevisionHistoryPersistence { pub fn new(object_id: &str, pool: Arc) -> Self { let object_id = object_id.to_owned(); Self { object_id, pool } } } impl RevisionHistoryDiskCache for SQLiteRevisionHistoryPersistence { fn write_history(&self, revision: Revision) -> FlowyResult<()> { let record = ( dsl::object_id.eq(revision.object_id), dsl::start_rev_id.eq(revision.base_rev_id), dsl::end_rev_id.eq(revision.rev_id), dsl::data.eq(revision.delta_data), ); let conn = self.pool.get().map_err(internal_error)?; let _ = insert_or_ignore_into(dsl::rev_history) .values(vec![record]) .execute(&*conn)?; Ok(()) } fn read_histories(&self) -> FlowyResult> { let conn = self.pool.get().map_err(internal_error)?; let records: Vec = dsl::rev_history .filter(dsl::object_id.eq(&self.object_id)) .load::(&*conn)?; Ok(records .into_iter() .map(|record| record.into()) .collect::>()) } } #[derive(PartialEq, Clone, Debug, Queryable, Identifiable, Insertable, Associations)] #[table_name = "rev_history"] struct RevisionRecord { id: i32, object_id: String, start_rev_id: i64, end_rev_id: i64, data: Vec, } pub struct RevisionHistory { pub object_id: String, pub start_rev_id: i64, pub end_rev_id: i64, pub data: Vec, } impl std::convert::From for RevisionHistory { fn from(record: RevisionRecord) -> Self { RevisionHistory { object_id: record.object_id, start_rev_id: record.start_rev_id, end_rev_id: record.end_rev_id, data: record.data, } } }