alterColumn method
void
alterColumn(
- String tableName,
- String columnName,
- void modify(
- SchemaColumn targetColumn
- String? unencodedInitialValue,
Validates and alters a column in a table in schema.
Alterations are made by setting properties of the column passed to modify
. If the column's nullability
changes from nullable to not nullable, all previously null values for that column
are set to the value of unencodedInitialValue
.
Example:
database.alterColumn("table", "column", (c) {
c.isIndexed = true;
c.isNullable = false;
}), unencodedInitialValue: "0");
Implementation
void alterColumn(
String tableName,
String columnName,
void Function(SchemaColumn targetColumn) modify, {
String? unencodedInitialValue,
}) {
final table = schema.tableForName(tableName);
if (table == null) {
throw SchemaException("Table $tableName does not exist.");
}
final existingColumn = table[columnName];
if (existingColumn == null) {
throw SchemaException("Column $columnName does not exist.");
}
final newColumn = SchemaColumn.from(existingColumn);
modify(newColumn);
if (existingColumn.type != newColumn.type) {
throw SchemaException(
"May not change column type for '${existingColumn.name}' in '$tableName' (${existingColumn.typeString} -> ${newColumn.typeString})",
);
}
if (existingColumn.autoincrement != newColumn.autoincrement) {
throw SchemaException(
"May not change column autoincrementing behavior for '${existingColumn.name}' in '$tableName'",
);
}
if (existingColumn.isPrimaryKey != newColumn.isPrimaryKey) {
throw SchemaException(
"May not change column primary key status for '${existingColumn.name}' in '$tableName'",
);
}
if (existingColumn.relatedTableName != newColumn.relatedTableName) {
throw SchemaException(
"May not change reference table for foreign key column '${existingColumn.name}' in '$tableName' (${existingColumn.relatedTableName} -> ${newColumn.relatedTableName})",
);
}
if (existingColumn.relatedColumnName != newColumn.relatedColumnName) {
throw SchemaException(
"May not change reference column for foreign key column '${existingColumn.name}' in '$tableName' (${existingColumn.relatedColumnName} -> ${newColumn.relatedColumnName})",
);
}
if (existingColumn.name != newColumn.name) {
renameColumn(tableName, existingColumn.name, newColumn.name);
}
table.replaceColumn(existingColumn, newColumn);
final innerCommands = <String>[];
if (existingColumn.isIndexed != newColumn.isIndexed) {
if (store != null) {
if (newColumn.isIndexed!) {
commands.addAll(store!.addIndexToColumn(table, newColumn));
} else {
commands.addAll(store!.deleteIndexFromColumn(table, newColumn));
}
} else {
innerCommands.add("c.isIndexed = ${newColumn.isIndexed}");
}
}
if (existingColumn.isUnique != newColumn.isUnique) {
if (store != null) {
commands.addAll(store!.alterColumnUniqueness(table, newColumn));
} else {
innerCommands.add('c.isUnique = ${newColumn.isUnique}');
}
}
if (existingColumn.defaultValue != newColumn.defaultValue) {
if (store != null) {
commands.addAll(store!.alterColumnDefaultValue(table, newColumn));
} else {
final value = newColumn.defaultValue == null
? 'null'
: '"${newColumn.defaultValue}"';
innerCommands.add('c.defaultValue = $value');
}
}
if (existingColumn.isNullable != newColumn.isNullable) {
if (store != null) {
commands.addAll(
store!
.alterColumnNullability(table, newColumn, unencodedInitialValue),
);
} else {
innerCommands.add('c.isNullable = ${newColumn.isNullable}');
}
}
if (existingColumn.deleteRule != newColumn.deleteRule) {
if (store != null) {
commands.addAll(store!.alterColumnDeleteRule(table, newColumn));
} else {
innerCommands.add('c.deleteRule = ${newColumn.deleteRule}');
}
}
if (store == null && innerCommands.isNotEmpty) {
commands.add(
'database.alterColumn("$tableName", "$columnName", (c) {${innerCommands.join(";")};});',
);
}
}