feat(writer): 🎉 Improve primary key handling by checking for explicit constraints and columns
Some checks failed
CI / Test (1.25) (push) Successful in -26m17s
CI / Test (1.24) (push) Successful in -25m44s
CI / Lint (push) Successful in -26m43s
CI / Build (push) Failing after -27m1s
Release / Build and Release (push) Successful in -26m39s
Integration Tests / Integration Tests (push) Successful in -26m25s
Some checks failed
CI / Test (1.25) (push) Successful in -26m17s
CI / Test (1.24) (push) Successful in -25m44s
CI / Lint (push) Successful in -26m43s
CI / Build (push) Failing after -27m1s
Release / Build and Release (push) Successful in -26m39s
Integration Tests / Integration Tests (push) Successful in -26m25s
This commit is contained in:
@@ -427,9 +427,11 @@ func (w *MigrationWriter) generateIndexScripts(model *models.Schema, current *mo
|
|||||||
for _, modelTable := range model.Tables {
|
for _, modelTable := range model.Tables {
|
||||||
currentTable := currentTables[strings.ToLower(modelTable.Name)]
|
currentTable := currentTables[strings.ToLower(modelTable.Name)]
|
||||||
|
|
||||||
// Process primary keys first
|
// Process primary keys first - check explicit constraints
|
||||||
|
foundExplicitPK := false
|
||||||
for constraintName, constraint := range modelTable.Constraints {
|
for constraintName, constraint := range modelTable.Constraints {
|
||||||
if constraint.Type == models.PrimaryKeyConstraint {
|
if constraint.Type == models.PrimaryKeyConstraint {
|
||||||
|
foundExplicitPK = true
|
||||||
shouldCreate := true
|
shouldCreate := true
|
||||||
|
|
||||||
if currentTable != nil {
|
if currentTable != nil {
|
||||||
@@ -464,6 +466,53 @@ func (w *MigrationWriter) generateIndexScripts(model *models.Schema, current *mo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If no explicit PK constraint, check for columns with IsPrimaryKey = true
|
||||||
|
if !foundExplicitPK {
|
||||||
|
pkColumns := []string{}
|
||||||
|
for _, col := range modelTable.Columns {
|
||||||
|
if col.IsPrimaryKey {
|
||||||
|
pkColumns = append(pkColumns, col.SQLName())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(pkColumns) > 0 {
|
||||||
|
sort.Strings(pkColumns)
|
||||||
|
constraintName := fmt.Sprintf("pk_%s_%s", strings.ToLower(model.Name), strings.ToLower(modelTable.Name))
|
||||||
|
shouldCreate := true
|
||||||
|
|
||||||
|
if currentTable != nil {
|
||||||
|
// Check if a PK constraint already exists (by any name)
|
||||||
|
for _, constraint := range currentTable.Constraints {
|
||||||
|
if constraint.Type == models.PrimaryKeyConstraint {
|
||||||
|
shouldCreate = false
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if shouldCreate {
|
||||||
|
sql, err := w.executor.ExecuteCreatePrimaryKey(CreatePrimaryKeyData{
|
||||||
|
SchemaName: model.Name,
|
||||||
|
TableName: modelTable.Name,
|
||||||
|
ConstraintName: constraintName,
|
||||||
|
Columns: strings.Join(pkColumns, ", "),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
script := MigrationScript{
|
||||||
|
ObjectName: fmt.Sprintf("%s.%s.%s", model.Name, modelTable.Name, constraintName),
|
||||||
|
ObjectType: "create primary key",
|
||||||
|
Schema: model.Name,
|
||||||
|
Priority: 160,
|
||||||
|
Sequence: len(scripts),
|
||||||
|
Body: sql,
|
||||||
|
}
|
||||||
|
scripts = append(scripts, script)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Process indexes
|
// Process indexes
|
||||||
for indexName, modelIndex := range modelTable.Indexes {
|
for indexName, modelIndex := range modelTable.Indexes {
|
||||||
// Skip primary key indexes
|
// Skip primary key indexes
|
||||||
|
|||||||
@@ -127,13 +127,35 @@ func (w *Writer) GenerateSchemaStatements(schema *models.Schema) ([]string, erro
|
|||||||
|
|
||||||
// Phase 4: Primary keys
|
// Phase 4: Primary keys
|
||||||
for _, table := range schema.Tables {
|
for _, table := range schema.Tables {
|
||||||
|
// First check for explicit PrimaryKeyConstraint
|
||||||
|
var pkConstraint *models.Constraint
|
||||||
for _, constraint := range table.Constraints {
|
for _, constraint := range table.Constraints {
|
||||||
if constraint.Type != models.PrimaryKeyConstraint {
|
if constraint.Type == models.PrimaryKeyConstraint {
|
||||||
continue
|
pkConstraint = constraint
|
||||||
|
break
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if pkConstraint != nil {
|
||||||
stmt := fmt.Sprintf("ALTER TABLE %s.%s ADD CONSTRAINT %s PRIMARY KEY (%s)",
|
stmt := fmt.Sprintf("ALTER TABLE %s.%s ADD CONSTRAINT %s PRIMARY KEY (%s)",
|
||||||
schema.SQLName(), table.SQLName(), constraint.Name, strings.Join(constraint.Columns, ", "))
|
schema.SQLName(), table.SQLName(), pkConstraint.Name, strings.Join(pkConstraint.Columns, ", "))
|
||||||
statements = append(statements, stmt)
|
statements = append(statements, stmt)
|
||||||
|
} else {
|
||||||
|
// No explicit constraint, check for columns with IsPrimaryKey = true
|
||||||
|
pkColumns := []string{}
|
||||||
|
for _, col := range table.Columns {
|
||||||
|
if col.IsPrimaryKey {
|
||||||
|
pkColumns = append(pkColumns, col.SQLName())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(pkColumns) > 0 {
|
||||||
|
// Sort for consistent output
|
||||||
|
sort.Strings(pkColumns)
|
||||||
|
pkName := fmt.Sprintf("pk_%s_%s", schema.SQLName(), table.SQLName())
|
||||||
|
stmt := fmt.Sprintf("ALTER TABLE %s.%s ADD CONSTRAINT %s PRIMARY KEY (%s)",
|
||||||
|
schema.SQLName(), table.SQLName(), pkName, strings.Join(pkColumns, ", "))
|
||||||
|
statements = append(statements, stmt)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -458,20 +480,27 @@ func (w *Writer) writePrimaryKeys(schema *models.Schema) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if pkConstraint == nil {
|
var columnNames []string
|
||||||
// No explicit PK constraint, skip
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
pkName := fmt.Sprintf("pk_%s_%s", schema.SQLName(), table.SQLName())
|
pkName := fmt.Sprintf("pk_%s_%s", schema.SQLName(), table.SQLName())
|
||||||
|
|
||||||
// Build column list
|
if pkConstraint != nil {
|
||||||
columnNames := make([]string, 0, len(pkConstraint.Columns))
|
// Build column list from explicit constraint
|
||||||
|
columnNames = make([]string, 0, len(pkConstraint.Columns))
|
||||||
for _, colName := range pkConstraint.Columns {
|
for _, colName := range pkConstraint.Columns {
|
||||||
if col, ok := table.Columns[colName]; ok {
|
if col, ok := table.Columns[colName]; ok {
|
||||||
columnNames = append(columnNames, col.SQLName())
|
columnNames = append(columnNames, col.SQLName())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// No explicit PK constraint, check for columns with IsPrimaryKey = true
|
||||||
|
for _, col := range table.Columns {
|
||||||
|
if col.IsPrimaryKey {
|
||||||
|
columnNames = append(columnNames, col.SQLName())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Sort for consistent output
|
||||||
|
sort.Strings(columnNames)
|
||||||
|
}
|
||||||
|
|
||||||
if len(columnNames) == 0 {
|
if len(columnNames) == 0 {
|
||||||
continue
|
continue
|
||||||
|
|||||||
Reference in New Issue
Block a user