Skip to content

Commit

Permalink
✨ add register user and create profile tx
Browse files Browse the repository at this point in the history
  • Loading branch information
codermuss committed Aug 2, 2024
1 parent ae4a34a commit 3575318
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 16 deletions.
29 changes: 14 additions & 15 deletions api/register.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package api

import (
"fmt"
"net/http"
"time"

Expand Down Expand Up @@ -60,7 +61,7 @@ func (server *Server) RegisterUser(ctx *gin.Context) {
return
}

arg := db.InsertUserParams{
argUser := db.InsertUserParams{
Username: req.Username,
HashedPassword: hashedPassword,
FullName: req.FullName,
Expand All @@ -69,7 +70,17 @@ func (server *Server) RegisterUser(ctx *gin.Context) {
Avatar: req.Avatar,
BirthDate: req.BirthDate,
}
user, err := server.store.InsertUser(ctx, arg)
argAfterCreate := func(user db.User) error {
fmt.Println("after create triggered")
return nil
}

arg := db.RegisterUserTxParams{
InsertUserParams: argUser,
AfterCreate: argAfterCreate,
}

userAndProfile, err := server.store.RegisterUserTx(ctx, arg)

if err != nil {

Expand All @@ -94,21 +105,9 @@ func (server *Server) RegisterUser(ctx *gin.Context) {
return
}

responseUser := UserResponse{
ID: user.ID,
Username: user.Username,
FullName: user.FullName,
Email: user.Email,
Role: user.Role,
Avatar: user.Avatar,
BirthDate: user.BirthDate,
PasswordChangedAt: user.PasswordChangedAt,
CreatedAt: user.CreatedAt,
}

BuildResponse(ctx, BaseResponse{
Code: http.StatusOK,
Data: responseUser,
Data: userAndProfile,
Message: ResponseMessage{
Type: SUCCESS,
Content: server.lm.Translate(localeValue, localization.User_RegisterSuccess),
Expand Down
15 changes: 15 additions & 0 deletions db/mock/store.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

25 changes: 25 additions & 0 deletions db/sqlc/exec_tx.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package db

import (
"context"
"fmt"
)

func (store *SQLStore) execTx(ctx context.Context, fn func(*Queries) error) error {
tx, err := store.connPool.Begin(ctx)
if err != nil {
return err
}
// * Note [codermuss]: Begin db transaction
q := New(tx)
// * Note [codermuss]: execute query
err = fn(q)
// * Note [codermuss]: if there is an error Rollback the query
if err != nil {
if rbErr := tx.Rollback(ctx); rbErr != nil {
return fmt.Errorf("tx err: %v, rb err: %v", err, rbErr)
}
return err
}
return tx.Commit(ctx)
}
7 changes: 6 additions & 1 deletion db/sqlc/store.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
package db

import "github.com/jackc/pgx/v5/pgxpool"
import (
"context"

"github.com/jackc/pgx/v5/pgxpool"
)

type Store interface {
Querier
RegisterUserTx(ctx context.Context, arg RegisterUserTxParams) (RegisterUserTxResult, error)
}

type SQLStore struct {
Expand Down
54 changes: 54 additions & 0 deletions db/sqlc/tx_create_user.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package db

import (
"context"

"github.com/jackc/pgx/v5/pgtype"
)

type RegisterUserTxParams struct {
InsertUserParams
// * Note [codermuss]: This function will be executed after the user is inserted,
// * Note [codermuss]: inside the same transaction. And its output error will be used to decide
// * Note [codermuss]: whether to commit or rollback the transaction.
AfterCreate func(user User) error
}
type RegisterUserTxResult struct {
User User
Profile Profile
}

// * Note [codermuss]: This method responsible with creating user.
// * Note [codermuss]: It uses execTx to handle DB Transaction error
func (store *SQLStore) RegisterUserTx(ctx context.Context, arg RegisterUserTxParams) (RegisterUserTxResult, error) {
var result RegisterUserTxResult

err := store.execTx(ctx, func(q *Queries) error {
var err error
result.User, err = q.InsertUser(ctx, arg.InsertUserParams)
if err != nil {
return err
}
profileArg := InsertProfileParams{
UserID: result.User.ID,
Bio: pgtype.Text{Valid: true, String: ""},
PostCount: pgtype.Int4{
Valid: true, Int32: 0,
},
LikeCount: pgtype.Int4{
Valid: true, Int32: 0,
},
FollowerCount: pgtype.Int4{
Valid: true, Int32: 0,
},
}

result.Profile, err = q.InsertProfile(ctx, profileArg)
if err != nil {
return err
}

return arg.AfterCreate(result.User)
})
return result, err
}

0 comments on commit 3575318

Please sign in to comment.