Feat: room and actions repos
This commit is contained in:
10
go.mod
10
go.mod
@ -4,5 +4,15 @@ go 1.24
|
|||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/BurntSushi/toml v1.5.0
|
github.com/BurntSushi/toml v1.5.0
|
||||||
|
github.com/jackc/pgx/v5 v5.7.5
|
||||||
github.com/rs/xid v1.6.0
|
github.com/rs/xid v1.6.0
|
||||||
)
|
)
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/jackc/pgpassfile v1.0.0 // indirect
|
||||||
|
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
|
||||||
|
github.com/jackc/puddle/v2 v2.2.2 // indirect
|
||||||
|
golang.org/x/crypto v0.37.0 // indirect
|
||||||
|
golang.org/x/sync v0.13.0 // indirect
|
||||||
|
golang.org/x/text v0.24.0 // indirect
|
||||||
|
)
|
||||||
|
28
go.sum
28
go.sum
@ -1,4 +1,32 @@
|
|||||||
github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg=
|
github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg=
|
||||||
github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
|
github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
|
||||||
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
|
||||||
|
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
|
||||||
|
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo=
|
||||||
|
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
|
||||||
|
github.com/jackc/pgx/v5 v5.7.5 h1:JHGfMnQY+IEtGM63d+NGMjoRpysB2JBwDr5fsngwmJs=
|
||||||
|
github.com/jackc/pgx/v5 v5.7.5/go.mod h1:aruU7o91Tc2q2cFp5h4uP3f6ztExVpyVv88Xl/8Vl8M=
|
||||||
|
github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo=
|
||||||
|
github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/rs/xid v1.6.0 h1:fV591PaemRlL6JfRxGDEPl69wICngIQ3shQtzfy2gxU=
|
github.com/rs/xid v1.6.0 h1:fV591PaemRlL6JfRxGDEPl69wICngIQ3shQtzfy2gxU=
|
||||||
github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0=
|
github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0=
|
||||||
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
|
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
|
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
|
||||||
|
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||||
|
golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE=
|
||||||
|
golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc=
|
||||||
|
golang.org/x/sync v0.13.0 h1:AauUjRAJ9OSnvULf/ARrrVywoJDy0YS2AwQ98I37610=
|
||||||
|
golang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
||||||
|
golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0=
|
||||||
|
golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
@ -70,33 +70,33 @@ type CardMark struct {
|
|||||||
|
|
||||||
type Room struct {
|
type Room struct {
|
||||||
ID string `json:"id" db:"id"`
|
ID string `json:"id" db:"id"`
|
||||||
CreatedAt time.Time `json:"created_at" db:"created_at"` // limit?
|
CreatedAt time.Time `json:"created_at" db:"created_at"`
|
||||||
RoomLink string
|
CreatorName string `json:"creator_name" db:"creator_name"`
|
||||||
CreatorName string `json:"creator_name"`
|
TeamTurn UserTeam `db:"team_turn"`
|
||||||
ActionHistory []Action
|
ThisTurnLimit uint8 `db:"this_turn_limit"`
|
||||||
TeamTurn UserTeam
|
OpenedThisTurn uint8 `db:"opened_this_turn"`
|
||||||
RedTeam Team
|
BlueCounter uint8 `db:"blue_counter"`
|
||||||
BlueTeam Team
|
RedCounter uint8 `db:"red_counter"`
|
||||||
Cards []WordCard
|
RedTurn bool `db:"red_turn"`
|
||||||
ThisTurnLimit uint8 // how many cards guessers can open this turn
|
MimeDone bool `db:"mime_done"`
|
||||||
OpenedThisTurn uint8 // how many cards have been opened this turn
|
IsPublic bool `db:"is_public"`
|
||||||
WCMap map[string]WordColor
|
IsRunning bool `json:"is_running" db:"is_running"`
|
||||||
BotMap map[string]BotPlayer // key is bot name
|
Language string `json:"language" example:"en" form:"language" db:"language"`
|
||||||
BlueCounter uint8
|
RoundTime uint32 `json:"round_time" db:"round_time"`
|
||||||
RedCounter uint8
|
IsOver bool `db:"is_over"`
|
||||||
RedTurn bool // false is blue turn
|
TeamWon UserTeam `db:"team_won"`
|
||||||
MimeDone bool
|
RoomPass string `json:"room_pass" db:"room_pass"`
|
||||||
IsPublic bool
|
// fields not in db
|
||||||
IsRunning bool `json:"is_running"`
|
RoomLink string `db:"-"`
|
||||||
Language string `json:"language" example:"en" form:"language"`
|
ActionHistory []Action `db:"-"`
|
||||||
RoundTime int32 `json:"round_time"`
|
RedTeam Team `db:"-"`
|
||||||
IsOver bool
|
BlueTeam Team `db:"-"`
|
||||||
TeamWon UserTeam // blue | red
|
Cards []WordCard `db:"-"`
|
||||||
//
|
WCMap map[string]WordColor `db:"-"`
|
||||||
Mark CardMark // card is marked
|
BotMap map[string]BotPlayer `db:"-"`
|
||||||
// needed for debug
|
Mark CardMark `db:"-"`
|
||||||
LogJournal []string
|
LogJournal []string `db:"-"`
|
||||||
Settings GameSettings
|
Settings GameSettings `db:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Room) ClearMarks() {
|
func (r *Room) ClearMarks() {
|
||||||
@ -325,10 +325,10 @@ type WordCard struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type GameSettings struct {
|
type GameSettings struct {
|
||||||
Language string `json:"language" example:"en" form:"language"`
|
Language string `json:"language" example:"en" form:"language" db:"language"`
|
||||||
RoomPass string `json:"room_pass"`
|
RoomPass string `json:"room_pass" db:"room_pass"`
|
||||||
TurnSecondsLeft uint32
|
TurnSecondsLeft uint32 `db:"-"`
|
||||||
RoundTime uint32
|
RoundTime uint32 `json:"round_time" db:"round_time"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// =====
|
// =====
|
||||||
@ -343,19 +343,14 @@ type RoomReq struct {
|
|||||||
|
|
||||||
func (rr *RoomReq) CreateRoom(creator string) *Room {
|
func (rr *RoomReq) CreateRoom(creator string) *Room {
|
||||||
roomID := xid.New().String()
|
roomID := xid.New().String()
|
||||||
settings := GameSettings{
|
|
||||||
Language: rr.Language,
|
|
||||||
RoomPass: rr.RoomPass,
|
|
||||||
RoundTime: rr.RoundTime,
|
|
||||||
}
|
|
||||||
return &Room{
|
return &Room{
|
||||||
// RoomName: ,
|
ID: roomID,
|
||||||
ID: roomID,
|
CreatedAt: time.Now(),
|
||||||
CreatedAt: time.Now(),
|
|
||||||
// PlayerList: []string{creator},
|
|
||||||
CreatorName: creator,
|
CreatorName: creator,
|
||||||
|
Language: rr.Language,
|
||||||
|
RoundTime: rr.RoundTime,
|
||||||
|
RoomPass: rr.RoomPass,
|
||||||
BotMap: make(map[string]BotPlayer),
|
BotMap: make(map[string]BotPlayer),
|
||||||
Settings: settings,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
46
repos/actions.go
Normal file
46
repos/actions.go
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
package repos
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"gralias/models"
|
||||||
|
|
||||||
|
"github.com/jackc/pgx/v5"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ActionsRepo interface {
|
||||||
|
ListActions(ctx context.Context, roomID string) ([]models.Action, error)
|
||||||
|
CreateAction(ctx context.Context, roomID string, action *models.Action) error
|
||||||
|
GetLastClue(ctx context.Context, roomID string) (*models.Action, error)
|
||||||
|
DeleteActionsByRoomID(ctx context.Context, roomID string) error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *RepoProvider) ListActions(ctx context.Context, roomID string) ([]models.Action, error) {
|
||||||
|
rows, err := p.DB.Query(ctx, `SELECT actor, actor_color, action_type, word, word_color, number_associated FROM actions WHERE room_id = $1 ORDER BY created_at ASC`, roomID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return pgx.CollectRows(rows, pgx.RowToStructByName[models.Action])
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *RepoProvider) CreateAction(ctx context.Context, roomID string, a *models.Action) error {
|
||||||
|
_, err := p.DB.Exec(ctx, `INSERT INTO actions (room_id, actor, actor_color, action_type, word, word_color, number_associated) VALUES ($1, $2, $3, $4, $5, $6, $7)`,
|
||||||
|
roomID, a.Actor, a.ActorColor, a.Action, a.Word, a.WordColor, a.Number)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *RepoProvider) GetLastClue(ctx context.Context, roomID string) (*models.Action, error) {
|
||||||
|
rows, err := p.DB.Query(ctx, `SELECT actor, actor_color, action_type, word, word_color, number_associated FROM actions WHERE room_id = $1 AND action_type = 'gave_clue' ORDER BY created_at DESC LIMIT 1`, roomID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
action, err := pgx.CollectOneRow(rows, pgx.RowToStructByName[models.Action])
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &action, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *RepoProvider) DeleteActionsByRoomID(ctx context.Context, roomID string) error {
|
||||||
|
_, err := p.DB.Exec(ctx, `DELETE FROM actions WHERE room_id = $1`, roomID)
|
||||||
|
return err
|
||||||
|
}
|
@ -1,9 +1,11 @@
|
|||||||
package repos
|
package repos
|
||||||
|
|
||||||
|
import "github.com/jackc/pgx/v5/pgxpool"
|
||||||
|
|
||||||
type AllRepos interface {
|
type AllRepos interface {
|
||||||
RoomsRepo
|
RoomsRepo
|
||||||
}
|
}
|
||||||
|
|
||||||
type RepoProvider struct {
|
type RepoProvider struct {
|
||||||
// db connection
|
DB *pgxpool.Pool
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,55 @@
|
|||||||
package repos
|
package repos
|
||||||
|
|
||||||
import "gralias/models"
|
import (
|
||||||
|
"context"
|
||||||
|
"gralias/models"
|
||||||
|
|
||||||
|
"github.com/jackc/pgx/v5"
|
||||||
|
)
|
||||||
|
|
||||||
type RoomsRepo interface {
|
type RoomsRepo interface {
|
||||||
ListRooms() ([]models.Room, error)
|
ListRooms(ctx context.Context) ([]models.Room, error)
|
||||||
GetRoomByID(id string) (*models.Room, error)
|
GetRoomByID(ctx context.Context, id string) (*models.Room, error)
|
||||||
CreateRoom(room *models.Room) error
|
CreateRoom(ctx context.Context, room *models.Room) error
|
||||||
DeleteRoomByID(id string) error
|
DeleteRoomByID(ctx context.Context, id string) error
|
||||||
|
UpdateRoom(ctx context.Context, room *models.Room) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// provider implementation
|
func (p *RepoProvider) ListRooms(ctx context.Context) ([]models.Room, error) {
|
||||||
func (p RepoProvider) ListRooms() ([]models.Room, error) {
|
rows, err := p.DB.Query(ctx, `SELECT * FROM rooms`)
|
||||||
return nil, nil
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
rooms, err := pgx.CollectRows(rows, pgx.RowToStructByName[models.Room])
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return rooms, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *RepoProvider) GetRoomByID(ctx context.Context, id string) (*models.Room, error) {
|
||||||
|
rows, err := p.DB.Query(ctx, `SELECT * FROM rooms WHERE id = $1`, id)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
room, err := pgx.CollectOneRow(rows, pgx.RowToStructByName[models.Room])
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &room, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *RepoProvider) CreateRoom(ctx context.Context, r *models.Room) error {
|
||||||
|
_, err := p.DB.Exec(ctx, `INSERT INTO rooms (id, created_at, creator_name, team_turn, this_turn_limit, opened_this_turn, blue_counter, red_counter, red_turn, mime_done, is_public, is_running, language, round_time, is_over, team_won, room_pass) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17)`, r.ID, r.CreatedAt, r.CreatorName, r.TeamTurn, r.ThisTurnLimit, r.OpenedThisTurn, r.BlueCounter, r.RedCounter, r.RedTurn, r.MimeDone, r.IsPublic, r.IsRunning, r.Language, r.RoundTime, r.IsOver, r.TeamWon, r.Settings.RoomPass)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *RepoProvider) DeleteRoomByID(ctx context.Context, id string) error {
|
||||||
|
_, err := p.DB.Exec(ctx, `DELETE FROM rooms WHERE id = $1`, id)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *RepoProvider) UpdateRoom(ctx context.Context, r *models.Room) error {
|
||||||
|
_, err := p.DB.Exec(ctx, `UPDATE rooms SET team_turn = $1, this_turn_limit = $2, opened_this_turn = $3, blue_counter = $4, red_counter = $5, red_turn = $6, mime_done = $7, is_public = $8, is_running = $9, language = $10, round_time = $11, is_over = $12, team_won = $13, room_pass = $14 WHERE id = $15`, r.TeamTurn, r.ThisTurnLimit, r.OpenedThisTurn, r.BlueCounter, r.RedCounter, r.RedTurn, r.MimeDone, r.IsPublic, r.IsRunning, r.Language, r.RoundTime, r.IsOver, r.TeamWon, r.Settings.RoomPass, r.ID)
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user