Skip to content

Commit 14223b2

Browse files
committed
Add SetLazyLoad option, which sets the boolean to enable migration file to be loaded only when needed.
1 parent 5d0f4bf commit 14223b2

File tree

2 files changed

+98
-8
lines changed

2 files changed

+98
-8
lines changed

migrate.go

+72-8
Original file line numberDiff line numberDiff line change
@@ -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

4446
var 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+
124137
type 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

133149
func (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+
163204
type 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

707771
func GetMigrationRecords(db *sql.DB, dialect string) ([]*MigrationRecord, error) {

migrate_test.go

+26
Original file line numberDiff line numberDiff line change
@@ -665,3 +665,29 @@ func (s *SqliteMigrateSuite) TestGetMigrationDbMapWithDisableCreateTable(c *C) {
665665
_, err := migSet.getMigrationDbMap(s.Db, "postgres")
666666
c.Assert(err, IsNil)
667667
}
668+
669+
func (s *SqliteMigrateSuite) TestFileMigrateWithLazyLoad(c *C) {
670+
migrations := &FileMigrationSource{
671+
Dir: "test-migrations",
672+
}
673+
674+
SetLazyLoad(true)
675+
migrationsNotLoaded, err := migrations.FindMigrations()
676+
c.Assert(err, IsNil)
677+
for _, migration := range migrationsNotLoaded {
678+
c.Assert(migration.DisableTransactionUp, Equals, false)
679+
c.Assert(migration.DisableTransactionDown, Equals, false)
680+
c.Assert(len(migration.Up), Equals, 0)
681+
c.Assert(len(migration.Down), Equals, 0)
682+
}
683+
// Executes two migrations
684+
n, err := Exec(s.Db, "sqlite3", migrations, Up)
685+
c.Assert(err, IsNil)
686+
c.Assert(n, Equals, 2)
687+
688+
// Has data
689+
id, err := s.DbMap.SelectInt("SELECT id FROM people")
690+
c.Assert(err, IsNil)
691+
c.Assert(id, Equals, int64(1))
692+
SetLazyLoad(false)
693+
}

0 commit comments

Comments
 (0)