renderAlterAddColumns method

  1. @override
List<String> renderAlterAddColumns(
  1. String table,
  2. TableBlueprint changes, {
  3. String afterColumn = '',
  4. String beforeColumn = '',
})
override

Implementation

@override
List<String> renderAlterAddColumns(
  String table,
  TableBlueprint changes, {
  String afterColumn = '',
  String beforeColumn = '',
}) {
  if (beforeColumn.isNotEmpty) {
    throw UnsupportedError(
      'MySQL has no BEFORE clause for ADD COLUMN. Use afterColumn with the '
      'preceding column instead.',
    );
  }

  final clauses = <String>[];

  for (final col in changes.columns) {
    var clause = 'ADD COLUMN ${_renderColumn(col)}';
    if (afterColumn.isNotEmpty) clause += ' AFTER `$afterColumn`';
    clauses.add(clause);
  }

  if (changes.primaryKey != null) {
    clauses.add('ADD PRIMARY KEY (`${changes.primaryKey}`)');
  }

  for (final uc in changes.uniqueConstraints) {
    final cols = uc.columns.map((c) => '`$c`').join(', ');
    clauses.add('ADD CONSTRAINT `${uc.name}` UNIQUE ($cols)');
  }

  for (final idx in changes.indexes) {
    final cols = idx.columns.map((c) => '`$c`').join(', ');
    if (idx.type == ColumnIndex.indexKey) {
      clauses.add('ADD INDEX `${idx.name}` ($cols)');
    } else {
      clauses.add(
        'ADD ${idx.type.name.toUpperCase()} INDEX `${idx.name}` ($cols)',
      );
    }
  }

  for (final fk in changes.foreignKeys) {
    final constraint = fk.constrained
        ? 'CONSTRAINT `FK_${table}_${fk.referencesTable}` '
        : '';
    clauses.add(
      'ADD ${constraint}FOREIGN KEY (`${fk.columnName}`) '
      'REFERENCES `${fk.referencesTable}` (`${fk.referencesColumn}`) '
      'ON UPDATE ${fk.onUpdate} ON DELETE ${fk.onDelete}',
    );
  }

  if (clauses.isEmpty) return [];

  final buf = StringBuffer('ALTER TABLE `$table`\n');
  for (var i = 0; i < clauses.length; i++) {
    final sep = i == clauses.length - 1 ? '' : ',';
    buf.writeln('  ${clauses[i]}$sep');
  }
  return [buf.toString().trimRight()];
}