truncate method
Deletes every row from every table except the migrator's own
bookkeeping, keeping the schema, and resets autoincrement counters so
ids restart at 1. Wire into tearDown.
Deletion runs inside a transaction with defer_foreign_keys on, so
tables can be emptied in any order: constraints are checked at commit,
by which point every table is empty. The pragma is transaction-scoped
and SQLite clears it on commit or rollback, so enforcement cannot stay
off. pragma foreign_keys = off would NOT work here — SQLite ignores it
inside a transaction.
Implementation
Future<void> truncate() async {
const bookkeeping = 'migrations';
final connection = _connection;
final schema = Schema.on(connection);
final rows = await connection.select(schema.grammar.compileTableListing());
final tables = [
for (final row in rows)
if (row.values.first case final String name when name != bookkeeping)
name,
];
await connection.transaction((tx) async {
await tx.execute('pragma defer_foreign_keys = on');
for (final table in tables) {
await tx.execute('delete from ${connection.grammar.wrapTable(table)}');
}
if (await schema.hasTable('sqlite_sequence')) {
await tx.execute('delete from sqlite_sequence where name != ?', [
bookkeeping,
]);
}
});
}