Merge pull request #1847 from simolus3/sync-write-indexeddb

Add synchronised persistence to WasmDatabase
This commit is contained in:
Simon Binder 2022-05-23 12:32:54 +02:00 committed by GitHub
commit b8b372f7c7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 38 additions and 4 deletions

View File

@ -1,4 +1,6 @@
@internal @internal
import 'dart:async';
import 'package:meta/meta.dart'; import 'package:meta/meta.dart';
import 'package:sqlite3/common.dart'; import 'package:sqlite3/common.dart';
@ -23,7 +25,7 @@ abstract class Sqlite3Delegate<DB extends CommonDatabase>
/// A delegate that will call [openDatabase] to open the database. /// A delegate that will call [openDatabase] to open the database.
Sqlite3Delegate(this._setup) : _closeUnderlyingWhenClosed = true; 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. /// been opened.
Sqlite3Delegate.opened(this._db, this._setup, this._closeUnderlyingWhenClosed) Sqlite3Delegate.opened(this._db, this._setup, this._closeUnderlyingWhenClosed)
: _hasCreatedDatabase = true { : _hasCreatedDatabase = true {
@ -47,6 +49,12 @@ abstract class Sqlite3Delegate<DB extends CommonDatabase>
@override @override
Future<bool> get isOpen => Future.value(_isOpen); Future<bool> 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<void> flush() => null;
@override @override
Future<void> open(QueryExecutorUser db) async { Future<void> open(QueryExecutorUser db) async {
if (!_hasCreatedDatabase) { if (!_hasCreatedDatabase) {
@ -88,6 +96,10 @@ abstract class Sqlite3Delegate<DB extends CommonDatabase>
stmt.dispose(); stmt.dispose();
} }
if (!isInTransaction) {
await flush();
}
return Future.value(); return Future.value();
} }
@ -99,6 +111,10 @@ abstract class Sqlite3Delegate<DB extends CommonDatabase>
stmt.execute(args); stmt.execute(args);
stmt.dispose(); stmt.dispose();
} }
if (!isInTransaction) {
await flush();
}
} }
@override @override
@ -132,6 +148,8 @@ abstract class Sqlite3Delegate<DB extends CommonDatabase>
if (_closeUnderlyingWhenClosed) { if (_closeUnderlyingWhenClosed) {
beforeClose(_db); beforeClose(_db);
_db.dispose(); _db.dispose();
await flush();
} }
} }
} }

View File

@ -16,6 +16,7 @@ library drift.wasm;
import 'package:meta/meta.dart'; import 'package:meta/meta.dart';
import 'package:sqlite3/common.dart'; import 'package:sqlite3/common.dart';
import 'package:sqlite3/wasm.dart';
import 'backends.dart'; import 'backends.dart';
import 'src/sqlite3/database.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 /// Creates a wasm database at [path] in the virtual file system of the
/// [sqlite3] module. /// [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({ factory WasmDatabase({
required CommmonSqlite3 sqlite3, required CommmonSqlite3 sqlite3,
required String path, required String path,
WasmDatabaseSetup? setup, WasmDatabaseSetup? setup,
IndexedDbFileSystem? fileSystem,
bool logStatements = false, 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. /// Creates an in-memory database in the loaded [sqlite3] database.
@ -53,15 +61,18 @@ class WasmDatabase extends DelegatedDatabase {
WasmDatabaseSetup? setup, WasmDatabaseSetup? setup,
bool logStatements = false, bool logStatements = false,
}) { }) {
return WasmDatabase._(_WasmDelegate(sqlite3, null, setup), logStatements); return WasmDatabase._(
_WasmDelegate(sqlite3, null, setup, null), logStatements);
} }
} }
class _WasmDelegate extends Sqlite3Delegate<CommonDatabase> { class _WasmDelegate extends Sqlite3Delegate<CommonDatabase> {
final CommmonSqlite3 _sqlite3; final CommmonSqlite3 _sqlite3;
final String? _path; final String? _path;
final IndexedDbFileSystem? _fileSystem;
_WasmDelegate(this._sqlite3, this._path, WasmDatabaseSetup? setup) _WasmDelegate(
this._sqlite3, this._path, WasmDatabaseSetup? setup, this._fileSystem)
: super(setup); : super(setup);
@override @override
@ -73,4 +84,9 @@ class _WasmDelegate extends Sqlite3Delegate<CommonDatabase> {
return _sqlite3.open(path); return _sqlite3.open(path);
} }
} }
@override
Future<void> flush() async {
await _fileSystem?.flush();
}
} }