84 lines
3.0 KiB
Go
84 lines
3.0 KiB
Go
package persistence
|
|
|
|
import (
|
|
"database/sql"
|
|
"errors"
|
|
"fmt"
|
|
"gitlab.com/offline-twitter/twitter_offline_engine/pkg/scraper"
|
|
)
|
|
|
|
type SpaceParticipant struct {
|
|
UserID scraper.UserID `db:"user_id"`
|
|
SpaceID scraper.SpaceID `db:"space_id"`
|
|
}
|
|
|
|
// Save a Space
|
|
func (p Profile) SaveSpace(s scraper.Space) error {
|
|
_, err := p.DB.NamedExec(`
|
|
insert into spaces (id, created_by_id, short_url, state, title, created_at, started_at, ended_at, updated_at,
|
|
is_available_for_replay, replay_watch_count, live_listeners_count, is_details_fetched)
|
|
values (:id, nullif(:created_by_id, 0), :short_url, :state, :title, :created_at, :started_at, :ended_at, :updated_at,
|
|
:is_available_for_replay, :replay_watch_count, :live_listeners_count, :is_details_fetched)
|
|
on conflict do update
|
|
set id=:id,
|
|
created_by_id=case when created_by_id is not null then created_by_id else nullif(:created_by_id, 0) end,
|
|
short_url=case when short_url == "" then :short_url else short_url end,
|
|
state=case when :state != "" then :state else state end,
|
|
title=case when :is_details_fetched then :title else title end,
|
|
updated_at=max(:updated_at, updated_at),
|
|
ended_at=max(:ended_at, ended_at),
|
|
is_available_for_replay=:is_available_for_replay,
|
|
replay_watch_count=:replay_watch_count,
|
|
live_listeners_count=max(:live_listeners_count, live_listeners_count),
|
|
is_details_fetched=(is_details_fetched or :is_details_fetched)
|
|
`, &s)
|
|
if err != nil {
|
|
return fmt.Errorf("Error saving space (space ID %q, value: %#v):\n %w", s.ID, s, err)
|
|
}
|
|
|
|
space_participants := []SpaceParticipant{}
|
|
for _, participant_id := range s.ParticipantIds {
|
|
space_participants = append(space_participants, SpaceParticipant{UserID: participant_id, SpaceID: s.ID})
|
|
}
|
|
if len(space_participants) > 0 {
|
|
_, err = p.DB.NamedExec(`
|
|
insert or replace into space_participants (user_id, space_id) values (:user_id, :space_id)
|
|
`, space_participants)
|
|
if err != nil {
|
|
return fmt.Errorf("Error saving participants (space ID %q, participants: %#v):\n %w", s.ID, space_participants, err)
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// Get a Space by ID
|
|
func (p Profile) GetSpaceById(id scraper.SpaceID) (space scraper.Space, err error) {
|
|
err = p.DB.Get(&space,
|
|
`select id, ifnull(created_by_id, 0) created_by_id, short_url, state, title, created_at, started_at, ended_at, updated_at,
|
|
is_available_for_replay, replay_watch_count, live_listeners_count, is_details_fetched
|
|
from spaces
|
|
where id = ?`, id)
|
|
if err != nil {
|
|
return
|
|
}
|
|
space.ParticipantIds = []scraper.UserID{}
|
|
rows, err := p.DB.Query(`select user_id from space_participants where space_id = ?`, id)
|
|
if errors.Is(err, sql.ErrNoRows) {
|
|
err = nil
|
|
}
|
|
defer rows.Close()
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
var participant_id scraper.UserID
|
|
for rows.Next() {
|
|
err = rows.Scan(&participant_id)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
space.ParticipantIds = append(space.ParticipantIds, participant_id)
|
|
}
|
|
|
|
return
|
|
}
|