@@ -76,7 +76,24 @@ func (t *PatchTable) alter() []string {
7676 ret = append (ret , c .alter ()... )
7777 }
7878 }
79- // TODO: others
79+ for _ , idx := range t .indexes {
80+ if idx .from == nil {
81+ ret = append (ret , idx .create ()... )
82+ } else if idx .to == nil {
83+ ret = append (ret , idx .drop ()... )
84+ } else {
85+ ret = append (ret , idx .alter ()... )
86+ }
87+ }
88+ for _ , ctr := range t .constraints {
89+ if ctr .from == nil {
90+ ret = append (ret , ctr .create ()... )
91+ } else if ctr .to == nil {
92+ ret = append (ret , ctr .drop ()... )
93+ } else {
94+ ret = append (ret , ctr .alter ()... )
95+ }
96+ }
8097 return ret
8198}
8299
@@ -92,6 +109,7 @@ func (t *PatchTable) drop() []string {
92109type PatchColumn struct {
93110 from , to * Column
94111 tableName string
112+ newTable bool
95113}
96114
97115func (c * PatchColumn ) GenerateSQL () []string {
@@ -106,6 +124,9 @@ func (c *PatchColumn) GenerateSQL() []string {
106124
107125func (c * PatchColumn ) create () []string {
108126 sb := & strings.Builder {}
127+ if ! c .newTable {
128+ fmt .Fprintf (sb , "ALTER TABLE %s ADD COLUMN " , c .tableName )
129+ }
109130 fmt .Fprint (sb , c .to .Name , " " , c .to .Type )
110131 if ! c .to .Nullable {
111132 fmt .Fprint (sb , " NOT NULL" )
@@ -179,40 +200,49 @@ func (i *PatchIndex) GenerateSQL() []string {
179200 return i .drop ()
180201}
181202
182- func ( i * PatchIndex ) create () [] string {
203+ func createIndexDDL ( idx * Index ) string {
183204 sb := & strings.Builder {}
184205 fmt .Fprint (sb , "CREATE" )
185- if i . to .IsUnique {
206+ if idx .IsUnique {
186207 fmt .Fprint (sb , " UNIQUE" )
187208 }
188209 fmt .Fprint (sb , " INDEX" )
189- if i . to .Concurrently {
210+ if idx .Concurrently {
190211 fmt .Fprint (sb , " CONCURRENTLY" )
191212 }
192213 fmt .Fprintf (sb , " %s ON %s" ,
193- i . to . Name , * i . to .Table )
194- if len (i . to .MethodName ) > 0 {
195- fmt .Fprint (sb , " USING " , i . to .MethodName )
214+ idx . Name , * idx .Table )
215+ if len (idx .MethodName ) > 0 {
216+ fmt .Fprint (sb , " USING " , idx .MethodName )
196217 }
197218 sb .WriteByte ('(' )
198- if len (i . to .ColDef ) > 0 {
199- sb .WriteString (i . to .ColDef )
219+ if len (idx .ColDef ) > 0 {
220+ sb .WriteString (idx .ColDef )
200221 } else {
201- fmt .Fprint (sb , strings .Join (i . to .Columns , ", " ))
222+ fmt .Fprint (sb , strings .Join (idx .Columns , ", " ))
202223 }
203224 sb .WriteByte (')' )
204- if len (i . to .With ) > 0 {
205- fmt .Fprint (sb , " WITH " , i . to .With )
225+ if len (idx .With ) > 0 {
226+ fmt .Fprint (sb , " WITH " , idx .With )
206227 }
207- if len (i . to .Tablespace ) > 0 {
208- fmt .Fprint (sb , " TABLESPACE " , i . to .Tablespace )
228+ if len (idx .Tablespace ) > 0 {
229+ fmt .Fprint (sb , " TABLESPACE " , idx .Tablespace )
209230 }
210- if len (i . to .Where ) > 0 {
211- fmt .Fprint (sb , " WHERE " , i . to .Where )
231+ if len (idx .Where ) > 0 {
232+ fmt .Fprint (sb , " WHERE " , idx .Where )
212233 }
213- return []string {sb .String ()}
234+ return sb .String ()
235+ }
236+
237+ func (i * PatchIndex ) create () []string {
238+ return []string {createIndexDDL (i .to )}
239+ }
240+ func (i * PatchIndex ) alter () []string {
241+ if strings .EqualFold (createIndexDDL (i .from ), createIndexDDL (i .to )) {
242+ return nil
243+ }
244+ return append (i .drop (), i .create ()... )
214245}
215- func (i * PatchIndex ) alter () []string { return nil }
216246func (i * PatchIndex ) drop () []string {
217247 // always drop unused indexes
218248 return []string {
@@ -223,43 +253,59 @@ func (i *PatchIndex) drop() []string {
223253type PatchConstraint struct {
224254 from , to * Constraint
225255 tableName string
256+ newTable bool
226257}
227258
228259func (c * PatchConstraint ) GenerateSQL () []string {
229260 if c .from != nil && c .to != nil {
261+ c .from .Table = & c .tableName
262+ c .to .Table = & c .tableName
230263 return c .alter ()
231264 }
232265 if c .from == nil {
266+ c .to .Table = & c .tableName
233267 return c .create ()
234268 }
269+ c .from .Table = & c .tableName
235270 return c .drop ()
236271}
237272
238- func ( c * PatchConstraint ) create () [] string {
273+ func createConstraintDDL ( ctr * Constraint , newTable bool ) string {
239274 sb := & strings.Builder {}
240- fmt .Fprint (sb , "CONSTRAINT " , c .to .Name )
241- if len (c .to .Check ) > 0 {
242- fmt .Fprint (sb , " CHECK (" , c .to .Check , ")" )
275+ if ! newTable {
276+ fmt .Fprintf (sb , "ALTER TABLE %s ADD " , * ctr .Table )
243277 }
244- switch c .to .Type {
278+ fmt .Fprint (sb , "CONSTRAINT " , ctr .Name )
279+ if len (ctr .Check ) > 0 {
280+ fmt .Fprint (sb , " CHECK (" , ctr .Check , ")" )
281+ }
282+ switch ctr .Type {
245283 case TypeFK :
246- if c . to .ReferenceTable == nil {
247- fmt .Fprint (sb , " FOREIGN KEY (" , strings .Join (c . to .Columns , ", " ), ")" )
248- fmt .Fprintf (sb , " REFERENCES %s (%s)" , * c . to . ReferenceTable , strings .Join (c . to .ReferenceColumns , ", " ))
249- if len (c . to .OnDelete ) > 0 {
250- fmt .Fprint (sb , " ON DELETE " , c . to .OnDelete )
284+ if ctr .ReferenceTable == nil {
285+ fmt .Fprint (sb , " FOREIGN KEY (" , strings .Join (ctr .Columns , ", " ), ")" )
286+ fmt .Fprintf (sb , " REFERENCES %s (%s)" , * ctr . ReferenceTable , strings .Join (ctr .ReferenceColumns , ", " ))
287+ if len (ctr .OnDelete ) > 0 {
288+ fmt .Fprint (sb , " ON DELETE " , ctr .OnDelete )
251289 }
252290 }
253291 case TypePK :
254- fmt .Fprint (sb , " PRIMARY KEY (" , strings .Join (c . to .Columns , ", " ), ")" )
292+ fmt .Fprint (sb , " PRIMARY KEY (" , strings .Join (ctr .Columns , ", " ), ")" )
255293 case TypeUQ :
256- fmt .Fprint (sb , " UNIQUE (" , strings .Join (c . to .Columns , ", " ), ")" )
294+ fmt .Fprint (sb , " UNIQUE (" , strings .Join (ctr .Columns , ", " ), ")" )
257295 }
258- return []string {sb .String ()}
296+ return sb .String ()
297+ }
298+
299+ func (c * PatchConstraint ) create () []string {
300+ return []string {createConstraintDDL (c .to , c .newTable )}
259301}
260302
261303func (c * PatchConstraint ) alter () []string {
262- return nil
304+ if strings .EqualFold (createConstraintDDL (c .from , c .newTable ),
305+ createConstraintDDL (c .to , c .newTable )) {
306+ return nil
307+ }
308+ return append (c .drop (), c .create ()... )
263309}
264310
265311func (c * PatchConstraint ) drop () []string {
@@ -283,26 +329,36 @@ func (r *PatchRelation) GenerateSQL() []string {
283329 return r .drop ()
284330}
285331
286- func (r * PatchRelation ) create () [] string {
332+ func createRelationDDL (r * Relation ) string {
287333 sb := & strings.Builder {}
288- fmt .Fprintf (sb , "ALTER TABLE %s ADD FOREIGN KEY (" , r .to . Table .Name )
289- for i , c := range r .to . Columns {
334+ fmt .Fprintf (sb , "ALTER TABLE %s ADD CONSTRAINT %s FOREIGN KEY (" , r .Table . Name , r .Name )
335+ for i , c := range r .Columns {
290336 if i > 0 {
291337 sb .WriteString (", " )
292338 }
293339 sb .WriteString (c .Name )
294340 }
295- fmt .Fprintf (sb , ") REFERENCES %s (" , r .to . ParentTable .Name )
296- for i , c := range r .to . ParentColumns {
341+ fmt .Fprintf (sb , ") REFERENCES %s (" , r .ParentTable .Name )
342+ for i , c := range r .ParentColumns {
297343 if i > 0 {
298344 sb .WriteString (", " )
299345 }
300346 sb .WriteString (c .Name )
301347 }
302348 sb .WriteByte (')' )
303- return []string {sb .String ()}
349+ return sb .String ()
350+ }
351+
352+ func (r * PatchRelation ) create () []string {
353+ return []string {createRelationDDL (r .to )}
354+ }
355+ func (r * PatchRelation ) alter () []string {
356+ if strings .EqualFold (createRelationDDL (r .from ),
357+ createRelationDDL (r .to )) {
358+ return nil
359+ }
360+ return append (r .drop (), r .create ()... )
304361}
305- func (r * PatchRelation ) alter () []string { return nil }
306362func (r * PatchRelation ) drop () []string {
307363 // TODO:
308364 // declare r record;
@@ -389,6 +445,9 @@ func (s *PatchSchema) Build(from, to *Schema) {
389445 }
390446 }
391447 for _ , idx := range t .Indexes {
448+ if idx .Table == nil {
449+ idx .Table = & t .Name
450+ }
392451 pi := & PatchIndex {
393452 from : idx ,
394453 }
@@ -400,7 +459,38 @@ func (s *PatchSchema) Build(from, to *Schema) {
400459 }
401460 pt .indexes = append (pt .indexes , pi )
402461 }
462+
463+ if rt != nil {
464+ for _ , idx := range rt .Indexes {
465+ if idx .Table == nil {
466+ idx .Table = & rt .Name
467+ }
468+ pi := & PatchIndex {
469+ to : idx ,
470+ }
471+ ti , err := t .FindIndexByName (idx .Name )
472+ fnd := false
473+ if err == nil {
474+ pi .from = ti
475+
476+ for _ , v := range pt .indexes {
477+ if v .from == pi .from &&
478+ v .to == pi .to {
479+ fnd = true
480+ break
481+ }
482+ }
483+ }
484+ if ! fnd {
485+ pt .indexes = append (pt .indexes , pi )
486+ }
487+ }
488+ }
489+
403490 for _ , c := range t .Constraints {
491+ if c .Table == nil {
492+ c .Table = & t .Name
493+ }
404494 pc := & PatchConstraint {
405495 tableName : t .Name ,
406496 from : c ,
@@ -413,6 +503,34 @@ func (s *PatchSchema) Build(from, to *Schema) {
413503 }
414504 pt .constraints = append (pt .constraints , pc )
415505 }
506+
507+ if rt != nil {
508+ for _ , c := range rt .Constraints {
509+ if c .Table == nil {
510+ c .Table = & rt .Name
511+ }
512+ pc := & PatchConstraint {
513+ tableName : rt .Name ,
514+ to : c ,
515+ }
516+ tc , err := t .FindConstraintByName (c .Name )
517+ fnd := false
518+ if err == nil {
519+ pc .from = tc
520+
521+ for _ , v := range pt .constraints {
522+ if v .from == pc .from &&
523+ v .to == pc .to {
524+ fnd = true
525+ break
526+ }
527+ }
528+ }
529+ if ! fnd {
530+ pt .constraints = append (pt .constraints , pc )
531+ }
532+ }
533+ }
416534 }
417535 // create tables
418536 for _ , rt := range to .Tables {
@@ -435,19 +553,27 @@ func (s *PatchSchema) Build(from, to *Schema) {
435553 pc := & PatchColumn {
436554 tableName : rt .Name ,
437555 to : c ,
556+ newTable : true ,
438557 }
439558 pt .columns = append (pt .columns , pc )
440559 }
441560 for _ , idx := range rt .Indexes {
561+ if idx .Table == nil {
562+ idx .Table = & rt .Name
563+ }
442564 pi := & PatchIndex {
443565 to : idx ,
444566 }
445567 pt .indexes = append (pt .indexes , pi )
446568 }
447569 for _ , c := range rt .Constraints {
570+ if c .Table == nil {
571+ c .Table = & rt .Name
572+ }
448573 pc := & PatchConstraint {
449574 tableName : rt .Name ,
450575 to : c ,
576+ newTable : true ,
451577 }
452578 pt .constraints = append (pt .constraints , pc )
453579 }
0 commit comments