migrate method
Initialize or update the database.
Throws MigrationError if the database cannot be migrated.
Implementation
Future<void> migrate(SqliteConnection db) async {
_validateCreateDatabase();
await db.writeTransaction((tx) async {
await tx.execute(
'CREATE TABLE IF NOT EXISTS $migrationTable(id INTEGER PRIMARY KEY, down_migrations TEXT)');
int currentVersion = await getCurrentVersion(tx);
if (currentVersion == version) {
return;
}
// Handle down migrations
while (currentVersion > version) {
final migrationRow = await tx.getOptional(
'SELECT id, down_migrations FROM $migrationTable WHERE id > ? ORDER BY id DESC LIMIT 1',
[version]);
if (migrationRow == null || migrationRow['down_migrations'] == null) {
throw MigrationError(
'No down migration found from $currentVersion to $version');
}
final migrations = jsonDecode(migrationRow['down_migrations']);
for (var migration in migrations) {
await tx.execute(migration['sql'], migration['params']);
}
// Refresh version
int prevVersion = currentVersion;
currentVersion = await getCurrentVersion(tx);
if (prevVersion == currentVersion) {
throw MigrationError(
'Database down from version $currentVersion to $version failed - version not updated after dow migration');
}
}
// Clean setup
if (currentVersion == 0 && createDatabase != null) {
await createDatabase!.fn(tx);
// Still need to persist the migrations
for (var migration in migrations) {
if (migration.toVersion <= createDatabase!.toVersion) {
await _persistMigration(migration, tx, migrationTable);
}
}
currentVersion = await getCurrentVersion(tx);
}
// Up migrations
for (var migration in migrations) {
if (migration.toVersion > currentVersion) {
await migration.fn(tx);
await _persistMigration(migration, tx, migrationTable);
}
}
});
}