Add setup callback for moor ffi

This commit is contained in:
Simon Binder 2020-07-18 18:19:42 +02:00
parent ebb7448d1b
commit 165fc37721
No known key found for this signature in database
GPG Key ID: 7891917E4147B8C0
3 changed files with 54 additions and 6 deletions

View File

@ -5,6 +5,13 @@ import 'package:sqlite3/sqlite3.dart';
import 'moor_ffi_functions.dart';
/// Signature of a function that can perform setup work on a [database] before
/// moor is fully ready.
///
/// This could be used to, for instance, set encryption keys for SQLCipher
/// implementations.
typedef DatabaseSetup = void Function(Database database);
/// A moor database that runs on the Dart VM.
class VmDatabase extends DelegatedDatabase {
VmDatabase._(DatabaseDelegate delegate, bool logStatements)
@ -12,13 +19,28 @@ class VmDatabase extends DelegatedDatabase {
/// Creates a database that will store its result in the [file], creating it
/// if it doesn't exist.
factory VmDatabase(File file, {bool logStatements = false}) {
return VmDatabase._(_VmDelegate(file), logStatements);
///
/// If [logStatements] is true (defaults to `false`), generated sql statements
/// will be printed before executing. This can be useful for debugging.
/// The optional [setup] function can be used to perform a setup just after
/// the database is opened, before moor is fully ready. This can be used to
/// add custom user-defined sql functions or to provide encryption keys in
/// SQLCipher implementations.
factory VmDatabase(File file,
{bool logStatements = false, DatabaseSetup setup}) {
return VmDatabase._(_VmDelegate(file, setup), logStatements);
}
/// Creates an in-memory database won't persist its changes on disk.
factory VmDatabase.memory({bool logStatements = false}) {
return VmDatabase._(_VmDelegate(null), logStatements);
///
/// If [logStatements] is true (defaults to `false`), generated sql statements
/// will be printed before executing. This can be useful for debugging.
/// The optional [setup] function can be used to perform a setup just after
/// the database is opened, before moor is fully ready. This can be used to
/// add custom user-defined sql functions or to provide encryption keys in
/// SQLCipher implementations.
factory VmDatabase.memory({bool logStatements = false, DatabaseSetup setup}) {
return VmDatabase._(_VmDelegate(null, setup), logStatements);
}
}
@ -26,11 +48,12 @@ class _VmDelegate extends DatabaseDelegate {
Database _db;
final File file;
final DatabaseSetup setup;
_VmDelegate(this.file);
_VmDelegate(this.file, this.setup);
@override
final TransactionDelegate transactionDelegate = const NoTransactionDelegate();
TransactionDelegate get transactionDelegate => const NoTransactionDelegate();
@override
DbVersionDelegate versionDelegate;
@ -46,6 +69,9 @@ class _VmDelegate extends DatabaseDelegate {
_db = sqlite3.openInMemory();
}
_db.useMoorVersions();
if (setup != null) {
setup(_db);
}
versionDelegate = _VmVersionDelegate(_db);
return Future.value();
}

View File

@ -1,3 +1,4 @@
@TestOn('vm')
import 'dart:math';
import 'package:moor/src/ffi/moor_ffi_functions.dart';

View File

@ -0,0 +1,21 @@
@TestOn('vm')
import 'package:moor/ffi.dart';
import 'package:test/test.dart';
import '../data/tables/todos.dart';
void main() {
test('can use a custom setup function', () async {
final executor = VmDatabase.memory(setup: (db) {
db.createFunction(
functionName: 'my_function',
function: (args) => 'hello from Dart',
);
});
final db = TodoDb(executor);
final row = await db.customSelect('SELECT my_function() AS r;').getSingle();
expect(row.readString('r'), 'hello from Dart');
});
}