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:
@@ -439,7 +439,9 @@ func (r *Reader) queryForeignKeys(schemaName string) (map[string][]*models.Const
|
||||
fcl.relname AS referenced_table_name,
|
||||
fatt.attname AS referenced_column,
|
||||
` + actionCase("con.confupdtype") + ` AS update_rule,
|
||||
` + actionCase("con.confdeltype") + ` AS delete_rule
|
||||
` + actionCase("con.confdeltype") + ` AS delete_rule,
|
||||
con.condeferrable AS deferrable,
|
||||
con.condeferred AS initially_deferred
|
||||
FROM pg_catalog.pg_constraint con
|
||||
JOIN pg_catalog.pg_class cl ON cl.oid = con.conrelid
|
||||
JOIN pg_catalog.pg_namespace ns ON ns.oid = cl.relnamespace
|
||||
@@ -470,6 +472,8 @@ func (r *Reader) queryForeignKeys(schemaName string) (map[string][]*models.Const
|
||||
referencedColumns []string
|
||||
updateRule string
|
||||
deleteRule string
|
||||
deferrable bool
|
||||
initiallyDeferred bool
|
||||
}
|
||||
|
||||
fkMap := make(map[string]*fkData)
|
||||
@@ -479,8 +483,9 @@ func (r *Reader) queryForeignKeys(schemaName string) (map[string][]*models.Const
|
||||
var foreignSchema, foreignTable, foreignColumn string
|
||||
var referencedSchema, referencedTable, referencedColumn string
|
||||
var updateRule, deleteRule string
|
||||
var deferrable, initiallyDeferred bool
|
||||
|
||||
if err := rows.Scan(&schema, &tableName, &constraintName, &foreignSchema, &foreignTable, &foreignColumn, &referencedSchema, &referencedTable, &referencedColumn, &updateRule, &deleteRule); err != nil {
|
||||
if err := rows.Scan(&schema, &tableName, &constraintName, &foreignSchema, &foreignTable, &foreignColumn, &referencedSchema, &referencedTable, &referencedColumn, &updateRule, &deleteRule, &deferrable, &initiallyDeferred); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -497,6 +502,8 @@ func (r *Reader) queryForeignKeys(schemaName string) (map[string][]*models.Const
|
||||
referencedColumns: []string{},
|
||||
updateRule: updateRule,
|
||||
deleteRule: deleteRule,
|
||||
deferrable: deferrable,
|
||||
initiallyDeferred: initiallyDeferred,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -517,6 +524,9 @@ func (r *Reader) queryForeignKeys(schemaName string) (map[string][]*models.Const
|
||||
constraint.ReferencedColumns = fk.referencedColumns
|
||||
constraint.OnUpdate = fk.updateRule
|
||||
constraint.OnDelete = fk.deleteRule
|
||||
deferrable, initiallyDeferred := fk.deferrable, fk.initiallyDeferred
|
||||
constraint.Deferrable = &deferrable
|
||||
constraint.InitiallyDeferred = &initiallyDeferred
|
||||
|
||||
tableKey := fk.schema + "." + fk.tableName
|
||||
foreignKeys[tableKey] = append(foreignKeys[tableKey], constraint)
|
||||
|
||||
Reference in New Issue
Block a user