From 80ffe320aa41ad64556159afc8d85b12fa22db08 Mon Sep 17 00:00:00 2001 From: Maxim Krasilnikov Date: Thu, 24 May 2018 00:29:12 +0300 Subject: [PATCH] Another migrate pkg (#3) --- Gopkg.lock | 18 +- README.md | 6 +- converter/converter.go | 2 +- driver/{stump => impg}/migrator.go | 4 +- driver/interface.go | 10 +- .../{stump => impg}/101_wrong.down.sql | 0 .../{stump => impg}/101_wrong.up.sql | 0 .../{stump => impg}/102_never.down.sql | 0 .../{stump => impg}/102_never.up.sql | 0 .../{stump => impg}/1_users.down.sql | 0 .../migrations/{stump => impg}/1_users.up.sql | 0 .../{stump => impg}/2_wallets.down.sql | 0 .../{stump => impg}/2_wallets.up.sql | 0 .../3_add_users_email.down.sql | 0 .../{stump => impg}/3_add_users_email.up.sql | 0 .../{stump => impg}/4_text.down.sql | 0 .../migrations/{stump => impg}/4_text.up.sql | 0 .../{stump => impg}/5_statement.down.sql | 0 .../{stump => impg}/5_statement.up.sql | 0 tests/vars.go | 2 +- vendor/github.com/go-pg/pg/CHANGELOG.md | 8 + vendor/github.com/go-pg/pg/README.md | 1 + vendor/github.com/go-pg/pg/db.go | 12 +- vendor/github.com/go-pg/pg/error.go | 5 + vendor/github.com/go-pg/pg/options.go | 2 +- .../github.com/go-pg/pg/orm/count_estimate.go | 2 +- .../github.com/go-pg/pg/orm/create_table.go | 7 +- vendor/github.com/go-pg/pg/orm/drop_table.go | 7 +- vendor/github.com/go-pg/pg/orm/field.go | 9 +- vendor/github.com/go-pg/pg/orm/format.go | 13 +- vendor/github.com/go-pg/pg/orm/insert.go | 14 +- vendor/github.com/go-pg/pg/orm/model.go | 8 +- vendor/github.com/go-pg/pg/orm/model_func.go | 89 ++++ vendor/github.com/go-pg/pg/orm/model_scan.go | 52 +- vendor/github.com/go-pg/pg/orm/model_table.go | 6 +- .../go-pg/pg/orm/model_table_struct.go | 8 +- vendor/github.com/go-pg/pg/orm/query.go | 165 +++--- vendor/github.com/go-pg/pg/orm/relation.go | 10 +- vendor/github.com/go-pg/pg/orm/table.go | 481 ++++++++++-------- .../github.com/go-pg/pg/orm/table_params.go | 2 +- vendor/github.com/go-pg/pg/orm/tables.go | 71 ++- vendor/github.com/go-pg/pg/orm/update.go | 7 +- vendor/github.com/go-pg/pg/pg.go | 14 +- vendor/github.com/go-pg/pg/tx.go | 5 + .../github.com/im-kulikov/migrate/.gitignore | 14 + .../github.com/im-kulikov/migrate/Gopkg.lock | 46 ++ .../github.com/im-kulikov/migrate/Gopkg.toml | 42 ++ .../stump => im-kulikov/migrate}/LICENSE | 2 +- .../github.com/im-kulikov/migrate/README.md | 9 + .../package => im-kulikov}/migrate/helpers.go | 2 +- .../package => im-kulikov}/migrate/migrate.go | 3 +- .../package => im-kulikov}/migrate/vars.go | 7 +- .../m1ome/stump/package/migrate/.gitkeep | 0 53 files changed, 778 insertions(+), 387 deletions(-) rename driver/{stump => impg}/migrator.go (97%) rename tests/migrations/{stump => impg}/101_wrong.down.sql (100%) rename tests/migrations/{stump => impg}/101_wrong.up.sql (100%) rename tests/migrations/{stump => impg}/102_never.down.sql (100%) rename tests/migrations/{stump => impg}/102_never.up.sql (100%) rename tests/migrations/{stump => impg}/1_users.down.sql (100%) rename tests/migrations/{stump => impg}/1_users.up.sql (100%) rename tests/migrations/{stump => impg}/2_wallets.down.sql (100%) rename tests/migrations/{stump => impg}/2_wallets.up.sql (100%) rename tests/migrations/{stump => impg}/3_add_users_email.down.sql (100%) rename tests/migrations/{stump => impg}/3_add_users_email.up.sql (100%) rename tests/migrations/{stump => impg}/4_text.down.sql (100%) rename tests/migrations/{stump => impg}/4_text.up.sql (100%) rename tests/migrations/{stump => impg}/5_statement.down.sql (100%) rename tests/migrations/{stump => impg}/5_statement.up.sql (100%) create mode 100644 vendor/github.com/go-pg/pg/orm/model_func.go create mode 100644 vendor/github.com/im-kulikov/migrate/.gitignore create mode 100644 vendor/github.com/im-kulikov/migrate/Gopkg.lock create mode 100644 vendor/github.com/im-kulikov/migrate/Gopkg.toml rename vendor/github.com/{m1ome/stump => im-kulikov/migrate}/LICENSE (96%) create mode 100644 vendor/github.com/im-kulikov/migrate/README.md rename vendor/github.com/{m1ome/stump/package => im-kulikov}/migrate/helpers.go (99%) rename vendor/github.com/{m1ome/stump/package => im-kulikov}/migrate/migrate.go (99%) rename vendor/github.com/{m1ome/stump/package => im-kulikov}/migrate/vars.go (94%) delete mode 100644 vendor/github.com/m1ome/stump/package/migrate/.gitkeep diff --git a/Gopkg.lock b/Gopkg.lock index 03d0c08..1dacbb5 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -17,8 +17,8 @@ "orm", "types" ] - revision = "5b73ce88484575f3480edf393237f6bf79d5f166" - version = "v6.11.2" + revision = "1e63a7fcab7d4389be48b02a4997c87771fcfae8" + version = "v6.13.2" [[projects]] name = "github.com/go-sql-driver/mysql" @@ -62,6 +62,12 @@ ] revision = "ef8a98b0bbce4a65b5aa4c368430a80ddc533168" +[[projects]] + name = "github.com/im-kulikov/migrate" + packages = ["."] + revision = "d4c757bb8788aab88714200b6cee2c32d1eb9954" + version = "0.1" + [[projects]] branch = "master" name = "github.com/jinzhu/inflection" @@ -83,12 +89,6 @@ ] revision = "d34b9ff171c21ad295489235aec8b6626023cd04" -[[projects]] - branch = "master" - name = "github.com/m1ome/stump" - packages = ["package/migrate"] - revision = "a3828aa14114dd2ca24265a42ebc39d35fa73649" - [[projects]] name = "github.com/magiconair/properties" packages = ["."] @@ -231,6 +231,6 @@ [solve-meta] analyzer-name = "dep" analyzer-version = 1 - inputs-digest = "66d45a0ecdfeb846cb107ab625eb44b570df0853ef23943c6f5138f3ede679f1" + inputs-digest = "86f56382f7ac9490aa2dea248cb88c3fc05ea35419a01a2ee3b0d406032d6b27" solver-name = "gps-cdcl" solver-version = 1 diff --git a/README.md b/README.md index d019013..3c7d26e 100644 --- a/README.md +++ b/README.md @@ -17,8 +17,10 @@ Aimed to add extra features and hide some limitations of existing golang migrati PackageName | Version | Postgres | MySQL ----------- | ------- | ------------------- | -------- -goose | 2.3.0 | :heavy_check_mark: | :heavy_check_mark: -migrate | 3.2.0 | :heavy_check_mark: | :heavy_check_mark: +[goose](https://github.com/pressly/goose) | 2.3.0 | :heavy_check_mark: | :heavy_check_mark: +[migrate](https://github.com/golang-migrate/migrate) | 3.2.0 | :heavy_check_mark: | :heavy_check_mark: +[impg](https://github.com/im-kulikov/migrate) | 0.1 | :heavy_check_mark: + ## Features diff --git a/converter/converter.go b/converter/converter.go index ee2dde7..7077df6 100644 --- a/converter/converter.go +++ b/converter/converter.go @@ -60,7 +60,7 @@ func createFormatter(name string) (Formatter, error) { return &GooseFormatter{}, nil case driver.Migrate: return &MigrateFormatter{}, nil - case driver.Stump: + case driver.Impg: return &MigrateFormatter{}, nil default: return nil, fmt.Errorf("unsupported driver name %s", name) diff --git a/driver/stump/migrator.go b/driver/impg/migrator.go similarity index 97% rename from driver/stump/migrator.go rename to driver/impg/migrator.go index a4e6aeb..bcbad0b 100644 --- a/driver/stump/migrator.go +++ b/driver/impg/migrator.go @@ -1,4 +1,4 @@ -package stump +package impg import ( "fmt" @@ -9,7 +9,7 @@ import ( "github.com/chapsuk/miga/logger" "github.com/chapsuk/miga/utils" "github.com/go-pg/pg" - orig "github.com/m1ome/stump/package/migrate" + orig "github.com/im-kulikov/migrate" ) type Migrator struct { diff --git a/driver/interface.go b/driver/interface.go index 39ebd4b..b52057e 100644 --- a/driver/interface.go +++ b/driver/interface.go @@ -4,21 +4,21 @@ import ( "errors" "github.com/chapsuk/miga/driver/goose" + "github.com/chapsuk/miga/driver/impg" "github.com/chapsuk/miga/driver/migrate" - "github.com/chapsuk/miga/driver/stump" ) const ( Goose = "goose" Migrate = "migrate" - Stump = "stump" + Impg = "impg" ) func Available(name string) bool { switch name { case Goose: case Migrate: - // case Stump: + case Impg: default: return false } @@ -63,8 +63,8 @@ func New(cfg *Config) (Interface, error) { cfg.VersionTableName, cfg.Dir, ) - case Stump: - return stump.New( + case Impg: + return impg.New( cfg.Dialect, cfg.Dsn, cfg.VersionTableName, diff --git a/tests/migrations/stump/101_wrong.down.sql b/tests/migrations/impg/101_wrong.down.sql similarity index 100% rename from tests/migrations/stump/101_wrong.down.sql rename to tests/migrations/impg/101_wrong.down.sql diff --git a/tests/migrations/stump/101_wrong.up.sql b/tests/migrations/impg/101_wrong.up.sql similarity index 100% rename from tests/migrations/stump/101_wrong.up.sql rename to tests/migrations/impg/101_wrong.up.sql diff --git a/tests/migrations/stump/102_never.down.sql b/tests/migrations/impg/102_never.down.sql similarity index 100% rename from tests/migrations/stump/102_never.down.sql rename to tests/migrations/impg/102_never.down.sql diff --git a/tests/migrations/stump/102_never.up.sql b/tests/migrations/impg/102_never.up.sql similarity index 100% rename from tests/migrations/stump/102_never.up.sql rename to tests/migrations/impg/102_never.up.sql diff --git a/tests/migrations/stump/1_users.down.sql b/tests/migrations/impg/1_users.down.sql similarity index 100% rename from tests/migrations/stump/1_users.down.sql rename to tests/migrations/impg/1_users.down.sql diff --git a/tests/migrations/stump/1_users.up.sql b/tests/migrations/impg/1_users.up.sql similarity index 100% rename from tests/migrations/stump/1_users.up.sql rename to tests/migrations/impg/1_users.up.sql diff --git a/tests/migrations/stump/2_wallets.down.sql b/tests/migrations/impg/2_wallets.down.sql similarity index 100% rename from tests/migrations/stump/2_wallets.down.sql rename to tests/migrations/impg/2_wallets.down.sql diff --git a/tests/migrations/stump/2_wallets.up.sql b/tests/migrations/impg/2_wallets.up.sql similarity index 100% rename from tests/migrations/stump/2_wallets.up.sql rename to tests/migrations/impg/2_wallets.up.sql diff --git a/tests/migrations/stump/3_add_users_email.down.sql b/tests/migrations/impg/3_add_users_email.down.sql similarity index 100% rename from tests/migrations/stump/3_add_users_email.down.sql rename to tests/migrations/impg/3_add_users_email.down.sql diff --git a/tests/migrations/stump/3_add_users_email.up.sql b/tests/migrations/impg/3_add_users_email.up.sql similarity index 100% rename from tests/migrations/stump/3_add_users_email.up.sql rename to tests/migrations/impg/3_add_users_email.up.sql diff --git a/tests/migrations/stump/4_text.down.sql b/tests/migrations/impg/4_text.down.sql similarity index 100% rename from tests/migrations/stump/4_text.down.sql rename to tests/migrations/impg/4_text.down.sql diff --git a/tests/migrations/stump/4_text.up.sql b/tests/migrations/impg/4_text.up.sql similarity index 100% rename from tests/migrations/stump/4_text.up.sql rename to tests/migrations/impg/4_text.up.sql diff --git a/tests/migrations/stump/5_statement.down.sql b/tests/migrations/impg/5_statement.down.sql similarity index 100% rename from tests/migrations/stump/5_statement.down.sql rename to tests/migrations/impg/5_statement.down.sql diff --git a/tests/migrations/stump/5_statement.up.sql b/tests/migrations/impg/5_statement.up.sql similarity index 100% rename from tests/migrations/stump/5_statement.up.sql rename to tests/migrations/impg/5_statement.up.sql diff --git a/tests/vars.go b/tests/vars.go index 76837e9..7035de1 100644 --- a/tests/vars.go +++ b/tests/vars.go @@ -23,7 +23,7 @@ var ( drivers = map[driverName]dialects{ "goose": []string{"mysql", "postgres"}, "migrate": []string{"mysql", "postgres"}, - // "stump": []string{"postgres"}, + "impg": []string{"postgres"}, } dsns = map[string]dsn{ diff --git a/vendor/github.com/go-pg/pg/CHANGELOG.md b/vendor/github.com/go-pg/pg/CHANGELOG.md index e6b605e..b54f830 100644 --- a/vendor/github.com/go-pg/pg/CHANGELOG.md +++ b/vendor/github.com/go-pg/pg/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## v6.12 + +- `Insert`, `Update`, and `Delete` can return `pg.ErrNoRows` and `pg.ErrMultiRows` when `Returning` is used and model expects single row. + +## v6.11 + +- `db.Model(&strct).Update()` and `db.Model(&strct).Delete()` no longer adds WHERE condition based on primary key when there are no conditions. Instead you should use `db.Update(&strct)` or `db.Model(&strct).WherePK().Update()`. + ## v6.10 - `?Columns` is renamed to `?TableColumns`. `?Columns` is changed to produce column names without table alias. diff --git a/vendor/github.com/go-pg/pg/README.md b/vendor/github.com/go-pg/pg/README.md index 5d8b73e..1e38b1c 100644 --- a/vendor/github.com/go-pg/pg/README.md +++ b/vendor/github.com/go-pg/pg/README.md @@ -29,6 +29,7 @@ - ORM supports [has one](https://godoc.org/github.com/go-pg/pg#example-DB-Model-HasOne), [belongs to](https://godoc.org/github.com/go-pg/pg#example-DB-Model-BelongsTo), [has many](https://godoc.org/github.com/go-pg/pg#example-DB-Model-HasMany), and [many to many](https://godoc.org/github.com/go-pg/pg#example-DB-Model-ManyToMany) with composite/multi-column primary keys. - [Creating tables from structs](https://godoc.org/github.com/go-pg/pg#example-DB-CreateTable). - [Pagination](https://godoc.org/github.com/go-pg/pg/orm#Pagination) and [URL filters](https://godoc.org/github.com/go-pg/pg/orm#URLFilters) helpers. +- [ForEach](https://godoc.org/github.com/go-pg/pg#example-DB-Model-ForEach) that calls a function for each row returned by the query without loading all rows into the memory. - Works with PgBouncer in transaction pooling mode. - [Migrations](https://github.com/go-pg/migrations). - [Sharding](https://github.com/go-pg/sharding). diff --git a/vendor/github.com/go-pg/pg/db.go b/vendor/github.com/go-pg/pg/db.go index c443d94..d9ec607 100644 --- a/vendor/github.com/go-pg/pg/db.go +++ b/vendor/github.com/go-pg/pg/db.go @@ -47,6 +47,7 @@ func (db *DB) Options() *Options { return db.opt } +// Context returns DB context. func (db *DB) Context() context.Context { if db.ctx != nil { return db.ctx @@ -54,6 +55,7 @@ func (db *DB) Context() context.Context { return context.Background() } +// WithContext returns a copy of the DB that uses the ctx. func (db *DB) WithContext(ctx context.Context) *DB { return &DB{ opt: db.opt, @@ -66,7 +68,7 @@ func (db *DB) WithContext(ctx context.Context) *DB { } } -// WithTimeout returns a DB that uses d as the read/write timeout. +// WithTimeout returns a copy of the DB that uses d as the read/write timeout. func (db *DB) WithTimeout(d time.Duration) *DB { newopt := *db.opt newopt.ReadTimeout = d @@ -83,7 +85,8 @@ func (db *DB) WithTimeout(d time.Duration) *DB { } } -// WithParam returns a DB that replaces the param with the value in queries. +// WithParam returns a copy of the DB that replaces the param with the value +// in queries. func (db *DB) WithParam(param string, value interface{}) *DB { return &DB{ opt: db.opt, @@ -96,6 +99,11 @@ func (db *DB) WithParam(param string, value interface{}) *DB { } } +// Param returns value for the param. +func (db *DB) Param(param string) (interface{}, bool) { + return db.fmter.Param(param) +} + type PoolStats pool.Stats // PoolStats returns connection pool stats. diff --git a/vendor/github.com/go-pg/pg/error.go b/vendor/github.com/go-pg/pg/error.go index b906ea2..9952076 100644 --- a/vendor/github.com/go-pg/pg/error.go +++ b/vendor/github.com/go-pg/pg/error.go @@ -7,7 +7,12 @@ import ( "github.com/go-pg/pg/internal" ) +// ErrNoRows is returned by QueryOne and ExecOne when query returned zero rows +// but at least one row is expected. var ErrNoRows = internal.ErrNoRows + +// ErrMultiRows is returned by QueryOne and ExecOne when query returned +// multiple rows but exactly one row is expected. var ErrMultiRows = internal.ErrMultiRows // Error represents an error returned by PostgreSQL server diff --git a/vendor/github.com/go-pg/pg/options.go b/vendor/github.com/go-pg/pg/options.go index c107e3f..0a321fa 100644 --- a/vendor/github.com/go-pg/pg/options.go +++ b/vendor/github.com/go-pg/pg/options.go @@ -134,7 +134,7 @@ func ParseURL(sURL string) (*Options, error) { } // scheme - if parsedUrl.Scheme != "postgres" { + if parsedUrl.Scheme != "postgres" && parsedUrl.Scheme != "postgresql" { return nil, errors.New("pg: invalid scheme: " + parsedUrl.Scheme) } diff --git a/vendor/github.com/go-pg/pg/orm/count_estimate.go b/vendor/github.com/go-pg/pg/orm/count_estimate.go index 2fd26e9..3d6f8cf 100644 --- a/vendor/github.com/go-pg/pg/orm/count_estimate.go +++ b/vendor/github.com/go-pg/pg/orm/count_estimate.go @@ -41,7 +41,7 @@ END; $$ LANGUAGE plpgsql; `, placeholder) -// CountEstimate uses EXPLAIN to get estimated number of rows matching the query. +// CountEstimate uses EXPLAIN to get estimated number of rows returned the query. // If that number is bigger than the threshold it returns the estimation. // Otherwise it executes another query using count aggregate function and // returns the result. diff --git a/vendor/github.com/go-pg/pg/orm/create_table.go b/vendor/github.com/go-pg/pg/orm/create_table.go index 9f9bc94..7f714d6 100644 --- a/vendor/github.com/go-pg/pg/orm/create_table.go +++ b/vendor/github.com/go-pg/pg/orm/create_table.go @@ -17,7 +17,12 @@ type CreateTableOptions struct { } func CreateTable(db DB, model interface{}, opt *CreateTableOptions) (Result, error) { - return NewQuery(db, model).CreateTable(opt) + q := NewQuery(db, model) + + return q.db.Exec(createTableQuery{ + q: q, + opt: opt, + }) } type createTableQuery struct { diff --git a/vendor/github.com/go-pg/pg/orm/drop_table.go b/vendor/github.com/go-pg/pg/orm/drop_table.go index c1640d0..d3aa094 100644 --- a/vendor/github.com/go-pg/pg/orm/drop_table.go +++ b/vendor/github.com/go-pg/pg/orm/drop_table.go @@ -8,7 +8,12 @@ type DropTableOptions struct { } func DropTable(db DB, model interface{}, opt *DropTableOptions) (Result, error) { - return NewQuery(db, model).DropTable(opt) + q := NewQuery(db, model) + + return q.db.Exec(dropTableQuery{ + q: q, + opt: opt, + }) } type dropTableQuery struct { diff --git a/vendor/github.com/go-pg/pg/orm/field.go b/vendor/github.com/go-pg/pg/orm/field.go index bcabb8c..d8b53e0 100644 --- a/vendor/github.com/go-pg/pg/orm/field.go +++ b/vendor/github.com/go-pg/pg/orm/field.go @@ -16,7 +16,8 @@ const ( ) type Field struct { - Type reflect.Type + Field reflect.StructField + Type reflect.Type GoName string // struct field name, e.g. Id SQLName string // SQL name, .e.g. id @@ -47,9 +48,9 @@ func indexEqual(ind1, ind2 []int) bool { } func (f *Field) Copy() *Field { - copy := *f - copy.Index = copy.Index[:len(f.Index):len(f.Index)] - return © + cp := *f + cp.Index = cp.Index[:len(f.Index):len(f.Index)] + return &cp } func (f *Field) SetFlag(flag uint8) { diff --git a/vendor/github.com/go-pg/pg/orm/format.go b/vendor/github.com/go-pg/pg/orm/format.go index 8ef421f..5a4ac1f 100644 --- a/vendor/github.com/go-pg/pg/orm/format.go +++ b/vendor/github.com/go-pg/pg/orm/format.go @@ -7,6 +7,7 @@ import ( "strconv" "strings" + "github.com/go-pg/pg/internal" "github.com/go-pg/pg/internal/parser" "github.com/go-pg/pg/types" ) @@ -44,6 +45,11 @@ func (q *queryParamsAppender) AppendValue(b []byte, quote int) []byte { return q.AppendFormat(b, formatter) } +func (q *queryParamsAppender) Value() types.Q { + b := q.AppendValue(nil, 1) + return types.Q(internal.BytesToString(b)) +} + //------------------------------------------------------------------------------ type condGroupAppender struct { @@ -149,6 +155,11 @@ func (f *Formatter) WithParam(param string, value interface{}) Formatter { return cp } +func (f Formatter) Param(param string) (interface{}, bool) { + v, ok := f.namedParams[param] + return v, ok +} + func (f Formatter) Append(dst []byte, src string, params ...interface{}) []byte { if (params == nil && f.namedParams == nil) || strings.IndexByte(src, '?') == -1 { return append(dst, src...) @@ -210,7 +221,7 @@ func (f Formatter) append(dst []byte, p *parser.Parser, params []interface{}) [] } if f.namedParams != nil { - param, paramOK := f.namedParams[id] + param, paramOK := f.Param(id) if paramOK { dst = f.appendParam(dst, param) continue diff --git a/vendor/github.com/go-pg/pg/orm/insert.go b/vendor/github.com/go-pg/pg/orm/insert.go index ba4e02f..5e1c201 100644 --- a/vendor/github.com/go-pg/pg/orm/insert.go +++ b/vendor/github.com/go-pg/pg/orm/insert.go @@ -18,17 +18,17 @@ type insertQuery struct { var _ QueryAppender = (*insertQuery)(nil) -func (q insertQuery) Copy() QueryAppender { - return insertQuery{ +func (q *insertQuery) Copy() QueryAppender { + return &insertQuery{ q: q.q.Copy(), } } -func (q insertQuery) Query() *Query { +func (q *insertQuery) Query() *Query { return q.q } -func (q insertQuery) AppendQuery(b []byte) ([]byte, error) { +func (q *insertQuery) AppendQuery(b []byte) ([]byte, error) { if q.q.stickyErr != nil { return nil, q.q.stickyErr } @@ -116,7 +116,7 @@ func (q insertQuery) AppendQuery(b []byte) ([]byte, error) { if len(q.q.returning) > 0 { b = q.q.appendReturning(b) } else if len(q.returningFields) > 0 { - b = q.appendReturningFields(b, q.returningFields) + b = appendReturningFields(b, q.returningFields) } return b, nil @@ -128,7 +128,7 @@ func (q *insertQuery) appendValues(b []byte, fields []*Field, v reflect.Value) [ b = append(b, ", "...) } - app, ok := q.q.values[f.SQLName] + app, ok := q.q.modelValues[f.SQLName] if ok { b = app.AppendFormat(b, q.q) continue @@ -153,7 +153,7 @@ func (ins *insertQuery) addReturningField(field *Field) { ins.returningFields = append(ins.returningFields, field) } -func (insertQuery) appendReturningFields(b []byte, fields []*Field) []byte { +func appendReturningFields(b []byte, fields []*Field) []byte { b = append(b, " RETURNING "...) b = appendColumns(b, "", fields) return b diff --git a/vendor/github.com/go-pg/pg/orm/model.go b/vendor/github.com/go-pg/pg/orm/model.go index 38f5fbc..60bae3f 100644 --- a/vendor/github.com/go-pg/pg/orm/model.go +++ b/vendor/github.com/go-pg/pg/orm/model.go @@ -15,15 +15,15 @@ type useQueryOne interface { type HooklessModel interface { // Init is responsible to initialize/reset model state. - // It is guaranteed to be called once no matter how many rows + // It is called only once no matter how many rows // were returned by database. Init() error // NewModel returns ColumnScanner that is used to scan columns - // from the current row. + // from the current row. It is called once for every row. NewModel() ColumnScanner - // AddModel adds ColumnScanner to the Collection. + // AddModel adds ColumnScanner created by NewModel to the Collection. AddModel(ColumnScanner) error ColumnScanner @@ -78,7 +78,7 @@ func NewModel(values ...interface{}) (Model, error) { if structType.Kind() == reflect.Struct && structType != timeType { m := sliceTableModel{ structTableModel: structTableModel{ - table: Tables.Get(structType), + table: GetTable(structType), root: v, }, slice: v, diff --git a/vendor/github.com/go-pg/pg/orm/model_func.go b/vendor/github.com/go-pg/pg/orm/model_func.go new file mode 100644 index 0000000..64b300b --- /dev/null +++ b/vendor/github.com/go-pg/pg/orm/model_func.go @@ -0,0 +1,89 @@ +package orm + +import ( + "fmt" + "reflect" +) + +var errorType = reflect.TypeOf((*error)(nil)).Elem() + +type funcModel struct { + Model + fnv reflect.Value + fnIn []reflect.Value +} + +var _ Model = (*funcModel)(nil) + +func newFuncModel(fn interface{}) *funcModel { + m := &funcModel{ + fnv: reflect.ValueOf(fn), + } + + fnt := m.fnv.Type() + if fnt.Kind() != reflect.Func { + panic(fmt.Errorf("ForEach expects a %s, got a %s", + reflect.Func, fnt.Kind())) + } + + if fnt.NumIn() < 1 { + panic(fmt.Errorf("ForEach expects at least 1 arg, got %d", fnt.NumIn())) + } + + if fnt.NumOut() != 1 { + panic(fmt.Errorf("ForEach must return 1 value, got %d", fnt.NumOut())) + } + if fnt.Out(0) != errorType { + panic(fmt.Errorf("ForEach must return an error, got %T", fnt.Out(0))) + } + + if fnt.NumIn() > 1 { + initFuncModelScan(m, fnt) + return m + } + + t0 := fnt.In(0) + var v0 reflect.Value + if t0.Kind() == reflect.Ptr { + t0 = t0.Elem() + v0 = reflect.New(t0) + } else { + v0 = reflect.New(t0).Elem() + } + + m.fnIn = []reflect.Value{v0} + + model, ok := v0.Interface().(Model) + if ok { + m.Model = model + return m + } + + if v0.Kind() == reflect.Ptr { + v0 = v0.Elem() + } + if v0.Kind() != reflect.Struct { + panic(fmt.Errorf("ForEach accepts a %s, got %s", + reflect.Struct, v0.Kind())) + } + m.Model = newStructTableModelValue(v0) + + return m +} + +func initFuncModelScan(m *funcModel, fnt reflect.Type) { + m.fnIn = make([]reflect.Value, fnt.NumIn()) + for i := 0; i < fnt.NumIn(); i++ { + m.fnIn[i] = reflect.New(fnt.In(i)).Elem() + } + m.Model = scanReflectValues(m.fnIn) +} + +func (m *funcModel) AddModel(_ ColumnScanner) error { + out := m.fnv.Call(m.fnIn) + errv := out[0] + if !errv.IsNil() { + return errv.Interface().(error) + } + return nil +} diff --git a/vendor/github.com/go-pg/pg/orm/model_scan.go b/vendor/github.com/go-pg/pg/orm/model_scan.go index f7b15fa..6874b73 100644 --- a/vendor/github.com/go-pg/pg/orm/model_scan.go +++ b/vendor/github.com/go-pg/pg/orm/model_scan.go @@ -2,37 +2,67 @@ package orm import ( "fmt" + "reflect" "github.com/go-pg/pg/types" ) -type valuesModel struct { +type scanValuesModel struct { Discard values []interface{} } -var _ Model = valuesModel{} +var _ Model = scanValuesModel{} -func Scan(values ...interface{}) valuesModel { - return valuesModel{ +func Scan(values ...interface{}) scanValuesModel { + return scanValuesModel{ values: values, } } -func (valuesModel) useQueryOne() bool { +func (scanValuesModel) useQueryOne() bool { return true } -func (m valuesModel) NewModel() ColumnScanner { +func (m scanValuesModel) NewModel() ColumnScanner { return m } -func (m valuesModel) ScanColumn(colIdx int, colName string, b []byte) error { +func (m scanValuesModel) ScanColumn(colIdx int, colName string, b []byte) error { if colIdx >= len(m.values) { - return fmt.Errorf( - "pg: no Scan var for column index=%d name=%q", - colIdx, colName, - ) + return fmt.Errorf("pg: no Scan var for column index=%d name=%q", + colIdx, colName) } return types.Scan(m.values[colIdx], b) } + +//------------------------------------------------------------------------------ + +type scanReflectValuesModel struct { + Discard + values []reflect.Value +} + +var _ Model = scanReflectValuesModel{} + +func scanReflectValues(values []reflect.Value) scanReflectValuesModel { + return scanReflectValuesModel{ + values: values, + } +} + +func (scanReflectValuesModel) useQueryOne() bool { + return true +} + +func (m scanReflectValuesModel) NewModel() ColumnScanner { + return m +} + +func (m scanReflectValuesModel) ScanColumn(colIdx int, colName string, b []byte) error { + if colIdx >= len(m.values) { + return fmt.Errorf("pg: no Scan var for column index=%d name=%q", + colIdx, colName) + } + return types.ScanValue(m.values[colIdx], b) +} diff --git a/vendor/github.com/go-pg/pg/orm/model_table.go b/vendor/github.com/go-pg/pg/orm/model_table.go index 30ab234..4d16814 100644 --- a/vendor/github.com/go-pg/pg/orm/model_table.go +++ b/vendor/github.com/go-pg/pg/orm/model_table.go @@ -61,7 +61,7 @@ func newTableModelValue(v reflect.Value) (tableModel, error) { if structType.Kind() == reflect.Struct { m := sliceTableModel{ structTableModel: structTableModel{ - table: Tables.Get(structType), + table: GetTable(structType), root: v, }, slice: v, @@ -79,7 +79,7 @@ func newTableModelIndex(root reflect.Value, index []int, rel *Relation) (tableMo if typ.Kind() == reflect.Struct { return &structTableModel{ - table: Tables.Get(typ), + table: GetTable(typ), rel: rel, root: root, @@ -92,7 +92,7 @@ func newTableModelIndex(root reflect.Value, index []int, rel *Relation) (tableMo if structType.Kind() == reflect.Struct { m := sliceTableModel{ structTableModel: structTableModel{ - table: Tables.Get(structType), + table: GetTable(structType), rel: rel, root: root, diff --git a/vendor/github.com/go-pg/pg/orm/model_table_struct.go b/vendor/github.com/go-pg/pg/orm/model_table_struct.go index 9df915b..d5cdc44 100644 --- a/vendor/github.com/go-pg/pg/orm/model_table_struct.go +++ b/vendor/github.com/go-pg/pg/orm/model_table_struct.go @@ -22,7 +22,7 @@ var _ tableModel = (*structTableModel)(nil) func newStructTableModelValue(v reflect.Value) *structTableModel { return &structTableModel{ - table: Tables.Get(v.Type()), + table: GetTable(v.Type()), root: v, strct: v, } @@ -30,7 +30,7 @@ func newStructTableModelValue(v reflect.Value) *structTableModel { func newStructTableModelType(typ reflect.Type) *structTableModel { return &structTableModel{ - table: Tables.Get(typ), + table: GetTable(typ), } } @@ -202,8 +202,8 @@ func (m *structTableModel) ScanColumn(colIdx int, colName string, b []byte) erro if m.table.HasFlag(discardUnknownColumns) { return nil } - return fmt.Errorf("pg: can't find column=%s in model=%s", - colName, m.table.Type.Name()) + return fmt.Errorf("pg: can't find column=%s in %s (try discard_unknown_columns)", + colName, m.table) } func (m *structTableModel) scanColumn( diff --git a/vendor/github.com/go-pg/pg/orm/query.go b/vendor/github.com/go-pg/pg/orm/query.go index f98377a..36529b8 100644 --- a/vendor/github.com/go-pg/pg/orm/query.go +++ b/vendor/github.com/go-pg/pg/orm/query.go @@ -30,22 +30,22 @@ type Query struct { model tableModel ignoreModel bool - with []withQuery - tables []FormatAppender - columns []FormatAppender - set []FormatAppender - values map[string]*queryParamsAppender - where []sepFormatAppender - updWhere []sepFormatAppender - joins []*joinQuery - group []FormatAppender - having []*queryParamsAppender - order []FormatAppender - onConflict *queryParamsAppender - returning []*queryParamsAppender - limit int - offset int - selFor FormatAppender + with []withQuery + tables []FormatAppender + columns []FormatAppender + set []FormatAppender + modelValues map[string]*queryParamsAppender + where []sepFormatAppender + updWhere []sepFormatAppender + joins []*joinQuery + group []FormatAppender + having []*queryParamsAppender + order []FormatAppender + onConflict *queryParamsAppender + returning []*queryParamsAppender + limit int + offset int + selFor *queryParamsAppender } var _ queryAppender = (*Query)(nil) @@ -69,6 +69,14 @@ func (q *Query) AppendQuery(b []byte) ([]byte, error) { // Copy returns copy of the Query. func (q *Query) Copy() *Query { + var modelValues map[string]*queryParamsAppender + if len(q.modelValues) > 0 { + modelValues = make(map[string]*queryParamsAppender, len(q.modelValues)) + for k, v := range q.modelValues { + modelValues[k] = v + } + } + copy := &Query{ db: q.db, stickyErr: q.stickyErr, @@ -76,19 +84,21 @@ func (q *Query) Copy() *Query { model: q.model, ignoreModel: q.ignoreModel, - tables: q.tables[:len(q.tables):len(q.tables)], - columns: q.columns[:len(q.columns):len(q.columns)], - set: q.set[:len(q.set):len(q.set)], - where: q.where[:len(q.where):len(q.where)], - updWhere: q.updWhere[:len(q.updWhere):len(q.updWhere)], - joins: q.joins[:len(q.joins):len(q.joins)], - group: q.group[:len(q.group):len(q.group)], - having: q.having[:len(q.having):len(q.having)], - order: q.order[:len(q.order):len(q.order)], - onConflict: q.onConflict, - returning: q.returning[:len(q.returning):len(q.returning)], - limit: q.limit, - offset: q.offset, + tables: q.tables[:len(q.tables):len(q.tables)], + columns: q.columns[:len(q.columns):len(q.columns)], + set: q.set[:len(q.set):len(q.set)], + modelValues: modelValues, + where: q.where[:len(q.where):len(q.where)], + updWhere: q.updWhere[:len(q.updWhere):len(q.updWhere)], + joins: q.joins[:len(q.joins):len(q.joins)], + group: q.group[:len(q.group):len(q.group)], + having: q.having[:len(q.having):len(q.having)], + order: q.order[:len(q.order):len(q.order)], + onConflict: q.onConflict, + returning: q.returning[:len(q.returning):len(q.returning)], + limit: q.limit, + offset: q.offset, + selFor: q.selFor, } for _, with := range q.with { copy = copy.With(with.name, with.query.Copy()) @@ -158,8 +168,14 @@ func (q *Query) TableExpr(expr string, params ...interface{}) *Query { return q } -// Column adds column to the Query quoting it according to PostgreSQL rules. -// ColumnExpr can be used to bypass quoting restriction. +// Column adds a column to the Query quoting it according to PostgreSQL rules. +// ColumnExpr can be used to bypass quoting restriction. Column name can be: +// - column_name, +// - table_alias.column_name, +// - table_alias.*, +// - RelationName, +// - RelationName.column_name, +// - RelationName._ to join relation without selecting relation data. func (q *Query) Column(columns ...string) *Query { for _, column := range columns { if column == "_" { @@ -196,7 +212,6 @@ func (q *Query) getDataFields() ([]*Field, error) { func (q *Query) _getFields(omitPKs bool) ([]*Field, error) { table := q.model.Table() - var columns []*Field for _, col := range q.columns { f, ok := col.(fieldAppender) @@ -227,10 +242,8 @@ func (q *Query) Relation(name string, apply ...func(*Query) (*Query, error)) *Qu } _, join := q.model.Join(name, fn) if join == nil { - return q.err(fmt.Errorf( - "model=%s does not have relation=%s", - q.model.Table().Type.Name(), name, - )) + return q.err(fmt.Errorf("%s does not have relation=%q", + q.model.Table(), name)) } return q } @@ -240,11 +253,23 @@ func (q *Query) Set(set string, params ...interface{}) *Query { return q } +// Value overwrites model value for the column in INSERT and UPDATE queries. func (q *Query) Value(column string, value string, params ...interface{}) *Query { - if q.values == nil { - q.values = make(map[string]*queryParamsAppender) + if !q.hasModel() { + q.err(errors.New("pg: Model(nil)")) + return q + } + + table := q.model.Table() + if _, ok := table.FieldsMap[column]; !ok { + q.err(fmt.Errorf("%s does not have column=%q", table, column)) + return q } - q.values[column] = &queryParamsAppender{value, params} + + if q.modelValues == nil { + q.modelValues = make(map[string]*queryParamsAppender) + } + q.modelValues[column] = &queryParamsAppender{value, params} return q } @@ -306,6 +331,11 @@ func (q *Query) whereGroup(conj string, fn func(*Query) (*Query, error)) *Query return q } + if len(newq.where) == 0 { + newq.where = saved + return newq + } + f := &condGroupAppender{ sep: conj, cond: newq.where, @@ -337,15 +367,15 @@ func (q *Query) addWhere(f sepFormatAppender) { // Where("id = ?id") func (q *Query) WherePK() *Query { if !q.hasModel() { - q.stickyErr = errors.New("pg: Model(nil)") + q.err(errors.New("pg: Model(nil)")) return q } if q.model.Kind() == reflect.Slice { - q.stickyErr = errors.New("pg: WherePK requires struct Model") + q.err(errors.New("pg: WherePK requires struct Model")) return q } if err := q.model.Table().checkPKs(); err != nil { - q.stickyErr = err + q.err(err) return q } q.where = append(q.where, wherePKQuery{q}) @@ -596,6 +626,15 @@ func (q *Query) SelectAndCount(values ...interface{}) (count int, err error) { return count, err } +// ForEach calls the function for each row returned by the query +// without loading all rows into the memory. +// Function accepts a struct, pointer to a struct, orm.Model, +// or values for columns in a row. Function must return an error. +func (q *Query) ForEach(fn interface{}) error { + m := newFuncModel(fn) + return q.Select(m) +} + func (q *Query) forEachHasOneJoin(fn func(*join)) { if q.model == nil { return @@ -648,7 +687,8 @@ func (q *Query) Insert(values ...interface{}) (Result, error) { } } - res, err := q.db.Query(model, insertQuery{q: q}, q.model) + query := &insertQuery{q: q} + res, err := q.returningQuery(model, query) if err != nil { return nil, err } @@ -693,6 +733,9 @@ func (q *Query) SelectOrInsert(values ...interface{}) (inserted bool, _ error) { res, err := insertq.Insert(values...) if err != nil { insertErr = err + if err == internal.ErrNoRows { + continue + } if pgErr, ok := err.(internal.PGError); ok { if pgErr.IntegrityViolation() { continue @@ -743,7 +786,8 @@ func (q *Query) update(scan []interface{}, omitZero bool) (Result, error) { } } - res, err := q.db.Query(model, updateQuery{q: q, omitZero: omitZero}, q.model) + query := updateQuery{q: q, omitZero: omitZero} + res, err := q.returningQuery(model, query) if err != nil { return nil, err } @@ -758,6 +802,16 @@ func (q *Query) update(scan []interface{}, omitZero bool) (Result, error) { return res, nil } +func (q *Query) returningQuery(model Model, query interface{}) (Result, error) { + if len(q.returning) == 0 { + return q.db.Query(model, query, q.model) + } + if _, ok := model.(useQueryOne); ok { + return q.db.QueryOne(model, query, q.model) + } + return q.db.Query(model, query, q.model) +} + // Delete deletes the model. func (q *Query) Delete(values ...interface{}) (Result, error) { if q.stickyErr != nil { @@ -776,7 +830,7 @@ func (q *Query) Delete(values ...interface{}) (Result, error) { } } - res, err := q.db.Query(model, deleteQuery{q}, q.model) + res, err := q.returningQuery(model, deleteQuery{q}) if err != nil { return nil, err } @@ -791,27 +845,6 @@ func (q *Query) Delete(values ...interface{}) (Result, error) { return res, nil } -// CreateTable creates table for the model. -func (q *Query) CreateTable(opt *CreateTableOptions) (Result, error) { - if q.stickyErr != nil { - return nil, q.stickyErr - } - return q.db.Exec(createTableQuery{ - q: q, - opt: opt, - }) -} - -func (q *Query) DropTable(opt *DropTableOptions) (Result, error) { - if q.stickyErr != nil { - return nil, q.stickyErr - } - return q.db.Exec(dropTableQuery{ - q: q, - opt: opt, - }) -} - // Exec is an alias for DB.Exec. func (q *Query) Exec(query interface{}, params ...interface{}) (Result, error) { params = append(params, q.model) diff --git a/vendor/github.com/go-pg/pg/orm/relation.go b/vendor/github.com/go-pg/pg/orm/relation.go index e3d591c..720e6ad 100644 --- a/vendor/github.com/go-pg/pg/orm/relation.go +++ b/vendor/github.com/go-pg/pg/orm/relation.go @@ -1,6 +1,10 @@ package orm -import "github.com/go-pg/pg/types" +import ( + "fmt" + + "github.com/go-pg/pg/types" +) const ( HasOneRelation = 1 << iota @@ -22,3 +26,7 @@ type Relation struct { BaseFKs []string JoinFKs []string } + +func (r *Relation) String() string { + return fmt.Sprintf("relation=%s", r.Field.GoName) +} diff --git a/vendor/github.com/go-pg/pg/orm/table.go b/vendor/github.com/go-pg/pg/orm/table.go index 341bdbd..70deea9 100644 --- a/vendor/github.com/go-pg/pg/orm/table.go +++ b/vendor/github.com/go-pg/pg/orm/table.go @@ -35,6 +35,7 @@ var nullFloatType = reflect.TypeOf((*sql.NullFloat64)(nil)).Elem() var nullIntType = reflect.TypeOf((*sql.NullInt64)(nil)).Elem() var nullStringType = reflect.TypeOf((*sql.NullString)(nil)).Elem() +// Table represents a SQL table created from Go struct. type Table struct { Type reflect.Type zeroStruct reflect.Value @@ -57,12 +58,50 @@ type Table struct { } func newTable(typ reflect.Type) *Table { - t := &Table{ - Type: typ, + t := new(Table) + t.Type = typ + t.zeroStruct = reflect.Zero(t.Type) + t.TypeName = internal.ToExported(t.Type.Name()) + t.ModelName = internal.Underscore(t.Type.Name()) + t.Name = types.Q(types.AppendField(nil, tableNameInflector(t.ModelName), 1)) + t.Alias = types.Q(types.AppendField(nil, t.ModelName, 1)) + + typ = reflect.PtrTo(t.Type) + if typ.Implements(afterQueryHookType) { + t.SetFlag(AfterQueryHookFlag) + } + if typ.Implements(afterSelectHookType) { + t.SetFlag(AfterSelectHookFlag) + } + if typ.Implements(beforeInsertHookType) { + t.SetFlag(BeforeInsertHookFlag) + } + if typ.Implements(afterInsertHookType) { + t.SetFlag(AfterInsertHookFlag) + } + if typ.Implements(beforeUpdateHookType) { + t.SetFlag(BeforeUpdateHookFlag) + } + if typ.Implements(afterUpdateHookType) { + t.SetFlag(AfterUpdateHookFlag) + } + if typ.Implements(beforeDeleteHookType) { + t.SetFlag(BeforeDeleteHookFlag) + } + if typ.Implements(afterDeleteHookType) { + t.SetFlag(AfterDeleteHookFlag) } + + t.initFields() + t.initMethods() + return t } +func (t *Table) init() { + t.initRelations() +} + func (t *Table) String() string { return "model=" + t.TypeName } @@ -122,18 +161,20 @@ func removeField(fields []*Field, field *Field) []*Field { func (t *Table) GetField(fieldName string) (*Field, error) { field, ok := t.FieldsMap[fieldName] if !ok { - return nil, fmt.Errorf("can't find column=%s in table=%s", fieldName, t.Name) + return nil, fmt.Errorf("can't find column=%s in %s", fieldName, t) } return field, nil } func (t *Table) AppendParam(b []byte, strct reflect.Value, name string) ([]byte, bool) { - if field, ok := t.FieldsMap[name]; ok { + field, ok := t.FieldsMap[name] + if ok { b = field.AppendValue(b, strct, 1) return b, true } - if method, ok := t.Methods[name]; ok { + method, ok := t.Methods[name] + if ok { b = method.AppendValue(b, strct.Addr(), 1) return b, true } @@ -141,75 +182,10 @@ func (t *Table) AppendParam(b []byte, strct reflect.Value, name string) ([]byte, return b, false } -func (t *Table) addRelation(rel *Relation) { - if t.Relations == nil { - t.Relations = make(map[string]*Relation) - } - t.Relations[rel.Field.GoName] = rel -} - -func (t *Table) init() { - t.zeroStruct = reflect.Zero(t.Type) - t.TypeName = internal.ToExported(t.Type.Name()) - t.ModelName = internal.Underscore(t.Type.Name()) - t.Name = types.Q(types.AppendField(nil, tableNameInflector(t.ModelName), 1)) - t.Alias = types.Q(types.AppendField(nil, t.ModelName, 1)) - +func (t *Table) initFields() { t.Fields = make([]*Field, 0, t.Type.NumField()) t.FieldsMap = make(map[string]*Field, t.Type.NumField()) - t.addFields(t.Type, nil) - typ := reflect.PtrTo(t.Type) - - if typ.Implements(afterQueryHookType) { - t.SetFlag(AfterQueryHookFlag) - } - if typ.Implements(afterSelectHookType) { - t.SetFlag(AfterSelectHookFlag) - } - if typ.Implements(beforeInsertHookType) { - t.SetFlag(BeforeInsertHookFlag) - } - if typ.Implements(afterInsertHookType) { - t.SetFlag(AfterInsertHookFlag) - } - if typ.Implements(beforeUpdateHookType) { - t.SetFlag(BeforeUpdateHookFlag) - } - if typ.Implements(afterUpdateHookType) { - t.SetFlag(AfterUpdateHookFlag) - } - if typ.Implements(beforeDeleteHookType) { - t.SetFlag(BeforeDeleteHookFlag) - } - if typ.Implements(afterDeleteHookType) { - t.SetFlag(AfterDeleteHookFlag) - } - - if t.Methods == nil { - t.Methods = make(map[string]*Method) - } - for i := 0; i < typ.NumMethod(); i++ { - m := typ.Method(i) - if m.PkgPath != "" { - continue - } - if m.Type.NumIn() > 1 { - continue - } - if m.Type.NumOut() != 1 { - continue - } - - retType := m.Type.Out(0) - method := Method{ - Index: m.Index, - - appender: types.Appender(retType), - } - - t.Methods[m.Name] = &method - } } func (t *Table) addFields(typ reflect.Type, baseIndex []int) { @@ -217,8 +193,8 @@ func (t *Table) addFields(typ reflect.Type, baseIndex []int) { f := typ.Field(i) // Make a copy so slice is not shared between fields. - var index []int - index = append(index, baseIndex...) + index := make([]int, len(baseIndex)) + copy(index, baseIndex) if f.Anonymous { sqlTag := f.Tag.Get("sql") @@ -226,17 +202,18 @@ func (t *Table) addFields(typ reflect.Type, baseIndex []int) { continue } - embeddedTable := Tables.get(indirectType(f.Type), true) + fieldType := indirectType(f.Type) + t.addFields(fieldType, append(index, f.Index...)) pgTag := parseTag(f.Tag.Get("pg")) if _, ok := pgTag.Options["override"]; ok { + embeddedTable := newTable(fieldType) t.TypeName = embeddedTable.TypeName t.Name = embeddedTable.Name t.Alias = embeddedTable.Alias t.ModelName = embeddedTable.ModelName } - t.addFields(embeddedTable.Type, append(index, f.Index...)) continue } @@ -252,7 +229,7 @@ func (t *Table) newField(f reflect.StructField, index []int) *Field { switch f.Name { case "tableName", "TableName": - if index != nil { + if len(index) > 0 { return nil } @@ -293,8 +270,9 @@ func (t *Table) newField(f reflect.StructField, index []int) *Field { t.RemoveField(field) } - field := Field{ - Type: indirectType(f.Type), + field := &Field{ + Field: f, + Type: indirectType(f.Type), GoName: f.Name, SQLName: sqlTag.Name, @@ -313,7 +291,7 @@ func (t *Table) newField(f reflect.StructField, index []int) *Field { if t.Unique == nil { t.Unique = make(map[string][]*Field) } - t.Unique[v] = append(t.Unique[v], &field) + t.Unique[v] = append(t.Unique[v], field) } } if v, ok := sqlTag.Options["default"]; ok { @@ -345,7 +323,7 @@ func (t *Table) newField(f reflect.StructField, index []int) *Field { field.SetFlag(ArrayFlag) } - field.SQLType = fieldSQLType(&field, pgTag, sqlTag) + field.SQLType = fieldSQLType(field, pgTag, sqlTag) if strings.HasSuffix(field.SQLType, "[]") { field.SetFlag(ArrayFlag) } @@ -369,172 +347,219 @@ func (t *Table) newField(f reflect.StructField, index []int) *Field { } field.isZero = isZeroFunc(f.Type) - if !skip && isColumn(f.Type) { - return &field + if skip { + t.FieldsMap[field.SQLName] = field + return nil + } + return field +} + +func (t *Table) initMethods() { + t.Methods = make(map[string]*Method) + typ := reflect.PtrTo(t.Type) + for i := 0; i < typ.NumMethod(); i++ { + m := typ.Method(i) + if m.PkgPath != "" { + continue + } + if m.Type.NumIn() > 1 { + continue + } + if m.Type.NumOut() != 1 { + continue + } + + retType := m.Type.Out(0) + t.Methods[m.Name] = &Method{ + Index: m.Index, + + appender: types.Appender(retType), + } + } +} + +func (t *Table) initRelations() { + for _, field := range t.FieldsMap { + if t.tryRelation(field) { + t.DataFields = removeField(t.DataFields, field) + t.Fields = removeField(t.Fields, field) + } + } +} + +func (t *Table) tryRelation(field *Field) bool { + if isColumn(field.Type) { + return false } switch field.Type.Kind() { case reflect.Slice: - elemType := indirectType(field.Type.Elem()) - if elemType.Kind() != reflect.Struct { - break - } + return t.tryRelationSlice(field) + case reflect.Struct: + return t.tryRelationStruct(field) + } + return false +} - joinTable := Tables.get(elemType, true) +func (t *Table) tryRelationSlice(field *Field) bool { + elemType := indirectType(field.Type.Elem()) + if elemType.Kind() != reflect.Struct { + return false + } - fk, fkOK := pgTag.Options["fk"] - if fkOK { - if fk == "-" { - break - } - fk = tryUnderscorePrefix(fk) + pgTag := parseTag(field.Field.Tag.Get("pg")) + joinTable := _tables.get(elemType, true) + + fk, fkOK := pgTag.Options["fk"] + if fkOK { + if fk == "-" { + return false } + fk = tryUnderscorePrefix(fk) + } - if m2mTableName, _ := pgTag.Options["many2many"]; m2mTableName != "" { - m2mTable := Tables.getByName(m2mTableName) + if m2mTableName, _ := pgTag.Options["many2many"]; m2mTableName != "" { + m2mTable := _tables.getByName(m2mTableName) - var m2mTableAlias types.Q - if m2mTable != nil { - m2mTableAlias = m2mTable.Alias - } else if ind := strings.IndexByte(m2mTableName, '.'); ind >= 0 { - m2mTableAlias = types.Q(m2mTableName[ind+1:]) - } else { - m2mTableAlias = types.Q(m2mTableName) - } + var m2mTableAlias types.Q + if m2mTable != nil { + m2mTableAlias = m2mTable.Alias + } else if ind := strings.IndexByte(m2mTableName, '.'); ind >= 0 { + m2mTableAlias = types.Q(m2mTableName[ind+1:]) + } else { + m2mTableAlias = types.Q(m2mTableName) + } - var fks []string - if !fkOK { - fk = t.ModelName + "_" + var fks []string + if !fkOK { + fk = t.ModelName + "_" + } + if m2mTable != nil { + keys := foreignKeys(t, m2mTable, fk, fkOK) + if len(keys) == 0 { + return false } - if m2mTable != nil { - keys := foreignKeys(t, m2mTable, fk, fkOK) - if len(keys) == 0 { - break - } - for _, fk := range keys { - fks = append(fks, fk.SQLName) - } + for _, fk := range keys { + fks = append(fks, fk.SQLName) + } + } else { + if fkOK && len(t.PKs) == 1 { + fks = append(fks, fk) } else { - if fkOK && len(t.PKs) == 1 { - fks = append(fks, fk) - } else { - for _, pk := range t.PKs { - fks = append(fks, fk+pk.SQLName) - } + for _, pk := range t.PKs { + fks = append(fks, fk+pk.SQLName) } } + } - joinFK, joinFKOK := pgTag.Options["joinFK"] - if joinFKOK { - joinFK = tryUnderscorePrefix(joinFK) - } else { - joinFK = joinTable.ModelName + "_" + joinFK, joinFKOK := pgTag.Options["joinFK"] + if joinFKOK { + joinFK = tryUnderscorePrefix(joinFK) + } else { + joinFK = joinTable.ModelName + "_" + } + var joinFKs []string + if m2mTable != nil { + keys := foreignKeys(joinTable, m2mTable, joinFK, joinFKOK) + if len(keys) == 0 { + return false } - var joinFKs []string - if m2mTable != nil { - keys := foreignKeys(joinTable, m2mTable, joinFK, joinFKOK) - if len(keys) == 0 { - break - } - for _, fk := range keys { - joinFKs = append(joinFKs, fk.SQLName) - } + for _, fk := range keys { + joinFKs = append(joinFKs, fk.SQLName) + } + } else { + if joinFKOK && len(joinTable.PKs) == 1 { + joinFKs = append(joinFKs, joinFK) } else { - if joinFKOK && len(joinTable.PKs) == 1 { - joinFKs = append(joinFKs, joinFK) - } else { - for _, pk := range joinTable.PKs { - joinFKs = append(joinFKs, joinFK+pk.SQLName) - } + for _, pk := range joinTable.PKs { + joinFKs = append(joinFKs, joinFK+pk.SQLName) } } - - t.addRelation(&Relation{ - Type: Many2ManyRelation, - Field: &field, - JoinTable: joinTable, - M2MTableName: types.Q(m2mTableName), - M2MTableAlias: m2mTableAlias, - BaseFKs: fks, - JoinFKs: joinFKs, - }) - return nil } - s, polymorphic := pgTag.Options["polymorphic"] - var typeField *Field - if polymorphic { - fk = tryUnderscorePrefix(s) + t.addRelation(&Relation{ + Type: Many2ManyRelation, + Field: field, + JoinTable: joinTable, + M2MTableName: types.Q(m2mTableName), + M2MTableAlias: m2mTableAlias, + BaseFKs: fks, + JoinFKs: joinFKs, + }) + return true + } - typeField = joinTable.getField(fk + "type") - if typeField == nil { - break - } - } else if !fkOK { - fk = t.ModelName + "_" - } + s, polymorphic := pgTag.Options["polymorphic"] + var typeField *Field + if polymorphic { + fk = tryUnderscorePrefix(s) - fks := foreignKeys(t, joinTable, fk, fkOK || polymorphic) - if len(fks) == 0 { - break + typeField = joinTable.getField(fk + "type") + if typeField == nil { + return false } + } else if !fkOK { + fk = t.ModelName + "_" + } - var fkValues []*Field - fkValue, ok := pgTag.Options["fk_value"] - if ok { - if len(fks) > 1 { - panic(fmt.Errorf("got fk_value, but there are %d fks", len(fks))) - } + fks := foreignKeys(t, joinTable, fk, fkOK || polymorphic) + if len(fks) == 0 { + return false + } - f := t.getField(fkValue) - if f == nil { - panic(fmt.Errorf("fk_value=%q not found in %s", fkValue, t)) - } - fkValues = append(fkValues, f) - } else { - fkValues = t.PKs - } - - if len(fks) > 0 { - t.addRelation(&Relation{ - Type: HasManyRelation, - Field: &field, - JoinTable: joinTable, - FKs: fks, - Polymorphic: typeField, - FKValues: fkValues, - }) - return nil - } - case reflect.Struct: - joinTable := Tables.get(field.Type, true) - if len(joinTable.Fields) == 0 { - break - } - - for _, ff := range joinTable.FieldsMap { - ff = ff.Copy() - ff.SQLName = field.SQLName + "__" + ff.SQLName - ff.Column = types.Q(types.AppendField(nil, ff.SQLName, 1)) - ff.Index = append(field.Index[:len(field.Index):len(field.Index)], ff.Index...) - if _, ok := t.FieldsMap[ff.SQLName]; !ok { - t.FieldsMap[ff.SQLName] = ff - } + var fkValues []*Field + fkValue, ok := pgTag.Options["fk_value"] + if ok { + if len(fks) > 1 { + panic(fmt.Errorf("got fk_value, but there are %d fks", len(fks))) } - if t.tryHasOne(joinTable, &field, pgTag) || - t.tryBelongsToOne(joinTable, &field, pgTag) { - t.FieldsMap[field.SQLName] = &field - return nil + f := t.getField(fkValue) + if f == nil { + panic(fmt.Errorf("fk_value=%q not found in %s", fkValue, t)) } + fkValues = append(fkValues, f) + } else { + fkValues = t.PKs } - if skip { - t.FieldsMap[field.SQLName] = &field - return nil + if len(fks) > 0 { + t.addRelation(&Relation{ + Type: HasManyRelation, + Field: field, + JoinTable: joinTable, + FKs: fks, + Polymorphic: typeField, + FKValues: fkValues, + }) + return true } - return &field + return false +} + +func (t *Table) tryRelationStruct(field *Field) bool { + pgTag := parseTag(field.Field.Tag.Get("pg")) + joinTable := _tables.get(field.Type, true) + if len(joinTable.Fields) == 0 { + return false + } + + res := t.tryHasOne(joinTable, field, pgTag) || + t.tryBelongsToOne(joinTable, field, pgTag) + + for _, f := range joinTable.FieldsMap { + f = f.Copy() + f.GoName = field.GoName + "_" + f.GoName + f.SQLName = field.SQLName + "__" + f.SQLName + f.Column = types.Q(types.AppendField(nil, f.SQLName, 1)) + f.Index = appendNew(field.Index, f.Index...) + if _, ok := t.FieldsMap[f.SQLName]; !ok { + t.FieldsMap[f.SQLName] = f + } + } + + return res } func isPostgresKeyword(s string) bool { @@ -696,6 +721,17 @@ func (t *Table) tryBelongsToOne(joinTable *Table, field *Field, tag *tag) bool { return false } +func (t *Table) addRelation(rel *Relation) { + if t.Relations == nil { + t.Relations = make(map[string]*Relation) + } + _, ok := t.Relations[rel.Field.GoName] + if ok { + panic(fmt.Errorf("%s already has %s", t, rel)) + } + t.Relations[rel.Field.GoName] = rel +} + func foreignKeys(base, join *Table, fk string, tryFK bool) []*Field { var fks []*Field @@ -748,17 +784,7 @@ func foreignKeys(base, join *Table, fk string, tryFK bool) []*Field { } func (t *Table) getField(name string) *Field { - if f, ok := t.FieldsMap[name]; ok { - return f - } - - for i := 0; i < t.Type.NumField(); i++ { - f := t.Type.Field(i) - if internal.Underscore(f.Name) == name { - return t.newField(f, nil) - } - } - return nil + return t.FieldsMap[name] } func scanJSONValue(v reflect.Value, b []byte) error { @@ -783,3 +809,10 @@ func tryUnderscorePrefix(s string) string { } return s } + +func appendNew(dst []int, src ...int) []int { + cp := make([]int, len(dst)+len(src)) + copy(cp, dst) + copy(cp[len(dst):], src) + return cp +} diff --git a/vendor/github.com/go-pg/pg/orm/table_params.go b/vendor/github.com/go-pg/pg/orm/table_params.go index 3d60382..db3437a 100644 --- a/vendor/github.com/go-pg/pg/orm/table_params.go +++ b/vendor/github.com/go-pg/pg/orm/table_params.go @@ -19,7 +19,7 @@ func newTableParams(strct interface{}) (*tableParams, bool) { } return &tableParams{ - table: Tables.Get(v.Type()), + table: GetTable(v.Type()), strct: v, }, true } diff --git a/vendor/github.com/go-pg/pg/orm/tables.go b/vendor/github.com/go-pg/pg/orm/tables.go index 7f1e6cf..8200fcb 100644 --- a/vendor/github.com/go-pg/pg/orm/tables.go +++ b/vendor/github.com/go-pg/pg/orm/tables.go @@ -6,17 +6,34 @@ import ( "sync" ) -var Tables = newTables() +var _tables = newTables() + +type tableInProgress struct { + table *Table + wg sync.WaitGroup +} + +// GetTable returns a Table for a struct type. +func GetTable(typ reflect.Type) *Table { + return _tables.Get(typ) +} + +// RegisterTable registers a struct as SQL table. +// It is usually used to register intermediate table +// in many to many relationship. +func RegisterTable(strct interface{}) { + _tables.Register(strct) +} type tables struct { mu sync.RWMutex - inProgress map[reflect.Type]*Table + inProgress map[reflect.Type]*tableInProgress tables map[reflect.Type]*Table } func newTables() *tables { return &tables{ - inProgress: make(map[reflect.Type]*Table), + inProgress: make(map[reflect.Type]*tableInProgress), tables: make(map[reflect.Type]*Table), } } @@ -29,7 +46,7 @@ func (t *tables) Register(strct interface{}) { _ = t.Get(typ) } -func (t *tables) get(typ reflect.Type, inProgress bool) *Table { +func (t *tables) get(typ reflect.Type, allowInProgress bool) *Table { if typ.Kind() != reflect.Struct { panic(fmt.Errorf("got %s, wanted %s", typ.Kind(), reflect.Struct)) } @@ -41,33 +58,39 @@ func (t *tables) get(typ reflect.Type, inProgress bool) *Table { return table } - var dup bool t.mu.Lock() + table, ok = t.tables[typ] - if !ok { - if inProgress { - table, ok = t.inProgress[typ] - } - if !ok { - table = newTable(typ) - _, dup = t.inProgress[typ] - if !dup { - t.inProgress[typ] = table - } - } + if ok { + t.mu.Unlock() + return table } - t.mu.Unlock() - if !ok { - table.init() - if !dup { - t.mu.Lock() - delete(t.inProgress, typ) - t.tables[typ] = table - t.mu.Unlock() + inProgress := t.inProgress[typ] + if inProgress != nil { + t.mu.Unlock() + if !allowInProgress { + inProgress.wg.Wait() } + return inProgress.table } + table = newTable(typ) + inProgress = &tableInProgress{ + table: table, + } + inProgress.wg.Add(1) + t.inProgress[typ] = inProgress + + t.mu.Unlock() + table.init() + inProgress.wg.Done() + t.mu.Lock() + + delete(t.inProgress, typ) + t.tables[typ] = table + + t.mu.Unlock() return table } diff --git a/vendor/github.com/go-pg/pg/orm/update.go b/vendor/github.com/go-pg/pg/orm/update.go index 4f0b3a0..eaf4c1c 100644 --- a/vendor/github.com/go-pg/pg/orm/update.go +++ b/vendor/github.com/go-pg/pg/orm/update.go @@ -18,8 +18,7 @@ func Update(db DB, model interface{}) error { } type updateQuery struct { - q *Query - + q *Query omitZero bool } @@ -147,13 +146,14 @@ func (q updateQuery) appendSetStruct(b []byte, strct reflect.Value) ([]byte, err b = append(b, f.Column...) b = append(b, " = "...) - app, ok := q.q.values[f.SQLName] + app, ok := q.q.modelValues[f.SQLName] if ok { b = app.AppendFormat(b, q.q) } else { b = f.AppendValue(b, strct, 1) } } + return b, nil } @@ -177,6 +177,7 @@ func (q updateQuery) appendSetSlice(b []byte, slice reflect.Value) ([]byte, erro b = append(b, "_data."...) b = append(b, f.Column...) } + return b, nil } diff --git a/vendor/github.com/go-pg/pg/pg.go b/vendor/github.com/go-pg/pg/pg.go index c104f6c..2c2e372 100644 --- a/vendor/github.com/go-pg/pg/pg.go +++ b/vendor/github.com/go-pg/pg/pg.go @@ -42,15 +42,23 @@ func F(field string) types.ValueAppender { // In accepts a slice and returns a wrapper that can be used with PostgreSQL // IN operator: // -// Where("id IN (?)", pg.In(1, 2, 3)) +// Where("id IN (?)", pg.In([]int{1, 2, 3, 4})) +// +// produces +// +// WHERE id IN (1, 2, 3, 4) func In(slice interface{}) types.ValueAppender { return types.InSlice(slice) } -// In accepts multiple values and returns a wrapper that can be used +// InMulti accepts multiple values and returns a wrapper that can be used // with PostgreSQL IN operator: // -// Where("id IN (?)", pg.In(1, 2, 3)) +// Where("(id1, id2) IN (?)", pg.InMulti([]int{1, 2}, []int{3, 4})) +// +// produces +// +// WHERE (id1, id2) IN ((1, 2), (3, 4)) func InMulti(values ...interface{}) types.ValueAppender { return types.In(values...) } diff --git a/vendor/github.com/go-pg/pg/tx.go b/vendor/github.com/go-pg/pg/tx.go index 9ccf7b0..bcbdecc 100644 --- a/vendor/github.com/go-pg/pg/tx.go +++ b/vendor/github.com/go-pg/pg/tx.go @@ -64,6 +64,11 @@ func (db *DB) RunInTransaction(fn func(*Tx) error) error { return tx.RunInTransaction(fn) } +// DB returns a DB which started the Tx. +func (tx *Tx) DB() *DB { + return tx.db +} + // Begin returns the transaction. func (tx *Tx) Begin() (*Tx, error) { return tx, nil diff --git a/vendor/github.com/im-kulikov/migrate/.gitignore b/vendor/github.com/im-kulikov/migrate/.gitignore new file mode 100644 index 0000000..f9b3a1d --- /dev/null +++ b/vendor/github.com/im-kulikov/migrate/.gitignore @@ -0,0 +1,14 @@ +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib + +# Test binary, build with `go test -c` +*.test + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out + +vendor \ No newline at end of file diff --git a/vendor/github.com/im-kulikov/migrate/Gopkg.lock b/vendor/github.com/im-kulikov/migrate/Gopkg.lock new file mode 100644 index 0000000..9623bce --- /dev/null +++ b/vendor/github.com/im-kulikov/migrate/Gopkg.lock @@ -0,0 +1,46 @@ +# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. + + +[[projects]] + name = "github.com/davecgh/go-spew" + packages = ["spew"] + revision = "346938d642f2ec3594ed81d874461961cd0faa76" + version = "v1.1.0" + +[[projects]] + name = "github.com/go-pg/pg" + packages = [ + ".", + "internal", + "internal/parser", + "internal/pool", + "orm", + "types" + ] + revision = "1e63a7fcab7d4389be48b02a4997c87771fcfae8" + version = "v6.13.2" + +[[projects]] + branch = "master" + name = "github.com/jinzhu/inflection" + packages = ["."] + revision = "04140366298a54a039076d798123ffa108fff46c" + +[[projects]] + name = "github.com/pmezard/go-difflib" + packages = ["difflib"] + revision = "792786c7400a136282c1664665ae0a8db921c6c2" + version = "v1.0.0" + +[[projects]] + name = "github.com/stretchr/testify" + packages = ["assert"] + revision = "12b6f73e6084dad08a7c6e575284b177ecafbc71" + version = "v1.2.1" + +[solve-meta] + analyzer-name = "dep" + analyzer-version = 1 + inputs-digest = "908d8054cee91f877ea14e15aaa9b6f9d74dcd9662da6db8e924bd2a8fc1943e" + solver-name = "gps-cdcl" + solver-version = 1 diff --git a/vendor/github.com/im-kulikov/migrate/Gopkg.toml b/vendor/github.com/im-kulikov/migrate/Gopkg.toml new file mode 100644 index 0000000..50edf1f --- /dev/null +++ b/vendor/github.com/im-kulikov/migrate/Gopkg.toml @@ -0,0 +1,42 @@ +# Gopkg.toml example +# +# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md +# for detailed Gopkg.toml documentation. +# +# required = ["github.com/user/thing/cmd/thing"] +# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"] +# +# [[constraint]] +# name = "github.com/user/project" +# version = "1.0.0" +# +# [[constraint]] +# name = "github.com/user/project2" +# branch = "dev" +# source = "github.com/myfork/project2" +# +# [[override]] +# name = "github.com/x/y" +# version = "2.4.0" +# +# [prune] +# non-go = false +# go-tests = true +# unused-packages = true + + +[[constraint]] + name = "github.com/davecgh/go-spew" + version = "1.1.0" + +[[constraint]] + name = "github.com/go-pg/pg" + version = "6.13.2" + +[[constraint]] + name = "github.com/stretchr/testify" + version = "1.2.1" + +[prune] + go-tests = true + unused-packages = true diff --git a/vendor/github.com/m1ome/stump/LICENSE b/vendor/github.com/im-kulikov/migrate/LICENSE similarity index 96% rename from vendor/github.com/m1ome/stump/LICENSE rename to vendor/github.com/im-kulikov/migrate/LICENSE index 7b292ab..09aaaf1 100644 --- a/vendor/github.com/m1ome/stump/LICENSE +++ b/vendor/github.com/im-kulikov/migrate/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2018 Pavel Makarenko +Copyright (c) 2018 Evgeniy Kulikov Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/vendor/github.com/im-kulikov/migrate/README.md b/vendor/github.com/im-kulikov/migrate/README.md new file mode 100644 index 0000000..33f9149 --- /dev/null +++ b/vendor/github.com/im-kulikov/migrate/README.md @@ -0,0 +1,9 @@ +# Simple PostgreSQL migrator + +[![CircleCI](https://circleci.com/gh/im-kulikov/migrate/tree/master.svg?style=svg)](https://circleci.com/gh/im-kulikov/migrate/tree/master) + +- up / down migrations +- list of applied migrations +- list of planned migrations +- version (number) of latest applied migration +- version (name) of latest applied migration \ No newline at end of file diff --git a/vendor/github.com/m1ome/stump/package/migrate/helpers.go b/vendor/github.com/im-kulikov/migrate/helpers.go similarity index 99% rename from vendor/github.com/m1ome/stump/package/migrate/helpers.go rename to vendor/github.com/im-kulikov/migrate/helpers.go index d18d66b..874ee5d 100644 --- a/vendor/github.com/m1ome/stump/package/migrate/helpers.go +++ b/vendor/github.com/im-kulikov/migrate/helpers.go @@ -174,4 +174,4 @@ func CreateMigration(folder, name string) error { } return nil -} \ No newline at end of file +} diff --git a/vendor/github.com/m1ome/stump/package/migrate/migrate.go b/vendor/github.com/im-kulikov/migrate/migrate.go similarity index 99% rename from vendor/github.com/m1ome/stump/package/migrate/migrate.go rename to vendor/github.com/im-kulikov/migrate/migrate.go index 70d2b4d..bb286a9 100644 --- a/vendor/github.com/m1ome/stump/package/migrate/migrate.go +++ b/vendor/github.com/im-kulikov/migrate/migrate.go @@ -11,6 +11,7 @@ import ( "github.com/go-pg/pg/orm" ) +// Logger interface for migrator type Logger interface { Infof(format string, args ...interface{}) } @@ -302,4 +303,4 @@ func (m *migrate) VersionName() (version string, err error) { } return -} \ No newline at end of file +} diff --git a/vendor/github.com/m1ome/stump/package/migrate/vars.go b/vendor/github.com/im-kulikov/migrate/vars.go similarity index 94% rename from vendor/github.com/m1ome/stump/package/migrate/vars.go rename to vendor/github.com/im-kulikov/migrate/vars.go index dee5603..4811018 100644 --- a/vendor/github.com/m1ome/stump/package/migrate/vars.go +++ b/vendor/github.com/im-kulikov/migrate/vars.go @@ -34,8 +34,6 @@ var ( // ErrNoDB set to Options ErrNoDB = fmt.Errorf("no db") - // ErrNoLogger set to Options - ErrNoLogger = fmt.Errorf("no logger") // ErrDirNotExists when migration path not exists ErrDirNotExists = fmt.Errorf("migrations dir not exists") // ErrBothMigrateTypes when up or down migration file not found @@ -43,3 +41,8 @@ var ( // ErrPositiveSteps when steps < 0 ErrPositiveSteps = errors.New("steps must be a positive number") ) + +// SetTableName for migrations +func SetTableName(name string) { + tableName = name +} diff --git a/vendor/github.com/m1ome/stump/package/migrate/.gitkeep b/vendor/github.com/m1ome/stump/package/migrate/.gitkeep deleted file mode 100644 index e69de29..0000000