verifyColumns function
Column drift check. Constraints, indexes and unmanaged objects are separate catalog checks; this method does not pretend that columns prove full equality.
Implementation
Future<List<String>> verifyColumns(
SqlDatabase<Backend> db,
List<TableSchema> tables,
) async {
final differences = <String>[];
for (final table in tables) {
final inspected = await inspectColumns(db, table.name);
final actual = {for (final c in inspected) c.name: c};
var contextMatches = true;
for (final expected in table.columns) {
final column = actual.remove(expected.name);
final path = '${table.name}.${expected.name}';
if (column == null) {
contextMatches = false;
differences.add('$path is missing');
continue;
}
if (column.storageType != columnStorageType(expected, db.dialect)) {
contextMatches = false;
differences.add('$path type is ${column.storageType}');
}
if (column.nullable != expected.nullable) {
differences.add('$path nullability differs');
}
if ((column.temporalPrecision ?? 6) !=
(expected.temporalPrecision ?? 6)) {
differences.add('$path temporal precision differs');
}
if (!matchesDecimalDigits(expected, column)) {
differences.add('$path decimal precision/scale differs');
}
if (db.dialect == SqlDialect.sqlite &&
!matchesCollation(expected, column)) {
differences.add('$path collation differs');
}
if (expected.codec.sqlType == 'integer' &&
(column.integerBits ?? 64) != (expected.integerBits ?? 64)) {
differences.add('$path integer width differs');
}
}
for (final extra in actual.keys) {
differences.add('${table.name}.$extra is unmanaged');
}
differences.addAll(
await verifyComputed(
db,
table,
inspected,
contextMatches: contextMatches,
),
);
}
return differences;
}