From 4215df47c93c6ea26f21c74a9d52f78d1d103dde Mon Sep 17 00:00:00 2001 From: jloup Date: Mon, 30 Apr 2018 21:12:37 +0200 Subject: [PATCH] Databse migrations. --- Gopkg.lock | 8 ++++- db/db.go | 86 ++++++++++++++++++++++++++++-------------------- db/migrations.go | 41 +++++++++++++++++++++++ 3 files changed, 98 insertions(+), 37 deletions(-) create mode 100644 db/migrations.go diff --git a/Gopkg.lock b/Gopkg.lock index 1e1aad8..8d11158 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -51,6 +51,12 @@ revision = "d459835d2b077e44f7c9b453505ee29881d5d12d" version = "v1.2" +[[projects]] + name = "github.com/go-pg/migrations" + packages = ["."] + revision = "91a824bb86a910befc819700ec6e21858c41b022" + version = "v6.2.0" + [[projects]] name = "github.com/go-pg/pg" packages = [ @@ -156,6 +162,6 @@ [solve-meta] analyzer-name = "dep" analyzer-version = 1 - inputs-digest = "d3c9b3094ed174bcf1631e3a998a75d557c65c195d7a8fd5ca9912f71f334ce1" + inputs-digest = "e3fa83f0fc133d3c408abdc47e5c2ca08062fec7c34ea04c21ea122492ab863d" solver-name = "gps-cdcl" solver-version = 1 diff --git a/db/db.go b/db/db.go index bc4b8b3..7f87201 100644 --- a/db/db.go +++ b/db/db.go @@ -1,9 +1,7 @@ package db import ( - "fmt" - "strings" - + migrate "github.com/go-pg/migrations" "github.com/go-pg/pg" "github.com/go-pg/pg/orm" "github.com/jloup/utils" @@ -25,15 +23,60 @@ func Init(config DBConfig) { DB = connect(config) - err = createSchema(DB) + err = migratedb() if err != nil { - log.Errorf("cannot create schemas %v\n", err) + log.Fatalf("cannot migratedb '%v'\n", err) } +} - err = createIndexes(DB) +func migratedb() error { + /* Remove after first MEP */ + version, err := migrate.Version(DB) if err != nil { - log.Errorf("cannot create indexes %v\n", err) + return err + } + + if version == 0 { + return migrate.SetVersion(DB, 1) } + /***/ + + mig := make([]migrate.Migration, 0) + + for _, migration := range migrations { + mig = append(mig, migrate.Migration{ + Version: migration.Version, + Up: func(db orm.DB) error { + for _, query := range migration.Up { + _, err := db.Exec(query) + if err != nil { + return err + } + } + + return nil + }, + Down: func(db orm.DB) error { + for _, query := range migration.Down { + _, err := db.Exec(query) + if err != nil { + return err + } + } + + return nil + }, + }) + } + + oldVersion, newVersion, err := migrate.RunMigrations(DB, mig, "up") + + if oldVersion != newVersion { + log.Infof("Migrate DB: %v -> %v", oldVersion, newVersion) + } else { + log.Infof("DB up-to-date: version '%v'", newVersion) + } + return err } func connect(config DBConfig) *pg.DB { @@ -44,32 +87,3 @@ func connect(config DBConfig) *pg.DB { Addr: config.Address, }) } - -func createSchema(db *pg.DB) error { - for _, model := range []interface{}{&User{}, &MarketConfig{}} { - err := db.CreateTable(model, &orm.CreateTableOptions{IfNotExists: true}) - if err != nil { - return err - } - } - return nil -} - -func createIndexes(db *pg.DB) error { - indexes := []struct { - TableName string - Name string - Columns []string - }{ - {"market_configs", "market_name_user_id_idx", []string{"user_id", "market_name"}}, - } - - for _, index := range indexes { - _, err := db.Exec(fmt.Sprintf("CREATE UNIQUE INDEX IF NOT EXISTS %s ON %s (%s)", index.Name, index.TableName, strings.Join(index.Columns, ","))) - if err != nil { - return err - } - } - - return nil -} diff --git a/db/migrations.go b/db/migrations.go new file mode 100644 index 0000000..ce5caf6 --- /dev/null +++ b/db/migrations.go @@ -0,0 +1,41 @@ +package db + +type Migration struct { + Version int64 + Up []string + Down []string +} + +var migrations []Migration = []Migration{ + { + Version: 1, + Up: []string{ + `CREATE TABLE users ( + id BIGSERIAL PRIMARY KEY, + email text NOT NULL, + password_hash text NOT NULL, + otp_secret text, + is_otp_setup boolean, + status smallint, + UNIQUE(email) + )`, + `CREATE TABLE market_configs ( + id BIGSERIAL PRIMARY KEY, + market_name text NOT NULL, + user_id bigint NOT NULL REFERENCES users(id), + config jsonb, + UNIQUE(user_id, market_name) + )`, + `CREATE TABLE report_lines ( + id BIGSERIAL PRIMARY KEY, + date timestamp with time zone NOT NULL, + report_id bigint NOT NULL, + type text, + payload jsonb + )`, + "CREATE INDEX IF NOT EXISTS report_lines_report_id ON report_lines (report_id)", + "CREATE INDEX IF NOT EXISTS report_lines_type ON report_lines (type)", + }, + Down: []string{"DROP TABLE users", "DROP TABLE market_configs", "DROP TABLE report_lines"}, + }, +} -- 2.41.0