flit

package module
v0.0.0-...-20f4a72 Latest Latest
Warning

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

Go to latest
Published: Apr 24, 2025 License: MIT Imports: 10 Imported by: 0

README

Flit

Flit is a Go package that implements SQL database migrations. It is built on top of Go's standard database/sql package. There are many packages like this one and all of them are better, but Flit is small and easy to understand.

Flit reads migrations from .sql files and executes each one as a single SQL statement. Completed migrations are recorded in the flits table, which is created automatically.

To use Flit, create a new migrator and call Migrate when your process starts. You can handle concurrent processes by configuring a guard function like the following example.

Example

package main

import (
	"context"
	"database/sql"
	"fmt"
	"os"

	"github.com/180-studios/flit"

	_ "github.com/go-sql-driver/mysql"
)

func main() {
	db, err := sql.Open("mysql", os.Getenv("MYSQL_DSN"))
	if err != nil {
		panic(err)
	}

	defer db.Close()

	dir := os.Args[1]

	// read migrations from dir/*.sql (or embed them)
	// manage concurrency with MySQL's GET_LOCK/RELEASE_LOCK
	m := flit.New(db, os.DirFS(dir), flit.WithGuard(flit.GuardMySQL))
	applied, err := m.Migrate(context.Background())
	if err != nil {
		panic(err)
	}

	fmt.Println(applied)
}

Development

The MySQL tests are skipped unless the TEST_MYSQL_DSN environment variable is set.

Dependencies

Flit doesn't have any runtime dependencies other than the standard library. The tests and examples depend on the github.com/go-sql-driver/mysql and github.com/mattn/go-sqlite3 modules.

Documentation

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func GuardMySQL

func GuardMySQL(ctx context.Context, conn *sql.Conn, f func(context.Context, *sql.Conn) error) (err error)

GuardMySQL manages migration concurrency with MySQL's GET_LOCK and RELEASE_LOCK functions. It gets a lock named "flit" before calling f and releases it after f returns. GuardMySQL blocks until the lock is acquired or ctx is done. Use this guard function by passing a WithGuard option to New.

Types

type ConfigOption

type ConfigOption func(*Migrator)

A ConfigOption can be passed to New to change the configuration. The WithGlob option configures the pattern used to load migration files. The WithGuard option configures the concurrency guard function.

func WithGlob

func WithGlob(glob string) ConfigOption

WithGlob configures Flit to load migration files matching the given glob.

func WithGuard

func WithGuard(g GuardFunc) ConfigOption

WithGuard configures Flit to call the given GuardFunc for concurrency control. For example, GuardMySQL uses MySQL's GET_LOCK and RELEASE_LOCK functions.

type GuardFunc

type GuardFunc func(context.Context, *sql.Conn, func(context.Context, *sql.Conn) error) error

GuardFunc is called by Migrator.Migrate to manage concurrency.

type Migrator

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

A Migrator holds the configuration required to migrate a database. Call New to create a new Migrator.

Example
package main

import (
	"context"
	"database/sql"
	"fmt"
	"os"

	"github.com/180-studios/flit"

	_ "github.com/go-sql-driver/mysql"
	_ "github.com/mattn/go-sqlite3"
)

func main() {
	db, err := sql.Open("sqlite3", "file::memory:?cache=shared")
	if err != nil {
		panic(err)
	}

	defer db.Close()

	m := flit.New(db, os.DirFS("testdata/example"))
	applied, err := m.Migrate(context.Background())
	if err != nil {
		panic(err)
	}

	fmt.Println(applied)
}
Output:

[001-first.sql 002-second.sql]

func New

func New(db *sql.DB, fsys fs.FS, options ...ConfigOption) *Migrator

New creates a new migrator for the given database, file system, and options.

func (*Migrator) Migrate

func (m *Migrator) Migrate(ctx context.Context) (applied []string, err error)

Migrate applies pending migrations to the database. It returns the names of the migrations that were applied.

Migrations are loaded from .sql files in the root of the configured file system. The migrations are ordered by name before being applied. Each migration is executed as a single SQL statement. After a migration is completed a checksum of its name is recorded in the "flits" table, which is created automatically.

Migrate is guarded by a mutex. This guard can be replaced by passing a WithGuard option to New. For example, GuardMySQL uses MySQL's GET_LOCK and RELEASE_LOCK functions.

Directories

Path Synopsis
cmd
example command
Example is the example code embedded in the README.
Example is the example code embedded in the README.
flit command
Package mysqltest provides a helper to create test-scoped MySQL databases.
Package mysqltest provides a helper to create test-scoped MySQL databases.
Package sqlitetest provides a test helper to create an in-memory SQLite database.
Package sqlitetest provides a test helper to create an in-memory SQLite database.

Jump to

Keyboard shortcuts

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