hiling_go/db/repository/reviews.go
2026-06-16 19:38:23 +03:00

261 lines
8.8 KiB
Go
Executable File

package db
import (
"context"
"time"
"github.com/jackc/pgx/v5/pgtype"
)
const createReview = `-- name: CreateReview :one
INSERT INTO reviews (
submitted_by,
comments,
score,
is_from_critic,
is_hided,
location_id,
title
) VALUES ($1, $2, $3, $4, $5, $6, $7)
RETURNING id, submitted_by, comments, score, is_from_critic, is_hided, location_id, title, created_at, updated_at
`
type CreateReviewParams struct {
SubmittedBy int32 `json:"submitted_by"`
Comments string `json:"comments"`
Score int16 `json:"score"`
IsFromCritic bool `json:"is_from_critic"`
IsHided bool `json:"is_hided"`
LocationID int32 `json:"location_id"`
Title pgtype.Text `json:"title"`
}
func (q *Queries) CreateReview(ctx context.Context, arg CreateReviewParams) (Review, error) {
row := q.db.QueryRow(ctx, createReview,
arg.SubmittedBy,
arg.Comments,
arg.Score,
arg.IsFromCritic,
arg.IsHided,
arg.LocationID,
arg.Title,
)
var i Review
err := row.Scan(
&i.ID,
&i.SubmittedBy,
&i.Comments,
&i.Score,
&i.IsFromCritic,
&i.IsHided,
&i.LocationID,
&i.Title,
&i.CreatedAt,
&i.UpdatedAt,
)
return i, err
}
type GetListLocationReviewsParams struct {
LocationID int32 `json:"location_id"`
Limit int8 `json:"limit"`
Offset int8 `json:"offset"`
IsCritics bool `json:"is_critics"`
}
type GetListLocationReviewsRow struct {
ID int32 `json:"id"`
Title pgtype.Text `json:"title"`
Score int8 `json:"score"`
Comment string `json:"comments"`
UserID int32 `json:"user_id"`
Username string `json:"username"`
UserAvatar pgtype.Text `json:"user_avatar"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
const getListLocationReviews = `
SELECT
re.id as id,
re.title as title,
re.score as score,
re.comments as comments,
u.id as user_id,
u.username as username,
u.avatar_picture as user_avatar,
re.created_at as created_at,
re.updated_at as updated_at
FROM REVIEWS re
JOIN users u on re.submitted_by = u.id
WHERE re.location_id = $1 AND re.is_from_critic = $2
LIMIT $3
OFFSET $4;
`
type GetReviewByLocationAndIdParams struct {
ID int32 `json:"id"`
LocationID int32 `json:"location_id"`
}
type GetReviewByLocationAndId struct {
ID int32 `json:"id"`
Title pgtype.Text `json:"title"`
SubmittedBy int32 `json:"submitted_by"`
LocationID int32 `json:"location_id"`
Score int16 `json:"score"`
Comments string `json:"comments"`
CreatedAt pgtype.Timestamp `json:"created_at"`
UpdatedAt pgtype.Timestamp `json:"updated_at"`
Username string `json:"username"`
UserAvatar pgtype.Text `json:"user_avatar"`
}
const getReviewByLocationAndId = `
SELECT
re.id,
re.title,
re.submitted_by,
re.location_id,
re.score,
re.comments,
re.created_at,
re.updated_at,
u.username,
u.avatar_picture
FROM reviews re
JOIN users u on re.submitted_by = u.id
WHERE re.id = $1 AND re.location_id = $2 AND re.is_hided = false;
`
func (q *Queries) GetReviewByLocationAndId(ctx context.Context, arg GetReviewByLocationAndIdParams) (GetReviewByLocationAndId, error) {
row := q.db.QueryRow(ctx, getReviewByLocationAndId, arg.ID, arg.LocationID)
var i GetReviewByLocationAndId
err := row.Scan(
&i.ID,
&i.Title,
&i.SubmittedBy,
&i.LocationID,
&i.Score,
&i.Comments,
&i.CreatedAt,
&i.UpdatedAt,
&i.Username,
&i.UserAvatar,
)
return i, err
}
type GetLocationReviewGradesRow struct {
CriticAvgTasteGrade pgtype.Float8 `json:"critic_avg_taste_grade"`
CriticTasteGradeCount int64 `json:"critic_taste_grade_count"`
CriticAvgComfortGrade pgtype.Float8 `json:"critic_avg_comfort_grade"`
CriticComfortGradeCount int64 `json:"critic_comfort_grade_count"`
CriticAvgCleanlinessGrade pgtype.Float8 `json:"critic_avg_cleanliness_grade"`
CriticCleanlinessGradeCount int64 `json:"critic_cleanliness_grade_count"`
CriticAvgServiceGrade pgtype.Float8 `json:"critic_avg_service_grade"`
CriticServiceGradeCount int64 `json:"critic_service_grade_count"`
CriticAvgFacilitiesGrade pgtype.Float8 `json:"critic_avg_facilities_grade"`
CriticFacilitiesGradeCount int64 `json:"critic_facilities_grade_count"`
UserAvgTasteGrade pgtype.Float8 `json:"user_avg_taste_grade"`
UserTasteGradeCount int64 `json:"user_taste_grade_count"`
UserAvgComfortGrade pgtype.Float8 `json:"user_avg_comfort_grade"`
UserComfortGradeCount int64 `json:"user_comfort_grade_count"`
UserAvgCleanlinessGrade pgtype.Float8 `json:"user_avg_cleanliness_grade"`
UserCleanlinessGradeCount int64 `json:"user_cleanliness_grade_count"`
UserAvgServiceGrade pgtype.Float8 `json:"user_avg_service_grade"`
UserServiceGradeCount int64 `json:"user_service_grade_count"`
UserAvgFacilitiesGrade pgtype.Float8 `json:"user_avg_facilities_grade"`
UserFacilitiesGradeCount int64 `json:"user_facilities_grade_count"`
}
const getLocationReviewGrades = `
SELECT
AVG(re.taste_grade) FILTER (WHERE re.is_from_critic = true)::float8 AS critic_avg_taste_grade,
COUNT(re.taste_grade) FILTER (WHERE re.is_from_critic = true) AS critic_taste_grade_count,
AVG(re.comfort_grade) FILTER (WHERE re.is_from_critic = true)::float8 AS critic_avg_comfort_grade,
COUNT(re.comfort_grade) FILTER (WHERE re.is_from_critic = true) AS critic_comfort_grade_count,
AVG(re.cleanliness_grade) FILTER (WHERE re.is_from_critic = true)::float8 AS critic_avg_cleanliness_grade,
COUNT(re.cleanliness_grade) FILTER (WHERE re.is_from_critic = true) AS critic_cleanliness_grade_count,
AVG(re.service_grade) FILTER (WHERE re.is_from_critic = true)::float8 AS critic_avg_service_grade,
COUNT(re.service_grade) FILTER (WHERE re.is_from_critic = true) AS critic_service_grade_count,
AVG(re.facilities_grade) FILTER (WHERE re.is_from_critic = true)::float8 AS critic_avg_facilities_grade,
COUNT(re.facilities_grade) FILTER (WHERE re.is_from_critic = true) AS critic_facilities_grade_count,
AVG(re.taste_grade) FILTER (WHERE re.is_from_critic = false)::float8 AS user_avg_taste_grade,
COUNT(re.taste_grade) FILTER (WHERE re.is_from_critic = false) AS user_taste_grade_count,
AVG(re.comfort_grade) FILTER (WHERE re.is_from_critic = false)::float8 AS user_avg_comfort_grade,
COUNT(re.comfort_grade) FILTER (WHERE re.is_from_critic = false) AS user_comfort_grade_count,
AVG(re.cleanliness_grade) FILTER (WHERE re.is_from_critic = false)::float8 AS user_avg_cleanliness_grade,
COUNT(re.cleanliness_grade) FILTER (WHERE re.is_from_critic = false) AS user_cleanliness_grade_count,
AVG(re.service_grade) FILTER (WHERE re.is_from_critic = false)::float8 AS user_avg_service_grade,
COUNT(re.service_grade) FILTER (WHERE re.is_from_critic = false) AS user_service_grade_count,
AVG(re.facilities_grade) FILTER (WHERE re.is_from_critic = false)::float8 AS user_avg_facilities_grade,
COUNT(re.facilities_grade) FILTER (WHERE re.is_from_critic = false) AS user_facilities_grade_count
FROM reviews re
WHERE re.location_id = $1 AND re.is_hided = false;
`
func (q *Queries) GetLocationReviewGrades(ctx context.Context, locationID int32) (GetLocationReviewGradesRow, error) {
row := q.db.QueryRow(ctx, getLocationReviewGrades, locationID)
var i GetLocationReviewGradesRow
err := row.Scan(
&i.CriticAvgTasteGrade,
&i.CriticTasteGradeCount,
&i.CriticAvgComfortGrade,
&i.CriticComfortGradeCount,
&i.CriticAvgCleanlinessGrade,
&i.CriticCleanlinessGradeCount,
&i.CriticAvgServiceGrade,
&i.CriticServiceGradeCount,
&i.CriticAvgFacilitiesGrade,
&i.CriticFacilitiesGradeCount,
&i.UserAvgTasteGrade,
&i.UserTasteGradeCount,
&i.UserAvgComfortGrade,
&i.UserComfortGradeCount,
&i.UserAvgCleanlinessGrade,
&i.UserCleanlinessGradeCount,
&i.UserAvgServiceGrade,
&i.UserServiceGradeCount,
&i.UserAvgFacilitiesGrade,
&i.UserFacilitiesGradeCount,
)
return i, err
}
func (q *Queries) GetListLocationReviews(ctx context.Context, arg GetListLocationReviewsParams) ([]GetListLocationReviewsRow, error) {
rows, err := q.db.Query(ctx, getListLocationReviews, arg.LocationID, arg.IsCritics, arg.Limit, arg.Offset)
if err != nil {
return nil, err
}
defer rows.Close()
items := []GetListLocationReviewsRow{}
for rows.Next() {
var i GetListLocationReviewsRow
if err := rows.Scan(
&i.ID,
&i.Title,
&i.Score,
&i.Comment,
&i.UserID,
&i.Username,
&i.UserAvatar,
&i.CreatedAt,
&i.UpdatedAt,
); err != nil {
return nil, err
}
items = append(items, i)
}
rows.Close()
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}