object migrations

This commit is contained in:
Pavel 2019-09-18 13:40:36 +03:00
parent bb0172bc8d
commit f26e535fd8
4 changed files with 280 additions and 6 deletions

View File

@ -4,8 +4,8 @@ import (
"html/template"
"github.com/gin-gonic/gin"
"github.com/op/go-logging"
"github.com/gobuffalo/packr/v2"
"github.com/op/go-logging"
)
// Engine struct

260
core/migrate.go Normal file
View File

@ -0,0 +1,260 @@
package core
import (
"sort"
"github.com/jinzhu/gorm"
"github.com/pkg/errors"
"gopkg.in/gormigrate.v1"
)
// migrations default GORMigrate tool
var migrations *Migrate
// Migrate tool, decorates gormigrate.Migration in order to provide better interface & versioning
type Migrate struct {
db *gorm.DB
first *gormigrate.Migration
versions []string
migrations map[string]*gormigrate.Migration
GORMigrate *gormigrate.Gormigrate
prepared bool
}
// MigrationInfo with migration info
type MigrationInfo struct {
ID string `gorm:"column:id; type:varchar(255)"`
}
// TableName for MigrationInfo
func (MigrationInfo) TableName() string {
return "migrations"
}
// Migrations returns default migrate
func Migrations() *Migrate {
if migrations == nil {
migrations = &Migrate{
db: nil,
prepared: false,
migrations: map[string]*gormigrate.Migration{},
}
}
return migrations
}
// Add GORMigrate to migrate
func (m *Migrate) Add(migration *gormigrate.Migration) {
if migration == nil {
return
}
m.migrations[migration.ID] = migration
}
// SetORM to migrate
func (m *Migrate) SetDB(db *gorm.DB) *Migrate {
m.db = db
return m
}
// Migrate all, including schema initialization
func (m *Migrate) Migrate() error {
if err := m.prepareMigrations(); err != nil {
return err
}
if len(m.migrations) > 0 {
return m.GORMigrate.Migrate()
}
return nil
}
// Rollback all migrations
func (m *Migrate) Rollback() error {
if err := m.prepareMigrations(); err != nil {
return err
}
if err := m.GORMigrate.RollbackTo(m.first.ID); err == nil {
if err := m.GORMigrate.RollbackMigration(m.first); err == nil {
return nil
} else {
return err
}
} else {
return err
}
}
// MigrateTo specified version
func (m *Migrate) MigrateTo(version string) error {
if err := m.prepareMigrations(); err != nil {
return err
}
current := m.Current()
switch {
case current > version:
return m.GORMigrate.RollbackTo(version)
case current < version:
return m.GORMigrate.MigrateTo(version)
default:
return nil
}
}
// MigrateNextTo migrate to next version from specified version
func (m *Migrate) MigrateNextTo(version string) error {
if err := m.prepareMigrations(); err != nil {
return err
}
if next, err := m.NextFrom(version); err == nil {
current := m.Current()
switch {
case current > next:
return m.GORMigrate.RollbackTo(next)
case current < next:
return m.GORMigrate.MigrateTo(next)
default:
return nil
}
} else {
return nil
}
}
// MigratePreviousTo migrate to previous version from specified version
func (m *Migrate) MigratePreviousTo(version string) error {
if err := m.prepareMigrations(); err != nil {
return err
}
if prev, err := m.PreviousFrom(version); err == nil {
current := m.Current()
switch {
case current > prev:
return m.GORMigrate.RollbackTo(prev)
case current < prev:
return m.GORMigrate.MigrateTo(prev)
default:
return nil
}
} else {
return nil
}
}
// RollbackTo specified version
func (m *Migrate) RollbackTo(version string) error {
if err := m.prepareMigrations(); err != nil {
return err
}
return m.GORMigrate.RollbackTo(version)
}
// Current migration version
func (m *Migrate) Current() string {
var migrationInfo MigrationInfo
if m.db == nil {
return "0"
}
if !m.db.HasTable(MigrationInfo{}) {
m.db.CreateTable(MigrationInfo{})
return "0"
}
if err := m.db.Last(&migrationInfo).Error; err == nil {
return migrationInfo.ID
} else {
return "0"
}
}
// NextFrom returns next version from passed version
func (m *Migrate) NextFrom(version string) (string, error) {
for key, ver := range m.versions {
if ver == version {
if key < (len(m.versions) - 1) {
return m.versions[key+1], nil
} else {
return "", errors.New("this is last migration")
}
}
}
return "", errors.New("cannot find specified migration")
}
// PreviousFrom returns previous version from passed version
func (m *Migrate) PreviousFrom(version string) (string, error) {
for key, ver := range m.versions {
if ver == version {
if key > 0 {
return m.versions[key-1], nil
} else {
return "", errors.New("this is first migration")
}
}
}
return "", errors.New("cannot find specified migration")
}
// Close db connection
func (m *Migrate) Close() error {
return m.db.Close()
}
// prepareMigrations prepare migrate
func (m *Migrate) prepareMigrations() error {
var (
keys []string
migrations []*gormigrate.Migration
)
if m.db == nil {
return errors.New("db must not be nil")
}
if m.prepared {
return nil
}
for key := range m.migrations {
keys = append(keys, key)
}
sort.Strings(keys)
m.versions = keys
if len(keys) > 0 {
if i, ok := m.migrations[keys[0]]; ok {
m.first = i
}
}
for _, key := range keys {
if i, ok := m.migrations[key]; ok {
migrations = append(migrations, i)
}
}
options := &gormigrate.Options{
TableName: gormigrate.DefaultOptions.TableName,
IDColumnName: gormigrate.DefaultOptions.IDColumnName,
IDColumnSize: gormigrate.DefaultOptions.IDColumnSize,
UseTransaction: true,
ValidateUnknownMigrations: true,
}
m.GORMigrate = gormigrate.New(m.db, options, migrations)
m.prepared = true
return nil
}

