generated from VLADIMIR/template
fix
This commit is contained in:
@@ -12,6 +12,8 @@ import (
|
||||
var (
|
||||
ErrReviewNotFound = errors.New("Отзыв не найден")
|
||||
ErrReviewExists = errors.New("Отзыв от команды уже оставлен")
|
||||
ErrTeamNotFound = errors.New("Команда не найдена")
|
||||
ErrInvalidStatus = errors.New("Недопустимый статус модерации")
|
||||
)
|
||||
|
||||
type Review struct {
|
||||
@@ -28,40 +30,63 @@ type Review struct {
|
||||
|
||||
type Repo struct{ pool *pgxpool.Pool }
|
||||
|
||||
func New(pool *pgxpool.Pool) *Repo { return &Repo{pool: pool} }
|
||||
func NewGameReviewsRepo(pool *pgxpool.Pool) *Repo { return &Repo{pool: pool} }
|
||||
|
||||
func (r *Repo) Create(ctx context.Context, gameID, teamID int, rating int32, text string) (*Review, error) {
|
||||
review := &Review{}
|
||||
err := r.pool.QueryRow(ctx, `
|
||||
err := r.pool.QueryRow(
|
||||
ctx,
|
||||
`
|
||||
INSERT INTO game_reviews (game_id, team_id, rating, text)
|
||||
SELECT $1, t.id, $3, $4 FROM teams t WHERE t.id = $2 AND t.game_id = $1
|
||||
SELECT $1, t.id, $3, $4
|
||||
FROM teams t
|
||||
WHERE t.id = $2 AND t.game_id = $1
|
||||
ON CONFLICT (game_id, team_id) DO NOTHING
|
||||
RETURNING id, game_id, team_id, rating, text, status, created_at`, gameID, teamID, rating, text).Scan(
|
||||
RETURNING id, game_id, team_id, rating, text, status, created_at`,
|
||||
gameID,
|
||||
teamID,
|
||||
rating,
|
||||
text,
|
||||
).Scan(
|
||||
&review.ID, &review.GameID, &review.TeamID, &review.Rating, &review.Text, &review.Status, &review.CreatedAt)
|
||||
if errors.Is(err, pgx.ErrNoRows) {
|
||||
var exists bool
|
||||
if err := r.pool.QueryRow(ctx, `SELECT EXISTS (SELECT 1 FROM game_reviews WHERE game_id=$1 AND team_id=$2)`, gameID, teamID).Scan(&exists); err != nil {
|
||||
if err := r.pool.QueryRow(
|
||||
ctx,
|
||||
`SELECT EXISTS (
|
||||
SELECT 1
|
||||
FROM game_reviews
|
||||
WHERE game_id = $1 AND team_id = $2
|
||||
)`,
|
||||
gameID,
|
||||
teamID,
|
||||
).Scan(&exists); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if exists {
|
||||
return nil, ErrReviewExists
|
||||
}
|
||||
return nil, errors.New("Команда не найдена")
|
||||
return nil, ErrTeamNotFound
|
||||
}
|
||||
return review, err
|
||||
}
|
||||
|
||||
func (r *Repo) GetByID(ctx context.Context, id int) (*Review, error) {
|
||||
return r.queryOne(ctx, `WHERE r.id=$1`, id)
|
||||
return r.queryOne(ctx, id)
|
||||
}
|
||||
|
||||
func (r *Repo) List(ctx context.Context, gameID int, all bool) ([]*Review, float64, int32, error) {
|
||||
where := "r.game_id=$1 AND r.status='approved'"
|
||||
if all {
|
||||
where = "r.game_id=$1"
|
||||
}
|
||||
rows, err := r.pool.Query(ctx, `SELECT r.id,r.game_id,r.team_id,t.name,g.name,r.rating,r.text,r.status,r.created_at
|
||||
FROM game_reviews r JOIN teams t ON t.id=r.team_id JOIN games g ON g.id=r.game_id WHERE `+where+` ORDER BY r.created_at DESC`, gameID)
|
||||
rows, err := r.pool.Query(
|
||||
ctx,
|
||||
`SELECT r.id, r.game_id, r.team_id, t.name, g.name, r.rating, r.text, r.status, r.created_at
|
||||
FROM game_reviews r
|
||||
JOIN teams t ON t.id = r.team_id
|
||||
JOIN games g ON g.id = r.game_id
|
||||
WHERE r.game_id = $1 AND ($2 OR r.status = 'approved')
|
||||
ORDER BY r.created_at DESC`,
|
||||
gameID,
|
||||
all,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, 0, 0, err
|
||||
}
|
||||
@@ -79,16 +104,27 @@ func (r *Repo) List(ctx context.Context, gameID int, all bool) ([]*Review, float
|
||||
}
|
||||
var average float64
|
||||
var count int64
|
||||
if err := r.pool.QueryRow(ctx, `SELECT COALESCE(AVG(rating),0), COUNT(*) FROM game_reviews WHERE game_id=$1 AND status='approved'`, gameID).Scan(&average, &count); err != nil {
|
||||
if err := r.pool.QueryRow(
|
||||
ctx,
|
||||
`SELECT COALESCE(AVG(rating), 0), COUNT(*)
|
||||
FROM game_reviews
|
||||
WHERE game_id = $1 AND status = 'approved'`,
|
||||
gameID,
|
||||
).Scan(&average, &count); err != nil {
|
||||
return nil, 0, 0, err
|
||||
}
|
||||
return reviews, average, int32(count), nil
|
||||
}
|
||||
|
||||
func (r *Repo) ListForModeration(ctx context.Context) ([]*Review, error) {
|
||||
rows, err := r.pool.Query(ctx, `SELECT r.id,r.game_id,r.team_id,t.name,g.name,r.rating,r.text,r.status,r.created_at
|
||||
FROM game_reviews r JOIN teams t ON t.id=r.team_id JOIN games g ON g.id=r.game_id
|
||||
ORDER BY CASE WHEN r.status='pending' THEN 0 ELSE 1 END, r.created_at ASC`)
|
||||
rows, err := r.pool.Query(
|
||||
ctx,
|
||||
`SELECT r.id, r.game_id, r.team_id, t.name, g.name, r.rating, r.text, r.status, r.created_at
|
||||
FROM game_reviews r
|
||||
JOIN teams t ON t.id = r.team_id
|
||||
JOIN games g ON g.id = r.game_id
|
||||
ORDER BY CASE WHEN r.status = 'pending' THEN 0 ELSE 1 END, r.created_at ASC`,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -105,34 +141,51 @@ func (r *Repo) ListForModeration(ctx context.Context) ([]*Review, error) {
|
||||
}
|
||||
|
||||
func (r *Repo) Moderate(ctx context.Context, id int, status string) (*Review, error) {
|
||||
review, err := r.queryOne(ctx, `WHERE r.id=$1`, id)
|
||||
if status != "approved" && status != "rejected" && status != "hidden" {
|
||||
return nil, ErrInvalidStatus
|
||||
}
|
||||
if _, err := r.queryOne(ctx, id); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_, err := r.pool.Exec(
|
||||
ctx,
|
||||
`UPDATE game_reviews
|
||||
SET status = $2, moderated_at = NOW()
|
||||
WHERE id = $1`,
|
||||
id,
|
||||
status,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if status == "approved" || status == "rejected" || status == "hidden" {
|
||||
_, err = r.pool.Exec(ctx, `UPDATE game_reviews SET status=$2, moderated_at=NOW() WHERE id=$1`, id, status)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return r.queryOne(ctx, `WHERE r.id=$1`, id)
|
||||
}
|
||||
return review, errors.New("Недопустимый статус модерации")
|
||||
return r.queryOne(ctx, id)
|
||||
}
|
||||
|
||||
func (r *Repo) ScenarioRating(ctx context.Context, scenarioID int) (float64, int32, error) {
|
||||
var average float64
|
||||
var count int64
|
||||
err := r.pool.QueryRow(ctx, `SELECT COALESCE(AVG(r.rating),0), COUNT(*)
|
||||
FROM game_reviews r JOIN games g ON g.id=r.game_id
|
||||
WHERE g.scenario_id=$1 AND g.status='finish' AND r.status='approved'`, scenarioID).Scan(&average, &count)
|
||||
err := r.pool.QueryRow(
|
||||
ctx,
|
||||
`SELECT COALESCE(AVG(r.rating), 0), COUNT(*)
|
||||
FROM game_reviews r
|
||||
JOIN games g ON g.id = r.game_id
|
||||
WHERE g.scenario_id = $1 AND g.status = 'finish' AND r.status = 'approved'`,
|
||||
scenarioID,
|
||||
).Scan(&average, &count)
|
||||
return average, int32(count), err
|
||||
}
|
||||
|
||||
func (r *Repo) ListByScenario(ctx context.Context, scenarioID int) ([]*Review, float64, int32, error) {
|
||||
rows, err := r.pool.Query(ctx, `SELECT r.id,r.game_id,r.team_id,t.name,g.name,r.rating,r.text,r.status,r.created_at
|
||||
FROM game_reviews r JOIN teams t ON t.id=r.team_id JOIN games g ON g.id=r.game_id
|
||||
WHERE g.scenario_id=$1 AND g.status='finish' AND r.status='approved'
|
||||
ORDER BY r.created_at DESC`, scenarioID)
|
||||
rows, err := r.pool.Query(
|
||||
ctx,
|
||||
`SELECT r.id, r.game_id, r.team_id, t.name, g.name, r.rating, r.text, r.status, r.created_at
|
||||
FROM game_reviews r
|
||||
JOIN teams t ON t.id = r.team_id
|
||||
JOIN games g ON g.id = r.game_id
|
||||
WHERE g.scenario_id = $1 AND g.status = 'finish' AND r.status = 'approved'
|
||||
ORDER BY r.created_at DESC`,
|
||||
scenarioID,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, 0, 0, err
|
||||
}
|
||||
@@ -152,10 +205,17 @@ func (r *Repo) ListByScenario(ctx context.Context, scenarioID int) ([]*Review, f
|
||||
return reviews, average, count, err
|
||||
}
|
||||
|
||||
func (r *Repo) queryOne(ctx context.Context, condition string, id int) (*Review, error) {
|
||||
func (r *Repo) queryOne(ctx context.Context, id int) (*Review, error) {
|
||||
review := &Review{}
|
||||
err := r.pool.QueryRow(ctx, `SELECT r.id,r.game_id,r.team_id,t.name,g.name,r.rating,r.text,r.status,r.created_at
|
||||
FROM game_reviews r JOIN teams t ON t.id=r.team_id JOIN games g ON g.id=r.game_id `+condition, id).Scan(
|
||||
err := r.pool.QueryRow(
|
||||
ctx,
|
||||
`SELECT r.id, r.game_id, r.team_id, t.name, g.name, r.rating, r.text, r.status, r.created_at
|
||||
FROM game_reviews r
|
||||
JOIN teams t ON t.id = r.team_id
|
||||
JOIN games g ON g.id = r.game_id
|
||||
WHERE r.id = $1`,
|
||||
id,
|
||||
).Scan(
|
||||
&review.ID, &review.GameID, &review.TeamID, &review.TeamName, &review.GameName, &review.Rating, &review.Text, &review.Status, &review.CreatedAt)
|
||||
if errors.Is(err, pgx.ErrNoRows) {
|
||||
return nil, ErrReviewNotFound
|
||||
|
||||
Reference in New Issue
Block a user