@@ -38,6 +38,10 @@ type Config struct {
38
38
// Only Migrator.DoStep method will be bounded with this timeout.
39
39
Timeout time.Duration
40
40
41
+ // NoDatabaseLock set to true will run migrations without taking a database lock.
42
+ // Default is false.
43
+ NoDatabaseLock bool
44
+
41
45
// DisableTx will run every migration not in a transaction.
42
46
// This completely depends on a specific Migrator implementation
43
47
// because not every database supports transaction, so this option can be no-op all the time.
@@ -118,11 +122,6 @@ const (
118
122
modeMaxPossible
119
123
)
120
124
121
- // AsLocklessMigrator makes given migrator to not take a lock on database.
122
- func AsLocklessMigrator (m Migrator ) Migrator {
123
- return & locklessMigrator {m }
124
- }
125
-
126
125
// Run the Migrator with migration queries provided by the Loader.
127
126
func Run (ctx context.Context , config Config ) error {
128
127
switch {
@@ -191,20 +190,12 @@ func (m *mig) load() ([]*Migration, error) {
191
190
}
192
191
193
192
func (m * mig ) runMigrations (ctx context.Context , ms []* Migration ) (err error ) {
194
- if err := m .LockDB (ctx ); err != nil {
195
- if ! m .UseForce {
196
- return fmt .Errorf ("lock db: %w" , err )
197
- }
198
- if err := m .UnlockDB (ctx ); err != nil {
199
- return fmt .Errorf ("force unlock db: %w" , err )
200
- }
201
- if err := m .LockDB (ctx ); err != nil {
202
- return fmt .Errorf ("force lock db: %w" , err )
203
- }
193
+ if err := m .lockDB (ctx ); err != nil {
194
+ return err
204
195
}
205
196
206
197
defer func () {
207
- if errUnlock := m .UnlockDB (ctx ); err == nil && errUnlock != nil {
198
+ if errUnlock := m .unlockDB (ctx ); err == nil && errUnlock != nil {
208
199
err = fmt .Errorf ("unlock db: %w" , errUnlock )
209
200
}
210
201
}()
@@ -221,6 +212,32 @@ func (m *mig) runMigrations(ctx context.Context, ms []*Migration) (err error) {
221
212
return err
222
213
}
223
214
215
+ func (m * mig ) lockDB (ctx context.Context ) error {
216
+ if m .Config .NoDatabaseLock {
217
+ return nil
218
+ }
219
+
220
+ if err := m .LockDB (ctx ); err != nil {
221
+ if ! m .UseForce {
222
+ return fmt .Errorf ("lock db: %w" , err )
223
+ }
224
+ if err := m .UnlockDB (ctx ); err != nil {
225
+ return fmt .Errorf ("force unlock db: %w" , err )
226
+ }
227
+ if err := m .LockDB (ctx ); err != nil {
228
+ return fmt .Errorf ("force lock db: %w" , err )
229
+ }
230
+ }
231
+ return nil
232
+ }
233
+
234
+ func (m * mig ) unlockDB (ctx context.Context ) error {
235
+ if m .Config .NoDatabaseLock {
236
+ return nil
237
+ }
238
+ return m .UnlockDB (ctx )
239
+ }
240
+
224
241
func (m * mig ) runMigrationsLocked (ctx context.Context , ms []* Migration ) error {
225
242
curr , target , err := m .getCurrAndTargetVersions (ctx , len (ms ))
226
243
if err != nil {
@@ -343,21 +360,3 @@ func (m *Migration) toStep(up, disableTx bool) Step {
343
360
DisableTx : disableTx ,
344
361
}
345
362
}
346
-
347
- type locklessMigrator struct {
348
- m Migrator
349
- }
350
-
351
- func (llm * locklessMigrator ) LockDB (ctx context.Context ) error { return nil }
352
- func (llm * locklessMigrator ) UnlockDB (ctx context.Context ) error { return nil }
353
-
354
- func (llm * locklessMigrator ) Init (ctx context.Context ) error { return llm .m .Init (ctx ) }
355
- func (llm * locklessMigrator ) Drop (ctx context.Context ) error { return llm .m .Drop (ctx ) }
356
-
357
- func (llm * locklessMigrator ) Version (ctx context.Context ) (version int , err error ) {
358
- return llm .m .Version (ctx )
359
- }
360
-
361
- func (llm * locklessMigrator ) DoStep (ctx context.Context , step Step ) error {
362
- return llm .m .DoStep (ctx , step )
363
- }
0 commit comments