updaet add location into trasnaction

This commit is contained in:
nochill 2023-10-03 19:44:31 +07:00
parent 641831a3ae
commit 8dbebd9f17
7 changed files with 144 additions and 58 deletions

View File

@ -11,7 +11,6 @@ import (
db "git.nochill.in/nochill/hiling_go/db/sqlc" db "git.nochill.in/nochill/hiling_go/db/sqlc"
"git.nochill.in/nochill/hiling_go/util" "git.nochill.in/nochill/hiling_go/util"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/lib/pq"
ysqlc "github.com/yiplee/sqlc" ysqlc "github.com/yiplee/sqlc"
) )
@ -27,48 +26,17 @@ type createLocationReq struct {
func (server *Server) createLocation(ctx *gin.Context) { func (server *Server) createLocation(ctx *gin.Context) {
var req createLocationReq var req createLocationReq
var imgPath string var imgPath string
var tempImg []db.CreateImageParams
if err := ctx.Bind(&req); err != nil { if err := ctx.Bind(&req); err != nil {
ctx.JSON(http.StatusBadRequest, ValidationErrorResponse(err)) ctx.JSON(http.StatusBadRequest, ValidationErrorResponse(err))
return return
} }
arg := db.CreateLocationParams{
Address: req.Address,
Name: req.Name,
LocationType: db.LocationType(req.LocationType),
SubmittedBy: req.SubmittedBy,
RegencyID: req.RegencyID,
IsDeleted: false,
ApprovedBy: sql.NullInt32{Int32: 0, Valid: false},
GoogleMapsLink: sql.NullString{Valid: len(req.GoogleMapsLink) > 0, String: req.GoogleMapsLink},
}
id, err := server.Store.CreateLocation(ctx, arg)
if err != nil {
if pqErr, ok := err.(*pq.Error); ok {
switch pqErr.Code.Name() {
case "foreign_key_violation", "unique_violation":
if pqErr.Constraint == "locations_regency_id_fkey" {
ctx.JSON(http.StatusConflict, ErrorResponse(err, fmt.Sprintf("Failed to submit location, there's no regency with id: %d", arg.RegencyID)))
return
}
if pqErr.Constraint == "submitted_by_fkey" {
ctx.JSON(http.StatusConflict, ErrorResponse(err, fmt.Sprintf("Failed to submit location, there's no user with id: %d", arg.SubmittedBy)))
return
}
}
}
ctx.JSON(http.StatusInternalServerError, ErrorResponse(err, "Something went wrong while try to create location"))
return
}
form, _ := ctx.MultipartForm() form, _ := ctx.MultipartForm()
thumbnails := form.File["thumbnail"] thumbnails := form.File["thumbnail"]
if len(thumbnails) > 0 { if len(thumbnails) > 0 {
var tempImg []db.CreateImageParams
for _, img := range thumbnails { for _, img := range thumbnails {
fileExt := filepath.Ext(img.Filename) fileExt := filepath.Ext(img.Filename)
now := time.Now() now := time.Now()
@ -84,21 +52,27 @@ func (server *Server) createLocation(ctx *gin.Context) {
ctx.JSON(http.StatusInternalServerError, ErrorResponse(err, "Error while try to save thumbnail image")) ctx.JSON(http.StatusInternalServerError, ErrorResponse(err, "Error while try to save thumbnail image"))
return return
} }
tempImg = append(tempImg, db.CreateImageParams{
ImageUrl: imgPath,
UploadedBy: req.SubmittedBy,
ImageType: "locations",
ImageOf: id,
})
} }
err := server.Store.CreateImage(ctx, tempImg) arg := db.CreateLocationTxParams{
Address: req.Address,
Name: req.Name,
LocationType: db.LocationType(req.LocationType),
SubmittedBy: req.SubmittedBy,
RegencyID: req.RegencyID,
IsDeleted: false,
ApprovedBy: sql.NullInt32{Int32: 0, Valid: false},
GoogleMapsLink: sql.NullString{Valid: len(req.GoogleMapsLink) > 0, String: req.GoogleMapsLink},
Thumbnail: tempImg,
}
err := server.Store.CreateLocationTx(ctx, arg)
if err != nil { if err != nil {
ctx.JSON(http.StatusInternalServerError, ErrorResponse(err, "Something went wrong while try to save image")) ctx.JSON(http.StatusInternalServerError, ErrorResponse(err, "Something went wrong while try to save Location"))
return return
} }
} }
ctx.Writer.WriteHeader(http.StatusOK) ctx.Writer.WriteHeader(http.StatusOK)

View File

@ -93,6 +93,20 @@ func (mr *MockStoreMockRecorder) CreateLocation(arg0, arg1 interface{}) *gomock.
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateLocation", reflect.TypeOf((*MockStore)(nil).CreateLocation), arg0, arg1) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateLocation", reflect.TypeOf((*MockStore)(nil).CreateLocation), arg0, arg1)
} }
// CreateLocationTx mocks base method.
func (m *MockStore) CreateLocationTx(arg0 context.Context, arg1 db.CreateLocationTxParams) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "CreateLocationTx", arg0, arg1)
ret0, _ := ret[0].(error)
return ret0
}
// CreateLocationTx indicates an expected call of CreateLocationTx.
func (mr *MockStoreMockRecorder) CreateLocationTx(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateLocationTx", reflect.TypeOf((*MockStore)(nil).CreateLocationTx), arg0, arg1)
}
// CreateReview mocks base method. // CreateReview mocks base method.
func (m *MockStore) CreateReview(arg0 context.Context, arg1 db.CreateReviewParams) (db.Review, error) { func (m *MockStore) CreateReview(arg0 context.Context, arg1 db.CreateReviewParams) (db.Review, error) {
m.ctrl.T.Helper() m.ctrl.T.Helper()
@ -362,6 +376,20 @@ func (mr *MockStoreMockRecorder) RemoveFollowUser(arg0, arg1 interface{}) *gomoc
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveFollowUser", reflect.TypeOf((*MockStore)(nil).RemoveFollowUser), arg0, arg1) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveFollowUser", reflect.TypeOf((*MockStore)(nil).RemoveFollowUser), arg0, arg1)
} }
// UpdateLocationThumbnail mocks base method.
func (m *MockStore) UpdateLocationThumbnail(arg0 context.Context, arg1 db.UpdateLocationThumbnailParams) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "UpdateLocationThumbnail", arg0, arg1)
ret0, _ := ret[0].(error)
return ret0
}
// UpdateLocationThumbnail indicates an expected call of UpdateLocationThumbnail.
func (mr *MockStoreMockRecorder) UpdateLocationThumbnail(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateLocationThumbnail", reflect.TypeOf((*MockStore)(nil).UpdateLocationThumbnail), arg0, arg1)
}
// UpdatePassword mocks base method. // UpdatePassword mocks base method.
func (m *MockStore) UpdatePassword(arg0 context.Context, arg1 db.UpdatePasswordParams) error { func (m *MockStore) UpdatePassword(arg0 context.Context, arg1 db.UpdatePasswordParams) error {
m.ctrl.T.Helper() m.ctrl.T.Helper()

View File

@ -28,3 +28,9 @@ AND
target_id = $1 target_id = $1
AND AND
approved_by IS NOT NULL; approved_by IS NOT NULL;
-- name: UpdateLocationThumbnail :exec
UPDATE locations
SET thumbnail = $1
WHERE id = $2;

View File

@ -149,3 +149,19 @@ func (q *Queries) GetLocationTag(ctx context.Context, targetID int32) ([]string,
} }
return items, nil return items, nil
} }
const updateLocationThumbnail = `-- name: UpdateLocationThumbnail :exec
UPDATE locations
SET thumbnail = $1
WHERE id = $2
`
type UpdateLocationThumbnailParams struct {
Thumbnail sql.NullString `json:"thumbnail"`
ID int32 `json:"id"`
}
func (q *Queries) UpdateLocationThumbnail(ctx context.Context, arg UpdateLocationThumbnailParams) error {
_, err := q.db.ExecContext(ctx, updateLocationThumbnail, arg.Thumbnail, arg.ID)
return err
}

