brant

package module
v0.3.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 10, 2025 License: MIT Imports: 18 Imported by: 0

README

brant

builds.sr.ht status godoc

A brant is a small goose.

Brant is a minimalist database migration tool. Both a CLI and a library.

Manage your database schema by creating incremental SQL changes.

Design

Brant is inpired by and forked from goose. But the functionality was condensed down to a bare minimum:

  • Migrations are single .sql files with annotations (embed FS supported)
  • Only records current schema version in the database; no history, no stats
  • Linear migration history only; no branches, no out-of-order migrations
  • Versioning is arbitrary; can be sequential, can be timestamp, just has to be numbers in correct order

The only features added are the ability to "stamp" the database (which means setting the database version without running any migrations) and that migrations are loaded recursively (so they can be structured in folders if so desired).

Databases

Brant currently supports SQLite, PostgreSQL, MySQL, and Turso. Other databases could be added easily by anyone interested.

Migrations

Brant migrations are just like goose SQL migrations. In fact, the parser supports both +brant and +goose annotations, so goose migration files can be used with brant (but the version table is incompatible, so the database would have to be stamped to the current version when migrating).

A simple migration might look like this:

-- +brant Up
CREATE TABLE post (
    id int NOT NULL,
    title text,
    body text,
    PRIMARY KEY(id)
);

-- +brant Down
DROP TABLE post;

Like goose, brant expects migration files to have names starting with <VERSION>_, where <VERSION> is an arbitray number that imposes the correct order on migrations. Common schemes are using either sequential IDs or timestamps.

CLI usage

Usage: brant [--verbose] [--debug] [--json] [--log FILE] [--dir DIR] [--dialect DIALECT] [--driver DRIVER] [--dsn DSN] [--table TABLE] [--exclude NAME] [--out-of-band] <command> [<args>]

Options:
  --verbose              More verbose log output
  --debug                Show debug log messages (implies --verbose)
  --json                 Log messages as structured JSON
  --log FILE             Log messages to FILE (default: stderr)
  --dir DIR, -D DIR      Load migrations from DIR [default: ./migrations, env: BRANT_MIGRATION_DIR]
  --dialect DIALECT, -d DIALECT
                         The database dialect to use (default: infer from connection string) [env: BRANT_DIALECT]
  --driver DRIVER        Override the database driver (default: infer from dialect) [env: BRANT_DRIVER]
  --dsn DSN              The driver-specific data source name [env: BRANT_DSN]
  --table TABLE, -t TABLE
                         Name of the brant version tracking table [env: BRANT_TABLE]
  --exclude NAME, -x NAME
                         exclude files or directories when loading migrations
  --out-of-band, -O      run migrations without changing DB version
  --help, -h             display this help and exit

Commands:
  up                     Migrate the database up
  down                   Migrate the database down
  current                Print current database version
  list                   List available migrations
  stamp                  Set database version without running migrations
  validate               Load and validate migration files
  ping                   Check database connectivity

Use `<cmd> --help` for help with individual commands

License

Licensed under MIT License.

Contact

Feel free to send questions, patches, or other feedback to my public inbox.

Documentation

Index

Constants

View Source
const VERSION_HEAD = math.MaxInt64

When passed as version to Provider.Stamp, stamps to latest available version.

Variables

This section is empty.

Functions

func GetVersion

func GetVersion(filename string) (int64, error)

GetVersion parses the version from the migration file name.

Types

type Direction

type Direction string

Direction is a direction in which a migration can be performed.

const (
	DirectionUp   Direction = "up"
	DirectionDown Direction = "down"
)

type Migration

type Migration struct {
	Source
	// contains filtered or unexported fields
}

Migration struct represents a migration.

func (*Migration) Load

func (m *Migration) Load() error

func (*Migration) Statements

func (m *Migration) Statements(d Direction) ([]string, error)

func (*Migration) String

func (m *Migration) String() string

func (*Migration) UseTx

func (m *Migration) UseTx() (bool, error)

type MigrationContext

type MigrationContext struct {
	// contains filtered or unexported fields
}

type MigrationResult

type MigrationResult struct {
	// The source of the executed migration.
	Source *Source
	// The duration of the executed migration.
	Duration time.Duration
	// The direction of the executed migration.
	Direction Direction
	// The number of statements executed.
	NumStatements int
	// Error is only set if the migration failed.
	Error error
}

MigrationResult is the result of a single migration operation.

func (*MigrationResult) String

func (m *MigrationResult) String() string

String returns a string representation of the migration result.

type OnSuccessHook

type OnSuccessHook func(ctx context.Context, tx database.DBTxConn) error

type Options

type Options struct {
	Dir            string
	Driver         string
	DataSourceName string
	TableName      string

	Filesystem fs.FS

	OutOfBand bool

	ExcludeFilenames []string
}

Options is a set of options to use when creating a new Provider.

Options can be created with [Options.DefaultOptions] and then modified with WithX methods. For example:

options := brant.DefaultOptions().WithDir("data/schema/migrations").WithVerbose(true)
brant.NewProvider(slog.Default(), dialect.Postgres, options)

