@@ -39,6 +39,8 @@ type MigrationSet struct {
3939 IgnoreUnknown bool
4040 // DisableCreateTable disable the creation of the migration table
4141 DisableCreateTable bool
42+ // LazyLoad enable migration file to be loaded only when needed.
43+ LazyLoad bool
4244}
4345
4446var migSet = MigrationSet {}
@@ -121,13 +123,27 @@ func SetIgnoreUnknown(v bool) {
121123 migSet .IgnoreUnknown = v
122124}
123125
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+
124137type Migration struct {
125138 Id string
126139 Up []string
127140 Down []string
128141
129142 DisableTransactionUp bool
130143 DisableTransactionDown bool
144+
145+ // lazyLoadFile is information of migration file, which is used to load migration file later if not nil.
146+ lazyLoadFile * migrationFile
131147}
132148
133149func (m Migration ) Less (other * Migration ) bool {
@@ -160,6 +176,31 @@ func (m Migration) VersionInt() int64 {
160176 return value
161177}
162178
179+ // Load parses migration file if not yet
180+ func (m * Migration ) Load () error {
181+ if m .lazyLoadFile == nil {
182+ return nil
183+ }
184+ root := m .lazyLoadFile .root
185+ name := m .lazyLoadFile .baseName
186+ file , err := m .lazyLoadFile .dir .Open (path .Join (root , name ))
187+ if err != nil {
188+ return fmt .Errorf ("Error while opening %s: %s" , name , err )
189+ }
190+ defer func () { _ = file .Close () }()
191+
192+ parsed , err := sqlparse .ParseMigration (file )
193+ if err != nil {
194+ return fmt .Errorf ("Error parsing migration (%s): %s" , m .Id , err )
195+ }
196+ m .Up = parsed .UpStatements
197+ m .Down = parsed .DownStatements
198+ m .DisableTransactionUp = parsed .DisableTransactionUp
199+ m .DisableTransactionDown = parsed .DisableTransactionDown
200+ m .lazyLoadFile = nil
201+ return nil
202+ }
203+
163204type PlannedMigration struct {
164205 * Migration
165206
@@ -266,12 +307,23 @@ func findMigrations(dir http.FileSystem, root string) ([]*Migration, error) {
266307
267308 for _ , info := range files {
268309 if strings .HasSuffix (info .Name (), ".sql" ) {
269- migration , err := migrationFromFile (dir , root , info )
270- if err != nil {
271- return nil , err
310+ if migSet .LazyLoad {
311+ migration := & Migration {
312+ Id : info .Name (),
313+ lazyLoadFile : & migrationFile {
314+ dir : dir ,
315+ root : root ,
316+ baseName : info .Name (),
317+ },
318+ }
319+ migrations = append (migrations , migration )
320+ } else {
321+ migration , err := migrationFromFile (dir , root , info )
322+ if err != nil {
323+ return nil , err
324+ }
325+ migrations = append (migrations , migration )
272326 }
273-
274- migrations = append (migrations , migration )
275327 }
276328 }
277329
@@ -575,7 +627,11 @@ func (ms MigrationSet) PlanMigration(db *sql.DB, dialect string, m MigrationSour
575627 // Add missing migrations up to the last run migration.
576628 // This can happen for example when merges happened.
577629 if len (existingMigrations ) > 0 {
578- result = append (result , ToCatchup (migrations , existingMigrations , record )... )
630+ catchUp , err := ToCatchup (migrations , existingMigrations , record )
631+ if err != nil {
632+ return nil , nil , err
633+ }
634+ result = append (result , catchUp ... )
579635 }
580636
581637 // Figure out which migrations to apply
@@ -585,6 +641,10 @@ func (ms MigrationSet) PlanMigration(db *sql.DB, dialect string, m MigrationSour
585641 toApplyCount = max
586642 }
587643 for _ , v := range toApply [0 :toApplyCount ] {
644+ err = v .Load ()
645+ if err != nil {
646+ return nil , nil , err
647+ }
588648
589649 if dir == Up {
590650 result = append (result , & PlannedMigration {
@@ -683,7 +743,7 @@ func ToApply(migrations []*Migration, current string, direction MigrationDirecti
683743 panic ("Not possible" )
684744}
685745
686- func ToCatchup (migrations , existingMigrations []* Migration , lastRun * Migration ) []* PlannedMigration {
746+ func ToCatchup (migrations , existingMigrations []* Migration , lastRun * Migration ) ( []* PlannedMigration , error ) {
687747 missing := make ([]* PlannedMigration , 0 )
688748 for _ , migration := range migrations {
689749 found := false
@@ -694,14 +754,18 @@ func ToCatchup(migrations, existingMigrations []*Migration, lastRun *Migration)
694754 }
695755 }
696756 if ! found && migration .Less (lastRun ) {
757+ err := migration .Load ()
758+ if err != nil {
759+ return nil , err
760+ }
697761 missing = append (missing , & PlannedMigration {
698762 Migration : migration ,
699763 Queries : migration .Up ,
700764 DisableTransaction : migration .DisableTransactionUp ,
701765 })
702766 }
703767 }
704- return missing
768+ return missing , nil
705769}
706770
707771func GetMigrationRecords (db * sql.DB , dialect string ) ([]* MigrationRecord , error ) {
0 commit comments