From 3680cbacff19a776896224d0673b162ae0d52a3d Mon Sep 17 00:00:00 2001 From: Yokoyama Hirokazu Date: Fri, 29 May 2020 03:32:55 +0900 Subject: [PATCH] =?UTF-8?q?SQLBoiler=E3=81=AE=E5=B0=8E=E5=85=A5=E3=81=A7?= =?UTF-8?q?=E3=83=A2=E3=83=87=E3=83=AB=E4=BD=9C=E6=88=90=20(#4)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * go mod & sum * 設定ファイル * 生成されたモデル --- Makefile | 3 + domain/dbmodel/articles.go | 1111 +++++++++++++++++++++++++++ domain/dbmodel/articles_test.go | 735 ++++++++++++++++++ domain/dbmodel/boil_main_test.go | 119 +++ domain/dbmodel/boil_queries.go | 33 + domain/dbmodel/boil_queries_test.go | 52 ++ domain/dbmodel/boil_suites_test.go | 121 +++ domain/dbmodel/boil_table_names.go | 10 + domain/dbmodel/boil_types.go | 52 ++ domain/dbmodel/mysql_main_test.go | 243 ++++++ domain/dbmodel/mysql_suites_test.go | 10 + domain/dbmodel/mysql_upsert.go | 58 ++ go.mod | 22 + go.sum | 341 ++++++++ sqlboiler.toml | 13 + 15 files changed, 2923 insertions(+) create mode 100644 domain/dbmodel/articles.go create mode 100644 domain/dbmodel/articles_test.go create mode 100644 domain/dbmodel/boil_main_test.go create mode 100644 domain/dbmodel/boil_queries.go create mode 100644 domain/dbmodel/boil_queries_test.go create mode 100644 domain/dbmodel/boil_suites_test.go create mode 100644 domain/dbmodel/boil_table_names.go create mode 100644 domain/dbmodel/boil_types.go create mode 100644 domain/dbmodel/mysql_main_test.go create mode 100644 domain/dbmodel/mysql_suites_test.go create mode 100644 domain/dbmodel/mysql_upsert.go create mode 100644 go.mod create mode 100644 go.sum create mode 100644 sqlboiler.toml diff --git a/Makefile b/Makefile index e6593ae..0bc9080 100644 --- a/Makefile +++ b/Makefile @@ -5,3 +5,6 @@ dev: docker-compose build docker-compose up -d docker-compose ps + +genmodel: + go run github.com/volatiletech/sqlboiler mysql \ No newline at end of file diff --git a/domain/dbmodel/articles.go b/domain/dbmodel/articles.go new file mode 100644 index 0000000..6f75f52 --- /dev/null +++ b/domain/dbmodel/articles.go @@ -0,0 +1,1111 @@ +// Code generated by SQLBoiler 3.7.1 (https://github.com/volatiletech/sqlboiler). DO NOT EDIT. +// This file is meant to be re-generated in place and/or deleted at any time. + +package dbmodel + +import ( + "context" + "database/sql" + "fmt" + "reflect" + "strconv" + "strings" + "sync" + "time" + + "github.com/friendsofgo/errors" + "github.com/volatiletech/sqlboiler/boil" + "github.com/volatiletech/sqlboiler/queries" + "github.com/volatiletech/sqlboiler/queries/qm" + "github.com/volatiletech/sqlboiler/queries/qmhelper" + "github.com/volatiletech/sqlboiler/strmangle" +) + +// Article is an object representing the database table. +type Article struct { + ArticleID int `boil:"article_id" json:"article_id" toml:"article_id" yaml:"article_id"` + Title string `boil:"title" json:"title" toml:"title" yaml:"title"` + Body string `boil:"body" json:"body" toml:"body" yaml:"body"` + PostedAt time.Time `boil:"posted_at" json:"posted_at" toml:"posted_at" yaml:"posted_at"` + CreatedAt time.Time `boil:"created_at" json:"created_at" toml:"created_at" yaml:"created_at"` + UpdatedAt time.Time `boil:"updated_at" json:"updated_at" toml:"updated_at" yaml:"updated_at"` + + R *articleR `boil:"-" json:"-" toml:"-" yaml:"-"` + L articleL `boil:"-" json:"-" toml:"-" yaml:"-"` +} + +var ArticleColumns = struct { + ArticleID string + Title string + Body string + PostedAt string + CreatedAt string + UpdatedAt string +}{ + ArticleID: "article_id", + Title: "title", + Body: "body", + PostedAt: "posted_at", + CreatedAt: "created_at", + UpdatedAt: "updated_at", +} + +// Generated where + +type whereHelperint struct{ field string } + +func (w whereHelperint) EQ(x int) qm.QueryMod { return qmhelper.Where(w.field, qmhelper.EQ, x) } +func (w whereHelperint) NEQ(x int) qm.QueryMod { return qmhelper.Where(w.field, qmhelper.NEQ, x) } +func (w whereHelperint) LT(x int) qm.QueryMod { return qmhelper.Where(w.field, qmhelper.LT, x) } +func (w whereHelperint) LTE(x int) qm.QueryMod { return qmhelper.Where(w.field, qmhelper.LTE, x) } +func (w whereHelperint) GT(x int) qm.QueryMod { return qmhelper.Where(w.field, qmhelper.GT, x) } +func (w whereHelperint) GTE(x int) qm.QueryMod { return qmhelper.Where(w.field, qmhelper.GTE, x) } +func (w whereHelperint) IN(slice []int) qm.QueryMod { + values := make([]interface{}, 0, len(slice)) + for _, value := range slice { + values = append(values, value) + } + return qm.WhereIn(fmt.Sprintf("%s IN ?", w.field), values...) +} + +type whereHelperstring struct{ field string } + +func (w whereHelperstring) EQ(x string) qm.QueryMod { return qmhelper.Where(w.field, qmhelper.EQ, x) } +func (w whereHelperstring) NEQ(x string) qm.QueryMod { return qmhelper.Where(w.field, qmhelper.NEQ, x) } +func (w whereHelperstring) LT(x string) qm.QueryMod { return qmhelper.Where(w.field, qmhelper.LT, x) } +func (w whereHelperstring) LTE(x string) qm.QueryMod { return qmhelper.Where(w.field, qmhelper.LTE, x) } +func (w whereHelperstring) GT(x string) qm.QueryMod { return qmhelper.Where(w.field, qmhelper.GT, x) } +func (w whereHelperstring) GTE(x string) qm.QueryMod { return qmhelper.Where(w.field, qmhelper.GTE, x) } +func (w whereHelperstring) IN(slice []string) qm.QueryMod { + values := make([]interface{}, 0, len(slice)) + for _, value := range slice { + values = append(values, value) + } + return qm.WhereIn(fmt.Sprintf("%s IN ?", w.field), values...) +} + +type whereHelpertime_Time struct{ field string } + +func (w whereHelpertime_Time) EQ(x time.Time) qm.QueryMod { + return qmhelper.Where(w.field, qmhelper.EQ, x) +} +func (w whereHelpertime_Time) NEQ(x time.Time) qm.QueryMod { + return qmhelper.Where(w.field, qmhelper.NEQ, x) +} +func (w whereHelpertime_Time) LT(x time.Time) qm.QueryMod { + return qmhelper.Where(w.field, qmhelper.LT, x) +} +func (w whereHelpertime_Time) LTE(x time.Time) qm.QueryMod { + return qmhelper.Where(w.field, qmhelper.LTE, x) +} +func (w whereHelpertime_Time) GT(x time.Time) qm.QueryMod { + return qmhelper.Where(w.field, qmhelper.GT, x) +} +func (w whereHelpertime_Time) GTE(x time.Time) qm.QueryMod { + return qmhelper.Where(w.field, qmhelper.GTE, x) +} + +var ArticleWhere = struct { + ArticleID whereHelperint + Title whereHelperstring + Body whereHelperstring + PostedAt whereHelpertime_Time + CreatedAt whereHelpertime_Time + UpdatedAt whereHelpertime_Time +}{ + ArticleID: whereHelperint{field: "`articles`.`article_id`"}, + Title: whereHelperstring{field: "`articles`.`title`"}, + Body: whereHelperstring{field: "`articles`.`body`"}, + PostedAt: whereHelpertime_Time{field: "`articles`.`posted_at`"}, + CreatedAt: whereHelpertime_Time{field: "`articles`.`created_at`"}, + UpdatedAt: whereHelpertime_Time{field: "`articles`.`updated_at`"}, +} + +// ArticleRels is where relationship names are stored. +var ArticleRels = struct { +}{} + +// articleR is where relationships are stored. +type articleR struct { +} + +// NewStruct creates a new relationship struct +func (*articleR) NewStruct() *articleR { + return &articleR{} +} + +// articleL is where Load methods for each relationship are stored. +type articleL struct{} + +var ( + articleAllColumns = []string{"article_id", "title", "body", "posted_at", "created_at", "updated_at"} + articleColumnsWithoutDefault = []string{"title", "body", "posted_at", "created_at", "updated_at"} + articleColumnsWithDefault = []string{"article_id"} + articlePrimaryKeyColumns = []string{"article_id"} +) + +type ( + // ArticleSlice is an alias for a slice of pointers to Article. + // This should generally be used opposed to []Article. + ArticleSlice []*Article + // ArticleHook is the signature for custom Article hook methods + ArticleHook func(context.Context, boil.ContextExecutor, *Article) error + + articleQuery struct { + *queries.Query + } +) + +// Cache for insert, update and upsert +var ( + articleType = reflect.TypeOf(&Article{}) + articleMapping = queries.MakeStructMapping(articleType) + articlePrimaryKeyMapping, _ = queries.BindMapping(articleType, articleMapping, articlePrimaryKeyColumns) + articleInsertCacheMut sync.RWMutex + articleInsertCache = make(map[string]insertCache) + articleUpdateCacheMut sync.RWMutex + articleUpdateCache = make(map[string]updateCache) + articleUpsertCacheMut sync.RWMutex + articleUpsertCache = make(map[string]insertCache) +) + +var ( + // Force time package dependency for automated UpdatedAt/CreatedAt. + _ = time.Second + // Force qmhelper dependency for where clause generation (which doesn't + // always happen) + _ = qmhelper.Where +) + +var articleBeforeInsertHooks []ArticleHook +var articleBeforeUpdateHooks []ArticleHook +var articleBeforeDeleteHooks []ArticleHook +var articleBeforeUpsertHooks []ArticleHook + +var articleAfterInsertHooks []ArticleHook +var articleAfterSelectHooks []ArticleHook +var articleAfterUpdateHooks []ArticleHook +var articleAfterDeleteHooks []ArticleHook +var articleAfterUpsertHooks []ArticleHook + +// doBeforeInsertHooks executes all "before insert" hooks. +func (o *Article) doBeforeInsertHooks(ctx context.Context, exec boil.ContextExecutor) (err error) { + if boil.HooksAreSkipped(ctx) { + return nil + } + + for _, hook := range articleBeforeInsertHooks { + if err := hook(ctx, exec, o); err != nil { + return err + } + } + + return nil +} + +// doBeforeUpdateHooks executes all "before Update" hooks. +func (o *Article) doBeforeUpdateHooks(ctx context.Context, exec boil.ContextExecutor) (err error) { + if boil.HooksAreSkipped(ctx) { + return nil + } + + for _, hook := range articleBeforeUpdateHooks { + if err := hook(ctx, exec, o); err != nil { + return err + } + } + + return nil +} + +// doBeforeDeleteHooks executes all "before Delete" hooks. +func (o *Article) doBeforeDeleteHooks(ctx context.Context, exec boil.ContextExecutor) (err error) { + if boil.HooksAreSkipped(ctx) { + return nil + } + + for _, hook := range articleBeforeDeleteHooks { + if err := hook(ctx, exec, o); err != nil { + return err + } + } + + return nil +} + +// doBeforeUpsertHooks executes all "before Upsert" hooks. +func (o *Article) doBeforeUpsertHooks(ctx context.Context, exec boil.ContextExecutor) (err error) { + if boil.HooksAreSkipped(ctx) { + return nil + } + + for _, hook := range articleBeforeUpsertHooks { + if err := hook(ctx, exec, o); err != nil { + return err + } + } + + return nil +} + +// doAfterInsertHooks executes all "after Insert" hooks. +func (o *Article) doAfterInsertHooks(ctx context.Context, exec boil.ContextExecutor) (err error) { + if boil.HooksAreSkipped(ctx) { + return nil + } + + for _, hook := range articleAfterInsertHooks { + if err := hook(ctx, exec, o); err != nil { + return err + } + } + + return nil +} + +// doAfterSelectHooks executes all "after Select" hooks. +func (o *Article) doAfterSelectHooks(ctx context.Context, exec boil.ContextExecutor) (err error) { + if boil.HooksAreSkipped(ctx) { + return nil + } + + for _, hook := range articleAfterSelectHooks { + if err := hook(ctx, exec, o); err != nil { + return err + } + } + + return nil +} + +// doAfterUpdateHooks executes all "after Update" hooks. +func (o *Article) doAfterUpdateHooks(ctx context.Context, exec boil.ContextExecutor) (err error) { + if boil.HooksAreSkipped(ctx) { + return nil + } + + for _, hook := range articleAfterUpdateHooks { + if err := hook(ctx, exec, o); err != nil { + return err + } + } + + return nil +} + +// doAfterDeleteHooks executes all "after Delete" hooks. +func (o *Article) doAfterDeleteHooks(ctx context.Context, exec boil.ContextExecutor) (err error) { + if boil.HooksAreSkipped(ctx) { + return nil + } + + for _, hook := range articleAfterDeleteHooks { + if err := hook(ctx, exec, o); err != nil { + return err + } + } + + return nil +} + +// doAfterUpsertHooks executes all "after Upsert" hooks. +func (o *Article) doAfterUpsertHooks(ctx context.Context, exec boil.ContextExecutor) (err error) { + if boil.HooksAreSkipped(ctx) { + return nil + } + + for _, hook := range articleAfterUpsertHooks { + if err := hook(ctx, exec, o); err != nil { + return err + } + } + + return nil +} + +// AddArticleHook registers your hook function for all future operations. +func AddArticleHook(hookPoint boil.HookPoint, articleHook ArticleHook) { + switch hookPoint { + case boil.BeforeInsertHook: + articleBeforeInsertHooks = append(articleBeforeInsertHooks, articleHook) + case boil.BeforeUpdateHook: + articleBeforeUpdateHooks = append(articleBeforeUpdateHooks, articleHook) + case boil.BeforeDeleteHook: + articleBeforeDeleteHooks = append(articleBeforeDeleteHooks, articleHook) + case boil.BeforeUpsertHook: + articleBeforeUpsertHooks = append(articleBeforeUpsertHooks, articleHook) + case boil.AfterInsertHook: + articleAfterInsertHooks = append(articleAfterInsertHooks, articleHook) + case boil.AfterSelectHook: + articleAfterSelectHooks = append(articleAfterSelectHooks, articleHook) + case boil.AfterUpdateHook: + articleAfterUpdateHooks = append(articleAfterUpdateHooks, articleHook) + case boil.AfterDeleteHook: + articleAfterDeleteHooks = append(articleAfterDeleteHooks, articleHook) + case boil.AfterUpsertHook: + articleAfterUpsertHooks = append(articleAfterUpsertHooks, articleHook) + } +} + +// OneG returns a single article record from the query using the global executor. +func (q articleQuery) OneG(ctx context.Context) (*Article, error) { + return q.One(ctx, boil.GetContextDB()) +} + +// One returns a single article record from the query. +func (q articleQuery) One(ctx context.Context, exec boil.ContextExecutor) (*Article, error) { + o := &Article{} + + queries.SetLimit(q.Query, 1) + + err := q.Bind(ctx, exec, o) + if err != nil { + if errors.Cause(err) == sql.ErrNoRows { + return nil, sql.ErrNoRows + } + return nil, errors.Wrap(err, "dbmodel: failed to execute a one query for articles") + } + + if err := o.doAfterSelectHooks(ctx, exec); err != nil { + return o, err + } + + return o, nil +} + +// AllG returns all Article records from the query using the global executor. +func (q articleQuery) AllG(ctx context.Context) (ArticleSlice, error) { + return q.All(ctx, boil.GetContextDB()) +} + +// All returns all Article records from the query. +func (q articleQuery) All(ctx context.Context, exec boil.ContextExecutor) (ArticleSlice, error) { + var o []*Article + + err := q.Bind(ctx, exec, &o) + if err != nil { + return nil, errors.Wrap(err, "dbmodel: failed to assign all query results to Article slice") + } + + if len(articleAfterSelectHooks) != 0 { + for _, obj := range o { + if err := obj.doAfterSelectHooks(ctx, exec); err != nil { + return o, err + } + } + } + + return o, nil +} + +// CountG returns the count of all Article records in the query, and panics on error. +func (q articleQuery) CountG(ctx context.Context) (int64, error) { + return q.Count(ctx, boil.GetContextDB()) +} + +// Count returns the count of all Article records in the query. +func (q articleQuery) Count(ctx context.Context, exec boil.ContextExecutor) (int64, error) { + var count int64 + + queries.SetSelect(q.Query, nil) + queries.SetCount(q.Query) + + err := q.Query.QueryRowContext(ctx, exec).Scan(&count) + if err != nil { + return 0, errors.Wrap(err, "dbmodel: failed to count articles rows") + } + + return count, nil +} + +// ExistsG checks if the row exists in the table, and panics on error. +func (q articleQuery) ExistsG(ctx context.Context) (bool, error) { + return q.Exists(ctx, boil.GetContextDB()) +} + +// Exists checks if the row exists in the table. +func (q articleQuery) Exists(ctx context.Context, exec boil.ContextExecutor) (bool, error) { + var count int64 + + queries.SetSelect(q.Query, nil) + queries.SetCount(q.Query) + queries.SetLimit(q.Query, 1) + + err := q.Query.QueryRowContext(ctx, exec).Scan(&count) + if err != nil { + return false, errors.Wrap(err, "dbmodel: failed to check if articles exists") + } + + return count > 0, nil +} + +// Articles retrieves all the records using an executor. +func Articles(mods ...qm.QueryMod) articleQuery { + mods = append(mods, qm.From("`articles`")) + return articleQuery{NewQuery(mods...)} +} + +// FindArticleG retrieves a single record by ID. +func FindArticleG(ctx context.Context, articleID int, selectCols ...string) (*Article, error) { + return FindArticle(ctx, boil.GetContextDB(), articleID, selectCols...) +} + +// FindArticle retrieves a single record by ID with an executor. +// If selectCols is empty Find will return all columns. +func FindArticle(ctx context.Context, exec boil.ContextExecutor, articleID int, selectCols ...string) (*Article, error) { + articleObj := &Article{} + + sel := "*" + if len(selectCols) > 0 { + sel = strings.Join(strmangle.IdentQuoteSlice(dialect.LQ, dialect.RQ, selectCols), ",") + } + query := fmt.Sprintf( + "select %s from `articles` where `article_id`=?", sel, + ) + + q := queries.Raw(query, articleID) + + err := q.Bind(ctx, exec, articleObj) + if err != nil { + if errors.Cause(err) == sql.ErrNoRows { + return nil, sql.ErrNoRows + } + return nil, errors.Wrap(err, "dbmodel: unable to select from articles") + } + + return articleObj, nil +} + +// InsertG a single record. See Insert for whitelist behavior description. +func (o *Article) InsertG(ctx context.Context, columns boil.Columns) error { + return o.Insert(ctx, boil.GetContextDB(), columns) +} + +// Insert a single record using an executor. +// See boil.Columns.InsertColumnSet documentation to understand column list inference for inserts. +func (o *Article) Insert(ctx context.Context, exec boil.ContextExecutor, columns boil.Columns) error { + if o == nil { + return errors.New("dbmodel: no articles provided for insertion") + } + + var err error + if !boil.TimestampsAreSkipped(ctx) { + currTime := time.Now().In(boil.GetLocation()) + + if o.CreatedAt.IsZero() { + o.CreatedAt = currTime + } + if o.UpdatedAt.IsZero() { + o.UpdatedAt = currTime + } + } + + if err := o.doBeforeInsertHooks(ctx, exec); err != nil { + return err + } + + nzDefaults := queries.NonZeroDefaultSet(articleColumnsWithDefault, o) + + key := makeCacheKey(columns, nzDefaults) + articleInsertCacheMut.RLock() + cache, cached := articleInsertCache[key] + articleInsertCacheMut.RUnlock() + + if !cached { + wl, returnColumns := columns.InsertColumnSet( + articleAllColumns, + articleColumnsWithDefault, + articleColumnsWithoutDefault, + nzDefaults, + ) + + cache.valueMapping, err = queries.BindMapping(articleType, articleMapping, wl) + if err != nil { + return err + } + cache.retMapping, err = queries.BindMapping(articleType, articleMapping, returnColumns) + if err != nil { + return err + } + if len(wl) != 0 { + cache.query = fmt.Sprintf("INSERT INTO `articles` (`%s`) %%sVALUES (%s)%%s", strings.Join(wl, "`,`"), strmangle.Placeholders(dialect.UseIndexPlaceholders, len(wl), 1, 1)) + } else { + cache.query = "INSERT INTO `articles` () VALUES ()%s%s" + } + + var queryOutput, queryReturning string + + if len(cache.retMapping) != 0 { + cache.retQuery = fmt.Sprintf("SELECT `%s` FROM `articles` WHERE %s", strings.Join(returnColumns, "`,`"), strmangle.WhereClause("`", "`", 0, articlePrimaryKeyColumns)) + } + + cache.query = fmt.Sprintf(cache.query, queryOutput, queryReturning) + } + + value := reflect.Indirect(reflect.ValueOf(o)) + vals := queries.ValuesFromMapping(value, cache.valueMapping) + + if boil.IsDebug(ctx) { + writer := boil.DebugWriterFrom(ctx) + fmt.Fprintln(writer, cache.query) + fmt.Fprintln(writer, vals) + } + result, err := exec.ExecContext(ctx, cache.query, vals...) + + if err != nil { + return errors.Wrap(err, "dbmodel: unable to insert into articles") + } + + var lastID int64 + var identifierCols []interface{} + + if len(cache.retMapping) == 0 { + goto CacheNoHooks + } + + lastID, err = result.LastInsertId() + if err != nil { + return ErrSyncFail + } + + o.ArticleID = int(lastID) + if lastID != 0 && len(cache.retMapping) == 1 && cache.retMapping[0] == articleMapping["article_id"] { + goto CacheNoHooks + } + + identifierCols = []interface{}{ + o.ArticleID, + } + + if boil.IsDebug(ctx) { + writer := boil.DebugWriterFrom(ctx) + fmt.Fprintln(writer, cache.retQuery) + fmt.Fprintln(writer, identifierCols...) + } + err = exec.QueryRowContext(ctx, cache.retQuery, identifierCols...).Scan(queries.PtrsFromMapping(value, cache.retMapping)...) + if err != nil { + return errors.Wrap(err, "dbmodel: unable to populate default values for articles") + } + +CacheNoHooks: + if !cached { + articleInsertCacheMut.Lock() + articleInsertCache[key] = cache + articleInsertCacheMut.Unlock() + } + + return o.doAfterInsertHooks(ctx, exec) +} + +// UpdateG a single Article record using the global executor. +// See Update for more documentation. +func (o *Article) UpdateG(ctx context.Context, columns boil.Columns) (int64, error) { + return o.Update(ctx, boil.GetContextDB(), columns) +} + +// Update uses an executor to update the Article. +// See boil.Columns.UpdateColumnSet documentation to understand column list inference for updates. +// Update does not automatically update the record in case of default values. Use .Reload() to refresh the records. +func (o *Article) Update(ctx context.Context, exec boil.ContextExecutor, columns boil.Columns) (int64, error) { + if !boil.TimestampsAreSkipped(ctx) { + currTime := time.Now().In(boil.GetLocation()) + + o.UpdatedAt = currTime + } + + var err error + if err = o.doBeforeUpdateHooks(ctx, exec); err != nil { + return 0, err + } + key := makeCacheKey(columns, nil) + articleUpdateCacheMut.RLock() + cache, cached := articleUpdateCache[key] + articleUpdateCacheMut.RUnlock() + + if !cached { + wl := columns.UpdateColumnSet( + articleAllColumns, + articlePrimaryKeyColumns, + ) + + if !columns.IsWhitelist() { + wl = strmangle.SetComplement(wl, []string{"created_at"}) + } + if len(wl) == 0 { + return 0, errors.New("dbmodel: unable to update articles, could not build whitelist") + } + + cache.query = fmt.Sprintf("UPDATE `articles` SET %s WHERE %s", + strmangle.SetParamNames("`", "`", 0, wl), + strmangle.WhereClause("`", "`", 0, articlePrimaryKeyColumns), + ) + cache.valueMapping, err = queries.BindMapping(articleType, articleMapping, append(wl, articlePrimaryKeyColumns...)) + if err != nil { + return 0, err + } + } + + values := queries.ValuesFromMapping(reflect.Indirect(reflect.ValueOf(o)), cache.valueMapping) + + if boil.IsDebug(ctx) { + writer := boil.DebugWriterFrom(ctx) + fmt.Fprintln(writer, cache.query) + fmt.Fprintln(writer, values) + } + var result sql.Result + result, err = exec.ExecContext(ctx, cache.query, values...) + if err != nil { + return 0, errors.Wrap(err, "dbmodel: unable to update articles row") + } + + rowsAff, err := result.RowsAffected() + if err != nil { + return 0, errors.Wrap(err, "dbmodel: failed to get rows affected by update for articles") + } + + if !cached { + articleUpdateCacheMut.Lock() + articleUpdateCache[key] = cache + articleUpdateCacheMut.Unlock() + } + + return rowsAff, o.doAfterUpdateHooks(ctx, exec) +} + +// UpdateAllG updates all rows with the specified column values. +func (q articleQuery) UpdateAllG(ctx context.Context, cols M) (int64, error) { + return q.UpdateAll(ctx, boil.GetContextDB(), cols) +} + +// UpdateAll updates all rows with the specified column values. +func (q articleQuery) UpdateAll(ctx context.Context, exec boil.ContextExecutor, cols M) (int64, error) { + queries.SetUpdate(q.Query, cols) + + result, err := q.Query.ExecContext(ctx, exec) + if err != nil { + return 0, errors.Wrap(err, "dbmodel: unable to update all for articles") + } + + rowsAff, err := result.RowsAffected() + if err != nil { + return 0, errors.Wrap(err, "dbmodel: unable to retrieve rows affected for articles") + } + + return rowsAff, nil +} + +// UpdateAllG updates all rows with the specified column values. +func (o ArticleSlice) UpdateAllG(ctx context.Context, cols M) (int64, error) { + return o.UpdateAll(ctx, boil.GetContextDB(), cols) +} + +// UpdateAll updates all rows with the specified column values, using an executor. +func (o ArticleSlice) UpdateAll(ctx context.Context, exec boil.ContextExecutor, cols M) (int64, error) { + ln := int64(len(o)) + if ln == 0 { + return 0, nil + } + + if len(cols) == 0 { + return 0, errors.New("dbmodel: update all requires at least one column argument") + } + + colNames := make([]string, len(cols)) + args := make([]interface{}, len(cols)) + + i := 0 + for name, value := range cols { + colNames[i] = name + args[i] = value + i++ + } + + // Append all of the primary key values for each column + for _, obj := range o { + pkeyArgs := queries.ValuesFromMapping(reflect.Indirect(reflect.ValueOf(obj)), articlePrimaryKeyMapping) + args = append(args, pkeyArgs...) + } + + sql := fmt.Sprintf("UPDATE `articles` SET %s WHERE %s", + strmangle.SetParamNames("`", "`", 0, colNames), + strmangle.WhereClauseRepeated(string(dialect.LQ), string(dialect.RQ), 0, articlePrimaryKeyColumns, len(o))) + + if boil.IsDebug(ctx) { + writer := boil.DebugWriterFrom(ctx) + fmt.Fprintln(writer, sql) + fmt.Fprintln(writer, args...) + } + result, err := exec.ExecContext(ctx, sql, args...) + if err != nil { + return 0, errors.Wrap(err, "dbmodel: unable to update all in article slice") + } + + rowsAff, err := result.RowsAffected() + if err != nil { + return 0, errors.Wrap(err, "dbmodel: unable to retrieve rows affected all in update all article") + } + return rowsAff, nil +} + +// UpsertG attempts an insert, and does an update or ignore on conflict. +func (o *Article) UpsertG(ctx context.Context, updateColumns, insertColumns boil.Columns) error { + return o.Upsert(ctx, boil.GetContextDB(), updateColumns, insertColumns) +} + +var mySQLArticleUniqueColumns = []string{ + "article_id", +} + +// Upsert attempts an insert using an executor, and does an update or ignore on conflict. +// See boil.Columns documentation for how to properly use updateColumns and insertColumns. +func (o *Article) Upsert(ctx context.Context, exec boil.ContextExecutor, updateColumns, insertColumns boil.Columns) error { + if o == nil { + return errors.New("dbmodel: no articles provided for upsert") + } + if !boil.TimestampsAreSkipped(ctx) { + currTime := time.Now().In(boil.GetLocation()) + + if o.CreatedAt.IsZero() { + o.CreatedAt = currTime + } + o.UpdatedAt = currTime + } + + if err := o.doBeforeUpsertHooks(ctx, exec); err != nil { + return err + } + + nzDefaults := queries.NonZeroDefaultSet(articleColumnsWithDefault, o) + nzUniques := queries.NonZeroDefaultSet(mySQLArticleUniqueColumns, o) + + if len(nzUniques) == 0 { + return errors.New("cannot upsert with a table that cannot conflict on a unique column") + } + + // Build cache key in-line uglily - mysql vs psql problems + buf := strmangle.GetBuffer() + buf.WriteString(strconv.Itoa(updateColumns.Kind)) + for _, c := range updateColumns.Cols { + buf.WriteString(c) + } + buf.WriteByte('.') + buf.WriteString(strconv.Itoa(insertColumns.Kind)) + for _, c := range insertColumns.Cols { + buf.WriteString(c) + } + buf.WriteByte('.') + for _, c := range nzDefaults { + buf.WriteString(c) + } + buf.WriteByte('.') + for _, c := range nzUniques { + buf.WriteString(c) + } + key := buf.String() + strmangle.PutBuffer(buf) + + articleUpsertCacheMut.RLock() + cache, cached := articleUpsertCache[key] + articleUpsertCacheMut.RUnlock() + + var err error + + if !cached { + insert, ret := insertColumns.InsertColumnSet( + articleAllColumns, + articleColumnsWithDefault, + articleColumnsWithoutDefault, + nzDefaults, + ) + update := updateColumns.UpdateColumnSet( + articleAllColumns, + articlePrimaryKeyColumns, + ) + + if len(update) == 0 { + return errors.New("dbmodel: unable to upsert articles, could not build update column list") + } + + ret = strmangle.SetComplement(ret, nzUniques) + cache.query = buildUpsertQueryMySQL(dialect, "articles", update, insert) + cache.retQuery = fmt.Sprintf( + "SELECT %s FROM `articles` WHERE %s", + strings.Join(strmangle.IdentQuoteSlice(dialect.LQ, dialect.RQ, ret), ","), + strmangle.WhereClause("`", "`", 0, nzUniques), + ) + + cache.valueMapping, err = queries.BindMapping(articleType, articleMapping, insert) + if err != nil { + return err + } + if len(ret) != 0 { + cache.retMapping, err = queries.BindMapping(articleType, articleMapping, ret) + if err != nil { + return err + } + } + } + + value := reflect.Indirect(reflect.ValueOf(o)) + vals := queries.ValuesFromMapping(value, cache.valueMapping) + var returns []interface{} + if len(cache.retMapping) != 0 { + returns = queries.PtrsFromMapping(value, cache.retMapping) + } + + if boil.IsDebug(ctx) { + writer := boil.DebugWriterFrom(ctx) + fmt.Fprintln(writer, cache.query) + fmt.Fprintln(writer, vals) + } + result, err := exec.ExecContext(ctx, cache.query, vals...) + + if err != nil { + return errors.Wrap(err, "dbmodel: unable to upsert for articles") + } + + var lastID int64 + var uniqueMap []uint64 + var nzUniqueCols []interface{} + + if len(cache.retMapping) == 0 { + goto CacheNoHooks + } + + lastID, err = result.LastInsertId() + if err != nil { + return ErrSyncFail + } + + o.ArticleID = int(lastID) + if lastID != 0 && len(cache.retMapping) == 1 && cache.retMapping[0] == articleMapping["article_id"] { + goto CacheNoHooks + } + + uniqueMap, err = queries.BindMapping(articleType, articleMapping, nzUniques) + if err != nil { + return errors.Wrap(err, "dbmodel: unable to retrieve unique values for articles") + } + nzUniqueCols = queries.ValuesFromMapping(reflect.Indirect(reflect.ValueOf(o)), uniqueMap) + + if boil.IsDebug(ctx) { + writer := boil.DebugWriterFrom(ctx) + fmt.Fprintln(writer, cache.retQuery) + fmt.Fprintln(writer, nzUniqueCols...) + } + err = exec.QueryRowContext(ctx, cache.retQuery, nzUniqueCols...).Scan(returns...) + if err != nil { + return errors.Wrap(err, "dbmodel: unable to populate default values for articles") + } + +CacheNoHooks: + if !cached { + articleUpsertCacheMut.Lock() + articleUpsertCache[key] = cache + articleUpsertCacheMut.Unlock() + } + + return o.doAfterUpsertHooks(ctx, exec) +} + +// DeleteG deletes a single Article record. +// DeleteG will match against the primary key column to find the record to delete. +func (o *Article) DeleteG(ctx context.Context) (int64, error) { + return o.Delete(ctx, boil.GetContextDB()) +} + +// Delete deletes a single Article record with an executor. +// Delete will match against the primary key column to find the record to delete. +func (o *Article) Delete(ctx context.Context, exec boil.ContextExecutor) (int64, error) { + if o == nil { + return 0, errors.New("dbmodel: no Article provided for delete") + } + + if err := o.doBeforeDeleteHooks(ctx, exec); err != nil { + return 0, err + } + + args := queries.ValuesFromMapping(reflect.Indirect(reflect.ValueOf(o)), articlePrimaryKeyMapping) + sql := "DELETE FROM `articles` WHERE `article_id`=?" + + if boil.IsDebug(ctx) { + writer := boil.DebugWriterFrom(ctx) + fmt.Fprintln(writer, sql) + fmt.Fprintln(writer, args...) + } + result, err := exec.ExecContext(ctx, sql, args...) + if err != nil { + return 0, errors.Wrap(err, "dbmodel: unable to delete from articles") + } + + rowsAff, err := result.RowsAffected() + if err != nil { + return 0, errors.Wrap(err, "dbmodel: failed to get rows affected by delete for articles") + } + + if err := o.doAfterDeleteHooks(ctx, exec); err != nil { + return 0, err + } + + return rowsAff, nil +} + +// DeleteAll deletes all matching rows. +func (q articleQuery) DeleteAll(ctx context.Context, exec boil.ContextExecutor) (int64, error) { + if q.Query == nil { + return 0, errors.New("dbmodel: no articleQuery provided for delete all") + } + + queries.SetDelete(q.Query) + + result, err := q.Query.ExecContext(ctx, exec) + if err != nil { + return 0, errors.Wrap(err, "dbmodel: unable to delete all from articles") + } + + rowsAff, err := result.RowsAffected() + if err != nil { + return 0, errors.Wrap(err, "dbmodel: failed to get rows affected by deleteall for articles") + } + + return rowsAff, nil +} + +// DeleteAllG deletes all rows in the slice. +func (o ArticleSlice) DeleteAllG(ctx context.Context) (int64, error) { + return o.DeleteAll(ctx, boil.GetContextDB()) +} + +// DeleteAll deletes all rows in the slice, using an executor. +func (o ArticleSlice) DeleteAll(ctx context.Context, exec boil.ContextExecutor) (int64, error) { + if len(o) == 0 { + return 0, nil + } + + if len(articleBeforeDeleteHooks) != 0 { + for _, obj := range o { + if err := obj.doBeforeDeleteHooks(ctx, exec); err != nil { + return 0, err + } + } + } + + var args []interface{} + for _, obj := range o { + pkeyArgs := queries.ValuesFromMapping(reflect.Indirect(reflect.ValueOf(obj)), articlePrimaryKeyMapping) + args = append(args, pkeyArgs...) + } + + sql := "DELETE FROM `articles` WHERE " + + strmangle.WhereClauseRepeated(string(dialect.LQ), string(dialect.RQ), 0, articlePrimaryKeyColumns, len(o)) + + if boil.IsDebug(ctx) { + writer := boil.DebugWriterFrom(ctx) + fmt.Fprintln(writer, sql) + fmt.Fprintln(writer, args) + } + result, err := exec.ExecContext(ctx, sql, args...) + if err != nil { + return 0, errors.Wrap(err, "dbmodel: unable to delete all from article slice") + } + + rowsAff, err := result.RowsAffected() + if err != nil { + return 0, errors.Wrap(err, "dbmodel: failed to get rows affected by deleteall for articles") + } + + if len(articleAfterDeleteHooks) != 0 { + for _, obj := range o { + if err := obj.doAfterDeleteHooks(ctx, exec); err != nil { + return 0, err + } + } + } + + return rowsAff, nil +} + +// ReloadG refetches the object from the database using the primary keys. +func (o *Article) ReloadG(ctx context.Context) error { + if o == nil { + return errors.New("dbmodel: no Article provided for reload") + } + + return o.Reload(ctx, boil.GetContextDB()) +} + +// Reload refetches the object from the database +// using the primary keys with an executor. +func (o *Article) Reload(ctx context.Context, exec boil.ContextExecutor) error { + ret, err := FindArticle(ctx, exec, o.ArticleID) + if err != nil { + return err + } + + *o = *ret + return nil +} + +// ReloadAllG refetches every row with matching primary key column values +// and overwrites the original object slice with the newly updated slice. +func (o *ArticleSlice) ReloadAllG(ctx context.Context) error { + if o == nil { + return errors.New("dbmodel: empty ArticleSlice provided for reload all") + } + + return o.ReloadAll(ctx, boil.GetContextDB()) +} + +// ReloadAll refetches every row with matching primary key column values +// and overwrites the original object slice with the newly updated slice. +func (o *ArticleSlice) ReloadAll(ctx context.Context, exec boil.ContextExecutor) error { + if o == nil || len(*o) == 0 { + return nil + } + + slice := ArticleSlice{} + var args []interface{} + for _, obj := range *o { + pkeyArgs := queries.ValuesFromMapping(reflect.Indirect(reflect.ValueOf(obj)), articlePrimaryKeyMapping) + args = append(args, pkeyArgs...) + } + + sql := "SELECT `articles`.* FROM `articles` WHERE " + + strmangle.WhereClauseRepeated(string(dialect.LQ), string(dialect.RQ), 0, articlePrimaryKeyColumns, len(*o)) + + q := queries.Raw(sql, args...) + + err := q.Bind(ctx, exec, &slice) + if err != nil { + return errors.Wrap(err, "dbmodel: unable to reload all in ArticleSlice") + } + + *o = slice + + return nil +} + +// ArticleExistsG checks if the Article row exists. +func ArticleExistsG(ctx context.Context, articleID int) (bool, error) { + return ArticleExists(ctx, boil.GetContextDB(), articleID) +} + +// ArticleExists checks if the Article row exists. +func ArticleExists(ctx context.Context, exec boil.ContextExecutor, articleID int) (bool, error) { + var exists bool + sql := "select exists(select 1 from `articles` where `article_id`=? limit 1)" + + if boil.IsDebug(ctx) { + writer := boil.DebugWriterFrom(ctx) + fmt.Fprintln(writer, sql) + fmt.Fprintln(writer, articleID) + } + row := exec.QueryRowContext(ctx, sql, articleID) + + err := row.Scan(&exists) + if err != nil { + return false, errors.Wrap(err, "dbmodel: unable to check if articles exists") + } + + return exists, nil +} diff --git a/domain/dbmodel/articles_test.go b/domain/dbmodel/articles_test.go new file mode 100644 index 0000000..257d692 --- /dev/null +++ b/domain/dbmodel/articles_test.go @@ -0,0 +1,735 @@ +// Code generated by SQLBoiler 3.7.1 (https://github.com/volatiletech/sqlboiler). DO NOT EDIT. +// This file is meant to be re-generated in place and/or deleted at any time. + +package dbmodel + +import ( + "bytes" + "context" + "reflect" + "testing" + + "github.com/volatiletech/sqlboiler/boil" + "github.com/volatiletech/sqlboiler/queries" + "github.com/volatiletech/sqlboiler/randomize" + "github.com/volatiletech/sqlboiler/strmangle" +) + +var ( + // Relationships sometimes use the reflection helper queries.Equal/queries.Assign + // so force a package dependency in case they don't. + _ = queries.Equal +) + +func testArticles(t *testing.T) { + t.Parallel() + + query := Articles() + + if query.Query == nil { + t.Error("expected a query, got nothing") + } +} + +func testArticlesDelete(t *testing.T) { + t.Parallel() + + seed := randomize.NewSeed() + var err error + o := &Article{} + if err = randomize.Struct(seed, o, articleDBTypes, true, articleColumnsWithDefault...); err != nil { + t.Errorf("Unable to randomize Article struct: %s", err) + } + + ctx := context.Background() + tx := MustTx(boil.BeginTx(ctx, nil)) + defer func() { _ = tx.Rollback() }() + if err = o.Insert(ctx, tx, boil.Infer()); err != nil { + t.Error(err) + } + + if rowsAff, err := o.Delete(ctx, tx); err != nil { + t.Error(err) + } else if rowsAff != 1 { + t.Error("should only have deleted one row, but affected:", rowsAff) + } + + count, err := Articles().Count(ctx, tx) + if err != nil { + t.Error(err) + } + + if count != 0 { + t.Error("want zero records, got:", count) + } +} + +func testArticlesQueryDeleteAll(t *testing.T) { + t.Parallel() + + seed := randomize.NewSeed() + var err error + o := &Article{} + if err = randomize.Struct(seed, o, articleDBTypes, true, articleColumnsWithDefault...); err != nil { + t.Errorf("Unable to randomize Article struct: %s", err) + } + + ctx := context.Background() + tx := MustTx(boil.BeginTx(ctx, nil)) + defer func() { _ = tx.Rollback() }() + if err = o.Insert(ctx, tx, boil.Infer()); err != nil { + t.Error(err) + } + + if rowsAff, err := Articles().DeleteAll(ctx, tx); err != nil { + t.Error(err) + } else if rowsAff != 1 { + t.Error("should only have deleted one row, but affected:", rowsAff) + } + + count, err := Articles().Count(ctx, tx) + if err != nil { + t.Error(err) + } + + if count != 0 { + t.Error("want zero records, got:", count) + } +} + +func testArticlesSliceDeleteAll(t *testing.T) { + t.Parallel() + + seed := randomize.NewSeed() + var err error + o := &Article{} + if err = randomize.Struct(seed, o, articleDBTypes, true, articleColumnsWithDefault...); err != nil { + t.Errorf("Unable to randomize Article struct: %s", err) + } + + ctx := context.Background() + tx := MustTx(boil.BeginTx(ctx, nil)) + defer func() { _ = tx.Rollback() }() + if err = o.Insert(ctx, tx, boil.Infer()); err != nil { + t.Error(err) + } + + slice := ArticleSlice{o} + + if rowsAff, err := slice.DeleteAll(ctx, tx); err != nil { + t.Error(err) + } else if rowsAff != 1 { + t.Error("should only have deleted one row, but affected:", rowsAff) + } + + count, err := Articles().Count(ctx, tx) + if err != nil { + t.Error(err) + } + + if count != 0 { + t.Error("want zero records, got:", count) + } +} + +func testArticlesExists(t *testing.T) { + t.Parallel() + + seed := randomize.NewSeed() + var err error + o := &Article{} + if err = randomize.Struct(seed, o, articleDBTypes, true, articleColumnsWithDefault...); err != nil { + t.Errorf("Unable to randomize Article struct: %s", err) + } + + ctx := context.Background() + tx := MustTx(boil.BeginTx(ctx, nil)) + defer func() { _ = tx.Rollback() }() + if err = o.Insert(ctx, tx, boil.Infer()); err != nil { + t.Error(err) + } + + e, err := ArticleExists(ctx, tx, o.ArticleID) + if err != nil { + t.Errorf("Unable to check if Article exists: %s", err) + } + if !e { + t.Errorf("Expected ArticleExists to return true, but got false.") + } +} + +func testArticlesFind(t *testing.T) { + t.Parallel() + + seed := randomize.NewSeed() + var err error + o := &Article{} + if err = randomize.Struct(seed, o, articleDBTypes, true, articleColumnsWithDefault...); err != nil { + t.Errorf("Unable to randomize Article struct: %s", err) + } + + ctx := context.Background() + tx := MustTx(boil.BeginTx(ctx, nil)) + defer func() { _ = tx.Rollback() }() + if err = o.Insert(ctx, tx, boil.Infer()); err != nil { + t.Error(err) + } + + articleFound, err := FindArticle(ctx, tx, o.ArticleID) + if err != nil { + t.Error(err) + } + + if articleFound == nil { + t.Error("want a record, got nil") + } +} + +func testArticlesBind(t *testing.T) { + t.Parallel() + + seed := randomize.NewSeed() + var err error + o := &Article{} + if err = randomize.Struct(seed, o, articleDBTypes, true, articleColumnsWithDefault...); err != nil { + t.Errorf("Unable to randomize Article struct: %s", err) + } + + ctx := context.Background() + tx := MustTx(boil.BeginTx(ctx, nil)) + defer func() { _ = tx.Rollback() }() + if err = o.Insert(ctx, tx, boil.Infer()); err != nil { + t.Error(err) + } + + if err = Articles().Bind(ctx, tx, o); err != nil { + t.Error(err) + } +} + +func testArticlesOne(t *testing.T) { + t.Parallel() + + seed := randomize.NewSeed() + var err error + o := &Article{} + if err = randomize.Struct(seed, o, articleDBTypes, true, articleColumnsWithDefault...); err != nil { + t.Errorf("Unable to randomize Article struct: %s", err) + } + + ctx := context.Background() + tx := MustTx(boil.BeginTx(ctx, nil)) + defer func() { _ = tx.Rollback() }() + if err = o.Insert(ctx, tx, boil.Infer()); err != nil { + t.Error(err) + } + + if x, err := Articles().One(ctx, tx); err != nil { + t.Error(err) + } else if x == nil { + t.Error("expected to get a non nil record") + } +} + +func testArticlesAll(t *testing.T) { + t.Parallel() + + seed := randomize.NewSeed() + var err error + articleOne := &Article{} + articleTwo := &Article{} + if err = randomize.Struct(seed, articleOne, articleDBTypes, false, articleColumnsWithDefault...); err != nil { + t.Errorf("Unable to randomize Article struct: %s", err) + } + if err = randomize.Struct(seed, articleTwo, articleDBTypes, false, articleColumnsWithDefault...); err != nil { + t.Errorf("Unable to randomize Article struct: %s", err) + } + + ctx := context.Background() + tx := MustTx(boil.BeginTx(ctx, nil)) + defer func() { _ = tx.Rollback() }() + if err = articleOne.Insert(ctx, tx, boil.Infer()); err != nil { + t.Error(err) + } + if err = articleTwo.Insert(ctx, tx, boil.Infer()); err != nil { + t.Error(err) + } + + slice, err := Articles().All(ctx, tx) + if err != nil { + t.Error(err) + } + + if len(slice) != 2 { + t.Error("want 2 records, got:", len(slice)) + } +} + +func testArticlesCount(t *testing.T) { + t.Parallel() + + var err error + seed := randomize.NewSeed() + articleOne := &Article{} + articleTwo := &Article{} + if err = randomize.Struct(seed, articleOne, articleDBTypes, false, articleColumnsWithDefault...); err != nil { + t.Errorf("Unable to randomize Article struct: %s", err) + } + if err = randomize.Struct(seed, articleTwo, articleDBTypes, false, articleColumnsWithDefault...); err != nil { + t.Errorf("Unable to randomize Article struct: %s", err) + } + + ctx := context.Background() + tx := MustTx(boil.BeginTx(ctx, nil)) + defer func() { _ = tx.Rollback() }() + if err = articleOne.Insert(ctx, tx, boil.Infer()); err != nil { + t.Error(err) + } + if err = articleTwo.Insert(ctx, tx, boil.Infer()); err != nil { + t.Error(err) + } + + count, err := Articles().Count(ctx, tx) + if err != nil { + t.Error(err) + } + + if count != 2 { + t.Error("want 2 records, got:", count) + } +} + +func articleBeforeInsertHook(ctx context.Context, e boil.ContextExecutor, o *Article) error { + *o = Article{} + return nil +} + +func articleAfterInsertHook(ctx context.Context, e boil.ContextExecutor, o *Article) error { + *o = Article{} + return nil +} + +func articleAfterSelectHook(ctx context.Context, e boil.ContextExecutor, o *Article) error { + *o = Article{} + return nil +} + +func articleBeforeUpdateHook(ctx context.Context, e boil.ContextExecutor, o *Article) error { + *o = Article{} + return nil +} + +func articleAfterUpdateHook(ctx context.Context, e boil.ContextExecutor, o *Article) error { + *o = Article{} + return nil +} + +func articleBeforeDeleteHook(ctx context.Context, e boil.ContextExecutor, o *Article) error { + *o = Article{} + return nil +} + +func articleAfterDeleteHook(ctx context.Context, e boil.ContextExecutor, o *Article) error { + *o = Article{} + return nil +} + +func articleBeforeUpsertHook(ctx context.Context, e boil.ContextExecutor, o *Article) error { + *o = Article{} + return nil +} + +func articleAfterUpsertHook(ctx context.Context, e boil.ContextExecutor, o *Article) error { + *o = Article{} + return nil +} + +func testArticlesHooks(t *testing.T) { + t.Parallel() + + var err error + + ctx := context.Background() + empty := &Article{} + o := &Article{} + + seed := randomize.NewSeed() + if err = randomize.Struct(seed, o, articleDBTypes, false); err != nil { + t.Errorf("Unable to randomize Article object: %s", err) + } + + AddArticleHook(boil.BeforeInsertHook, articleBeforeInsertHook) + if err = o.doBeforeInsertHooks(ctx, nil); err != nil { + t.Errorf("Unable to execute doBeforeInsertHooks: %s", err) + } + if !reflect.DeepEqual(o, empty) { + t.Errorf("Expected BeforeInsertHook function to empty object, but got: %#v", o) + } + articleBeforeInsertHooks = []ArticleHook{} + + AddArticleHook(boil.AfterInsertHook, articleAfterInsertHook) + if err = o.doAfterInsertHooks(ctx, nil); err != nil { + t.Errorf("Unable to execute doAfterInsertHooks: %s", err) + } + if !reflect.DeepEqual(o, empty) { + t.Errorf("Expected AfterInsertHook function to empty object, but got: %#v", o) + } + articleAfterInsertHooks = []ArticleHook{} + + AddArticleHook(boil.AfterSelectHook, articleAfterSelectHook) + if err = o.doAfterSelectHooks(ctx, nil); err != nil { + t.Errorf("Unable to execute doAfterSelectHooks: %s", err) + } + if !reflect.DeepEqual(o, empty) { + t.Errorf("Expected AfterSelectHook function to empty object, but got: %#v", o) + } + articleAfterSelectHooks = []ArticleHook{} + + AddArticleHook(boil.BeforeUpdateHook, articleBeforeUpdateHook) + if err = o.doBeforeUpdateHooks(ctx, nil); err != nil { + t.Errorf("Unable to execute doBeforeUpdateHooks: %s", err) + } + if !reflect.DeepEqual(o, empty) { + t.Errorf("Expected BeforeUpdateHook function to empty object, but got: %#v", o) + } + articleBeforeUpdateHooks = []ArticleHook{} + + AddArticleHook(boil.AfterUpdateHook, articleAfterUpdateHook) + if err = o.doAfterUpdateHooks(ctx, nil); err != nil { + t.Errorf("Unable to execute doAfterUpdateHooks: %s", err) + } + if !reflect.DeepEqual(o, empty) { + t.Errorf("Expected AfterUpdateHook function to empty object, but got: %#v", o) + } + articleAfterUpdateHooks = []ArticleHook{} + + AddArticleHook(boil.BeforeDeleteHook, articleBeforeDeleteHook) + if err = o.doBeforeDeleteHooks(ctx, nil); err != nil { + t.Errorf("Unable to execute doBeforeDeleteHooks: %s", err) + } + if !reflect.DeepEqual(o, empty) { + t.Errorf("Expected BeforeDeleteHook function to empty object, but got: %#v", o) + } + articleBeforeDeleteHooks = []ArticleHook{} + + AddArticleHook(boil.AfterDeleteHook, articleAfterDeleteHook) + if err = o.doAfterDeleteHooks(ctx, nil); err != nil { + t.Errorf("Unable to execute doAfterDeleteHooks: %s", err) + } + if !reflect.DeepEqual(o, empty) { + t.Errorf("Expected AfterDeleteHook function to empty object, but got: %#v", o) + } + articleAfterDeleteHooks = []ArticleHook{} + + AddArticleHook(boil.BeforeUpsertHook, articleBeforeUpsertHook) + if err = o.doBeforeUpsertHooks(ctx, nil); err != nil { + t.Errorf("Unable to execute doBeforeUpsertHooks: %s", err) + } + if !reflect.DeepEqual(o, empty) { + t.Errorf("Expected BeforeUpsertHook function to empty object, but got: %#v", o) + } + articleBeforeUpsertHooks = []ArticleHook{} + + AddArticleHook(boil.AfterUpsertHook, articleAfterUpsertHook) + if err = o.doAfterUpsertHooks(ctx, nil); err != nil { + t.Errorf("Unable to execute doAfterUpsertHooks: %s", err) + } + if !reflect.DeepEqual(o, empty) { + t.Errorf("Expected AfterUpsertHook function to empty object, but got: %#v", o) + } + articleAfterUpsertHooks = []ArticleHook{} +} + +func testArticlesInsert(t *testing.T) { + t.Parallel() + + seed := randomize.NewSeed() + var err error + o := &Article{} + if err = randomize.Struct(seed, o, articleDBTypes, true, articleColumnsWithDefault...); err != nil { + t.Errorf("Unable to randomize Article struct: %s", err) + } + + ctx := context.Background() + tx := MustTx(boil.BeginTx(ctx, nil)) + defer func() { _ = tx.Rollback() }() + if err = o.Insert(ctx, tx, boil.Infer()); err != nil { + t.Error(err) + } + + count, err := Articles().Count(ctx, tx) + if err != nil { + t.Error(err) + } + + if count != 1 { + t.Error("want one record, got:", count) + } +} + +func testArticlesInsertWhitelist(t *testing.T) { + t.Parallel() + + seed := randomize.NewSeed() + var err error + o := &Article{} + if err = randomize.Struct(seed, o, articleDBTypes, true); err != nil { + t.Errorf("Unable to randomize Article struct: %s", err) + } + + ctx := context.Background() + tx := MustTx(boil.BeginTx(ctx, nil)) + defer func() { _ = tx.Rollback() }() + if err = o.Insert(ctx, tx, boil.Whitelist(articleColumnsWithoutDefault...)); err != nil { + t.Error(err) + } + + count, err := Articles().Count(ctx, tx) + if err != nil { + t.Error(err) + } + + if count != 1 { + t.Error("want one record, got:", count) + } +} + +func testArticlesReload(t *testing.T) { + t.Parallel() + + seed := randomize.NewSeed() + var err error + o := &Article{} + if err = randomize.Struct(seed, o, articleDBTypes, true, articleColumnsWithDefault...); err != nil { + t.Errorf("Unable to randomize Article struct: %s", err) + } + + ctx := context.Background() + tx := MustTx(boil.BeginTx(ctx, nil)) + defer func() { _ = tx.Rollback() }() + if err = o.Insert(ctx, tx, boil.Infer()); err != nil { + t.Error(err) + } + + if err = o.Reload(ctx, tx); err != nil { + t.Error(err) + } +} + +func testArticlesReloadAll(t *testing.T) { + t.Parallel() + + seed := randomize.NewSeed() + var err error + o := &Article{} + if err = randomize.Struct(seed, o, articleDBTypes, true, articleColumnsWithDefault...); err != nil { + t.Errorf("Unable to randomize Article struct: %s", err) + } + + ctx := context.Background() + tx := MustTx(boil.BeginTx(ctx, nil)) + defer func() { _ = tx.Rollback() }() + if err = o.Insert(ctx, tx, boil.Infer()); err != nil { + t.Error(err) + } + + slice := ArticleSlice{o} + + if err = slice.ReloadAll(ctx, tx); err != nil { + t.Error(err) + } +} + +func testArticlesSelect(t *testing.T) { + t.Parallel() + + seed := randomize.NewSeed() + var err error + o := &Article{} + if err = randomize.Struct(seed, o, articleDBTypes, true, articleColumnsWithDefault...); err != nil { + t.Errorf("Unable to randomize Article struct: %s", err) + } + + ctx := context.Background() + tx := MustTx(boil.BeginTx(ctx, nil)) + defer func() { _ = tx.Rollback() }() + if err = o.Insert(ctx, tx, boil.Infer()); err != nil { + t.Error(err) + } + + slice, err := Articles().All(ctx, tx) + if err != nil { + t.Error(err) + } + + if len(slice) != 1 { + t.Error("want one record, got:", len(slice)) + } +} + +var ( + articleDBTypes = map[string]string{`ArticleID`: `int`, `Title`: `text`, `Body`: `text`, `PostedAt`: `datetime`, `CreatedAt`: `timestamp`, `UpdatedAt`: `timestamp`} + _ = bytes.MinRead +) + +func testArticlesUpdate(t *testing.T) { + t.Parallel() + + if 0 == len(articlePrimaryKeyColumns) { + t.Skip("Skipping table with no primary key columns") + } + if len(articleAllColumns) == len(articlePrimaryKeyColumns) { + t.Skip("Skipping table with only primary key columns") + } + + seed := randomize.NewSeed() + var err error + o := &Article{} + if err = randomize.Struct(seed, o, articleDBTypes, true, articleColumnsWithDefault...); err != nil { + t.Errorf("Unable to randomize Article struct: %s", err) + } + + ctx := context.Background() + tx := MustTx(boil.BeginTx(ctx, nil)) + defer func() { _ = tx.Rollback() }() + if err = o.Insert(ctx, tx, boil.Infer()); err != nil { + t.Error(err) + } + + count, err := Articles().Count(ctx, tx) + if err != nil { + t.Error(err) + } + + if count != 1 { + t.Error("want one record, got:", count) + } + + if err = randomize.Struct(seed, o, articleDBTypes, true, articlePrimaryKeyColumns...); err != nil { + t.Errorf("Unable to randomize Article struct: %s", err) + } + + if rowsAff, err := o.Update(ctx, tx, boil.Infer()); err != nil { + t.Error(err) + } else if rowsAff != 1 { + t.Error("should only affect one row but affected", rowsAff) + } +} + +func testArticlesSliceUpdateAll(t *testing.T) { + t.Parallel() + + if len(articleAllColumns) == len(articlePrimaryKeyColumns) { + t.Skip("Skipping table with only primary key columns") + } + + seed := randomize.NewSeed() + var err error + o := &Article{} + if err = randomize.Struct(seed, o, articleDBTypes, true, articleColumnsWithDefault...); err != nil { + t.Errorf("Unable to randomize Article struct: %s", err) + } + + ctx := context.Background() + tx := MustTx(boil.BeginTx(ctx, nil)) + defer func() { _ = tx.Rollback() }() + if err = o.Insert(ctx, tx, boil.Infer()); err != nil { + t.Error(err) + } + + count, err := Articles().Count(ctx, tx) + if err != nil { + t.Error(err) + } + + if count != 1 { + t.Error("want one record, got:", count) + } + + if err = randomize.Struct(seed, o, articleDBTypes, true, articlePrimaryKeyColumns...); err != nil { + t.Errorf("Unable to randomize Article struct: %s", err) + } + + // Remove Primary keys and unique columns from what we plan to update + var fields []string + if strmangle.StringSliceMatch(articleAllColumns, articlePrimaryKeyColumns) { + fields = articleAllColumns + } else { + fields = strmangle.SetComplement( + articleAllColumns, + articlePrimaryKeyColumns, + ) + } + + value := reflect.Indirect(reflect.ValueOf(o)) + typ := reflect.TypeOf(o).Elem() + n := typ.NumField() + + updateMap := M{} + for _, col := range fields { + for i := 0; i < n; i++ { + f := typ.Field(i) + if f.Tag.Get("boil") == col { + updateMap[col] = value.Field(i).Interface() + } + } + } + + slice := ArticleSlice{o} + if rowsAff, err := slice.UpdateAll(ctx, tx, updateMap); err != nil { + t.Error(err) + } else if rowsAff != 1 { + t.Error("wanted one record updated but got", rowsAff) + } +} + +func testArticlesUpsert(t *testing.T) { + t.Parallel() + + if len(articleAllColumns) == len(articlePrimaryKeyColumns) { + t.Skip("Skipping table with only primary key columns") + } + if len(mySQLArticleUniqueColumns) == 0 { + t.Skip("Skipping table with no unique columns to conflict on") + } + + seed := randomize.NewSeed() + var err error + // Attempt the INSERT side of an UPSERT + o := Article{} + if err = randomize.Struct(seed, &o, articleDBTypes, false); err != nil { + t.Errorf("Unable to randomize Article struct: %s", err) + } + + ctx := context.Background() + tx := MustTx(boil.BeginTx(ctx, nil)) + defer func() { _ = tx.Rollback() }() + if err = o.Upsert(ctx, tx, boil.Infer(), boil.Infer()); err != nil { + t.Errorf("Unable to upsert Article: %s", err) + } + + count, err := Articles().Count(ctx, tx) + if err != nil { + t.Error(err) + } + if count != 1 { + t.Error("want one record, got:", count) + } + + // Attempt the UPDATE side of an UPSERT + if err = randomize.Struct(seed, &o, articleDBTypes, false, articlePrimaryKeyColumns...); err != nil { + t.Errorf("Unable to randomize Article struct: %s", err) + } + + if err = o.Upsert(ctx, tx, boil.Infer(), boil.Infer()); err != nil { + t.Errorf("Unable to upsert Article: %s", err) + } + + count, err = Articles().Count(ctx, tx) + if err != nil { + t.Error(err) + } + if count != 1 { + t.Error("want one record, got:", count) + } +} diff --git a/domain/dbmodel/boil_main_test.go b/domain/dbmodel/boil_main_test.go new file mode 100644 index 0000000..be68c48 --- /dev/null +++ b/domain/dbmodel/boil_main_test.go @@ -0,0 +1,119 @@ +// Code generated by SQLBoiler 3.7.1 (https://github.com/volatiletech/sqlboiler). DO NOT EDIT. +// This file is meant to be re-generated in place and/or deleted at any time. + +package dbmodel + +import ( + "database/sql" + "flag" + "fmt" + "math/rand" + "os" + "path/filepath" + "strings" + "testing" + "time" + + "github.com/spf13/viper" + "github.com/volatiletech/sqlboiler/boil" +) + +var flagDebugMode = flag.Bool("test.sqldebug", false, "Turns on debug mode for SQL statements") +var flagConfigFile = flag.String("test.config", "", "Overrides the default config") + +const outputDirDepth = 2 + +var ( + dbMain tester +) + +type tester interface { + setup() error + conn() (*sql.DB, error) + teardown() error +} + +func TestMain(m *testing.M) { + if dbMain == nil { + fmt.Println("no dbMain tester interface was ready") + os.Exit(-1) + } + + rand.Seed(time.Now().UnixNano()) + + flag.Parse() + + var err error + + // Load configuration + err = initViper() + if err != nil { + fmt.Println("unable to load config file") + os.Exit(-2) + } + + // Set DebugMode so we can see generated sql statements + boil.DebugMode = *flagDebugMode + + if err = dbMain.setup(); err != nil { + fmt.Println("Unable to execute setup:", err) + os.Exit(-4) + } + + conn, err := dbMain.conn() + if err != nil { + fmt.Println("failed to get connection:", err) + } + + var code int + boil.SetDB(conn) + code = m.Run() + + if err = dbMain.teardown(); err != nil { + fmt.Println("Unable to execute teardown:", err) + os.Exit(-5) + } + + os.Exit(code) +} + +func initViper() error { + if flagConfigFile != nil && *flagConfigFile != "" { + viper.SetConfigFile(*flagConfigFile) + if err := viper.ReadInConfig(); err != nil { + return err + } + return nil + } + + var err error + + viper.SetConfigName("sqlboiler") + + configHome := os.Getenv("XDG_CONFIG_HOME") + homePath := os.Getenv("HOME") + wd, err := os.Getwd() + if err != nil { + wd = strings.Repeat("../", outputDirDepth) + } else { + wd = wd + strings.Repeat("/..", outputDirDepth) + } + + configPaths := []string{wd} + if len(configHome) > 0 { + configPaths = append(configPaths, filepath.Join(configHome, "sqlboiler")) + } else { + configPaths = append(configPaths, filepath.Join(homePath, ".config/sqlboiler")) + } + + for _, p := range configPaths { + viper.AddConfigPath(p) + } + + // Ignore errors here, fall back to defaults and validation to provide errs + _ = viper.ReadInConfig() + viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_")) + viper.AutomaticEnv() + + return nil +} diff --git a/domain/dbmodel/boil_queries.go b/domain/dbmodel/boil_queries.go new file mode 100644 index 0000000..5428ff0 --- /dev/null +++ b/domain/dbmodel/boil_queries.go @@ -0,0 +1,33 @@ +// Code generated by SQLBoiler 3.7.1 (https://github.com/volatiletech/sqlboiler). DO NOT EDIT. +// This file is meant to be re-generated in place and/or deleted at any time. + +package dbmodel + +import ( + "github.com/volatiletech/sqlboiler/drivers" + "github.com/volatiletech/sqlboiler/queries" + "github.com/volatiletech/sqlboiler/queries/qm" +) + +var dialect = drivers.Dialect{ + LQ: 0x60, + RQ: 0x60, + + UseIndexPlaceholders: false, + UseLastInsertID: true, + UseSchema: false, + UseDefaultKeyword: false, + UseAutoColumns: false, + UseTopClause: false, + UseOutputClause: false, + UseCaseWhenExistsClause: false, +} + +// NewQuery initializes a new Query using the passed in QueryMods +func NewQuery(mods ...qm.QueryMod) *queries.Query { + q := &queries.Query{} + queries.SetDialect(q, &dialect) + qm.Apply(q, mods...) + + return q +} diff --git a/domain/dbmodel/boil_queries_test.go b/domain/dbmodel/boil_queries_test.go new file mode 100644 index 0000000..2404734 --- /dev/null +++ b/domain/dbmodel/boil_queries_test.go @@ -0,0 +1,52 @@ +// Code generated by SQLBoiler 3.7.1 (https://github.com/volatiletech/sqlboiler). DO NOT EDIT. +// This file is meant to be re-generated in place and/or deleted at any time. + +package dbmodel + +import ( + "bytes" + "fmt" + "io" + "io/ioutil" + "math/rand" + "regexp" + + "github.com/volatiletech/sqlboiler/boil" +) + +var dbNameRand *rand.Rand + +func MustTx(transactor boil.ContextTransactor, err error) boil.ContextTransactor { + if err != nil { + panic(fmt.Sprintf("Cannot create a transactor: %s", err)) + } + return transactor +} + +func newFKeyDestroyer(regex *regexp.Regexp, reader io.Reader) io.Reader { + return &fKeyDestroyer{ + reader: reader, + rgx: regex, + } +} + +type fKeyDestroyer struct { + reader io.Reader + buf *bytes.Buffer + rgx *regexp.Regexp +} + +func (f *fKeyDestroyer) Read(b []byte) (int, error) { + if f.buf == nil { + all, err := ioutil.ReadAll(f.reader) + if err != nil { + return 0, err + } + + all = bytes.Replace(all, []byte{'\r', '\n'}, []byte{'\n'}, -1) + all = f.rgx.ReplaceAll(all, []byte{}) + f.buf = bytes.NewBuffer(all) + } + + return f.buf.Read(b) +} diff --git a/domain/dbmodel/boil_suites_test.go b/domain/dbmodel/boil_suites_test.go new file mode 100644 index 0000000..1dd276d --- /dev/null +++ b/domain/dbmodel/boil_suites_test.go @@ -0,0 +1,121 @@ +// Code generated by SQLBoiler 3.7.1 (https://github.com/volatiletech/sqlboiler). DO NOT EDIT. +// This file is meant to be re-generated in place and/or deleted at any time. + +package dbmodel + +import "testing" + +// This test suite runs each operation test in parallel. +// Example, if your database has 3 tables, the suite will run: +// table1, table2 and table3 Delete in parallel +// table1, table2 and table3 Insert in parallel, and so forth. +// It does NOT run each operation group in parallel. +// Separating the tests thusly grants avoidance of Postgres deadlocks. +func TestParent(t *testing.T) { + t.Run("Articles", testArticles) +} + +func TestDelete(t *testing.T) { + t.Run("Articles", testArticlesDelete) +} + +func TestQueryDeleteAll(t *testing.T) { + t.Run("Articles", testArticlesQueryDeleteAll) +} + +func TestSliceDeleteAll(t *testing.T) { + t.Run("Articles", testArticlesSliceDeleteAll) +} + +func TestExists(t *testing.T) { + t.Run("Articles", testArticlesExists) +} + +func TestFind(t *testing.T) { + t.Run("Articles", testArticlesFind) +} + +func TestBind(t *testing.T) { + t.Run("Articles", testArticlesBind) +} + +func TestOne(t *testing.T) { + t.Run("Articles", testArticlesOne) +} + +func TestAll(t *testing.T) { + t.Run("Articles", testArticlesAll) +} + +func TestCount(t *testing.T) { + t.Run("Articles", testArticlesCount) +} + +func TestHooks(t *testing.T) { + t.Run("Articles", testArticlesHooks) +} + +func TestInsert(t *testing.T) { + t.Run("Articles", testArticlesInsert) + t.Run("Articles", testArticlesInsertWhitelist) +} + +// TestToOne tests cannot be run in parallel +// or deadlocks can occur. +func TestToOne(t *testing.T) {} + +// TestOneToOne tests cannot be run in parallel +// or deadlocks can occur. +func TestOneToOne(t *testing.T) {} + +// TestToMany tests cannot be run in parallel +// or deadlocks can occur. +func TestToMany(t *testing.T) {} + +// TestToOneSet tests cannot be run in parallel +// or deadlocks can occur. +func TestToOneSet(t *testing.T) {} + +// TestToOneRemove tests cannot be run in parallel +// or deadlocks can occur. +func TestToOneRemove(t *testing.T) {} + +// TestOneToOneSet tests cannot be run in parallel +// or deadlocks can occur. +func TestOneToOneSet(t *testing.T) {} + +// TestOneToOneRemove tests cannot be run in parallel +// or deadlocks can occur. +func TestOneToOneRemove(t *testing.T) {} + +// TestToManyAdd tests cannot be run in parallel +// or deadlocks can occur. +func TestToManyAdd(t *testing.T) {} + +// TestToManySet tests cannot be run in parallel +// or deadlocks can occur. +func TestToManySet(t *testing.T) {} + +// TestToManyRemove tests cannot be run in parallel +// or deadlocks can occur. +func TestToManyRemove(t *testing.T) {} + +func TestReload(t *testing.T) { + t.Run("Articles", testArticlesReload) +} + +func TestReloadAll(t *testing.T) { + t.Run("Articles", testArticlesReloadAll) +} + +func TestSelect(t *testing.T) { + t.Run("Articles", testArticlesSelect) +} + +func TestUpdate(t *testing.T) { + t.Run("Articles", testArticlesUpdate) +} + +func TestSliceUpdateAll(t *testing.T) { + t.Run("Articles", testArticlesSliceUpdateAll) +} diff --git a/domain/dbmodel/boil_table_names.go b/domain/dbmodel/boil_table_names.go new file mode 100644 index 0000000..765adb5 --- /dev/null +++ b/domain/dbmodel/boil_table_names.go @@ -0,0 +1,10 @@ +// Code generated by SQLBoiler 3.7.1 (https://github.com/volatiletech/sqlboiler). DO NOT EDIT. +// This file is meant to be re-generated in place and/or deleted at any time. + +package dbmodel + +var TableNames = struct { + Articles string +}{ + Articles: "articles", +} diff --git a/domain/dbmodel/boil_types.go b/domain/dbmodel/boil_types.go new file mode 100644 index 0000000..5367a91 --- /dev/null +++ b/domain/dbmodel/boil_types.go @@ -0,0 +1,52 @@ +// Code generated by SQLBoiler 3.7.1 (https://github.com/volatiletech/sqlboiler). DO NOT EDIT. +// This file is meant to be re-generated in place and/or deleted at any time. + +package dbmodel + +import ( + "strconv" + + "github.com/friendsofgo/errors" + "github.com/volatiletech/sqlboiler/boil" + "github.com/volatiletech/sqlboiler/strmangle" +) + +// M type is for providing columns and column values to UpdateAll. +type M map[string]interface{} + +// ErrSyncFail occurs during insert when the record could not be retrieved in +// order to populate default value information. This usually happens when LastInsertId +// fails or there was a primary key configuration that was not resolvable. +var ErrSyncFail = errors.New("dbmodel: failed to synchronize data after insert") + +type insertCache struct { + query string + retQuery string + valueMapping []uint64 + retMapping []uint64 +} + +type updateCache struct { + query string + valueMapping []uint64 +} + +func makeCacheKey(cols boil.Columns, nzDefaults []string) string { + buf := strmangle.GetBuffer() + + buf.WriteString(strconv.Itoa(cols.Kind)) + for _, w := range cols.Cols { + buf.WriteString(w) + } + + if len(nzDefaults) != 0 { + buf.WriteByte('.') + } + for _, nz := range nzDefaults { + buf.WriteString(nz) + } + + str := buf.String() + strmangle.PutBuffer(buf) + return str +} diff --git a/domain/dbmodel/mysql_main_test.go b/domain/dbmodel/mysql_main_test.go new file mode 100644 index 0000000..f5f9566 --- /dev/null +++ b/domain/dbmodel/mysql_main_test.go @@ -0,0 +1,243 @@ +// Code generated by SQLBoiler 3.7.1 (https://github.com/volatiletech/sqlboiler). DO NOT EDIT. +// This file is meant to be re-generated in place and/or deleted at any time. + +package dbmodel + +import ( + "bytes" + "database/sql" + "fmt" + "io" + "io/ioutil" + "os" + "os/exec" + "regexp" + "strings" + + "github.com/friendsofgo/errors" + _ "github.com/go-sql-driver/mysql" + "github.com/kat-co/vala" + "github.com/spf13/viper" + "github.com/volatiletech/sqlboiler/drivers/sqlboiler-mysql/driver" + "github.com/volatiletech/sqlboiler/randomize" +) + +var rgxMySQLkey = regexp.MustCompile(`(?m)((,\n)?\s+CONSTRAINT.*?FOREIGN KEY.*?\n)+`) + +type mysqlTester struct { + dbConn *sql.DB + + dbName string + host string + user string + pass string + sslmode string + port int + + optionFile string + + testDBName string + skipSQLCmd bool +} + +func init() { + dbMain = &mysqlTester{} +} + +func (m *mysqlTester) setup() error { + var err error + + viper.SetDefault("mysql.sslmode", "true") + viper.SetDefault("mysql.port", 3306) + + m.dbName = viper.GetString("mysql.dbname") + m.host = viper.GetString("mysql.host") + m.user = viper.GetString("mysql.user") + m.pass = viper.GetString("mysql.pass") + m.port = viper.GetInt("mysql.port") + m.sslmode = viper.GetString("mysql.sslmode") + m.testDBName = viper.GetString("mysql.testdbname") + m.skipSQLCmd = viper.GetBool("mysql.skipsqlcmd") + + err = vala.BeginValidation().Validate( + vala.StringNotEmpty(m.user, "mysql.user"), + vala.StringNotEmpty(m.host, "mysql.host"), + vala.Not(vala.Equals(m.port, 0, "mysql.port")), + vala.StringNotEmpty(m.dbName, "mysql.dbname"), + vala.StringNotEmpty(m.sslmode, "mysql.sslmode"), + ).Check() + + if err != nil { + return err + } + + // Create a randomized db name. + if len(m.testDBName) == 0 { + m.testDBName = randomize.StableDBName(m.dbName) + } + + if err = m.makeOptionFile(); err != nil { + return errors.Wrap(err, "couldn't make option file") + } + + if !m.skipSQLCmd { + if err = m.dropTestDB(); err != nil { + return err + } + if err = m.createTestDB(); err != nil { + return err + } + + dumpCmd := exec.Command("mysqldump", m.defaultsFile(), "--no-data", m.dbName) + createCmd := exec.Command("mysql", m.defaultsFile(), "--database", m.testDBName) + + r, w := io.Pipe() + dumpCmdStderr := &bytes.Buffer{} + createCmdStderr := &bytes.Buffer{} + + dumpCmd.Stdout = w + dumpCmd.Stderr = dumpCmdStderr + + createCmd.Stdin = newFKeyDestroyer(rgxMySQLkey, r) + createCmd.Stderr = createCmdStderr + + if err = dumpCmd.Start(); err != nil { + return errors.Wrap(err, "failed to start mysqldump command") + } + if err = createCmd.Start(); err != nil { + return errors.Wrap(err, "failed to start mysql command") + } + + if err = dumpCmd.Wait(); err != nil { + fmt.Println(err) + fmt.Println(dumpCmdStderr.String()) + return errors.Wrap(err, "failed to wait for mysqldump command") + } + + _ = w.Close() // After dumpCmd is done, close the write end of the pipe + + if err = createCmd.Wait(); err != nil { + fmt.Println(err) + fmt.Println(createCmdStderr.String()) + return errors.Wrap(err, "failed to wait for mysql command") + } + } + + return nil +} + +func (m *mysqlTester) sslMode(mode string) string { + switch mode { + case "true": + return "REQUIRED" + case "false": + return "DISABLED" + default: + return "PREFERRED" + } +} + +func (m *mysqlTester) defaultsFile() string { + return fmt.Sprintf("--defaults-file=%s", m.optionFile) +} + +func (m *mysqlTester) makeOptionFile() error { + tmp, err := ioutil.TempFile("", "optionfile") + if err != nil { + return errors.Wrap(err, "failed to create option file") + } + + isTCP := false + _, err = os.Stat(m.host) + if os.IsNotExist(err) { + isTCP = true + } else if err != nil { + return errors.Wrap(err, "could not stat m.host") + } + + fmt.Fprintln(tmp, "[client]") + fmt.Fprintf(tmp, "host=%s\n", m.host) + fmt.Fprintf(tmp, "port=%d\n", m.port) + fmt.Fprintf(tmp, "user=%s\n", m.user) + if len(m.pass) != 0 { + fmt.Fprintf(tmp, "password=%s\n", m.pass) + } + fmt.Fprintf(tmp, "ssl-mode=%s\n", m.sslMode(m.sslmode)) + if isTCP { + fmt.Fprintln(tmp, "protocol=tcp") + } + + fmt.Fprintln(tmp, "[mysqldump]") + fmt.Fprintf(tmp, "host=%s\n", m.host) + fmt.Fprintf(tmp, "port=%d\n", m.port) + fmt.Fprintf(tmp, "user=%s\n", m.user) + if len(m.pass) != 0 { + fmt.Fprintf(tmp, "password=%s\n", m.pass) + } + fmt.Fprintf(tmp, "ssl-mode=%s\n", m.sslMode(m.sslmode)) + if isTCP { + fmt.Fprintln(tmp, "protocol=tcp") + } + + m.optionFile = tmp.Name() + + return tmp.Close() +} + +func (m *mysqlTester) createTestDB() error { + sql := fmt.Sprintf("create database %s;", m.testDBName) + return m.runCmd(sql, "mysql") +} + +func (m *mysqlTester) dropTestDB() error { + sql := fmt.Sprintf("drop database if exists %s;", m.testDBName) + return m.runCmd(sql, "mysql") +} + +func (m *mysqlTester) teardown() error { + if m.dbConn != nil { + return m.dbConn.Close() + } + + if !m.skipSQLCmd { + if err := m.dropTestDB(); err != nil { + return err + } + } + + return os.Remove(m.optionFile) +} + +func (m *mysqlTester) runCmd(stdin, command string, args ...string) error { + args = append([]string{m.defaultsFile()}, args...) + + cmd := exec.Command(command, args...) + cmd.Stdin = strings.NewReader(stdin) + + stdout := &bytes.Buffer{} + stderr := &bytes.Buffer{} + cmd.Stdout = stdout + cmd.Stderr = stderr + if err := cmd.Run(); err != nil { + fmt.Println("failed running:", command, args) + fmt.Println(stdout.String()) + fmt.Println(stderr.String()) + return err + } + + return nil +} + +func (m *mysqlTester) conn() (*sql.DB, error) { + if m.dbConn != nil { + return m.dbConn, nil + } + + var err error + m.dbConn, err = sql.Open("mysql", driver.MySQLBuildQueryString(m.user, m.pass, m.testDBName, m.host, m.port, m.sslmode)) + if err != nil { + return nil, err + } + + return m.dbConn, nil +} diff --git a/domain/dbmodel/mysql_suites_test.go b/domain/dbmodel/mysql_suites_test.go new file mode 100644 index 0000000..971ac41 --- /dev/null +++ b/domain/dbmodel/mysql_suites_test.go @@ -0,0 +1,10 @@ +// Code generated by SQLBoiler 3.7.1 (https://github.com/volatiletech/sqlboiler). DO NOT EDIT. +// This file is meant to be re-generated in place and/or deleted at any time. + +package dbmodel + +import "testing" + +func TestUpsert(t *testing.T) { + t.Run("Articles", testArticlesUpsert) +} diff --git a/domain/dbmodel/mysql_upsert.go b/domain/dbmodel/mysql_upsert.go new file mode 100644 index 0000000..6a3c3a1 --- /dev/null +++ b/domain/dbmodel/mysql_upsert.go @@ -0,0 +1,58 @@ +// Code generated by SQLBoiler 3.7.1 (https://github.com/volatiletech/sqlboiler). DO NOT EDIT. +// This file is meant to be re-generated in place and/or deleted at any time. + +package dbmodel + +import ( + "fmt" + "strings" + + "github.com/volatiletech/sqlboiler/drivers" + "github.com/volatiletech/sqlboiler/strmangle" +) + +// buildUpsertQueryMySQL builds a SQL statement string using the upsertData provided. +func buildUpsertQueryMySQL(dia drivers.Dialect, tableName string, update, whitelist []string) string { + whitelist = strmangle.IdentQuoteSlice(dia.LQ, dia.RQ, whitelist) + tableName = strmangle.IdentQuote(dia.LQ, dia.RQ, tableName) + + buf := strmangle.GetBuffer() + defer strmangle.PutBuffer(buf) + + var columns string + if len(whitelist) != 0 { + columns = strings.Join(whitelist, ",") + } + + if len(update) == 0 { + fmt.Fprintf( + buf, + "INSERT IGNORE INTO %s (%s) VALUES (%s)", + tableName, + columns, + strmangle.Placeholders(dia.UseIndexPlaceholders, len(whitelist), 1, 1), + ) + return buf.String() + } + + fmt.Fprintf( + buf, + "INSERT INTO %s (%s) VALUES (%s) ON DUPLICATE KEY UPDATE ", + tableName, + columns, + strmangle.Placeholders(dia.UseIndexPlaceholders, len(whitelist), 1, 1), + ) + + for i, v := range update { + if i != 0 { + buf.WriteByte(',') + } + quoted := strmangle.IdentQuote(dia.LQ, dia.RQ, v) + buf.WriteString(quoted) + buf.WriteString(" = VALUES(") + buf.WriteString(quoted) + buf.WriteByte(')') + } + + return buf.String() +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..6318e03 --- /dev/null +++ b/go.mod @@ -0,0 +1,22 @@ +module github.com/hiroyky/nikki_backend + +go 1.14 + +require ( + github.com/friendsofgo/errors v0.9.2 // indirect + github.com/fsnotify/fsnotify v1.4.9 // indirect + github.com/go-sql-driver/mysql v1.5.0 // indirect + github.com/mitchellh/mapstructure v1.3.1 // indirect + github.com/pelletier/go-toml v1.8.0 // indirect + github.com/spf13/afero v1.2.2 // indirect + github.com/spf13/cast v1.3.1 // indirect + github.com/spf13/cobra v1.0.0 // indirect + github.com/spf13/jwalterweatherman v1.1.0 // indirect + github.com/spf13/pflag v1.0.5 // indirect + github.com/spf13/viper v1.7.0 // indirect + github.com/volatiletech/inflect v0.0.1 // indirect + github.com/volatiletech/sqlboiler v3.7.1+incompatible // indirect + golang.org/x/sys v0.0.0-20200523222454-059865788121 // indirect + golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 // indirect + gopkg.in/ini.v1 v1.57.0 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..d5c8c1e --- /dev/null +++ b/go.sum @@ -0,0 +1,341 @@ +cloud.google.com/go v0.26.0/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.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= +cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= +cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= +cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= +github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= +github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= +github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= +github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= +github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/friendsofgo/errors v0.9.2 h1:X6NYxef4efCBdwI7BgS820zFaN7Cphrmb+Pljdzjtgk= +github.com/friendsofgo/errors v0.9.2/go.mod h1:yCvFW5AkDIL9qn7suHVLiI/gH228n7PC4Pn44IGoTOI= +github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs= +github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= +github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= +github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= +github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= +github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= +github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= +github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= +github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= +github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= +github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +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/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4= +github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= +github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= +github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= +github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.3.1 h1:cCBH2gTD2K0OtLlv/Y5H01VQCqmlDxz30kS5Y5bqfLA= +github.com/mitchellh/mapstructure v1.3.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= +github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc= +github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/pelletier/go-toml v1.8.0 h1:Keo9qb7iRJs2voHvunFtuuYFsbWeOBh8/P9v/kVMFtw= +github.com/pelletier/go-toml v1.8.0/go.mod h1:D6yutnOGMveHEPV7VQOuvI/gXY61bv+9bAOTRnLElKs= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= +github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI= +github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc= +github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= +github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng= +github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cobra v1.0.0 h1:6m/oheQuQ13N9ks4hubMG6BnvwOeaJrqSPLahSnczz8= +github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= +github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk= +github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= +github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= +github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= +github.com/spf13/viper v1.7.0 h1:xVKxvI7ouOI5I+U9s2eeiUfMaWBVoXA3AWskkrqK0VM= +github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= +github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= +github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= +github.com/volatiletech/inflect v0.0.1 h1:2a6FcMQyhmPZcLa+uet3VJ8gLn/9svWhJxJYwvE8KsU= +github.com/volatiletech/inflect v0.0.1/go.mod h1:IBti31tG6phkHitLlr5j7shC5SOo//x0AjDzaJU1PLA= +github.com/volatiletech/sqlboiler v1.0.0 h1:p0aCjD4tyDfjDjL6jakkfnrWWC4Z2wd1SNM7sS3rzAQ= +github.com/volatiletech/sqlboiler v3.7.1+incompatible h1:dm9/NjDskQVwAarmpeZ2UqLn1NKE8M3WHSHBS4jw2x8= +github.com/volatiletech/sqlboiler v3.7.1+incompatible/go.mod h1:jLfDkkHWPbS2cWRLkyC20vQWaIQsASEY7gM7zSo11Yw= +github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= +github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/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-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0 h1:HyfiK1WMnHj5FXFXatD+Qs1A/xC2Run6RzeW1SyHxpc= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200523222454-059865788121 h1:rITEj+UZHYC927n8GT97eC3zrpzXdb/voyeOuVKS46o= +golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7 h1:9zdDQZ7Thm29KFXgAX/+yaf3eVbP7djjWp/dXAppNCc= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= +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= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/ini.v1 v1.51.0 h1:AQvPpx3LzTDM0AjnIRlVFwFFGC+npRopjZxLJj6gdno= +gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/ini.v1 v1.57.0 h1:9unxIsFcTt4I55uWluz+UmL95q4kdJ0buvQ1ZIqVQww= +gopkg.in/ini.v1 v1.57.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= +gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= diff --git a/sqlboiler.toml b/sqlboiler.toml new file mode 100644 index 0000000..33ac2ac --- /dev/null +++ b/sqlboiler.toml @@ -0,0 +1,13 @@ +pkgname="dbmodel" +output="domain/dbmodel" +add-global-variants=true + +[mysql] +dbname = "nikki_db" +host = "127.0.0.1" +port = 3306 +user = "root" +pass = "password" +blacklist = [] +whitelist = [] +sslmode = "false"