7
go.mod
View File

@ -6,18 +6,14 @@ require (
github.com/aws/aws-sdk-go v1.23.9
github.com/certifi/gocertifi v0.0.0-20190506164543-d2eda7129713 // indirect
github.com/denisenkom/go-mssqldb v0.0.0-20190830225923-3302f0226fbd // indirect
github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5 // indirect
github.com/getsentry/raven-go v0.0.0-20180903072508-084a9de9eb03
github.com/gin-contrib/multitemplate v0.0.0-20180827023943-5799bbbb6dce
github.com/gin-contrib/sse v0.1.0 // indirect
github.com/gin-gonic/gin v1.3.0
github.com/go-sql-driver/mysql v1.4.1 // indirect
github.com/gobuffalo/packr/v2 v2.6.0
github.com/golang/protobuf v1.3.2 // indirect
github.com/google/go-querystring v1.0.0 // indirect
github.com/jinzhu/gorm v1.9.1
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.0.1 // indirect
github.com/jinzhu/gorm v1.9.10
github.com/lib/pq v1.2.0 // indirect
github.com/mattn/go-isatty v0.0.9 // indirect
github.com/mattn/go-sqlite3 v1.11.0 // indirect
@ -32,5 +28,6 @@ require (
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2
golang.org/x/tools v0.0.0-20190830082254-f340ed3ae274 // indirect
gopkg.in/go-playground/validator.v8 v8.18.2
gopkg.in/gormigrate.v1 v1.6.0 // indirect
gopkg.in/yaml.v2 v2.2.2
)

17
go.sum
View File

@ -1,4 +1,5 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.33.1/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.37.4 h1:glPeL3BQJsbF6aIIYfZizMwc5LTYz250bDMjttbBGAU=
cloud.google.com/go v0.37.4/go.mod h1:NHPJ89PdicEuT9hdPXMROBD91xc5uRDxsMtSB16k7hw=
@ -25,6 +26,8 @@ github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/denisenkom/go-mssqldb v0.0.0-20181014144952-4e0d7dc8888f/go.mod h1:xN/JuLBIz4bjkxNmByTiV1IbhfnYb6oo99phBn4Eqhc=
github.com/denisenkom/go-mssqldb v0.0.0-20190515213511-eb9f6a1743f3/go.mod h1:zAg7JM8CkOJ43xKXIj7eRO9kmWm/TW578qo+oDO6tuM=
github.com/denisenkom/go-mssqldb v0.0.0-20190830225923-3302f0226fbd h1:DoaaxHqzWPQCWKSTmsi8UDSiFqxbfue+Xt+qi/BFKb8=
github.com/denisenkom/go-mssqldb v0.0.0-20190830225923-3302f0226fbd/go.mod h1:uU0N10vx1abI4qeVe79CxepBP6PPREVTgMS5Gx6/mOk=
github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
@ -51,6 +54,7 @@ github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSC
github.com/gobuffalo/logger v1.0.0/go.mod h1:2zbswyIUa45I+c+FLXuWl9zSWEiVuthsk8ze5s8JvPs=
github.com/gobuffalo/packd v0.3.0/go.mod h1:zC7QkmNkYVGKPw4tHpBQ+ml7W/3tIebgeo1b36chA3Q=
github.com/gobuffalo/packr/v2 v2.6.0/go.mod h1:sgEE1xNZ6G0FNN5xn9pevVu4nywaxHvgup67xisti08=
github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
@ -79,8 +83,14 @@ github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpO
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/jinzhu/gorm v1.9.1 h1:lDSDtsCt5AGGSKTs8AHlSDbbgif4G4+CKJ8ETBDVHTA=
github.com/jinzhu/gorm v1.9.1/go.mod h1:Vla75njaFJ8clLU1W44h34PjIkijhjHIYnZxMqCdxqo=
github.com/jinzhu/gorm v1.9.2 h1:lCvgEaqe/HVE+tjAR2mt4HbbHAZsQOv3XAZiEZV37iw=
github.com/jinzhu/gorm v1.9.2/go.mod h1:Vla75njaFJ8clLU1W44h34PjIkijhjHIYnZxMqCdxqo=
github.com/jinzhu/gorm v1.9.10 h1:HvrsqdhCW78xpJF67g1hMxS6eCToo9PZH4LDB8WKPac=
github.com/jinzhu/gorm v1.9.10/go.mod h1:Kh6hTsSGffh4ui079FHrR5Gg+5D0hgihqDcsDN2BBJY=
github.com/jinzhu/inflection v0.0.0-20180308033659-04140366298a/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
github.com/jinzhu/now v0.0.0-20181116074157-8ec929ed50c3/go.mod h1:oHTiXerJ20+SfYcrdlBO7rzZRJWGwSTQ0iUY2jI6Gfc=
github.com/jinzhu/now v1.0.1 h1:HjfetcXq097iXP0uoPCdnM4Efp5/9MsM0/M+XOTeR3M=
github.com/jinzhu/now v1.0.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM=
@ -96,6 +106,8 @@ github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFB
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.2.0 h1:LXpIM/LZ5xGFhOpXAQUIMM1HdyqzVYM13zNdjCEEcA0=
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
@ -103,6 +115,7 @@ github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVc
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.9 h1:d5US/mDsogSGW37IV293h//ZFaeajb69h+EHFsv2xGg=
github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/mattn/go-sqlite3 v1.11.0 h1:LDdKkqtYlom37fkvqs8rMPFKAMe8+SgjbwZ6ex1/A/Q=
github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
@ -161,6 +174,7 @@ github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLY
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181112202954-3d3f9f413869/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c h1:Vj5n4GlwjmQteupaxJ9+0FNOmBrHfq7vN4btdGoDZgI=
@ -219,6 +233,7 @@ golang.org/x/tools v0.0.0-20190830082254-f340ed3ae274/go.mod h1:b+2E5dAYhXwXZwtn
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
@ -233,6 +248,8 @@ gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/go-playground/validator.v8 v8.18.2 h1:lFB4DoMU6B626w8ny76MV7VX6W2VHct2GVOI3xgiMrQ=
gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y=
gopkg.in/gormigrate.v1 v1.6.0 h1:XpYM6RHQPmzwY7Uyu+t+xxMXc86JYFJn4nEc9HzQjsI=
gopkg.in/gormigrate.v1 v1.6.0/go.mod h1:Lf00lQrHqfSYWiTtPcyQabsDdM6ejZaMgV0OU6JMSlw=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=