Feat: player stats [WIP]
This commit is contained in:
@ -86,3 +86,20 @@ CREATE TABLE journal(
|
|||||||
FOREIGN KEY (username) REFERENCES players(username) ON DELETE CASCADE,
|
FOREIGN KEY (username) REFERENCES players(username) ON DELETE CASCADE,
|
||||||
FOREIGN KEY (room_id) REFERENCES rooms(id) ON DELETE CASCADE
|
FOREIGN KEY (room_id) REFERENCES rooms(id) ON DELETE CASCADE
|
||||||
);
|
);
|
||||||
|
|
||||||
|
CREATE TABLE player_stats (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
player_username TEXT NOT NULL UNIQUE,
|
||||||
|
games_played INTEGER NOT NULL DEFAULT 0,
|
||||||
|
games_won INTEGER NOT NULL DEFAULT 0,
|
||||||
|
games_lost INTEGER NOT NULL DEFAULT 0,
|
||||||
|
opened_opposite_words INTEGER NOT NULL DEFAULT 0,
|
||||||
|
opened_white_words INTEGER NOT NULL DEFAULT 0,
|
||||||
|
opened_black_words INTEGER NOT NULL DEFAULT 0,
|
||||||
|
mime_winrate REAL NOT NULL DEFAULT 0.0,
|
||||||
|
guesser_winrate REAL NOT NULL DEFAULT 0.0,
|
||||||
|
played_as_mime INTEGER NOT NULL DEFAULT 0,
|
||||||
|
played_as_guesser INTEGER NOT NULL DEFAULT 0,
|
||||||
|
FOREIGN KEY (player_username) REFERENCES players(username) ON DELETE CASCADE
|
||||||
|
);
|
||||||
|
|
||||||
|
@ -138,6 +138,22 @@ type Journal struct {
|
|||||||
CreatedAt time.Time `db:"created_at"`
|
CreatedAt time.Time `db:"created_at"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type PlayerStats struct {
|
||||||
|
ID uint32 `db:"id"`
|
||||||
|
PlayerUsername string `db:"player_username"`
|
||||||
|
GamesPlayed int `db:"games_played"`
|
||||||
|
GamesWon int `db:"games_won"`
|
||||||
|
GamesLost int `db:"games_lost"`
|
||||||
|
OpenedOppositeWords int `db:"opened_opposite_words"`
|
||||||
|
OpenedWhiteWords int `db:"opened_white_words"`
|
||||||
|
OpenedBlackWords int `db:"opened_black_words"`
|
||||||
|
MimeWinrate float64 `db:"mime_winrate"`
|
||||||
|
GuesserWinrate float64 `db:"guesser_winrate"`
|
||||||
|
PlayedAsMime int `db:"played_as_mime"`
|
||||||
|
PlayedAsGuesser int `db:"played_as_guesser"`
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
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"`
|
CreatedAt time.Time `json:"created_at" db:"created_at"`
|
||||||
|
@ -2,7 +2,6 @@ package repos
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"gralias/config"
|
|
||||||
"log/slog"
|
"log/slog"
|
||||||
"os"
|
"os"
|
||||||
"sync"
|
"sync"
|
||||||
@ -20,6 +19,7 @@ type AllRepos interface {
|
|||||||
WordCardsRepo
|
WordCardsRepo
|
||||||
SettingsRepo
|
SettingsRepo
|
||||||
CardMarksRepo
|
CardMarksRepo
|
||||||
|
PlayerStatsRepo
|
||||||
InitTx(ctx context.Context) (context.Context, *sqlx.Tx, error)
|
InitTx(ctx context.Context) (context.Context, *sqlx.Tx, error)
|
||||||
Close()
|
Close()
|
||||||
}
|
}
|
||||||
@ -32,12 +32,7 @@ type RepoProvider struct {
|
|||||||
|
|
||||||
var RP AllRepos
|
var RP AllRepos
|
||||||
|
|
||||||
func init() {
|
|
||||||
cfg := config.LoadConfigOrDefault("")
|
|
||||||
// sqlite3 has lock on write, so we need to have only one connection per whole app
|
|
||||||
// https://github.com/mattn/go-sqlite3/issues/274#issuecomment-232942571
|
|
||||||
RP = NewRepoProvider(cfg.DBPath)
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewRepoProvider(pathToDB string) *RepoProvider {
|
func NewRepoProvider(pathToDB string) *RepoProvider {
|
||||||
db, err := sqlx.Connect("sqlite3", pathToDB)
|
db, err := sqlx.Connect("sqlite3", pathToDB)
|
||||||
|
42
repos/player_stats.go
Normal file
42
repos/player_stats.go
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
package repos
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"gralias/models"
|
||||||
|
|
||||||
|
"github.com/jmoiron/sqlx"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PlayerStatsRepo interface {
|
||||||
|
GetPlayerStats(ctx context.Context, username string) (*models.PlayerStats, error)
|
||||||
|
UpdatePlayerStats(ctx context.Context, stats *models.PlayerStats) error
|
||||||
|
CreatePlayerStats(ctx context.Context, username string) error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *RepoProvider) GetPlayerStats(ctx context.Context, username string) (*models.PlayerStats, error) {
|
||||||
|
stats := &models.PlayerStats{}
|
||||||
|
err := sqlx.GetContext(ctx, p.DB, stats, "SELECT * FROM player_stats WHERE player_username = ?", username)
|
||||||
|
return stats, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *RepoProvider) UpdatePlayerStats(ctx context.Context, stats *models.PlayerStats) error {
|
||||||
|
_, err := p.DB.NamedExecContext(ctx, `UPDATE player_stats SET
|
||||||
|
games_played = :games_played,
|
||||||
|
games_won = :games_won,
|
||||||
|
games_lost = :games_lost,
|
||||||
|
opened_opposite_words = :opened_opposite_words,
|
||||||
|
opened_white_words = :opened_white_words,
|
||||||
|
opened_black_words = :opened_black_words,
|
||||||
|
mime_winrate = :mime_winrate,
|
||||||
|
guesser_winrate = :guesser_winrate,
|
||||||
|
played_as_mime = :played_as_mime,
|
||||||
|
played_as_guesser = :played_as_guesser
|
||||||
|
WHERE player_username = :player_username`, stats)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *RepoProvider) CreatePlayerStats(ctx context.Context, username string) error {
|
||||||
|
db := getDB(ctx, p.DB)
|
||||||
|
_, err := db.ExecContext(ctx, "INSERT INTO player_stats (player_username) VALUES (?)", username)
|
||||||
|
return err
|
||||||
|
}
|
Reference in New Issue
Block a user