add images
This commit is contained in:
parent
a866730e37
commit
d05a9671ee
44
api/image.go
Normal file
44
api/image.go
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
db "git.nochill.in/nochill/hiling_go/db/sqlc"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
type getAllImagesReq struct {
|
||||||
|
Page int32 `form:"page" binding:"required,min=1"`
|
||||||
|
PageSize int32 `form:"page_size" binding:"required,min=5"`
|
||||||
|
LocationId int32 `form:"location_id" binding:"required,numeric"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (server *Server) getAllImagesByLocation(ctx *gin.Context) {
|
||||||
|
var req getAllImagesReq
|
||||||
|
if err := ctx.BindQuery(&req); err != nil {
|
||||||
|
ctx.JSON(http.StatusBadRequest, ValidationErrorResponse(err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
arg := db.GetImagesByLocationParams{
|
||||||
|
Limit: req.PageSize,
|
||||||
|
Offset: (req.Page - 1) * req.PageSize,
|
||||||
|
LocationId: req.LocationId,
|
||||||
|
}
|
||||||
|
|
||||||
|
count, err := server.Store.GetCountImageByLocation(ctx, arg.LocationId)
|
||||||
|
if err != nil {
|
||||||
|
ctx.JSON(http.StatusInternalServerError, ErrorResponse(err, "Something went wrong"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
images, err := server.Store.GetImagesByLocation(ctx, arg)
|
||||||
|
if err != nil {
|
||||||
|
ctx.JSON(http.StatusInternalServerError, ErrorResponse(err, "Something went wrong"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ctx.JSON(http.StatusOK, gin.H{
|
||||||
|
"total_image": count,
|
||||||
|
"images": images,
|
||||||
|
})
|
||||||
|
}
|
@ -46,6 +46,9 @@ func (server *Server) getRoutes() {
|
|||||||
router.GET("/locations", server.getListLocations)
|
router.GET("/locations", server.getListLocations)
|
||||||
router.GET("/location/:location_id", server.getLocation)
|
router.GET("/location/:location_id", server.getLocation)
|
||||||
|
|
||||||
|
//IMAGES
|
||||||
|
router.GET("/images/location", server.getAllImagesByLocation)
|
||||||
|
|
||||||
server.Router = router
|
server.Router = router
|
||||||
}
|
}
|
||||||
|
|
||||||
|
8
db/csv_seeder/images.csv
Normal file
8
db/csv_seeder/images.csv
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
id,image_url,uploaded_by,image_type,image_of
|
||||||
|
1#https://dynamic-media-cdn.tripadvisor.com/media/photo-o/1b/ee/b0/7b/murni-s-warung-shop-ubud.jpg?w=1200&h=-1&s=1#1#ocations#1
|
||||||
|
2#https://dynamic-media-cdn.tripadvisor.com/media/photo-o/1b/4f/fc/65/getlstd-property-photo.jpg?w=1100&h=-1&s=1#1#locations#1
|
||||||
|
3#https://dynamic-media-cdn.tripadvisor.com/media/photo-o/1b/ee/b0/43/murni-s-warung-shop-ubud.jpg?w=1200&h=-1&s=1#1#locations#1
|
||||||
|
4#https://dynamic-media-cdn.tripadvisor.com/media/photo-o/1b/ee/af/d0/murni-s-warung-shop-ubud.jpg?w=1200&h=-1&s=1#1#locations#1
|
||||||
|
5#https://dynamic-media-cdn.tripadvisor.com/media/photo-o/04/0f/7e/53/istiqlal-mosque-mesjid.jpg?w=1200&h=-1&s=1#1#locations#2
|
||||||
|
6#https://dynamic-media-cdn.tripadvisor.com/media/photo-o/28/27/1a/5a/istiqlal-mosque.jpg?w=1200&h=-1&s=1#1#locations#2
|
||||||
|
7#https://dynamic-media-cdn.tripadvisor.com/media/photo-o/28/27/1a/5a/istiqlal-mosque.jpg?w=1200&h=-1&s=1#1#locations#2
|
|
1
db/migrations/000004_create_images_table.down.sql
Normal file
1
db/migrations/000004_create_images_table.down.sql
Normal file
@ -0,0 +1 @@
|
|||||||
|
DROP TABLE IF EXISTS images;
|
9
db/migrations/000004_create_images_table.up.sql
Normal file
9
db/migrations/000004_create_images_table.up.sql
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
CREATE TABLE images(
|
||||||
|
id serial primary key not null,
|
||||||
|
image_url varchar not null,
|
||||||
|
uploaded_by integer references "users"("id") not null,
|
||||||
|
image_type varchar not null, -- Locations, Stories
|
||||||
|
image_of integer not null, -- Location_id, stories_id
|
||||||
|
created_at timestamp default (now()) not null,
|
||||||
|
updated_at timestamp default (now()) not null
|
||||||
|
);
|
@ -64,6 +64,36 @@ func (mr *MockStoreMockRecorder) CreateUser(arg0, arg1 interface{}) *gomock.Call
|
|||||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateUser", reflect.TypeOf((*MockStore)(nil).CreateUser), arg0, arg1)
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateUser", reflect.TypeOf((*MockStore)(nil).CreateUser), arg0, arg1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetCountImageByLocation mocks base method.
|
||||||
|
func (m *MockStore) GetCountImageByLocation(arg0 context.Context, arg1 int32) (int64, error) {
|
||||||
|
m.ctrl.T.Helper()
|
||||||
|
ret := m.ctrl.Call(m, "GetCountImageByLocation", arg0, arg1)
|
||||||
|
ret0, _ := ret[0].(int64)
|
||||||
|
ret1, _ := ret[1].(error)
|
||||||
|
return ret0, ret1
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetCountImageByLocation indicates an expected call of GetCountImageByLocation.
|
||||||
|
func (mr *MockStoreMockRecorder) GetCountImageByLocation(arg0, arg1 interface{}) *gomock.Call {
|
||||||
|
mr.mock.ctrl.T.Helper()
|
||||||
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCountImageByLocation", reflect.TypeOf((*MockStore)(nil).GetCountImageByLocation), arg0, arg1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetImagesByLocation mocks base method.
|
||||||
|
func (m *MockStore) GetImagesByLocation(arg0 context.Context, arg1 db.GetImagesByLocationParams) ([]db.GetImagesByLocationRow, error) {
|
||||||
|
m.ctrl.T.Helper()
|
||||||
|
ret := m.ctrl.Call(m, "GetImagesByLocation", arg0, arg1)
|
||||||
|
ret0, _ := ret[0].([]db.GetImagesByLocationRow)
|
||||||
|
ret1, _ := ret[1].(error)
|
||||||
|
return ret0, ret1
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetImagesByLocation indicates an expected call of GetImagesByLocation.
|
||||||
|
func (mr *MockStoreMockRecorder) GetImagesByLocation(arg0, arg1 interface{}) *gomock.Call {
|
||||||
|
mr.mock.ctrl.T.Helper()
|
||||||
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetImagesByLocation", reflect.TypeOf((*MockStore)(nil).GetImagesByLocation), arg0, arg1)
|
||||||
|
}
|
||||||
|
|
||||||
// GetListLocations mocks base method.
|
// GetListLocations mocks base method.
|
||||||
func (m *MockStore) GetListLocations(arg0 context.Context) ([]db.Location, error) {
|
func (m *MockStore) GetListLocations(arg0 context.Context) ([]db.Location, error) {
|
||||||
m.ctrl.T.Helper()
|
m.ctrl.T.Helper()
|
||||||
@ -95,10 +125,10 @@ func (mr *MockStoreMockRecorder) GetListRecentLocationsWithRatings(arg0, arg1 in
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetLocation mocks base method.
|
// GetLocation mocks base method.
|
||||||
func (m *MockStore) GetLocation(arg0 context.Context, arg1 int32) (db.Location, error) {
|
func (m *MockStore) GetLocation(arg0 context.Context, arg1 int32) (db.GetLocationRow, error) {
|
||||||
m.ctrl.T.Helper()
|
m.ctrl.T.Helper()
|
||||||
ret := m.ctrl.Call(m, "GetLocation", arg0, arg1)
|
ret := m.ctrl.Call(m, "GetLocation", arg0, arg1)
|
||||||
ret0, _ := ret[0].(db.Location)
|
ret0, _ := ret[0].(db.GetLocationRow)
|
||||||
ret1, _ := ret[1].(error)
|
ret1, _ := ret[1].(error)
|
||||||
return ret0, ret1
|
return ret0, ret1
|
||||||
}
|
}
|
||||||
|
6
db/queries/images.sql
Normal file
6
db/queries/images.sql
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
-- name: GetCountImageByLocation :one
|
||||||
|
SELECT
|
||||||
|
COUNT(id)
|
||||||
|
FROM images
|
||||||
|
WHERE image_type = 'locations'
|
||||||
|
AND image_of = $1;
|
61
db/sqlc/images.go
Normal file
61
db/sqlc/images.go
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
package db
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type GetImagesByLocationParams struct {
|
||||||
|
Limit int32
|
||||||
|
Offset int32
|
||||||
|
LocationId int32
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetImagesByLocationRow struct {
|
||||||
|
ID int32 `json:"id"`
|
||||||
|
Src string `json:"src"`
|
||||||
|
CreatedAt time.Time `json:"created_at"`
|
||||||
|
UploadedBy string `json:"uploaded_by"`
|
||||||
|
}
|
||||||
|
|
||||||
|
const getImagesByLocationQ = `
|
||||||
|
SELECT
|
||||||
|
i.id,
|
||||||
|
i.image_url as src,
|
||||||
|
i.created_at,
|
||||||
|
u.username as uploaded_by
|
||||||
|
FROM images i
|
||||||
|
JOIN users u on i.uploaded_by = u.id
|
||||||
|
WHERE i.image_type = 'locations' AND image_of = $1
|
||||||
|
LIMIT $2
|
||||||
|
OFFSET $3
|
||||||
|
`
|
||||||
|
|
||||||
|
func (q *Queries) GetImagesByLocation(ctx context.Context, arg GetImagesByLocationParams) ([]GetImagesByLocationRow, error) {
|
||||||
|
rows, err := q.db.QueryContext(ctx, getImagesByLocationQ, arg.LocationId, arg.Limit, arg.Offset)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
items := []GetImagesByLocationRow{}
|
||||||
|
for rows.Next() {
|
||||||
|
var i GetImagesByLocationRow
|
||||||
|
if err := rows.Scan(
|
||||||
|
&i.ID,
|
||||||
|
&i.Src,
|
||||||
|
&i.CreatedAt,
|
||||||
|
&i.UploadedBy,
|
||||||
|
); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
items = append(items, i)
|
||||||
|
}
|
||||||
|
if err := rows.Close(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := rows.Err(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return items, nil
|
||||||
|
}
|
25
db/sqlc/images.sql.go
Normal file
25
db/sqlc/images.sql.go
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
// Code generated by sqlc. DO NOT EDIT.
|
||||||
|
// versions:
|
||||||
|
// sqlc v1.20.0
|
||||||
|
// source: images.sql
|
||||||
|
|
||||||
|
package db
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
)
|
||||||
|
|
||||||
|
const getCountImageByLocation = `-- name: GetCountImageByLocation :one
|
||||||
|
SELECT
|
||||||
|
COUNT(id)
|
||||||
|
FROM images
|
||||||
|
WHERE image_type = 'locations'
|
||||||
|
AND image_of = $1
|
||||||
|
`
|
||||||
|
|
||||||
|
func (q *Queries) GetCountImageByLocation(ctx context.Context, imageOf int32) (int64, error) {
|
||||||
|
row := q.db.QueryRowContext(ctx, getCountImageByLocation, imageOf)
|
||||||
|
var count int64
|
||||||
|
err := row.Scan(&count)
|
||||||
|
return count, err
|
||||||
|
}
|
@ -124,6 +124,16 @@ type Comment struct {
|
|||||||
UpdatedAt sql.NullTime `json:"updated_at"`
|
UpdatedAt sql.NullTime `json:"updated_at"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Image struct {
|
||||||
|
ID int32 `json:"id"`
|
||||||
|
ImageUrl string `json:"image_url"`
|
||||||
|
UploadedBy int32 `json:"uploaded_by"`
|
||||||
|
ImageType string `json:"image_type"`
|
||||||
|
ImageOf int32 `json:"image_of"`
|
||||||
|
CreatedAt time.Time `json:"created_at"`
|
||||||
|
UpdatedAt time.Time `json:"updated_at"`
|
||||||
|
}
|
||||||
|
|
||||||
type Location struct {
|
type Location struct {
|
||||||
ID int32 `json:"id"`
|
ID int32 `json:"id"`
|
||||||
Address string `json:"address"`
|
Address string `json:"address"`
|
||||||
@ -187,10 +197,10 @@ type Review struct {
|
|||||||
type Tag struct {
|
type Tag struct {
|
||||||
ID int32 `json:"id"`
|
ID int32 `json:"id"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
|
SubmittedBy int32 `json:"submitted_by"`
|
||||||
TargetID sql.NullInt32 `json:"target_id"`
|
TargetID sql.NullInt32 `json:"target_id"`
|
||||||
TagsType sql.NullString `json:"tags_type"`
|
TagsType sql.NullString `json:"tags_type"`
|
||||||
CreatedAt sql.NullTime `json:"created_at"`
|
ApprovedBy int32 `json:"approved_by"`
|
||||||
UpdatedAt sql.NullTime `json:"updated_at"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type User struct {
|
type User struct {
|
||||||
@ -213,6 +223,17 @@ type User struct {
|
|||||||
UpdatedAt sql.NullTime `json:"updated_at"`
|
UpdatedAt sql.NullTime `json:"updated_at"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type UserActivity struct {
|
||||||
|
ID int32 `json:"id"`
|
||||||
|
TargetID int32 `json:"target_id"`
|
||||||
|
Target string `json:"target"`
|
||||||
|
Action string `json:"action"`
|
||||||
|
Link sql.NullString `json:"link"`
|
||||||
|
Comment sql.NullString `json:"comment"`
|
||||||
|
CreatedAt time.Time `json:"created_at"`
|
||||||
|
UpdatedAt time.Time `json:"updated_at"`
|
||||||
|
}
|
||||||
|
|
||||||
type UserReport struct {
|
type UserReport struct {
|
||||||
ID int32 `json:"id"`
|
ID int32 `json:"id"`
|
||||||
Message string `json:"message"`
|
Message string `json:"message"`
|
||||||
|
@ -11,9 +11,10 @@ import (
|
|||||||
type Querier interface {
|
type Querier interface {
|
||||||
CreateLocation(ctx context.Context, arg CreateLocationParams) error
|
CreateLocation(ctx context.Context, arg CreateLocationParams) error
|
||||||
CreateUser(ctx context.Context, arg CreateUserParams) (User, error)
|
CreateUser(ctx context.Context, arg CreateUserParams) (User, error)
|
||||||
|
GetCountImageByLocation(ctx context.Context, imageOf int32) (int64, error)
|
||||||
GetListLocations(ctx context.Context) ([]Location, error)
|
GetListLocations(ctx context.Context) ([]Location, error)
|
||||||
GetListRecentLocationsWithRatings(ctx context.Context, limit int32) ([]GetListRecentLocationsWithRatingsRow, error)
|
GetListRecentLocationsWithRatings(ctx context.Context, limit int32) ([]GetListRecentLocationsWithRatingsRow, error)
|
||||||
GetLocation(ctx context.Context, id int32) (Location, error)
|
GetLocation(ctx context.Context, id int32) (GetLocationRow, 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)
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@ import (
|
|||||||
type Store interface {
|
type Store interface {
|
||||||
Querier
|
Querier
|
||||||
GetTopListLocations(ctx context.Context, arg GetTopListLocationsParams) ([]GetTopListLocationsRow, error)
|
GetTopListLocations(ctx context.Context, arg GetTopListLocationsParams) ([]GetTopListLocationsRow, error)
|
||||||
|
GetImagesByLocation(ctx context.Context, arg GetImagesByLocationParams) ([]GetImagesByLocationRow, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type SQLStore struct {
|
type SQLStore struct {
|
||||||
|
Loading…
Reference in New Issue
Block a user