fix(codegen): sort map iteration to make generated output deterministic

Table.Columns/Constraints/Indexes/Relationships are Go maps, and every
writer, reader, diff, inspector, and merge code path that iterated them
directly was subject to Go's randomized map order, so identical input
could produce different output (or a different in-report violation/diff
order) on every run. Most visibly this showed up as bun/gorm `unique:`
struct tags changing order across consecutive `make models` runs with no
source change.

Fixed by sorting map iteration (by Sequence then Name, or alphabetically
for string-keyed maps) everywhere the order affects generated output or
first-match tie-break logic, across the bun, gorm, sqlite, dbml, drawdb,
pgsql, prisma, graphql, typeorm, drizzle, and dctx writers; the dctx,
prisma, and typeorm readers; the shared models.GetPrimaryKey/
GetForeignKeys helpers; pkg/diff, pkg/inspector, and pkg/merge; and the
TUI column/relationship pickers in pkg/ui.
This commit is contained in:
2026-08-10 20:54:40 +02:00
parent b95b74f0a3
commit 3b88c386a1
32 changed files with 733 additions and 100 deletions
+5 -5
View File
@@ -143,7 +143,7 @@ func (w *Writer) writeTable(schema string, table *models.Table) error {
// writeIndexes writes indexes for a table
func (w *Writer) writeIndexes(schema string, table *models.Table) error {
for _, index := range table.Indexes {
for _, index := range sortIndexes(table.Indexes) {
// Skip primary key indexes
if strings.HasSuffix(index.Name, "_pkey") {
continue
@@ -174,7 +174,7 @@ func (w *Writer) writeIndexes(schema string, table *models.Table) error {
// writeUniqueConstraints writes unique constraints as unique indexes
func (w *Writer) writeUniqueConstraints(schema string, table *models.Table) error {
for _, constraint := range table.Constraints {
for _, constraint := range sortConstraints(table.Constraints) {
if constraint.Type != models.UniqueConstraint {
continue
}
@@ -195,7 +195,7 @@ func (w *Writer) writeUniqueConstraints(schema string, table *models.Table) erro
}
// Also handle unique indexes from the Indexes map
for _, index := range table.Indexes {
for _, index := range sortIndexes(table.Indexes) {
if !index.Unique {
continue
}
@@ -232,7 +232,7 @@ func (w *Writer) writeUniqueConstraints(schema string, table *models.Table) erro
// writeCheckConstraints writes check constraints as comments
func (w *Writer) writeCheckConstraints(schema string, table *models.Table) error {
for _, constraint := range table.Constraints {
for _, constraint := range sortConstraints(table.Constraints) {
if constraint.Type != models.CheckConstraint {
continue
}
@@ -257,7 +257,7 @@ func (w *Writer) writeCheckConstraints(schema string, table *models.Table) error
// writeForeignKeys writes foreign keys as comments
func (w *Writer) writeForeignKeys(schema string, table *models.Table) error {
for _, constraint := range table.Constraints {
for _, constraint := range sortConstraints(table.Constraints) {
if constraint.Type != models.ForeignKeyConstraint {
continue
}