fix: contain generated files and assets and harden SQL rendering
This commit is contained in:
@@ -61,6 +61,16 @@ func (w *MigrationWriter) GenerateScripts(model, current *models.Database) ([]Mi
|
||||
current = models.InitDatabase(model.Name)
|
||||
}
|
||||
|
||||
var err error
|
||||
model, err = prepareModel(model, w.options.LowercaseIdentifiers)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
current, err = prepareModel(current, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Check if audit is configured in metadata
|
||||
var auditConfig *AuditConfig
|
||||
if w.options.Metadata != nil {
|
||||
@@ -93,7 +103,7 @@ func (w *MigrationWriter) GenerateScripts(model, current *models.Database) ([]Mi
|
||||
if cs == nil {
|
||||
continue
|
||||
}
|
||||
if strings.EqualFold(cs.Name, modelSchema.Name) {
|
||||
if cs.Name == modelSchema.Name {
|
||||
currentSchema = cs
|
||||
break
|
||||
}
|
||||
@@ -166,7 +176,7 @@ func (w *MigrationWriter) WriteMigration(model, current *models.Database) error
|
||||
// Write header
|
||||
fmt.Fprintf(w.writer, "-- PostgreSQL Migration Script\n")
|
||||
fmt.Fprintf(w.writer, "-- Generated by RelSpec\n")
|
||||
fmt.Fprintf(w.writer, "-- Source: %s -> %s\n", current.Name, model.Name)
|
||||
fmt.Fprintf(w.writer, "-- Source: %s -> %s\n", commentText(current.Name), commentText(model.Name))
|
||||
if w.options.ContinueOnError {
|
||||
fmt.Fprintf(w.writer, "\\set ON_ERROR_STOP off\n")
|
||||
}
|
||||
@@ -175,7 +185,7 @@ func (w *MigrationWriter) WriteMigration(model, current *models.Database) error
|
||||
// Write scripts
|
||||
for _, script := range scripts {
|
||||
fmt.Fprintf(w.writer, "-- Priority: %d | Type: %s | Object: %s\n",
|
||||
script.Priority, script.ObjectType, script.ObjectName)
|
||||
script.Priority, commentText(script.ObjectType), commentText(script.ObjectName))
|
||||
fmt.Fprintf(w.writer, "%s\n\n", script.Body)
|
||||
}
|
||||
|
||||
@@ -256,12 +266,12 @@ func (w *MigrationWriter) generateDropScripts(model, current *models.Schema) ([]
|
||||
// Build map of model tables for quick lookup
|
||||
modelTables := make(map[string]*models.Table)
|
||||
for _, table := range model.Tables {
|
||||
modelTables[strings.ToLower(table.Name)] = table
|
||||
modelTables[table.Name] = table
|
||||
}
|
||||
|
||||
// Find constraints to drop
|
||||
for _, currentTable := range current.Tables {
|
||||
modelTable, existsInModel := modelTables[strings.ToLower(currentTable.Name)]
|
||||
modelTable, existsInModel := modelTables[currentTable.Name]
|
||||
|
||||
if !existsInModel {
|
||||
continue
|
||||
@@ -296,7 +306,7 @@ func (w *MigrationWriter) generateDropScripts(model, current *models.Schema) ([]
|
||||
if refSchema == "" {
|
||||
refSchema = current.Name
|
||||
}
|
||||
if strings.EqualFold(refTable, currentTable.Name) && strings.EqualFold(refSchema, current.Name) {
|
||||
if (refTable == currentTable.Name) && (refSchema == current.Name) {
|
||||
fkKey := fmt.Sprintf("%s.%s.%s", current.Name, otherTable.Name, fkName)
|
||||
if !droppedFKs[fkKey] {
|
||||
droppedFKs[fkKey] = true
|
||||
@@ -395,13 +405,13 @@ func (w *MigrationWriter) generateTableScripts(model, current *models.Schema) ([
|
||||
currentTables := make(map[string]*models.Table)
|
||||
if current != nil {
|
||||
for _, table := range current.Tables {
|
||||
currentTables[strings.ToLower(table.Name)] = table
|
||||
currentTables[table.Name] = table
|
||||
}
|
||||
}
|
||||
|
||||
// Process each model table
|
||||
for _, modelTable := range model.Tables {
|
||||
currentTable, exists := currentTables[strings.ToLower(modelTable.Name)]
|
||||
currentTable, exists := currentTables[modelTable.Name]
|
||||
|
||||
if !exists {
|
||||
// Table doesn't exist, create it
|
||||
@@ -439,12 +449,12 @@ func (w *MigrationWriter) generateAlterTableScripts(schema *models.Schema, model
|
||||
// Build map of current columns
|
||||
currentColumns := make(map[string]*models.Column)
|
||||
for name, col := range currentTable.Columns {
|
||||
currentColumns[strings.ToLower(name)] = col
|
||||
currentColumns[name] = col
|
||||
}
|
||||
|
||||
// Check each model column
|
||||
for _, modelCol := range sortColumns(modelTable.Columns) {
|
||||
currentCol, exists := currentColumns[strings.ToLower(modelCol.Name)]
|
||||
currentCol, exists := currentColumns[modelCol.Name]
|
||||
|
||||
if !exists {
|
||||
// Column doesn't exist, add it
|
||||
@@ -574,13 +584,13 @@ func (w *MigrationWriter) generateIndexScripts(model, current *models.Schema) ([
|
||||
currentTables := make(map[string]*models.Table)
|
||||
if current != nil {
|
||||
for _, table := range current.Tables {
|
||||
currentTables[strings.ToLower(table.Name)] = table
|
||||
currentTables[table.Name] = table
|
||||
}
|
||||
}
|
||||
|
||||
// Process each model table
|
||||
for _, modelTable := range model.Tables {
|
||||
currentTable := currentTables[strings.ToLower(modelTable.Name)]
|
||||
currentTable := currentTables[modelTable.Name]
|
||||
|
||||
// Process primary keys first - check explicit constraints
|
||||
foundExplicitPK := false
|
||||
@@ -603,7 +613,7 @@ func (w *MigrationWriter) generateIndexScripts(model, current *models.Schema) ([
|
||||
SchemaName: model.Name,
|
||||
TableName: modelTable.Name,
|
||||
ConstraintName: constraintName,
|
||||
Columns: strings.Join(constraint.Columns, ", "),
|
||||
Columns: quotedIdentifiers(constraint.Columns),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -627,12 +637,12 @@ func (w *MigrationWriter) generateIndexScripts(model, current *models.Schema) ([
|
||||
pkColumns := []string{}
|
||||
for _, col := range modelTable.Columns {
|
||||
if col.IsPrimaryKey {
|
||||
pkColumns = append(pkColumns, col.SQLName())
|
||||
pkColumns = append(pkColumns, col.Name)
|
||||
}
|
||||
}
|
||||
if len(pkColumns) > 0 {
|
||||
sort.Strings(pkColumns)
|
||||
constraintName := fmt.Sprintf("pk_%s_%s", model.SQLName(), modelTable.SQLName())
|
||||
constraintName := fmt.Sprintf("pk_%s_%s", model.Name, modelTable.Name)
|
||||
shouldCreate := true
|
||||
|
||||
if currentTable != nil {
|
||||
@@ -650,7 +660,7 @@ func (w *MigrationWriter) generateIndexScripts(model, current *models.Schema) ([
|
||||
SchemaName: model.Name,
|
||||
TableName: modelTable.Name,
|
||||
ConstraintName: constraintName,
|
||||
Columns: strings.Join(pkColumns, ", "),
|
||||
Columns: quotedIdentifiers(pkColumns),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -750,7 +760,7 @@ func buildIndexColumnExpressionsFiltered(table *models.Table, index *models.Inde
|
||||
continue
|
||||
}
|
||||
|
||||
colExpr := col.SQLName()
|
||||
colExpr := quoteIdent(col.Name)
|
||||
if opClass := indexOperatorClassForColumn(col, indexType, index.Comment); opClass != "" {
|
||||
colExpr = fmt.Sprintf("%s %s", colExpr, opClass)
|
||||
}
|
||||
@@ -767,12 +777,12 @@ func (w *MigrationWriter) generateUniqueConstraintScripts(model, current *models
|
||||
currentTables := make(map[string]*models.Table)
|
||||
if current != nil {
|
||||
for _, table := range current.Tables {
|
||||
currentTables[strings.ToLower(table.Name)] = table
|
||||
currentTables[table.Name] = table
|
||||
}
|
||||
}
|
||||
|
||||
for _, modelTable := range model.Tables {
|
||||
currentTable := currentTables[strings.ToLower(modelTable.Name)]
|
||||
currentTable := currentTables[modelTable.Name]
|
||||
|
||||
for _, constraint := range sortConstraints(modelTable.Constraints) {
|
||||
if constraint.Type != models.UniqueConstraint {
|
||||
@@ -788,7 +798,7 @@ func (w *MigrationWriter) generateUniqueConstraintScripts(model, current *models
|
||||
columnExprs := make([]string, 0, len(constraint.Columns))
|
||||
for _, colName := range constraint.Columns {
|
||||
if col, ok := modelTable.Columns[colName]; ok {
|
||||
columnExprs = append(columnExprs, col.SQLName())
|
||||
columnExprs = append(columnExprs, quoteIdent(col.Name))
|
||||
}
|
||||
}
|
||||
if len(columnExprs) == 0 {
|
||||
@@ -838,7 +848,7 @@ func adoptableUniqueIndex(table *models.Table, constraint *models.Constraint) st
|
||||
return ""
|
||||
}
|
||||
for i, col := range index.Columns {
|
||||
if !strings.EqualFold(col, constraint.Columns[i]) {
|
||||
if !(col == constraint.Columns[i]) {
|
||||
return ""
|
||||
}
|
||||
}
|
||||
@@ -855,13 +865,13 @@ func (w *MigrationWriter) generateForeignKeyScripts(model, current *models.Schem
|
||||
currentTables := make(map[string]*models.Table)
|
||||
if current != nil {
|
||||
for _, table := range current.Tables {
|
||||
currentTables[strings.ToLower(table.Name)] = table
|
||||
currentTables[table.Name] = table
|
||||
}
|
||||
}
|
||||
|
||||
// Process each model table
|
||||
for _, modelTable := range model.Tables {
|
||||
currentTable := currentTables[strings.ToLower(modelTable.Name)]
|
||||
currentTable := currentTables[modelTable.Name]
|
||||
|
||||
// Process each constraint
|
||||
for _, constraint := range sortConstraints(modelTable.Constraints) {
|
||||
@@ -904,10 +914,10 @@ func (w *MigrationWriter) generateForeignKeyScripts(model, current *models.Schem
|
||||
SchemaName: model.Name,
|
||||
TableName: modelTable.Name,
|
||||
ConstraintName: constraintName,
|
||||
SourceColumns: strings.Join(constraint.Columns, ", "),
|
||||
SourceColumns: quotedIdentifiers(constraint.Columns),
|
||||
TargetSchema: constraint.ReferencedSchema,
|
||||
TargetTable: constraint.ReferencedTable,
|
||||
TargetColumns: strings.Join(constraint.ReferencedColumns, ", "),
|
||||
TargetColumns: quotedIdentifiers(constraint.ReferencedColumns),
|
||||
OnDelete: onDelete,
|
||||
OnUpdate: onUpdate,
|
||||
Deferral: deferral,
|
||||
@@ -939,20 +949,20 @@ func (w *MigrationWriter) generateCommentScripts(model, current *models.Schema)
|
||||
currentTables := make(map[string]*models.Table)
|
||||
if current != nil {
|
||||
for _, table := range current.Tables {
|
||||
currentTables[strings.ToLower(table.Name)] = table
|
||||
currentTables[table.Name] = table
|
||||
}
|
||||
}
|
||||
|
||||
// Process each model table
|
||||
for _, modelTable := range model.Tables {
|
||||
currentTable := currentTables[strings.ToLower(modelTable.Name)]
|
||||
currentTable := currentTables[modelTable.Name]
|
||||
|
||||
// Table comment (skipped when the live table already carries the same comment)
|
||||
if modelTable.Description != "" && (currentTable == nil || strings.TrimSpace(currentTable.Description) != strings.TrimSpace(modelTable.Description)) {
|
||||
sql, err := w.executor.ExecuteCommentTable(CommentTableData{
|
||||
SchemaName: model.Name,
|
||||
TableName: modelTable.Name,
|
||||
Comment: escapeQuote(modelTable.Description),
|
||||
Comment: modelTable.Description,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -976,7 +986,7 @@ func (w *MigrationWriter) generateCommentScripts(model, current *models.Schema)
|
||||
SchemaName: model.Name,
|
||||
TableName: modelTable.Name,
|
||||
ColumnName: col.Name,
|
||||
Comment: escapeQuote(col.Description),
|
||||
Comment: col.Description,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -1229,21 +1239,21 @@ func constraintsEqual(c1, c2 *models.Constraint) bool {
|
||||
return false
|
||||
}
|
||||
for i, col := range c1.Columns {
|
||||
if !strings.EqualFold(col, c2.Columns[i]) {
|
||||
if !(col == c2.Columns[i]) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// For foreign keys, also compare referenced table and columns
|
||||
if c1.Type == models.ForeignKeyConstraint {
|
||||
if !strings.EqualFold(c1.ReferencedTable, c2.ReferencedTable) {
|
||||
if !(c1.ReferencedTable == c2.ReferencedTable) {
|
||||
return false
|
||||
}
|
||||
if len(c1.ReferencedColumns) != len(c2.ReferencedColumns) {
|
||||
return false
|
||||
}
|
||||
for i, col := range c1.ReferencedColumns {
|
||||
if !strings.EqualFold(col, c2.ReferencedColumns[i]) {
|
||||
if !(col == c2.ReferencedColumns[i]) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
@@ -1273,7 +1283,7 @@ func indexesEqual(idx1, idx2 *models.Index) bool {
|
||||
return false
|
||||
}
|
||||
for i, col := range idx1.Columns {
|
||||
if !strings.EqualFold(col, idx2.Columns[i]) {
|
||||
if !(col == idx2.Columns[i]) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
@@ -1327,7 +1337,7 @@ func currentColumnHasDescription(currentTable *models.Table, col *models.Column)
|
||||
return false
|
||||
}
|
||||
for _, cc := range currentTable.Columns {
|
||||
if strings.EqualFold(cc.Name, col.Name) {
|
||||
if cc.Name == col.Name {
|
||||
return strings.TrimSpace(cc.Description) == strings.TrimSpace(col.Description)
|
||||
}
|
||||
}
|
||||
@@ -1355,7 +1365,7 @@ func primaryKeyColumnsMatch(modelTable *models.Table, current *models.Constraint
|
||||
return false
|
||||
}
|
||||
for i, col := range modelCols {
|
||||
if !strings.EqualFold(col, current.Columns[i]) {
|
||||
if !(col == current.Columns[i]) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user