Documentation ¶
Index ¶
- type ArticleAdjustFavoritesCountDafT
- type ArticleCreateDafT
- type ArticleDeleteDafT
- type ArticleGetBySlugDafT
- type ArticleUpdateDafT
- type ArticlesFeedDafT
- type ArticlesListDafT
- type CommentCreateDafT
- type CommentDeleteDafT
- type CommentsGetBySlugDafT
- type FavoriteCreateDafT
- type FavoriteDeleteDafT
- type FollowingCreateDafT
- type FollowingDeleteDafT
- type FollowingGetDafT
- type PwUser
- type RecCtxUser
- type TagAddToArticleDafT
- type TagCreateDafT
- type TagsAddNewDafT
- type TagsAddToArticleDafT
- type TagsGetAllDafT
- type UserCreateDafT
- type UserCreateExplicitTxDafT
- type UserGetByEmailDafT
- type UserGetByNameDafT
- type UserGetByNameExplicitTxDafT
- type UserUpdateDafT
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type ArticleAdjustFavoritesCountDafT ¶
type ArticleAdjustFavoritesCountDafT = func( ctx context.Context, tx pgx.Tx, slug string, delta int, ) (int, time.Time, error)
ArticleAdjustFavoritesCountDafT is the type of the stereotype instance for the DAF that increments the favorites count of an article.
var ArticleAdjustFavoritesCountDaf ArticleAdjustFavoritesCountDafT = func( ctx context.Context, tx pgx.Tx, slug string, delta int, ) (int, time.Time, error) { sql := ` UPDATE articles SET favorites_count = favorites_count + $2, updated_at = clock_timestamp() WHERE slug = $1 RETURNING favorites_count, updated_at ` args := []any{ slug, delta, } var favoritesCount int var updatedAt time.Time row := tx.QueryRow(ctx, sql, args...) if err := row.Scan(&favoritesCount, &updatedAt); err != nil { if err == pgx.ErrNoRows { err = dbpgx.DbErrRecordNotFound.Make(nil, bf.ErrMsgArticleSlugNotFound, slug) } return 0, time.Time{}, dbpgx.ClassifyError(err).Make(err, "") } return favoritesCount, updatedAt, nil }
ArticleAdjustFavoritesCountDaf implements a stereotype instance of type ArticleAdjustFavoritesCountDafT.
type ArticleCreateDafT ¶
ArticleCreateDafT is the type of the stereotype instance for the DAF that creates an article.
var ArticleCreateDaf ArticleCreateDafT = func( ctx context.Context, tx pgx.Tx, article *model.Article, ) error { sql := ` INSERT INTO articles (author_id, title, slug, description, body, favorites_count) VALUES ($1, $2, $3, $4, $5, $6) RETURNING id, created_at, updated_at ` args := []any{ article.AuthorId, article.Title, article.Slug, article.Description, article.Body, article.FavoritesCount, } row := tx.QueryRow(ctx, sql, args...) err := row.Scan(&article.Id, &article.CreatedAt, &article.UpdatedAt) if kind := dbpgx.ClassifyError(err); kind != nil { if kind == dbpgx.DbErrUniqueViolation { return kind.Make(err, bf.ErrMsgDuplicateArticleSlug, article.Slug) } return kind.Make(err, "") } return nil }
ArticleCreateDaf implements a stereotype instance of type ArticleCreateDafT.
type ArticleDeleteDafT ¶
ArticleDeleteDafT is the type of the stereotype instance for the DAF that deletes an article.
var ArticleDeleteDaf ArticleDeleteDafT = func( ctx context.Context, tx pgx.Tx, slug string, ) error { sql := ` DELETE FROM articles WHERE slug = $1 ` c, err := tx.Exec(ctx, sql, slug) if kind := dbpgx.ClassifyError(err); kind != nil { return kind.Make(err, "") } if c.RowsAffected() == 0 { return dbpgx.DbErrRecordNotFound.Make(nil, bf.ErrMsgArticleSlugNotFound, slug) } return nil }
ArticleDeleteDaf implements a stereotype instance of type ArticleDeleteDafT.
type ArticleGetBySlugDafT ¶
type ArticleGetBySlugDafT = func(ctx context.Context, tx pgx.Tx, currUserId uint, slug string) (model.ArticlePlus, error)
ArticleGetBySlugDafT is the type of the stereotype instance for the DAF that retrieves an article by slug.
var ArticleGetBySlugDaf ArticleGetBySlugDafT = func( ctx context.Context, tx pgx.Tx, currUserId uint, slug string, ) (model.ArticlePlus, error) { whereTuples := []types.Tuple2[string, any]{ {"a.slug = $%d", slug}, } where, whereArgs := whereClauseFromTuples(2, whereTuples) results, err := readArticles(ctx, tx, currUserId, where, nil, nil, whereArgs...) if err != nil { return model.ArticlePlus{}, err } if len(results) == 0 { return model.ArticlePlus{}, dbpgx.DbErrRecordNotFound.Make(nil, bf.ErrMsgArticleSlugNotFound, slug) } if len(results) > 1 { return model.ArticlePlus{}, dbpgx.DbErrUnexpectedMultipleRecords.Make(nil, "Found multiple articles with same slug '%v'", slug) } return results[0], nil }
ArticleGetBySlugDaf implements a stereotype instance of type ArticleGetBySlugDafT.
type ArticleUpdateDafT ¶
ArticleUpdateDafT is the type of the stereotype instance for the DAF that updates an article.
var ArticleUpdateDaf ArticleUpdateDafT = func( ctx context.Context, tx pgx.Tx, article *model.Article, ) error { sql := ` UPDATE articles SET title = $1, description = $2, body = $3, updated_at = clock_timestamp() WHERE slug = $4 AND updated_at = $5 RETURNING updated_at ` args := []any{ article.Title, article.Description, article.Body, article.Slug, article.UpdatedAt, } row := tx.QueryRow(ctx, sql, args...) if err := row.Scan(&article.UpdatedAt); err != nil { if err == pgx.ErrNoRows { err = dbpgx.DbErrRecordNotFound.Make(nil, bf.ErrMsgArticleSlugNotFound, article.Slug) } return dbpgx.ClassifyError(err).Make(err, "") } return nil }
ArticleUpdateDaf implements a stereotype instance of type ArticleUpdateDafT.
type ArticlesFeedDafT ¶
type ArticlesFeedDafT = func(ctx context.Context, tx pgx.Tx, currUserId uint, optLimit *int, optOffset *int) ([]model.ArticlePlus, error)
ArticlesFeedDafT is the type of the stereotype instance for the DAF that queries for all articles authored by other users followed by the current user, with optional limit and offset pagination parameters.
var ArticlesFeedDaf ArticlesFeedDafT = func( ctx context.Context, tx pgx.Tx, currUserId uint, optLimit *int, optOffset *int, ) ([]model.ArticlePlus, error) { whereTuples := []types.Tuple2[string, any]{ {"fo.follower_id = $%d", currUserId}, } where, whereArgs := whereClauseFromTuples(2, whereTuples) results, err := readArticles(ctx, tx, currUserId, where, optLimit, optOffset, whereArgs...) if err != nil { return nil, err } return results, nil }
ArticlesFeedDaf implements a stereotype instance of type ArticlesFeedDafT.
type ArticlesListDafT ¶
type ArticlesListDafT = func(ctx context.Context, tx pgx.Tx, currUserId uint, criteria rpc.ArticleCriteria) ([]model.ArticlePlus, error)
ArticlesListDafT is the type of the stereotype instance for the DAF that retrieve recent articles based on a set of query parameters.
var ArticlesListDaf ArticlesListDafT = func( ctx context.Context, tx pgx.Tx, currUserId uint, criteria rpc.ArticleCriteria, ) ([]model.ArticlePlus, error) { // See mainArticlePlusQuery var join string var joinArgs []any if v := criteria.FavoritedBy; v != nil { join = join + ` LEFT JOIN favorites fa1 ON a.id = fa1.article_id -- at most one due to below LEFT JOIN users ufa1 ON ufa1.id = fa1.user_id -- AND ufa1.username = $2 ` } if v := criteria.Tag; v != nil { join = join + ` LEFT JOIN article_tags at1 ON at1.article_id = a.id LEFT JOIN tags t1 ON t1.id = at1.tag_id -- AND t1.name = $2 ` } var whereTuples []types.Tuple2[string, any] if v := criteria.FavoritedBy; v != nil { whereTuples = append(whereTuples, types.Tuple2[string, any]{"ufa1.username = $%d", *v}) } if v := criteria.Tag; v != nil { whereTuples = append(whereTuples, types.Tuple2[string, any]{"t1.name = $%d", *v}) } if v := criteria.Author; v != nil { whereTuples = append(whereTuples, types.Tuple2[string, any]{"ua.username = $%d", *v}) } initialIndex := 2 + len(joinArgs) where, whereArgs := whereClauseFromTuples(initialIndex, whereTuples) additionalSql := join + where additionalArgs := append(joinArgs, whereArgs...) results, err := readArticles(ctx, tx, currUserId, additionalSql, criteria.Limit, criteria.Offset, additionalArgs...) if err != nil { return nil, err } return results, nil }
ArticlesListDaf implements a stereotype instance of type ArticlesListDafT.
type CommentCreateDafT ¶
CommentCreateDafT is the type of the stereotype instance for the DAF that creates a comment for an article.
var CommentCreateDaf CommentCreateDafT = func( ctx context.Context, tx pgx.Tx, comment *model.Comment, ) error { sql := ` INSERT INTO comments (article_id, author_id, body) VALUES ($1, $2, $3) RETURNING id, created_at ` args := []any{ comment.ArticleId, comment.AuthorId, comment.Body, } row := tx.QueryRow(ctx, sql, args...) err := row.Scan(&comment.Id, &comment.CreatedAt) if kind := dbpgx.ClassifyError(err); kind != nil { return kind.Make(err, "") } return nil }
CommentCreateDaf implements a stereotype instance of type CommentCreateDafT.
type CommentDeleteDafT ¶
type CommentDeleteDafT = func( ctx context.Context, tx pgx.Tx, commentId uint, articleId uint, authorId uint, ) error
CommentDeleteDafT is the type of the stereotype instance for the DAF that deletes a comment.
var CommentDeleteDaf CommentDeleteDafT = func( ctx context.Context, tx pgx.Tx, commentId uint, articleId uint, authorId uint, ) error { sql := ` DELETE FROM comments WHERE id = $1 AND article_id = $2 AND author_id = $3 ` args := []any{ commentId, articleId, authorId, } c, err := tx.Exec(ctx, sql, args...) if kind := dbpgx.ClassifyError(err); kind != nil { return kind.Make(err, "") } if c.RowsAffected() == 0 { return dbpgx.DbErrRecordNotFound.Make(nil, bf.ErrMsgCommentNotFound) } return nil }
CommentDeleteDaf implements a stereotype instance of type CommentDeleteDafT.
type CommentsGetBySlugDafT ¶
type CommentsGetBySlugDafT = func(ctx context.Context, tx pgx.Tx, slug string) ([]model.Comment, error)
CommentsGetBySlugDafT is the type of the stereotype instance for the DAF that retrieves all comments for the article with a given slug.
var CommentsGetBySlugDaf CommentsGetBySlugDafT = func( ctx context.Context, tx pgx.Tx, slug string, ) ([]model.Comment, error) { sql := ` SELECT c.* FROM comments c LEFT JOIN articles a ON c.article_id = a.id WHERE a.slug = $1 ` args := []any{slug} comments, err := dbpgx.ReadMany[model.Comment](ctx, tx, sql, -1, -1, args...) return comments, err }
CommentsGetBySlugDaf implements a stereotype instance of type CommentGetBySlugDafT.
type FavoriteCreateDafT ¶
FavoriteCreateDafT is the instance of the DAF stereotype that associates an article with a user that favors it.
var FavoriteCreateDaf FavoriteCreateDafT = func( ctx context.Context, tx pgx.Tx, articleId uint, userId uint, ) error { sql := ` INSERT INTO favorites (article_id, user_id) VALUES ($1, $2) ` args := []any{articleId, userId} _, err := tx.Exec(ctx, sql, args...) if kind := dbpgx.ClassifyError(err); kind != nil { if kind == dbpgx.DbErrUniqueViolation { return kind.Make(err, bf.ErrMsgArticleAlreadyFavorited, articleId) } return kind.Make(err, "") } return nil }
FavoriteCreateDaf is the instance of the DAF stereotype that associates an article with a user that favors it.
type FavoriteDeleteDafT ¶
FavoriteDeleteDafT is the instance of the DAF stereotype that disaassociates an article from a user that favors it. Returns the number of rows affected, which can be 0 or 1.
var FavoriteDeleteDaf FavoriteDeleteDafT = func( ctx context.Context, tx pgx.Tx, articleId uint, userId uint, ) error { sql := ` DELETE FROM favorites WHERE article_id = $1 AND user_id = $2 ` args := []any{articleId, userId} c, err := tx.Exec(ctx, sql, args...) if kind := dbpgx.ClassifyError(err); kind != nil { return kind.Make(err, "") } if c.RowsAffected() == 0 { return dbpgx.DbErrRecordNotFound.Make(nil, bf.ErrMsgArticleWasNotFavorited, articleId) } return nil }
FavoriteDeleteDaf is the instance of the DAF stereotype that disaassociates an article from a user that favors it.
type FollowingCreateDafT ¶
type FollowingCreateDafT = func( ctx context.Context, tx pgx.Tx, followerId uint, followeeId uint, ) (time.Time, error)
FollowingCreateDafT is the type of the stereotype instance for the DAF that associates a follower with a followee.
var FollowingCreateDaf FollowingCreateDafT = func( ctx context.Context, tx pgx.Tx, followerId uint, followeeId uint, ) (time.Time, error) { sql := ` INSERT INTO followings (follower_id, followee_id) VALUES ($1, $2) RETURNING followed_on ` args := []any{followerId, followeeId} var followedOn time.Time row := tx.QueryRow(ctx, sql, args...) err := row.Scan(&followedOn) if kind := dbpgx.ClassifyError(err); kind != nil { if kind == dbpgx.DbErrUniqueViolation { return time.Time{}, kind.Make(err, bf.ErrMsgUserAlreadyFollowed, followeeId) } return time.Time{}, kind.Make(err, "") } return followedOn, nil }
FollowingCreateDaf is the instance of the DAF stereotype that associates a follower with a followee.
type FollowingDeleteDafT ¶
type FollowingDeleteDafT = func( ctx context.Context, tx pgx.Tx, followerId uint, followeeId uint, ) error
FollowingDeleteDafT is the type of the stereotype instance for the DAF that disaassociates a follower from a followee.
var FollowingDeleteDaf FollowingDeleteDafT = func( ctx context.Context, tx pgx.Tx, followerId uint, followeeId uint, ) error { sql := ` DELETE FROM followings WHERE follower_id = $1 AND followee_id = $2 ` args := []any{followerId, followeeId} c, err := tx.Exec(ctx, sql, args...) if kind := dbpgx.ClassifyError(err); kind != nil { return kind.Make(err, "") } if c.RowsAffected() == 0 { return dbpgx.DbErrRecordNotFound.Make(nil, bf.ErrMsgUserWasNotFollowed, followeeId) } return nil }
FollowingDeleteDaf is the instance of the DAF stereotype that disaassociates a follower from a followee.
type FollowingGetDafT ¶
type FollowingGetDafT = func( ctx context.Context, tx pgx.Tx, followerId uint, followeeId uint, ) (model.Following, error)
FollowingGetDafT is the type of the stereotype instance for the DAF that retrieves an association between a follower and a followee.
var FollowingGetDaf FollowingGetDafT = func( ctx context.Context, tx pgx.Tx, followerId uint, followeeId uint, ) (model.Following, error) { var zero model.Following sql := ` SELECT * FROM followings WHERE follower_id = $1 AND followee_id = $2 ` args := []any{ followerId, followeeId, } rows, err := tx.Query(ctx, sql, args...) if kind := dbpgx.ClassifyError(err); kind != nil { return zero, kind.Make(err, "") } defer rows.Close() var following model.Following err = pgxscan.ScanOne(&following, rows) if kind := dbpgx.ClassifyError(err); kind != nil { if kind != dbpgx.DbErrRecordNotFound { return zero, kind.Make(err, "") } } return following, nil }
FollowingGetDaf implements a stereotype instance of type FollowingGetDafT. Returns the association record if found or a zero model.Following otherwise.
type TagAddToArticleDafT ¶
type TagAddToArticleDafT = func(ctx context.Context, tx pgx.Tx, tag model.Tag, article model.Article) error
TagAddToArticleDafT is the type of the stereotype instance for the DAF that associates a tag with an article.
var TagAddToArticleDaf TagAddToArticleDafT = func( ctx context.Context, tx pgx.Tx, tag model.Tag, article model.Article, ) error { sql := ` INSERT INTO article_tags (article_id, tag_id) VALUES ($1, $2) ` args := []any{article.Id, tag.Id} _, err := tx.Exec(ctx, sql, args...) if kind := dbpgx.ClassifyError(err); kind != nil { if kind == dbpgx.DbErrUniqueViolation { return kind.Make(err, bf.ErrMsgTagOnArticleAlreadyExists, tag.Name, article.Slug) } return kind.Make(err, "") } return nil }
TagAddToArticleDaf implements a stereotype instance of type TagAddToArticleDafT.
type TagCreateDafT ¶
TagCreateDafT is the type of the stereotype instance for the DAF that creates a new tag.
var TagCreateDaf TagCreateDafT = func( ctx context.Context, tx pgx.Tx, tag *model.Tag, ) error { sql := ` INSERT INTO tags (name) VALUES ($1) RETURNING id ` args := []any{strings.ToUpper(tag.Name)} row := tx.QueryRow(ctx, sql, args...) err := row.Scan(&tag.Id) if kind := dbpgx.ClassifyError(err); kind != nil { if kind == dbpgx.DbErrRecordNotFound { return dbpgx.DbErrUniqueViolation.Make(err, bf.ErrMsgTagNameAlreadyExists, tag.Name) } return kind.Make(err, "") } return nil }
TagCreateDaf implements a stereotype instance of type TagCreateDafT.
type TagsAddNewDafT ¶
TagsAddNewDafT is the type of the stereotype instance for the DAF that adds a list of tags, skipping those that already exist.
var TagsAddNewDaf TagsAddNewDafT = func( ctx context.Context, tx pgx.Tx, names []string, ) error { if len(names) == 0 { return nil } preSql := ` INSERT INTO tags (name) SELECT x.name FROM ( VALUES %v ) x (name) WHERE NOT EXISTS ( SELECT 1 FROM tags t WHERE t.name = x.name ) ` var values []string for _, name := range names { values = append(values, fmt.Sprintf("('%v')", name)) } valueString := strings.Join(values, ", ") sql := fmt.Sprintf(preSql, valueString) log.Debug("sql:", sql) _, err := tx.Exec(ctx, sql) if kind := dbpgx.ClassifyError(err); kind != nil { return kind.Make(err, "") } return nil }
TagsAddNewDaf implements a stereotype instance of type TagsAddNewDafT.
type TagsAddToArticleDafT ¶
type TagsAddToArticleDafT = func(ctx context.Context, tx pgx.Tx, names []string, article model.Article) error
TagsAddToArticleDafT is the type of the stereotype instance for the DAF that associates a list of tags with an article, skipping those that are already associated.
var TagsAddToArticleDaf TagsAddToArticleDafT = func( ctx context.Context, tx pgx.Tx, names []string, article model.Article, ) error { if len(names) == 0 { return nil } preSql := ` INSERT INTO article_tags (article_id, tag_id) SELECT $1, t.id FROM tags t WHERE t.name IN (%v) AND NOT EXISTS ( SELECT 1 FROM article_tags at WHERE at.tag_id = t.id ) ` var values []string for _, name := range names { values = append(values, fmt.Sprintf("'%v'", name)) } valueString := strings.Join(values, ", ") sql := fmt.Sprintf(preSql, valueString) log.Debug("sql:", sql) _, err := tx.Exec(ctx, sql, article.Id) if kind := dbpgx.ClassifyError(err); kind != nil { return kind.Make(err, "") } return nil }
TagsAddToArticleDaf implements a stereotype instance of type TagsAddToArticleDafT.
type TagsGetAllDafT ¶
TagsGetAllDafT is the type of the stereotype instance for the DAF that retrieves all tags.
type UserCreateDafT ¶
UserCreateDafT is the type of the stereotype instance for the DAF that creates a user.
var UserCreateDaf UserCreateDafT = func( ctx context.Context, user *model.User, ) (RecCtxUser, error) { tx, err := dbpgx.GetCtxTx(ctx) if err != nil { return RecCtxUser{}, err } return UserCreateExplicitTxDaf(ctx, tx, user) }
UserCreateDaf implements a stereotype instance of type UserCreateDafT.
type UserCreateExplicitTxDafT ¶
type UserCreateExplicitTxDafT = func(ctx context.Context, tx pgx.Tx, user *model.User) (RecCtxUser, error)
UserCreateExplicitTxDafT is the type of the stereotype instance for the DAF that creates a user taking an explicit pgx.Tx.
var UserCreateExplicitTxDaf UserCreateExplicitTxDafT = func( ctx context.Context, tx pgx.Tx, user *model.User, ) (RecCtxUser, error) { sql := ` INSERT INTO users (username, email, password_hash, password_salt, bio, image) VALUES ($1, $2, $3, $4, $5, $6) RETURNING id, created_at, updated_at ` user.Email = strings.ToLower(user.Email) args := []any{ user.Username, user.Email, user.PasswordHash, user.PasswordSalt, user.Bio, user.ImageLink, } row := tx.QueryRow(ctx, sql, args...) var recCtx RecCtxUser err := row.Scan(&user.Id, &recCtx.CreatedAt, &recCtx.UpdatedAt) if kind := dbpgx.ClassifyError(err); kind != nil { if kind == dbpgx.DbErrUniqueViolation { return RecCtxUser{}, kind.Make( err, bf.ErrMsgUsernameOrEmailDuplicate, user.Username, user.Email, ) } return RecCtxUser{}, kind.Make(err, "") } return recCtx, nil }
UserCreateExplicitTxDaf implements a stereotype instance of type UserCreateDafT.
type UserGetByEmailDafT ¶
UserGetByEmailDafT is the type of the stereotype instance for the DAF that retrieves a user by email address.
var UserGetByEmailDaf UserGetByEmailDafT = func( ctx context.Context, email string, ) (model.User, RecCtxUser, error) { tx, err := dbpgx.GetCtxTx(ctx) if err != nil { return model.User{}, RecCtxUser{}, err } pwUser := PwUser{} err = dbpgx.ReadSingle(ctx, tx, "users", "email", strings.ToLower(email), &pwUser) if kind := dbpgx.ClassifyError(err); kind != nil { if kind == dbpgx.DbErrRecordNotFound { return model.User{}, RecCtxUser{}, kind.Decorate(util.SafeCast[errx.Errx](err), bf.ErrMsgUserEmailNotFound, email) } return model.User{}, RecCtxUser{}, err } return pwUser.Entity, pwUser.RecCtx, nil }
UserGetByEmailDaf implements a stereotype instance of type UserGetByEmailDafT.
type UserGetByNameDafT ¶
UserGetByNameDafT is the type of the stereotype instance for the DAF that retrieves a user by username.
var UserGetByNameDaf UserGetByNameDafT = func( ctx context.Context, username string, ) (model.User, RecCtxUser, error) { tx, err := dbpgx.GetCtxTx(ctx) if err != nil { return model.User{}, RecCtxUser{}, err } return UserGetByNameExplicitTxDaf(ctx, tx, username) }
UserGetByNameDaf implements a stereotype instance of type UserGetByNameDafT.
type UserGetByNameExplicitTxDafT ¶
type UserGetByNameExplicitTxDafT = func( ctx context.Context, tx pgx.Tx, username string, ) (model.User, RecCtxUser, error)
UserGetByNameExplicitTxDafT is the type of the stereotype instance for the DAF that retrieves a user by username taking an explicit pgx.Tx.
var UserGetByNameExplicitTxDaf UserGetByNameExplicitTxDafT = func( ctx context.Context, tx pgx.Tx, username string, ) (model.User, RecCtxUser, error) { pwUser := PwUser{} err := dbpgx.ReadSingle(ctx, tx, "users", "username", username, &pwUser) if kind := dbpgx.ClassifyError(err); kind != nil { if kind == dbpgx.DbErrRecordNotFound { errX := util.SafeCast[errx.Errx](err) return model.User{}, RecCtxUser{}, errX.Customize(bf.ErrMsgUsernameNotFound, username) } return model.User{}, RecCtxUser{}, err } return pwUser.Entity, pwUser.RecCtx, nil }
UserGetByNameExplicitTxDaf implements a stereotype instance of type UserGetByNameDafT with explicit passing of a pgx.Tx.
type UserUpdateDafT ¶
type UserUpdateDafT = func(ctx context.Context, user model.User, recCtx RecCtxUser) (RecCtxUser, error)
UserUpdateDafT is the type of the stereotype instance for the DAF that updates a user.
var UserUpdateDaf UserUpdateDafT = func( ctx context.Context, user model.User, recCtx RecCtxUser, ) (RecCtxUser, error) { tx, err := dbpgx.GetCtxTx(ctx) if err != nil { return RecCtxUser{}, errx.ErrxOf(err) } sql := ` UPDATE users SET username = $1, email = $2, bio = $3, image = $4, password_hash = $5, password_salt = $6, updated_at = clock_timestamp() WHERE id = $7 AND updated_at = $8 RETURNING updated_at ` user.Email = strings.ToLower(user.Email) args := []interface{}{ user.Username, user.Email, user.Bio, user.ImageLink, user.PasswordHash, user.PasswordSalt, user.Id, recCtx.UpdatedAt, } log.Debug("UserUpdateDaf sql: ", sql) log.Debug("UserUpdateDaf args: ", args) newRecCtx := recCtx row := tx.QueryRow(ctx, sql, args...) err = row.Scan(&newRecCtx.UpdatedAt) if kind := dbpgx.ClassifyError(err); kind != nil { if kind == dbpgx.DbErrUniqueViolation { return RecCtxUser{}, kind.Make( err, bf.ErrMsgUsernameOrEmailDuplicate, user.Username, user.Email, ) } return RecCtxUser{}, kind.Make(err, "") } return newRecCtx, nil }
UserUpdateDaf implements a stereotype instance of type UserUpdateDafT.