mirror of
https://github.com/AmanTahiliani/box-box.git
synced 2026-08-07 19:56:18 -04:00
Add local-first refactor foundation
This commit is contained in:
295
internal/store/meetings.go
Normal file
295
internal/store/meetings.go
Normal file
@@ -0,0 +1,295 @@
|
||||
package store
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
// UpsertMeeting inserts or updates a meeting by meeting_key.
|
||||
func (s *Store) UpsertMeeting(m Meeting) error {
|
||||
if m.UpdatedAt.IsZero() {
|
||||
m.UpdatedAt = time.Now()
|
||||
}
|
||||
|
||||
_, err := s.db.Exec(`
|
||||
INSERT INTO meetings (
|
||||
meeting_key, meeting_name, meeting_official_name, location,
|
||||
country_code, country_name, circuit_key, circuit_short_name,
|
||||
gmt_offset, date_start, date_end, year, updated_at
|
||||
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
ON CONFLICT(meeting_key) DO UPDATE SET
|
||||
meeting_name = excluded.meeting_name,
|
||||
meeting_official_name = excluded.meeting_official_name,
|
||||
location = excluded.location,
|
||||
country_code = excluded.country_code,
|
||||
country_name = excluded.country_name,
|
||||
circuit_key = excluded.circuit_key,
|
||||
circuit_short_name = excluded.circuit_short_name,
|
||||
gmt_offset = excluded.gmt_offset,
|
||||
date_start = excluded.date_start,
|
||||
date_end = excluded.date_end,
|
||||
year = excluded.year,
|
||||
updated_at = excluded.updated_at
|
||||
`,
|
||||
m.MeetingKey,
|
||||
m.MeetingName,
|
||||
nullString(m.MeetingOfficialName),
|
||||
nullString(m.Location),
|
||||
nullString(m.CountryCode),
|
||||
nullString(m.CountryName),
|
||||
nullableZeroInt(m.CircuitKey),
|
||||
nullString(m.CircuitShortName),
|
||||
nullString(m.GMTOffset),
|
||||
nullString(m.DateStart),
|
||||
nullString(m.DateEnd),
|
||||
m.Year,
|
||||
m.UpdatedAt.Unix(),
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("upsert meeting: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetMeeting returns a meeting by key.
|
||||
func (s *Store) GetMeeting(meetingKey int) (Meeting, error) {
|
||||
var m Meeting
|
||||
var updatedAt int64
|
||||
var officialName, location, countryCode, countryName sql.NullString
|
||||
var circuitKey sql.NullInt64
|
||||
var circuitShortName, gmtOffset, dateStart, dateEnd sql.NullString
|
||||
|
||||
err := s.db.QueryRow(`
|
||||
SELECT meeting_key, meeting_name, meeting_official_name, location,
|
||||
country_code, country_name, circuit_key, circuit_short_name,
|
||||
gmt_offset, date_start, date_end, year, updated_at
|
||||
FROM meetings
|
||||
WHERE meeting_key = ?
|
||||
`, meetingKey).Scan(
|
||||
&m.MeetingKey,
|
||||
&m.MeetingName,
|
||||
&officialName,
|
||||
&location,
|
||||
&countryCode,
|
||||
&countryName,
|
||||
&circuitKey,
|
||||
&circuitShortName,
|
||||
&gmtOffset,
|
||||
&dateStart,
|
||||
&dateEnd,
|
||||
&m.Year,
|
||||
&updatedAt,
|
||||
)
|
||||
if err != nil {
|
||||
return Meeting{}, err
|
||||
}
|
||||
|
||||
m.MeetingOfficialName = officialName.String
|
||||
m.Location = location.String
|
||||
m.CountryCode = countryCode.String
|
||||
m.CountryName = countryName.String
|
||||
if circuitKey.Valid {
|
||||
m.CircuitKey = int(circuitKey.Int64)
|
||||
}
|
||||
m.CircuitShortName = circuitShortName.String
|
||||
m.GMTOffset = gmtOffset.String
|
||||
m.DateStart = dateStart.String
|
||||
m.DateEnd = dateEnd.String
|
||||
m.UpdatedAt = time.Unix(updatedAt, 0)
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// ListMeetingsByYear returns meetings for a season ordered by start date.
|
||||
func (s *Store) ListMeetingsByYear(year int) ([]Meeting, error) {
|
||||
rows, err := s.db.Query(`
|
||||
SELECT meeting_key, meeting_name, meeting_official_name, location,
|
||||
country_code, country_name, circuit_key, circuit_short_name,
|
||||
gmt_offset, date_start, date_end, year, updated_at
|
||||
FROM meetings
|
||||
WHERE year = ?
|
||||
ORDER BY date_start ASC, meeting_key ASC
|
||||
`, year)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
return scanMeetings(rows)
|
||||
}
|
||||
|
||||
// UpsertSession inserts or updates a session by session_key.
|
||||
func (s *Store) UpsertSession(sess Session) error {
|
||||
if sess.UpdatedAt.IsZero() {
|
||||
sess.UpdatedAt = time.Now()
|
||||
}
|
||||
|
||||
_, err := s.db.Exec(`
|
||||
INSERT INTO sessions (
|
||||
session_key, meeting_key, session_name, session_type,
|
||||
circuit_key, date_start, date_end, gmt_offset, updated_at
|
||||
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
ON CONFLICT(session_key) DO UPDATE SET
|
||||
meeting_key = excluded.meeting_key,
|
||||
session_name = excluded.session_name,
|
||||
session_type = excluded.session_type,
|
||||
circuit_key = excluded.circuit_key,
|
||||
date_start = excluded.date_start,
|
||||
date_end = excluded.date_end,
|
||||
gmt_offset = excluded.gmt_offset,
|
||||
updated_at = excluded.updated_at
|
||||
`,
|
||||
sess.SessionKey,
|
||||
sess.MeetingKey,
|
||||
sess.SessionName,
|
||||
sess.SessionType,
|
||||
nullableZeroInt(sess.CircuitKey),
|
||||
nullString(sess.DateStart),
|
||||
nullString(sess.DateEnd),
|
||||
nullString(sess.GMTOffset),
|
||||
sess.UpdatedAt.Unix(),
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("upsert session: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetSession returns a session by key.
|
||||
func (s *Store) GetSession(sessionKey int) (Session, error) {
|
||||
var sess Session
|
||||
var updatedAt int64
|
||||
var circuitKey sql.NullInt64
|
||||
var dateStart, dateEnd, gmtOffset sql.NullString
|
||||
|
||||
err := s.db.QueryRow(`
|
||||
SELECT session_key, meeting_key, session_name, session_type,
|
||||
circuit_key, date_start, date_end, gmt_offset, updated_at
|
||||
FROM sessions
|
||||
WHERE session_key = ?
|
||||
`, sessionKey).Scan(
|
||||
&sess.SessionKey,
|
||||
&sess.MeetingKey,
|
||||
&sess.SessionName,
|
||||
&sess.SessionType,
|
||||
&circuitKey,
|
||||
&dateStart,
|
||||
&dateEnd,
|
||||
&gmtOffset,
|
||||
&updatedAt,
|
||||
)
|
||||
if err != nil {
|
||||
return Session{}, err
|
||||
}
|
||||
|
||||
if circuitKey.Valid {
|
||||
sess.CircuitKey = int(circuitKey.Int64)
|
||||
}
|
||||
sess.DateStart = dateStart.String
|
||||
sess.DateEnd = dateEnd.String
|
||||
sess.GMTOffset = gmtOffset.String
|
||||
sess.UpdatedAt = time.Unix(updatedAt, 0)
|
||||
return sess, nil
|
||||
}
|
||||
|
||||
// ListSessionsByMeeting returns sessions for a meeting ordered by start time.
|
||||
func (s *Store) ListSessionsByMeeting(meetingKey int) ([]Session, error) {
|
||||
rows, err := s.db.Query(`
|
||||
SELECT session_key, meeting_key, session_name, session_type,
|
||||
circuit_key, date_start, date_end, gmt_offset, updated_at
|
||||
FROM sessions
|
||||
WHERE meeting_key = ?
|
||||
ORDER BY date_start ASC, session_key ASC
|
||||
`, meetingKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
return scanSessions(rows)
|
||||
}
|
||||
|
||||
func scanMeetings(rows *sql.Rows) ([]Meeting, error) {
|
||||
var out []Meeting
|
||||
for rows.Next() {
|
||||
var m Meeting
|
||||
var updatedAt int64
|
||||
var officialName, location, countryCode, countryName sql.NullString
|
||||
var circuitKey sql.NullInt64
|
||||
var circuitShortName, gmtOffset, dateStart, dateEnd sql.NullString
|
||||
|
||||
if err := rows.Scan(
|
||||
&m.MeetingKey,
|
||||
&m.MeetingName,
|
||||
&officialName,
|
||||
&location,
|
||||
&countryCode,
|
||||
&countryName,
|
||||
&circuitKey,
|
||||
&circuitShortName,
|
||||
&gmtOffset,
|
||||
&dateStart,
|
||||
&dateEnd,
|
||||
&m.Year,
|
||||
&updatedAt,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
m.MeetingOfficialName = officialName.String
|
||||
m.Location = location.String
|
||||
m.CountryCode = countryCode.String
|
||||
m.CountryName = countryName.String
|
||||
if circuitKey.Valid {
|
||||
m.CircuitKey = int(circuitKey.Int64)
|
||||
}
|
||||
m.CircuitShortName = circuitShortName.String
|
||||
m.GMTOffset = gmtOffset.String
|
||||
m.DateStart = dateStart.String
|
||||
m.DateEnd = dateEnd.String
|
||||
m.UpdatedAt = time.Unix(updatedAt, 0)
|
||||
out = append(out, m)
|
||||
}
|
||||
return out, rows.Err()
|
||||
}
|
||||
|
||||
func scanSessions(rows *sql.Rows) ([]Session, error) {
|
||||
var out []Session
|
||||
for rows.Next() {
|
||||
var sess Session
|
||||
var updatedAt int64
|
||||
var circuitKey sql.NullInt64
|
||||
var dateStart, dateEnd, gmtOffset sql.NullString
|
||||
|
||||
if err := rows.Scan(
|
||||
&sess.SessionKey,
|
||||
&sess.MeetingKey,
|
||||
&sess.SessionName,
|
||||
&sess.SessionType,
|
||||
&circuitKey,
|
||||
&dateStart,
|
||||
&dateEnd,
|
||||
&gmtOffset,
|
||||
&updatedAt,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if circuitKey.Valid {
|
||||
sess.CircuitKey = int(circuitKey.Int64)
|
||||
}
|
||||
sess.DateStart = dateStart.String
|
||||
sess.DateEnd = dateEnd.String
|
||||
sess.GMTOffset = gmtOffset.String
|
||||
sess.UpdatedAt = time.Unix(updatedAt, 0)
|
||||
out = append(out, sess)
|
||||
}
|
||||
return out, rows.Err()
|
||||
}
|
||||
|
||||
func nullableZeroInt(v int) any {
|
||||
if v == 0 {
|
||||
return nil
|
||||
}
|
||||
return v
|
||||
}
|
||||
Reference in New Issue
Block a user