Stage 3: game domain (lifecycle, journal+cache, hint, word-check, GCG, stats)
Tests · Go / test (push) Successful in 6s
Tests · Integration / integration (push) Successful in 8s
Tests · Go / test (pull_request) Successful in 5s
Tests · Integration / integration (pull_request) Successful in 8s

internal/game drives the engine over a single match and owns everything the
engine does not: event-sourced persistence (a games row + an append-only decoded
move journal, with the live engine.Game kept warm in a cache and rebuilt by
replay on a miss), the play/pass/exchange/resign transitions with
validate-at-submit scoring, an unlimited score/legality preview, the hint
(per-game allowance + profile wallet), the word-check tool with complaint
capture, per-player game state, history and GCG export (Poslfit dialect), and a
background turn-timeout sweeper that auto-resigns overdue turns honouring each
player's daily away window. Like Stages 1-2 it is a service/store layer with no
HTTP; the gateway surface lands in Stage 6.

Engine: additive decoded domain API (Direction, SubmitPlay/SubmitExchange/
EvaluatePlay/HintView/Hand, MoveRecord.{Dir,MainRow,MainCol}, Registry.Lookup,
ParseVariant) so internal/game never imports scrabble-solver; and a Resign fix
so the resigner keeps their score yet never wins (the other player wins a
two-player game). Timeout reuses Resign.

Persistence: migration 00002 adds games, game_players, game_moves, complaints,
account_stats and extends accounts with away_start/away_end/hint_balance; go-jet
regenerated. account gained SpendHint. Config adds BACKEND_DICT_DIR (required),
BACKEND_DICT_VERSION, BACKEND_GAME_TIMEOUT_SWEEP_INTERVAL, BACKEND_GAME_CACHE_TTL;
main loads the registry at boot (hard dependency) and starts the sweeper.

