feat(pgsql): unique constraints on apply, matching unique index names, FK deferral
- migration writer now emits unique constraints (direct apply and live diff previously dropped them); idempotent via the existing DO block - unique constraint adopts a same-named model unique index with ADD CONSTRAINT ... UNIQUE USING INDEX instead of building a second index - dbml reader names unnamed unique indexes ukey_<table>_<cols> to match the unique constraint naming - foreign key deferral: Constraint.Deferrable/InitiallyDeferred are *bool (nil = unspecified, never diffed); writers emit DEFERRABLE, DEFERRABLE INITIALLY DEFERRED and NOT DEFERRABLE; live reader reads condeferrable and condeferred; dbml reader/writer support deferrable and initially deferred - tests and README/naming docs updated
This commit is contained in:
@@ -345,6 +345,7 @@ func (w *Writer) GenerateSchemaStatements(schema *models.Schema) ([]string, erro
|
||||
TableName: table.Name,
|
||||
ConstraintName: constraint.Name,
|
||||
Columns: strings.Join(constraint.Columns, ", "),
|
||||
UsingIndex: adoptableUniqueIndex(table, constraint),
|
||||
}
|
||||
|
||||
stmt, err := w.executor.ExecuteCreateUniqueConstraint(data)
|
||||
@@ -411,7 +412,7 @@ func (w *Writer) GenerateSchemaStatements(schema *models.Schema) ([]string, erro
|
||||
TargetColumns: strings.Join(constraint.ReferencedColumns, ", "),
|
||||
OnDelete: onDelete,
|
||||
OnUpdate: onUpdate,
|
||||
Deferrable: false,
|
||||
Deferral: constraint.DeferralClause(),
|
||||
}
|
||||
|
||||
stmt, err := w.executor.ExecuteCreateForeignKeyWithCheck(data)
|
||||
@@ -1150,7 +1151,7 @@ func (w *Writer) writeIndexes(schema *models.Schema) error {
|
||||
if indexName == "" {
|
||||
indexType := "idx"
|
||||
if index.Unique {
|
||||
indexType = "uidx"
|
||||
indexType = "ukey"
|
||||
}
|
||||
columnSuffix := strings.Join(index.Columns, "_")
|
||||
indexName = fmt.Sprintf("%s_%s_%s", indexType, table.SQLName(), strings.ToLower(columnSuffix))
|
||||
@@ -1236,6 +1237,7 @@ func (w *Writer) writeUniqueConstraints(schema *models.Schema) error {
|
||||
TableName: table.Name,
|
||||
ConstraintName: constraint.Name,
|
||||
Columns: strings.Join(columnExprs, ", "),
|
||||
UsingIndex: adoptableUniqueIndex(table, constraint),
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to generate unique constraint: %w", err)
|
||||
@@ -1380,7 +1382,7 @@ func (w *Writer) writeForeignKeys(schema *models.Schema) error {
|
||||
TargetColumns: strings.Join(targetColumns, ", "),
|
||||
OnDelete: onDelete,
|
||||
OnUpdate: onUpdate,
|
||||
Deferrable: true,
|
||||
Deferral: "DEFERRABLE",
|
||||
}
|
||||
sql, err := w.executor.ExecuteCreateForeignKeyWithCheck(data)
|
||||
if err != nil {
|
||||
@@ -1459,7 +1461,7 @@ func (w *Writer) writeForeignKeys(schema *models.Schema) error {
|
||||
TargetColumns: strings.Join(targetColumns, ", "),
|
||||
OnDelete: onDelete,
|
||||
OnUpdate: onUpdate,
|
||||
Deferrable: false,
|
||||
Deferral: constraint.DeferralClause(),
|
||||
}
|
||||
sql, err := w.executor.ExecuteCreateForeignKeyWithCheck(data)
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user