@@ -39,6 +39,8 @@ type MigrationSet struct {
39
39
IgnoreUnknown bool
40
40
// DisableCreateTable disable the creation of the migration table
41
41
DisableCreateTable bool
42
+ // LazyLoad enable migration file to be loaded only when needed.
43
+ LazyLoad bool
42
44
}
43
45
44
46
var migSet = MigrationSet {}
@@ -121,13 +123,28 @@ func SetIgnoreUnknown(v bool) {
121
123
migSet .IgnoreUnknown = v
122
124
}
123
125
126
+ // SetLazyLoad sets the boolean to enable migration file to be loaded only when needed.
127
+ func SetLazyLoad (v bool ) {
128
+ migSet .LazyLoad = v
129
+ }
130
+
131
+ type migrationFile struct {
132
+ dir http.FileSystem
133
+ root string
134
+ baseName string
135
+ }
136
+
124
137
type Migration struct {
125
138
Id string
126
139
Up []string
127
140
Down []string
128
141
129
142
DisableTransactionUp bool
130
143
DisableTransactionDown bool
144
+
145
+ delayLoad bool
146
+ // file is information of migration file, which is used to load migration file later if delayLoad is true.
147
+ file * migrationFile
131
148
}
132
149
133
150
func (m Migration ) Less (other * Migration ) bool {
@@ -160,6 +177,34 @@ func (m Migration) VersionInt() int64 {
160
177
return value
161
178
}
162
179
180
+ // Load parses migration file if not yet
181
+ func (m * Migration ) Load () error {
182
+ if ! m .delayLoad {
183
+ return nil
184
+ }
185
+ if m .file == nil {
186
+ return fmt .Errorf ("Error m.file must not be nil when call loadFile" )
187
+ }
188
+ root := m .file .root
189
+ name := m .file .baseName
190
+ file , err := m .file .dir .Open (path .Join (root , name ))
191
+ if err != nil {
192
+ return fmt .Errorf ("Error while opening %s: %s" , name , err )
193
+ }
194
+ defer func () { _ = file .Close () }()
195
+
196
+ parsed , err := sqlparse .ParseMigration (file )
197
+ if err != nil {
198
+ return fmt .Errorf ("Error parsing migration (%s): %s" , m .Id , err )
199
+ }
200
+ m .Up = parsed .UpStatements
201
+ m .Down = parsed .DownStatements
202
+ m .DisableTransactionUp = parsed .DisableTransactionUp
203
+ m .DisableTransactionDown = parsed .DisableTransactionDown
204
+ m .delayLoad = false
205
+ return nil
206
+ }
207
+
163
208
type PlannedMigration struct {
164
209
* Migration
165
210
@@ -266,12 +311,24 @@ 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
+ if migSet .LazyLoad {
315
+ migration := & Migration {
316
+ Id : info .Name (),
317
+ delayLoad : true ,
318
+ file : & migrationFile {
319
+ dir : dir ,
320
+ root : root ,
321
+ baseName : info .Name (),
322
+ },
323
+ }
324
+ migrations = append (migrations , migration )
325
+ } else {
326
+ migration , err := migrationFromFile (dir , root , info )
327
+ if err != nil {
328
+ return nil , err
329
+ }
330
+ migrations = append (migrations , migration )
272
331
}
273
-
274
- migrations = append (migrations , migration )
275
332
}
276
333
}
277
334
@@ -575,7 +632,11 @@ func (ms MigrationSet) PlanMigration(db *sql.DB, dialect string, m MigrationSour
575
632
// Add missing migrations up to the last run migration.
576
633
// This can happen for example when merges happened.
577
634
if len (existingMigrations ) > 0 {
578
- result = append (result , ToCatchup (migrations , existingMigrations , record )... )
635
+ catchUp , err := ToCatchup (migrations , existingMigrations , record )
636
+ if err != nil {
637
+ return nil , nil , err
638
+ }
639
+ result = append (result , catchUp ... )
579
640
}
580
641
581
642
// Figure out which migrations to apply
@@ -585,6 +646,10 @@ func (ms MigrationSet) PlanMigration(db *sql.DB, dialect string, m MigrationSour
585
646
toApplyCount = max
586
647
}
587
648
for _ , v := range toApply [0 :toApplyCount ] {
649
+ err = v .Load ()
650
+ if err != nil {
651
+ return nil , nil , err
652
+ }
588
653
589
654
if dir == Up {
590
655
result = append (result , & PlannedMigration {
@@ -683,7 +748,7 @@ func ToApply(migrations []*Migration, current string, direction MigrationDirecti
683
748
panic ("Not possible" )
684
749
}
685
750
686
- func ToCatchup (migrations , existingMigrations []* Migration , lastRun * Migration ) []* PlannedMigration {
751
+ func ToCatchup (migrations , existingMigrations []* Migration , lastRun * Migration ) ( []* PlannedMigration , error ) {
687
752
missing := make ([]* PlannedMigration , 0 )
688
753
for _ , migration := range migrations {
689
754
found := false
@@ -694,14 +759,18 @@ func ToCatchup(migrations, existingMigrations []*Migration, lastRun *Migration)
694
759
}
695
760
}
696
761
if ! found && migration .Less (lastRun ) {
762
+ err := migration .Load ()
763
+ if err != nil {
764
+ return nil , err
765
+ }
697
766
missing = append (missing , & PlannedMigration {
698
767
Migration : migration ,
699
768
Queries : migration .Up ,
700
769
DisableTransaction : migration .DisableTransactionUp ,
701
770
})
702
771
}
703
772
}
704
- return missing
773
+ return missing , nil
705
774
}
706
775
707
776
func GetMigrationRecords (db * sql.DB , dialect string ) ([]* MigrationRecord , error ) {
0 commit comments