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"
"git.nochill.in/nochill/hiling_go/util"
"github.com/gin-gonic/gin"
"github.com/lib/pq"
ysqlc "github.com/yiplee/sqlc"
)
@ -27,48 +26,17 @@ type createLocationReq struct {
func (server *Server) createLocation(ctx *gin.Context) {
var req createLocationReq
var imgPath string
var tempImg []db.CreateImageParams
if err := ctx.Bind(&req); err != nil {
ctx.JSON(http.StatusBadRequest, ValidationErrorResponse(err))
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()
thumbnails := form.File["thumbnail"]
if len(thumbnails) > 0 {
var tempImg []db.CreateImageParams
for _, img := range thumbnails {
fileExt := filepath.Ext(img.Filename)
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"))
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 {
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
}
}
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)
}
// 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.
func (m *MockStore) CreateReview(arg0 context.Context, arg1 db.CreateReviewParams) (db.Review, error) {
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)
}
// 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.
func (m *MockStore) UpdatePassword(arg0 context.Context, arg1 db.UpdatePasswordParams) error {
m.ctrl.T.Helper()

View File

@ -27,4 +27,10 @@ WHERE tags_type = 'location'
AND
target_id = $1
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
}
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)
GetUserReviewByLocation(ctx context.Context, arg GetUserReviewByLocationParams) (GetUserReviewByLocationRow, error)
RemoveFollowUser(ctx context.Context, arg RemoveFollowUserParams) error
UpdateLocationThumbnail(ctx context.Context, arg UpdateLocationThumbnailParams) error
UpdatePassword(ctx context.Context, arg UpdatePasswordParams) error
UpdateUser(ctx context.Context, arg UpdateUserParams) (User, error)
}

View File

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