pilgrim/internal/pilgrim_conf/context.go

220 lines
6.2 KiB
Go
Raw Normal View History

2025-03-15 19:03:22 +02:00
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{
2025-03-15 13:02:47 +02:00
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 },
),
2025-03-15 13:02:47 +02:00
Username: PickFirstAvailable(
cli.Username,
func() (string, bool) { return cliUrlParts.Username, cliUrlParts.Username != EmptyString },
env.Username,
func() (string, bool) { return envUrlParts.Username, envUrlParts.Username != EmptyString },
),
2025-03-15 13:02:47 +02:00
Password: PickFirstAvailable(
cli.Password,
func() (string, bool) { return cliUrlParts.Password, cliUrlParts.Password != EmptyString },
env.Password,
func() (string, bool) { return envUrlParts.Password, envUrlParts.Password != EmptyString },
),
2025-03-15 13:02:47 +02:00
Host: PickFirstAvailable(
cli.Host,
func() (string, bool) { return cliUrlParts.Host, cliUrlParts.Host != EmptyString },
env.Host,
func() (string, bool) { return envUrlParts.Host, envUrlParts.Host != EmptyString },
),
2025-03-15 13:02:47 +02:00
Port: PickFirstAvailable(
cli.Port,
func() (string, bool) { return cliUrlParts.Port, cliUrlParts.Port != EmptyString },
env.Port,
func() (string, bool) { return envUrlParts.Port, envUrlParts.Port != EmptyString },
),
2025-03-15 13:02:47 +02:00
Segments: PickFirstAvailable(
cli.Segments,
func() ([]string, bool) { return cliUrlParts.Segments, cliUrlParts.Segments != nil },
env.Segments,
func() ([]string, bool) { return envUrlParts.Segments, envUrlParts.Segments != nil },
),
2025-03-15 13:02:47 +02:00
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)
}
2025-03-15 19:03:22 +02:00
migrationPhase, migrationScript, _ := determineMigrationPhaseAndScript(cli)
2025-03-15 13:02:47 +02:00
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,
}
}
2025-03-15 13:02:47 +02:00
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
}
}
2025-03-15 13:02:47 +02:00
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
}