@@ -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,28 @@ 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+ delayLoad bool
146+ // file is information of migration file, which is used to load migration file later if delayLoad is true.
147+ file * migrationFile
131148}
132149
133150func (m Migration ) Less (other * Migration ) bool {
@@ -160,6 +177,34 @@ func (m Migration) VersionInt() int64 {
160177 return value
161178}
162179
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+
163208type PlannedMigration struct {
164209 * Migration
165210
@@ -266,12 +311,24 @@ func findMigrations(dir http.FileSystem, root string) ([]*Migration, error) {
266311
267312 for _ , info := range files {
268313 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 )
272331 }
273-
274- migrations = append (migrations , migration )
275332 }
276333 }
277334
@@ -575,7 +632,11 @@ func (ms MigrationSet) PlanMigration(db *sql.DB, dialect string, m MigrationSour
575632 // Add missing migrations up to the last run migration.
576633 // This can happen for example when merges happened.
577634 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 ... )
579640 }
580641
581642 // Figure out which migrations to apply
@@ -585,6 +646,10 @@ func (ms MigrationSet) PlanMigration(db *sql.DB, dialect string, m MigrationSour
585646 toApplyCount = max
586647 }
587648 for _ , v := range toApply [0 :toApplyCount ] {
649+ err = v .Load ()
650+ if err != nil {
651+ return nil , nil , err
652+ }
588653
589654 if dir == Up {
590655 result = append (result , & PlannedMigration {
@@ -683,7 +748,7 @@ func ToApply(migrations []*Migration, current string, direction MigrationDirecti
683748 panic ("Not possible" )
684749}
685750
686- func ToCatchup (migrations , existingMigrations []* Migration , lastRun * Migration ) []* PlannedMigration {
751+ func ToCatchup (migrations , existingMigrations []* Migration , lastRun * Migration ) ( []* PlannedMigration , error ) {
687752 missing := make ([]* PlannedMigration , 0 )
688753 for _ , migration := range migrations {
689754 found := false
@@ -694,14 +759,18 @@ func ToCatchup(migrations, existingMigrations []*Migration, lastRun *Migration)
694759 }
695760 }
696761 if ! found && migration .Less (lastRun ) {
762+ err := migration .Load ()
763+ if err != nil {
764+ return nil , err
765+ }
697766 missing = append (missing , & PlannedMigration {
698767 Migration : migration ,
699768 Queries : migration .Up ,
700769 DisableTransaction : migration .DisableTransactionUp ,
701770 })
702771 }
703772 }
704- return missing
773+ return missing , nil
705774}
706775
707776func GetMigrationRecords (db * sql.DB , dialect string ) ([]* MigrationRecord , error ) {
0 commit comments