mirror of https://github.com/AMT-Cheif/drift.git
Fix triggers in example app
This commit is contained in:
parent
ee66465d47
commit
04c3dbf1b5
|
@ -0,0 +1 @@
|
|||
{"_meta":{"description":"This file contains a serialized version of schema entities for drift.","version":"1.0.0"},"options":{"store_date_time_values_as_text":false},"entities":[{"id":0,"references":[],"type":"table","data":{"name":"categories","was_declared_in_moor":false,"columns":[{"name":"id","getter_name":"id","moor_type":"ColumnType.integer","nullable":false,"customConstraints":null,"defaultConstraints":"PRIMARY KEY AUTOINCREMENT","default_dart":null,"default_client_dart":null,"dsl_features":["auto-increment","primary-key"]},{"name":"name","getter_name":"name","moor_type":"ColumnType.text","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"color","getter_name":"color","moor_type":"ColumnType.integer","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[],"type_converter":{"dart_expr":"const ColorConverter()","dart_type_name":"Color"}}],"is_virtual":false}},{"id":1,"references":[0],"type":"table","data":{"name":"todo_entries","was_declared_in_moor":false,"columns":[{"name":"id","getter_name":"id","moor_type":"ColumnType.integer","nullable":false,"customConstraints":null,"defaultConstraints":"PRIMARY KEY AUTOINCREMENT","default_dart":null,"default_client_dart":null,"dsl_features":["auto-increment","primary-key"]},{"name":"description","getter_name":"description","moor_type":"ColumnType.text","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"category","getter_name":"category","moor_type":"ColumnType.integer","nullable":true,"customConstraints":null,"defaultConstraints":"REFERENCES categories (id)","default_dart":null,"default_client_dart":null,"dsl_features":["unknown"]},{"name":"due_date","getter_name":"dueDate","moor_type":"ColumnType.datetime","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]}],"is_virtual":false}},{"id":2,"references":[1],"type":"table","data":{"name":"text_entries","was_declared_in_moor":true,"columns":[{"name":"description","getter_name":"description","moor_type":"ColumnType.text","nullable":false,"customConstraints":"","default_dart":null,"default_client_dart":null,"dsl_features":[]}],"is_virtual":true,"create_virtual_stmt":"CREATE VIRTUAL TABLE text_entries USING fts5 (\n description,\n content=todo_entries,\n content_rowid=id\n);"}},{"id":3,"references":[1,2],"type":"trigger","data":{"on":1,"refences_in_body":[2,1],"name":"todos_insert","sql":"CREATE TRIGGER todos_insert AFTER INSERT ON todo_entries BEGIN INSERT INTO text_entries (\"rowid\", description) VALUES (new.id, new.description);END"}},{"id":4,"references":[1,2],"type":"trigger","data":{"on":1,"refences_in_body":[2,1],"name":"todos_delete","sql":"CREATE TRIGGER todos_delete AFTER DELETE ON todo_entries BEGIN INSERT INTO text_entries (text_entries, \"rowid\", description) VALUES ('delete', old.id, old.description);END"}},{"id":5,"references":[1,2],"type":"trigger","data":{"on":1,"refences_in_body":[2,1],"name":"todos_update","sql":"CREATE TRIGGER todos_update AFTER UPDATE ON todo_entries BEGIN INSERT INTO text_entries (text_entries, \"rowid\", description) VALUES ('delete', new.id, new.description);INSERT INTO text_entries (\"rowid\", description) VALUES (new.id, new.description);END"}}]}
|
|
@ -16,15 +16,29 @@ class AppDatabase extends _$AppDatabase {
|
|||
: super.connect(connection);
|
||||
|
||||
@override
|
||||
int get schemaVersion => 2;
|
||||
int get schemaVersion => 3;
|
||||
|
||||
@override
|
||||
MigrationStrategy get migration {
|
||||
return MigrationStrategy(
|
||||
onUpgrade: ((m, from, to) async {
|
||||
if (from == 1) {
|
||||
// The todoEntries.dueDate column was added in version 2.
|
||||
await m.addColumn(todoEntries, todoEntries.dueDate);
|
||||
for (var step = from + 1; step <= to; step++) {
|
||||
switch (step) {
|
||||
case 2:
|
||||
// The todoEntries.dueDate column was added in version 2.
|
||||
await m.addColumn(todoEntries, todoEntries.dueDate);
|
||||
break;
|
||||
case 3:
|
||||
// New triggers were added in version 3:
|
||||
await m.create(todosDelete);
|
||||
await m.create(todosUpdate);
|
||||
|
||||
// Also, the `REFERENCES` constraint was added to
|
||||
// [TodoEntries.category]. Run a table migration to rebuild all
|
||||
// column constraints without loosing data.
|
||||
await m.alterTable(TableMigration(todoEntries));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}),
|
||||
beforeOpen: (details) async {
|
||||
|
|
|
@ -623,6 +623,12 @@ abstract class _$AppDatabase extends GeneratedDatabase {
|
|||
late final Trigger todosInsert = Trigger(
|
||||
'CREATE TRIGGER todos_insert AFTER INSERT ON todo_entries BEGIN INSERT INTO text_entries ("rowid", description) VALUES (new.id, new.description);END',
|
||||
'todos_insert');
|
||||
late final Trigger todosDelete = Trigger(
|
||||
'CREATE TRIGGER todos_delete AFTER DELETE ON todo_entries BEGIN INSERT INTO text_entries (text_entries, "rowid", description) VALUES (\'delete\', old.id, old.description);END',
|
||||
'todos_delete');
|
||||
late final Trigger todosUpdate = Trigger(
|
||||
'CREATE TRIGGER todos_update AFTER UPDATE ON todo_entries BEGIN INSERT INTO text_entries (text_entries, "rowid", description) VALUES (\'delete\', new.id, new.description);INSERT INTO text_entries ("rowid", description) VALUES (new.id, new.description);END',
|
||||
'todos_update');
|
||||
Selectable<CategoriesWithCountResult> _categoriesWithCount() {
|
||||
return customSelect(
|
||||
'SELECT c.*, (SELECT COUNT(*) FROM todo_entries WHERE category = c.id) AS amount FROM categories AS c UNION ALL SELECT NULL, NULL, NULL, (SELECT COUNT(*) FROM todo_entries WHERE category IS NULL)',
|
||||
|
@ -663,8 +669,14 @@ abstract class _$AppDatabase extends GeneratedDatabase {
|
|||
Iterable<TableInfo<Table, dynamic>> get allTables =>
|
||||
allSchemaEntities.whereType<TableInfo<Table, Object?>>();
|
||||
@override
|
||||
List<DatabaseSchemaEntity> get allSchemaEntities =>
|
||||
[categories, todoEntries, textEntries, todosInsert];
|
||||
List<DatabaseSchemaEntity> get allSchemaEntities => [
|
||||
categories,
|
||||
todoEntries,
|
||||
textEntries,
|
||||
todosInsert,
|
||||
todosDelete,
|
||||
todosUpdate
|
||||
];
|
||||
@override
|
||||
StreamQueryUpdateRules get streamUpdateRules => const StreamQueryUpdateRules(
|
||||
[
|
||||
|
@ -675,6 +687,20 @@ abstract class _$AppDatabase extends GeneratedDatabase {
|
|||
TableUpdate('text_entries', kind: UpdateKind.insert),
|
||||
],
|
||||
),
|
||||
WritePropagation(
|
||||
on: TableUpdateQuery.onTableName('todo_entries',
|
||||
limitUpdateKind: UpdateKind.delete),
|
||||
result: [
|
||||
TableUpdate('text_entries', kind: UpdateKind.insert),
|
||||
],
|
||||
),
|
||||
WritePropagation(
|
||||
on: TableUpdateQuery.onTableName('todo_entries',
|
||||
limitUpdateKind: UpdateKind.update),
|
||||
result: [
|
||||
TableUpdate('text_entries', kind: UpdateKind.insert),
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
|
|
@ -15,17 +15,14 @@ CREATE TRIGGER todos_insert AFTER INSERT ON todo_entries BEGIN
|
|||
INSERT INTO text_entries(rowid, description) VALUES (new.id, new.description);
|
||||
END;
|
||||
|
||||
-- todo: Investigate why these two triggers are causing problems
|
||||
/*
|
||||
CREATE TRIGGER todos_delete AFTER INSERT ON todo_entries BEGIN
|
||||
INSERT INTO text_entries(text_entries, rowid, description) VALUES ('delete', new.id, new.description);
|
||||
CREATE TRIGGER todos_delete AFTER DELETE ON todo_entries BEGIN
|
||||
INSERT INTO text_entries(text_entries, rowid, description) VALUES ('delete', old.id, old.description);
|
||||
END;
|
||||
|
||||
CREATE TRIGGER todos_update AFTER INSERT ON todo_entries BEGIN
|
||||
CREATE TRIGGER todos_update AFTER UPDATE ON todo_entries BEGIN
|
||||
INSERT INTO text_entries(text_entries, rowid, description) VALUES ('delete', new.id, new.description);
|
||||
INSERT INTO text_entries(rowid, description) VALUES (new.id, new.description);
|
||||
END;
|
||||
*/
|
||||
|
||||
-- Queries can also be defined here, they're then added as methods to the database.
|
||||
_categoriesWithCount: SELECT c.*,
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
import 'package:drift/drift.dart';
|
||||
import 'package:drift_dev/api/migrations.dart';
|
||||
import 'schema_v2.dart' as v2;
|
||||
import 'schema_v3.dart' as v3;
|
||||
import 'schema_v1.dart' as v1;
|
||||
|
||||
class GeneratedHelper implements SchemaInstantiationHelper {
|
||||
|
@ -11,10 +12,12 @@ class GeneratedHelper implements SchemaInstantiationHelper {
|
|||
switch (version) {
|
||||
case 2:
|
||||
return v2.DatabaseAtV2(db);
|
||||
case 3:
|
||||
return v3.DatabaseAtV3(db);
|
||||
case 1:
|
||||
return v1.DatabaseAtV1(db);
|
||||
default:
|
||||
throw MissingSchemaException(version, const {2, 1});
|
||||
throw MissingSchemaException(version, const {2, 3, 1});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -78,13 +78,18 @@ class TodoEntries extends Table with TableInfo {
|
|||
bool get dontWriteConstraints => false;
|
||||
}
|
||||
|
||||
class text_entriesTable extends Table with TableInfo, VirtualTableInfo {
|
||||
class TextEntries extends Table with TableInfo, VirtualTableInfo {
|
||||
@override
|
||||
final GeneratedDatabase attachedDatabase;
|
||||
final String? _alias;
|
||||
text_entriesTable(this.attachedDatabase, [this._alias]);
|
||||
TextEntries(this.attachedDatabase, [this._alias]);
|
||||
late final GeneratedColumn<String> description = GeneratedColumn<String>(
|
||||
'description', aliasedName, false,
|
||||
type: DriftSqlType.string,
|
||||
requiredDuringInsert: true,
|
||||
$customConstraints: '');
|
||||
@override
|
||||
List<GeneratedColumn> get $columns => [];
|
||||
List<GeneratedColumn> get $columns => [description];
|
||||
@override
|
||||
String get aliasedName => _alias ?? 'text_entries';
|
||||
@override
|
||||
|
@ -97,8 +102,8 @@ class text_entriesTable extends Table with TableInfo, VirtualTableInfo {
|
|||
}
|
||||
|
||||
@override
|
||||
text_entriesTable createAlias(String alias) {
|
||||
return text_entriesTable(attachedDatabase, alias);
|
||||
TextEntries createAlias(String alias) {
|
||||
return TextEntries(attachedDatabase, alias);
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -113,12 +118,13 @@ class DatabaseAtV1 extends GeneratedDatabase {
|
|||
DatabaseAtV1.connect(DatabaseConnection c) : super.connect(c);
|
||||
late final Categories categories = Categories(this);
|
||||
late final TodoEntries todoEntries = TodoEntries(this);
|
||||
late final text_entriesTable textEntries = text_entriesTable(this);
|
||||
late final TextEntries textEntries = TextEntries(this);
|
||||
late final Trigger todosInsert = Trigger(
|
||||
'CREATE TRIGGER todos_insert AFTER INSERT ON todo_entries BEGIN\n INSERT INTO text_entries(rowid, description) VALUES (new.id, new.description);\nEND;',
|
||||
'todos_insert');
|
||||
@override
|
||||
Iterable<TableInfo> get allTables => allSchemaEntities.whereType<TableInfo>();
|
||||
Iterable<TableInfo<Table, dynamic>> get allTables =>
|
||||
allSchemaEntities.whereType<TableInfo<Table, Object?>>();
|
||||
@override
|
||||
List<DatabaseSchemaEntity> get allSchemaEntities =>
|
||||
[categories, todoEntries, textEntries, todosInsert];
|
||||
|
|
|
@ -81,13 +81,18 @@ class TodoEntries extends Table with TableInfo {
|
|||
bool get dontWriteConstraints => false;
|
||||
}
|
||||
|
||||
class text_entriesTable extends Table with TableInfo, VirtualTableInfo {
|
||||
class TextEntries extends Table with TableInfo, VirtualTableInfo {
|
||||
@override
|
||||
final GeneratedDatabase attachedDatabase;
|
||||
final String? _alias;
|
||||
text_entriesTable(this.attachedDatabase, [this._alias]);
|
||||
TextEntries(this.attachedDatabase, [this._alias]);
|
||||
late final GeneratedColumn<String> description = GeneratedColumn<String>(
|
||||
'description', aliasedName, false,
|
||||
type: DriftSqlType.string,
|
||||
requiredDuringInsert: true,
|
||||
$customConstraints: '');
|
||||
@override
|
||||
List<GeneratedColumn> get $columns => [];
|
||||
List<GeneratedColumn> get $columns => [description];
|
||||
@override
|
||||
String get aliasedName => _alias ?? 'text_entries';
|
||||
@override
|
||||
|
@ -100,8 +105,8 @@ class text_entriesTable extends Table with TableInfo, VirtualTableInfo {
|
|||
}
|
||||
|
||||
@override
|
||||
text_entriesTable createAlias(String alias) {
|
||||
return text_entriesTable(attachedDatabase, alias);
|
||||
TextEntries createAlias(String alias) {
|
||||
return TextEntries(attachedDatabase, alias);
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -116,12 +121,13 @@ class DatabaseAtV2 extends GeneratedDatabase {
|
|||
DatabaseAtV2.connect(DatabaseConnection c) : super.connect(c);
|
||||
late final Categories categories = Categories(this);
|
||||
late final TodoEntries todoEntries = TodoEntries(this);
|
||||
late final text_entriesTable textEntries = text_entriesTable(this);
|
||||
late final TextEntries textEntries = TextEntries(this);
|
||||
late final Trigger todosInsert = Trigger(
|
||||
'CREATE TRIGGER todos_insert AFTER INSERT ON todo_entries BEGIN\n INSERT INTO text_entries(rowid, description) VALUES (new.id, new.description);\nEND;',
|
||||
'todos_insert');
|
||||
@override
|
||||
Iterable<TableInfo> get allTables => allSchemaEntities.whereType<TableInfo>();
|
||||
Iterable<TableInfo<Table, dynamic>> get allTables =>
|
||||
allSchemaEntities.whereType<TableInfo<Table, Object?>>();
|
||||
@override
|
||||
List<DatabaseSchemaEntity> get allSchemaEntities =>
|
||||
[categories, todoEntries, textEntries, todosInsert];
|
||||
|
|
|
@ -0,0 +1,150 @@
|
|||
// GENERATED CODE, DO NOT EDIT BY HAND.
|
||||
//@dart=2.12
|
||||
import 'package:drift/drift.dart';
|
||||
|
||||
class Categories extends Table with TableInfo {
|
||||
@override
|
||||
final GeneratedDatabase attachedDatabase;
|
||||
final String? _alias;
|
||||
Categories(this.attachedDatabase, [this._alias]);
|
||||
late final GeneratedColumn<int> id = GeneratedColumn<int>(
|
||||
'id', aliasedName, false,
|
||||
type: DriftSqlType.int,
|
||||
requiredDuringInsert: false,
|
||||
defaultConstraints: 'PRIMARY KEY AUTOINCREMENT');
|
||||
late final GeneratedColumn<String> name = GeneratedColumn<String>(
|
||||
'name', aliasedName, false,
|
||||
type: DriftSqlType.string, requiredDuringInsert: true);
|
||||
late final GeneratedColumn<int> color = GeneratedColumn<int>(
|
||||
'color', aliasedName, false,
|
||||
type: DriftSqlType.int, requiredDuringInsert: true);
|
||||
@override
|
||||
List<GeneratedColumn> get $columns => [id, name, color];
|
||||
@override
|
||||
String get aliasedName => _alias ?? 'categories';
|
||||
@override
|
||||
String get actualTableName => 'categories';
|
||||
@override
|
||||
Set<GeneratedColumn> get $primaryKey => {id};
|
||||
@override
|
||||
Never map(Map<String, dynamic> data, {String? tablePrefix}) {
|
||||
throw UnsupportedError('TableInfo.map in schema verification code');
|
||||
}
|
||||
|
||||
@override
|
||||
Categories createAlias(String alias) {
|
||||
return Categories(attachedDatabase, alias);
|
||||
}
|
||||
|
||||
@override
|
||||
bool get dontWriteConstraints => false;
|
||||
}
|
||||
|
||||
class TodoEntries extends Table with TableInfo {
|
||||
@override
|
||||
final GeneratedDatabase attachedDatabase;
|
||||
final String? _alias;
|
||||
TodoEntries(this.attachedDatabase, [this._alias]);
|
||||
late final GeneratedColumn<int> id = GeneratedColumn<int>(
|
||||
'id', aliasedName, false,
|
||||
type: DriftSqlType.int,
|
||||
requiredDuringInsert: false,
|
||||
defaultConstraints: 'PRIMARY KEY AUTOINCREMENT');
|
||||
late final GeneratedColumn<String> description = GeneratedColumn<String>(
|
||||
'description', aliasedName, false,
|
||||
type: DriftSqlType.string, requiredDuringInsert: true);
|
||||
late final GeneratedColumn<int> category = GeneratedColumn<int>(
|
||||
'category', aliasedName, true,
|
||||
type: DriftSqlType.int,
|
||||
requiredDuringInsert: false,
|
||||
defaultConstraints: 'REFERENCES categories (id)');
|
||||
late final GeneratedColumn<DateTime> dueDate = GeneratedColumn<DateTime>(
|
||||
'due_date', aliasedName, true,
|
||||
type: DriftSqlType.dateTime, requiredDuringInsert: false);
|
||||
@override
|
||||
List<GeneratedColumn> get $columns => [id, description, category, dueDate];
|
||||
@override
|
||||
String get aliasedName => _alias ?? 'todo_entries';
|
||||
@override
|
||||
String get actualTableName => 'todo_entries';
|
||||
@override
|
||||
Set<GeneratedColumn> get $primaryKey => {id};
|
||||
@override
|
||||
Never map(Map<String, dynamic> data, {String? tablePrefix}) {
|
||||
throw UnsupportedError('TableInfo.map in schema verification code');
|
||||
}
|
||||
|
||||
@override
|
||||
TodoEntries createAlias(String alias) {
|
||||
return TodoEntries(attachedDatabase, alias);
|
||||
}
|
||||
|
||||
@override
|
||||
bool get dontWriteConstraints => false;
|
||||
}
|
||||
|
||||
class TextEntries extends Table with TableInfo, VirtualTableInfo {
|
||||
@override
|
||||
final GeneratedDatabase attachedDatabase;
|
||||
final String? _alias;
|
||||
TextEntries(this.attachedDatabase, [this._alias]);
|
||||
late final GeneratedColumn<String> description = GeneratedColumn<String>(
|
||||
'description', aliasedName, false,
|
||||
type: DriftSqlType.string,
|
||||
requiredDuringInsert: true,
|
||||
$customConstraints: '');
|
||||
@override
|
||||
List<GeneratedColumn> get $columns => [description];
|
||||
@override
|
||||
String get aliasedName => _alias ?? 'text_entries';
|
||||
@override
|
||||
String get actualTableName => 'text_entries';
|
||||
@override
|
||||
Set<GeneratedColumn> get $primaryKey => <GeneratedColumn>{};
|
||||
@override
|
||||
Never map(Map<String, dynamic> data, {String? tablePrefix}) {
|
||||
throw UnsupportedError('TableInfo.map in schema verification code');
|
||||
}
|
||||
|
||||
@override
|
||||
TextEntries createAlias(String alias) {
|
||||
return TextEntries(attachedDatabase, alias);
|
||||
}
|
||||
|
||||
@override
|
||||
bool get dontWriteConstraints => true;
|
||||
@override
|
||||
String get moduleAndArgs =>
|
||||
'fts5(description, content=todo_entries, content_rowid=id)';
|
||||
}
|
||||
|
||||
class DatabaseAtV3 extends GeneratedDatabase {
|
||||
DatabaseAtV3(QueryExecutor e) : super(e);
|
||||
DatabaseAtV3.connect(DatabaseConnection c) : super.connect(c);
|
||||
late final Categories categories = Categories(this);
|
||||
late final TodoEntries todoEntries = TodoEntries(this);
|
||||
late final TextEntries textEntries = TextEntries(this);
|
||||
late final Trigger todosInsert = Trigger(
|
||||
'CREATE TRIGGER todos_insert AFTER INSERT ON todo_entries BEGIN INSERT INTO text_entries ("rowid", description) VALUES (new.id, new.description);END',
|
||||
'todos_insert');
|
||||
late final Trigger todosDelete = Trigger(
|
||||
'CREATE TRIGGER todos_delete AFTER DELETE ON todo_entries BEGIN INSERT INTO text_entries (text_entries, "rowid", description) VALUES (\'delete\', old.id, old.description);END',
|
||||
'todos_delete');
|
||||
late final Trigger todosUpdate = Trigger(
|
||||
'CREATE TRIGGER todos_update AFTER UPDATE ON todo_entries BEGIN INSERT INTO text_entries (text_entries, "rowid", description) VALUES (\'delete\', new.id, new.description);INSERT INTO text_entries ("rowid", description) VALUES (new.id, new.description);END',
|
||||
'todos_update');
|
||||
@override
|
||||
Iterable<TableInfo<Table, dynamic>> get allTables =>
|
||||
allSchemaEntities.whereType<TableInfo<Table, Object?>>();
|
||||
@override
|
||||
List<DatabaseSchemaEntity> get allSchemaEntities => [
|
||||
categories,
|
||||
todoEntries,
|
||||
textEntries,
|
||||
todosInsert,
|
||||
todosDelete,
|
||||
todosUpdate
|
||||
];
|
||||
@override
|
||||
int get schemaVersion => 3;
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
import 'package:app/database/database.dart';
|
||||
import 'package:drift/drift.dart';
|
||||
import 'package:drift_dev/api/migrations.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
|
@ -13,6 +14,60 @@ void main() {
|
|||
verifier = SchemaVerifier(GeneratedHelper());
|
||||
});
|
||||
|
||||
group('schema integrity is kept', () {
|
||||
const currentVersion = 3;
|
||||
|
||||
// This loop tests all possible schema upgrades. It uses drift APIs to
|
||||
// ensure that the schema is in the expected format after an upgrade, but
|
||||
// simple tests like these can't ensure that your migration doesn't loose
|
||||
// data.
|
||||
for (var start = 1; start < currentVersion; start++) {
|
||||
group('from v$start', () {
|
||||
for (var target = start + 1; target <= currentVersion; target++) {
|
||||
test('to v$target', () async {
|
||||
// Use startAt() to obtain a database connection with all tables
|
||||
// from the old schema set up.
|
||||
final connection = await verifier.startAt(start);
|
||||
final db = AppDatabase.forTesting(connection);
|
||||
addTearDown(db.close);
|
||||
|
||||
// Use this to run a migration and then validate that the database
|
||||
// has the expected schema.
|
||||
await verifier.migrateAndValidate(db, target);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// For specific schema upgrades, you can also write manual tests to ensure
|
||||
// that running the migration does not loose data.
|
||||
test('upgrading from v1 to v2 does not loose data', () async {
|
||||
// Use startAt(1) to obtain a usable database
|
||||
final connection = await verifier.schemaAt(1);
|
||||
connection.rawDatabase.execute(
|
||||
'INSERT INTO todo_entries (description) VALUES (?)',
|
||||
['My manually added entry'],
|
||||
);
|
||||
|
||||
final db = AppDatabase.forTesting(connection.newConnection());
|
||||
addTearDown(db.close);
|
||||
await verifier.migrateAndValidate(db, 2);
|
||||
|
||||
// Make sure that the row is still there after migrating
|
||||
expect(
|
||||
db.todoEntries.select().get(),
|
||||
completion(
|
||||
[
|
||||
const TodoEntry(
|
||||
id: 1,
|
||||
description: 'My manually added entry',
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
});
|
||||
|
||||
test('upgrade from v1 to v2', () async {
|
||||
// Use startAt(1) to obtain a database connection with all tables
|
||||
// from the v1 schema.
|
||||
|
|
Loading…
Reference in New Issue