219 lines
6.2 KiB
Go
219 lines
6.2 KiB
Go
package pilgrim_conf
|
|
|
|
import (
|
|
"log"
|
|
)
|
|
|
|
const DefaultMigrationDirectory = "./migrations"
|
|
const DefaultMigrationTable = "pilgrim_migrations"
|
|
|
|
type MigrationPhase bool
|
|
|
|
const (
|
|
MigrationPhase_Up MigrationPhase = true
|
|
MigrationPhase_Down = false
|
|
)
|
|
|
|
type PilgrimConfigurationRetriever interface {
|
|
UrlParts() UrlParts
|
|
MigrationDirectory() string
|
|
MigrationPhase() MigrationPhase
|
|
MigrationScript() string
|
|
MigrationStrictOrdering() bool
|
|
MigrationIsChecksumValidationEnabled() bool
|
|
MigrationTable() string
|
|
MigrationSchema() string
|
|
|
|
ValidateChecksums() bool
|
|
ValidateLatest() bool
|
|
ValidateMigrationOrder() bool
|
|
}
|
|
|
|
type pilgrimContext struct {
|
|
urlParts UrlParts
|
|
migrationDirectory string
|
|
migrationPhase MigrationPhase
|
|
migrationScript string
|
|
migrationStrictOrdering bool
|
|
migrationIsChecksumValidationEnabled bool
|
|
migrationSchema string
|
|
migrationTable string
|
|
|
|
validateMigrationOrder bool
|
|
validateLatest bool
|
|
validateChecksums bool
|
|
}
|
|
|
|
func NewPilgrimContext(cli CliFlagRetriever, env EnvVarRetriever) *pilgrimContext {
|
|
|
|
cliUrl, _ := cli.Url()
|
|
cliUrlParts := ParseDatabaseUrl(cliUrl)
|
|
envUrl, _ := env.Url()
|
|
envUrlParts := ParseDatabaseUrl(envUrl)
|
|
|
|
urlParts := UrlParts{
|
|
Driver: PickFirstAvailable(
|
|
cli.Driver,
|
|
func() (DbDriver, bool) { return DbDriver(cliUrlParts.Driver), cliUrlParts.Driver != EmptyString },
|
|
env.Driver,
|
|
func() (DbDriver, bool) { return DbDriver(envUrlParts.Driver), envUrlParts.Driver != EmptyString },
|
|
),
|
|
Username: PickFirstAvailable(
|
|
cli.Username,
|
|
func() (string, bool) { return cliUrlParts.Username, cliUrlParts.Username != EmptyString },
|
|
env.Username,
|
|
func() (string, bool) { return envUrlParts.Username, envUrlParts.Username != EmptyString },
|
|
),
|
|
Password: PickFirstAvailable(
|
|
cli.Password,
|
|
func() (string, bool) { return cliUrlParts.Password, cliUrlParts.Password != EmptyString },
|
|
env.Password,
|
|
func() (string, bool) { return envUrlParts.Password, envUrlParts.Password != EmptyString },
|
|
),
|
|
Host: PickFirstAvailable(
|
|
cli.Host,
|
|
func() (string, bool) { return cliUrlParts.Host, cliUrlParts.Host != EmptyString },
|
|
env.Host,
|
|
func() (string, bool) { return envUrlParts.Host, envUrlParts.Host != EmptyString },
|
|
),
|
|
Port: PickFirstAvailable(
|
|
cli.Port,
|
|
func() (string, bool) { return cliUrlParts.Port, cliUrlParts.Port != EmptyString },
|
|
env.Port,
|
|
func() (string, bool) { return envUrlParts.Port, envUrlParts.Port != EmptyString },
|
|
),
|
|
Segments: PickFirstAvailable(
|
|
cli.Segments,
|
|
func() ([]string, bool) { return cliUrlParts.Segments, cliUrlParts.Segments != nil },
|
|
env.Segments,
|
|
func() ([]string, bool) { return envUrlParts.Segments, envUrlParts.Segments != nil },
|
|
),
|
|
Arguments: PickFirstAvailable(
|
|
cli.Args,
|
|
func() (map[string]string, bool) { return cliUrlParts.Arguments, cliUrlParts.Arguments != nil },
|
|
env.Args,
|
|
func() (map[string]string, bool) { return envUrlParts.Arguments, envUrlParts.Arguments != nil },
|
|
),
|
|
}
|
|
|
|
isValid, err := urlParts.Validate()
|
|
|
|
if !isValid {
|
|
log.Fatalln(err)
|
|
}
|
|
|
|
migrationPhase, migrationScript, _ := determineMigrationPhaseAndScript(cli)
|
|
|
|
migrationDirectory := PickFirstAvailable(cli.Directory, env.Directory, func() (string, bool) { return DefaultMigrationDirectory, true })
|
|
migrationSchema := PickFirstAvailable(cli.MigrationTableSchema, env.MigrationTableSchema, pickFirstDefault(EmptyString)) // Default depends on driver, set empty for now
|
|
migrationTable := PickFirstAvailable(cli.MigrationTable, env.MigrationTable, pickFirstDefault(DefaultMigrationTable))
|
|
|
|
migrationStrictOrdering, _ := cli.IsStrictOrderingEnabled()
|
|
migrationIsChecksumValidationEnabled, _ := cli.IsChecksumValidationEnabled()
|
|
|
|
validateMigrationOrder, _ := cli.IsValidatingMigrationOrder()
|
|
validateLatest, _ := cli.IsValidatingLatest()
|
|
validateChecksums, _ := cli.IsValidatingLatest()
|
|
|
|
return &pilgrimContext{
|
|
urlParts,
|
|
migrationDirectory,
|
|
migrationPhase,
|
|
migrationScript,
|
|
migrationStrictOrdering,
|
|
migrationIsChecksumValidationEnabled,
|
|
migrationSchema,
|
|
migrationTable,
|
|
validateMigrationOrder,
|
|
validateLatest,
|
|
validateChecksums,
|
|
}
|
|
}
|
|
|
|
type MigrationPhaseRetriever interface {
|
|
Script() (script string, isScriptProvided bool)
|
|
IsUp() (isUp, isUpProvided bool)
|
|
IsDown() (isDown, isDownProvided bool)
|
|
}
|
|
|
|
func determineMigrationPhaseAndScript(cli MigrationPhaseRetriever) (phase MigrationPhase, script string, err error) {
|
|
script, _ = cli.Script()
|
|
|
|
isUp, isUpProvided := cli.IsUp()
|
|
_, isDownProvided := cli.IsDown()
|
|
|
|
if (!isUpProvided && !isDownProvided) || (isUpProvided && isDownProvided) {
|
|
return MigrationPhase_Down, EmptyString, PilgrimInvalidError("Must provide either --up or --down, but not both.")
|
|
}
|
|
|
|
if isUp {
|
|
phase = MigrationPhase_Up
|
|
} else {
|
|
phase = MigrationPhase_Down
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
func pickFirstDefault[T any](defaultVal T) func() (value T, provided bool) {
|
|
return func() (value T, provided bool) {
|
|
return defaultVal, true
|
|
}
|
|
}
|
|
|
|
func PickFirstAvailable[T any](valueProviders ...func() (value T, provided bool)) (value T) {
|
|
for _, getValue := range valueProviders {
|
|
val, provided := getValue()
|
|
|
|
if provided {
|
|
return val
|
|
}
|
|
}
|
|
|
|
value, _ = valueProviders[len(valueProviders)-1]()
|
|
return
|
|
}
|
|
|
|
func (c *pilgrimContext) UrlParts() UrlParts {
|
|
return c.urlParts
|
|
}
|
|
|
|
func (c *pilgrimContext) MigrationDirectory() string {
|
|
return c.migrationDirectory
|
|
}
|
|
|
|
func (c *pilgrimContext) MigrationPhase() MigrationPhase {
|
|
return MigrationPhase(c.migrationPhase)
|
|
}
|
|
|
|
func (c *pilgrimContext) MigrationScript() string {
|
|
return c.migrationScript
|
|
}
|
|
|
|
func (c *pilgrimContext) MigrationStrictOrdering() bool {
|
|
return c.migrationStrictOrdering
|
|
}
|
|
|
|
func (c *pilgrimContext) MigrationIsChecksumValidationEnabled() bool {
|
|
return c.migrationIsChecksumValidationEnabled
|
|
}
|
|
|
|
func (c *pilgrimContext) MigrationSchema() string {
|
|
return c.migrationSchema
|
|
}
|
|
|
|
func (c *pilgrimContext) MigrationTable() string {
|
|
return c.migrationTable
|
|
}
|
|
|
|
func (c *pilgrimContext) ValidateChecksums() bool {
|
|
return c.validateChecksums
|
|
}
|
|
|
|
func (c *pilgrimContext) ValidateMigrationOrder() bool {
|
|
return c.validateMigrationOrder
|
|
}
|
|
|
|
func (c *pilgrimContext) ValidateLatest() bool {
|
|
return c.validateLatest
|
|
}
|