Skip to content

Commit b3347c3

Browse files
committed
Replace AsLockless with Config.NoDatabaseLock
1 parent 6d16391 commit b3347c3

File tree

3 files changed

+44
-44
lines changed

3 files changed

+44
-44
lines changed

GUIDE.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -50,20 +50,20 @@ Credits goes to [Postgres.ai](https://postgres.ai/) mentioning this feature at c
5050

5151
## Do not take database locks
5252

53-
If for some reason you don't want or you can't take lock on database (why???) there is `AsLocklessMigrator` function to achieve this:
53+
If for some reason you don't want or you can't take lock on database there is `Config.NoDatabaseLock` field to achieve this:
5454

5555
```go
5656
// let's take Postgres for example
5757
m := dbump_pg.NewMigrator(...)
5858

59-
// volia, now m is a migrator that will not take a lock
60-
m = dbump.AsLocklessMigrator(m)
59+
cfg := dbump.Config{
60+
NoDatabaseLock: true,
61+
// set other fields
62+
}
6163

62-
// pass m in config param as before
63-
dbump.Run(...)
64+
dbump.Run(context.Background(), cfg)
6465
```
6566

6667
However, lock prevents from running few migrators at once, possible creating bad situations that's is hard to fix.
6768

68-
Also, not all migrators supports locks.
69-
69+
Also, not all migrators support locks.

dbump.go

Lines changed: 33 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@ type Config struct {
3838
// Only Migrator.DoStep method will be bounded with this timeout.
3939
Timeout time.Duration
4040

41+
// NoDatabaseLock set to true will run migrations without taking a database lock.
42+
// Default is false.
43+
NoDatabaseLock bool
44+
4145
// DisableTx will run every migration not in a transaction.
4246
// This completely depends on a specific Migrator implementation
4347
// because not every database supports transaction, so this option can be no-op all the time.
@@ -118,11 +122,6 @@ const (
118122
modeMaxPossible
119123
)
120124

121-
// AsLocklessMigrator makes given migrator to not take a lock on database.
122-
func AsLocklessMigrator(m Migrator) Migrator {
123-
return &locklessMigrator{m}
124-
}
125-
126125
// Run the Migrator with migration queries provided by the Loader.
127126
func Run(ctx context.Context, config Config) error {
128127
switch {
@@ -191,20 +190,12 @@ func (m *mig) load() ([]*Migration, error) {
191190
}
192191

193192
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
204195
}
205196

206197
defer func() {
207-
if errUnlock := m.UnlockDB(ctx); err == nil && errUnlock != nil {
198+
if errUnlock := m.unlockDB(ctx); err == nil && errUnlock != nil {
208199
err = fmt.Errorf("unlock db: %w", errUnlock)
209200
}
210201
}()
@@ -221,6 +212,32 @@ func (m *mig) runMigrations(ctx context.Context, ms []*Migration) (err error) {
221212
return err
222213
}
223214

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+
224241
func (m *mig) runMigrationsLocked(ctx context.Context, ms []*Migration) error {
225242
curr, target, err := m.getCurrAndTargetVersions(ctx, len(ms))
226243
if err != nil {
@@ -343,21 +360,3 @@ func (m *Migration) toStep(up, disableTx bool) Step {
343360
DisableTx: disableTx,
344361
}
345362
}
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-
}

dbump_test.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -238,9 +238,10 @@ func TestLockless(t *testing.T) {
238238

239239
mm := &tests.MockMigrator{}
240240
cfg := dbump.Config{
241-
Migrator: dbump.AsLocklessMigrator(mm),
242-
Loader: dbump.NewSliceLoader(testdataMigrations),
243-
Mode: dbump.ModeApplyAll,
241+
Migrator: mm,
242+
Loader: dbump.NewSliceLoader(testdataMigrations),
243+
Mode: dbump.ModeApplyAll,
244+
NoDatabaseLock: true,
244245
}
245246

246247
failIfErr(t, dbump.Run(context.Background(), cfg))

0 commit comments

Comments
 (0)