adjust with multiple image locations
This commit is contained in:
parent
110cbfeec0
commit
5a5d157882
@ -20,6 +20,7 @@ type createLocationReq struct {
|
||||
Name string `form:"name" binding:"required"`
|
||||
SubmittedBy int32 `form:"submitted_by" binding:"required,number"`
|
||||
RegencyID int16 `form:"regency_id" binding:"required,number"`
|
||||
LocationType string `form:"location_type" binding:"required"`
|
||||
GoogleMapsLink string `form:"google_maps_link"`
|
||||
}
|
||||
|
||||
@ -27,40 +28,23 @@ func (server *Server) createLocation(ctx *gin.Context) {
|
||||
var req createLocationReq
|
||||
var imgPath string
|
||||
|
||||
var thumbnail, _ = ctx.FormFile("thumbnail")
|
||||
|
||||
if err := ctx.Bind(&req); err != nil {
|
||||
ctx.JSON(http.StatusBadRequest, ValidationErrorResponse(err))
|
||||
return
|
||||
}
|
||||
|
||||
if thumbnail != nil {
|
||||
img := thumbnail
|
||||
fileExt := filepath.Ext(img.Filename)
|
||||
now := time.Now()
|
||||
dir := fmt.Sprintf("public/upload/images/locations/%s/thumbnail", req.Name)
|
||||
osFilename := fmt.Sprintf("%s%s%s", util.RandomString(5), fmt.Sprintf("%v", now.Unix()), fileExt)
|
||||
imgPath = fmt.Sprintf("%s%s", dir, osFilename)
|
||||
|
||||
if _, err := os.Stat(dir); os.IsNotExist(err) {
|
||||
os.Mkdir(dir, 0775)
|
||||
}
|
||||
|
||||
if err := ctx.SaveUploadedFile(img, imgPath); err != nil {
|
||||
ctx.JSON(http.StatusInternalServerError, ErrorResponse(err, "Error while try to save thumbnail image"))
|
||||
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},
|
||||
}
|
||||
|
||||
err := server.Store.CreateLocation(ctx, arg)
|
||||
id, err := server.Store.CreateLocation(ctx, arg)
|
||||
|
||||
if err != nil {
|
||||
if pqErr, ok := err.(*pq.Error); ok {
|
||||
@ -76,10 +60,47 @@ func (server *Server) createLocation(ctx *gin.Context) {
|
||||
}
|
||||
}
|
||||
}
|
||||
ctx.JSON(http.StatusInternalServerError, ErrorResponse(err, "Something went wrong"))
|
||||
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()
|
||||
dir := fmt.Sprintf("public/upload/images/locations/%s/thumbnail", req.Name)
|
||||
osFilename := fmt.Sprintf("%s%s%s", util.RandomString(5), fmt.Sprintf("%v", now.Unix()), fileExt)
|
||||
imgPath = fmt.Sprintf("%s/%s", dir, osFilename)
|
||||
|
||||
if _, err := os.Stat(dir); os.IsNotExist(err) {
|
||||
os.Mkdir(dir, 0775)
|
||||
}
|
||||
|
||||
if err := ctx.SaveUploadedFile(img, imgPath); err != nil {
|
||||
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)
|
||||
|
||||
if err != nil {
|
||||
ctx.JSON(http.StatusInternalServerError, ErrorResponse(err, "Something went wrong while try to save image"))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
ctx.Writer.WriteHeader(http.StatusOK)
|
||||
|
||||
}
|
||||
|
@ -50,14 +50,29 @@ func (mr *MockStoreMockRecorder) CheckIfReviewExists(arg0, arg1 interface{}) *go
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CheckIfReviewExists", reflect.TypeOf((*MockStore)(nil).CheckIfReviewExists), arg0, arg1)
|
||||
}
|
||||
|
||||
// CreateLocation mocks base method.
|
||||
func (m *MockStore) CreateLocation(arg0 context.Context, arg1 db.CreateLocationParams) error {
|
||||
// CreateImage mocks base method.
|
||||
func (m *MockStore) CreateImage(arg0 context.Context, arg1 []db.CreateImageParams) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "CreateLocation", arg0, arg1)
|
||||
ret := m.ctrl.Call(m, "CreateImage", arg0, arg1)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// CreateImage indicates an expected call of CreateImage.
|
||||
func (mr *MockStoreMockRecorder) CreateImage(arg0, arg1 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateImage", reflect.TypeOf((*MockStore)(nil).CreateImage), arg0, arg1)
|
||||
}
|
||||
|
||||
// CreateLocation mocks base method.
|
||||
func (m *MockStore) CreateLocation(arg0 context.Context, arg1 db.CreateLocationParams) (int32, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "CreateLocation", arg0, arg1)
|
||||
ret0, _ := ret[0].(int32)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// CreateLocation indicates an expected call of CreateLocation.
|
||||
func (mr *MockStoreMockRecorder) CreateLocation(arg0, arg1 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
|
@ -19,17 +19,6 @@ WHERE approved_by IS NOT NULL
|
||||
ORDER BY l.created_at ASC
|
||||
LIMIT $1;
|
||||
|
||||
-- name: CreateLocation :exec
|
||||
INSERT INTO locations(
|
||||
address,
|
||||
name,
|
||||
submitted_by,
|
||||
regency_id,
|
||||
google_maps_link
|
||||
) values (
|
||||
$1, $2, $3, $4, $5
|
||||
);
|
||||
|
||||
-- name: GetLocationTag :many
|
||||
SELECT
|
||||
name
|
||||
|
@ -2,7 +2,10 @@ package db
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"git.nochill.in/nochill/hiling_go/util"
|
||||
)
|
||||
|
||||
type GetImagesByLocationParams struct {
|
||||
@ -59,3 +62,38 @@ func (q *Queries) GetImagesByLocation(ctx context.Context, arg GetImagesByLocati
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
type CreateImageParams struct {
|
||||
ImageUrl string `json:"url"`
|
||||
UploadedBy int32 `json:"uploaded_by"`
|
||||
ImageType string `json:"image_type"`
|
||||
ImageOf int32 `json:"image_of"`
|
||||
}
|
||||
|
||||
func (q *Queries) CreateImage(ctx context.Context, arg []CreateImageParams) error {
|
||||
|
||||
values := []interface{}{}
|
||||
|
||||
queryStr := ` INSERT INTO
|
||||
images(image_url, uploaded_by, image_type, image_of)
|
||||
VALUES
|
||||
`
|
||||
|
||||
for _, row := range arg {
|
||||
queryStr += "(?, ?, ?, ?),"
|
||||
values = append(values, row.ImageUrl, row.UploadedBy, row.ImageType, row.ImageOf)
|
||||
}
|
||||
|
||||
queryStr = strings.TrimSuffix(queryStr, ",")
|
||||
|
||||
// Replacing ? with $n for postgres
|
||||
queryStr = util.ReplaceSQL(queryStr, "?")
|
||||
|
||||
// prepare the statement
|
||||
stmt, _ := q.db.PrepareContext(ctx, queryStr)
|
||||
|
||||
// format all vals at once
|
||||
_, err := stmt.ExecContext(ctx, values...)
|
||||
|
||||
return err
|
||||
}
|
||||
|
@ -171,3 +171,53 @@ func (q *Queries) GetLocation(ctx context.Context, location_id int32) (GetLocati
|
||||
|
||||
return i, err
|
||||
}
|
||||
|
||||
const createLocation = `-- name: CreateLocation :exec
|
||||
INSERT INTO locations(
|
||||
address,
|
||||
name,
|
||||
submitted_by,
|
||||
location_type,
|
||||
regency_id,
|
||||
google_maps_link,
|
||||
approved_by,
|
||||
is_deleted
|
||||
) values (
|
||||
$1, $2, $3, $4, $5, $6, $7, $8
|
||||
)
|
||||
RETURNING id
|
||||
`
|
||||
|
||||
type CreateLocationParams 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"`
|
||||
}
|
||||
|
||||
func (q *Queries) CreateLocation(ctx context.Context, arg CreateLocationParams) (int32, error) {
|
||||
row := q.db.QueryRowContext(ctx, createLocation,
|
||||
arg.Address,
|
||||
arg.Name,
|
||||
arg.SubmittedBy,
|
||||
arg.LocationType,
|
||||
arg.RegencyID,
|
||||
arg.GoogleMapsLink,
|
||||
arg.ApprovedBy,
|
||||
arg.IsDeleted,
|
||||
)
|
||||
|
||||
var i int32
|
||||
|
||||
err := row.Scan(
|
||||
&i,
|
||||
)
|
||||
|
||||
fmt.Println(i)
|
||||
|
||||
return i, err
|
||||
}
|
||||
|
@ -10,37 +10,6 @@ import (
|
||||
"database/sql"
|
||||
)
|
||||
|
||||
const createLocation = `-- name: CreateLocation :exec
|
||||
INSERT INTO locations(
|
||||
address,
|
||||
name,
|
||||
submitted_by,
|
||||
regency_id,
|
||||
google_maps_link
|
||||
) values (
|
||||
$1, $2, $3, $4, $5
|
||||
)
|
||||
`
|
||||
|
||||
type CreateLocationParams struct {
|
||||
Address string `json:"address"`
|
||||
Name string `json:"name"`
|
||||
SubmittedBy int32 `json:"submitted_by"`
|
||||
RegencyID int16 `json:"regency_id"`
|
||||
GoogleMapsLink sql.NullString `json:"google_maps_link"`
|
||||
}
|
||||
|
||||
func (q *Queries) CreateLocation(ctx context.Context, arg CreateLocationParams) error {
|
||||
_, err := q.db.ExecContext(ctx, createLocation,
|
||||
arg.Address,
|
||||
arg.Name,
|
||||
arg.SubmittedBy,
|
||||
arg.RegencyID,
|
||||
arg.GoogleMapsLink,
|
||||
)
|
||||
return err
|
||||
}
|
||||
|
||||
const getListLocations = `-- name: GetListLocations :many
|
||||
SELECT id, address, name, google_maps_link, location_type, submitted_by, total_visited, thumbnail, regency_id, is_deleted, created_at, updated_at, approved_by, approved_at FROM locations
|
||||
`
|
||||
|
@ -10,7 +10,6 @@ import (
|
||||
|
||||
type Querier interface {
|
||||
CheckIfReviewExists(ctx context.Context, arg CheckIfReviewExistsParams) (int64, error)
|
||||
CreateLocation(ctx context.Context, arg CreateLocationParams) error
|
||||
CreateSession(ctx context.Context, arg CreateSessionParams) (UserSession, error)
|
||||
CreateUser(ctx context.Context, arg CreateUserParams) (User, error)
|
||||
GetCountImageByLocation(ctx context.Context, imageOf int32) (int64, error)
|
||||
|
@ -15,6 +15,8 @@ type Store interface {
|
||||
GetUser(ctx context.Context, username string) (GetUserRow, error)
|
||||
CreateReview(ctx context.Context, arg CreateReviewParams) (Review, error)
|
||||
GetListLocationReviews(ctx context.Context, arg GetListLocationReviewsParams) ([]GetListLocationReviewsRow, error)
|
||||
CreateLocation(ctx context.Context, arg CreateLocationParams) (int32, error)
|
||||
CreateImage(ctx context.Context, arg []CreateImageParams) error
|
||||
}
|
||||
|
||||
type SQLStore struct {
|
||||
|
@ -31,6 +31,6 @@ func TestCreateLocation(t *testing.T) {
|
||||
GoogleMapsLink: sql.NullString{Valid: true, String: util.RandomString(10)},
|
||||
}
|
||||
|
||||
err := testQueries.CreateLocation(context.Background(), arg)
|
||||
_, err := testQueries.CreateLocation(context.Background(), arg)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
14
util/common.go
Normal file
14
util/common.go
Normal file
@ -0,0 +1,14 @@
|
||||
package util
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func ReplaceSQL(old, searchPattern string) string {
|
||||
tmpCount := strings.Count(old, searchPattern)
|
||||
for m := 1; m <= tmpCount; m++ {
|
||||
old = strings.Replace(old, searchPattern, "$"+strconv.Itoa(m), 1)
|
||||
}
|
||||
return old
|
||||
}
|
Loading…
Reference in New Issue
Block a user