Skip to content

Commit

Permalink
add comments for source
Browse files Browse the repository at this point in the history
  • Loading branch information
mattes committed Feb 10, 2017
1 parent 2da9761 commit b6bd4fe
Show file tree
Hide file tree
Showing 7 changed files with 116 additions and 13 deletions.
4 changes: 4 additions & 0 deletions database/testing/testing.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// Package testing has the database tests.
// All database drivers must pass the Test function.
// This lives in it's own package so it stays a test dependency.
package testing

import (
Expand All @@ -8,6 +11,7 @@ import (
"github.com/mattes/migrate/database"
)

// Test runs tests against database implementations.
func Test(t *testing.T, d database.Driver, migration []byte) {
if migration == nil {
panic("test must provide migration reader")
Expand Down
34 changes: 34 additions & 0 deletions source/driver.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
// Package source provides the Source interface.
// All source drivers must implement this interface, register themselves,
// optionally provide a `WithInstance` function and pass the tests
// in package source/testing.
package source

import (
Expand All @@ -10,22 +14,51 @@ import (
var driversMu sync.RWMutex
var drivers = make(map[string]Driver)

// Driver is an interface every driver must implement.
// The driver implementation must pass the `Test` in source/testing.
// Optionally provide a `WithInstance` function, so users can bypass `Open`
// and use an existing source instance.
type Driver interface {
// Open returns a a new driver instance configured with parameters
// coming from the URL string. Migrate will call this function
// only once per instance.
Open(url string) (Driver, error)

// Close closes the underlying source instance managed by the driver.
// Migrate will call this function only once per instance.
Close() error

// First returns the very first migration version available to the driver.
// Migrate will call this function multiple times.
// If there is no version available, it must return os.ErrNotExist.
First() (version uint, err error)

// Prev returns the previous version for a given version available to the driver.
// Migrate will call this function multiple times.
// If there is no previous version available, it must return os.ErrNotExist.
Prev(version uint) (prevVersion uint, err error)

// Next returns the next version for a given version available to the driver.
// Migrate will call this function multiple times.
// If there is no next version available, it must return os.ErrNotExist.
Next(version uint) (nextVersion uint, err error)

// ReadUp returns the UP migration body and an identifier that helps
// finding this migration in the source for a given version.
// If there is no up migration available for this version,
// it must return os.ErrNotExist.
// Do not start reading, just return the ReadCloser!
ReadUp(version uint) (r io.ReadCloser, identifier string, err error)

// ReadDown returns the DOWN migration body and an identifier that helps
// finding this migration in the source for a given version.
// If there is no down migration available for this version,
// it must return os.ErrNotExist.
// Do not start reading, just return the ReadCloser!
ReadDown(version uint) (r io.ReadCloser, identifier string, err error)
}

// Open returns a new driver instance.
func Open(url string) (Driver, error) {
u, err := nurl.Parse(url)
if err != nil {
Expand All @@ -46,6 +79,7 @@ func Open(url string) (Driver, error) {
return d.Open(url)
}

// Register globally registers a driver.
func Register(name string, driver Driver) {
driversMu.Lock()
defer driversMu.Unlock()
Expand Down
8 changes: 8 additions & 0 deletions source/driver_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package source

func ExampleDriver() {
// see source/stub for an example

// source/stub/stub.go has the driver implementation
// source/stub/stub_test.go runs source/testing/test.go:Test
}
21 changes: 18 additions & 3 deletions source/migration.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,35 @@ import (
"sort"
)

// Direction is either up or down.
type Direction string

const (
Down Direction = "down"
Up = "up"
)

// Migration is a helper struct for source drivers that need to
// build the full directory tree in memory.
// Migration is fully independent from migrate.Migration.
type Migration struct {
Version uint
// Version is the version of this migration.
Version uint

// Identifier can be any string that helps identifying
// this migration in the source.
Identifier string
Direction Direction
Raw string

// Direction is either Up or Down.
Direction Direction

// Raw holds the raw location path to this migration in source.
// ReadUp and ReadDown will use this.
Raw string
}

// Migrations wraps Migration and has an internal index
// to keep track of Migration order.
type Migrations struct {
index uintSlice
migrations map[uint]map[Direction]*Migration
Expand Down
33 changes: 33 additions & 0 deletions source/migration_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package source

import (
"testing"
)

func TestNewMigrations(t *testing.T) {
// TODO
}

func TestAppend(t *testing.T) {
// TODO
}

func TestBuildIndex(t *testing.T) {
// TODO
}

func TestFirst(t *testing.T) {
// TODO
}

func TestPrev(t *testing.T) {
// TODO
}

func TestUp(t *testing.T) {
// TODO
}

func TestDown(t *testing.T) {
// TODO
}
17 changes: 11 additions & 6 deletions source/parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,21 @@ import (
"strconv"
)

var ErrParse = fmt.Errorf("no match")

var DefaultParse = Parse
var (
ErrParse = fmt.Errorf("no match")
)

var DefaultRegex = Regex
var (
DefaultParse = Parse
DefaultRegex = Regex
)

// filename example: `123_name.up.ext`
// filename example: `123_name.down.ext`
// Regex matches the following pattern:
// 123_name.up.ext
// 123_name.down.ext
var Regex = regexp.MustCompile(`^([0-9]+)_(.*)\.(` + string(Down) + `|` + string(Up) + `)\.(.*)$`)

// Parse returns Migration for matching Regex pattern.
func Parse(raw string) (*Migration, error) {
m := Regex.FindStringSubmatch(raw)
if len(m) == 5 {
Expand Down
12 changes: 8 additions & 4 deletions source/testing/testing.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// Package testing has the source tests.
// All source drivers must pass the Test function.
// This lives in it's own package so it stays a test dependency.
package testing

import (
Expand All @@ -7,13 +10,14 @@ import (
"github.com/mattes/migrate/source"
)

// Test tests a driver implementation
// It assumes the following migration "files"
//
// u = up file, d = down file, n = version
// Test runs tests against source implementations.
// It assumes that the driver tests has access to the following migrations:
//
// u = up migration, d = down migration, n = version
// | 1 | - | 3 | 4 | 5 | - | 7 |
// | u d | - | u | u d | d | - | u d |
//
// See source/stub/stub_test.go or source/file/file_test.go for an example.
func Test(t *testing.T, d source.Driver) {
TestFirst(t, d)
TestPrev(t, d)
Expand Down

0 comments on commit b6bd4fe

Please sign in to comment.