Source File
migrate.go
Belonging Package
github.com/golang-migrate/migrate/v4
package migrate
import (
iurl
)
var DefaultPrefetchMigrations = uint(10)
var DefaultLockTimeout = 15 * time.Second
var (
ErrNoChange = errors.New("no change")
ErrNilVersion = errors.New("no migration")
ErrInvalidVersion = errors.New("version must be >= -1")
ErrLocked = errors.New("database locked")
ErrLockTimeout = errors.New("timeout: can't acquire database lock")
)
type ErrShortLimit struct {
Short uint
}
func ( ErrShortLimit) () string {
return fmt.Sprintf("limit %v short", .Short)
}
type ErrDirty struct {
Version int
}
func ( ErrDirty) () string {
return fmt.Sprintf("Dirty database version %v. Fix and force version.", .Version)
}
type Migrate struct {
sourceName string
sourceDrv source.Driver
databaseName string
databaseDrv database.Driver
func (, string) (*Migrate, error) {
:= newCommon()
, := iurl.SchemeFromURL()
if != nil {
return nil,
}
.sourceName =
, := iurl.SchemeFromURL()
if != nil {
return nil,
}
.databaseName =
, := source.Open()
if != nil {
return nil,
}
.sourceDrv =
, := database.Open()
if != nil {
return nil,
}
.databaseDrv =
return , nil
}
func ( string, string, database.Driver) (*Migrate, error) {
:= newCommon()
, := iurl.SchemeFromURL()
if != nil {
return nil,
}
.sourceName =
.databaseName =
, := source.Open()
if != nil {
return nil,
}
.sourceDrv =
.databaseDrv =
return , nil
}
func ( string, source.Driver, string) (*Migrate, error) {
:= newCommon()
, := iurl.SchemeFromURL()
if != nil {
return nil,
}
.databaseName =
.sourceName =
, := database.Open()
if != nil {
return nil,
}
.databaseDrv =
.sourceDrv =
return , nil
}
func ( string, source.Driver, string, database.Driver) (*Migrate, error) {
:= newCommon()
.sourceName =
.databaseName =
.sourceDrv =
.databaseDrv =
return , nil
}
func () *Migrate {
return &Migrate{
GracefulStop: make(chan bool, 1),
PrefetchMigrations: DefaultPrefetchMigrations,
LockTimeout: DefaultLockTimeout,
isLockedMu: &sync.Mutex{},
}
}
func ( *Migrate) ( int) error {
if == 0 {
return ErrNoChange
}
if := .lock(); != nil {
return
}
, , := .databaseDrv.Version()
if != nil {
return .unlockErr()
}
if {
return .unlockErr(ErrDirty{})
}
:= make(chan interface{}, .PrefetchMigrations)
if > 0 {
go .readUp(, , )
} else {
go .readDown(, -, )
}
return .unlockErr(.runMigrations())
}
func ( *Migrate) () error {
if := .lock(); != nil {
return
}
, , := .databaseDrv.Version()
if != nil {
return .unlockErr()
}
if {
return .unlockErr(ErrDirty{})
}
:= make(chan interface{}, .PrefetchMigrations)
go .readUp(, -1, )
return .unlockErr(.runMigrations())
}
func ( *Migrate) () error {
if := .lock(); != nil {
return
}
, , := .databaseDrv.Version()
if != nil {
return .unlockErr()
}
if {
return .unlockErr(ErrDirty{})
}
:= make(chan interface{}, .PrefetchMigrations)
go .readDown(, -1, )
return .unlockErr(.runMigrations())
}
func ( *Migrate) ( ...*Migration) error {
if len() == 0 {
return ErrNoChange
}
if := .lock(); != nil {
return
}
, , := .databaseDrv.Version()
if != nil {
return .unlockErr()
}
if {
return .unlockErr(ErrDirty{})
}
:= make(chan interface{}, .PrefetchMigrations)
go func() {
defer close()
for , := range {
if .PrefetchMigrations > 0 && .Body != nil {
.logVerbosePrintf("Start buffering %v\n", .LogString())
} else {
.logVerbosePrintf("Scheduled %v\n", .LogString())
}
<-
go func( *Migration) {
if := .Buffer(); != nil {
.logErr()
}
}()
}
}()
return .unlockErr(.runMigrations())
}
func ( *Migrate) ( int) error {
if < -1 {
return ErrInvalidVersion
}
if := .lock(); != nil {
return
}
if := .databaseDrv.SetVersion(, false); != nil {
return .unlockErr()
}
return .unlock()
}
func ( *Migrate) () ( uint, bool, error) {
, , := .databaseDrv.Version()
if != nil {
return 0, false,
}
if == database.NilVersion {
return 0, false, ErrNilVersion
}
return suint(), , nil
}
if >= 0 {
if := .versionExists(suint()); != nil {
<-
return
}
}
if >= 0 {
if := .versionExists(suint()); != nil {
<-
return
}
}
if == {
<- ErrNoChange
return
}
if >= 0 {
if := .versionExists(suint()); != nil {
<-
return
}
}
if == 0 {
<- ErrNoChange
return
}
:= 0
for < || == -1 {
if .stop() {
return
}
if == -1 && == 0 {
<- ErrNoChange
return
}
if == -1 {
return
}
if > 0 && == 0 {
<- os.ErrNotExist
return
}
if < {
<- ErrShortLimit{suint( - )}
return
}
}
if != nil {
<-
return
}
, := .newMigration(, int())
if != nil {
<-
return
}
<-
go func() {
if := .Buffer(); != nil {
.logErr()
}
}()
= int()
++
}
}
if >= 0 {
if := .versionExists(suint()); != nil {
<-
return
}
}
if == 0 {
<- ErrNoChange
return
}
if == -1 && == -1 {
<- ErrNoChange
return
}
if == -1 || - > 0 {
, := .sourceDrv.First()
if != nil {
<-
return
}
, := .newMigration(, -1)
if != nil {
<-
return
}
<-
go func() {
if := .Buffer(); != nil {
.logErr()
}
}()
++
}
if < {
<- ErrShortLimit{suint( - )}
}
return
}
if != nil {
<-
return
}
, := .newMigration(suint(), int())
if != nil {
<-
return
}
<-
go func() {
if := .Buffer(); != nil {
.logErr()
}
}()
= int()
++
}
}
if := .databaseDrv.SetVersion(.TargetVersion, true); != nil {
return
}
if .Body != nil {
.logVerbosePrintf("Read and execute %v\n", .LogString())
if := .databaseDrv.Run(.BufferedBody); != nil {
return
}
}
if := .databaseDrv.SetVersion(.TargetVersion, false); != nil {
return
}
:= time.Now()
:= .FinishedReading.Sub(.StartedBuffering)
:= .Sub(.FinishedReading)
func ( *Migrate) () bool {
if .isGracefulStop {
return true
}
select {
case <-.GracefulStop:
.isGracefulStop = true
return true
default:
return false
}
}
, = NewMigration(, , , )
if != nil {
return nil,
}
}
} else {
, , := .sourceDrv.ReadDown()
, = NewMigration(, , , )
if != nil {
return nil,
}
}
}
if .PrefetchMigrations > 0 && .Body != nil {
.logVerbosePrintf("Start buffering %v\n", .LogString())
} else {
.logVerbosePrintf("Scheduled %v\n", .LogString())
}
return , nil
}
func ( *Migrate) () error {
.isLockedMu.Lock()
defer .isLockedMu.Unlock()
if .isLocked {
return ErrLocked
}
:= time.After(.LockTimeout)
go func() {
for {
select {
case <-:
return
case <-:
<- ErrLockTimeout
return
}
}
}()
go func() {
if := .databaseDrv.Lock(); != nil {
<-
} else {
<- nil
}
}()
func ( *Migrate) () error {
.isLockedMu.Lock()
defer .isLockedMu.Unlock()
![]() |
The pages are generated with Golds v0.3.2-preview. (GOOS=darwin GOARCH=amd64) Golds is a Go 101 project developed by Tapir Liu. PR and bug reports are welcome and can be submitted to the issue list. Please follow @Go100and1 (reachable from the left QR code) to get the latest news of Golds. |