Skip to content

Commit bddcede

Browse files
committed
db: Drop all tables on downgrade
We previously missed tables that are not known to the schema. This becomes an issue if a new table is added at a newer schema level. When we go back to an earlier schema, that new table remains in the database, so subsequent attempts to upgrade to the later schema level that adds the table will fail, because it already exists. Testing for this is blocked until #1172. Signed-off-by: Zixuan James Li <[email protected]>
1 parent e9243d1 commit bddcede

File tree

1 file changed

+21
-8
lines changed

1 file changed

+21
-8
lines changed

Diff for: lib/model/database.dart

+21-8
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,26 @@ class AppDatabase extends _$AppDatabase {
6565
@override
6666
int get schemaVersion => 2; // See note.
6767

68+
Future<void> _resetDatabase(Migrator m) async {
69+
// This should only ever happen in dev. As a dev convenience,
70+
// drop everything from the database and start over.
71+
await m.database.transaction(() async {
72+
final query = m.database.customSelect(
73+
"SELECT name FROM sqlite_master WHERE type='table'");
74+
for (final row in await query.get()) {
75+
final data = row.data;
76+
final tableName = data['name'] as String;
77+
// Skip sqlite-internal tables, https://www.sqlite.org/fileformat2.html#intschema
78+
// https://github.com/simolus3/drift/blob/0901c984a987e54ba0b67e227adbfdcf3c08eeb4/drift_dev/lib/src/services/schema/verifier_common.dart#L9-L22
79+
if (tableName.startsWith('sqlite_')) continue;
80+
// SQL injection could be a concern, but the database would've been
81+
// compromised if the table name is corrupted.
82+
await m.database.customStatement('DROP TABLE $tableName');
83+
}
84+
await m.createAll();
85+
});
86+
}
87+
6888
@override
6989
MigrationStrategy get migration {
7090
return MigrationStrategy(
@@ -74,14 +94,7 @@ class AppDatabase extends _$AppDatabase {
7494
onUpgrade: (Migrator m, int from, int to) async {
7595
if (from > to) {
7696
// TODO(log): log schema downgrade as an error
77-
// This should only ever happen in dev. As a dev convenience,
78-
// drop everything from the database and start over.
79-
for (final entity in allSchemaEntities) {
80-
// This will miss any entire tables (or indexes, etc.) that
81-
// don't exist at this version. For a dev-only feature, that's OK.
82-
await m.drop(entity);
83-
}
84-
await m.createAll();
97+
await _resetDatabase(m);
8598
return;
8699
}
87100
assert(1 <= from && from <= to && to <= schemaVersion);

0 commit comments

Comments
 (0)