From e5fc403451558809792b71407d5a50a64c4ba460 Mon Sep 17 00:00:00 2001 From: Eduard S Date: Wed, 30 Dec 2020 11:53:14 +0100 Subject: [PATCH] Add cli command to wipe the SQL DB - Refactor the migrations code so that packr is only called (via an init function in `db/utils.go`). - When loading the migrations, make sure there is at least one migration, otherwise panic (this would happen if the node is built incorrectly) --- cli/node/main.go | 50 +++++++++++++++++++++++++++++++++++++++++++ db/utils.go | 55 +++++++++++++++++++++++++++++++++++++++++------- test/dbUtils.go | 12 +++-------- 3 files changed, 100 insertions(+), 17 deletions(-) diff --git a/cli/node/main.go b/cli/node/main.go index 92513a2..19ba2bd 100644 --- a/cli/node/main.go +++ b/cli/node/main.go @@ -9,6 +9,7 @@ import ( ethKeystore "github.com/ethereum/go-ethereum/accounts/keystore" "github.com/ethereum/go-ethereum/crypto" "github.com/hermeznetwork/hermez-node/config" + dbUtils "github.com/hermeznetwork/hermez-node/db" "github.com/hermeznetwork/hermez-node/log" "github.com/hermeznetwork/hermez-node/node" "github.com/hermeznetwork/tracerr" @@ -19,6 +20,7 @@ const ( flagCfg = "cfg" flagMode = "mode" flagSK = "privatekey" + flagYes = "yes" modeSync = "sync" modeCoord = "coord" ) @@ -55,6 +57,41 @@ func cmdImportKey(c *cli.Context) error { return nil } +func cmdWipeSQL(c *cli.Context) error { + _cfg, err := parseCli(c) + if err != nil { + return tracerr.Wrap(fmt.Errorf("error parsing flags and config: %w", err)) + } + cfg := _cfg.node + yes := c.Bool(flagYes) + if !yes { + fmt.Print("*WARNING* Are you sure you want to delete the SQL DB? [y/N]: ") + var input string + if _, err := fmt.Scanln(&input); err != nil { + return tracerr.Wrap(err) + } + input = strings.ToLower(input) + if !(input == "y" || input == "yes") { + return nil + } + } + db, err := dbUtils.ConnectSQLDB( + cfg.PostgreSQL.Port, + cfg.PostgreSQL.Host, + cfg.PostgreSQL.User, + cfg.PostgreSQL.Password, + cfg.PostgreSQL.Name, + ) + if err != nil { + return tracerr.Wrap(err) + } + log.Info("Wiping SQL DB...") + if err := dbUtils.MigrationsDown(db.DB); err != nil { + return tracerr.Wrap(err) + } + return nil +} + func cmdRun(c *cli.Context) error { cfg, err := parseCli(c) if err != nil { @@ -159,6 +196,19 @@ func main() { Required: true, }}, }, + { + Name: "wipesql", + Aliases: []string{}, + Usage: "Wipe the SQL DB (HistoryDB and L2DB), " + + "leaving the DB in a clean state", + Action: cmdWipeSQL, + Flags: []cli.Flag{ + &cli.BoolFlag{ + Name: flagYes, + Usage: "automatic yes to the prompt", + Required: false, + }}, + }, { Name: "run", Aliases: []string{}, diff --git a/db/utils.go b/db/utils.go index 7e96586..579f705 100644 --- a/db/utils.go +++ b/db/utils.go @@ -15,8 +15,43 @@ import ( "github.com/russross/meddler" ) -// InitSQLDB runs migrations and registers meddlers -func InitSQLDB(port int, host, user, password, name string) (*sqlx.DB, error) { +var migrations *migrate.PackrMigrationSource + +func init() { + migrations = &migrate.PackrMigrationSource{ + Box: packr.New("hermez-db-migrations", "./migrations"), + } + ms, err := migrations.FindMigrations() + if err != nil { + panic(err) + } + if len(ms) == 0 { + panic(fmt.Errorf("no SQL migrations found")) + } +} + +// MigrationsUp runs the SQL migrations Up +func MigrationsUp(db *sql.DB) error { + nMigrations, err := migrate.Exec(db, "postgres", migrations, migrate.Up) + if err != nil { + return tracerr.Wrap(err) + } + log.Info("successfully ran ", nMigrations, " migrations Up") + return nil +} + +// MigrationsDown runs the SQL migrations Down +func MigrationsDown(db *sql.DB) error { + nMigrations, err := migrate.Exec(db, "postgres", migrations, migrate.Down) + if err != nil { + return tracerr.Wrap(err) + } + log.Info("successfully ran ", nMigrations, " migrations Down") + return nil +} + +// ConnectSQLDB connects to the SQL DB +func ConnectSQLDB(port int, host, user, password, name string) (*sqlx.DB, error) { // Init meddler initMeddler() meddler.Default = meddler.PostgreSQL @@ -33,15 +68,19 @@ func InitSQLDB(port int, host, user, password, name string) (*sqlx.DB, error) { if err != nil { return nil, tracerr.Wrap(err) } - // Run DB migrations - migrations := &migrate.PackrMigrationSource{ - Box: packr.New("hermez-db-migrations", "./migrations"), - } - nMigrations, err := migrate.Exec(db.DB, "postgres", migrations, migrate.Up) + return db, nil +} + +// InitSQLDB runs migrations and registers meddlers +func InitSQLDB(port int, host, user, password, name string) (*sqlx.DB, error) { + db, err := ConnectSQLDB(port, host, user, password, name) if err != nil { return nil, tracerr.Wrap(err) } - log.Info("successfully ran ", nMigrations, " migrations") + // Run DB migrations + if err := MigrationsUp(db.DB); err != nil { + return nil, tracerr.Wrap(err) + } return db, nil } diff --git a/test/dbUtils.go b/test/dbUtils.go index dc27872..ea108b9 100644 --- a/test/dbUtils.go +++ b/test/dbUtils.go @@ -3,9 +3,8 @@ package test import ( "testing" - "github.com/gobuffalo/packr/v2" + dbUtils "github.com/hermeznetwork/hermez-node/db" "github.com/jmoiron/sqlx" - migrate "github.com/rubenv/sql-migrate" "github.com/stretchr/testify/assert" ) @@ -28,15 +27,10 @@ func AssertUSD(t *testing.T, expected, actual *float64) { // WipeDB redo all the migrations of the SQL DB (HistoryDB and L2DB), // efectively recreating the original state func WipeDB(db *sqlx.DB) { - migrations := &migrate.PackrMigrationSource{ - Box: packr.New("hermez-db-migrations", "../db/migrations"), - } - _, err := migrate.Exec(db.DB, "postgres", migrations, migrate.Down) - if err != nil { + if err := dbUtils.MigrationsDown(db.DB); err != nil { panic(err) } - _, err = migrate.Exec(db.DB, "postgres", migrations, migrate.Up) - if err != nil { + if err := dbUtils.MigrationsUp(db.DB); err != nil { panic(err) } }