Documentation
¶
Overview ¶
Package queen provides a database migration library for Go.
Queen allows you to define migrations in code (not separate files), supports both SQL and Go function migrations, and provides excellent testing helpers for validating your migrations.
Basic usage:
db, _ := sql.Open("postgres", "...")
driver := postgres.New(db)
q := queen.New(driver)
q.Add(queen.M{
Version: "001",
Name: "create_users",
UpSQL: "CREATE TABLE users (id SERIAL PRIMARY KEY)",
DownSQL: "DROP TABLE users",
})
if err := q.Up(context.Background()); err != nil {
log.Fatal(err)
}
Index ¶
- Variables
- type Applied
- type Config
- type Driver
- type M
- type Migration
- type MigrationError
- type MigrationFunc
- type MigrationStatus
- type Queen
- func (q *Queen) Add(m M) error
- func (q *Queen) Close() error
- func (q *Queen) Down(ctx context.Context, n int) error
- func (q *Queen) MustAdd(m M)
- func (q *Queen) Reset(ctx context.Context) error
- func (q *Queen) Status(ctx context.Context) ([]MigrationStatus, error)
- func (q *Queen) Up(ctx context.Context) error
- func (q *Queen) UpSteps(ctx context.Context, n int) error
- func (q *Queen) Validate(ctx context.Context) error
- type Status
- type TestHelper
Constants ¶
This section is empty.
Variables ¶
var ( // ErrNoMigrations is returned when no migrations are registered. ErrNoMigrations = errors.New("no migrations registered") // ErrVersionConflict is returned when duplicate version is detected. ErrVersionConflict = errors.New("version conflict") // ErrMigrationNotFound is returned when a migration version doesn't exist. ErrMigrationNotFound = errors.New("migration not found") // ErrChecksumMismatch is returned when a migration's checksum doesn't match. ErrChecksumMismatch = errors.New("checksum mismatch") // ErrLockTimeout is returned when unable to acquire lock within timeout. ErrLockTimeout = errors.New("lock timeout") // ErrNoDriver is returned when driver is not initialized. ErrNoDriver = errors.New("driver not initialized") // ErrInvalidMigration is returned when migration validation fails. ErrInvalidMigration = errors.New("invalid migration") // ErrAlreadyApplied is returned when trying to apply already applied migration. ErrAlreadyApplied = errors.New("migration already applied") )
Common errors that can be returned by Queen operations.
Functions ¶
This section is empty.
Types ¶
type Applied ¶
type Applied struct {
// Version is the unique version identifier of the migration.
Version string
// Name is the human-readable name of the migration.
Name string
// AppliedAt is when the migration was applied.
AppliedAt time.Time
// Checksum is the hash of the migration content at the time it was applied.
Checksum string
}
Applied represents a migration that has been applied to the database. This is returned by Driver.GetApplied().
type Config ¶
type Config struct {
// TableName is the name of the table used to track migrations.
// Default: "queen_migrations"
TableName string
// LockTimeout is how long to wait for the migration lock.
// Default: 30 minutes
LockTimeout time.Duration
// SkipLock disables migration locking (not recommended for prod env).
// Default: false
SkipLock bool
}
Config holds configuration options for Queen.
type Driver ¶
type Driver interface {
// Init initializes the driver and creates the migrations tracking table if needed.
// This should be called before any other operations.
Init(ctx context.Context) error
// GetApplied returns all migrations that have been applied to the database.
// The returned slice should be sorted by applied time in ascending order.
GetApplied(ctx context.Context) ([]Applied, error)
// Record marks a migration as applied in the database.
// This should be called after successfully executing a migration.
Record(ctx context.Context, m *Migration) error
// Remove removes a migration record from the database.
// This should be called after successfully rolling back a migration.
Remove(ctx context.Context, version string) error
// Lock acquires an exclusive lock to prevent concurrent migrations.
// If the lock cannot be acquired within the specified timeout, it returns ErrLockTimeout.
// The lock is automatically released when the context is cancelled.
Lock(ctx context.Context, timeout time.Duration) error
// Unlock releases the migration lock.
// This should be called in a defer statement after acquiring the lock.
Unlock(ctx context.Context) error
// Exec executes a function within a transaction.
// If the function returns an error, the transaction is rolled back.
// Otherwise, the transaction is committed.
Exec(ctx context.Context, fn func(*sql.Tx) error) error
// Close closes the database connection.
Close() error
}
Driver is the interface that database-specific drivers must implement. It abstracts away database-specific migration tracking and locking.
type M ¶
type M = Migration
M is a convenient alias for Migration, used in registration:
q.Add(queen.M{
Version: "001",
Name: "create_users",
UpSQL: "CREATE TABLE users...",
DownSQL: "DROP TABLE users",
})
type Migration ¶
type Migration struct {
// Version is a unique identifier for this migration.
// Examples: "001", "002", "user_001", "v1.0.0"
Version string
// Name is a human-readable description of the migration.
// Examples: "create_users", "add_email_index"
Name string
// UpSQL is the SQL statement to apply the migration.
// Used for simple SQL migrations.
UpSQL string
// DownSQL is the SQL statement to rollback the migration.
// Optional but recommended for safe rollbacks.
DownSQL string
// UpFunc is a Go function to apply the migration.
// Used for complex migrations that need programmatic logic.
UpFunc MigrationFunc
// DownFunc is a Go function to rollback the migration.
// Optional but recommended for safe rollbacks.
DownFunc MigrationFunc
// ManualChecksum is an optional manual checksum for Go function migrations.
// When using UpFunc/DownFunc, set this to track migration changes.
// Example: "v1", "v2", or descriptive like "normalize-emails-v1"
// If not set, checksum validation will be skipped for Go functions.
ManualChecksum string
// contains filtered or unexported fields
}
Migration represents a single database migration. It can be defined using SQL strings, Go functions, or both.
For SQL migrations, use UpSQL and DownSQL fields. For Go function migrations, use UpFunc and DownFunc fields.
The Version field must be unique across all migrations. Queen uses natural sorting, so "001", "002", "010" work correctly. You can also use prefixes like "user_001", "post_001" for modular organization.
func (*Migration) Checksum ¶
Checksum returns a unique hash of the migration content. For SQL migrations, it hashes UpSQL and DownSQL. For Go function migrations with ManualChecksum, it uses that value. For Go function migrations without ManualChecksum, it returns a special marker.
func (*Migration) HasRollback ¶
HasRollback returns true if the migration has a down migration.
func (*Migration) IsDestructive ¶
IsDestructive returns true if the migration contains potentially destructive operations. This checks for DROP TABLE, DROP DATABASE, TRUNCATE, etc. Only checks DownSQL, as Up migrations are assumed to be constructive.
type MigrationError ¶
MigrationError wraps an error with migration context.
func (*MigrationError) Error ¶
func (e *MigrationError) Error() string
func (*MigrationError) Unwrap ¶
func (e *MigrationError) Unwrap() error
type MigrationFunc ¶
MigrationFunc is a function that executes a migration using a transaction. It receives a context and a transaction, and should return an error if the migration fails.
type MigrationStatus ¶
type MigrationStatus struct {
// Version is the unique version identifier of the migration.
Version string
// Name is the human-readable name of the migration.
Name string
// Status indicates whether the migration is pending, applied, or modified.
Status Status
// AppliedAt is when the migration was applied (nil if not applied).
AppliedAt *time.Time
// Checksum is the current checksum of the migration.
Checksum string
// HasRollback indicates if the migration has a down migration.
HasRollback bool
// Destructive indicates if the down migration contains destructive operations.
Destructive bool
}
MigrationStatus contains detailed information about a migration's current state. This is returned by Queen.Status().
type Queen ¶
type Queen struct {
// contains filtered or unexported fields
}
Queen is the main migration manager. It holds registered migrations and orchestrates their execution.
func NewWithConfig ¶
NewWithConfig creates a new Queen instance with custom configuration.
func (*Queen) Add ¶
Add registers a new migration. If a migration with the same version already exists, it returns ErrVersionConflict. The migration is validated before being added.
func (*Queen) Down ¶
Down rolls back the last n migrations. If n is 0 or negative, only the last migration is rolled back.
func (*Queen) MustAdd ¶
MustAdd is like Add but panics on error. Useful for migration registration at package init time.
func (*Queen) Status ¶
func (q *Queen) Status(ctx context.Context) ([]MigrationStatus, error)
Status returns the status of all registered migrations.
func (*Queen) Up ¶
Up applies all pending migrations in order. It acquires a lock, loads applied migrations, and applies any pending ones.
type Status ¶
type Status int
Status represents the current state of a migration.
const ( // StatusPending indicates the migration has not been applied yet. StatusPending Status = iota // StatusApplied indicates the migration has been successfully applied. StatusApplied // StatusModified indicates the migration has been applied, // but its content has changed (checksum mismatch). StatusModified )
type TestHelper ¶
type TestHelper struct {
*Queen
// contains filtered or unexported fields
}
TestHelper provides testing utilities for migrations.
func NewTest ¶
func NewTest(t *testing.T, driver Driver) *TestHelper
NewTest creates a new Queen instance for testing. It uses the provided driver and will clean up automatically when the test ends.
Usage:
func TestMigrations(t *testing.T) {
db := setupTestDB(t) // Your test DB setup
driver := postgres.New(db)
q := queen.NewTest(t, driver)
q.MustAdd(queen.M{...})
// Test will automatically clean up
}
func (*TestHelper) MustDown ¶
func (th *TestHelper) MustDown(n int)
MustDown is like Down but fails the test on error.
func (*TestHelper) MustReset ¶
func (th *TestHelper) MustReset()
MustReset is like Reset but fails the test on error.
func (*TestHelper) MustUp ¶
func (th *TestHelper) MustUp()
MustUp is like Up but fails the test on error.
func (*TestHelper) MustValidate ¶
func (th *TestHelper) MustValidate()
MustValidate is like Validate but fails the test on error.
func (*TestHelper) TestUpDown ¶
func (th *TestHelper) TestUpDown()
TestUpDown tests that migrations can be applied and rolled back successfully. This validates that your Down migrations work correctly.
Usage:
func TestMigrations(t *testing.T) {
q := queen.NewTest(t, driver)
q.MustAdd(queen.M{...})
q.TestUpDown() // Tests both up and down
}
Directories
¶
| Path | Synopsis |
|---|---|
|
drivers
|
|
|
mock
Package mock provides an in-memory mock driver for testing Queen without a real database.
|
Package mock provides an in-memory mock driver for testing Queen without a real database. |
|
postgres
Package postgres provides a PostgreSQL driver for Queen migrations.
|
Package postgres provides a PostgreSQL driver for Queen migrations. |
|
internal
|
|
|
checksum
Package checksum provides checksum calculation for migrations.
|
Package checksum provides checksum calculation for migrations. |
|
sort
Package sort provides natural sorting for migration versions.
|
Package sort provides natural sorting for migration versions. |