feat(m1): backend scaffold - entries CRUD, start/stop, auth, migrations
This commit is contained in:
94
internal/store/closed_day_store.go
Normal file
94
internal/store/closed_day_store.go
Normal file
@@ -0,0 +1,94 @@
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user