diff options
Diffstat (limited to 'src/models/posts.go')
| -rw-r--r-- | src/models/posts.go | 518 |
1 files changed, 507 insertions, 11 deletions
diff --git a/src/models/posts.go b/src/models/posts.go index d644268..7fb455c 100644 --- a/src/models/posts.go +++ b/src/models/posts.go @@ -26,8 +26,9 @@ import ( type Post struct { ID int `boil:"id" json:"id" toml:"id" yaml:"id"` Title string `boil:"title" json:"title" toml:"title" yaml:"title"` + Description null.String `boil:"description" json:"description,omitempty" toml:"description" yaml:"description,omitempty"` URL null.String `boil:"url" json:"url,omitempty" toml:"url" yaml:"url,omitempty"` - Description string `boil:"description" json:"description" toml:"description" yaml:"description"` + UserID int `boil:"user_id" json:"user_id" toml:"user_id" yaml:"user_id"` 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"` @@ -38,15 +39,17 @@ type Post struct { var PostColumns = struct { ID string Title string - URL string Description string + URL string + UserID string CreatedAt string UpdatedAt string }{ ID: "id", Title: "title", - URL: "url", Description: "description", + URL: "url", + UserID: "user_id", CreatedAt: "created_at", UpdatedAt: "updated_at", } @@ -54,15 +57,17 @@ var PostColumns = struct { var PostTableColumns = struct { ID string Title string - URL string Description string + URL string + UserID string CreatedAt string UpdatedAt string }{ ID: "posts.id", Title: "posts.title", - URL: "posts.url", Description: "posts.description", + URL: "posts.url", + UserID: "posts.user_id", CreatedAt: "posts.created_at", UpdatedAt: "posts.updated_at", } @@ -193,25 +198,34 @@ func (w whereHelpertime_Time) GTE(x time.Time) qm.QueryMod { var PostWhere = struct { ID whereHelperint Title whereHelperstring + Description whereHelpernull_String URL whereHelpernull_String - Description whereHelperstring + UserID whereHelperint CreatedAt whereHelpertime_Time UpdatedAt whereHelpertime_Time }{ ID: whereHelperint{field: "\"posts\".\"id\""}, Title: whereHelperstring{field: "\"posts\".\"title\""}, + Description: whereHelpernull_String{field: "\"posts\".\"description\""}, URL: whereHelpernull_String{field: "\"posts\".\"url\""}, - Description: whereHelperstring{field: "\"posts\".\"description\""}, + UserID: whereHelperint{field: "\"posts\".\"user_id\""}, CreatedAt: whereHelpertime_Time{field: "\"posts\".\"created_at\""}, UpdatedAt: whereHelpertime_Time{field: "\"posts\".\"updated_at\""}, } // PostRels is where relationship names are stored. var PostRels = struct { -}{} + User string + Tags string +}{ + User: "User", + Tags: "Tags", +} // postR is where relationships are stored. type postR struct { + User *User `boil:"User" json:"User" toml:"User" yaml:"User"` + Tags TagSlice `boil:"Tags" json:"Tags" toml:"Tags" yaml:"Tags"` } // NewStruct creates a new relationship struct @@ -219,13 +233,27 @@ func (*postR) NewStruct() *postR { return &postR{} } +func (r *postR) GetUser() *User { + if r == nil { + return nil + } + return r.User +} + +func (r *postR) GetTags() TagSlice { + if r == nil { + return nil + } + return r.Tags +} + // postL is where Load methods for each relationship are stored. type postL struct{} var ( - postAllColumns = []string{"id", "title", "url", "description", "created_at", "updated_at"} - postColumnsWithoutDefault = []string{"title", "description"} - postColumnsWithDefault = []string{"id", "url", "created_at", "updated_at"} + postAllColumns = []string{"id", "title", "description", "url", "user_id", "created_at", "updated_at"} + postColumnsWithoutDefault = []string{"title", "user_id"} + postColumnsWithDefault = []string{"id", "description", "url", "created_at", "updated_at"} postPrimaryKeyColumns = []string{"id"} postGeneratedColumns = []string{} ) @@ -535,6 +563,474 @@ func (q postQuery) Exists(ctx context.Context, exec boil.ContextExecutor) (bool, return count > 0, nil } +// User pointed to by the foreign key. +func (o *Post) User(mods ...qm.QueryMod) userQuery { + queryMods := []qm.QueryMod{ + qm.Where("\"id\" = ?", o.UserID), + } + + queryMods = append(queryMods, mods...) + + return Users(queryMods...) +} + +// Tags retrieves all the tag's Tags with an executor. +func (o *Post) Tags(mods ...qm.QueryMod) tagQuery { + var queryMods []qm.QueryMod + if len(mods) != 0 { + queryMods = append(queryMods, mods...) + } + + queryMods = append(queryMods, + qm.InnerJoin("\"post_tags\" on \"tags\".\"id\" = \"post_tags\".\"tag_id\""), + qm.Where("\"post_tags\".\"post_id\"=?", o.ID), + ) + + return Tags(queryMods...) +} + +// LoadUser allows an eager lookup of values, cached into the +// loaded structs of the objects. This is for an N-1 relationship. +func (postL) LoadUser(ctx context.Context, e boil.ContextExecutor, singular bool, maybePost interface{}, mods queries.Applicator) error { + var slice []*Post + var object *Post + + if singular { + var ok bool + object, ok = maybePost.(*Post) + if !ok { + object = new(Post) + ok = queries.SetFromEmbeddedStruct(&object, &maybePost) + if !ok { + return errors.New(fmt.Sprintf("failed to set %T from embedded struct %T", object, maybePost)) + } + } + } else { + s, ok := maybePost.(*[]*Post) + if ok { + slice = *s + } else { + ok = queries.SetFromEmbeddedStruct(&slice, maybePost) + if !ok { + return errors.New(fmt.Sprintf("failed to set %T from embedded struct %T", slice, maybePost)) + } + } + } + + args := make(map[interface{}]struct{}) + if singular { + if object.R == nil { + object.R = &postR{} + } + args[object.UserID] = struct{}{} + + } else { + for _, obj := range slice { + if obj.R == nil { + obj.R = &postR{} + } + + args[obj.UserID] = struct{}{} + + } + } + + if len(args) == 0 { + return nil + } + + argsSlice := make([]interface{}, len(args)) + i := 0 + for arg := range args { + argsSlice[i] = arg + i++ + } + + query := NewQuery( + qm.From(`users`), + qm.WhereIn(`users.id in ?`, argsSlice...), + ) + if mods != nil { + mods.Apply(query) + } + + results, err := query.QueryContext(ctx, e) + if err != nil { + return errors.Wrap(err, "failed to eager load User") + } + + var resultSlice []*User + if err = queries.Bind(results, &resultSlice); err != nil { + return errors.Wrap(err, "failed to bind eager loaded slice User") + } + + if err = results.Close(); err != nil { + return errors.Wrap(err, "failed to close results of eager load for users") + } + if err = results.Err(); err != nil { + return errors.Wrap(err, "error occurred during iteration of eager loaded relations for users") + } + + if len(userAfterSelectHooks) != 0 { + for _, obj := range resultSlice { + if err := obj.doAfterSelectHooks(ctx, e); err != nil { + return err + } + } + } + + if len(resultSlice) == 0 { + return nil + } + + if singular { + foreign := resultSlice[0] + object.R.User = foreign + if foreign.R == nil { + foreign.R = &userR{} + } + foreign.R.Posts = append(foreign.R.Posts, object) + return nil + } + + for _, local := range slice { + for _, foreign := range resultSlice { + if local.UserID == foreign.ID { + local.R.User = foreign + if foreign.R == nil { + foreign.R = &userR{} + } + foreign.R.Posts = append(foreign.R.Posts, local) + break + } + } + } + + return nil +} + +// LoadTags allows an eager lookup of values, cached into the +// loaded structs of the objects. This is for a 1-M or N-M relationship. +func (postL) LoadTags(ctx context.Context, e boil.ContextExecutor, singular bool, maybePost interface{}, mods queries.Applicator) error { + var slice []*Post + var object *Post + + if singular { + var ok bool + object, ok = maybePost.(*Post) + if !ok { + object = new(Post) + ok = queries.SetFromEmbeddedStruct(&object, &maybePost) + if !ok { + return errors.New(fmt.Sprintf("failed to set %T from embedded struct %T", object, maybePost)) + } + } + } else { + s, ok := maybePost.(*[]*Post) + if ok { + slice = *s + } else { + ok = queries.SetFromEmbeddedStruct(&slice, maybePost) + if !ok { + return errors.New(fmt.Sprintf("failed to set %T from embedded struct %T", slice, maybePost)) + } + } + } + + args := make(map[interface{}]struct{}) + if singular { + if object.R == nil { + object.R = &postR{} + } + args[object.ID] = struct{}{} + } else { + for _, obj := range slice { + if obj.R == nil { + obj.R = &postR{} + } + args[obj.ID] = struct{}{} + } + } + + if len(args) == 0 { + return nil + } + + argsSlice := make([]interface{}, len(args)) + i := 0 + for arg := range args { + argsSlice[i] = arg + i++ + } + + query := NewQuery( + qm.Select("\"tags\".\"id\", \"tags\".\"tag\", \"tags\".\"description\", \"tags\".\"user_id\", \"tags\".\"created_at\", \"tags\".\"updated_at\", \"a\".\"post_id\""), + qm.From("\"tags\""), + qm.InnerJoin("\"post_tags\" as \"a\" on \"tags\".\"id\" = \"a\".\"tag_id\""), + qm.WhereIn("\"a\".\"post_id\" in ?", argsSlice...), + ) + if mods != nil { + mods.Apply(query) + } + + results, err := query.QueryContext(ctx, e) + if err != nil { + return errors.Wrap(err, "failed to eager load tags") + } + + var resultSlice []*Tag + + var localJoinCols []int + for results.Next() { + one := new(Tag) + var localJoinCol int + + err = results.Scan(&one.ID, &one.Tag, &one.Description, &one.UserID, &one.CreatedAt, &one.UpdatedAt, &localJoinCol) + if err != nil { + return errors.Wrap(err, "failed to scan eager loaded results for tags") + } + if err = results.Err(); err != nil { + return errors.Wrap(err, "failed to plebian-bind eager loaded slice tags") + } + + resultSlice = append(resultSlice, one) + localJoinCols = append(localJoinCols, localJoinCol) + } + + if err = results.Close(); err != nil { + return errors.Wrap(err, "failed to close results in eager load on tags") + } + if err = results.Err(); err != nil { + return errors.Wrap(err, "error occurred during iteration of eager loaded relations for tags") + } + + if len(tagAfterSelectHooks) != 0 { + for _, obj := range resultSlice { + if err := obj.doAfterSelectHooks(ctx, e); err != nil { + return err + } + } + } + if singular { + object.R.Tags = resultSlice + for _, foreign := range resultSlice { + if foreign.R == nil { + foreign.R = &tagR{} + } + foreign.R.Posts = append(foreign.R.Posts, object) + } + return nil + } + + for i, foreign := range resultSlice { + localJoinCol := localJoinCols[i] + for _, local := range slice { + if local.ID == localJoinCol { + local.R.Tags = append(local.R.Tags, foreign) + if foreign.R == nil { + foreign.R = &tagR{} + } + foreign.R.Posts = append(foreign.R.Posts, local) + break + } + } + } + + return nil +} + +// SetUser of the post to the related item. +// Sets o.R.User to related. +// Adds o to related.R.Posts. +func (o *Post) SetUser(ctx context.Context, exec boil.ContextExecutor, insert bool, related *User) error { + var err error + if insert { + if err = related.Insert(ctx, exec, boil.Infer()); err != nil { + return errors.Wrap(err, "failed to insert into foreign table") + } + } + + updateQuery := fmt.Sprintf( + "UPDATE \"posts\" SET %s WHERE %s", + strmangle.SetParamNames("\"", "\"", 1, []string{"user_id"}), + strmangle.WhereClause("\"", "\"", 2, postPrimaryKeyColumns), + ) + values := []interface{}{related.ID, o.ID} + + if boil.IsDebug(ctx) { + writer := boil.DebugWriterFrom(ctx) + fmt.Fprintln(writer, updateQuery) + fmt.Fprintln(writer, values) + } + if _, err = exec.ExecContext(ctx, updateQuery, values...); err != nil { + return errors.Wrap(err, "failed to update local table") + } + + o.UserID = related.ID + if o.R == nil { + o.R = &postR{ + User: related, + } + } else { + o.R.User = related + } + + if related.R == nil { + related.R = &userR{ + Posts: PostSlice{o}, + } + } else { + related.R.Posts = append(related.R.Posts, o) + } + + return nil +} + +// AddTags adds the given related objects to the existing relationships +// of the post, optionally inserting them as new records. +// Appends related to o.R.Tags. +// Sets related.R.Posts appropriately. +func (o *Post) AddTags(ctx context.Context, exec boil.ContextExecutor, insert bool, related ...*Tag) error { + var err error + for _, rel := range related { + if insert { + if err = rel.Insert(ctx, exec, boil.Infer()); err != nil { + return errors.Wrap(err, "failed to insert into foreign table") + } + } + } + + for _, rel := range related { + query := "insert into \"post_tags\" (\"post_id\", \"tag_id\") values ($1, $2)" + values := []interface{}{o.ID, rel.ID} + + if boil.IsDebug(ctx) { + writer := boil.DebugWriterFrom(ctx) + fmt.Fprintln(writer, query) + fmt.Fprintln(writer, values) + } + _, err = exec.ExecContext(ctx, query, values...) + if err != nil { + return errors.Wrap(err, "failed to insert into join table") + } + } + if o.R == nil { + o.R = &postR{ + Tags: related, + } + } else { + o.R.Tags = append(o.R.Tags, related...) + } + + for _, rel := range related { + if rel.R == nil { + rel.R = &tagR{ + Posts: PostSlice{o}, + } + } else { + rel.R.Posts = append(rel.R.Posts, o) + } + } + return nil +} + +// SetTags removes all previously related items of the +// post replacing them completely with the passed +// in related items, optionally inserting them as new records. +// Sets o.R.Posts's Tags accordingly. +// Replaces o.R.Tags with related. +// Sets related.R.Posts's Tags accordingly. +func (o *Post) SetTags(ctx context.Context, exec boil.ContextExecutor, insert bool, related ...*Tag) error { + query := "delete from \"post_tags\" where \"post_id\" = $1" + values := []interface{}{o.ID} + if boil.IsDebug(ctx) { + writer := boil.DebugWriterFrom(ctx) + fmt.Fprintln(writer, query) + fmt.Fprintln(writer, values) + } + _, err := exec.ExecContext(ctx, query, values...) + if err != nil { + return errors.Wrap(err, "failed to remove relationships before set") + } + + removeTagsFromPostsSlice(o, related) + if o.R != nil { + o.R.Tags = nil + } + + return o.AddTags(ctx, exec, insert, related...) +} + +// RemoveTags relationships from objects passed in. +// Removes related items from R.Tags (uses pointer comparison, removal does not keep order) +// Sets related.R.Posts. +func (o *Post) RemoveTags(ctx context.Context, exec boil.ContextExecutor, related ...*Tag) error { + if len(related) == 0 { + return nil + } + + var err error + query := fmt.Sprintf( + "delete from \"post_tags\" where \"post_id\" = $1 and \"tag_id\" in (%s)", + strmangle.Placeholders(dialect.UseIndexPlaceholders, len(related), 2, 1), + ) + values := []interface{}{o.ID} + for _, rel := range related { + values = append(values, rel.ID) + } + + if boil.IsDebug(ctx) { + writer := boil.DebugWriterFrom(ctx) + fmt.Fprintln(writer, query) + fmt.Fprintln(writer, values) + } + _, err = exec.ExecContext(ctx, query, values...) + if err != nil { + return errors.Wrap(err, "failed to remove relationships before set") + } + removeTagsFromPostsSlice(o, related) + if o.R == nil { + return nil + } + + for _, rel := range related { + for i, ri := range o.R.Tags { + if rel != ri { + continue + } + + ln := len(o.R.Tags) + if ln > 1 && i < ln-1 { + o.R.Tags[i] = o.R.Tags[ln-1] + } + o.R.Tags = o.R.Tags[:ln-1] + break + } + } + + return nil +} + +func removeTagsFromPostsSlice(o *Post, related []*Tag) { + for _, rel := range related { + if rel.R == nil { + continue + } + for i, ri := range rel.R.Posts { + if o.ID != ri.ID { + continue + } + + ln := len(rel.R.Posts) + if ln > 1 && i < ln-1 { + rel.R.Posts[i] = rel.R.Posts[ln-1] + } + rel.R.Posts = rel.R.Posts[:ln-1] + break + } + } +} + // Posts retrieves all the records using an executor. func Posts(mods ...qm.QueryMod) postQuery { mods = append(mods, qm.From("\"posts\"")) |
