From 7fb1f737d96543fddc538b16037493380fa08177 Mon Sep 17 00:00:00 2001 From: A Gardner <3100188+actgardner@users.noreply.github.com> Date: Wed, 20 May 2020 10:57:15 -0400 Subject: [PATCH 1/3] Make it possible to run migrations as a library --- cmd/perform.go | 54 +++++++++----------------------------------- database/mysql.go | 6 +++++ database/postgres.go | 6 +++++ database/sqlite3.go | 6 +++++ migration/migrate.go | 47 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 76 insertions(+), 43 deletions(-) create mode 100644 migration/migrate.go diff --git a/cmd/perform.go b/cmd/perform.go index 05d660b..4a5f67d 100644 --- a/cmd/perform.go +++ b/cmd/perform.go @@ -9,6 +9,7 @@ import ( "github.com/andrewpillar/mgrt/config" "github.com/andrewpillar/mgrt/database" + "github.com/andrewpillar/mgrt/migration" "github.com/andrewpillar/mgrt/revision" "github.com/andrewpillar/mgrt/util" ) @@ -34,15 +35,15 @@ func loadRevisions(c cli.Command, d revision.Direction) ([]*revision.Revision, e var err error switch d { - case revision.Up: - revisions, err = revision.Oldest() - break - case revision.Down: - revisions, err = revision.Latest() - break - default: - err = errors.New("unknown direction") - break + case revision.Up: + revisions, err = revision.Oldest() + break + case revision.Down: + revisions, err = revision.Latest() + break + default: + err = errors.New("unknown direction") + break } return revisions, err @@ -83,38 +84,5 @@ func perform(c cli.Command, d revision.Direction) { force := c.Flags.IsSet("force") - for _, r := range revisions { - r.Direction = d - - if err := r.GenHash(); err != nil { - util.ExitError("failed to perform revision", err) - } - - if err := db.Perform(r, force); err != nil { - if err != database.ErrAlreadyPerformed { - util.ExitError("failed to perform revision", fmt.Errorf("%s: %d", err, r.ID)) - } - - fmt.Printf("%s - %s: %d", d, err, r.ID) - - if r.Message != "" { - fmt.Printf(": %s", r.Message) - } - - fmt.Printf("\n") - continue - } - - if err := db.Log(r, force); err != nil { - util.ExitError("failed to log revision", err) - } - - fmt.Printf("%s - performed revision: %d", d, r.ID) - - if r.Message != "" { - fmt.Printf(": %s", r.Message) - } - - fmt.Printf("\n") - } + migration.Perform(db, revisions, d, force) } diff --git a/database/mysql.go b/database/mysql.go index 26d7cf7..41b9454 100644 --- a/database/mysql.go +++ b/database/mysql.go @@ -55,6 +55,12 @@ func init() { databases["mysql"] = &MySQL{} } +func (p *MySQL) FromConn(db *sql.DB) { + p.database = &database{ + DB: db, + } +} + func (m *MySQL) Open(cfg *config.Config) error { dsn := fmt.Sprintf(mysqlDsn, cfg.Username, cfg.Password, cfg.Address, cfg.Database) diff --git a/database/postgres.go b/database/postgres.go index 918e414..9816bd7 100644 --- a/database/postgres.go +++ b/database/postgres.go @@ -52,6 +52,12 @@ func init() { databases["postgres"] = &Postgres{} } +func (p *Postgres) FromConn(db *sql.DB) { + p.database = &database{ + DB: db, + } +} + func (p *Postgres) Open(cfg *config.Config) error { host, port, err := net.SplitHostPort(cfg.Address) diff --git a/database/sqlite3.go b/database/sqlite3.go index 90e3c2e..54b1b70 100644 --- a/database/sqlite3.go +++ b/database/sqlite3.go @@ -32,6 +32,12 @@ func init() { databases["sqlite3"] = &SQLite3{} } +func (p *SQLite3) FromConn(db *sql.DB) { + p.database = &database{ + DB: db, + } +} + func (s *SQLite3) Open(cfg *config.Config) error { db, err := sql.Open("sqlite3", cfg.Address) diff --git a/migration/migrate.go b/migration/migrate.go new file mode 100644 index 0000000..6419924 --- /dev/null +++ b/migration/migrate.go @@ -0,0 +1,47 @@ +package migrate + +import ( + "fmt" + + "github.com/andrewpillar/mgrt/database" + "github.com/andrewpillar/mgrt/revision" + "github.com/andrewpillar/mgrt/util" +) + +func Perform(db database.DB, revisions []*revision.Revision, d revision.Direction, force bool) { + for _, r := range revisions { + + r.Direction = d + + if err := r.GenHash(); err != nil { + util.ExitError("failed to perform revision", err) + } + + if err := db.Perform(r, force); err != nil { + if err != database.ErrAlreadyPerformed { + util.ExitError("failed to perform revision", fmt.Errorf("%s: %d", err, r.ID)) + } + + fmt.Printf("%s - %s: %d", d, err, r.ID) + + if r.Message != "" { + fmt.Printf(": %s", r.Message) + } + + fmt.Printf("\n") + continue + } + + if err := db.Log(r, force); err != nil { + util.ExitError("failed to log revision", err) + } + + fmt.Printf("%s - performed revision: %d", d, r.ID) + + if r.Message != "" { + fmt.Printf(": %s", r.Message) + } + + fmt.Printf("\n") + } +} From 55949aa58e87aa7117ba652c9867a31eea720277 Mon Sep 17 00:00:00 2001 From: A Gardner <3100188+actgardner@users.noreply.github.com> Date: Wed, 20 May 2020 11:09:20 -0400 Subject: [PATCH 2/3] Return errors from migration.Perform --- cmd/perform.go | 5 ++++- migration/migrate.go | 12 ++++++------ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/cmd/perform.go b/cmd/perform.go index 4a5f67d..42c8883 100644 --- a/cmd/perform.go +++ b/cmd/perform.go @@ -84,5 +84,8 @@ func perform(c cli.Command, d revision.Direction) { force := c.Flags.IsSet("force") - migration.Perform(db, revisions, d, force) + err = migration.Perform(db, revisions, d, force) + if err != nil { + util.ExitError("failed to perform revision ", err) + } } diff --git a/migration/migrate.go b/migration/migrate.go index 6419924..95b38a0 100644 --- a/migration/migrate.go +++ b/migration/migrate.go @@ -1,25 +1,24 @@ -package migrate +package migration import ( "fmt" "github.com/andrewpillar/mgrt/database" "github.com/andrewpillar/mgrt/revision" - "github.com/andrewpillar/mgrt/util" ) -func Perform(db database.DB, revisions []*revision.Revision, d revision.Direction, force bool) { +func Perform(db database.DB, revisions []*revision.Revision, d revision.Direction, force bool) error { for _, r := range revisions { r.Direction = d if err := r.GenHash(); err != nil { - util.ExitError("failed to perform revision", err) + return err } if err := db.Perform(r, force); err != nil { if err != database.ErrAlreadyPerformed { - util.ExitError("failed to perform revision", fmt.Errorf("%s: %d", err, r.ID)) + return fmt.Errorf("%s: %d", err, r.ID) } fmt.Printf("%s - %s: %d", d, err, r.ID) @@ -33,7 +32,7 @@ func Perform(db database.DB, revisions []*revision.Revision, d revision.Directio } if err := db.Log(r, force); err != nil { - util.ExitError("failed to log revision", err) + return err } fmt.Printf("%s - performed revision: %d", d, r.ID) @@ -44,4 +43,5 @@ func Perform(db database.DB, revisions []*revision.Revision, d revision.Directio fmt.Printf("\n") } + return nil } From 45706714dcedd85706e05e024009f838e19b12bd Mon Sep 17 00:00:00 2001 From: A Gardner <3100188+actgardner@users.noreply.github.com> Date: Mon, 22 Jun 2020 11:39:57 -0400 Subject: [PATCH 3/3] Raise clearer error when an invalid ID is specified --- revision/revision.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/revision/revision.go b/revision/revision.go index 0c3830e..5befe43 100644 --- a/revision/revision.go +++ b/revision/revision.go @@ -17,8 +17,8 @@ import ( ) var ( - upFile = "up.sql" - downFile = "down.sql" + upFile = "up.sql" + downFile = "down.sql" reslug = regexp.MustCompile("[^a-zA-Z0-9]") redup = regexp.MustCompile("-{2,}") @@ -196,6 +196,10 @@ func Find(id string) (*Revision, error) { } } + if base == "" { + return nil, errors.New("no revision found with ID: " + id) + } + return resolveFromPath(filepath.Join(config.RevisionsDir(), base)) }