godfish

package module
Version: v0.7.0 Latest Latest
Warning

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

Go to latest
Published: Apr 24, 2021 License: ISC Imports: 11 Imported by: 0

README

godfish

Go Reference

mysql postgres

godfish is a relational database migration manager, similar to the very good dogfish, but written in golang.

goals

  • use SQL in the migration files, no other high-level DSLs
  • interface with many RDBMSs
  • as little dependencies outside of the standard library as possible
  • not terrible error messages

build

Make a CLI binary for the DB you want to use. This tool comes with a couple of driver implementations (mysql, postgres at the moment). Build one like so:

go build -o godfish_pg    github.com/rafaelespinoza/godfish/drivers/postgres/godfish
go build -o godfish_mysql github.com/rafaelespinoza/godfish/drivers/mysql/godfish

# OR
make postgres
make mysql

From there you could move it to $GOPATH/bin, move it to your project or whatever else you need to do.

usage

godfish help
godfish -h
godfish <command> -h

Configuration options are read from command line flags first. If those are not set, then it checks the configuration file.

connecting to the db

Database connection parameters are always read from environment variables. Set:

DB_DSN=
configure file paths

Manually set path to db migration files.

godfish -files db/migrations <command>

Make your life easier by creating a configuration file by invoking godfish init. This creates a file at .godfish.json, where you can configure things.

Change the path to the configuration file.

mv .godfish.json foo.json
godfish -conf foo.json
everything else
cat .godfish.json
# { "path_to_files": "db/migrations" }

godfish create-migration -name alpha
# outputs:
# db/migrations/forward-20200128070010-alpha.sql
# db/migrations/reverse-20200128070010-alpha.sql

godfish create-migration -name bravo -reversible=false
# outputs:
# db/migrations/forward-20200128070106-bravo.sql

#
# ... write the sql in those files ...
#

# apply migrations
godfish migrate
# apply migrations to up a specific version
godfish migrate -version 20060102150405

# show status
godfish info

# apply a reverse migration
godfish rollback

# rollback and re-apply the last migration
godfish remigrate

# show build metadata
godfish version
godfish version -json

other minutiae

Here are some notable differences between dogfish and godfish:

Filenames:

  • dogfish: migrate-${date}-${name}.sql, or rollback-${date}-${name}.sql
  • godfish: forward-${date}-${name}.sql, or reverse-${date}-${name}.sql

Note, dogfish uses the words, "migrate" and "rollback" to describe the migration's direction whereas godfish uses "forward" and "reverse". They are the same in that they are two complementaries. This change has one trivial benefit, the pieces of metadata encoded into the filename naturally align:

cd /path/to/db/migrations && ls -1

forward-20191112050547-init_foos.sql
forward-20191127051242-add_bars.sql
forward-20191205031405-update_more_stuff.sql
reverse-20191112050547-init_foos.sql
reverse-20191127051242-add_bars.sql
reverse-20191205031405-update_more_stuff.sql

contributing

These are welcome. To get you started, the code has some documentation, a godoc page, at least one implementation of each interface and tests.

Comments line lengths should be limited to 80 characters wide. Try not to make source code lines too long. More lines is fine with the exception of declarations of exported identifiers; they should be on one line, otherwise the generated godoc looks weird. There are also tests, those should pass.

tests

Docker and docker-compose are used to create environments and run the tests against a live database. Each database has a separate configuration. All of this lives in Makefile.docker and the .ci/ directory.

# Build environments and run tests
make -f Makefile.docker ci-mysql-up
make -f Makefile.docker ci-postgres-up

# Teardown
make -f Makefile.docker ci-mysql-down
make -f Makefile.docker ci-postgres-down

Documentation

Overview

Package godfish is a database migration library built to support the command line tool.

Index

Constants

View Source
const (
	// TimeFormat provides a consistent timestamp layout for migrations.
	TimeFormat = "20060102150405"
)

Variables

View Source
var (
	// ErrSchemaMigrationsDoesNotExist means there is no database table to
	// record migration status.
	ErrSchemaMigrationsDoesNotExist = errors.New("schema migrations table does not exist")
)

Functions

func ApplyMigration

func ApplyMigration(driver Driver, directoryPath string, direction Direction, version string) (err error)

ApplyMigration runs a migration at directoryPath with the specified version and direction.

func CreateSchemaMigrationsTable

func CreateSchemaMigrationsTable(driver Driver) (err error)

CreateSchemaMigrationsTable creates a table to track status of migrations on the database. Running any migration will create the table, so you don't usually need to call this function.

func Info

func Info(driver Driver, directoryPath string, direction Direction, finishAtVersion string) (err error)

Info displays the outputs of various helper functions.

func Init

