cursor location
This commit is contained in:
parent
3bd611a8a2
commit
28d8774280
@ -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
2
data.ms/VERSION
Executable file → Normal file
@ -1 +1 @@
|
|||||||
1.6.0
|
1.8.0
|
BIN
data.ms/auth/data.mdb
Executable file → Normal file
BIN
data.ms/auth/data.mdb
Executable file → Normal file
Binary file not shown.
BIN
data.ms/auth/lock.mdb
Executable file → Normal file
BIN
data.ms/auth/lock.mdb
Executable file → Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
2
data.ms/instance-uid
Executable file → Normal file
2
data.ms/instance-uid
Executable file → Normal file
@ -1 +1 @@
|
|||||||
3db8a6fc-efe2-4e2e-a2ca-2de2e6914f2a
|
864514bc-7376-4dbe-83ac-1a1c43681252
|
BIN
data.ms/tasks/data.mdb
Executable file → Normal file
BIN
data.ms/tasks/data.mdb
Executable file → Normal file
Binary file not shown.
BIN
data.ms/tasks/lock.mdb
Executable file → Normal file
BIN
data.ms/tasks/lock.mdb
Executable file → Normal file
Binary file not shown.
@ -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()
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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
25
db/sqlc/helper.go
Normal 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
|
||||||
|
}
|
@ -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
|
||||||
|
@ -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, ",")
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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 {
|
||||||
|
@ -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
54
util/cursor.go
Normal 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
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user