toSql method

String toSql(
  1. DatabaseDefinition targetDefinition
)

Implementation

String toSql(DatabaseDefinition targetDefinition) {
  final targetTable = targetDefinition.tables.firstWhere(
    (t) => t.name == name,
    orElse: () => throw StateError(
      'SQLite table migration for "$name" requires target table definition.',
    ),
  );

  final needsRebuild =
      modifyColumns.hasColumnMigrationThatRequiresRebuild ||
      deleteForeignKeys.isNotEmpty ||
      addForeignKeys.isNotEmpty ||
      addColumns.any((c) => c.addColumnNeedsRebuild(targetTable));
  if (needsRebuild) {
    return toSqliteRebuildSql(targetTable);
  }

  var out = '';

  // Drop indexes
  for (var deleteIndex in deleteIndexes) {
    out += 'DROP INDEX "$deleteIndex";\n';
  }

  // Drop columns
  for (var deleteColumn in deleteColumns) {
    out += 'ALTER TABLE "$name" DROP COLUMN "$deleteColumn";\n';
  }

  // Rename columns (must happen before add to avoid name collisions)
  for (var modifiedColumn in modifyColumns) {
    var fromName = modifiedColumn.columnName;
    var toName = modifiedColumn.newColumnName;
    if (toName != null && toName != fromName) {
      out += 'ALTER TABLE "$name" RENAME COLUMN "$fromName" TO "$toName";\n';
    }
  }

  // Add columns
  for (var addColumn in addColumns) {
    // Note: SQLite ADD COLUMN cannot support PRIMARY KEY or UNIQUE constraints.
    // These will be handled by the table rebuild.
    out += 'ALTER TABLE "$name" ADD COLUMN ${addColumn.toSqlFragment()};\n';
  }

  // Add indexes
  for (var addIndex in addIndexes) {
    out += addIndex.toSql(tableName: name);
  }

  out += '\n';
  return out;
}