From ed2c3c035d8189179a14c929686a64df877b8dcf Mon Sep 17 00:00:00 2001 From: Ralf Kistner Date: Mon, 4 Nov 2024 15:43:02 +0200 Subject: [PATCH 1/3] Flush at the end of each writeLock. --- packages/sqlite_async/lib/src/web/database.dart | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/sqlite_async/lib/src/web/database.dart b/packages/sqlite_async/lib/src/web/database.dart index 3e3233b..f392684 100644 --- a/packages/sqlite_async/lib/src/web/database.dart +++ b/packages/sqlite_async/lib/src/web/database.dart @@ -137,6 +137,7 @@ class WebDatabase return await callback(context); } finally { context.markClosed(); + await _database.fileSystem.flush(); } }); } else { @@ -148,6 +149,7 @@ class WebDatabase return await callback(context); } finally { context.markClosed(); + await _database.fileSystem.flush(); await _database.customRequest( CustomDatabaseMessage(CustomDatabaseMessageKind.releaseLock)); } From c06e4ec6377a2e9df6297e9dc7d46bcb039f97f1 Mon Sep 17 00:00:00 2001 From: Ralf Kistner Date: Tue, 5 Nov 2024 14:23:09 +0200 Subject: [PATCH 2/3] Make flush optional. --- .../sqlite_async/lib/src/web/database.dart | 22 ++++++++++---- .../src/web/database/web_sqlite_database.dart | 16 +++++++--- packages/sqlite_async/lib/web.dart | 30 +++++++++++++++++++ 3 files changed, 59 insertions(+), 9 deletions(-) diff --git a/packages/sqlite_async/lib/src/web/database.dart b/packages/sqlite_async/lib/src/web/database.dart index f392684..a4f0ddf 100644 --- a/packages/sqlite_async/lib/src/web/database.dart +++ b/packages/sqlite_async/lib/src/web/database.dart @@ -113,7 +113,8 @@ class WebDatabase @override Future writeTransaction( Future Function(SqliteWriteContext tx) callback, - {Duration? lockTimeout}) { + {Duration? lockTimeout, + bool? flush}) { return writeLock( (writeContext) => internalWriteTransaction(writeContext, (context) async { @@ -122,14 +123,15 @@ class WebDatabase return callback(_ExclusiveTransactionContext(this, writeContext)); }), debugContext: 'writeTransaction()', - lockTimeout: lockTimeout); + lockTimeout: lockTimeout, + flush: flush); } @override /// Internal writeLock which intercepts transaction context's to verify auto commit is not active Future writeLock(Future Function(SqliteWriteContext tx) callback, - {Duration? lockTimeout, String? debugContext}) async { + {Duration? lockTimeout, String? debugContext, bool? flush}) async { if (_mutex case var mutex?) { return await mutex.lock(() async { final context = _ExclusiveContext(this); @@ -137,7 +139,9 @@ class WebDatabase return await callback(context); } finally { context.markClosed(); - await _database.fileSystem.flush(); + if (flush != false) { + await this.flush(); + } } }); } else { @@ -149,12 +153,20 @@ class WebDatabase return await callback(context); } finally { context.markClosed(); - await _database.fileSystem.flush(); + if (flush != false) { + await this.flush(); + } await _database.customRequest( CustomDatabaseMessage(CustomDatabaseMessageKind.releaseLock)); } } } + + @override + Future flush() async { + await isInitialized; + return _database.fileSystem.flush(); + } } class _SharedContext implements SqliteReadContext { diff --git a/packages/sqlite_async/lib/src/web/database/web_sqlite_database.dart b/packages/sqlite_async/lib/src/web/database/web_sqlite_database.dart index c00377c..0f38b1c 100644 --- a/packages/sqlite_async/lib/src/web/database/web_sqlite_database.dart +++ b/packages/sqlite_async/lib/src/web/database/web_sqlite_database.dart @@ -131,24 +131,32 @@ class SqliteDatabaseImpl @override Future writeLock(Future Function(SqliteWriteContext tx) callback, - {Duration? lockTimeout, String? debugContext}) async { + {Duration? lockTimeout, String? debugContext, bool? flush}) async { await isInitialized; return _runZoned(() { return _connection.writeLock(callback, - lockTimeout: lockTimeout, debugContext: debugContext); + lockTimeout: lockTimeout, debugContext: debugContext, flush: flush); }, debugContext: debugContext ?? 'execute()'); } @override Future writeTransaction( Future Function(SqliteWriteContext tx) callback, - {Duration? lockTimeout}) async { + {Duration? lockTimeout, + bool? flush}) async { await isInitialized; return _runZoned( - () => _connection.writeTransaction(callback, lockTimeout: lockTimeout), + () => _connection.writeTransaction(callback, + lockTimeout: lockTimeout, flush: flush), debugContext: 'writeTransaction()'); } + @override + Future flush() async { + await isInitialized; + return _connection.flush(); + } + @override Future close() async { await isInitialized; diff --git a/packages/sqlite_async/lib/web.dart b/packages/sqlite_async/lib/web.dart index 7c49737..a4005e1 100644 --- a/packages/sqlite_async/lib/web.dart +++ b/packages/sqlite_async/lib/web.dart @@ -65,4 +65,34 @@ abstract class WebSqliteConnection implements SqliteConnection { ); return database; } + + /// Same as [SqliteConnection.writeLock]. + /// + /// Has an additional [flush] (defaults to true). This can be set to false + /// to delay flushing changes to the database file, losing durability guarantees. + /// This only has an effect when IndexedDB storage is used. + /// + /// See [flush] for details. + Future writeLock(Future Function(SqliteWriteContext tx) callback, + {Duration? lockTimeout, String? debugContext, bool? flush}); + + /// Same as [SqliteConnection.writeTransaction]. + /// + /// Has an additional [flush] (defaults to true). This can be set to false + /// to delay flushing changes to the database file, losing durability guarantees. + /// This only has an effect when IndexedDB storage is used. + /// + /// See [flush] for details. + Future writeTransaction( + Future Function(SqliteWriteContext tx) callback, + {Duration? lockTimeout, + bool? flush}); + + /// Flush changes to the underlying storage. + /// + /// When this returns, all changes previously written will be persisted + /// to storage. + /// + /// This only has an effect when IndexedDB storage is used. + Future flush(); } From ce0750e603ac59426dbc783ca4f1736bcc5ecbd8 Mon Sep 17 00:00:00 2001 From: Ralf Kistner Date: Wed, 6 Nov 2024 08:24:59 +0200 Subject: [PATCH 3/3] chore(release): publish packages - sqlite_async@0.11.0 - drift_sqlite_async@0.2.0-alpha.4 --- CHANGELOG.md | 28 ++++++++++++++++++++++++ packages/drift_sqlite_async/CHANGELOG.md | 4 ++++ packages/drift_sqlite_async/pubspec.yaml | 4 ++-- packages/sqlite_async/CHANGELOG.md | 4 ++++ packages/sqlite_async/pubspec.yaml | 2 +- 5 files changed, 39 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b9886c5..f5c9c0d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,34 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## 2024-11-06 + +### Changes + +--- + +Packages with breaking changes: + + - There are no breaking changes in this release. + +Packages with other changes: + + - [`sqlite_async` - `v0.11.0`](#sqlite_async---v0110) + - [`drift_sqlite_async` - `v0.2.0-alpha.4`](#drift_sqlite_async---v020-alpha4) + +Packages with dependency updates only: + +> Packages listed below depend on other packages in this workspace that have had changes. Their versions have been incremented to bump the minimum dependency versions of the packages they depend upon in this project. + + - `drift_sqlite_async` - `v0.2.0-alpha.4` + +--- + +#### `sqlite_async` - `v0.11.0` + + - Automatically flush IndexedDB storage to fix durability issues + + ## 2024-11-01 ### Changes diff --git a/packages/drift_sqlite_async/CHANGELOG.md b/packages/drift_sqlite_async/CHANGELOG.md index de46be7..23f501b 100644 --- a/packages/drift_sqlite_async/CHANGELOG.md +++ b/packages/drift_sqlite_async/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.2.0-alpha.4 + + - Update a dependency to the latest release. + ## 0.2.0-alpha.3 - Bump `sqlite_async` to v0.10.1 diff --git a/packages/drift_sqlite_async/pubspec.yaml b/packages/drift_sqlite_async/pubspec.yaml index 109314d..a2e8c99 100644 --- a/packages/drift_sqlite_async/pubspec.yaml +++ b/packages/drift_sqlite_async/pubspec.yaml @@ -1,5 +1,5 @@ name: drift_sqlite_async -version: 0.2.0-alpha.3 +version: 0.2.0-alpha.4 homepage: https://github.com/powersync-ja/sqlite_async.dart repository: https://github.com/powersync-ja/sqlite_async.dart description: Use Drift with a sqlite_async database, allowing both to be used in the same application. @@ -15,7 +15,7 @@ environment: sdk: ">=3.0.0 <4.0.0" dependencies: drift: ">=2.19.0 <3.0.0" - sqlite_async: ^0.10.1 + sqlite_async: ^0.11.0 dev_dependencies: build_runner: ^2.4.8 drift_dev: ">=2.19.0 <3.0.0" diff --git a/packages/sqlite_async/CHANGELOG.md b/packages/sqlite_async/CHANGELOG.md index 88f9875..ab91443 100644 --- a/packages/sqlite_async/CHANGELOG.md +++ b/packages/sqlite_async/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.11.0 + + - Automatically flush IndexedDB storage to fix durability issues + ## 0.10.1 - For database setups not using a shared worker, use a `BroadcastChannel` to share updates across different tabs. diff --git a/packages/sqlite_async/pubspec.yaml b/packages/sqlite_async/pubspec.yaml index 453f154..09adc13 100644 --- a/packages/sqlite_async/pubspec.yaml +++ b/packages/sqlite_async/pubspec.yaml @@ -1,6 +1,6 @@ name: sqlite_async description: High-performance asynchronous interface for SQLite on Dart and Flutter. -version: 0.10.1 +version: 0.11.0 repository: https://github.com/powersync-ja/sqlite_async.dart environment: sdk: ">=3.4.0 <4.0.0"