package postgres import ( "context" "botpontos/internal/domain" ) func readHoliday(row scanner) (domain.Holiday, error) { var h domain.Holiday err := row.Scan(&h.Day, &h.Name, &h.Source) return h, mapErr(err) } func (s *Store) IsHoliday(ctx context.Context, day string) (bool, error) { var exists bool err := s.pool.QueryRow(ctx, `SELECT EXISTS (SELECT 1 FROM holidays WHERE day = $1::text::date)`, day).Scan(&exists) return exists, err } func (s *Store) HasSyncedHolidays(ctx context.Context, year int) (bool, error) { var exists bool err := s.pool.QueryRow(ctx, ` SELECT EXISTS ( SELECT 1 FROM holidays WHERE source <> 'manual' AND day >= make_date($1::int, 1, 1) AND day < make_date($1::int + 1, 1, 1) )`, year).Scan(&exists) return exists, err } func (s *Store) ListHolidays(ctx context.Context, year int) ([]domain.Holiday, error) { rows, err := s.pool.Query(ctx, ` SELECT to_char(day, 'YYYY-MM-DD'), name, source FROM holidays WHERE day >= make_date($1::int, 1, 1) AND day < make_date($1::int + 1, 1, 1) ORDER BY day`, year) return collect(rows, err, readHoliday) } // InsertHolidays grava os feriados da API sem sobrescrever datas existentes // (feriados manuais nunca são substituídos). Devolve quantos foram inseridos. func (s *Store) InsertHolidays(ctx context.Context, holidays []domain.Holiday) (int64, error) { var inserted int64 err := s.inTx(ctx, func(q querier) error { for _, h := range holidays { tag, err := q.Exec(ctx, ` INSERT INTO holidays (day, name, source) VALUES ($1::text::date, $2, $3) ON CONFLICT (day) DO NOTHING`, h.Day, h.Name, h.Source) if err != nil { return err } inserted += tag.RowsAffected() } return nil }) return inserted, err } func (s *Store) AddHoliday(ctx context.Context, h domain.Holiday) error { _, err := s.pool.Exec(ctx, `INSERT INTO holidays (day, name, source) VALUES ($1::text::date, $2, $3)`, h.Day, h.Name, h.Source) return mapErr(err) } // DeleteManualHoliday remove só feriados cadastrados manualmente. func (s *Store) DeleteManualHoliday(ctx context.Context, day string) error { return expectOne(s.pool.Exec(ctx, `DELETE FROM holidays WHERE day = $1::text::date AND source = 'manual'`, day)) }