From 042063ea91d96dae9319981cf5cc607900d24ec8 Mon Sep 17 00:00:00 2001 From: Simon Binder Date: Thu, 9 Jul 2026 11:14:00 +0200 Subject: [PATCH] Add beforeOpen callback to native factories --- packages/sqlite_async/CHANGELOG.md | 5 +++++ .../database/native_sqlite_database.dart | 4 +++- .../native/native_sqlite_open_factory.dart | 13 ++++++++++++ .../sqlite_async/test/native/basic_test.dart | 20 +++++++++++++++++++ 4 files changed, 41 insertions(+), 1 deletion(-) diff --git a/packages/sqlite_async/CHANGELOG.md b/packages/sqlite_async/CHANGELOG.md index 5d18052..924097a 100644 --- a/packages/sqlite_async/CHANGELOG.md +++ b/packages/sqlite_async/CHANGELOG.md @@ -1,3 +1,8 @@ +## 0.14.4 + +- Native: Add the `NativeSqliteOpenFactory.beforeOpen` method, which can be overridden to configure + SQLite asynchronously before opening databases. + ## 0.14.3 - Include identifier of mutexes when a navigator lock attempt is aborted. diff --git a/packages/sqlite_async/lib/src/native/database/native_sqlite_database.dart b/packages/sqlite_async/lib/src/native/database/native_sqlite_database.dart index 8e6651d..e3c1202 100644 --- a/packages/sqlite_async/lib/src/native/database/native_sqlite_database.dart +++ b/packages/sqlite_async/lib/src/native/database/native_sqlite_database.dart @@ -251,7 +251,9 @@ final class NativeSqliteDatabaseImpl extends SqliteDatabaseImpl { static Future _openNativePool( NativeSqliteOpenFactory openFactory, - ) { + ) async { + await openFactory.beforeOpen(); + // We want to open pools asynchronously since running pragma statements as // part of openFactory.open might do IO. openAsync spawn a temporary isolate // for that. diff --git a/packages/sqlite_async/lib/src/native/native_sqlite_open_factory.dart b/packages/sqlite_async/lib/src/native/native_sqlite_open_factory.dart index 676c397..2c1cc97 100644 --- a/packages/sqlite_async/lib/src/native/native_sqlite_open_factory.dart +++ b/packages/sqlite_async/lib/src/native/native_sqlite_open_factory.dart @@ -1,3 +1,5 @@ +import 'dart:async'; + import 'package:sqlite3/sqlite3.dart' as sqlite; import '../common/abstract_open_factory.dart'; @@ -9,6 +11,17 @@ import '../common/abstract_open_factory.dart'; base class NativeSqliteOpenFactory extends InternalOpenFactory { NativeSqliteOpenFactory({required super.path, super.sqliteOptions}); + /// A (potentially asynchronous) hook to invoke before opening databases for + /// a pool. + /// + /// This does nothing by default, but can be overridden to apply global + /// SQLite configuration options before databases are opened, e.g. to set + /// [sqlite.CommonSqlite3.tempDirectory]. + /// + /// This method is invoked in the main isolate, not the background isolate + /// responsible for opening connections. + FutureOr beforeOpen() {} + @override List pragmaStatements(SqliteOpenOptions options) { List statements = []; diff --git a/packages/sqlite_async/test/native/basic_test.dart b/packages/sqlite_async/test/native/basic_test.dart index 721bf73..f6b6315 100644 --- a/packages/sqlite_async/test/native/basic_test.dart +++ b/packages/sqlite_async/test/native/basic_test.dart @@ -362,6 +362,15 @@ void main() { ), ); }); + + test('invokes beforeOpen callback on factories', () async { + final factoy = _BeforeSetupHook(path: path); + final db = SqliteDatabase.withFactory(factoy); + expect(factoy.didCallBeforeOpen, isFalse); + await db.initialize(); + + expect(factoy.didCallBeforeOpen, isTrue); + }); }); } @@ -381,3 +390,14 @@ final class _InvalidPragmaOnOpenFactory extends NativeSqliteOpenFactory { ]; } } + +final class _BeforeSetupHook extends NativeSqliteOpenFactory { + var didCallBeforeOpen = false; + + _BeforeSetupHook({required super.path}); + + @override + void beforeOpen() { + didCallBeforeOpen = true; + } +}