View File

@ -23,6 +23,7 @@ type Querier interface {
GetSession(ctx context.Context, id int32) (UserSession, error) GetSession(ctx context.Context, id int32) (UserSession, error)
GetUserReviewByLocation(ctx context.Context, arg GetUserReviewByLocationParams) (GetUserReviewByLocationRow, error) GetUserReviewByLocation(ctx context.Context, arg GetUserReviewByLocationParams) (GetUserReviewByLocationRow, error)
RemoveFollowUser(ctx context.Context, arg RemoveFollowUserParams) error RemoveFollowUser(ctx context.Context, arg RemoveFollowUserParams) error
UpdateLocationThumbnail(ctx context.Context, arg UpdateLocationThumbnailParams) error
UpdatePassword(ctx context.Context, arg UpdatePasswordParams) error UpdatePassword(ctx context.Context, arg UpdatePasswordParams) error
UpdateUser(ctx context.Context, arg UpdateUserParams) (User, error) UpdateUser(ctx context.Context, arg UpdateUserParams) (User, error)
} }

View File

@ -3,6 +3,7 @@ package db
import ( import (
"context" "context"
"database/sql" "database/sql"
"fmt"
"github.com/yiplee/sqlc" "github.com/yiplee/sqlc"
) )
@ -17,6 +18,7 @@ type Store interface {
GetListLocationReviews(ctx context.Context, arg GetListLocationReviewsParams) ([]GetListLocationReviewsRow, error) GetListLocationReviews(ctx context.Context, arg GetListLocationReviewsParams) ([]GetListLocationReviewsRow, error)
CreateLocation(ctx context.Context, arg CreateLocationParams) (int32, error) CreateLocation(ctx context.Context, arg CreateLocationParams) (int32, error)
CreateImage(ctx context.Context, arg []CreateImageParams) error CreateImage(ctx context.Context, arg []CreateImageParams) error
CreateLocationTx(ctx context.Context, arg CreateLocationTxParams) error
} }
type SQLStore struct { type SQLStore struct {
@ -32,19 +34,19 @@ func NewStore(db *sql.DB) Store {
} }
// TRANSACTION QUERY FUNCTION // TRANSACTION QUERY FUNCTION
// func (store *SQLStore) execTx(ctx context.Context, fn func(*Queries) error) error { func (store *SQLStore) execTx(ctx context.Context, fn func(*Queries) error) error {
// tx, err := store.db.BeginTx(ctx, nil) tx, err := store.db.BeginTx(ctx, nil)
// if err != nil { if err != nil {
// return err return err
// } }
// q := New(tx) q := New(tx)
// err = fn(q) err = fn(q)
// if err != nil { if err != nil {
// if rbErr := tx.Rollback(); rbErr != nil { if rbErr := tx.Rollback(); rbErr != nil {
// return fmt.Errorf("tx err: %v, rb err : %v", err, rbErr) return fmt.Errorf("tx err: %v, rb err : %v", err, rbErr)
// } }
// return err return err
// } }
// return tx.Commit() return tx.Commit()
// } }

59
db/sqlc/tx_location.go Normal file
View File

@ -0,0 +1,59 @@
package db
import (
"context"
"database/sql"
)
type CreateLocationTxParams struct {
Address string `json:"address"`
Name string `json:"name"`
SubmittedBy int32 `json:"submitted_by"`
LocationType LocationType `json:"location_type"`
RegencyID int16 `json:"regency_id"`
GoogleMapsLink sql.NullString `json:"google_maps_link"`
IsDeleted bool `json:"is_deleted"`
ApprovedBy sql.NullInt32 `json:"approved_by"`
Thumbnail []CreateImageParams `json:"thumbnails"`
}
func (store *SQLStore) CreateLocationTx(ctx context.Context, arg CreateLocationTxParams) error {
err := store.execTx(ctx, func(q *Queries) error {
var err error
location_id, err := q.CreateLocation(ctx, CreateLocationParams{
Address: arg.Address,
Name: arg.Name,
SubmittedBy: arg.SubmittedBy,
LocationType: arg.LocationType,
RegencyID: arg.RegencyID,
GoogleMapsLink: arg.GoogleMapsLink,
IsDeleted: arg.IsDeleted,
ApprovedBy: arg.ApprovedBy,
})
if err != nil {
return err
}
if len(arg.Thumbnail) > 0 {
err := q.CreateImage(ctx, arg.Thumbnail)
if err != nil {
return err
}
err = q.UpdateLocationThumbnail(ctx, UpdateLocationThumbnailParams{
Thumbnail: sql.NullString{Valid: true, String: arg.Thumbnail[0].ImageUrl},
ID: location_id,
})
if err != nil {
return err
}
}
return nil
})
return err
}