Documentation
¶
Overview ¶
Package dmorph provides a simple database migration framework.
Index ¶
- Constants
- Variables
- func Run(ctx context.Context, db *sql.DB, options ...MorphOption) error
- func WithGroupName(groupName string) func(*Morpher) error
- func WithMigrationKeyProperties(keyProp MigrationKeyProperties) func(*Morpher) error
- func WithTableName(tableName string) func(*Morpher) error
- type Dialect
- type FileMigration
- type Migration
- type MigrationKeyProperties
- type MorphOption
- func WithDialect(dialect Dialect) MorphOption
- func WithLog(log *slog.Logger) MorphOption
- func WithMigrationFromFile(name string) MorphOption
- func WithMigrationFromFileFS(name string, dir fs.FS) MorphOption
- func WithMigrations(migrations ...Migration) MorphOption
- func WithMigrationsFromFS(d fs.FS) MorphOption
- type Morpher
- type NamedParamsDialect
- func (b NamedParamsDialect) AppliedMigrations(ctx context.Context, db *sql.DB, tableName string, groupName string) ([]string, error)
- func (b NamedParamsDialect) EnsureMigrationTableExists(ctx context.Context, db *sql.DB, tableName string) error
- func (b NamedParamsDialect) RegisterMigration(ctx context.Context, tx *sql.Tx, id string, tableName string, groupName string) error
- type NumberedParamsDialect
- func (b NumberedParamsDialect) AppliedMigrations(ctx context.Context, db *sql.DB, tableName string, groupName string) ([]string, error)
- func (b NumberedParamsDialect) EnsureMigrationTableExists(ctx context.Context, db *sql.DB, tableName string) error
- func (b NumberedParamsDialect) RegisterMigration(ctx context.Context, tx *sql.Tx, id string, tableName string, groupName string) error
- type ParamName
Constants ¶
const ( // MigrationTableName is the default name for the migration management table in the database. MigrationTableName = "migrations" // MigrationGroupName is the default name for the migration group. MigrationGroupName = "default" )
Variables ¶
var ( // ValidTableNameRex is the regular expression used to check if a given migration table name is valid. ValidTableNameRex = regexp.MustCompile("^[a-zA-Z0-9_]+$") // ErrMigrationKeyFormat is returned when a migration key does not match the expected format. ErrMigrationKeyFormat = errors.New("migration key format invalid") // same (order of) applied migrations. Applying unrelated migrations could severely harm the database. ErrMigrationsUnrelated = errors.New("migrations unrelated") // ErrMigrationsUnsorted indicates that the already applied migrations were not registered in the order // (using the timestamp) that they should have been registered (using their id). ErrMigrationsUnsorted = errors.New("migrations unsorted") // ErrNoDialect signals that no dialect for the database operations was chosen. ErrNoDialect = errors.New("no dialect") // ErrNoMigrations signals that no migrations were chosen to be applied. ErrNoMigrations = errors.New("no migrations") // ErrNoMigrationTable occurs if there is no migration table present. ErrNoMigrationTable = errors.New("no migration table") // ErrNoMigrationGroup occurs if there is no migration group present. ErrNoMigrationGroup = errors.New("no migration group") // ErrMigrationTableNameInvalid occurs if the migration table does not adhere to ValidTableNameRex. ErrMigrationTableNameInvalid = errors.New("invalid migration table name") // ErrMigrationGroupNameInvalid occurs if the migration group name is empty. ErrMigrationGroupNameInvalid = errors.New("invalid migration group name") // ErrParamNameInvalid occurs if the param name is invalid. ErrParamNameInvalid = errors.New("invalid param name") // ErrMigrationsTooOld signals that the migrations to be applied are older than the migrations that are already // present in the database. This error can occur when an older version of the application is started using a database // used already by a newer version of the application. ErrMigrationsTooOld = errors.New("migrations too old") )
Functions ¶
func Run ¶
Run is a convenience function to easily get the migration job done. For more control use the Morpher directly.
func WithGroupName ¶
WithGroupName sets the migration group name on the provided Morpher instance. If not supplied, the default MigrationGroupName is used instead.
func WithMigrationKeyProperties ¶
func WithMigrationKeyProperties(keyProp MigrationKeyProperties) func(*Morpher) error
WithMigrationKeyProperties sets the migration key comparison properties for a Morpher instance.
func WithTableName ¶
WithTableName sets the migration table name to the given one. If not supplied, the default MigrationTableName is used instead.
Types ¶
type Dialect ¶
type Dialect interface {
EnsureMigrationTableExists(ctx context.Context, db *sql.DB, tableName string) error
AppliedMigrations(ctx context.Context, db *sql.DB, tableName string, groupName string) ([]string, error)
RegisterMigration(ctx context.Context, tx *sql.Tx, id string, tableName string, groupName string) error
}
Dialect is an interface describing the functionalities needed to manage migrations inside a database.
type FileMigration ¶
FileMigration implements the Migration interface. It helps to apply migrations from a file or fs.FS.
func (FileMigration) Key ¶
func (f FileMigration) Key() string
Key returns the key of the migration to register in the migration table.
type Migration ¶
type Migration interface {
Key() string // identifier, used for ordering
Migrate(ctx context.Context, tx *sql.Tx) error // migration functionality
}
Migration is an interface to provide abstract information about the migration at hand.
type MigrationKeyProperties ¶
type MigrationKeyProperties struct {
MigrationOrder func(m, n Migration) int
MigrationKeyOrder func(m, n string) int
MigrationKeyValid func(m string) bool
}
MigrationKeyProperties defines the properties and functions for managing migration key behaviors.
func MigrationKeyAlphabetical ¶
func MigrationKeyAlphabetical() MigrationKeyProperties
MigrationKeyAlphabetical returns MigrationKeyProperties configured for alphabetical sorting of migration keys.
func MigrationKeySemVerPrefix ¶
func MigrationKeySemVerPrefix() MigrationKeyProperties
MigrationKeySemVerPrefix returns a MigrationKeyProperties object configured for semantic version prefix-based operations.
type MorphOption ¶
MorphOption is the type used for functional options.
func WithDialect ¶
func WithDialect(dialect Dialect) MorphOption
WithDialect sets the vendor-specific database dialect to be used.
func WithLog ¶
func WithLog(log *slog.Logger) MorphOption
WithLog sets the logger that is to be used. If none is supplied, the default logger is used instead.
func WithMigrationFromFile ¶
func WithMigrationFromFile(name string) MorphOption
WithMigrationFromFile generates a FileMigration that will run the content of the given file.
func WithMigrationFromFileFS ¶
func WithMigrationFromFileFS(name string, dir fs.FS) MorphOption
WithMigrationFromFileFS generates a FileMigration that will run the content of the given file from the given filesystem.
func WithMigrations ¶
func WithMigrations(migrations ...Migration) MorphOption
WithMigrations adds the given migrations to be executed.
func WithMigrationsFromFS ¶
func WithMigrationsFromFS(d fs.FS) MorphOption
WithMigrationsFromFS generates a FileMigration that will run all migration scripts of the files in the given filesystem.
type Morpher ¶
type Morpher struct {
Dialect Dialect // database vendor specific dialect
Migrations []Migration // migrations to be applied
TableName string // table name for migration management
GroupName string // name of the migration group
KeyProp MigrationKeyProperties // migration comparison mode
Log *slog.Logger // logger to be used
}
Morpher contains all the required information to run a given set of database migrations on a database.
func NewMorpher ¶
func NewMorpher(options ...MorphOption) (*Morpher, error)
NewMorpher creates a new Morpher configuring it with the given options. It ensures that the newly created Morpher has migrations and a database dialect configured. If no migration table name is given, the default MigrationTableName is used instead.
func (*Morpher) IsValid ¶
IsValid checks if the Morpher contains all the required information to run.
func (*Morpher) Run ¶
Run runs the configured Morpher on the given database. If the migrations already applied to the database are a superset of the migrations the Morpher would apply, ErrMigrationsTooOld is returned. Run will run each migration in a separate transaction, with the last step to register the migration in the migration table.
type NamedParamsDialect ¶
type NamedParamsDialect struct {
CreateTemplate string // statement ensuring the existence of the migration table
AppliedTemplate string // statement getting applied migrations ordered by application date
RegisterTemplate string // statement registering a migration
}
NamedParamsDialect is a convenience type for databases that manage the necessary operations solely using queries. Defining the CreateTemplate, AppliedTemplate and RegisterTemplate enables the NamedParamsDialect to perform all the necessary operations to fulfill the Dialect interface.
func DialectCSVQ ¶
func DialectCSVQ() NamedParamsDialect
DialectCSVQ returns a Dialect configured for CSVQ databases.
func DialectDB2 ¶
func DialectDB2() NamedParamsDialect
DialectDB2 returns a Dialect configured for DB2 databases.
func DialectMSSQL ¶
func DialectMSSQL() NamedParamsDialect
DialectMSSQL returns a Dialect configured for Microsoft SQL Server databases.
func DialectOracle ¶
func DialectOracle() NamedParamsDialect
DialectOracle returns a Dialect configured for Oracle Database.
func DialectPostgres ¶
func DialectPostgres() NamedParamsDialect
DialectPostgres returns a Dialect configured for Postgres databases.
func DialectSQLite ¶
func DialectSQLite() NamedParamsDialect
DialectSQLite returns a Dialect configured for SQLite databases.
func (NamedParamsDialect) AppliedMigrations ¶
func (b NamedParamsDialect) AppliedMigrations( ctx context.Context, db *sql.DB, tableName string, groupName string) ([]string, error)
AppliedMigrations gets the already applied migrations from the database, ordered by application date.
func (NamedParamsDialect) EnsureMigrationTableExists ¶
func (b NamedParamsDialect) EnsureMigrationTableExists(ctx context.Context, db *sql.DB, tableName string) error
EnsureMigrationTableExists ensures that the migration table, saving the applied migrations ids, exists.
type NumberedParamsDialect ¶
type NumberedParamsDialect struct {
NamedParamsDialect
AppliedMigrationsParamsOrder []ParamName // defines the order of parameters for retrieving applied migrations.
RegisterMigrationParamsOrder []ParamName // defines the order of parameters for registering a migration.
}
NumberedParamsDialect extends NamedParamsDialect to support positional parameterized SQL queries.
func DialectMySQL ¶
func DialectMySQL() NumberedParamsDialect
DialectMySQL returns a Dialect configured for MySQL databases.
func DialectSQLiteNumbered ¶
func DialectSQLiteNumbered() NumberedParamsDialect
DialectSQLiteNumbered returns a Dialect configured for SQLite databases with numbered parameters. This is mainly used for tests, but nothing speaks against it being used otherwise.
func (NumberedParamsDialect) AppliedMigrations ¶
func (b NumberedParamsDialect) AppliedMigrations( ctx context.Context, db *sql.DB, tableName string, groupName string) ([]string, error)
AppliedMigrations gets the already applied migrations from the database, ordered by application date.
func (NumberedParamsDialect) EnsureMigrationTableExists ¶
func (b NumberedParamsDialect) EnsureMigrationTableExists(ctx context.Context, db *sql.DB, tableName string) error
EnsureMigrationTableExists ensures that the migration table, saving the applied migrations ids, exists.