func Init(pathToFile string) (err error)

Init creates a configuration file at pathToFile unless it already exists.

func Migrate

func Migrate(driver Driver, directoryPath string, direction Direction, finishAtVersion string) (err error)

Migrate executes all migrations at directoryPath in the specified direction.

Types

type AppliedVersions

type AppliedVersions interface {
	Close() error
	Next() bool
	Scan(dest ...interface{}) error
}

AppliedVersions represents an iterative list of migrations that have been run against the database and have been recorded in the schema migrations table. It's enough to convert a *sql.Rows struct when implementing the Driver interface since a *sql.Rows already satisfies this interface. See existing Driver implementations in this package for examples.

type Config added in v0.7.0

type Config struct {
	PathToFiles string `json:"path_to_files"`
}

Config is for various runtime settings.

type Direction

type Direction uint8

Direction describes which way the change goes.

const (
	// DirUnknown is a fallback value for an undetermined direction.
	DirUnknown Direction = iota
	// DirForward is like migrate up, typically the change you want to apply to
	// the DB.
	DirForward
	// DirReverse is like migrate down; used for rollbacks. Not all changes can
	// be rolled back.
	DirReverse
)

func (Direction) String

func (d Direction) String() string

type Driver

type Driver interface {
	// Name should return the name of the driver: ie: postgres, mysql, etc
	Name() string

	// Connect should open a connection (a *sql.DB) to the database and save an
	// internal reference to that connection for later use. This library might
	// call this method multiple times, so use the internal reference if it's
	// present instead of reconnecting to the database.
	Connect(dsn string) (*sql.DB, error)
	// Close should check if there's an internal reference to a database
	// connection (a *sql.DB) and if it's present, close it. Then reset the
	// internal reference to that connection to nil.
	Close() error

	// AppliedVersions queries the schema migrations table for migration
	// versions that have been executed against the database. If the schema
	// migrations table does not exist, the returned error should be
	// ErrSchemaMigrationsDoesNotExist.
	AppliedVersions() (AppliedVersions, error)
	// CreateSchemaMigrationsTable should create a table to record migration
	// versions once they've been applied. The version should be a timestamp as
	// a string, formatted as the TimeFormat variable in this package.
	CreateSchemaMigrationsTable() error
	// Execute runs the schema change and commits it to the database. The query
	// parameter is a SQL string and may contain placeholders for the values in
	// args. Input should be passed to conn so it could be sanitized, escaped.
	Execute(query string, args ...interface{}) error
	// UpdateSchemaMigrations records a timestamped version of a migration that
	// has been successfully applied by adding a new row to the schema
	// migrations table.
	UpdateSchemaMigrations(dir Direction, version string) error
}

A Driver describes what a database driver (anything at https://github.com/golang/go/wiki/SQLDrivers) should be able to do.

type Indirection

type Indirection struct {
	Value Direction
	Label string
}

Indirection is some glue to help determine the direction of a migration, usually from a filename with an alias for a direction.

type Migration

type Migration interface {
	Indirection() Indirection
	Label() string
	Version() Version
}

A Migration is a database change with a direction name and timestamp. Typically, a Migration with a DirForward Direction is paired with another migration of DirReverse that has the same label.

type MigrationParams

type MigrationParams struct {
	Forward    Migration
	Reverse    Migration
	Reversible bool
	Dirpath    string
	// contains filtered or unexported fields
}

MigrationParams collects inputs needed to generate migration files. Setting Reversible to true will generate a migration file for each direction. Otherwise, it only generates a file in the forward direction. The Directory field refers to the path to the directory with the migration files.

func NewMigrationParams

func NewMigrationParams(label string, reversible bool, dirpath string) (*MigrationParams, error)

NewMigrationParams constructs a MigrationParams that's ready to use. Passing in true for reversible means that a complementary SQL file will be made for rolling back. The dirpath is the path to the directory for the files. An error is returned if dirpath doesn't actually represent a directory.

func (*MigrationParams) GenerateFiles

func (m *MigrationParams) GenerateFiles() (err error)

GenerateFiles creates the migration files. If the migration is reversible it generates files in forward and reverse directions; otherwise is generates just one migration file in the forward direction. It closes each file handle when it's done.

type Version

type Version interface {
	Before(u Version) bool
	String() string
	Value() int64
}

Version is for comparing migrations to each other.

Directories

Path Synopsis
drivers
Package internal contains code for maintainers.
Package internal contains code for maintainers.
commands
Package commands contains all the CLI stuff.
Package commands contains all the CLI stuff.
stub
Package stub implements godfish interfaces for testing purposes.
Package stub implements godfish interfaces for testing purposes.

Jump to

Keyboard shortcuts

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