mirror of
https://github.com/AmanTahiliani/box-box.git
synced 2026-08-07 11:54:59 -04:00
296 lines
7.3 KiB
Go
296 lines
7.3 KiB
Go
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
|
|
}
|