mirror of https://github.com/AMT-Cheif/drift.git
Support creating databases from an asset
This commit is contained in:
parent
cdb231e1ae
commit
925f80aa9f
|
@ -1,6 +1,8 @@
|
|||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:tests/tests.dart';
|
||||
import 'package:test/test.dart';
|
||||
import 'package:moor_flutter/moor_flutter.dart';
|
||||
import 'package:sqflite/sqflite.dart' show getDatabasesPath;
|
||||
import 'package:path/path.dart';
|
||||
|
@ -27,4 +29,22 @@ class SqfliteExecutor extends TestExecutor {
|
|||
|
||||
void main() {
|
||||
runAllTests(SqfliteExecutor());
|
||||
|
||||
// Additional integration test for flutter: Test loading a database from asset
|
||||
test('can load a database from asset', () async {
|
||||
var didCallCreator = false;
|
||||
final executor = FlutterQueryExecutor.inDatabaseFolder(
|
||||
path: 'app_from_asset.db',
|
||||
singleInstance: true,
|
||||
creator: (file) async {
|
||||
final content = await rootBundle.load('test_asset.db');
|
||||
await file.writeAsBytes(content.buffer.asUint8List());
|
||||
didCallCreator = true;
|
||||
},
|
||||
);
|
||||
final database = Database(executor);
|
||||
await database.getUserById(0); // load user so that the db is opened
|
||||
|
||||
expect(didCallCreator, isTrue);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -159,7 +159,7 @@ packages:
|
|||
name: meta
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.6"
|
||||
version: "1.1.7"
|
||||
mime:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
|
@ -19,4 +19,8 @@ dependency_overrides:
|
|||
moor_flutter:
|
||||
path: ../../../moor_flutter
|
||||
moor:
|
||||
path: ../../../moor
|
||||
path: ../../../moor
|
||||
|
||||
flutter:
|
||||
assets:
|
||||
- test_asset.db
|
Binary file not shown.
|
@ -5,6 +5,7 @@
|
|||
library moor_flutter;
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
import 'package:meta/meta.dart';
|
||||
import 'package:path/path.dart';
|
||||
import 'package:moor/moor.dart';
|
||||
|
@ -14,6 +15,11 @@ import 'package:sqflite/sqflite.dart' as s;
|
|||
export 'package:moor_flutter/src/animated_list.dart';
|
||||
export 'package:moor/moor.dart';
|
||||
|
||||
/// Signature of a function that runs when a database doesn't exist on file.
|
||||
/// This can be useful to, for instance, load the database from an asset if it
|
||||
/// doesn't exist.
|
||||
typedef DatabaseCreator = FutureOr<void> Function(File file);
|
||||
|
||||
class _SqfliteDelegate extends DatabaseDelegate with _SqfliteExecutor {
|
||||
int _loadedSchemaVersion;
|
||||
@override
|
||||
|
@ -23,8 +29,10 @@ class _SqfliteDelegate extends DatabaseDelegate with _SqfliteExecutor {
|
|||
final String path;
|
||||
|
||||
bool singleInstance;
|
||||
final DatabaseCreator creator;
|
||||
|
||||
_SqfliteDelegate(this.inDbFolder, this.path, {this.singleInstance}) {
|
||||
_SqfliteDelegate(this.inDbFolder, this.path,
|
||||
{this.singleInstance, this.creator}) {
|
||||
singleInstance ??= true;
|
||||
}
|
||||
|
||||
|
@ -49,6 +57,11 @@ class _SqfliteDelegate extends DatabaseDelegate with _SqfliteExecutor {
|
|||
resolvedPath = path;
|
||||
}
|
||||
|
||||
final file = File(resolvedPath);
|
||||
if (creator != null && !await file.exists()) {
|
||||
await creator(file);
|
||||
}
|
||||
|
||||
// default value when no migration happened
|
||||
_loadedSchemaVersion = db.schemaVersion;
|
||||
|
||||
|
@ -82,7 +95,7 @@ class _SqfliteTransactionDelegate extends SupportedTransactionDelegate {
|
|||
final executor = _SqfliteTransactionExecutor(transaction);
|
||||
await run(executor);
|
||||
}).catchError((_) {
|
||||
// Ignore the errr! We send a fake exception to indicate a rollback.
|
||||
// Ignore the error! We send a fake exception to indicate a rollback.
|
||||
// sqflite will rollback, but the exception will bubble up. Here we stop
|
||||
// the exception.
|
||||
});
|
||||
|
@ -140,9 +153,20 @@ class FlutterQueryExecutor extends DelegatedDatabase {
|
|||
/// [path]. If [logStatements] is true, statements sent to the database will
|
||||
/// be [print]ed, which can be handy for debugging. The [singleInstance]
|
||||
/// parameter sets the corresponding parameter on [s.openDatabase].
|
||||
/// The [creator] will be called when the database file doesn't exist. It can
|
||||
/// be used to, for instance, populate default data from an asset. Note that
|
||||
/// migrations might behave differently when populating the database this way.
|
||||
/// For instance, a database created by an [creator] will not receive the
|
||||
/// [MigrationStrategy.onCreate] callback because it hasn't been created by
|
||||
/// moor.
|
||||
FlutterQueryExecutor(
|
||||
{@required String path, bool logStatements, bool singleInstance})
|
||||
: super(_SqfliteDelegate(false, path, singleInstance: singleInstance),
|
||||
{@required String path,
|
||||
bool logStatements,
|
||||
bool singleInstance,
|
||||
DatabaseCreator creator})
|
||||
: super(
|
||||
_SqfliteDelegate(false, path,
|
||||
singleInstance: singleInstance, creator: creator),
|
||||
logStatements: logStatements);
|
||||
|
||||
/// A query executor that will store the database in the file declared by
|
||||
|
@ -150,8 +174,19 @@ class FlutterQueryExecutor extends DelegatedDatabase {
|
|||
/// If [logStatements] is true, statements sent to the database will
|
||||
/// be [print]ed, which can be handy for debugging. The [singleInstance]
|
||||
/// parameter sets the corresponding parameter on [s.openDatabase].
|
||||
/// The [creator] will be called when the database file doesn't exist. It can
|
||||
/// be used to, for instance, populate default data from an asset. Note that
|
||||
/// migrations might behave differently when populating the database this way.
|
||||
/// For instance, a database created by an [creator] will not receive the
|
||||
/// [MigrationStrategy.onCreate] callback because it hasn't been created by
|
||||
/// moor.
|
||||
FlutterQueryExecutor.inDatabaseFolder(
|
||||
{@required String path, bool logStatements, bool singleInstance})
|
||||
: super(_SqfliteDelegate(true, path, singleInstance: singleInstance),
|
||||
{@required String path,
|
||||
bool logStatements,
|
||||
bool singleInstance,
|
||||
DatabaseCreator creator})
|
||||
: super(
|
||||
_SqfliteDelegate(true, path,
|
||||
singleInstance: singleInstance, creator: creator),
|
||||
logStatements: logStatements);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue