95 lines
2.6 KiB
Go
95 lines
2.6 KiB
Go
package store
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
|
|
"github.com/wotra/wotra/internal/domain"
|
|
)
|
|
|
|
// ClosedDayStore handles persistence for closed days.
|
|
type ClosedDayStore struct {
|
|
db *sql.DB
|
|
}
|
|
|
|
func NewClosedDayStore(db *sql.DB) *ClosedDayStore {
|
|
return &ClosedDayStore{db: db}
|
|
}
|
|
|
|
func (s *ClosedDayStore) Upsert(ctx context.Context, d *domain.ClosedDay) error {
|
|
_, err := s.db.ExecContext(ctx,
|
|
`INSERT INTO closed_days (day_key, start_time, end_time, worked_ms, kind, closed_at, updated_at)
|
|
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
ON CONFLICT(day_key) DO UPDATE SET
|
|
start_time=excluded.start_time, end_time=excluded.end_time,
|
|
worked_ms=excluded.worked_ms, kind=excluded.kind,
|
|
closed_at=excluded.closed_at, updated_at=excluded.updated_at`,
|
|
d.DayKey, d.StartTime, d.EndTime, d.WorkedMs, d.Kind, d.ClosedAt, d.UpdatedAt,
|
|
)
|
|
return err
|
|
}
|
|
|
|
func (s *ClosedDayStore) Delete(ctx context.Context, dayKey string) error {
|
|
_, err := s.db.ExecContext(ctx, `DELETE FROM closed_days WHERE day_key=?`, dayKey)
|
|
return err
|
|
}
|
|
|
|
func (s *ClosedDayStore) GetByDayKey(ctx context.Context, dayKey string) (*domain.ClosedDay, error) {
|
|
row := s.db.QueryRowContext(ctx,
|
|
`SELECT day_key, start_time, end_time, worked_ms, kind, closed_at, updated_at
|
|
FROM closed_days WHERE day_key=?`, dayKey)
|
|
return scanClosedDay(row)
|
|
}
|
|
|
|
func (s *ClosedDayStore) ListByDateRange(ctx context.Context, fromDayKey, toDayKey string) ([]*domain.ClosedDay, error) {
|
|
rows, err := s.db.QueryContext(ctx,
|
|
`SELECT day_key, start_time, end_time, worked_ms, kind, closed_at, updated_at
|
|
FROM closed_days WHERE day_key >= ? AND day_key <= ? ORDER BY day_key ASC`,
|
|
fromDayKey, toDayKey)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
var result []*domain.ClosedDay
|
|
for rows.Next() {
|
|
d, err := scanClosedDayRow(rows)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
result = append(result, d)
|
|
}
|
|
return result, rows.Err()
|
|
}
|
|
|
|
func scanClosedDay(row *sql.Row) (*domain.ClosedDay, error) {
|
|
var d domain.ClosedDay
|
|
var startTime, endTime sql.NullInt64
|
|
err := row.Scan(&d.DayKey, &startTime, &endTime, &d.WorkedMs, &d.Kind, &d.ClosedAt, &d.UpdatedAt)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if startTime.Valid {
|
|
d.StartTime = &startTime.Int64
|
|
}
|
|
if endTime.Valid {
|
|
d.EndTime = &endTime.Int64
|
|
}
|
|
return &d, nil
|
|
}
|
|
|
|
func scanClosedDayRow(rows *sql.Rows) (*domain.ClosedDay, error) {
|
|
var d domain.ClosedDay
|
|
var startTime, endTime sql.NullInt64
|
|
err := rows.Scan(&d.DayKey, &startTime, &endTime, &d.WorkedMs, &d.Kind, &d.ClosedAt, &d.UpdatedAt)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if startTime.Valid {
|
|
d.StartTime = &startTime.Int64
|
|
}
|
|
if endTime.Valid {
|
|
d.EndTime = &endTime.Int64
|
|
}
|
|
return &d, nil
|
|
}
|