Files
evening_detective_server/internal/repos/applications_repo/repo.go
T
2026-10-11 16:00:18 +07:00

148 lines
2.9 KiB
Go

// Package applications_repo provides database access for team applications.
package applications_repo
import (
"context"
"errors"
"evening_detective_server/internal/repos"
"github.com/jackc/pgx/v5/pgxpool"
)
var (
// ErrApplicationNotFound indicates that an application was not found.
ErrApplicationNotFound = errors.New("улика не найдена")
)
// ApplicationsRepo persists team applications.
type ApplicationsRepo struct {
pool *pgxpool.Pool
}
// NewApplicationsRepo creates an applications repository.
func NewApplicationsRepo(pool *pgxpool.Pool) *ApplicationsRepo {
return &ApplicationsRepo{
pool: pool,
}
}
// AddApplication stores an application for a team.
func (r *ApplicationsRepo) AddApplication(
ctx context.Context,
teamID string,
name string,
image string,
fileType string,
) (int, error) {
id := 0
err := r.pool.QueryRow(
ctx,
`INSERT INTO applications (name, image, file_type, team_id)
VALUES ($1, $2, $3, $4)
RETURNING id`,
name,
image,
fileType,
teamID,
).Scan(&id)
if err != nil {
return 0, err
}
return id, nil
}
// GetApplicationsByTeamIDsAndState returns applications matching team IDs and state.
func (r *ApplicationsRepo) GetApplicationsByTeamIDsAndState(
ctx context.Context,
teamIDs []string,
state string,
) (map[string][]*repos.Application, error) {
rows, err := r.pool.Query(
ctx,
`SELECT
name,
image,
file_type,
team_id
FROM applications
WHERE team_id = ANY($1) and status = $2`,
teamIDs,
state,
)
if err != nil {
return nil, err
}
defer rows.Close()
res := make(map[string][]*repos.Application, len(teamIDs))
for rows.Next() {
application := &repos.Application{}
err := rows.Scan(
&application.Name,
&application.Image,
&application.FileType,
&application.TeamID,
)
if err != nil {
return nil, err
}
res[application.TeamID] = append(res[application.TeamID], application)
}
if err := rows.Err(); err != nil {
return nil, err
}
return res, nil
}
// UpdateApplicationStatus changes an application's status.
func (r *ApplicationsRepo) UpdateApplicationStatus(
ctx context.Context,
teamID string,
name string,
status string,
) error {
tag, err := r.pool.Exec(
ctx,
`UPDATE applications
SET
status = $1
WHERE team_id = $2 and name = $3`,
status,
teamID,
name,
)
if err != nil {
return err
}
if tag.RowsAffected() == 0 {
return ErrApplicationNotFound
}
return nil
}
// DeleteApplicationByTeamIDAndName removes an application by team and name.
func (r *ApplicationsRepo) DeleteApplicationByTeamIDAndName(ctx context.Context, teamID string, name string) error {
tag, err := r.pool.Exec(
ctx,
`DELETE FROM applications
WHERE id IN (
SELECT id
FROM applications
WHERE team_id = $1 and name = $2
ORDER BY created_at DESC
LIMIT 1
)`,
teamID,
name,
)
if err != nil {
return err
}
if tag.RowsAffected() == 0 {
return ErrApplicationNotFound
}
return nil
}