truncate method

Future<void> truncate()

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,
      ]);
    }
  });
}