7
7
"fmt"
8
8
"io"
9
9
"net/http"
10
- "os"
11
10
"path"
12
11
"regexp"
13
12
"sort"
@@ -121,15 +120,61 @@ func SetIgnoreUnknown(v bool) {
121
120
migSet .IgnoreUnknown = v
122
121
}
123
122
124
- type Migration struct {
125
- Id string
126
- Up []string
127
- Down []string
128
-
123
+ type MigrationData struct {
124
+ Up []string
125
+ Down []string
129
126
DisableTransactionUp bool
130
127
DisableTransactionDown bool
131
128
}
132
129
130
+ type migrationFile struct {
131
+ dir http.FileSystem
132
+ root string
133
+ baseName string
134
+ }
135
+
136
+ type Migration struct {
137
+ Id string
138
+
139
+ // data may be nil if not parsed yet.
140
+ data * MigrationData
141
+ // file is information of migration file, which is used to parse later.
142
+ // file may be nil if migration file has already been parsed when Migration is initialized.
143
+ file * migrationFile
144
+ }
145
+
146
+ // Data parses migration file if not yet, and returns *MigrationData
147
+ func (m * Migration ) Data () (* MigrationData , error ) {
148
+ if m .data != nil {
149
+ return m .data , nil
150
+ }
151
+ err := m .loadFile ()
152
+ if err != nil {
153
+ return nil , err
154
+ }
155
+ return m .data , nil
156
+ }
157
+
158
+ func (m * Migration ) loadFile () error {
159
+ if m .file == nil {
160
+ return fmt .Errorf ("Error m.file must not be nil when call loadFile" )
161
+ }
162
+ root := m .file .root
163
+ name := m .file .baseName
164
+ file , err := m .file .dir .Open (path .Join (root , name ))
165
+ if err != nil {
166
+ return fmt .Errorf ("Error while opening %s: %s" , name , err )
167
+ }
168
+ defer func () { _ = file .Close () }()
169
+
170
+ migrationData , err := ParseMigration (name , file )
171
+ if err != nil {
172
+ return fmt .Errorf ("Error while parsing %s: %s" , name , err )
173
+ }
174
+ m .data = migrationData
175
+ return nil
176
+ }
177
+
133
178
func (m Migration ) Less (other * Migration ) bool {
134
179
switch {
135
180
case m .isNumeric () && other .isNumeric () && m .VersionInt () != other .VersionInt ():
@@ -266,11 +311,14 @@ func findMigrations(dir http.FileSystem, root string) ([]*Migration, error) {
266
311
267
312
for _ , info := range files {
268
313
if strings .HasSuffix (info .Name (), ".sql" ) {
269
- migration , err := migrationFromFile (dir , root , info )
270
- if err != nil {
271
- return nil , err
314
+ migration := & Migration {
315
+ Id : info .Name (),
316
+ file : & migrationFile {
317
+ dir : dir ,
318
+ root : root ,
319
+ baseName : info .Name (),
320
+ },
272
321
}
273
-
274
322
migrations = append (migrations , migration )
275
323
}
276
324
}
@@ -281,21 +329,6 @@ func findMigrations(dir http.FileSystem, root string) ([]*Migration, error) {
281
329
return migrations , nil
282
330
}
283
331
284
- func migrationFromFile (dir http.FileSystem , root string , info os.FileInfo ) (* Migration , error ) {
285
- path := path .Join (root , info .Name ())
286
- file , err := dir .Open (path )
287
- if err != nil {
288
- return nil , fmt .Errorf ("Error while opening %s: %s" , info .Name (), err )
289
- }
290
- defer func () { _ = file .Close () }()
291
-
292
- migration , err := ParseMigration (info .Name (), file )
293
- if err != nil {
294
- return nil , fmt .Errorf ("Error while parsing %s: %s" , info .Name (), err )
295
- }
296
- return migration , nil
297
- }
298
-
299
332
// Migrations from a bindata asset set.
300
333
type AssetMigrationSource struct {
301
334
// Asset should return content of file in path if exists
@@ -325,11 +358,14 @@ func (a AssetMigrationSource) FindMigrations() ([]*Migration, error) {
325
358
return nil , err
326
359
}
327
360
328
- migration , err := ParseMigration (name , bytes .NewReader (file ))
361
+ migrationData , err := ParseMigration (name , bytes .NewReader (file ))
329
362
if err != nil {
330
363
return nil , err
331
364
}
332
-
365
+ migration := & Migration {
366
+ Id : name ,
367
+ data : migrationData ,
368
+ }
333
369
migrations = append (migrations , migration )
334
370
}
335
371
}
@@ -382,11 +418,14 @@ func (p PackrMigrationSource) FindMigrations() ([]*Migration, error) {
382
418
return nil , err
383
419
}
384
420
385
- migration , err := ParseMigration (name , bytes .NewReader (file ))
421
+ migrationData , err := ParseMigration (name , bytes .NewReader (file ))
386
422
if err != nil {
387
423
return nil , err
388
424
}
389
-
425
+ migration := & Migration {
426
+ Id : name ,
427
+ data : migrationData ,
428
+ }
390
429
migrations = append (migrations , migration )
391
430
}
392
431
}
@@ -398,23 +437,18 @@ func (p PackrMigrationSource) FindMigrations() ([]*Migration, error) {
398
437
}
399
438
400
439
// Migration parsing
401
- func ParseMigration (id string , r io.ReadSeeker ) (* Migration , error ) {
402
- m := & Migration {
403
- Id : id ,
404
- }
405
-
440
+ func ParseMigration (id string , r io.ReadSeeker ) (* MigrationData , error ) {
406
441
parsed , err := sqlparse .ParseMigration (r )
407
442
if err != nil {
408
443
return nil , fmt .Errorf ("Error parsing migration (%s): %s" , id , err )
409
444
}
410
445
411
- m .Up = parsed .UpStatements
412
- m .Down = parsed .DownStatements
413
-
414
- m .DisableTransactionUp = parsed .DisableTransactionUp
415
- m .DisableTransactionDown = parsed .DisableTransactionDown
416
-
417
- return m , nil
446
+ return & MigrationData {
447
+ Up : parsed .UpStatements ,
448
+ Down : parsed .DownStatements ,
449
+ DisableTransactionUp : parsed .DisableTransactionUp ,
450
+ DisableTransactionDown : parsed .DisableTransactionDown ,
451
+ }, nil
418
452
}
419
453
420
454
type SqlExecutor interface {
@@ -575,7 +609,11 @@ func (ms MigrationSet) PlanMigration(db *sql.DB, dialect string, m MigrationSour
575
609
// Add missing migrations up to the last run migration.
576
610
// This can happen for example when merges happened.
577
611
if len (existingMigrations ) > 0 {
578
- result = append (result , ToCatchup (migrations , existingMigrations , record )... )
612
+ catchUp , err := ToCatchup (migrations , existingMigrations , record )
613
+ if err != nil {
614
+ return nil , nil , err
615
+ }
616
+ result = append (result , catchUp ... )
579
617
}
580
618
581
619
// Figure out which migrations to apply
@@ -585,18 +623,21 @@ func (ms MigrationSet) PlanMigration(db *sql.DB, dialect string, m MigrationSour
585
623
toApplyCount = max
586
624
}
587
625
for _ , v := range toApply [0 :toApplyCount ] {
588
-
626
+ migrationData , err := v .Data ()
627
+ if err != nil {
628
+ return nil , nil , err
629
+ }
589
630
if dir == Up {
590
631
result = append (result , & PlannedMigration {
591
632
Migration : v ,
592
- Queries : v .Up ,
593
- DisableTransaction : v .DisableTransactionUp ,
633
+ Queries : migrationData .Up ,
634
+ DisableTransaction : migrationData .DisableTransactionUp ,
594
635
})
595
636
} else if dir == Down {
596
637
result = append (result , & PlannedMigration {
597
638
Migration : v ,
598
- Queries : v .Down ,
599
- DisableTransaction : v .DisableTransactionDown ,
639
+ Queries : migrationData .Down ,
640
+ DisableTransaction : migrationData .DisableTransactionDown ,
600
641
})
601
642
}
602
643
}
@@ -683,7 +724,7 @@ func ToApply(migrations []*Migration, current string, direction MigrationDirecti
683
724
panic ("Not possible" )
684
725
}
685
726
686
- func ToCatchup (migrations , existingMigrations []* Migration , lastRun * Migration ) []* PlannedMigration {
727
+ func ToCatchup (migrations , existingMigrations []* Migration , lastRun * Migration ) ( []* PlannedMigration , error ) {
687
728
missing := make ([]* PlannedMigration , 0 )
688
729
for _ , migration := range migrations {
689
730
found := false
@@ -694,14 +735,18 @@ func ToCatchup(migrations, existingMigrations []*Migration, lastRun *Migration)
694
735
}
695
736
}
696
737
if ! found && migration .Less (lastRun ) {
738
+ migrationData , err := migration .Data ()
739
+ if err != nil {
740
+ return nil , err
741
+ }
697
742
missing = append (missing , & PlannedMigration {
698
743
Migration : migration ,
699
- Queries : migration .Up ,
700
- DisableTransaction : migration .DisableTransactionUp ,
744
+ Queries : migrationData .Up ,
745
+ DisableTransaction : migrationData .DisableTransactionUp ,
701
746
})
702
747
}
703
748
}
704
- return missing
749
+ return missing , nil
705
750
}
706
751
707
752
func GetMigrationRecords (db * sql.DB , dialect string ) ([]* MigrationRecord , error ) {
0 commit comments