Tests: engine resign + decoded-API tests; game unit tests (GCG, away-window
boundaries, hint budget, cache, keyed mutex, payload); inttest integration
(lifecycle, replay equivalence, timeout sweep with away grace, resign stats,
hint policy, word-check/complaint, per-game-lock). Docs (PLAN, ARCHITECTURE,
FUNCTIONAL +_ru, TESTING, README) updated.
This commit is contained in:
Ilia Denisov
2026-06-02 17:33:49 +02:00
parent f36f3df748
commit 751e74b14f
45 changed files with 4220 additions and 103 deletions
@@ -0,0 +1,23 @@
//
// Code generated by go-jet DO NOT EDIT.
//
// WARNING: Changes to this file may cause incorrect behavior
// and will be lost if the code is regenerated
//
package model
import (
"github.com/google/uuid"
"time"
)
type AccountStats struct {
AccountID uuid.UUID `sql:"primary_key"`
Wins int32
Losses int32
Draws int32
MaxGamePoints int32
MaxWordPoints int32
UpdatedAt time.Time
}
@@ -21,4 +21,7 @@ type Accounts struct {
BlockFriendRequests bool
CreatedAt time.Time
UpdatedAt time.Time
AwayStart time.Time
AwayEnd time.Time
HintBalance int32
}
@@ -0,0 +1,26 @@
//
// Code generated by go-jet DO NOT EDIT.
//
// WARNING: Changes to this file may cause incorrect behavior
// and will be lost if the code is regenerated
//
package model
import (
"github.com/google/uuid"
"time"
)
type Complaints struct {
ComplaintID uuid.UUID `sql:"primary_key"`
ComplainantID uuid.UUID
GameID uuid.UUID
Variant string
DictVersion string
Word string
WasValid bool
Note string
Status string
CreatedAt time.Time
}
@@ -0,0 +1,25 @@
//
// Code generated by go-jet DO NOT EDIT.
//
// WARNING: Changes to this file may cause incorrect behavior
// and will be lost if the code is regenerated
//
package model
import (
"github.com/google/uuid"
"time"
)
type GameMoves struct {
GameID uuid.UUID `sql:"primary_key"`
Seq int32 `sql:"primary_key"`
Seat int16
Action string
Score int32
RunningTotal int32
ExchangedCount int16
Payload string
CreatedAt time.Time
}
@@ -0,0 +1,21 @@
//
// Code generated by go-jet DO NOT EDIT.
//
// WARNING: Changes to this file may cause incorrect behavior
// and will be lost if the code is regenerated
//
package model
import (
"github.com/google/uuid"
)
type GamePlayers struct {
GameID uuid.UUID `sql:"primary_key"`
Seat int16 `sql:"primary_key"`
AccountID uuid.UUID
Score int32
HintsUsed int16
IsWinner bool
}
@@ -0,0 +1,32 @@
//
// Code generated by go-jet DO NOT EDIT.
//
// WARNING: Changes to this file may cause incorrect behavior
// and will be lost if the code is regenerated
//
package model
import (
"github.com/google/uuid"
"time"
)
type Games struct {
GameID uuid.UUID `sql:"primary_key"`
Variant string
DictVersion string
Seed int64
Status string
Players int16
ToMove int16
TurnStartedAt time.Time
TurnTimeoutSecs int32
HintsAllowed bool
HintsPerPlayer int16
MoveCount int32
EndReason *string
CreatedAt time.Time
UpdatedAt time.Time
FinishedAt *time.Time
}
@@ -0,0 +1,96 @@
//
// Code generated by go-jet DO NOT EDIT.
//
// WARNING: Changes to this file may cause incorrect behavior
// and will be lost if the code is regenerated
//
package table
import (
"github.com/go-jet/jet/v2/postgres"
)
var AccountStats = newAccountStatsTable("backend", "account_stats", "")
type accountStatsTable struct {
postgres.Table
// Columns
AccountID postgres.ColumnString
Wins postgres.ColumnInteger
Losses postgres.ColumnInteger
Draws postgres.ColumnInteger
MaxGamePoints postgres.ColumnInteger
MaxWordPoints postgres.ColumnInteger
UpdatedAt postgres.ColumnTimestampz
AllColumns postgres.ColumnList
MutableColumns postgres.ColumnList
DefaultColumns postgres.ColumnList
}
type AccountStatsTable struct {
accountStatsTable
EXCLUDED accountStatsTable
}
// AS creates new AccountStatsTable with assigned alias
func (a AccountStatsTable) AS(alias string) *AccountStatsTable {
return newAccountStatsTable(a.SchemaName(), a.TableName(), alias)
}
// Schema creates new AccountStatsTable with assigned schema name
func (a AccountStatsTable) FromSchema(schemaName string) *AccountStatsTable {
return newAccountStatsTable(schemaName, a.TableName(), a.Alias())
}
// WithPrefix creates new AccountStatsTable with assigned table prefix
func (a AccountStatsTable) WithPrefix(prefix string) *AccountStatsTable {
return newAccountStatsTable(a.SchemaName(), prefix+a.TableName(), a.TableName())
}
// WithSuffix creates new AccountStatsTable with assigned table suffix
func (a AccountStatsTable) WithSuffix(suffix string) *AccountStatsTable {
return newAccountStatsTable(a.SchemaName(), a.TableName()+suffix, a.TableName())
}
func newAccountStatsTable(schemaName, tableName, alias string) *AccountStatsTable {
return &AccountStatsTable{
accountStatsTable: newAccountStatsTableImpl(schemaName, tableName, alias),
EXCLUDED: newAccountStatsTableImpl("", "excluded", ""),
}
}
func newAccountStatsTableImpl(schemaName, tableName, alias string) accountStatsTable {
var (
AccountIDColumn = postgres.StringColumn("account_id")
WinsColumn = postgres.IntegerColumn("wins")
LossesColumn = postgres.IntegerColumn("losses")
DrawsColumn = postgres.IntegerColumn("draws")
MaxGamePointsColumn = postgres.IntegerColumn("max_game_points")
MaxWordPointsColumn = postgres.IntegerColumn("max_word_points")
UpdatedAtColumn = postgres.TimestampzColumn("updated_at")
allColumns = postgres.ColumnList{AccountIDColumn, WinsColumn, LossesColumn, DrawsColumn, MaxGamePointsColumn, MaxWordPointsColumn, UpdatedAtColumn}
mutableColumns = postgres.ColumnList{WinsColumn, LossesColumn, DrawsColumn, MaxGamePointsColumn, MaxWordPointsColumn, UpdatedAtColumn}
defaultColumns = postgres.ColumnList{WinsColumn, LossesColumn, DrawsColumn, MaxGamePointsColumn, MaxWordPointsColumn, UpdatedAtColumn}
)
return accountStatsTable{
Table: postgres.NewTable(schemaName, tableName, alias, allColumns...),
//Columns
AccountID: AccountIDColumn,
Wins: WinsColumn,
Losses: LossesColumn,
Draws: DrawsColumn,
MaxGamePoints: MaxGamePointsColumn,
MaxWordPoints: MaxWordPointsColumn,
UpdatedAt: UpdatedAtColumn,
AllColumns: allColumns,
MutableColumns: mutableColumns,
DefaultColumns: defaultColumns,
}
}
@@ -25,6 +25,9 @@ type accountsTable struct {
BlockFriendRequests postgres.ColumnBool
CreatedAt postgres.ColumnTimestampz
UpdatedAt postgres.ColumnTimestampz
AwayStart postgres.ColumnTime
AwayEnd postgres.ColumnTime
HintBalance postgres.ColumnInteger
AllColumns postgres.ColumnList
MutableColumns postgres.ColumnList
@@ -74,9 +77,12 @@ func newAccountsTableImpl(schemaName, tableName, alias string) accountsTable {
BlockFriendRequestsColumn = postgres.BoolColumn("block_friend_requests")
CreatedAtColumn = postgres.TimestampzColumn("created_at")
UpdatedAtColumn = postgres.TimestampzColumn("updated_at")
allColumns = postgres.ColumnList{AccountIDColumn, DisplayNameColumn, PreferredLanguageColumn, TimeZoneColumn, BlockChatColumn, BlockFriendRequestsColumn, CreatedAtColumn, UpdatedAtColumn}
mutableColumns = postgres.ColumnList{DisplayNameColumn, PreferredLanguageColumn, TimeZoneColumn, BlockChatColumn, BlockFriendRequestsColumn, CreatedAtColumn, UpdatedAtColumn}
defaultColumns = postgres.ColumnList{DisplayNameColumn, PreferredLanguageColumn, TimeZoneColumn, BlockChatColumn, BlockFriendRequestsColumn, CreatedAtColumn, UpdatedAtColumn}
AwayStartColumn = postgres.TimeColumn("away_start")
AwayEndColumn = postgres.TimeColumn("away_end")
HintBalanceColumn = postgres.IntegerColumn("hint_balance")
allColumns = postgres.ColumnList{AccountIDColumn, DisplayNameColumn, PreferredLanguageColumn, TimeZoneColumn, BlockChatColumn, BlockFriendRequestsColumn, CreatedAtColumn, UpdatedAtColumn, AwayStartColumn, AwayEndColumn, HintBalanceColumn}
mutableColumns = postgres.ColumnList{DisplayNameColumn, PreferredLanguageColumn, TimeZoneColumn, BlockChatColumn, BlockFriendRequestsColumn, CreatedAtColumn, UpdatedAtColumn, AwayStartColumn, AwayEndColumn, HintBalanceColumn}
defaultColumns = postgres.ColumnList{DisplayNameColumn, PreferredLanguageColumn, TimeZoneColumn, BlockChatColumn, BlockFriendRequestsColumn, CreatedAtColumn, UpdatedAtColumn, AwayStartColumn, AwayEndColumn, HintBalanceColumn}
)
return accountsTable{
@@ -91,6 +97,9 @@ func newAccountsTableImpl(schemaName, tableName, alias string) accountsTable {
BlockFriendRequests: BlockFriendRequestsColumn,
CreatedAt: CreatedAtColumn,
UpdatedAt: UpdatedAtColumn,
AwayStart: AwayStartColumn,
AwayEnd: AwayEndColumn,
HintBalance: HintBalanceColumn,
AllColumns: allColumns,
MutableColumns: mutableColumns,
@@ -0,0 +1,105 @@
//
// Code generated by go-jet DO NOT EDIT.
//
// WARNING: Changes to this file may cause incorrect behavior
// and will be lost if the code is regenerated
//
package table
import (
"github.com/go-jet/jet/v2/postgres"
)
var Complaints = newComplaintsTable("backend", "complaints", "")
type complaintsTable struct {
postgres.Table
// Columns
ComplaintID postgres.ColumnString
ComplainantID postgres.ColumnString
GameID postgres.ColumnString
Variant postgres.ColumnString
DictVersion postgres.ColumnString
Word postgres.ColumnString
WasValid postgres.ColumnBool
Note postgres.ColumnString
Status postgres.ColumnString
CreatedAt postgres.ColumnTimestampz
AllColumns postgres.ColumnList
MutableColumns postgres.ColumnList
DefaultColumns postgres.ColumnList
}
type ComplaintsTable struct {
complaintsTable
EXCLUDED complaintsTable
}
// AS creates new ComplaintsTable with assigned alias
func (a ComplaintsTable) AS(alias string) *ComplaintsTable {
return newComplaintsTable(a.SchemaName(), a.TableName(), alias)
}
// Schema creates new ComplaintsTable with assigned schema name
func (a ComplaintsTable) FromSchema(schemaName string) *ComplaintsTable {
return newComplaintsTable(schemaName, a.TableName(), a.Alias())
}
// WithPrefix creates new ComplaintsTable with assigned table prefix
func (a ComplaintsTable) WithPrefix(prefix string) *ComplaintsTable {
return newComplaintsTable(a.SchemaName(), prefix+a.TableName(), a.TableName())
}
// WithSuffix creates new ComplaintsTable with assigned table suffix
func (a ComplaintsTable) WithSuffix(suffix string) *ComplaintsTable {
return newComplaintsTable(a.SchemaName(), a.TableName()+suffix, a.TableName())
}
func newComplaintsTable(schemaName, tableName, alias string) *ComplaintsTable {
return &ComplaintsTable{
complaintsTable: newComplaintsTableImpl(schemaName, tableName, alias),
EXCLUDED: newComplaintsTableImpl("", "excluded", ""),
}
}
func newComplaintsTableImpl(schemaName, tableName, alias string) complaintsTable {
var (
ComplaintIDColumn = postgres.StringColumn("complaint_id")
ComplainantIDColumn = postgres.StringColumn("complainant_id")
GameIDColumn = postgres.StringColumn("game_id")
VariantColumn = postgres.StringColumn("variant")
DictVersionColumn = postgres.StringColumn("dict_version")
WordColumn = postgres.StringColumn("word")
WasValidColumn = postgres.BoolColumn("was_valid")
NoteColumn = postgres.StringColumn("note")
StatusColumn = postgres.StringColumn("status")
CreatedAtColumn = postgres.TimestampzColumn("created_at")
allColumns = postgres.ColumnList{ComplaintIDColumn, ComplainantIDColumn, GameIDColumn, VariantColumn, DictVersionColumn, WordColumn, WasValidColumn, NoteColumn, StatusColumn, CreatedAtColumn}
mutableColumns = postgres.ColumnList{ComplainantIDColumn, GameIDColumn, VariantColumn, DictVersionColumn, WordColumn, WasValidColumn, NoteColumn, StatusColumn, CreatedAtColumn}
defaultColumns = postgres.ColumnList{NoteColumn, StatusColumn, CreatedAtColumn}
)
return complaintsTable{
Table: postgres.NewTable(schemaName, tableName, alias, allColumns...),
//Columns
ComplaintID: ComplaintIDColumn,
ComplainantID: ComplainantIDColumn,
GameID: GameIDColumn,
Variant: VariantColumn,
DictVersion: DictVersionColumn,
Word: WordColumn,
WasValid: WasValidColumn,
Note: NoteColumn,
Status: StatusColumn,
CreatedAt: CreatedAtColumn,
AllColumns: allColumns,
MutableColumns: mutableColumns,
DefaultColumns: defaultColumns,
}
}
@@ -0,0 +1,102 @@
//
// Code generated by go-jet DO NOT EDIT.
//
// WARNING: Changes to this file may cause incorrect behavior
// and will be lost if the code is regenerated
//
package table
import (
"github.com/go-jet/jet/v2/postgres"
)
var GameMoves = newGameMovesTable("backend", "game_moves", "")
type gameMovesTable struct {
postgres.Table
// Columns
GameID postgres.ColumnString
Seq postgres.ColumnInteger
Seat postgres.ColumnInteger
Action postgres.ColumnString
Score postgres.ColumnInteger
RunningTotal postgres.ColumnInteger
ExchangedCount postgres.ColumnInteger
Payload postgres.ColumnString
CreatedAt postgres.ColumnTimestampz
AllColumns postgres.ColumnList
MutableColumns postgres.ColumnList
DefaultColumns postgres.ColumnList
}
type GameMovesTable struct {
gameMovesTable
EXCLUDED gameMovesTable
}
// AS creates new GameMovesTable with assigned alias
func (a GameMovesTable) AS(alias string) *GameMovesTable {
return newGameMovesTable(a.SchemaName(), a.TableName(), alias)
}
// Schema creates new GameMovesTable with assigned schema name
func (a GameMovesTable) FromSchema(schemaName string) *GameMovesTable {
return newGameMovesTable(schemaName, a.TableName(), a.Alias())
}
// WithPrefix creates new GameMovesTable with assigned table prefix
func (a GameMovesTable) WithPrefix(prefix string) *GameMovesTable {
return newGameMovesTable(a.SchemaName(), prefix+a.TableName(), a.TableName())
}
// WithSuffix creates new GameMovesTable with assigned table suffix
func (a GameMovesTable) WithSuffix(suffix string) *GameMovesTable {
return newGameMovesTable(a.SchemaName(), a.TableName()+suffix, a.TableName())
}
func newGameMovesTable(schemaName, tableName, alias string) *GameMovesTable {
return &GameMovesTable{
gameMovesTable: newGameMovesTableImpl(schemaName, tableName, alias),
EXCLUDED: newGameMovesTableImpl("", "excluded", ""),
}
}
func newGameMovesTableImpl(schemaName, tableName, alias string) gameMovesTable {
var (
GameIDColumn = postgres.StringColumn("game_id")
SeqColumn = postgres.IntegerColumn("seq")
SeatColumn = postgres.IntegerColumn("seat")
ActionColumn = postgres.StringColumn("action")
ScoreColumn = postgres.IntegerColumn("score")
RunningTotalColumn = postgres.IntegerColumn("running_total")
ExchangedCountColumn = postgres.IntegerColumn("exchanged_count")
PayloadColumn = postgres.StringColumn("payload")
CreatedAtColumn = postgres.TimestampzColumn("created_at")
allColumns = postgres.ColumnList{GameIDColumn, SeqColumn, SeatColumn, ActionColumn, ScoreColumn, RunningTotalColumn, ExchangedCountColumn, PayloadColumn, CreatedAtColumn}
mutableColumns = postgres.ColumnList{SeatColumn, ActionColumn, ScoreColumn, RunningTotalColumn, ExchangedCountColumn, PayloadColumn, CreatedAtColumn}
defaultColumns = postgres.ColumnList{ScoreColumn, RunningTotalColumn, ExchangedCountColumn, PayloadColumn, CreatedAtColumn}
)
return gameMovesTable{
Table: postgres.NewTable(schemaName, tableName, alias, allColumns...),
//Columns
GameID: GameIDColumn,
Seq: SeqColumn,
Seat: SeatColumn,
Action: ActionColumn,
Score: ScoreColumn,
RunningTotal: RunningTotalColumn,
ExchangedCount: ExchangedCountColumn,
Payload: PayloadColumn,
CreatedAt: CreatedAtColumn,
AllColumns: allColumns,
MutableColumns: mutableColumns,
DefaultColumns: defaultColumns,
}
}
@@ -0,0 +1,93 @@
//
// Code generated by go-jet DO NOT EDIT.
//
// WARNING: Changes to this file may cause incorrect behavior
// and will be lost if the code is regenerated
//
package table
import (
"github.com/go-jet/jet/v2/postgres"
)
var GamePlayers = newGamePlayersTable("backend", "game_players", "")
type gamePlayersTable struct {
postgres.Table
// Columns
GameID postgres.ColumnString
Seat postgres.ColumnInteger
AccountID postgres.ColumnString
Score postgres.ColumnInteger
HintsUsed postgres.ColumnInteger
IsWinner postgres.ColumnBool
AllColumns postgres.ColumnList
MutableColumns postgres.ColumnList
DefaultColumns postgres.ColumnList
}
type GamePlayersTable struct {
gamePlayersTable
EXCLUDED gamePlayersTable
}
// AS creates new GamePlayersTable with assigned alias
func (a GamePlayersTable) AS(alias string) *GamePlayersTable {
return newGamePlayersTable(a.SchemaName(), a.TableName(), alias)
}
// Schema creates new GamePlayersTable with assigned schema name
func (a GamePlayersTable) FromSchema(schemaName string) *GamePlayersTable {
return newGamePlayersTable(schemaName, a.TableName(), a.Alias())
}
// WithPrefix creates new GamePlayersTable with assigned table prefix
func (a GamePlayersTable) WithPrefix(prefix string) *GamePlayersTable {
return newGamePlayersTable(a.SchemaName(), prefix+a.TableName(), a.TableName())
}
// WithSuffix creates new GamePlayersTable with assigned table suffix
func (a GamePlayersTable) WithSuffix(suffix string) *GamePlayersTable {
return newGamePlayersTable(a.SchemaName(), a.TableName()+suffix, a.TableName())
}
func newGamePlayersTable(schemaName, tableName, alias string) *GamePlayersTable {
return &GamePlayersTable{
gamePlayersTable: newGamePlayersTableImpl(schemaName, tableName, alias),
EXCLUDED: newGamePlayersTableImpl("", "excluded", ""),
}
}
func newGamePlayersTableImpl(schemaName, tableName, alias string) gamePlayersTable {
var (
GameIDColumn = postgres.StringColumn("game_id")
SeatColumn = postgres.IntegerColumn("seat")
AccountIDColumn = postgres.StringColumn("account_id")
ScoreColumn = postgres.IntegerColumn("score")
HintsUsedColumn = postgres.IntegerColumn("hints_used")
IsWinnerColumn = postgres.BoolColumn("is_winner")
allColumns = postgres.ColumnList{GameIDColumn, SeatColumn, AccountIDColumn, ScoreColumn, HintsUsedColumn, IsWinnerColumn}
mutableColumns = postgres.ColumnList{AccountIDColumn, ScoreColumn, HintsUsedColumn, IsWinnerColumn}
defaultColumns = postgres.ColumnList{ScoreColumn, HintsUsedColumn, IsWinnerColumn}
)
return gamePlayersTable{
Table: postgres.NewTable(schemaName, tableName, alias, allColumns...),
//Columns
GameID: GameIDColumn,
Seat: SeatColumn,
AccountID: AccountIDColumn,
Score: ScoreColumn,
HintsUsed: HintsUsedColumn,
IsWinner: IsWinnerColumn,
AllColumns: allColumns,
MutableColumns: mutableColumns,
DefaultColumns: defaultColumns,
}
}
@@ -0,0 +1,123 @@
//
// Code generated by go-jet DO NOT EDIT.
//
// WARNING: Changes to this file may cause incorrect behavior
// and will be lost if the code is regenerated
//
package table
import (
"github.com/go-jet/jet/v2/postgres"
)
var Games = newGamesTable("backend", "games", "")
type gamesTable struct {
postgres.Table
// Columns
GameID postgres.ColumnString
Variant postgres.ColumnString
DictVersion postgres.ColumnString
Seed postgres.ColumnInteger
Status postgres.ColumnString
Players postgres.ColumnInteger
ToMove postgres.ColumnInteger
TurnStartedAt postgres.ColumnTimestampz
TurnTimeoutSecs postgres.ColumnInteger
HintsAllowed postgres.ColumnBool
HintsPerPlayer postgres.ColumnInteger
MoveCount postgres.ColumnInteger
EndReason postgres.ColumnString
CreatedAt postgres.ColumnTimestampz
UpdatedAt postgres.ColumnTimestampz
FinishedAt postgres.ColumnTimestampz
AllColumns postgres.ColumnList
MutableColumns postgres.ColumnList
DefaultColumns postgres.ColumnList
}
type GamesTable struct {
gamesTable
EXCLUDED gamesTable
}
// AS creates new GamesTable with assigned alias
func (a GamesTable) AS(alias string) *GamesTable {
return newGamesTable(a.SchemaName(), a.TableName(), alias)
}
// Schema creates new GamesTable with assigned schema name
func (a GamesTable) FromSchema(schemaName string) *GamesTable {
return newGamesTable(schemaName, a.TableName(), a.Alias())
}
// WithPrefix creates new GamesTable with assigned table prefix
func (a GamesTable) WithPrefix(prefix string) *GamesTable {
return newGamesTable(a.SchemaName(), prefix+a.TableName(), a.TableName())
}
// WithSuffix creates new GamesTable with assigned table suffix
func (a GamesTable) WithSuffix(suffix string) *GamesTable {
return newGamesTable(a.SchemaName(), a.TableName()+suffix, a.TableName())
}
func newGamesTable(schemaName, tableName, alias string) *GamesTable {
return &GamesTable{
gamesTable: newGamesTableImpl(schemaName, tableName, alias),
EXCLUDED: newGamesTableImpl("", "excluded", ""),
}
}
func newGamesTableImpl(schemaName, tableName, alias string) gamesTable {
var (
GameIDColumn = postgres.StringColumn("game_id")
VariantColumn = postgres.StringColumn("variant")
DictVersionColumn = postgres.StringColumn("dict_version")
SeedColumn = postgres.IntegerColumn("seed")
StatusColumn = postgres.StringColumn("status")
PlayersColumn = postgres.IntegerColumn("players")
ToMoveColumn = postgres.IntegerColumn("to_move")
TurnStartedAtColumn = postgres.TimestampzColumn("turn_started_at")
TurnTimeoutSecsColumn = postgres.IntegerColumn("turn_timeout_secs")
HintsAllowedColumn = postgres.BoolColumn("hints_allowed")
HintsPerPlayerColumn = postgres.IntegerColumn("hints_per_player")
MoveCountColumn = postgres.IntegerColumn("move_count")
EndReasonColumn = postgres.StringColumn("end_reason")
CreatedAtColumn = postgres.TimestampzColumn("created_at")
UpdatedAtColumn = postgres.TimestampzColumn("updated_at")
FinishedAtColumn = postgres.TimestampzColumn("finished_at")
allColumns = postgres.ColumnList{GameIDColumn, VariantColumn, DictVersionColumn, SeedColumn, StatusColumn, PlayersColumn, ToMoveColumn, TurnStartedAtColumn, TurnTimeoutSecsColumn, HintsAllowedColumn, HintsPerPlayerColumn, MoveCountColumn, EndReasonColumn, CreatedAtColumn, UpdatedAtColumn, FinishedAtColumn}
mutableColumns = postgres.ColumnList{VariantColumn, DictVersionColumn, SeedColumn, StatusColumn, PlayersColumn, ToMoveColumn, TurnStartedAtColumn, TurnTimeoutSecsColumn, HintsAllowedColumn, HintsPerPlayerColumn, MoveCountColumn, EndReasonColumn, CreatedAtColumn, UpdatedAtColumn, FinishedAtColumn}
defaultColumns = postgres.ColumnList{StatusColumn, ToMoveColumn, TurnStartedAtColumn, HintsAllowedColumn, HintsPerPlayerColumn, MoveCountColumn, CreatedAtColumn, UpdatedAtColumn}
)
return gamesTable{
Table: postgres.NewTable(schemaName, tableName, alias, allColumns...),
//Columns
GameID: GameIDColumn,
Variant: VariantColumn,
DictVersion: DictVersionColumn,
Seed: SeedColumn,
Status: StatusColumn,
Players: PlayersColumn,
ToMove: ToMoveColumn,
TurnStartedAt: TurnStartedAtColumn,
TurnTimeoutSecs: TurnTimeoutSecsColumn,
HintsAllowed: HintsAllowedColumn,
HintsPerPlayer: HintsPerPlayerColumn,
MoveCount: MoveCountColumn,
EndReason: EndReasonColumn,
CreatedAt: CreatedAtColumn,
UpdatedAt: UpdatedAtColumn,
FinishedAt: FinishedAtColumn,
AllColumns: allColumns,
MutableColumns: mutableColumns,
DefaultColumns: defaultColumns,
}
}
@@ -10,7 +10,12 @@ package table
// UseSchema sets a new schema name for all generated table SQL builder types. It is recommended to invoke
// this method only once at the beginning of the program.
func UseSchema(schema string) {
AccountStats = AccountStats.FromSchema(schema)
Accounts = Accounts.FromSchema(schema)
Complaints = Complaints.FromSchema(schema)
GameMoves = GameMoves.FromSchema(schema)
GamePlayers = GamePlayers.FromSchema(schema)
Games = Games.FromSchema(schema)
Identities = Identities.FromSchema(schema)
Sessions = Sessions.FromSchema(schema)
}