baseline method

Future<SchemaVerification> baseline(
  1. List<Migration> migrations, {
  2. required SchemaSnapshot expected,
})

Registers a verified existing database without replaying creation SQL.

Implementation

Future<SchemaVerification> baseline(
  List<Migration> migrations, {
  required SchemaSnapshot expected,
}) async {
  if (isMysqlFamily(database.dialect)) {
    return mysqlBaseline(this, migrations, expected);
  }
  validateMigrations(migrations, dialect: database.dialect);
  if (database.inTransaction) {
    throw const OrmException(
      'MIGRATION.SESSION',
      'Baseline requires an outer session.',
    );
  }
  if (migrations.isEmpty ||
      migrations.last.snapshot?.checksum !=
          expected.forDialect(database.dialect).checksum) {
    throw const OrmException(
      'MIGRATION.BASELINE',
      'The final migration must carry the expected baseline snapshot.',
    );
  }
  return migrationSession(
    database,
    lockTimeout,
    (session) => session.transaction(
      (tx) async {
        if ((await Migrator(tx).history()).isNotEmpty ||
            (await loadMigrationProgress(tx)).isNotEmpty) {
          throw const OrmException(
            'MIGRATION.BASELINE',
            'Migration history already exists.',
          );
        }
        final verification = await verifySchema(tx, expected);
        if (!verification.matches) {
          throw OrmException(
            'MIGRATION.DRIFT',
            verification.differences.join('\n'),
          );
        }
        await tx.execute(
          SqlCommand(
            'CREATE TABLE IF NOT EXISTS "_orm_migrations" (id TEXT PRIMARY KEY, checksum TEXT NOT NULL, applied_at TEXT NOT NULL)',
          ),
        );
        for (final migration in migrations) {
          await recordMigration(tx, migration);
        }
        return verification;
      },
      options: database.dialect == SqlDialect.sqlite
          ? const SqliteTransaction(mode: .immediate)
          : const PostgresTransaction(),
    ),
  );
}