forked from pgplex/pgschema
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcollector.go
More file actions
81 lines (73 loc) · 2.65 KB
/
Copy pathcollector.go
File metadata and controls
81 lines (73 loc) · 2.65 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
package diff
import "github.com/pgplex/pgschema/ir"
// diffContext provides context about the SQL statement being generated
type diffContext struct {
Type DiffType // e.g., DiffTypeTable, DiffTypeView, DiffTypeFunction
Operation DiffOperation // e.g., DiffOperationCreate, DiffOperationAlter, DiffOperationDrop
Path string // e.g., "schema.table" or "schema.table.column"
Source DiffSource // The ddlDiff element that generated this SQL
CanRunInTransaction bool // Whether this SQL can run in a transaction
}
// diffCollector collects SQL statements with their context information
type diffCollector struct {
diffs []Diff
pendingForeignKeys []*deferredConstraint
}
// newDiffCollector creates a new diffCollector
func newDiffCollector() *diffCollector {
return &diffCollector{
diffs: []Diff{},
pendingForeignKeys: nil,
}
}
// queueDeferredForeignKey schedules an ALTER TABLE ... ADD FOREIGN KEY for a later flush
// (after CREATE and MODIFY phases) so referenced tables and new PK/UNIQUE constraints exist.
func (c *diffCollector) queueDeferredForeignKey(table *ir.Table, constraint *ir.Constraint) {
if c == nil || table == nil || constraint == nil || constraint.Name == "" {
return
}
c.pendingForeignKeys = append(c.pendingForeignKeys, &deferredConstraint{
table: table,
constraint: constraint,
})
}
// flushDeferredForeignKeys emits pending foreign keys in dependency order.
func (c *diffCollector) flushDeferredForeignKeys(targetSchema string) {
if c == nil || len(c.pendingForeignKeys) == 0 {
return
}
sorted := sortDeferredForeignKeys(c.pendingForeignKeys)
for _, item := range sorted {
emitDeferredForeignKeyConstraint(item, targetSchema, c)
}
c.pendingForeignKeys = nil
}
// collect collects a single SQL statement with its context information
func (c *diffCollector) collect(context *diffContext, stmt string) {
if context != nil {
step := Diff{
Statements: []SQLStatement{{
SQL: stmt,
CanRunInTransaction: context.CanRunInTransaction,
}},
Type: context.Type,
Operation: context.Operation,
Path: context.Path,
Source: context.Source,
}
c.diffs = append(c.diffs, step)
}
}
// collectStatements collects multiple SQL statements as a single Diff
func (c *diffCollector) collectStatements(context *diffContext, statements []SQLStatement) {
if context != nil && len(statements) > 0 {
step := Diff{
Statements: statements,
Type: context.Type,
Operation: context.Operation,
Path: context.Path,
Source: context.Source,
}
c.diffs = append(c.diffs, step)
}
}