github.com/fr-nvriep/migrate/v4@v4.3.2/migrate.go (about)

     1  // Package migrate reads migrations from sources and runs them against databases.
     2  // Sources are defined by the `source.Driver` and databases by the `database.Driver`
     3  // interface. The driver interfaces are kept "dump", all migration logic is kept
     4  // in this package.
     5  package migrate
     6  
     7  import (
     8  	"errors"
     9  	"fmt"
    10  	"github.com/hashicorp/go-multierror"
    11  	"os"
    12  	"sync"
    13  	"time"
    14  
    15  	"github.com/fr-nvriep/migrate/v4/database"
    16  	"github.com/fr-nvriep/migrate/v4/source"
    17  )
    18  
    19  // DefaultPrefetchMigrations sets the number of migrations to pre-read
    20  // from the source. This is helpful if the source is remote, but has little
    21  // effect for a local source (i.e. file system).
    22  // Please note that this setting has a major impact on the memory usage,
    23  // since each pre-read migration is buffered in memory. See DefaultBufferSize.
    24  var DefaultPrefetchMigrations = uint(10)
    25  
    26  // DefaultLockTimeout sets the max time a database driver has to acquire a lock.
    27  var DefaultLockTimeout = 15 * time.Second
    28  
    29  var (
    30  	ErrNoChange       = errors.New("no change")
    31  	ErrNilVersion     = errors.New("no migration")
    32  	ErrInvalidVersion = errors.New("version must be >= -1")
    33  	ErrLocked         = errors.New("database locked")
    34  	ErrLockTimeout    = errors.New("timeout: can't acquire database lock")
    35  )
    36  
    37  // ErrShortLimit is an error returned when not enough migrations
    38  // can be returned by a source for a given limit.
    39  type ErrShortLimit struct {
    40  	Short uint
    41  }
    42  
    43  // Error implements the error interface.
    44  func (e ErrShortLimit) Error() string {
    45  	return fmt.Sprintf("limit %v short", e.Short)
    46  }
    47  
    48  type ErrDirty struct {
    49  	Version int
    50  }
    51  
    52  func (e ErrDirty) Error() string {
    53  	return fmt.Sprintf("Dirty database version %v. Fix and force version.", e.Version)
    54  }
    55  
    56  type Migrate struct {
    57  	sourceName   string
    58  	sourceDrv    source.Driver
    59  	databaseName string
    60  	databaseDrv  database.Driver
    61  
    62  	// Log accepts a Logger interface
    63  	Log Logger
    64  
    65  	// GracefulStop accepts `true` and will stop executing migrations
    66  	// as soon as possible at a safe break point, so that the database
    67  	// is not corrupted.
    68  	GracefulStop chan bool
    69  	isLockedMu   *sync.Mutex
    70  
    71  	isGracefulStop bool
    72  	isLocked       bool
    73  
    74  	// PrefetchMigrations defaults to DefaultPrefetchMigrations,
    75  	// but can be set per Migrate instance.
    76  	PrefetchMigrations uint
    77  
    78  	// LockTimeout defaults to DefaultLockTimeout,
    79  	// but can be set per Migrate instance.
    80  	LockTimeout time.Duration
    81  }
    82  
    83  // New returns a new Migrate instance from a source URL and a database URL.
    84  // The URL scheme is defined by each driver.
    85  func New(sourceURL, databaseURL string) (*Migrate, error) {
    86  	m := newCommon()
    87  
    88  	sourceName, err := sourceSchemeFromURL(sourceURL)
    89  	if err != nil {
    90  		return nil, err
    91  	}
    92  	m.sourceName = sourceName
    93  
    94  	databaseName, err := databaseSchemeFromURL(databaseURL)
    95  	if err != nil {
    96  		return nil, err
    97  	}
    98  	m.databaseName = databaseName
    99  
   100  	sourceDrv, err := source.Open(sourceURL)
   101  	if err != nil {
   102  		return nil, err
   103  	}
   104  	m.sourceDrv = sourceDrv
   105  
   106  	databaseDrv, err := database.Open(databaseURL)
   107  	if err != nil {
   108  		return nil, err
   109  	}
   110  	m.databaseDrv = databaseDrv
   111  
   112  	return m, nil
   113  }
   114  
   115  // NewWithDatabaseInstance returns a new Migrate instance from a source URL
   116  // and an existing database instance. The source URL scheme is defined by each driver.
   117  // Use any string that can serve as an identifier during logging as databaseName.
   118  // You are responsible for closing the underlying database client if necessary.
   119  func NewWithDatabaseInstance(sourceURL string, databaseName string, databaseInstance database.Driver) (*Migrate, error) {
   120  	m := newCommon()
   121  
   122  	sourceName, err := schemeFromURL(sourceURL)
   123  	if err != nil {
   124  		return nil, err
   125  	}
   126  	m.sourceName = sourceName
   127  
   128  	m.databaseName = databaseName
   129  
   130  	sourceDrv, err := source.Open(sourceURL)
   131  	if err != nil {
   132  		return nil, err
   133  	}
   134  	m.sourceDrv = sourceDrv
   135  
   136  	m.databaseDrv = databaseInstance
   137  
   138  	return m, nil
   139  }
   140  
   141  // NewWithSourceInstance returns a new Migrate instance from an existing source instance
   142  // and a database URL. The database URL scheme is defined by each driver.
   143  // Use any string that can serve as an identifier during logging as sourceName.
   144  // You are responsible for closing the underlying source client if necessary.
   145  func NewWithSourceInstance(sourceName string, sourceInstance source.Driver, databaseURL string) (*Migrate, error) {
   146  	m := newCommon()
   147  
   148  	databaseName, err := schemeFromURL(databaseURL)
   149  	if err != nil {
   150  		return nil, err
   151  	}
   152  	m.databaseName = databaseName
   153  
   154  	m.sourceName = sourceName
   155  
   156  	databaseDrv, err := database.Open(databaseURL)
   157  	if err != nil {
   158  		return nil, err
   159  	}
   160  	m.databaseDrv = databaseDrv
   161  
   162  	m.sourceDrv = sourceInstance
   163  
   164  	return m, nil
   165  }
   166  
   167  // NewWithInstance returns a new Migrate instance from an existing source and
   168  // database instance. Use any string that can serve as an identifier during logging
   169  // as sourceName and databaseName. You are responsible for closing down
   170  // the underlying source and database client if necessary.
   171  func NewWithInstance(sourceName string, sourceInstance source.Driver, databaseName string, databaseInstance database.Driver) (*Migrate, error) {
   172  	m := newCommon()
   173  
   174  	m.sourceName = sourceName
   175  	m.databaseName = databaseName
   176  
   177  	m.sourceDrv = sourceInstance
   178  	m.databaseDrv = databaseInstance
   179  
   180  	return m, nil
   181  }
   182  
   183  func newCommon() *Migrate {
   184  	return &Migrate{
   185  		GracefulStop:       make(chan bool, 1),
   186  		PrefetchMigrations: DefaultPrefetchMigrations,
   187  		LockTimeout:        DefaultLockTimeout,
   188  		isLockedMu:         &sync.Mutex{},
   189  	}
   190  }
   191  
   192  // Close closes the source and the database.
   193  func (m *Migrate) Close() (source error, database error) {
   194  	databaseSrvClose := make(chan error)
   195  	sourceSrvClose := make(chan error)
   196  
   197  	m.logVerbosePrintf("Closing source and database\n")
   198  
   199  	go func() {
   200  		databaseSrvClose <- m.databaseDrv.Close()
   201  	}()
   202  
   203  	go func() {
   204  		sourceSrvClose <- m.sourceDrv.Close()
   205  	}()
   206  
   207  	return <-sourceSrvClose, <-databaseSrvClose
   208  }
   209  
   210  // Migrate looks at the currently active migration version,
   211  // then migrates either up or down to the specified version.
   212  func (m *Migrate) Migrate(version uint) error {
   213  	if err := m.lock(); err != nil {
   214  		return err
   215  	}
   216  
   217  	curVersion, dirty, err := m.databaseDrv.Version()
   218  	if err != nil {
   219  		return m.unlockErr(err)
   220  	}
   221  
   222  	if dirty {
   223  		return m.unlockErr(ErrDirty{curVersion})
   224  	}
   225  
   226  	ret := make(chan interface{}, m.PrefetchMigrations)
   227  	go m.read(curVersion, int(version), ret)
   228  
   229  	return m.unlockErr(m.runMigrations(ret))
   230  }
   231  
   232  // Steps looks at the currently active migration version.
   233  // It will migrate up if n > 0, and down if n < 0.
   234  func (m *Migrate) Steps(n int) error {
   235  	if n == 0 {
   236  		return ErrNoChange
   237  	}
   238  
   239  	if err := m.lock(); err != nil {
   240  		return err
   241  	}
   242  
   243  	curVersion, dirty, err := m.databaseDrv.Version()
   244  	if err != nil {
   245  		return m.unlockErr(err)
   246  	}
   247  
   248  	if dirty {
   249  		return m.unlockErr(ErrDirty{curVersion})
   250  	}
   251  
   252  	ret := make(chan interface{}, m.PrefetchMigrations)
   253  
   254  	if n > 0 {
   255  		go m.readUp(curVersion, n, ret)
   256  	} else {
   257  		go m.readDown(curVersion, -n, ret)
   258  	}
   259  
   260  	return m.unlockErr(m.runMigrations(ret))
   261  }
   262  
   263  // Up looks at the currently active migration version
   264  // and will migrate all the way up (applying all up migrations).
   265  func (m *Migrate) Up() error {
   266  	if err := m.lock(); err != nil {
   267  		return err
   268  	}
   269  
   270  	curVersion, dirty, err := m.databaseDrv.Version()
   271  	if err != nil {
   272  		return m.unlockErr(err)
   273  	}
   274  
   275  	if dirty {
   276  		return m.unlockErr(ErrDirty{curVersion})
   277  	}
   278  
   279  	ret := make(chan interface{}, m.PrefetchMigrations)
   280  
   281  	go m.readUp(curVersion, -1, ret)
   282  	return m.unlockErr(m.runMigrations(ret))
   283  }
   284  
   285  // Down looks at the currently active migration version
   286  // and will migrate all the way down (applying all down migrations).
   287  func (m *Migrate) Down() error {
   288  	if err := m.lock(); err != nil {
   289  		return err
   290  	}
   291  
   292  	curVersion, dirty, err := m.databaseDrv.Version()
   293  	if err != nil {
   294  		return m.unlockErr(err)
   295  	}
   296  
   297  	if dirty {
   298  		return m.unlockErr(ErrDirty{curVersion})
   299  	}
   300  
   301  	ret := make(chan interface{}, m.PrefetchMigrations)
   302  	go m.readDown(curVersion, -1, ret)
   303  	return m.unlockErr(m.runMigrations(ret))
   304  }
   305  
   306  // Drop deletes everything in the database.
   307  func (m *Migrate) Drop() error {
   308  	if err := m.lock(); err != nil {
   309  		return err
   310  	}
   311  	if err := m.databaseDrv.Drop(); err != nil {
   312  		return m.unlockErr(err)
   313  	}
   314  	return m.unlock()
   315  }
   316  
   317  // Run runs any migration provided by you against the database.
   318  // It does not check any currently active version in database.
   319  // Usually you don't need this function at all. Use Migrate,
   320  // Steps, Up or Down instead.
   321  func (m *Migrate) Run(migration ...*Migration) error {
   322  	if len(migration) == 0 {
   323  		return ErrNoChange
   324  	}
   325  
   326  	if err := m.lock(); err != nil {
   327  		return err
   328  	}
   329  
   330  	curVersion, dirty, err := m.databaseDrv.Version()
   331  	if err != nil {
   332  		return m.unlockErr(err)
   333  	}
   334  
   335  	if dirty {
   336  		return m.unlockErr(ErrDirty{curVersion})
   337  	}
   338  
   339  	ret := make(chan interface{}, m.PrefetchMigrations)
   340  
   341  	go func() {
   342  		defer close(ret)
   343  		for _, migr := range migration {
   344  			if m.PrefetchMigrations > 0 && migr.Body != nil {
   345  				m.logVerbosePrintf("Start buffering %v\n", migr.LogString())
   346  			} else {
   347  				m.logVerbosePrintf("Scheduled %v\n", migr.LogString())
   348  			}
   349  
   350  			ret <- migr
   351  			go func(migr *Migration) {
   352  				if err := migr.Buffer(); err != nil {
   353  					m.logErr(err)
   354  				}
   355  			}(migr)
   356  		}
   357  	}()
   358  
   359  	return m.unlockErr(m.runMigrations(ret))
   360  }
   361  
   362  // Force sets a migration version.
   363  // It does not check any currently active version in database.
   364  // It resets the dirty state to false.
   365  func (m *Migrate) Force(version int) error {
   366  	if version < -1 {
   367  		return ErrInvalidVersion
   368  	}
   369  
   370  	if err := m.lock(); err != nil {
   371  		return err
   372  	}
   373  
   374  	if err := m.databaseDrv.SetVersion(version, false); err != nil {
   375  		return m.unlockErr(err)
   376  	}
   377  
   378  	return m.unlock()
   379  }
   380  
   381  // Version returns the currently active migration version.
   382  // If no migration has been applied, yet, it will return ErrNilVersion.
   383  func (m *Migrate) Version() (version uint, dirty bool, err error) {
   384  	v, d, err := m.databaseDrv.Version()
   385  	if err != nil {
   386  		return 0, false, err
   387  	}
   388  
   389  	if v == database.NilVersion {
   390  		return 0, false, ErrNilVersion
   391  	}
   392  
   393  	return suint(v), d, nil
   394  }
   395  
   396  // read reads either up or down migrations from source `from` to `to`.
   397  // Each migration is then written to the ret channel.
   398  // If an error occurs during reading, that error is written to the ret channel, too.
   399  // Once read is done reading it will close the ret channel.
   400  func (m *Migrate) read(from int, to int, ret chan<- interface{}) {
   401  	defer close(ret)
   402  
   403  	// check if from version exists
   404  	if from >= 0 {
   405  		if err := m.versionExists(suint(from)); err != nil {
   406  			ret <- err
   407  			return
   408  		}
   409  	}
   410  
   411  	// check if to version exists
   412  	if to >= 0 {
   413  		if err := m.versionExists(suint(to)); err != nil {
   414  			ret <- err
   415  			return
   416  		}
   417  	}
   418  
   419  	// no change?
   420  	if from == to {
   421  		ret <- ErrNoChange
   422  		return
   423  	}
   424  
   425  	if from < to {
   426  		// it's going up
   427  		// apply first migration if from is nil version
   428  		if from == -1 {
   429  			firstVersion, err := m.sourceDrv.First()
   430  			if err != nil {
   431  				ret <- err
   432  				return
   433  			}
   434  
   435  			migr, err := m.newMigration(firstVersion, int(firstVersion))
   436  			if err != nil {
   437  				ret <- err
   438  				return
   439  			}
   440  
   441  			ret <- migr
   442  			go func() {
   443  				if err := migr.Buffer(); err != nil {
   444  					m.logErr(err)
   445  				}
   446  			}()
   447  
   448  			from = int(firstVersion)
   449  		}
   450  
   451  		// run until we reach target ...
   452  		for from < to {
   453  			if m.stop() {
   454  				return
   455  			}
   456  
   457  			next, err := m.sourceDrv.Next(suint(from))
   458  			if err != nil {
   459  				ret <- err
   460  				return
   461  			}
   462  
   463  			migr, err := m.newMigration(next, int(next))
   464  			if err != nil {
   465  				ret <- err
   466  				return
   467  			}
   468  
   469  			ret <- migr
   470  			go func() {
   471  				if err := migr.Buffer(); err != nil {
   472  					m.logErr(err)
   473  				}
   474  			}()
   475  
   476  			from = int(next)
   477  		}
   478  
   479  	} else {
   480  		// it's going down
   481  		// run until we reach target ...
   482  		for from > to && from >= 0 {
   483  			if m.stop() {
   484  				return
   485  			}
   486  
   487  			prev, err := m.sourceDrv.Prev(suint(from))
   488  			if os.IsNotExist(err) && to == -1 {
   489  				// apply nil migration
   490  				migr, err := m.newMigration(suint(from), -1)
   491  				if err != nil {
   492  					ret <- err
   493  					return
   494  				}
   495  				ret <- migr
   496  				go func() {
   497  					if err := migr.Buffer(); err != nil {
   498  						m.logErr(err)
   499  					}
   500  				}()
   501  
   502  				return
   503  
   504  			} else if err != nil {
   505  				ret <- err
   506  				return
   507  			}
   508  
   509  			migr, err := m.newMigration(suint(from), int(prev))
   510  			if err != nil {
   511  				ret <- err
   512  				return
   513  			}
   514  
   515  			ret <- migr
   516  			go func() {
   517  				if err := migr.Buffer(); err != nil {
   518  					m.logErr(err)
   519  				}
   520  			}()
   521  
   522  			from = int(prev)
   523  		}
   524  	}
   525  }
   526  
   527  // readUp reads up migrations from `from` limitted by `limit`.
   528  // limit can be -1, implying no limit and reading until there are no more migrations.
   529  // Each migration is then written to the ret channel.
   530  // If an error occurs during reading, that error is written to the ret channel, too.
   531  // Once readUp is done reading it will close the ret channel.
   532  func (m *Migrate) readUp(from int, limit int, ret chan<- interface{}) {
   533  	defer close(ret)
   534  
   535  	// check if from version exists
   536  	if from >= 0 {
   537  		if err := m.versionExists(suint(from)); err != nil {
   538  			ret <- err
   539  			return
   540  		}
   541  	}
   542  
   543  	if limit == 0 {
   544  		ret <- ErrNoChange
   545  		return
   546  	}
   547  
   548  	count := 0
   549  	for count < limit || limit == -1 {
   550  		if m.stop() {
   551  			return
   552  		}
   553  
   554  		// apply first migration if from is nil version
   555  		if from == -1 {
   556  			firstVersion, err := m.sourceDrv.First()
   557  			if err != nil {
   558  				ret <- err
   559  				return
   560  			}
   561  
   562  			migr, err := m.newMigration(firstVersion, int(firstVersion))
   563  			if err != nil {
   564  				ret <- err
   565  				return
   566  			}
   567  
   568  			ret <- migr
   569  			go func() {
   570  				if err := migr.Buffer(); err != nil {
   571  					m.logErr(err)
   572  				}
   573  			}()
   574  			from = int(firstVersion)
   575  			count++
   576  			continue
   577  		}
   578  
   579  		// apply next migration
   580  		next, err := m.sourceDrv.Next(suint(from))
   581  		if os.IsNotExist(err) {
   582  			// no limit, but no migrations applied?
   583  			if limit == -1 && count == 0 {
   584  				ret <- ErrNoChange
   585  				return
   586  			}
   587  
   588  			// no limit, reached end
   589  			if limit == -1 {
   590  				return
   591  			}
   592  
   593  			// reached end, and didn't apply any migrations
   594  			if limit > 0 && count == 0 {
   595  				ret <- os.ErrNotExist
   596  				return
   597  			}
   598  
   599  			// applied less migrations than limit?
   600  			if count < limit {
   601  				ret <- ErrShortLimit{suint(limit - count)}
   602  				return
   603  			}
   604  		}
   605  		if err != nil {
   606  			ret <- err
   607  			return
   608  		}
   609  
   610  		migr, err := m.newMigration(next, int(next))
   611  		if err != nil {
   612  			ret <- err
   613  			return
   614  		}
   615  
   616  		ret <- migr
   617  		go func() {
   618  			if err := migr.Buffer(); err != nil {
   619  				m.logErr(err)
   620  			}
   621  		}()
   622  		from = int(next)
   623  		count++
   624  	}
   625  }
   626  
   627  // readDown reads down migrations from `from` limitted by `limit`.
   628  // limit can be -1, implying no limit and reading until there are no more migrations.
   629  // Each migration is then written to the ret channel.
   630  // If an error occurs during reading, that error is written to the ret channel, too.
   631  // Once readDown is done reading it will close the ret channel.
   632  func (m *Migrate) readDown(from int, limit int, ret chan<- interface{}) {
   633  	defer close(ret)
   634  
   635  	// check if from version exists
   636  	if from >= 0 {
   637  		if err := m.versionExists(suint(from)); err != nil {
   638  			ret <- err
   639  			return
   640  		}
   641  	}
   642  
   643  	if limit == 0 {
   644  		ret <- ErrNoChange
   645  		return
   646  	}
   647  
   648  	// no change if already at nil version
   649  	if from == -1 && limit == -1 {
   650  		ret <- ErrNoChange
   651  		return
   652  	}
   653  
   654  	// can't go over limit if already at nil version
   655  	if from == -1 && limit > 0 {
   656  		ret <- os.ErrNotExist
   657  		return
   658  	}
   659  
   660  	count := 0
   661  	for count < limit || limit == -1 {
   662  		if m.stop() {
   663  			return
   664  		}
   665  
   666  		prev, err := m.sourceDrv.Prev(suint(from))
   667  		if os.IsNotExist(err) {
   668  			// no limit or haven't reached limit, apply "first" migration
   669  			if limit == -1 || limit-count > 0 {
   670  				firstVersion, err := m.sourceDrv.First()
   671  				if err != nil {
   672  					ret <- err
   673  					return
   674  				}
   675  
   676  				migr, err := m.newMigration(firstVersion, -1)
   677  				if err != nil {
   678  					ret <- err
   679  					return
   680  				}
   681  				ret <- migr
   682  				go func() {
   683  					if err := migr.Buffer(); err != nil {
   684  						m.logErr(err)
   685  					}
   686  				}()
   687  				count++
   688  			}
   689  
   690  			if count < limit {
   691  				ret <- ErrShortLimit{suint(limit - count)}
   692  			}
   693  			return
   694  		}
   695  		if err != nil {
   696  			ret <- err
   697  			return
   698  		}
   699  
   700  		migr, err := m.newMigration(suint(from), int(prev))
   701  		if err != nil {
   702  			ret <- err
   703  			return
   704  		}
   705  
   706  		ret <- migr
   707  		go func() {
   708  			if err := migr.Buffer(); err != nil {
   709  				m.logErr(err)
   710  			}
   711  		}()
   712  		from = int(prev)
   713  		count++
   714  	}
   715  }
   716  
   717  // runMigrations reads *Migration and error from a channel. Any other type
   718  // sent on this channel will result in a panic. Each migration is then
   719  // proxied to the database driver and run against the database.
   720  // Before running a newly received migration it will check if it's supposed
   721  // to stop execution because it might have received a stop signal on the
   722  // GracefulStop channel.
   723  func (m *Migrate) runMigrations(ret <-chan interface{}) error {
   724  	for r := range ret {
   725  
   726  		if m.stop() {
   727  			return nil
   728  		}
   729  
   730  		switch r := r.(type) {
   731  		case error:
   732  			return r
   733  
   734  		case *Migration:
   735  			migr := r
   736  
   737  			// set version with dirty state
   738  			if err := m.databaseDrv.SetVersion(migr.TargetVersion, true); err != nil {
   739  				return err
   740  			}
   741  
   742  			if migr.Body != nil {
   743  				m.logVerbosePrintf("Read and execute %v\n", migr.LogString())
   744  				if err := m.databaseDrv.Run(migr.BufferedBody); err != nil {
   745  					return err
   746  				}
   747  			}
   748  
   749  			// set clean state
   750  			if err := m.databaseDrv.SetVersion(migr.TargetVersion, false); err != nil {
   751  				return err
   752  			}
   753  
   754  			endTime := time.Now()
   755  			readTime := migr.FinishedReading.Sub(migr.StartedBuffering)
   756  			runTime := endTime.Sub(migr.FinishedReading)
   757  
   758  			// log either verbose or normal
   759  			if m.Log != nil {
   760  				if m.Log.Verbose() {
   761  					m.logPrintf("Finished %v (read %v, ran %v)\n", migr.LogString(), readTime, runTime)
   762  				} else {
   763  					m.logPrintf("%v (%v)\n", migr.LogString(), readTime+runTime)
   764  				}
   765  			}
   766  
   767  		default:
   768  			return fmt.Errorf("unknown type: %T with value: %+v", r, r)
   769  		}
   770  	}
   771  	return nil
   772  }
   773  
   774  // versionExists checks the source if either the up or down migration for
   775  // the specified migration version exists.
   776  func (m *Migrate) versionExists(version uint) (result error) {
   777  	// try up migration first
   778  	up, _, err := m.sourceDrv.ReadUp(version)
   779  	if err == nil {
   780  		defer func() {
   781  			if errClose := up.Close(); errClose != nil {
   782  				result = multierror.Append(result, errClose)
   783  			}
   784  		}()
   785  	}
   786  	if os.IsExist(err) {
   787  		return nil
   788  	} else if !os.IsNotExist(err) {
   789  		return err
   790  	}
   791  
   792  	// then try down migration
   793  	down, _, err := m.sourceDrv.ReadDown(version)
   794  	if err == nil {
   795  		defer func() {
   796  			if errClose := down.Close(); errClose != nil {
   797  				result = multierror.Append(result, errClose)
   798  			}
   799  		}()
   800  	}
   801  	if os.IsExist(err) {
   802  		return nil
   803  	} else if !os.IsNotExist(err) {
   804  		return err
   805  	}
   806  
   807  	return os.ErrNotExist
   808  }
   809  
   810  // stop returns true if no more migrations should be run against the database
   811  // because a stop signal was received on the GracefulStop channel.
   812  // Calls are cheap and this function is not blocking.
   813  func (m *Migrate) stop() bool {
   814  	if m.isGracefulStop {
   815  		return true
   816  	}
   817  
   818  	select {
   819  	case <-m.GracefulStop:
   820  		m.isGracefulStop = true
   821  		return true
   822  
   823  	default:
   824  		return false
   825  	}
   826  }
   827  
   828  // newMigration is a helper func that returns a *Migration for the
   829  // specified version and targetVersion.
   830  func (m *Migrate) newMigration(version uint, targetVersion int) (*Migration, error) {
   831  	var migr *Migration
   832  
   833  	if targetVersion >= int(version) {
   834  		r, identifier, err := m.sourceDrv.ReadUp(version)
   835  		if os.IsNotExist(err) {
   836  			// create "empty" migration
   837  			migr, err = NewMigration(nil, "", version, targetVersion)
   838  			if err != nil {
   839  				return nil, err
   840  			}
   841  
   842  		} else if err != nil {
   843  			return nil, err
   844  
   845  		} else {
   846  			// create migration from up source
   847  			migr, err = NewMigration(r, identifier, version, targetVersion)
   848  			if err != nil {
   849  				return nil, err
   850  			}
   851  		}
   852  
   853  	} else {
   854  		r, identifier, err := m.sourceDrv.ReadDown(version)
   855  		if os.IsNotExist(err) {
   856  			// create "empty" migration
   857  			migr, err = NewMigration(nil, "", version, targetVersion)
   858  			if err != nil {
   859  				return nil, err
   860  			}
   861  
   862  		} else if err != nil {
   863  			return nil, err
   864  
   865  		} else {
   866  			// create migration from down source
   867  			migr, err = NewMigration(r, identifier, version, targetVersion)
   868  			if err != nil {
   869  				return nil, err
   870  			}
   871  		}
   872  	}
   873  
   874  	if m.PrefetchMigrations > 0 && migr.Body != nil {
   875  		m.logVerbosePrintf("Start buffering %v\n", migr.LogString())
   876  	} else {
   877  		m.logVerbosePrintf("Scheduled %v\n", migr.LogString())
   878  	}
   879  
   880  	return migr, nil
   881  }
   882  
   883  // lock is a thread safe helper function to lock the database.
   884  // It should be called as late as possible when running migrations.
   885  func (m *Migrate) lock() error {
   886  	m.isLockedMu.Lock()
   887  	defer m.isLockedMu.Unlock()
   888  
   889  	if m.isLocked {
   890  		return ErrLocked
   891  	}
   892  
   893  	// create done channel, used in the timeout goroutine
   894  	done := make(chan bool, 1)
   895  	defer func() {
   896  		done <- true
   897  	}()
   898  
   899  	// use errchan to signal error back to this context
   900  	errchan := make(chan error, 2)
   901  
   902  	// start timeout goroutine
   903  	timeout := time.After(m.LockTimeout)
   904  	go func() {
   905  		for {
   906  			select {
   907  			case <-done:
   908  				return
   909  			case <-timeout:
   910  				errchan <- ErrLockTimeout
   911  				return
   912  			}
   913  		}
   914  	}()
   915  
   916  	// now try to acquire the lock
   917  	go func() {
   918  		if err := m.databaseDrv.Lock(); err != nil {
   919  			errchan <- err
   920  		} else {
   921  			errchan <- nil
   922  		}
   923  	}()
   924  
   925  	// wait until we either receive ErrLockTimeout or error from Lock operation
   926  	err := <-errchan
   927  	if err == nil {
   928  		m.isLocked = true
   929  	}
   930  	return err
   931  }
   932  
   933  // unlock is a thread safe helper function to unlock the database.
   934  // It should be called as early as possible when no more migrations are
   935  // expected to be executed.
   936  func (m *Migrate) unlock() error {
   937  	m.isLockedMu.Lock()
   938  	defer m.isLockedMu.Unlock()
   939  
   940  	if err := m.databaseDrv.Unlock(); err != nil {
   941  		// BUG: Can potentially create a deadlock. Add a timeout.
   942  		return err
   943  	}
   944  
   945  	m.isLocked = false
   946  	return nil
   947  }
   948  
   949  // unlockErr calls unlock and returns a combined error
   950  // if a prevErr is not nil.
   951  func (m *Migrate) unlockErr(prevErr error) error {
   952  	if err := m.unlock(); err != nil {
   953  		return NewMultiError(prevErr, err)
   954  	}
   955  	return prevErr
   956  }
   957  
   958  // logPrintf writes to m.Log if not nil
   959  func (m *Migrate) logPrintf(format string, v ...interface{}) {
   960  	if m.Log != nil {
   961  		m.Log.Printf(format, v...)
   962  	}
   963  }
   964  
   965  // logVerbosePrintf writes to m.Log if not nil. Use for verbose logging output.
   966  func (m *Migrate) logVerbosePrintf(format string, v ...interface{}) {
   967  	if m.Log != nil && m.Log.Verbose() {
   968  		m.Log.Printf(format, v...)
   969  	}
   970  }
   971  
   972  // logErr writes error to m.Log if not nil
   973  func (m *Migrate) logErr(err error) {
   974  	if m.Log != nil {
   975  		m.Log.Printf("error: %v", err)
   976  	}
   977  }