Documentation
¶
Overview ¶
Package migrate provides a database-agnostic migration system with multi-module support, dependency ordering, and distributed locking.
Migrations are Go functions (not SQL files). Any Go module can register migrations into a shared, ordered, dependency-aware migration plan. Forge extensions ship their own migrations that compose with the host app.
Index ¶
- Constants
- Variables
- func DriverNameOf(exec Executor) (string, bool)
- func ExecutorAs[T any](exec Executor) (T, bool)
- func Executors() []string
- func IsLockError(err error) bool
- func MigrationLockTableSchema() string
- func MigrationTableSchema() string
- func RegisterExecutor(driverName string, factory ExecutorFactory)
- func RegisterRenderer(driverName string, r Renderer)
- func Unsupported(driverName, feature string) error
- type Action
- type AlterAction
- type AlterKind
- type AlterTable
- type AlterTableQuery
- func (q *AlterTableQuery) AddCheck(sql string) *AlterTableQuery
- func (q *AlterTableQuery) AddColumn(name string, typ ColumnType, opts ...ColumnOption) *AlterTableQuery
- func (q *AlterTableQuery) AddForeignKey(cols ...string) *AlterTableQuery
- func (q *AlterTableQuery) AddPrimaryKey(cols ...string) *AlterTableQuery
- func (q *AlterTableQuery) AddUnique(cols ...string) *AlterTableQuery
- func (q *AlterTableQuery) Cascade() *AlterTableQuery
- func (q *AlterTableQuery) DropColumn(name string) *AlterTableQuery
- func (q *AlterTableQuery) DropConstraint(name string) *AlterTableQuery
- func (q *AlterTableQuery) DropDefault(col string) *AlterTableQuery
- func (q *AlterTableQuery) DropNotNull(col string) *AlterTableQuery
- func (q *AlterTableQuery) Exec(ctx context.Context) error
- func (q *AlterTableQuery) IfExists() *AlterTableQuery
- func (q *AlterTableQuery) IfNotExists() *AlterTableQuery
- func (q *AlterTableQuery) Named(name string) *AlterTableQuery
- func (q *AlterTableQuery) OnDelete(a Action) *AlterTableQuery
- func (q *AlterTableQuery) Operation() (*AlterTable, error)
- func (q *AlterTableQuery) References(table string, cols ...string) *AlterTableQuery
- func (q *AlterTableQuery) RenameColumn(from, to string) *AlterTableQuery
- func (q *AlterTableQuery) RenameTo(name string) *AlterTableQuery
- func (q *AlterTableQuery) SetDefault(col string, value any) *AlterTableQuery
- func (q *AlterTableQuery) SetDefaultExpr(col, sql string) *AlterTableQuery
- func (q *AlterTableQuery) SetNotNull(col string) *AlterTableQuery
- func (q *AlterTableQuery) SetType(col string, typ ColumnType) *AlterTableQuery
- func (q *AlterTableQuery) Using(sql string) *AlterTableQuery
- type AppliedMigration
- type Column
- type ColumnOption
- func Check(sql string) ColumnOption
- func Default(value any) ColumnOption
- func DefaultExpr(sql string) ColumnOption
- func GeneratedAs(sql string) ColumnOption
- func Identity() ColumnOption
- func NotNull() ColumnOption
- func OnDelete(a Action) ColumnOption
- func PrimaryKey() ColumnOption
- func References(table string, columns ...string) ColumnOption
- func Unique() ColumnOption
- type ColumnType
- type Constraint
- type ConstraintKind
- type CreateIndex
- type CreateIndexQuery
- func (q *CreateIndexQuery) ColumnDesc(name string) *CreateIndexQuery
- func (q *CreateIndexQuery) ColumnExpr(sql string) *CreateIndexQuery
- func (q *CreateIndexQuery) Columns(names ...string) *CreateIndexQuery
- func (q *CreateIndexQuery) Concurrently() *CreateIndexQuery
- func (q *CreateIndexQuery) Exec(ctx context.Context) error
- func (q *CreateIndexQuery) Filter(doc any) *CreateIndexQuery
- func (q *CreateIndexQuery) IfNotExists() *CreateIndexQuery
- func (q *CreateIndexQuery) Include(cols ...string) *CreateIndexQuery
- func (q *CreateIndexQuery) On(table string) *CreateIndexQuery
- func (q *CreateIndexQuery) Operation() (*CreateIndex, error)
- func (q *CreateIndexQuery) Unique() *CreateIndexQuery
- func (q *CreateIndexQuery) Using(method string) *CreateIndexQuery
- func (q *CreateIndexQuery) Where(sql string) *CreateIndexQuery
- func (q *CreateIndexQuery) With(opts ...any) *CreateIndexQuery
- type CreateTable
- type CreateTableQuery
- func (q *CreateTableQuery) Check(expr string) *CreateTableQuery
- func (q *CreateTableQuery) Column(name string, typ ColumnType, opts ...ColumnOption) *CreateTableQuery
- func (q *CreateTableQuery) Exec(ctx context.Context) error
- func (q *CreateTableQuery) ForeignKey(cols ...string) *CreateTableQuery
- func (q *CreateTableQuery) IfNotExists() *CreateTableQuery
- func (q *CreateTableQuery) Model(model any) *CreateTableQuery
- func (q *CreateTableQuery) Named(name string) *CreateTableQuery
- func (q *CreateTableQuery) OnDelete(a Action) *CreateTableQuery
- func (q *CreateTableQuery) Operation() (*CreateTable, error)
- func (q *CreateTableQuery) PrimaryKey(cols ...string) *CreateTableQuery
- func (q *CreateTableQuery) References(table string, cols ...string) *CreateTableQuery
- func (q *CreateTableQuery) Unique(cols ...string) *CreateTableQuery
- func (q *CreateTableQuery) With(opts ...any) *CreateTableQuery
- type DB
- func (db *DB) Apply(ctx context.Context, op Operation) error
- func (db *DB) Dialect() string
- func (db *DB) Exec(ctx context.Context, query string, args ...any) (driver.Result, error)
- func (db *DB) Executor() Executor
- func (db *DB) NewAlterTable(table string) *AlterTableQuery
- func (db *DB) NewCreateIndex(name string) *CreateIndexQuery
- func (db *DB) NewCreateTable(table string) *CreateTableQuery
- func (db *DB) NewDropIndex(name string) *DropIndexQuery
- func (db *DB) NewDropTable(table string) *DropTableQuery
- func (db *DB) Query(ctx context.Context, query string, args ...any) (driver.Rows, error)
- type DefaultValue
- type DriverNamer
- type DropIndex
- type DropIndexQuery
- func (q *DropIndexQuery) Cascade() *DropIndexQuery
- func (q *DropIndexQuery) Concurrently() *DropIndexQuery
- func (q *DropIndexQuery) Exec(ctx context.Context) error
- func (q *DropIndexQuery) IfExists() *DropIndexQuery
- func (q *DropIndexQuery) On(table string) *DropIndexQuery
- func (q *DropIndexQuery) Operation() (*DropIndex, error)
- type DropTable
- type DropTableQuery
- type Executor
- type ExecutorFactory
- type Func
- type Group
- type GroupOption
- type GroupStatus
- type IndexColumn
- type LockInfo
- type LockInspector
- type MigrateFunc
- type MigrateResult
- type Migration
- type MigrationRegistry
- type MigrationStatus
- type Operation
- type Option
- type Orchestrator
- type Reference
- type Renderer
- type TxExecutor
- type TypeKind
- type Unwrapper
Constants ¶
const ( MigrationTable = "grove_migrations" MigrationLockTable = "grove_migration_locks" )
Schema constants for the migration tracking tables.
const DefaultLockTimeout = 5 * time.Minute
DefaultLockTimeout is the default maximum time Migrate/Rollback will wait to acquire the migration lock before giving up. Raised from the original 30s so that several extensions migrating the same database in one process serialize and wait instead of failing the boot.
Variables ¶
var ( Text = ColumnType{Kind: KindText} SmallInt = ColumnType{Kind: KindSmallInt} Integer = ColumnType{Kind: KindInteger} BigInt = ColumnType{Kind: KindBigInt} BigSerial = ColumnType{Kind: KindBigSerial} Boolean = ColumnType{Kind: KindBoolean} Timestamp = ColumnType{Kind: KindTimestamp} Date = ColumnType{Kind: KindDate} JSON = ColumnType{Kind: KindJSON} UUID = ColumnType{Kind: KindUUID} Bytes = ColumnType{Kind: KindBytes} Float = ColumnType{Kind: KindFloat} )
The portable types.
var DefaultRegistry = NewMigrationRegistry()
DefaultRegistry is the global migration registry. Modules register their groups here via init() functions.
var ErrInvalidOperation = errors.New("migrate: invalid schema operation")
ErrInvalidOperation is wrapped by every error a schema builder reports for a misused chain or an operation that can't be rendered.
var ErrLockHeld = errors.New("migrate: lock is held by another process")
ErrLockHeld is returned when a migration lock is already held.
var ErrSchemaUnsupported = errors.New("migrate: schema operation not supported")
ErrSchemaUnsupported is wrapped by the error a driver returns when it can't carry out a schema operation, or has no schema renderer at all.
var ErrTxUnsupported = errors.New("migrate: executor cannot run this migration in a transaction")
ErrTxUnsupported is what TxExecutor.BeginTx returns when the executor can't run the migration in a transaction. It isn't a failure: the migration runs plain, as it would on an executor without TxExecutor.
var ErrUnknownDriver = errors.New("migrate: cannot tell which driver this executor runs on")
ErrUnknownDriver is wrapped by the error a builder returns when it can't tell which driver its executor runs on.
Functions ¶
func DriverNameOf ¶ added in v1.10.0
DriverNameOf returns the driver name of exec, following Unwrapper through any wrappers until an executor implements DriverNamer. The bool is false when none does.
func ExecutorAs ¶ added in v1.10.0
ExecutorAs finds the first executor in exec's wrapper chain that is a T, following Unwrapper. A driver's own helpers use it to reach their concrete executor even when a test wrapper sits in front.
func Executors ¶
func Executors() []string
Executors returns the names of all registered executor factories.
func IsLockError ¶
IsLockError returns true if the error indicates a lock conflict.
func MigrationLockTableSchema ¶
func MigrationLockTableSchema() string
MigrationLockTableSchema returns the CREATE TABLE SQL for the lock table.
func MigrationTableSchema ¶
func MigrationTableSchema() string
MigrationTableSchema returns the CREATE TABLE SQL for the migration tracking table.
func RegisterExecutor ¶
func RegisterExecutor(driverName string, factory ExecutorFactory)
RegisterExecutor registers a migration executor factory for a given driver name. It is typically called from a driver's migrate package init() function for auto-registration, or explicitly by user code during setup.
Subsequent calls with the same name overwrite the previous registration.
Auto-registration example (in pgmigrate package):
func init() {
migrate.RegisterExecutor("pg", func(drv any) migrate.Executor {
return New(drv.(driver.Driver))
})
}
Explicit registration example:
migrate.RegisterExecutor("pg", func(drv any) migrate.Executor {
return pgmigrate.New(drv.(driver.Driver))
})
func RegisterRenderer ¶ added in v1.10.0
RegisterRenderer registers the schema renderer for a driver name, the same name the driver's executor reports through DriverNamer. A driver's migrate package usually calls it from init, next to RegisterExecutor.
Subsequent calls with the same name overwrite the previous registration, and a nil renderer counts as none registered.
func Unsupported ¶ added in v1.10.0
Unsupported reports that driverName can't do feature. The error wraps ErrSchemaUnsupported, so callers match it with errors.Is.
Types ¶
type AlterAction ¶ added in v1.10.0
type AlterAction struct {
Kind AlterKind
Column Column
Name string
NewName string
Default *DefaultValue
Type ColumnType
// Using is the expression that converts existing values for AlterSetType.
Using string
Constraint Constraint
IfExists bool
IfNotExists bool
Cascade bool
}
AlterAction is one change inside an AlterTable. Which fields matter depends on Kind:
- AlterAddColumn uses Column, and IfNotExists.
- AlterDropColumn uses Name, IfExists and Cascade.
- AlterSetNotNull, AlterDropNotNull and AlterDropDefault use Name, the column.
- AlterSetDefault uses Name and Default.
- AlterSetType uses Name, Type and optionally Using.
- AlterAddConstraint uses Constraint.
- AlterDropConstraint uses Name, the constraint, with IfExists and Cascade.
- AlterRenameColumn renames Name to NewName.
- AlterRenameTo uses NewName, the table's new name.
type AlterTable ¶ added in v1.10.0
type AlterTable struct {
Table string
Actions []AlterAction
}
AlterTable changes an existing table. Actions run in the order written.
type AlterTableQuery ¶ added in v1.10.0
type AlterTableQuery struct {
// contains filtered or unexported fields
}
AlterTableQuery builds an AlterTable. Each call adds one action, and the modifiers (IfExists, Using, Named and so on) apply to the action before them.
func (*AlterTableQuery) AddCheck ¶ added in v1.10.0
func (q *AlterTableQuery) AddCheck(sql string) *AlterTableQuery
AddCheck adds a CHECK constraint.
func (*AlterTableQuery) AddColumn ¶ added in v1.10.0
func (q *AlterTableQuery) AddColumn(name string, typ ColumnType, opts ...ColumnOption) *AlterTableQuery
AddColumn adds a column.
func (*AlterTableQuery) AddForeignKey ¶ added in v1.10.0
func (q *AlterTableQuery) AddForeignKey(cols ...string) *AlterTableQuery
AddForeignKey starts a foreign key over cols. Follow it with References, and optionally OnDelete.
func (*AlterTableQuery) AddPrimaryKey ¶ added in v1.10.0
func (q *AlterTableQuery) AddPrimaryKey(cols ...string) *AlterTableQuery
AddPrimaryKey adds a primary key over cols.
func (*AlterTableQuery) AddUnique ¶ added in v1.10.0
func (q *AlterTableQuery) AddUnique(cols ...string) *AlterTableQuery
AddUnique adds a UNIQUE constraint over cols.
func (*AlterTableQuery) Cascade ¶ added in v1.10.0
func (q *AlterTableQuery) Cascade() *AlterTableQuery
Cascade makes the DropColumn or DropConstraint before it drop whatever depends on the target too.
func (*AlterTableQuery) DropColumn ¶ added in v1.10.0
func (q *AlterTableQuery) DropColumn(name string) *AlterTableQuery
DropColumn drops a column.
func (*AlterTableQuery) DropConstraint ¶ added in v1.10.0
func (q *AlterTableQuery) DropConstraint(name string) *AlterTableQuery
DropConstraint drops the constraint called name.
func (*AlterTableQuery) DropDefault ¶ added in v1.10.0
func (q *AlterTableQuery) DropDefault(col string) *AlterTableQuery
DropDefault removes the default on col.
func (*AlterTableQuery) DropNotNull ¶ added in v1.10.0
func (q *AlterTableQuery) DropNotNull(col string) *AlterTableQuery
DropNotNull allows NULL in col again.
func (*AlterTableQuery) Exec ¶ added in v1.10.0
func (q *AlterTableQuery) Exec(ctx context.Context) error
Exec checks the chain, then has the renderer for the executor's driver apply it. A misused chain returns its error without touching the executor. An executor whose driver can't be told returns ErrUnknownDriver, and a driver with no renderer returns ErrSchemaUnsupported.
func (*AlterTableQuery) IfExists ¶ added in v1.10.0
func (q *AlterTableQuery) IfExists() *AlterTableQuery
IfExists makes the DropColumn or DropConstraint before it skip a missing target.
func (*AlterTableQuery) IfNotExists ¶ added in v1.10.0
func (q *AlterTableQuery) IfNotExists() *AlterTableQuery
IfNotExists makes the AddColumn before it skip a column that is already there.
func (*AlterTableQuery) Named ¶ added in v1.10.0
func (q *AlterTableQuery) Named(name string) *AlterTableQuery
Named names the constraint you just added. Left unnamed, the driver picks a name.
func (*AlterTableQuery) OnDelete ¶ added in v1.10.0
func (q *AlterTableQuery) OnDelete(a Action) *AlterTableQuery
OnDelete sets the referential action of the foreign key you just added. It has to follow References.
func (*AlterTableQuery) Operation ¶ added in v1.10.0
func (q *AlterTableQuery) Operation() (*AlterTable, error)
Operation returns what the chain describes. A misused chain returns its first mistake, wrapped in ErrInvalidOperation.
func (*AlterTableQuery) References ¶ added in v1.10.0
func (q *AlterTableQuery) References(table string, cols ...string) *AlterTableQuery
References sets the target of the foreign key you just added.
func (*AlterTableQuery) RenameColumn ¶ added in v1.10.0
func (q *AlterTableQuery) RenameColumn(from, to string) *AlterTableQuery
RenameColumn renames a column.
func (*AlterTableQuery) RenameTo ¶ added in v1.10.0
func (q *AlterTableQuery) RenameTo(name string) *AlterTableQuery
RenameTo renames the table.
func (*AlterTableQuery) SetDefault ¶ added in v1.10.0
func (q *AlterTableQuery) SetDefault(col string, value any) *AlterTableQuery
SetDefault sets a literal default on col. A nil value means DEFAULT NULL.
func (*AlterTableQuery) SetDefaultExpr ¶ added in v1.10.0
func (q *AlterTableQuery) SetDefaultExpr(col, sql string) *AlterTableQuery
SetDefaultExpr sets a default on col from a SQL expression.
func (*AlterTableQuery) SetNotNull ¶ added in v1.10.0
func (q *AlterTableQuery) SetNotNull(col string) *AlterTableQuery
SetNotNull forbids NULL in col.
func (*AlterTableQuery) SetType ¶ added in v1.10.0
func (q *AlterTableQuery) SetType(col string, typ ColumnType) *AlterTableQuery
SetType changes the type of col. Follow it with Using when existing values need converting.
func (*AlterTableQuery) Using ¶ added in v1.10.0
func (q *AlterTableQuery) Using(sql string) *AlterTableQuery
Using sets the expression that converts existing values for the SetType before it.
type AppliedMigration ¶
type AppliedMigration struct {
ID int64
Version string
Name string
Group string
MigratedAt string // ISO 8601 timestamp
}
AppliedMigration records that a migration has been applied.
type Column ¶ added in v1.10.0
type Column struct {
Name string
Type ColumnType
NotNull bool
Default *DefaultValue
PrimaryKey bool
Unique bool
// Check is a SQL expression for a column-level CHECK constraint.
Check string
References *Reference
// Identity makes the column GENERATED ALWAYS AS IDENTITY.
Identity bool
// Generated is a SQL expression for a stored generated column.
Generated string
}
Column describes one column of a table.
type ColumnOption ¶ added in v1.10.0
ColumnOption adjusts a column as a builder adds it. The builder wraps an error from an option in ErrInvalidOperation and the column's name, so an option returns a plain error.
func Check ¶ added in v1.10.0
func Check(sql string) ColumnOption
Check adds a column-level CHECK constraint.
func Default ¶ added in v1.10.0
func Default(value any) ColumnOption
Default sets a literal default. A nil value means DEFAULT NULL.
func DefaultExpr ¶ added in v1.10.0
func DefaultExpr(sql string) ColumnOption
DefaultExpr sets a default from a SQL expression such as now(), spliced in as written.
func GeneratedAs ¶ added in v1.10.0
func GeneratedAs(sql string) ColumnOption
GeneratedAs makes the column a stored generated column computed from sql.
func Identity ¶ added in v1.10.0
func Identity() ColumnOption
Identity makes the column GENERATED ALWAYS AS IDENTITY.
func OnDelete ¶ added in v1.10.0
func OnDelete(a Action) ColumnOption
OnDelete sets what happens to this row when the referenced row is deleted. It has to come after References.
func PrimaryKey ¶ added in v1.10.0
func PrimaryKey() ColumnOption
PrimaryKey makes the column the table's primary key. Use the table-level PrimaryKey for a composite one.
func References ¶ added in v1.10.0
func References(table string, columns ...string) ColumnOption
References makes the column a foreign key to table. A column-level reference names exactly one column. Use ForeignKey on the table for a composite key.
func Unique ¶ added in v1.10.0
func Unique() ColumnOption
Unique adds a UNIQUE constraint on this column alone.
type ColumnType ¶ added in v1.10.0
type ColumnType struct {
Kind TypeKind
// Raw is the type name passed straight to the driver when Kind is KindRaw.
Raw string
// Precision and Scale apply to KindNumeric. Both zero means no limits.
Precision, Scale int
// Elem is the element type when Kind is KindArray.
Elem *ColumnType
}
ColumnType is a driver-agnostic column type. Use the package variables (Text, Integer and friends), Numeric, ArrayOf, or Type for anything a driver names but grove doesn't.
func ArrayOf ¶ added in v1.10.0
func ArrayOf(elem ColumnType) ColumnType
ArrayOf is an array of elem.
func Numeric ¶ added in v1.10.0
func Numeric(precision, scale int) ColumnType
Numeric is an exact decimal with the given precision and scale.
func Type ¶ added in v1.10.0
func Type(raw string) ColumnType
Type passes raw to the driver untouched, for types with no portable name such as Type("INET").
type Constraint ¶ added in v1.10.0
type Constraint struct {
Kind ConstraintKind
Name string
Columns []string
Check string
References *Reference
}
Constraint is a table-level constraint. Name is empty when the driver should pick one.
type ConstraintKind ¶ added in v1.10.0
type ConstraintKind int
ConstraintKind says what a Constraint enforces.
const ( PrimaryKeyConstraint ConstraintKind = iota + 1 UniqueConstraint CheckConstraint ForeignKeyConstraint )
The table constraints a builder can declare.
type CreateIndex ¶ added in v1.10.0
type CreateIndex struct {
Name string
Table string
Columns []IndexColumn
Unique bool
IfNotExists bool
Concurrently bool
// Using is the access method, such as gin, on drivers that have one.
Using string
Include []string
// Where is a SQL predicate for a partial index.
Where string
// Filter is the document form of Where, for drivers that take one.
Filter any
// Options carries driver-specific settings. A driver rejects any value it
// doesn't recognise.
Options []any
}
CreateIndex creates an index.
type CreateIndexQuery ¶ added in v1.10.0
type CreateIndexQuery struct {
// contains filtered or unexported fields
}
CreateIndexQuery builds a CreateIndex.
func (*CreateIndexQuery) ColumnDesc ¶ added in v1.10.0
func (q *CreateIndexQuery) ColumnDesc(name string) *CreateIndexQuery
ColumnDesc adds a column sorted in descending order.
func (*CreateIndexQuery) ColumnExpr ¶ added in v1.10.0
func (q *CreateIndexQuery) ColumnExpr(sql string) *CreateIndexQuery
ColumnExpr adds a SQL expression such as lower(name) as an index key.
func (*CreateIndexQuery) Columns ¶ added in v1.10.0
func (q *CreateIndexQuery) Columns(names ...string) *CreateIndexQuery
Columns adds plain columns as index keys, in order.
func (*CreateIndexQuery) Concurrently ¶ added in v1.10.0
func (q *CreateIndexQuery) Concurrently() *CreateIndexQuery
Concurrently builds the index without blocking writes, on drivers that support it.
func (*CreateIndexQuery) Exec ¶ added in v1.10.0
func (q *CreateIndexQuery) Exec(ctx context.Context) error
Exec checks the chain, then has the renderer for the executor's driver apply it. A misused chain returns its error without touching the executor. An executor whose driver can't be told returns ErrUnknownDriver, and a driver with no renderer returns ErrSchemaUnsupported.
func (*CreateIndexQuery) Filter ¶ added in v1.10.0
func (q *CreateIndexQuery) Filter(doc any) *CreateIndexQuery
Filter is the document form of Where, for drivers that filter with a document, such as MongoDB's partialFilterExpression.
func (*CreateIndexQuery) IfNotExists ¶ added in v1.10.0
func (q *CreateIndexQuery) IfNotExists() *CreateIndexQuery
IfNotExists skips the statement when the index is already there.
func (*CreateIndexQuery) Include ¶ added in v1.10.0
func (q *CreateIndexQuery) Include(cols ...string) *CreateIndexQuery
Include adds non-key columns stored in the index.
func (*CreateIndexQuery) On ¶ added in v1.10.0
func (q *CreateIndexQuery) On(table string) *CreateIndexQuery
On sets the table the index covers.
func (*CreateIndexQuery) Operation ¶ added in v1.10.0
func (q *CreateIndexQuery) Operation() (*CreateIndex, error)
Operation returns what the chain describes. A misused chain returns its first mistake, wrapped in ErrInvalidOperation.
func (*CreateIndexQuery) Unique ¶ added in v1.10.0
func (q *CreateIndexQuery) Unique() *CreateIndexQuery
Unique makes the index enforce uniqueness.
func (*CreateIndexQuery) Using ¶ added in v1.10.0
func (q *CreateIndexQuery) Using(method string) *CreateIndexQuery
Using picks the index access method, such as gin.
func (*CreateIndexQuery) Where ¶ added in v1.10.0
func (q *CreateIndexQuery) Where(sql string) *CreateIndexQuery
Where makes the index partial, covering only rows that match the SQL predicate.
func (*CreateIndexQuery) With ¶ added in v1.10.0
func (q *CreateIndexQuery) With(opts ...any) *CreateIndexQuery
With passes driver-specific options. A driver returns an error for any option it doesn't recognise.
type CreateTable ¶ added in v1.10.0
type CreateTable struct {
Table string
IfNotExists bool
Columns []Column
Constraints []Constraint
// Model is a grove model to take the columns from instead of Columns.
Model any
// Options carries driver-specific settings, such as a Mongo collection
// option. A driver rejects any value it doesn't recognise.
Options []any
}
CreateTable creates a table, or a collection on drivers without tables.
Columns render in the order written, then Constraints in the order written, because a driver that names unnamed constraints derives the name from that order. A builder enforces this by rejecting a column declared after a table constraint, so the order you write is the order a driver sees. A builder never sets Model together with Columns or Constraints.
type CreateTableQuery ¶ added in v1.10.0
type CreateTableQuery struct {
// contains filtered or unexported fields
}
CreateTableQuery builds a CreateTable.
func (*CreateTableQuery) Check ¶ added in v1.10.0
func (q *CreateTableQuery) Check(expr string) *CreateTableQuery
Check adds a table-level CHECK constraint.
func (*CreateTableQuery) Column ¶ added in v1.10.0
func (q *CreateTableQuery) Column(name string, typ ColumnType, opts ...ColumnOption) *CreateTableQuery
Column adds a column. Columns render in the order you add them, and they all come before the table constraints. Declare every column first: a Column after PrimaryKey, Unique, Check or ForeignKey is a misuse, because the constraint modifiers (Named, References, OnDelete) bind to the last constraint and the written order would no longer be the rendered order.
func (*CreateTableQuery) Exec ¶ added in v1.10.0
func (q *CreateTableQuery) Exec(ctx context.Context) error
Exec checks the chain, then has the renderer for the executor's driver apply it. A misused chain returns its error without touching the executor. An executor whose driver can't be told returns ErrUnknownDriver, and a driver with no renderer returns ErrSchemaUnsupported.
func (*CreateTableQuery) ForeignKey ¶ added in v1.10.0
func (q *CreateTableQuery) ForeignKey(cols ...string) *CreateTableQuery
ForeignKey starts a foreign key over cols. Follow it with References, and optionally OnDelete.
func (*CreateTableQuery) IfNotExists ¶ added in v1.10.0
func (q *CreateTableQuery) IfNotExists() *CreateTableQuery
IfNotExists skips the statement when the table is already there.
func (*CreateTableQuery) Model ¶ added in v1.10.0
func (q *CreateTableQuery) Model(model any) *CreateTableQuery
Model takes the columns from a grove model instead of Column calls, for example Model((*User)(nil)). It can't be combined with columns or constraints.
func (*CreateTableQuery) Named ¶ added in v1.10.0
func (q *CreateTableQuery) Named(name string) *CreateTableQuery
Named names the constraint you just added. Left unnamed, the driver picks a name.
func (*CreateTableQuery) OnDelete ¶ added in v1.10.0
func (q *CreateTableQuery) OnDelete(a Action) *CreateTableQuery
OnDelete sets the referential action of the foreign key you just started. It has to follow References.
func (*CreateTableQuery) Operation ¶ added in v1.10.0
func (q *CreateTableQuery) Operation() (*CreateTable, error)
Operation returns what the chain describes. A misused chain returns its first mistake, wrapped in ErrInvalidOperation.
func (*CreateTableQuery) PrimaryKey ¶ added in v1.10.0
func (q *CreateTableQuery) PrimaryKey(cols ...string) *CreateTableQuery
PrimaryKey adds a table-level primary key over cols.
func (*CreateTableQuery) References ¶ added in v1.10.0
func (q *CreateTableQuery) References(table string, cols ...string) *CreateTableQuery
References sets the target of the foreign key you just started.
func (*CreateTableQuery) Unique ¶ added in v1.10.0
func (q *CreateTableQuery) Unique(cols ...string) *CreateTableQuery
Unique adds a table-level UNIQUE constraint over cols.
func (*CreateTableQuery) With ¶ added in v1.10.0
func (q *CreateTableQuery) With(opts ...any) *CreateTableQuery
With passes driver-specific options. A driver returns an error for any option it doesn't recognise.
type DB ¶ added in v1.10.0
type DB struct {
// contains filtered or unexported fields
}
DB is the handle a migration builds its schema through. It wraps an Executor, and the builders it hands out end in Exec, which looks up the renderer registered for the executor's driver and has it apply the operation. The same handle runs raw statements through Exec and Query for anything the builders don't cover.
func NewDB ¶ added in v1.10.0
NewDB wraps exec. Tests pass nil when they only inspect what a builder produces with Operation. Running a builder against a nil executor returns ErrUnknownDriver.
func (*DB) Apply ¶ added in v1.10.0
Apply hands op to the renderer registered for the executor's driver. The builders call it from Exec after checking the chain, so it validates nothing itself. The renderer gets the executor as the handle holds it, not the executor inside a wrapper, so a wrapper keeps seeing every statement.
func (*DB) Dialect ¶ added in v1.10.0
Dialect returns the name of the driver behind the executor, such as "pg" or "mongo", or "" when the executor and anything it wraps never name one.
func (*DB) Exec ¶ added in v1.10.0
Exec runs a statement that returns no rows, straight on the executor.
func (*DB) NewAlterTable ¶ added in v1.10.0
func (db *DB) NewAlterTable(table string) *AlterTableQuery
NewAlterTable starts an ALTER TABLE for table. Chain several actions and they run in order.
func (*DB) NewCreateIndex ¶ added in v1.10.0
func (db *DB) NewCreateIndex(name string) *CreateIndexQuery
NewCreateIndex starts a CREATE INDEX called name. It needs On and at least one column before it can run.
func (*DB) NewCreateTable ¶ added in v1.10.0
func (db *DB) NewCreateTable(table string) *CreateTableQuery
NewCreateTable starts a CREATE TABLE for table.
func (*DB) NewDropIndex ¶ added in v1.10.0
func (db *DB) NewDropIndex(name string) *DropIndexQuery
NewDropIndex starts a DROP INDEX for name.
func (*DB) NewDropTable ¶ added in v1.10.0
func (db *DB) NewDropTable(table string) *DropTableQuery
NewDropTable starts a DROP TABLE for table.
type DefaultValue ¶ added in v1.10.0
DefaultValue is a column default. A non-empty Expr is a SQL expression the driver splices in as written. Otherwise Value is a literal, and nil means NULL.
type DriverNamer ¶ added in v1.10.0
type DriverNamer interface {
DriverName() string
}
DriverNamer is implemented by an executor that knows which driver it runs on, such as "pg" or "mongo". It picks the renderer for that driver's schema operations.
type DropIndex ¶ added in v1.10.0
DropIndex drops an index. Table is needed only on drivers that scope indexes to a table or collection.
type DropIndexQuery ¶ added in v1.10.0
type DropIndexQuery struct {
// contains filtered or unexported fields
}
DropIndexQuery builds a DropIndex.
func (*DropIndexQuery) Cascade ¶ added in v1.10.0
func (q *DropIndexQuery) Cascade() *DropIndexQuery
Cascade drops whatever depends on the index too.
func (*DropIndexQuery) Concurrently ¶ added in v1.10.0
func (q *DropIndexQuery) Concurrently() *DropIndexQuery
Concurrently drops the index without blocking writes, on drivers that support it.
func (*DropIndexQuery) Exec ¶ added in v1.10.0
func (q *DropIndexQuery) Exec(ctx context.Context) error
Exec checks the chain, then has the renderer for the executor's driver apply it. A misused chain returns its error without touching the executor. An executor whose driver can't be told returns ErrUnknownDriver, and a driver with no renderer returns ErrSchemaUnsupported.
func (*DropIndexQuery) IfExists ¶ added in v1.10.0
func (q *DropIndexQuery) IfExists() *DropIndexQuery
IfExists skips the statement when the index is already gone.
func (*DropIndexQuery) On ¶ added in v1.10.0
func (q *DropIndexQuery) On(table string) *DropIndexQuery
On sets the table the index belongs to. Postgres doesn't need it, and MongoDB does.
func (*DropIndexQuery) Operation ¶ added in v1.10.0
func (q *DropIndexQuery) Operation() (*DropIndex, error)
Operation returns what the chain describes, or its first mistake wrapped in ErrInvalidOperation.
type DropTableQuery ¶ added in v1.10.0
type DropTableQuery struct {
// contains filtered or unexported fields
}
DropTableQuery builds a DropTable.
func (*DropTableQuery) Cascade ¶ added in v1.10.0
func (q *DropTableQuery) Cascade() *DropTableQuery
Cascade drops whatever depends on the table too.
func (*DropTableQuery) Exec ¶ added in v1.10.0
func (q *DropTableQuery) Exec(ctx context.Context) error
Exec checks the chain, then has the renderer for the executor's driver apply it. A misused chain returns its error without touching the executor. An executor whose driver can't be told returns ErrUnknownDriver, and a driver with no renderer returns ErrSchemaUnsupported.
func (*DropTableQuery) IfExists ¶ added in v1.10.0
func (q *DropTableQuery) IfExists() *DropTableQuery
IfExists skips the statement when the table is already gone.
func (*DropTableQuery) Operation ¶ added in v1.10.0
func (q *DropTableQuery) Operation() (*DropTable, error)
Operation returns what the chain describes, or its first mistake wrapped in ErrInvalidOperation.
type Executor ¶
type Executor interface {
// Exec executes a SQL statement that does not return rows.
Exec(ctx context.Context, query string, args ...any) (driver.Result, error)
// Query executes a SQL statement that returns rows.
Query(ctx context.Context, query string, args ...any) (driver.Rows, error)
// EnsureMigrationTable creates the migration tracking table if it doesn't exist.
EnsureMigrationTable(ctx context.Context) error
// EnsureLockTable creates the migration lock table if it doesn't exist.
EnsureLockTable(ctx context.Context) error
// AcquireLock attempts to acquire the distributed migration lock.
// Returns an error if the lock is held by another process.
AcquireLock(ctx context.Context, lockedBy string) error
// ReleaseLock releases the distributed migration lock.
ReleaseLock(ctx context.Context) error
// ListApplied returns all migrations that have been applied.
ListApplied(ctx context.Context) ([]*AppliedMigration, error)
// RecordApplied records that a migration was successfully applied.
RecordApplied(ctx context.Context, m *Migration) error
// RemoveApplied removes the record of an applied migration (for rollback).
RemoveApplied(ctx context.Context, m *Migration) error
}
Executor is the interface that driver-specific migration executors implement. It provides methods for running DDL/DML within migrations and managing the migration version table and lock.
func NewExecutorFor ¶
NewExecutorFor creates a migration Executor for the given driver using the registered factory. The driver must implement a Name() string method (satisfied by both grove.GroveDriver and driver.Driver). Returns an error if no factory is registered for the driver's name.
type ExecutorFactory ¶
ExecutorFactory is a function that creates a migration Executor from a driver. The driver parameter is typed as any to support both SQL-based drivers (driver.Driver) and non-SQL drivers (e.g., *mongodriver.MongoDB). Each factory performs its own type assertion on the driver.
type Func ¶ added in v1.10.0
Func is the body of a migration written against a DB. Up and down functions use it so they can reach the schema builders without caring which executor runs them.
type Group ¶
type Group struct {
// contains filtered or unexported fields
}
Group represents a collection of migrations owned by a module or extension. Each group has a unique name (e.g., "core", "forge.billing") and can declare dependencies on other groups.
func NewGroup ¶
func NewGroup(name string, opts ...GroupOption) *Group
NewGroup creates a new migration group with the given name and options.
var Migrations = migrate.NewGroup("core")
var Migrations = migrate.NewGroup("forge.billing", migrate.DependsOn("core"))
func (*Group) Add ¶ added in v1.10.0
Add registers a migration whose version and name come from the file that calls it, so the file name is the only place the version is written down. Call it from an init function in a file named <14 digit version>_<name>.go:
// 20240102030405_create_widgets.go
func init() {
Migrations.Add(
func(ctx context.Context, db *migrate.DB) error {
return db.NewCreateTable("widgets").
Column("id", migrate.Text, migrate.PrimaryKey()).
Exec(ctx)
},
func(ctx context.Context, db *migrate.DB) error {
return db.NewDropTable("widgets").Exec(ctx)
},
)
}
Add panics when the caller's file name doesn't fit that shape, or when the group already holds the version. An init that fails to register would otherwise leave a migration quietly missing from the plan.
func (*Group) DependsOnGroups ¶
DependsOnGroups returns the list of group names this group depends on.
func (*Group) Migrations ¶
Migrations returns a copy of the group's migrations sorted by version.
func (*Group) MustRegister ¶
MustRegister is like Register but panics on error.
type GroupOption ¶
type GroupOption func(*Group)
GroupOption configures a migration group.
func DependsOn ¶
func DependsOn(groups ...string) GroupOption
DependsOn declares that this group's migrations must run after the specified groups have completed.
type GroupStatus ¶
type GroupStatus struct {
Name string
Applied []*MigrationStatus
Pending []*MigrationStatus
}
GroupStatus describes the state of all migrations in a group.
type IndexColumn ¶ added in v1.10.0
IndexColumn is one key of an index: a column by Name, or an expression.
type LockInspector ¶
LockInspector is an optional capability: executors that can report who holds the migration lock implement it, letting the orchestrator produce a diagnosable error when the wait budget is exhausted.
type MigrateFunc ¶
type MigrateFunc func(ctx context.Context, exec Executor) error //nolint:revive // MigrateFunc is the established public API name
MigrateFunc is a function that performs a migration step. It receives a context and an Executor for running DDL/DML statements.
type MigrateResult ¶
type MigrateResult struct {
Applied []*Migration // Migrations that were applied
Rollback []*Migration // Migrations that were rolled back (for Rollback only)
}
MigrateResult holds the result of a Migrate or Rollback operation.
type Migration ¶
type Migration struct {
// Name is a human-readable identifier (e.g., "create_users").
Name string
// Version is a timestamp-based version string (e.g., "20240115120000").
// Migrations run in version order within dependency constraints.
Version string
// Group identifies the module/extension that owns this migration.
// Set automatically when registered with a Group.
Group string
// Up runs the forward migration.
Up MigrateFunc
// Down runs the rollback.
Down MigrateFunc
// Comment is an optional description.
Comment string
// Transactional makes the migrator run Up or Down and its applied record
// in one transaction when the executor supports it. Add and Define set
// it. Migrations registered as structs keep running without one.
Transactional bool
}
Migration represents a single versioned migration.
func Define ¶ added in v1.10.0
Define builds a migration from an up and a down function. It starts with Transactional on and then applies opts, so NoTransaction has the last word. Up and Down are left nil when the matching function is nil, which keeps the migrator's missing-Up check and the rollback-without-Down path working. Group.Register fills in Group.
type MigrationRegistry ¶
type MigrationRegistry struct {
// contains filtered or unexported fields
}
MigrationRegistry holds registered migration groups.
func NewMigrationRegistry ¶
func NewMigrationRegistry() *MigrationRegistry
NewMigrationRegistry creates an empty MigrationRegistry.
func (*MigrationRegistry) Groups ¶
func (r *MigrationRegistry) Groups() []*Group
Groups returns a copy of all registered migration groups.
func (*MigrationRegistry) Register ¶
func (r *MigrationRegistry) Register(groups ...*Group)
Register adds one or more migration groups to the registry.
type MigrationStatus ¶
type MigrationStatus struct {
Migration *Migration
Applied bool
AppliedAt string // empty if not applied
}
MigrationStatus describes the state of a single migration.
type Operation ¶ added in v1.10.0
type Operation interface {
// contains filtered or unexported methods
}
Operation is a schema change a builder produced and a driver renders. The concrete types are the five exported structs below, so a renderer switches on them. Nobody outside this package implements it.
type Option ¶ added in v1.10.0
type Option func(*Migration)
Option adjusts a migration built by Define or registered by Group.Add.
func NoTransaction ¶ added in v1.10.0
func NoTransaction() Option
NoTransaction opts a migration out of the transaction Add and Define give it by default. Use it for statements a transaction can't hold, such as CREATE INDEX CONCURRENTLY on Postgres.
type Orchestrator ¶
type Orchestrator struct {
// contains filtered or unexported fields
}
Orchestrator manages migration execution across multiple groups.
func NewOrchestrator ¶
func NewOrchestrator(executor Executor, groups ...*Group) *Orchestrator
NewOrchestrator creates a new migration orchestrator.
func (*Orchestrator) Migrate ¶
func (o *Orchestrator) Migrate(ctx context.Context) (*MigrateResult, error)
Migrate runs all pending migrations in dependency-resolved order.
Steps:
- Ensure migration and lock tables exist
- Acquire distributed lock
- Load already-applied migrations
- Topologically sort groups by dependencies
- Execute pending migrations in order, each in a transaction with its applied record when the migration is Transactional and the executor is a TxExecutor
- Release lock
func (*Orchestrator) Rollback ¶
func (o *Orchestrator) Rollback(ctx context.Context) (*MigrateResult, error)
Rollback rolls back the last batch of applied migrations (one per group, most recently applied first).
func (*Orchestrator) SetLockTimeout ¶
func (o *Orchestrator) SetLockTimeout(d time.Duration) *Orchestrator
SetLockTimeout overrides the lock-wait budget. 0 = wait until ctx deadline.
func (*Orchestrator) Status ¶
func (o *Orchestrator) Status(ctx context.Context) ([]*GroupStatus, error)
Status returns the status of all migrations across all groups.
type Reference ¶ added in v1.10.0
type Reference struct {
Table string
Columns []string
// OnDelete is empty when the driver's default applies.
OnDelete Action
}
Reference is the target of a foreign key.
type Renderer ¶ added in v1.10.0
Renderer turns schema operations into work on one driver. A driver's migrate package registers one with RegisterRenderer. Apply runs the work through exec, the executor the migration was handed, so a wrapper around it still sees every statement.
type TxExecutor ¶ added in v1.10.0
type TxExecutor interface {
// BeginTx opens the transaction. It returns [ErrTxUnsupported] when this
// executor can't hold one for the migration, and the orchestrator then runs
// the migration without it.
BeginTx(ctx context.Context) error
// CommitTx commits the transaction.
CommitTx(ctx context.Context) error
// RollbackTx abandons the transaction. The orchestrator also calls it
// after a failed CommitTx, so it has to tolerate a transaction that is
// already finished.
RollbackTx(ctx context.Context) error
}
TxExecutor is an optional interface an Executor implements so the orchestrator can run a migration and its applied record in one transaction. The orchestrator finds it with ExecutorAs, so a wrapper that has an Unwrap method keeps the transactions of the executor inside it, and executors that don't implement it keep working without one.
The orchestrator owns the transaction, and the executor holds its state on the connection that has the migration lock. BeginTx returns no handle: after it, every statement the migration runs through the executor, and the RecordApplied or RemoveApplied call that follows, must go through that transaction on that connection until CommitTx or RollbackTx.
type TypeKind ¶ added in v1.10.0
type TypeKind int
TypeKind says which portable type a ColumnType stands for.
type Unwrapper ¶ added in v1.10.0
type Unwrapper interface {
Unwrap() Executor
}
Unwrapper is implemented by an executor that wraps another one, such as a test double that counts statements. It lets DriverNameOf and ExecutorAs see through the wrapper to the executor inside.