refactor(electron): use sqlite to store server clock & sync meta (#6957)

After this PR, IDB should not be used in desktop any longer.
This commit is contained in:
pengx17
2024-05-16 06:31:04 +00:00
parent 27af9b4d1a
commit 3cca879a83
8 changed files with 322 additions and 84 deletions

View File

@@ -13,6 +13,16 @@ export class SqliteConnection {
getAllUpdates(): Promise<Array<UpdateRow>>
insertUpdates(updates: Array<InsertRow>): Promise<void>
replaceUpdates(docId: string | undefined | null, updates: Array<InsertRow>): Promise<void>
getServerClock(key: string): Promise<BlobRow | null>
setServerClock(key: string, data: Uint8Array): Promise<void>
getServerClockKeys(): Promise<Array<string>>
clearServerClock(): Promise<void>
delServerClock(key: string): Promise<void>
getSyncMetadata(key: string): Promise<BlobRow | null>
setSyncMetadata(key: string, data: Uint8Array): Promise<void>
getSyncMetadataKeys(): Promise<Array<string>>
clearSyncMetadata(): Promise<void>
delSyncMetadata(key: string): Promise<void>
initVersion(): Promise<void>
setVersion(version: number): Promise<void>
getMaxVersion(): Promise<number>

View File

@@ -15,5 +15,15 @@ CREATE TABLE IF NOT EXISTS "blobs" (
CREATE TABLE IF NOT EXISTS "version_info" (
version NUMBER NOT NULL,
timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL
);
CREATE TABLE IF NOT EXISTS "server_clock" (
key TEXT PRIMARY KEY NOT NULL,
data BLOB NOT NULL,
timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL
);
CREATE TABLE IF NOT EXISTS "sync_metadata" (
key TEXT PRIMARY KEY NOT NULL,
data BLOB NOT NULL,
timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL
)
"#;

View File

@@ -252,6 +252,114 @@ impl SqliteConnection {
Ok(())
}
#[napi]
pub async fn get_server_clock(&self, key: String) -> Option<BlobRow> {
sqlx::query_as!(
BlobRow,
"SELECT key, data, timestamp FROM server_clock WHERE key = ?",
key
)
.fetch_one(&self.pool)
.await
.ok()
}
#[napi]
pub async fn set_server_clock(&self, key: String, data: Uint8Array) -> napi::Result<()> {
let data = data.as_ref();
sqlx::query!(
"INSERT INTO server_clock (key, data) VALUES ($1, $2) ON CONFLICT(key) DO UPDATE SET data = excluded.data",
key,
data,
)
.execute(&self.pool)
.await
.map_err(anyhow::Error::from)?;
Ok(())
}
#[napi]
pub async fn get_server_clock_keys(&self) -> napi::Result<Vec<String>> {
let keys = sqlx::query!("SELECT key FROM server_clock")
.fetch_all(&self.pool)
.await
.map(|rows| rows.into_iter().map(|row| row.key).collect())
.map_err(anyhow::Error::from)?;
Ok(keys)
}
#[napi]
pub async fn clear_server_clock(&self) -> napi::Result<()> {
sqlx::query!("DELETE FROM server_clock")
.execute(&self.pool)
.await
.map_err(anyhow::Error::from)?;
Ok(())
}
#[napi]
pub async fn del_server_clock(&self, key: String) -> napi::Result<()> {
sqlx::query!("DELETE FROM server_clock WHERE key = ?", key)
.execute(&self.pool)
.await
.map_err(anyhow::Error::from)?;
Ok(())
}
#[napi]
pub async fn get_sync_metadata(&self, key: String) -> Option<BlobRow> {
sqlx::query_as!(
BlobRow,
"SELECT key, data, timestamp FROM sync_metadata WHERE key = ?",
key
)
.fetch_one(&self.pool)
.await
.ok()
}
#[napi]
pub async fn set_sync_metadata(&self, key: String, data: Uint8Array) -> napi::Result<()> {
let data = data.as_ref();
sqlx::query!(
"INSERT INTO sync_metadata (key, data) VALUES ($1, $2) ON CONFLICT(key) DO UPDATE SET data = excluded.data",
key,
data,
)
.execute(&self.pool)
.await
.map_err(anyhow::Error::from)?;
Ok(())
}
#[napi]
pub async fn get_sync_metadata_keys(&self) -> napi::Result<Vec<String>> {
let keys = sqlx::query!("SELECT key FROM sync_metadata")
.fetch_all(&self.pool)
.await
.map(|rows| rows.into_iter().map(|row| row.key).collect())
.map_err(anyhow::Error::from)?;
Ok(keys)
}
#[napi]
pub async fn clear_sync_metadata(&self) -> napi::Result<()> {
sqlx::query!("DELETE FROM sync_metadata")
.execute(&self.pool)
.await
.map_err(anyhow::Error::from)?;
Ok(())
}
#[napi]
pub async fn del_sync_metadata(&self, key: String) -> napi::Result<()> {
sqlx::query!("DELETE FROM sync_metadata WHERE key = ?", key)
.execute(&self.pool)
.await
.map_err(anyhow::Error::from)?;
Ok(())
}
#[napi]
pub async fn init_version(&self) -> napi::Result<()> {
// create version_info table