migrate method

Future<void> migrate(
  1. SqliteConnection db
)

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