| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345 |
- package postgres
- import (
- "context"
- "errors"
- "fmt"
- "time"
- "github.com/jackc/pgx/v5"
- )
- type Event struct {
- ID string
- PublicID string
- Slug string
- DisplayName string
- Summary *string
- Status string
- CurrentReleaseID *string
- CurrentReleasePubID *string
- ConfigLabel *string
- ManifestURL *string
- ManifestChecksum *string
- RouteCode *string
- }
- type EventRelease struct {
- ID string
- PublicID string
- EventID string
- ReleaseNo int
- ConfigLabel string
- ManifestURL string
- ManifestChecksum *string
- RouteCode *string
- BuildID *string
- Status string
- PublishedAt time.Time
- }
- type CreateGameSessionParams struct {
- SessionPublicID string
- UserID string
- EventID string
- EventReleaseID string
- DeviceKey string
- ClientType string
- RouteCode *string
- SessionTokenHash string
- SessionTokenExpiresAt time.Time
- }
- type GameSession struct {
- ID string
- SessionPublicID string
- UserID string
- EventID string
- EventReleaseID string
- DeviceKey string
- ClientType string
- RouteCode *string
- Status string
- SessionTokenExpiresAt time.Time
- }
- func (s *Store) GetEventByPublicID(ctx context.Context, eventPublicID string) (*Event, error) {
- row := s.pool.QueryRow(ctx, `
- SELECT
- e.id,
- e.event_public_id,
- e.slug,
- e.display_name,
- e.summary,
- e.status,
- e.current_release_id,
- er.release_public_id,
- er.config_label,
- er.manifest_url,
- er.manifest_checksum_sha256,
- er.route_code
- FROM events e
- LEFT JOIN event_releases er ON er.id = e.current_release_id
- WHERE e.event_public_id = $1
- LIMIT 1
- `, eventPublicID)
- var event Event
- err := row.Scan(
- &event.ID,
- &event.PublicID,
- &event.Slug,
- &event.DisplayName,
- &event.Summary,
- &event.Status,
- &event.CurrentReleaseID,
- &event.CurrentReleasePubID,
- &event.ConfigLabel,
- &event.ManifestURL,
- &event.ManifestChecksum,
- &event.RouteCode,
- )
- if errors.Is(err, pgx.ErrNoRows) {
- return nil, nil
- }
- if err != nil {
- return nil, fmt.Errorf("get event by public id: %w", err)
- }
- return &event, nil
- }
- func (s *Store) GetEventByID(ctx context.Context, eventID string) (*Event, error) {
- row := s.pool.QueryRow(ctx, `
- SELECT
- e.id,
- e.event_public_id,
- e.slug,
- e.display_name,
- e.summary,
- e.status,
- e.current_release_id,
- er.release_public_id,
- er.config_label,
- er.manifest_url,
- er.manifest_checksum_sha256,
- er.route_code
- FROM events e
- LEFT JOIN event_releases er ON er.id = e.current_release_id
- WHERE e.id = $1
- LIMIT 1
- `, eventID)
- var event Event
- err := row.Scan(
- &event.ID,
- &event.PublicID,
- &event.Slug,
- &event.DisplayName,
- &event.Summary,
- &event.Status,
- &event.CurrentReleaseID,
- &event.CurrentReleasePubID,
- &event.ConfigLabel,
- &event.ManifestURL,
- &event.ManifestChecksum,
- &event.RouteCode,
- )
- if errors.Is(err, pgx.ErrNoRows) {
- return nil, nil
- }
- if err != nil {
- return nil, fmt.Errorf("get event by id: %w", err)
- }
- return &event, nil
- }
- func (s *Store) NextEventReleaseNo(ctx context.Context, eventID string) (int, error) {
- var next int
- if err := s.pool.QueryRow(ctx, `
- SELECT COALESCE(MAX(release_no), 0) + 1
- FROM event_releases
- WHERE event_id = $1
- `, eventID).Scan(&next); err != nil {
- return 0, fmt.Errorf("next event release no: %w", err)
- }
- return next, nil
- }
- type CreateEventReleaseParams struct {
- PublicID string
- EventID string
- ReleaseNo int
- ConfigLabel string
- ManifestURL string
- ManifestChecksum *string
- RouteCode *string
- BuildID *string
- Status string
- PayloadJSON string
- }
- func (s *Store) CreateEventRelease(ctx context.Context, tx Tx, params CreateEventReleaseParams) (*EventRelease, error) {
- row := tx.QueryRow(ctx, `
- INSERT INTO event_releases (
- release_public_id,
- event_id,
- release_no,
- config_label,
- manifest_url,
- manifest_checksum_sha256,
- route_code,
- build_id,
- status,
- payload_jsonb
- )
- VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10::jsonb)
- RETURNING id, release_public_id, event_id, release_no, config_label, manifest_url, manifest_checksum_sha256, route_code, build_id, status, published_at
- `, params.PublicID, params.EventID, params.ReleaseNo, params.ConfigLabel, params.ManifestURL, params.ManifestChecksum, params.RouteCode, params.BuildID, params.Status, params.PayloadJSON)
- var item EventRelease
- if err := row.Scan(
- &item.ID,
- &item.PublicID,
- &item.EventID,
- &item.ReleaseNo,
- &item.ConfigLabel,
- &item.ManifestURL,
- &item.ManifestChecksum,
- &item.RouteCode,
- &item.BuildID,
- &item.Status,
- &item.PublishedAt,
- ); err != nil {
- return nil, fmt.Errorf("create event release: %w", err)
- }
- return &item, nil
- }
- func (s *Store) SetCurrentEventRelease(ctx context.Context, tx Tx, eventID, releaseID string) error {
- if _, err := tx.Exec(ctx, `
- UPDATE events
- SET current_release_id = $2
- WHERE id = $1
- `, eventID, releaseID); err != nil {
- return fmt.Errorf("set current event release: %w", err)
- }
- return nil
- }
- func (s *Store) CreateGameSession(ctx context.Context, tx Tx, params CreateGameSessionParams) (*GameSession, error) {
- row := tx.QueryRow(ctx, `
- INSERT INTO game_sessions (
- session_public_id,
- user_id,
- event_id,
- event_release_id,
- device_key,
- client_type,
- route_code,
- session_token_hash,
- session_token_expires_at
- )
- VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)
- RETURNING id, session_public_id, user_id, event_id, event_release_id, device_key, client_type, route_code, status, session_token_expires_at
- `, params.SessionPublicID, params.UserID, params.EventID, params.EventReleaseID, params.DeviceKey, params.ClientType, params.RouteCode, params.SessionTokenHash, params.SessionTokenExpiresAt)
- var session GameSession
- err := row.Scan(
- &session.ID,
- &session.SessionPublicID,
- &session.UserID,
- &session.EventID,
- &session.EventReleaseID,
- &session.DeviceKey,
- &session.ClientType,
- &session.RouteCode,
- &session.Status,
- &session.SessionTokenExpiresAt,
- )
- if err != nil {
- return nil, fmt.Errorf("create game session: %w", err)
- }
- return &session, nil
- }
- func (s *Store) ListEventReleasesByEventID(ctx context.Context, eventID string, limit int) ([]EventRelease, error) {
- if limit <= 0 || limit > 100 {
- limit = 20
- }
- rows, err := s.pool.Query(ctx, `
- SELECT id, release_public_id, event_id, release_no, config_label, manifest_url, manifest_checksum_sha256, route_code, build_id, status, published_at
- FROM event_releases
- WHERE event_id = $1
- ORDER BY release_no DESC
- LIMIT $2
- `, eventID, limit)
- if err != nil {
- return nil, fmt.Errorf("list event releases by event id: %w", err)
- }
- defer rows.Close()
- items := []EventRelease{}
- for rows.Next() {
- item, err := scanEventReleaseFromRows(rows)
- if err != nil {
- return nil, err
- }
- items = append(items, *item)
- }
- if err := rows.Err(); err != nil {
- return nil, fmt.Errorf("iterate event releases by event id: %w", err)
- }
- return items, nil
- }
- func (s *Store) GetEventReleaseByPublicID(ctx context.Context, releasePublicID string) (*EventRelease, error) {
- row := s.pool.QueryRow(ctx, `
- SELECT id, release_public_id, event_id, release_no, config_label, manifest_url, manifest_checksum_sha256, route_code, build_id, status, published_at
- FROM event_releases
- WHERE release_public_id = $1
- LIMIT 1
- `, releasePublicID)
- var item EventRelease
- err := row.Scan(
- &item.ID,
- &item.PublicID,
- &item.EventID,
- &item.ReleaseNo,
- &item.ConfigLabel,
- &item.ManifestURL,
- &item.ManifestChecksum,
- &item.RouteCode,
- &item.BuildID,
- &item.Status,
- &item.PublishedAt,
- )
- if errors.Is(err, pgx.ErrNoRows) {
- return nil, nil
- }
- if err != nil {
- return nil, fmt.Errorf("get event release by public id: %w", err)
- }
- return &item, nil
- }
- func scanEventReleaseFromRows(rows pgx.Rows) (*EventRelease, error) {
- var item EventRelease
- err := rows.Scan(
- &item.ID,
- &item.PublicID,
- &item.EventID,
- &item.ReleaseNo,
- &item.ConfigLabel,
- &item.ManifestURL,
- &item.ManifestChecksum,
- &item.RouteCode,
- &item.BuildID,
- &item.Status,
- &item.PublishedAt,
- )
- if err != nil {
- return nil, fmt.Errorf("scan event release row: %w", err)
- }
- return &item, nil
- }
|