package scenarios_repo import ( "context" "errors" "evening_detective_server/internal/repos" "github.com/jackc/pgx/v5" "github.com/jackc/pgx/v5/pgxpool" ) var ( ErrScenarioNotFound = errors.New("Сценарий не найден") ) type ScenariosRepo struct { pool *pgxpool.Pool } func NewScenariosRepo(pool *pgxpool.Pool) *ScenariosRepo { return &ScenariosRepo{ pool: pool, } } func (s *ScenariosRepo) AddScenario( ctx context.Context, name string, authorId int, ) (int, error) { id := 0 err := s.pool.QueryRow( ctx, `INSERT INTO scenarios (name, author_id) VALUES ($1, $2) RETURNING id`, name, authorId, ).Scan(&id) if err != nil { return 0, err } return id, nil } func (s *ScenariosRepo) GetScenariosByAuthorID( ctx context.Context, authorId int, ) ([]*repos.Scenario, error) { rows, err := s.pool.Query( ctx, `SELECT scenarios.id, scenarios.name, scenarios.description, scenarios.image, scenarios.scenario, users.id, users.username, scenarios.status, scenarios.updated_at, scenarios.created_at, scenarios.published_at FROM scenarios LEFT JOIN users on scenarios.author_id = users.id WHERE scenarios.author_id = $1 and is_deleted = FALSE ORDER BY created_at DESC`, authorId, ) if err != nil { return nil, err } defer rows.Close() var scenarios []*repos.Scenario for rows.Next() { scenario := &repos.Scenario{ Author: &repos.User{}, } err := rows.Scan( &scenario.ID, &scenario.Name, &scenario.Description, &scenario.Image, &scenario.Scenario, &scenario.Author.ID, &scenario.Author.Username, &scenario.Status, &scenario.UpdatedAt, &scenario.CreatedAt, &scenario.PublishedAt, ) if err != nil { return nil, err } scenarios = append(scenarios, scenario) } if err := rows.Err(); err != nil { return nil, err } return scenarios, nil } func (s *ScenariosRepo) GetScenariosByStatus( ctx context.Context, status string, ) ([]*repos.Scenario, error) { rows, err := s.pool.Query( ctx, `SELECT scenarios.id, scenarios.name, scenarios.description, scenarios.image, scenarios.scenario, users.id, users.username, scenarios.status, scenarios.updated_at, scenarios.created_at, scenarios.published_at FROM scenarios LEFT JOIN users on scenarios.author_id = users.id WHERE scenarios.status = $1 and is_deleted = FALSE ORDER BY created_at DESC`, status, ) if err != nil { return nil, err } defer rows.Close() var scenarios []*repos.Scenario for rows.Next() { scenario := &repos.Scenario{ Author: &repos.User{}, } err := rows.Scan( &scenario.ID, &scenario.Name, &scenario.Description, &scenario.Image, &scenario.Scenario, &scenario.Author.ID, &scenario.Author.Username, &scenario.Status, &scenario.UpdatedAt, &scenario.CreatedAt, &scenario.PublishedAt, ) if err != nil { return nil, err } scenarios = append(scenarios, scenario) } if err := rows.Err(); err != nil { return nil, err } return scenarios, nil } func (s *ScenariosRepo) GetScenarioByID( ctx context.Context, id int, ) (*repos.Scenario, error) { scenario := &repos.Scenario{ Author: &repos.User{}, } row := s.pool.QueryRow( ctx, `SELECT scenarios.id, scenarios.name, scenarios.description, scenarios.image, scenarios.scenario, users.id, users.username, scenarios.status, scenarios.updated_at, scenarios.created_at, scenarios.published_at, scenarios.is_deleted FROM scenarios LEFT JOIN users on scenarios.author_id = users.id WHERE scenarios.id = $1`, id, ) err := row.Scan( &scenario.ID, &scenario.Name, &scenario.Description, &scenario.Image, &scenario.Scenario, &scenario.Author.ID, &scenario.Author.Username, &scenario.Status, &scenario.UpdatedAt, &scenario.CreatedAt, &scenario.PublishedAt, &scenario.IsDeleted, ) if err != nil { if errors.Is(err, pgx.ErrNoRows) { return nil, ErrScenarioNotFound } return nil, err } return scenario, nil } func (s *ScenariosRepo) UpdateScenarioByID( ctx context.Context, id int, name string, description string, image string, ) error { tag, err := s.pool.Exec( ctx, `UPDATE scenarios SET name = $1, description = $2, image = $3, updated_at = NOW() WHERE id = $4`, name, description, image, id, ) if err != nil { return err } if tag.RowsAffected() == 0 { return ErrScenarioNotFound } return nil } func (s *ScenariosRepo) UpdateScenarioStatusByID( ctx context.Context, id int, status string, ) error { tag, err := s.pool.Exec( ctx, `UPDATE scenarios SET status = $1, published_at = NOW(), updated_at = NOW() WHERE id = $2`, status, id, ) if err != nil { return err } if tag.RowsAffected() == 0 { return ErrScenarioNotFound } return nil } func (s *ScenariosRepo) DeleteScenarioByID( ctx context.Context, id int, ) error { tag, err := s.pool.Exec( ctx, `UPDATE scenarios SET is_deleted = TRUE WHERE id = $1`, id, ) if err != nil { return err } if tag.RowsAffected() == 0 { return ErrScenarioNotFound } return nil } func (s *ScenariosRepo) GetStoryByScenarioID( ctx context.Context, id int, ) (string, error) { story := "" row := s.pool.QueryRow( ctx, `SELECT scenario FROM scenarios WHERE scenarios.id = $1`, id, ) err := row.Scan( &story, ) if err != nil { if errors.Is(err, pgx.ErrNoRows) { return "", ErrScenarioNotFound } return "", err } return story, nil } func (s *ScenariosRepo) UpdateStoryByScenarioID( ctx context.Context, id int, story string, ) error { tag, err := s.pool.Exec( ctx, `UPDATE scenarios SET scenario = $1, updated_at = NOW() WHERE id = $2`, story, id, ) if err != nil { return err } if tag.RowsAffected() == 0 { return ErrScenarioNotFound } return nil }