Fix `validateDatabaseSchema`

This commit is contained in:
Simon Binder 2022-03-01 20:41:00 +01:00
parent 7e798572a0
commit db1a4e2827
No known key found for this signature in database
GPG Key ID: 7891917E4147B8C0
4 changed files with 47 additions and 13 deletions

View File

@ -474,7 +474,7 @@ you can use a new API from `drift_dev` 1.5.0 to verify the current schema withou
import 'package:drift_dev/api/migrations.dart';
// Then, in your database...
final migration = SchemaMigration(
MigrationStrategy get migration = MigrationStratey(
onCreate: (m) async { /* ... */ }
onUpgrade: (m, from, to) async { /* your existing migration logic */ },
beforeOpen: (details) async {

View File

@ -325,6 +325,8 @@ void main() {
test('throws when a schema is not created properly', () {
final executor = NativeDatabase.memory();
final db = TodoDb(executor);
addTearDown(db.close);
db.migration = MigrationStrategy(
onCreate: (m) async {
// Only creating one table, won't be enough
@ -342,6 +344,8 @@ void main() {
test('does not throw for a matching schema', () {
final executor = NativeDatabase.memory();
final db = TodoDb(executor);
addTearDown(db.close);
db.migration = MigrationStrategy(
// use default and correct `onCreate`, validation should work
beforeOpen: (details) async {
@ -351,6 +355,14 @@ void main() {
expect(db.customSelect('SELECT 1;').get(), completes);
});
test("can be used on a database before it's opened", () async {
final executor = NativeDatabase.memory();
final db = TodoDb(executor);
addTearDown(db.close);
expect(db.validateDatabaseSchema(), completes);
});
});
}

View File

@ -86,14 +86,12 @@ extension VerifySelf on GeneratedDatabase {
.map((e) => e.entityName)
.toList();
final schemaOfThisDatabase =
await executor.collectSchemaInput(virtualTables);
final schemaOfThisDatabase = await collectSchemaInput(virtualTables);
// Collect the schema hwo it would be if we just called `createAll` on a
// Collect the schema how it would be if we just called `createAll` on a
// clean database.
final referenceDb = _GenerateFromScratch(this, NativeDatabase.memory());
final referenceSchema = await referenceDb
.doWhenOpened((e) => e.collectSchemaInput(virtualTables));
final referenceSchema = await referenceDb.collectSchemaInput(virtualTables);
verify(referenceSchema, schemaOfThisDatabase, validateDropped);
}

View File

@ -79,19 +79,43 @@ class VerifierImplementation implements SchemaVerifier {
}
}
Input? _parseInputFromSchemaRow(
Map<String, Object?> row, List<String> virtualTables) {
final name = row['name'] as String;
// Skip sqlite-internal tables
if (name.startsWith('sqlite_autoindex')) return null;
if (virtualTables.any((v) => name.startsWith('${v}_'))) return null;
return Input(name, row['sql'] as String);
}
extension CollectSchemaDb on DatabaseConnectionUser {
Future<List<Input>> collectSchemaInput(List<String> virtualTables) async {
final result = await customSelect('SELECT * FROM sqlite_master;').get();
final inputs = <Input>[];
for (final row in result) {
final input = _parseInputFromSchemaRow(row.data, virtualTables);
if (input != null) {
inputs.add(input);
}
}
return inputs;
}
}
extension CollectSchema on QueryExecutor {
Future<List<Input>> collectSchemaInput(List<String> virtualTables) async {
final result = await runSelect('SELECT * FROM sqlite_master;', const []);
final inputs = <Input>[];
for (final row in result) {
final name = row['name'] as String;
// Skip sqlite-internal tables
if (name.startsWith('sqlite_autoindex')) continue;
if (virtualTables.any((v) => name.startsWith('${v}_'))) continue;
inputs.add(Input(name, row['sql'] as String));
final input = _parseInputFromSchemaRow(row, virtualTables);
if (input != null) {
inputs.add(input);
}
}
return inputs;