diff --git a/drift/lib/src/sqlite3/database.dart b/drift/lib/src/sqlite3/database.dart index 522b7133..484ad83a 100644 --- a/drift/lib/src/sqlite3/database.dart +++ b/drift/lib/src/sqlite3/database.dart @@ -1,4 +1,6 @@ @internal +import 'dart:async'; + import 'package:meta/meta.dart'; import 'package:sqlite3/common.dart'; @@ -23,7 +25,7 @@ abstract class Sqlite3Delegate /// A delegate that will call [openDatabase] to open the database. Sqlite3Delegate(this._setup) : _closeUnderlyingWhenClosed = true; - /// A delegate using an underlying sqlite3 database object that has alreaddy + /// A delegate using an underlying sqlite3 database object that has already /// been opened. Sqlite3Delegate.opened(this._db, this._setup, this._closeUnderlyingWhenClosed) : _hasCreatedDatabase = true { @@ -47,6 +49,12 @@ abstract class Sqlite3Delegate @override Future get isOpen => Future.value(_isOpen); + /// Flush pending writes to the file system on platforms where that is + /// necessary. + /// + /// At the moment, we only support this for the WASM backend. + FutureOr flush() => null; + @override Future open(QueryExecutorUser db) async { if (!_hasCreatedDatabase) { @@ -88,6 +96,10 @@ abstract class Sqlite3Delegate stmt.dispose(); } + if (!isInTransaction) { + await flush(); + } + return Future.value(); } @@ -99,6 +111,10 @@ abstract class Sqlite3Delegate stmt.execute(args); stmt.dispose(); } + + if (!isInTransaction) { + await flush(); + } } @override @@ -132,6 +148,8 @@ abstract class Sqlite3Delegate if (_closeUnderlyingWhenClosed) { beforeClose(_db); _db.dispose(); + + await flush(); } } } diff --git a/drift/lib/wasm.dart b/drift/lib/wasm.dart index a2fd0598..0cc40d76 100644 --- a/drift/lib/wasm.dart +++ b/drift/lib/wasm.dart @@ -16,6 +16,7 @@ library drift.wasm; import 'package:meta/meta.dart'; import 'package:sqlite3/common.dart'; +import 'package:sqlite3/wasm.dart'; import 'backends.dart'; import 'src/sqlite3/database.dart'; @@ -38,13 +39,20 @@ class WasmDatabase extends DelegatedDatabase { /// Creates a wasm database at [path] in the virtual file system of the /// [sqlite3] module. + /// If [fileSystem] provided, the data is guaranteed to be + /// stored in the IndexedDB when the request is complete. Attention! + /// Insert/update queries may be slower when this option enabled. If you want + /// to insert more than one rows, be sure you run in a transaction if + /// possible. factory WasmDatabase({ required CommmonSqlite3 sqlite3, required String path, WasmDatabaseSetup? setup, + IndexedDbFileSystem? fileSystem, bool logStatements = false, }) { - return WasmDatabase._(_WasmDelegate(sqlite3, path, setup), logStatements); + return WasmDatabase._( + _WasmDelegate(sqlite3, path, setup, fileSystem), logStatements); } /// Creates an in-memory database in the loaded [sqlite3] database. @@ -53,15 +61,18 @@ class WasmDatabase extends DelegatedDatabase { WasmDatabaseSetup? setup, bool logStatements = false, }) { - return WasmDatabase._(_WasmDelegate(sqlite3, null, setup), logStatements); + return WasmDatabase._( + _WasmDelegate(sqlite3, null, setup, null), logStatements); } } class _WasmDelegate extends Sqlite3Delegate { final CommmonSqlite3 _sqlite3; final String? _path; + final IndexedDbFileSystem? _fileSystem; - _WasmDelegate(this._sqlite3, this._path, WasmDatabaseSetup? setup) + _WasmDelegate( + this._sqlite3, this._path, WasmDatabaseSetup? setup, this._fileSystem) : super(setup); @override @@ -73,4 +84,9 @@ class _WasmDelegate extends Sqlite3Delegate { return _sqlite3.open(path); } } + + @override + Future flush() async { + await _fileSystem?.flush(); + } }