Skip to content

Commit

Permalink
Fix failing tests, improve the comments
Browse files Browse the repository at this point in the history
  • Loading branch information
josephspurrier committed Jan 11, 2019
1 parent 2acf967 commit 3296fab
Show file tree
Hide file tree
Showing 7 changed files with 103 additions and 90 deletions.
60 changes: 30 additions & 30 deletions cmd/rove/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,13 @@ func migrateAll(t *testing.T) (*sqlx.DB, string) {
db, unique := testutil.SetupDatabase()

// Set the arguments.
os.Args = make([]string, 6)
os.Args[0] = "rove"
os.Args[1] = "migrate"
os.Args[2] = "all"
os.Args[3] = "testdata/success.sql"
os.Args[4] = "--envprefix"
os.Args[5] = unique
os.Args = []string{
"rove",
"all",
"testdata/success.sql",
"--envprefix",
unique,
}

// Redirect stdout.
backupd := os.Stdout
Expand Down Expand Up @@ -57,13 +57,13 @@ func TestMigrationReset(t *testing.T) {
db, unique := migrateAll(t)

// Set the arguments.
os.Args = make([]string, 6)
os.Args[0] = "rove"
os.Args[1] = "migrate"
os.Args[2] = "reset"
os.Args[3] = "testdata/success.sql"
os.Args[4] = "--envprefix"
os.Args[5] = unique
os.Args = []string{
"rove",
"reset",
"testdata/success.sql",
"--envprefix",
unique,
}

// Redirect stdout.
backupd := os.Stdout
Expand Down Expand Up @@ -99,14 +99,14 @@ func migrateUp(t *testing.T) (*sqlx.DB, string) {
db, unique := testutil.SetupDatabase()

// Set the arguments.
os.Args = make([]string, 7)
os.Args[0] = "rove"
os.Args[1] = "migrate"
os.Args[2] = "up"
os.Args[3] = "2"
os.Args[4] = "testdata/success.sql"
os.Args[5] = "--envprefix"
os.Args[6] = unique
os.Args = []string{
"rove",
"up",
"2",
"testdata/success.sql",
"--envprefix",
unique,
}

// Redirect stdout.
backupd := os.Stdout
Expand Down Expand Up @@ -137,14 +137,14 @@ func TestMigrationDown(t *testing.T) {
db, unique := migrateUp(t)

// Set the arguments.
os.Args = make([]string, 7)
os.Args[0] = "rove"
os.Args[1] = "migrate"
os.Args[2] = "down"
os.Args[3] = "1"
os.Args[4] = "testdata/success.sql"
os.Args[5] = "--envprefix"
os.Args[6] = unique
os.Args = []string{
"rove",
"down",
"1",
"testdata/success.sql",
"--envprefix",
unique,
}

// Redirect stdout.
backupd := os.Stdout
Expand Down
46 changes: 22 additions & 24 deletions interface.go
Original file line number Diff line number Diff line change
@@ -1,44 +1,42 @@
package rove

// Migration represents a database specific migration.
type Migration interface {
// CreateChangelogTable returns an error if there is a problem with the
// query. If it already exists, it should return nil.
CreateChangelogTable() error
// ChangesetApplied should return an error if there is a problem with the
// query. If there are no rows, that error can be returned and it will
// be ignored.
// Changelog represents a list of operations that can be run on a changelog.
type Changelog interface {
// Initialize should perform any work to set up the changelog or return an
// error.
Initialize() error
// ChangesetApplied should return the checksum from the changelog of a
// matching changeset, an error, or a blank string if the changeset doesn't
// exist in the changelog.
ChangesetApplied(id string, author string, filename string) (checksum string, err error)
// BeginTx starts a transaction.
// BeginTx should start a transaction on the changelog.
BeginTx() (Transaction, error)
// Count returns the number of changesets in the database and returns an
// error if there is a problem with the query.
// Count should return the number of changesets in the changelog or return
// an error.
Count() (count int, err error)
// Insert will insert a new record into the database.
// Insert should add a new changeset to the changelog or return an error.
Insert(id, author, filename string, count int, checksum, description, version string) error
// Returns a list of the changesets or it returns an error if there is an
// problem running the query.
Changesets(reverse bool) ([]Change, error)
// Delete the changeset from the database or return an error if there is a
// problem running the query.
// Changesets should return a list of the changesets or return an error.
Changesets(reverse bool) ([]Changeset, error)
// Delete should remove the changeset from the changelog or return an error.
Delete(id, author, filename string) error
}

// Change contains a single database record change.
type Change struct {
// Changeset is a single changeset.
type Changeset struct {
ID string
Author string
Filename string
OrderExecuted int
}

// Transaction represents a database transaction.
// Transaction represents a changelog transaction.
type Transaction interface {
// Commit will attempt to commit the changes to the database or return
// an error.
// Commit should attempt to commit the changes to to the changelog or
// return an error.
Commit() error
// Rollback rollback changes to the database after a filed commit.
// Rollback should undo changes to the changelog after a failed commit.
Rollback() error
// Exec runs a query on the database.
// Exec should prepare to make a change to the changelog.
Exec(query string, args ...interface{}) error
}
13 changes: 6 additions & 7 deletions migrate.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package rove

import (
"database/sql"
"fmt"
"strings"

Expand All @@ -11,13 +10,13 @@ import (
// Migrate will perform all the migrations in a file. If max is 0, all
// migrations are run.
func (r *Rove) Migrate(max int) error {
// Create a changelog table.
err := r.db.CreateChangelogTable()
// Create the object to store the changeset log.
err := r.db.Initialize()
if err != nil {
return err
}

arr := make([]changeset.Info, 0)
arr := make([]changeset.Record, 0)
// If a file is specified, use it to build the array.
if len(r.file) > 0 {
// Get the changesets.
Expand All @@ -43,7 +42,9 @@ func (r *Rove) Migrate(max int) error {
// Determine if the changeset was already applied.
// Count the number of rows.
checksum, err = r.db.ChangesetApplied(cs.ID, cs.Author, cs.Filename)
if err == nil {
if err != nil {
return fmt.Errorf("internal error on changeset %v:%v - %v", cs.Author, cs.ID, err.Error())
} else if checksum != "" {
// Determine if the checksums match.
if checksum != newChecksum {
return fmt.Errorf("checksum does not match - existing changeset %v:%v has checksum %v, but new changeset has checksum %v",
Expand All @@ -54,8 +55,6 @@ func (r *Rove) Migrate(max int) error {
fmt.Printf("Changeset already applied: %v:%v\n", cs.Author, cs.ID)
}
continue
} else if err != nil && err != sql.ErrNoRows {
return fmt.Errorf("internal error on changeset %v:%v - %v", cs.Author, cs.ID, err.Error())
}

arrQueries := strings.Split(cs.Changes(), ";")
Expand Down
18 changes: 9 additions & 9 deletions parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import (
)

// parseFileToArray will parse a file into changesets.
func parseFileToArray(filename string) ([]changeset.Info, error) {
func parseFileToArray(filename string) ([]changeset.Record, error) {
f, err := os.Open(filename)
if err != nil {
return nil, err
Expand All @@ -25,12 +25,12 @@ func parseFileToArray(filename string) ([]changeset.Info, error) {
}

// parseToArray will split the SQL migration into an ordered array.
func parseToArray(r io.Reader, filename string) ([]changeset.Info, error) {
func parseToArray(r io.Reader, filename string) ([]changeset.Record, error) {
scanner := bufio.NewScanner(r)
scanner.Split(bufio.ScanLines)

// Array of changesets.
arr := make([]changeset.Info, 0)
arr := make([]changeset.Record, 0)

for scanner.Scan() {
// Get the line without leading or trailing spaces.
Expand All @@ -57,7 +57,7 @@ func parseToArray(r io.Reader, filename string) ([]changeset.Info, error) {
// Start recording the changeset.
if strings.HasPrefix(line, elementChangeset) {
// Create a new changeset.
cs := new(changeset.Info)
cs := new(changeset.Record)
cs.ParseHeader(strings.TrimPrefix(line, elementChangeset))
cs.SetFileInfo(path.Base(filename), "sql", appVersion)
arr = append(arr, *cs)
Expand Down Expand Up @@ -88,7 +88,7 @@ func parseToArray(r io.Reader, filename string) ([]changeset.Info, error) {
}

// parseFileToMap will parse a file into a map.
func parseFileToMap(filename string) (map[string]changeset.Info, error) {
func parseFileToMap(filename string) (map[string]changeset.Record, error) {
f, err := os.Open(filename)
if err != nil {
return nil, err
Expand All @@ -99,7 +99,7 @@ func parseFileToMap(filename string) (map[string]changeset.Info, error) {
}

// parseReaderToMap will parse a reader to a map.
func parseReaderToMap(r io.Reader, filename string) (map[string]changeset.Info, error) {
func parseReaderToMap(r io.Reader, filename string) (map[string]changeset.Record, error) {
arr, err := parseToArray(r, filename)
if err != nil {
return nil, err
Expand All @@ -108,8 +108,8 @@ func parseReaderToMap(r io.Reader, filename string) (map[string]changeset.Info,
return parseArrayToMap(arr)
}

func parseArrayToMap(arr []changeset.Info) (map[string]changeset.Info, error) {
m := make(map[string]changeset.Info)
func parseArrayToMap(arr []changeset.Record) (map[string]changeset.Record, error) {
m := make(map[string]changeset.Record)

for _, cs := range arr {
id := fmt.Sprintf("%v:%v:%v", cs.Author, cs.ID, cs.Filename)
Expand All @@ -125,7 +125,7 @@ func parseArrayToMap(arr []changeset.Info) (map[string]changeset.Info, error) {

// loadChangesets will get the changesets based on the type of migration
// specified during the creation of the Rove object.
func (r *Rove) loadChangesets() (map[string]changeset.Info, error) {
func (r *Rove) loadChangesets() (map[string]changeset.Record, error) {
// Use the file to get the changesets first.
if len(r.file) > 0 {
// Get the changesets in a map.
Expand Down
19 changes: 10 additions & 9 deletions pkg/changeset/changeset.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// Package changeset handles operations on the text of a changeset.
package changeset

import (
Expand All @@ -10,8 +11,8 @@ var (
ErrInvalidHeader = errors.New("invalid changeset header")
)

// Info is a database changeset.
type Info struct {
// Record is a changeset.
type Record struct {
ID string
Author string
Filename string
Expand All @@ -24,7 +25,7 @@ type Info struct {
}

// ParseHeader will parse the header information.
func (cs *Info) ParseHeader(line string) error {
func (cs *Record) ParseHeader(line string) error {
arr := strings.Split(line, ":")
if len(arr) != 2 {
return ErrInvalidHeader
Expand All @@ -37,39 +38,39 @@ func (cs *Info) ParseHeader(line string) error {
}

// SetFileInfo will set the file information.
func (cs *Info) SetFileInfo(filename string, description string, version string) {
func (cs *Record) SetFileInfo(filename string, description string, version string) {
cs.Filename = filename
cs.Description = description
cs.Version = version
}

// AddRollback will add a rollback command.
func (cs *Info) AddRollback(line string) {
func (cs *Record) AddRollback(line string) {
if len(cs.rollback) == 0 {
cs.rollback = make([]string, 0)
}
cs.rollback = append(cs.rollback, line)
}

// AddChange will add a change command.
func (cs *Info) AddChange(line string) {
func (cs *Record) AddChange(line string) {
if len(cs.change) == 0 {
cs.change = make([]string, 0)
}
cs.change = append(cs.change, line)
}

// Changes will return all the changes.
func (cs *Info) Changes() string {
func (cs *Record) Changes() string {
return strings.Join(cs.change, "\n")
}

// Rollbacks will return all the rollbacks.
func (cs *Info) Rollbacks() string {
func (cs *Record) Rollbacks() string {
return strings.Join(cs.rollback, "\n")
}

// Checksum returns an MD5 checksum for the changeset.
func (cs *Info) Checksum() string {
func (cs *Record) Checksum() string {
return md5sum(cs.Changes())
}
Loading

0 comments on commit 3296fab

Please sign in to comment.