cursor location

This commit is contained in:
nochill 2024-08-19 07:40:01 +07:00
parent 3bd611a8a2
commit 28d8774280
27 changed files with 168 additions and 17 deletions

View File

@ -3,6 +3,7 @@ package api
import ( import (
"errors" "errors"
"fmt" "fmt"
"reflect"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/go-playground/validator/v10" "github.com/go-playground/validator/v10"
@ -48,6 +49,25 @@ func ValidationErrorResponse(err error) gin.H {
} }
} }
func ValidationErrorResponseV2(err error, s interface{}, tagName string) gin.H {
var ves validator.ValidationErrors
var temp []APIValidationError
if errors.As(err, &ves) {
out := make([]APIValidationError, len(ves))
for i, ve := range ves {
fieldName := ve.Field()
field, _ := reflect.TypeOf(s).FieldByName(fieldName)
tag := field.Tag.Get(tagName)
out[i] = APIValidationError{tag, validationErrorMsg(tag, ve.Param(), ve.ActualTag(), ve.Type().Name())}
}
temp = out
}
return gin.H{
"message": "Validation error",
"errors": temp,
}
}
func ErrorResponse(err error, msg string) gin.H { func ErrorResponse(err error, msg string) gin.H {
return gin.H{ return gin.H{
"error": err.Error(), "error": err.Error(),

2
data.ms/VERSION Executable file → Normal file
View File

@ -1 +1 @@
1.6.0 1.8.0

BIN
data.ms/auth/data.mdb Executable file → Normal file

Binary file not shown.

BIN
data.ms/auth/lock.mdb Executable file → Normal file

Binary file not shown.

2
data.ms/instance-uid Executable file → Normal file
View File

@ -1 +1 @@
3db8a6fc-efe2-4e2e-a2ca-2de2e6914f2a 864514bc-7376-4dbe-83ac-1a1c43681252

BIN
data.ms/tasks/data.mdb Executable file → Normal file

Binary file not shown.

BIN
data.ms/tasks/lock.mdb Executable file → Normal file

Binary file not shown.

View File

@ -187,6 +187,21 @@ func (mr *MockStoreMockRecorder) GetCountImageByLocation(arg0, arg1 any) *gomock
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCountImageByLocation", reflect.TypeOf((*MockStore)(nil).GetCountImageByLocation), arg0, arg1) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCountImageByLocation", reflect.TypeOf((*MockStore)(nil).GetCountImageByLocation), arg0, arg1)
} }
// GetCountLocations mocks base method.
func (m *MockStore) GetCountLocations(arg0 context.Context, arg1 db.GetCountLocationsParams) (int32, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetCountLocations", arg0, arg1)
ret0, _ := ret[0].(int32)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetCountLocations indicates an expected call of GetCountLocations.
func (mr *MockStoreMockRecorder) GetCountLocations(arg0, arg1 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCountLocations", reflect.TypeOf((*MockStore)(nil).GetCountLocations), arg0, arg1)
}
// GetImagesByLocation mocks base method. // GetImagesByLocation mocks base method.
func (m *MockStore) GetImagesByLocation(arg0 context.Context, arg1 db.GetImagesByLocationParams) ([]db.GetImagesByLocationRow, error) { func (m *MockStore) GetImagesByLocation(arg0 context.Context, arg1 db.GetImagesByLocationParams) ([]db.GetImagesByLocationRow, error) {
m.ctrl.T.Helper() m.ctrl.T.Helper()

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.25.0 // sqlc v1.26.0
package db package db

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.25.0 // sqlc v1.26.0
// source: follow.sql // source: follow.sql
package db package db

25
db/sqlc/helper.go Normal file
View File

@ -0,0 +1,25 @@
package db
import "strings"
func IsLocationTypeValid(l string) bool {
var validLocationTypes = []LocationType{
LocationTypeAmusementpark,
LocationTypeBeach,
LocationTypeCulinary,
LocationTypeHikingCamping,
LocationTypeOther,
}
lTypes := strings.Split(l, ",")
for _, v := range validLocationTypes {
for _, k := range lTypes {
if v != LocationType(k) {
return false
}
}
}
return true
}

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.25.0 // sqlc v1.26.0
// source: images.sql // source: images.sql
package db package db

View File

@ -111,6 +111,40 @@ func (q *Queries) GetTopListLocations(ctx context.Context, arg GetTopListLocatio
return items, nil return items, nil
} }
type GetCountLocationsParams struct {
LocationTypes string `json:"location_type"`
Regency string `json:"regency"`
}
func (q *Queries) GetCountLocations(ctx context.Context, arg GetCountLocationsParams) (int32, error) {
var count int32
sqlBuilder := pgq.Select("COUNT(id)").From("locations l")
if arg.Regency != "" {
regencies := strings.Split(arg.Regency, ",")
sqlBuilder = sqlBuilder.Where(pgq.Eq{"regency_id": regencies})
}
if arg.LocationTypes != "" {
locType := strings.Split(arg.LocationTypes, ",")
sqlBuilder = sqlBuilder.Where(pgq.Eq{"l.location_type": locType})
}
query, argx, err := sqlBuilder.SQL()
if err != nil {
return 0, err
}
err = q.db.QueryRow(ctx, query, argx...).Scan(&count)
if err != nil {
return 0, err
}
return count, err
}
type GetListRecentLocationsWithRatingsRow struct { type GetListRecentLocationsWithRatingsRow struct {
ID int32 `json:"id"` ID int32 `json:"id"`
Name string `json:"name"` Name string `json:"name"`
@ -125,9 +159,10 @@ type GetListRecentLocationsWithRatingsRow struct {
} }
type GetListRecentLocationsParams struct { type GetListRecentLocationsParams struct {
Limit int32 `json:"limit" default:"12"` Limit uint64 `json:"limit" default:"15"`
Regions string `json:"regions" default:""` Regions string `json:"regions" default:""`
LocationTypes string `json:"location_type" default:""` LocationTypes string `json:"location_type" default:""`
Offset uint64 `json:"offset" default:"0"`
} }
func (q *Queries) GetListRecentLocationsWithRatings(ctx context.Context, arg GetListRecentLocationsParams) ([]GetListRecentLocationsWithRatingsRow, error) { func (q *Queries) GetListRecentLocationsWithRatings(ctx context.Context, arg GetListRecentLocationsParams) ([]GetListRecentLocationsWithRatingsRow, error) {
@ -146,7 +181,8 @@ func (q *Queries) GetListRecentLocationsWithRatings(ctx context.Context, arg Get
From("locations l"). From("locations l").
Join("regencies re on re.id = l.regency_id"). Join("regencies re on re.id = l.regency_id").
Join("provinces pr on re.province_id = pr.id"). Join("provinces pr on re.province_id = pr.id").
Limit(uint64(arg.Limit)) Limit(arg.Limit).
Offset(arg.Offset)
if arg.Regions != "" { if arg.Regions != "" {
region := strings.Split(arg.Regions, ",") region := strings.Split(arg.Regions, ",")

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.25.0 // sqlc v1.26.0
// source: locations.sql // source: locations.sql
package db package db

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.25.0 // sqlc v1.26.0
package db package db

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.25.0 // sqlc v1.26.0
// source: news_events.sql // source: news_events.sql
package db package db

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.25.0 // sqlc v1.26.0
// source: provinces.sql // source: provinces.sql
package db package db

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.25.0 // sqlc v1.26.0
package db package db

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.25.0 // sqlc v1.26.0
// source: regencies.sql // source: regencies.sql
package db package db

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.25.0 // sqlc v1.26.0
// source: regions.sql // source: regions.sql
package db package db

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.25.0 // sqlc v1.26.0
// source: reviews.sql // source: reviews.sql
package db package db

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.25.0 // sqlc v1.26.0
// source: sessions.sql // source: sessions.sql
package db package db

View File

@ -22,6 +22,7 @@ type Store interface {
CreateLocationTx(ctx context.Context, arg CreateLocationTxParams) error CreateLocationTx(ctx context.Context, arg CreateLocationTxParams) error
GetNewsEventsList(ctx context.Context, arg GetNewsEventsListParams) ([]NewsEventRow, error) GetNewsEventsList(ctx context.Context, arg GetNewsEventsListParams) ([]NewsEventRow, error)
GetListRecentLocationsWithRatings(ctx context.Context, arg GetListRecentLocationsParams) ([]GetListRecentLocationsWithRatingsRow, error) GetListRecentLocationsWithRatings(ctx context.Context, arg GetListRecentLocationsParams) ([]GetListRecentLocationsWithRatingsRow, error)
GetCountLocations(ctx context.Context, arg GetCountLocationsParams) (int32, error)
} }
type SQLStore struct { type SQLStore struct {

View File

@ -1,6 +1,6 @@
// Code generated by sqlc. DO NOT EDIT. // Code generated by sqlc. DO NOT EDIT.
// versions: // versions:
// sqlc v1.25.0 // sqlc v1.26.0
// source: users.sql // source: users.sql
package db package db

54
util/cursor.go Normal file
View File

@ -0,0 +1,54 @@
package util
import (
"encoding/base64"
"encoding/json"
"time"
)
type PaginationInfo struct {
NextCursor string `json:"next_cursor"`
PrevCursor string `json:"prev_cursor"`
}
type Cursor map[string]interface{}
func CreateCursor(id string, createdAt time.Time, pointsNext bool) Cursor {
return Cursor{
"id": id,
"created_at": createdAt,
"points_next": pointsNext,
}
}
func GeneratePager(next Cursor, prev Cursor) PaginationInfo {
return PaginationInfo{
NextCursor: encodeCursor(next),
PrevCursor: encodeCursor(prev),
}
}
func encodeCursor(cursor Cursor) string {
if len(cursor) == 0 {
return ""
}
serializedCursor, err := json.Marshal(cursor)
if err != nil {
return ""
}
encodedCursor := base64.StdEncoding.EncodeToString(serializedCursor)
return encodedCursor
}
func DecodeCursor(cursor string) (Cursor, error) {
decodedCursor, err := base64.StdEncoding.DecodeString(cursor)
if err != nil {
return nil, err
}
var cur Cursor
if err := json.Unmarshal(decodedCursor, &cur); err != nil {
return nil, err
}
return cur, nil
}