All options are documented in their respective WithX function:

func DefaultOptions

func DefaultOptions() Options

func (Options) WithDataSourceName

func (o Options) WithDataSourceName(s string) Options

WithDataSourceName returns a new Options value with DataSourceName set to the given value.

DataSourceName is the driver-specific data source name to use for connecting to the database. See sql.Open.

func (Options) WithDir

func (o Options) WithDir(s string) Options

WithDir returns a new Options value with Dir set to the given value.

Dir is the directory containing the migration files. It defaults to "migrations".

func (Options) WithDriver

func (o Options) WithDriver(s string) Options

WithDriver returns a new Options value with Driver set to the given value.

Driver is the SQL driver to use for connecting to the database. See sql.Open.

func (Options) WithExcludeFilenames

func (o Options) WithExcludeFilenames(filenames ...string) Options

WithExcludeFilenames returns a new Options value with ExcludeFilenames set to the given value.

ExcludeFilenames is a list of file or directory names to ignore when loading migrations. By default, migrations are loaded by scanning the migration directory recursively and loading all .sql files.

To exclude files or directories, add their base name to ExcludeFilenames. As an example, assuming the following directory contents: - migrations/old/0001_some_old_migration_thats_no_longer_relevant.sql - migrations/old/0002_some_other_migration_thats_no_longer_relevant.sql - migrations/000_template.sql - migrations/001_some_migration.sql

To ignore everything in the "old" directory, and the template for new migrations, use

options.WithExcludeFilenames([]string{"old", "000_template.sql"})

func (Options) WithFilesystem

func (o Options) WithFilesystem(f fs.FS) Options

WithFilesystem returns a new Options value with Filesystem set to the given value.

Filesystem is the filesystem to use for loading migration files. By default, the host filesystem is used.

func (Options) WithOutOfBand

func (o Options) WithOutOfBand(b bool) Options

WithOutOfBand returns a new Options value with OutOfBand set to the given value.

If OutOfBand is true, migrations will be run without changing the database version. The default is false.

func (Options) WithTableName

func (o Options) WithTableName(s string) Options

WithTableName returns a new Options value with TableName set to the given value.

TableName is the name of the table used to track the database version. The default is "brant_db_version".

type Provider

type Provider struct {
	// contains filtered or unexported fields
}

Provider is a brant migration provider.

func NewProvider

func NewProvider(logger *slog.Logger, dialect dialect.Dialect, opt Options) (*Provider, error)

NewProvider creates a new brant migration provider.

func (*Provider) Close

func (p *Provider) Close() error

Close closes the provider's database connection pool.

func (*Provider) Current

func (p *Provider) Current(ctx context.Context) (int64, error)

Current retrieves the current database version.

func (*Provider) Down

func (p *Provider) Down(ctx context.Context) ([]*MigrationResult, error)

Down rolls back the most recent migration. Returns an empty list and no error if there are no migrations to roll back.

func (*Provider) DownTo

func (p *Provider) DownTo(ctx context.Context, version int64) ([]*MigrationResult, error)

DownTo rolls back all migrations down to but not including the specified version. Returns an empty list and no error if there are no migrations to roll back.

func (*Provider) List

func (p *Provider) List(ctx context.Context, all bool) ([]*Source, error)

func (*Provider) ListSources

func (p *Provider) ListSources() []*Source

func (*Provider) Ping

func (p *Provider) Ping(ctx context.Context) error

Ping attempts to ping the database to verify a connection is available.

func (*Provider) Stamp

func (p *Provider) Stamp(ctx context.Context, version int64, force bool) error

Stamp sets the database version to the provided value without running any migrations.

func (*Provider) Up

func (p *Provider) Up(ctx context.Context) ([]*MigrationResult, error)

Up applies all available migrations. Returns an empty list and no error if there are no migrations to apply.

If error is not nil, the result is the list of all successful migrations plus the one that failed.

func (*Provider) UpByOne

func (p *Provider) UpByOne(ctx context.Context) ([]*MigrationResult, error)

UpByOne applies the next available migration. Returns an empty list and no error if there are no migrations to apply.

func (*Provider) UpTo

func (p *Provider) UpTo(ctx context.Context, version int64) ([]*MigrationResult, error)

UpTo applies all available migrations up to and including the specified version. Returns an empty list and no error if there are no migrations to apply.

func (*Provider) Validate

func (p *Provider) Validate() error

Validate loads and validates all migrations.

type Source

type Source struct {
	// Path to the migration file, relative to its [Base]
	Path string
	// Base is the base directory where all migrations are located
	Base string
	// Version is the version of the migration.
	Version int64
	// FS is the filesystem that the source resides on
	FS fs.FS
}

Source represents a single migration source file on disk.

Directories

Path Synopsis
The cli package provides an entrypoint for writing a `brant`-like CLI tool.
The cli package provides an entrypoint for writing a `brant`-like CLI tool.
cmd
brant command
Package database defines a generic Store interface for interacting with the database.
Package database defines a generic Store interface for interacting with the database.
internal

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL