diff --git a/packages/frontend/apps/electron/src/helper/db/db-adapter.ts b/packages/frontend/apps/electron/src/helper/db/db-adapter.ts index 3ba6a5eb9b56..d61ea530e57f 100644 --- a/packages/frontend/apps/electron/src/helper/db/db-adapter.ts +++ b/packages/frontend/apps/electron/src/helper/db/db-adapter.ts @@ -141,6 +141,18 @@ export class SQLiteAdapter { } } + async checkpoint() { + try { + if (!this.db) { + logger.warn(`${this.path} is not connected`); + return; + } + await this.db.checkpoint(); + } catch (error) { + logger.error('checkpoint', error); + } + } + async getUpdatesCount(docId?: string) { try { if (!this.db) { diff --git a/packages/frontend/apps/electron/src/helper/db/workspace-db-adapter.ts b/packages/frontend/apps/electron/src/helper/db/workspace-db-adapter.ts index daf9155eaa3e..5767a902d26a 100644 --- a/packages/frontend/apps/electron/src/helper/db/workspace-db-adapter.ts +++ b/packages/frontend/apps/electron/src/helper/db/workspace-db-adapter.ts @@ -120,6 +120,10 @@ export class WorkspaceSQLiteDB { } return null; }; + + async checkpoint() { + await this.adapter.checkpoint(); + } } export async function openWorkspaceDatabase( diff --git a/packages/frontend/apps/electron/src/helper/dialog/dialog.ts b/packages/frontend/apps/electron/src/helper/dialog/dialog.ts index f3969e26ba9b..7a6fc9d3fab6 100644 --- a/packages/frontend/apps/electron/src/helper/dialog/dialog.ts +++ b/packages/frontend/apps/electron/src/helper/dialog/dialog.ts @@ -77,6 +77,7 @@ export async function saveDBFileAs( ): Promise { try { const db = await ensureSQLiteDB('workspace', workspaceId); + await db.checkpoint(); // make sure all changes (WAL) are written to db const fakedResult = getFakedResult(); const ret = diff --git a/packages/frontend/apps/electron/src/main/updater/electron-updater.ts b/packages/frontend/apps/electron/src/main/updater/electron-updater.ts index c71a6324b279..f1e823e4f1ad 100644 --- a/packages/frontend/apps/electron/src/main/updater/electron-updater.ts +++ b/packages/frontend/apps/electron/src/main/updater/electron-updater.ts @@ -98,8 +98,6 @@ export const registerUpdater = async () => { channel: buildType, }); - logger.debug('auto-updater feed config', feedUrl); - autoUpdater.setFeedURL(feedUrl); // register events for checkForUpdates diff --git a/packages/frontend/native/index.d.ts b/packages/frontend/native/index.d.ts index 429e556d0c64..c3611af9bfb2 100644 --- a/packages/frontend/native/index.d.ts +++ b/packages/frontend/native/index.d.ts @@ -30,6 +30,11 @@ export declare class SqliteConnection { get isClose(): boolean static validate(path: string): Promise migrateAddDocId(): Promise + /** + * Flush the WAL file to the database file. + * See https://www.sqlite.org/pragma.html#pragma_wal_checkpoint:~:text=PRAGMA%20schema.wal_checkpoint%3B + */ + checkpoint(): Promise } export interface BlobRow { diff --git a/packages/frontend/native/src/sqlite/mod.rs b/packages/frontend/native/src/sqlite/mod.rs index cfc91ee72c4f..17293d7ba9ff 100644 --- a/packages/frontend/native/src/sqlite/mod.rs +++ b/packages/frontend/native/src/sqlite/mod.rs @@ -53,7 +53,7 @@ impl SqliteConnection { let sqlite_options = SqliteConnectOptions::new() .filename(&path) .foreign_keys(false) - .journal_mode(sqlx::sqlite::SqliteJournalMode::Off); + .journal_mode(sqlx::sqlite::SqliteJournalMode::Wal); let pool = SqlitePoolOptions::new() .max_connections(4) .connect_lazy_with(sqlite_options); @@ -490,6 +490,19 @@ impl SqliteConnection { } } + /** + * Flush the WAL file to the database file. + * See https://www.sqlite.org/pragma.html#pragma_wal_checkpoint:~:text=PRAGMA%20schema.wal_checkpoint%3B + */ + #[napi] + pub async fn checkpoint(&self) -> napi::Result<()> { + sqlx::query("PRAGMA wal_checkpoint(FULL);") + .execute(&self.pool) + .await + .map_err(anyhow::Error::from)?; + Ok(()) + } + pub async fn migrate_add_doc_id_index(&self) -> napi::Result<()> { // ignore errors match sqlx::query("CREATE INDEX IF NOT EXISTS idx_doc_id ON updates(doc_id);")