Feat: word card repo

This commit is contained in:
Grail Finder
2025-07-03 15:00:06 +03:00
parent 66d7a633c8
commit 788c4efd9e
5 changed files with 137 additions and 12 deletions

View File

@ -24,7 +24,7 @@ CREATE TABLE players (
team TEXT NOT NULL DEFAULT '', -- 'red' or 'blue'
role TEXT NOT NULL DEFAULT '', -- 'guesser' or 'mime'
is_bot BOOLEAN NOT NULL DEFAULT FALSE,
FOREIGN KEY (room_id) REFERENCES rooms(id)
FOREIGN KEY (room_id) REFERENCES rooms(id) ON DELETE CASCADE
);
CREATE TABLE word_cards (
@ -34,7 +34,7 @@ CREATE TABLE word_cards (
color TEXT NOT NULL DEFAULT '',
revealed BOOLEAN NOT NULL DEFAULT FALSE,
mime_view BOOLEAN NOT NULL DEFAULT FALSE,
FOREIGN KEY (room_id) REFERENCES rooms(id)
FOREIGN KEY (room_id) REFERENCES rooms(id) ON DELETE CASCADE
);
CREATE TABLE card_marks (
@ -42,7 +42,7 @@ CREATE TABLE card_marks (
card_id INTEGER NOT NULL,
username TEXT NOT NULL,
active BOOLEAN NOT NULL DEFAULT TRUE,
FOREIGN KEY (card_id) REFERENCES word_cards(id)
FOREIGN KEY (card_id) REFERENCES word_cards(id) ON DELETE CASCADE
);
CREATE TABLE actions (
@ -55,7 +55,7 @@ CREATE TABLE actions (
word_color TEXT NOT NULL DEFAULT '',
number_associated TEXT NOT NULL DEFAULT '', -- for clues
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (room_id) REFERENCES rooms(id)
FOREIGN KEY (room_id) REFERENCES rooms(id) ON DELETE CASCADE
);
CREATE TABLE settings (
@ -65,7 +65,7 @@ CREATE TABLE settings (
room_pass TEXT NOT NULL DEFAULT '',
turn_time INTEGER NOT NULL DEFAULT 60, -- seconds
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (room_id) REFERENCES rooms(id)
FOREIGN KEY (room_id) REFERENCES rooms(id) ON DELETE CASCADE
);
CREATE TABLE sessions(
@ -74,5 +74,5 @@ CREATE TABLE sessions(
lifetime INTEGER NOT NULL DEFAULT 3600,
token_key TEXT NOT NULL DEFAULT '' UNIQUE, -- encoded value
username TEXT NOT NULL,
FOREIGN KEY (username) REFERENCES players(username)
);
FOREIGN KEY (username) REFERENCES players(username) ON DELETE CASCADE
);

View File

@ -16,6 +16,7 @@ type AllRepos interface {
ActionsRepo
PlayersRepo
SessionsRepo
WordCardsRepo
}
type RepoProvider struct {

View File

@ -53,10 +53,6 @@ func (p *RepoProvider) RoomCreate(ctx context.Context, r *models.Room) error {
func (p *RepoProvider) RoomDeleteByID(ctx context.Context, id string) error {
db := getDB(ctx, p.DB)
_, err := db.ExecContext(ctx, `DELETE FROM rooms WHERE id = ?`, id)
if err != nil {
return err
}
_, err = db.ExecContext(ctx, `DELETE FROM settings WHERE room_id = ?`, id)
return err
}

View File

@ -15,6 +15,10 @@ func setupTestDB(t *testing.T) (*sqlx.DB, func()) {
db, err := sqlx.Connect("sqlite3", ":memory:")
assert.NoError(t, err)
// Enable foreign key constraints for SQLite
_, err = db.Exec("PRAGMA foreign_keys = ON;")
assert.NoError(t, err)
schema := `
CREATE TABLE IF NOT EXISTS rooms (
id TEXT PRIMARY KEY,
@ -33,6 +37,47 @@ func setupTestDB(t *testing.T) (*sqlx.DB, func()) {
room_link TEXT NOT NULL DEFAULT ''
);
CREATE TABLE IF NOT EXISTS players (
id INTEGER PRIMARY KEY AUTOINCREMENT,
room_id TEXT,
username TEXT NOT NULL UNIQUE,
team TEXT NOT NULL DEFAULT '',
role TEXT NOT NULL DEFAULT '',
is_bot BOOLEAN NOT NULL DEFAULT FALSE,
FOREIGN KEY (room_id) REFERENCES rooms(id) ON DELETE CASCADE
);
CREATE TABLE IF NOT EXISTS word_cards (
id INTEGER PRIMARY KEY AUTOINCREMENT,
room_id TEXT NOT NULL,
word TEXT NOT NULL,
color TEXT NOT NULL DEFAULT '',
revealed BOOLEAN NOT NULL DEFAULT FALSE,
mime_view BOOLEAN NOT NULL DEFAULT FALSE,
FOREIGN KEY (room_id) REFERENCES rooms(id) ON DELETE CASCADE
);
CREATE TABLE IF NOT EXISTS card_marks (
id INTEGER PRIMARY KEY AUTOINCREMENT,
card_id INTEGER NOT NULL,
username TEXT NOT NULL,
active BOOLEAN NOT NULL DEFAULT TRUE,
FOREIGN KEY (card_id) REFERENCES word_cards(id) ON DELETE CASCADE
);
CREATE TABLE IF NOT EXISTS actions (
id INTEGER PRIMARY KEY AUTOINCREMENT,
room_id TEXT NOT NULL,
actor TEXT NOT NULL,
actor_color TEXT NOT NULL DEFAULT '',
action_type TEXT NOT NULL,
word TEXT NOT NULL DEFAULT '',
word_color TEXT NOT NULL DEFAULT '',
number_associated TEXT NOT NULL DEFAULT '',
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (room_id) REFERENCES rooms(id) ON DELETE CASCADE
);
CREATE TABLE IF NOT EXISTS settings (
id INTEGER PRIMARY KEY AUTOINCREMENT,
room_id TEXT NOT NULL,
@ -40,7 +85,16 @@ func setupTestDB(t *testing.T) (*sqlx.DB, func()) {
room_pass TEXT NOT NULL DEFAULT '',
turn_time INTEGER NOT NULL DEFAULT 60,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (room_id) REFERENCES rooms(id)
FOREIGN KEY (room_id) REFERENCES rooms(id) ON DELETE CASCADE
);
CREATE TABLE IF NOT EXISTS sessions(
id INTEGER PRIMARY KEY AUTOINCREMENT,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
lifetime INTEGER NOT NULL DEFAULT 3600,
token_key TEXT NOT NULL DEFAULT '' UNIQUE,
username TEXT NOT NULL,
FOREIGN KEY (username) REFERENCES players(username) ON DELETE CASCADE
);
`
_, err = db.Exec(schema)
@ -236,6 +290,17 @@ func TestRoomsRepo_DeleteRoomByID(t *testing.T) {
_, err = db.Exec(`INSERT INTO settings (room_id, language, room_pass, turn_time) VALUES (?, ?, ?, ?)`, room.ID, room.Settings.Language, room.Settings.RoomPass, room.Settings.RoundTime)
assert.NoError(t, err)
// Insert a word card for the room
wordCard := &models.WordCard{
RoomID: room.ID,
Word: "test_word",
Color: models.WordColorBlue,
Revealed: false,
Mime: false,
}
_, err = db.Exec(`INSERT INTO word_cards (room_id, word, color, revealed, mime_view) VALUES (?, ?, ?, ?, ?)`, wordCard.RoomID, wordCard.Word, wordCard.Color, wordCard.Revealed, wordCard.Mime)
assert.NoError(t, err)
err = repo.RoomDeleteByID(context.Background(), room.ID)
assert.NoError(t, err)
@ -247,6 +312,10 @@ func TestRoomsRepo_DeleteRoomByID(t *testing.T) {
err = db.Get(&count, "SELECT COUNT(*) FROM settings WHERE room_id = ?", room.ID)
assert.NoError(t, err)
assert.Equal(t, 0, count)
err = db.Get(&count, "SELECT COUNT(*) FROM word_cards WHERE room_id = ?", room.ID)
assert.NoError(t, err)
assert.Equal(t, 0, count)
}
func TestRoomsRepo_UpdateRoom(t *testing.T) {

59
repos/word_cards.go Normal file
View File

@ -0,0 +1,59 @@
package repos
import (
"context"
"gralias/models"
"github.com/jmoiron/sqlx"
)
type WordCardsRepo interface {
WordCardsCreate(ctx context.Context, card *models.WordCard) error
WordCardsGetByRoomID(ctx context.Context, roomID string) ([]models.WordCard, error)
WordCardGetByWordAndRoomID(ctx context.Context, word, roomID string) (*models.WordCard, error)
WordCardReveal(ctx context.Context, word, roomID string) error
WordCardsRevealAll(ctx context.Context, roomID string) error
WordCardsDeleteByRoomID(ctx context.Context, roomID string) error
}
func (p *RepoProvider) WordCardsCreate(ctx context.Context, card *models.WordCard) error {
db := getDB(ctx, p.DB)
_, err := db.ExecContext(ctx, `INSERT INTO word_cards (room_id, word, color, revealed, mime_view) VALUES (?, ?, ?, ?, ?)`, card.RoomID, card.Word, card.Color, card.Revealed, card.Mime)
return err
}
func (p *RepoProvider) WordCardsGetByRoomID(ctx context.Context, roomID string) ([]models.WordCard, error) {
cards := []models.WordCard{}
err := sqlx.SelectContext(ctx, p.DB, &cards, `SELECT * FROM word_cards WHERE room_id = ?`, roomID)
if err != nil {
return nil, err
}
return cards, nil
}
func (p *RepoProvider) WordCardGetByWordAndRoomID(ctx context.Context, word, roomID string) (*models.WordCard, error) {
card := &models.WordCard{}
err := sqlx.GetContext(ctx, p.DB, card, `SELECT * FROM word_cards WHERE word = ? AND room_id = ?`, word, roomID)
if err != nil {
return nil, err
}
return card, nil
}
func (p *RepoProvider) WordCardReveal(ctx context.Context, word, roomID string) error {
db := getDB(ctx, p.DB)
_, err := db.ExecContext(ctx, `UPDATE word_cards SET revealed = TRUE WHERE word = ? AND room_id = ?`, word, roomID)
return err
}
func (p *RepoProvider) WordCardsRevealAll(ctx context.Context, roomID string) error {
db := getDB(ctx, p.DB)
_, err := db.ExecContext(ctx, `UPDATE word_cards SET revealed = TRUE WHERE room_id = ?`, roomID)
return err
}
func (p *RepoProvider) WordCardsDeleteByRoomID(ctx context.Context, roomID string) error {
db := getDB(ctx, p.DB)
_, err := db.ExecContext(ctx, `DELETE FROM word_cards WHERE room_id = ?`, roomID)
return err
}