generateAddColumnAlterTableSQL method

AlterTableSQL generateAddColumnAlterTableSQL(
  1. String table,
  2. String fieldName,
  3. TypeInfo fieldType, {
  4. List<EntityField>? entityFieldAnnotations,
})

Implementation

AlterTableSQL generateAddColumnAlterTableSQL(
  String table,
  String fieldName,
  TypeInfo fieldType, {
  List<EntityField>? entityFieldAnnotations,
}) {
  var q = dialect.elementQuote;
  var columnName = normalizeColumnName(fieldName);
  var fieldSQLType = typeToSQLType(
    fieldType,
    columnName,
    entityFieldAnnotations: entityFieldAnnotations,
  );

  var comment = '${fieldType.toString(withT: false)} $fieldName';

  MapEntry<String, MapEntry<String, String>>? entityType;
  String? refTable;
  String? refColumn;

  if (fieldSQLType == null) {
    entityType = entityTypeToSQLType(
      fieldType,
      columnName,
      entityFieldAnnotations: entityFieldAnnotations,
    );
    if (entityType != null) {
      fieldSQLType = entityType.value.value;

      refTable = entityType.key;
      refColumn = entityType.value.key;

      comment += ' @ $refTable.$refColumn';
    }
  }

  if (fieldSQLType == null) {
    var enumType = enumTypeToSQLType(
      fieldType.type,
      columnName,
      entityFieldAnnotations: entityFieldAnnotations,
    );
    if (enumType != null) {
      var type = enumType.key;
      var values = enumType.value;

      fieldSQLType = _buildEnumSQLType(
        type,
        fieldSQLType,
        values,
        q,
        columnName,
      );

      comment += ' enum(${values.join(', ')})';
    }
  }

  var columnEntry = SQLEntry(
    'ADD',
    ' ADD COLUMN $q$columnName$q $fieldSQLType',
    comment: comment,
  );

  List<CreateIndexSQL>? indexes;
  List<AlterTableSQL>? constraints;

  if (entityFieldAnnotations != null && entityFieldAnnotations.isNotEmpty) {
    if (entityFieldAnnotations.hasUnique) {
      var constrainUniqueName = '${table}__${columnName}__unique';

      var uniqueEntry = SQLEntry(
        'CONSTRAINT',
        ' ADD CONSTRAINT $q$constrainUniqueName$q UNIQUE ($q$columnName$q)',
        columns: [
          SQLColumn(
            table,
            columnName,
            referenceTable: refTable!,
            referenceColumn: refColumn!,
          ),
        ],
      );

      constraints = [
        AlterTableSQL(dialect, table, [uniqueEntry]),
      ];
    } else if (entityFieldAnnotations.hasIndexed) {
      var indexName = '${table}__${columnName}__idx';
      indexes = [CreateIndexSQL(dialect, table, columnName, indexName)];
    }
  }

  if (entityType != null) {
    var fieldName = columnName;
    var ref = entityType;

    var refTableName = ref.key;
    var refField = ref.value.key.toLowerCase();

    var constrainName = '${table}__${columnName}__fkey';

    constraints ??= [];

    var constraintEntry = SQLEntry(
      'CONSTRAINT',
      ' ADD CONSTRAINT $q$constrainName$q FOREIGN KEY ($q$columnName$q) REFERENCES $q$refTableName$q($q$refField$q)',
      comment: '$fieldName @ $refTableName.$refField',
      columns: [
        SQLColumn(
          table,
          columnName,
          referenceTable: refTableName,
          referenceColumn: refField,
        ),
      ],
    );

    constraints.add(AlterTableSQL(dialect, table, [constraintEntry]));
  }

  var alterTableSQL = AlterTableSQL(
    dialect,
    table,
    [columnEntry],
    indexes: indexes,
    constraints: constraints,
  );

  return alterTableSQL;
}