From 9973546aad2e5f25d109783398462e5bf576829e Mon Sep 17 00:00:00 2001 From: Grail Finder Date: Wed, 2 Jul 2025 12:55:50 +0300 Subject: [PATCH] Enha: use of db methods --- handlers/actions.go | 82 ++++++++++++++-------------- handlers/auth.go | 20 +++++-- handlers/game.go | 17 +++--- handlers/handlers.go | 13 +++-- migrations/001_initial_schema.up.sql | 2 +- repos/rooms.go | 33 +++++------ 6 files changed, 89 insertions(+), 78 deletions(-) diff --git a/handlers/actions.go b/handlers/actions.go index ff45895..a812361 100644 --- a/handlers/actions.go +++ b/handlers/actions.go @@ -60,34 +60,34 @@ func createRoom(ctx context.Context, req *models.RoomReq) (*models.Room, error) // context -func getStateByCtx(ctx context.Context) (*models.UserState, error) { - username, ok := ctx.Value(models.CtxUsernameKey).(string) - if !ok { - log.Debug("no username in ctx") - return &models.UserState{}, errors.New("no username in ctx") - } - us, err := loadState(username) - if err != nil { - return &models.UserState{}, err - } - return us, nil -} +// func getStateByCtx(ctx context.Context) (*models.UserState, error) { +// username, ok := ctx.Value(models.CtxUsernameKey).(string) +// if !ok { +// log.Debug("no username in ctx") +// return &models.UserState{}, errors.New("no username in ctx") +// } +// us, err := loadState(username) +// if err != nil { +// return &models.UserState{}, err +// } +// return us, nil +// } // func dbCreate(fi *models.FullInfo) error{ // repo.CreateRoom() // } -// func saveFullInfo(fi *models.FullInfo) error { -// // INFO: no transactions; so case is possible where first object is updated but the second is not -// if err := saveState(fi.State.Username, fi.State); err != nil { -// return err -// } -// log.Debug("saved user state", "state", fi.State) -// if err := saveRoom(fi.Room); err != nil { -// return err -// } -// return nil -// } +func saveFullInfo(fi *models.FullInfo) error { + // INFO: no transactions; so case is possible where first object is updated but the second is not + if err := repo.PlayerUpdate(fi.State); err != nil { + return err + } + log.Debug("saved user state", "state", fi.State) + if err := repo.RoomUpdate(context.Background(), fi.Room); err != nil { + return err + } + return nil +} func notifyBotIfNeeded(room *models.Room) { if botName := room.WhichBotToMove(); botName != "" { @@ -229,24 +229,24 @@ func joinTeam(ctx context.Context, role, team string) (*models.FullInfo, error) } // get all rooms -func listRooms(allRooms bool) []*models.Room { - cacheMap := memcache.GetAll() - publicRooms := []*models.Room{} - // no way to know if room is public until unmarshal -_-; - for key, value := range cacheMap { - if strings.HasPrefix(key, models.CacheRoomPrefix) { - room := &models.Room{} - if err := json.Unmarshal(value, &room); err != nil { - log.Warn("failed to unmarshal room", "error", err) - continue - } - if room.IsPublic || allRooms { - publicRooms = append(publicRooms, room) - } - } - } - return publicRooms -} +// func listRooms(allRooms bool) []*models.Room { +// cacheMap := memcache.GetAll() +// publicRooms := []*models.Room{} +// // no way to know if room is public until unmarshal -_-; +// for key, value := range cacheMap { +// if strings.HasPrefix(key, models.CacheRoomPrefix) { +// room := &models.Room{} +// if err := json.Unmarshal(value, &room); err != nil { +// log.Warn("failed to unmarshal room", "error", err) +// continue +// } +// if room.IsPublic || allRooms { +// publicRooms = append(publicRooms, room) +// } +// } +// } +// return publicRooms +// } // get bots func listBots() map[string]map[string]string { diff --git a/handlers/auth.go b/handlers/auth.go index bfe6a68..ce63d1c 100644 --- a/handlers/auth.go +++ b/handlers/auth.go @@ -91,23 +91,31 @@ func HandleFrontLogin(w http.ResponseWriter, r *http.Request) { // check if room_id provided and exists if roomID != "" { log.Debug("got room_id in login", "room_id", roomID) - room, err := getRoomByID(roomID) + // room, err := getRoomByID(roomID) + room, err := repo.RoomGetByID(r.Context(), roomID) if err != nil { abortWithError(w, err.Error()) return } // room.PlayerList = append(room.PlayerList, fi.State.Username) - fi.State.RoomID = room.ID fi.Room = room fi.List = nil + fi.State.RoomID = room.ID + repo.PlayerSetRoomID(fi.State.Username, room.ID) + // repo.RoomUpdate() // save full info instead - if err := saveFullInfo(fi); err != nil { + // if err := saveFullInfo(fi); err != nil { + // abortWithError(w, err.Error()) + // return + // } + } else { + log.Debug("no room_id in login") + // fi.List = listRooms(false) + fi.List, err = repo.RoomList(r.Context()) + if err != nil { abortWithError(w, err.Error()) return } - } else { - log.Debug("no room_id in login") - fi.List = listRooms(false) // save state to cache // if err := saveState(cleanName, userstate); err != nil { if err := repo.PlayerUpdate(userstate); err != nil { diff --git a/handlers/game.go b/handlers/game.go index e5073ba..e81f854 100644 --- a/handlers/game.go +++ b/handlers/game.go @@ -42,17 +42,20 @@ func HandleCreateRoom(w http.ResponseWriter, r *http.Request) { } fi.State.RoomID = room.ID fi.Room = room - fi.Room.IsPublic = true // hardcode for local test; move to form - if err := repo.CreateRoom(r.Context(), room); err != nil { + if err := repo.RoomCreate(r.Context(), room); err != nil { abortWithError(w, err.Error()) return } - if err := saveFullInfo(fi); err != nil { - msg := "failed to set current room to session" - log.Error(msg, "error", err) - abortWithError(w, msg) + if err := repo.PlayerSetRoomID(fi.State.Username, room.ID); err != nil { + abortWithError(w, err.Error()) return } + // if err := saveFullInfo(fi); err != nil { + // msg := "failed to set current room to session" + // log.Error(msg, "error", err) + // abortWithError(w, msg) + // return + // } notify(models.NotifyRoomListUpdate, "") tmpl, err := template.ParseGlob("components/*.html") if err != nil { @@ -198,7 +201,7 @@ func HandleStartGame(w http.ResponseWriter, r *http.Request) { func HandleJoinRoom(w http.ResponseWriter, r *http.Request) { roomID := r.URL.Query().Get("id") - room, err := getRoomByID(roomID) + room, err := repo.RoomGetByID(r.Context(), roomID) if err != nil { abortWithError(w, err.Error()) return diff --git a/handlers/handlers.go b/handlers/handlers.go index b5d3622..dffb163 100644 --- a/handlers/handlers.go +++ b/handlers/handlers.go @@ -60,7 +60,7 @@ func HandleHome(w http.ResponseWriter, r *http.Request) { } } if fi != nil && fi.Room == nil { - rooms, err := repo.ListRooms(r.Context()) + rooms, err := repo.RoomList(r.Context()) if err != nil { log.Error("failed to list rooms;", "error", err) } @@ -96,7 +96,7 @@ func HandleExit(w http.ResponseWriter, r *http.Request) { // return // } if creatorLeft { - if err := repo.DeleteRoomByID(r.Context(), exitedRoom.ID); err != nil { + if err := repo.RoomDeleteByID(r.Context(), exitedRoom.ID); err != nil { log.Error("failed to remove room", "error", err) } // removeRoom(exitedRoom.ID) @@ -105,7 +105,7 @@ func HandleExit(w http.ResponseWriter, r *http.Request) { notify(models.NotifyRoomListUpdate, "") } // scary to update the whole room - if err := repo.UpdateRoom(r.Context(), exitedRoom); err != nil { + if err := repo.RoomUpdate(r.Context(), exitedRoom); err != nil { abortWithError(w, err.Error()) return } @@ -113,7 +113,12 @@ func HandleExit(w http.ResponseWriter, r *http.Request) { abortWithError(w, err.Error()) return } - fi.List = listRooms(false) + // fi.List = listRooms(false) + fi.List, err = repo.RoomList(r.Context()) + if err != nil { + abortWithError(w, err.Error()) + return + } if err := tmpl.ExecuteTemplate(w, "base", fi); err != nil { log.Error("failed to exec templ;", "error", err, "templ", "base") } diff --git a/migrations/001_initial_schema.up.sql b/migrations/001_initial_schema.up.sql index 076fd14..d4080bc 100644 --- a/migrations/001_initial_schema.up.sql +++ b/migrations/001_initial_schema.up.sql @@ -19,7 +19,7 @@ CREATE TABLE rooms ( CREATE TABLE players ( id INTEGER PRIMARY KEY AUTOINCREMENT, - room_id TEXT NOT NULL, + room_id TEXT, -- nullable username TEXT NOT NULL, team TEXT NOT NULL DEFAULT '', -- 'red' or 'blue' role TEXT NOT NULL DEFAULT '', -- 'guesser' or 'mime' diff --git a/repos/rooms.go b/repos/rooms.go index 799afd2..3978d58 100644 --- a/repos/rooms.go +++ b/repos/rooms.go @@ -6,15 +6,15 @@ import ( ) type RoomsRepo interface { - ListRooms(ctx context.Context) ([]*models.Room, error) - GetRoomByID(ctx context.Context, id string) (*models.Room, error) - GetRoomExtended(ctx context.Context, id string) (*models.Room, error) - CreateRoom(ctx context.Context, room *models.Room) error - DeleteRoomByID(ctx context.Context, id string) error - UpdateRoom(ctx context.Context, room *models.Room) error + RoomList(ctx context.Context) ([]*models.Room, error) + RoomGetByID(ctx context.Context, id string) (*models.Room, error) + RoomGetExtended(ctx context.Context, id string) (*models.Room, error) + RoomCreate(ctx context.Context, room *models.Room) error + RoomDeleteByID(ctx context.Context, id string) error + RoomUpdate(ctx context.Context, room *models.Room) error } -func (p *RepoProvider) ListRooms(ctx context.Context) ([]*models.Room, error) { +func (p *RepoProvider) RoomList(ctx context.Context) ([]*models.Room, error) { rooms := []*models.Room{} err := p.DB.SelectContext(ctx, &rooms, `SELECT * FROM rooms`) if err != nil { @@ -23,7 +23,7 @@ func (p *RepoProvider) ListRooms(ctx context.Context) ([]*models.Room, error) { return rooms, nil } -func (p *RepoProvider) GetRoomByID(ctx context.Context, id string) (*models.Room, error) { +func (p *RepoProvider) RoomGetByID(ctx context.Context, id string) (*models.Room, error) { room := &models.Room{} err := p.DB.GetContext(ctx, room, `SELECT * FROM rooms WHERE id = ?`, id) if err != nil { @@ -32,28 +32,27 @@ func (p *RepoProvider) GetRoomByID(ctx context.Context, id string) (*models.Room return room, nil } -func (p *RepoProvider) CreateRoom(ctx context.Context, r *models.Room) error { +func (p *RepoProvider) RoomCreate(ctx context.Context, r *models.Room) error { _, err := p.DB.ExecContext(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_running, is_over, team_won, room_link) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, r.ID, r.CreatedAt, r.CreatorName, r.TeamTurn, r.ThisTurnLimit, r.OpenedThisTurn, r.BlueCounter, r.RedCounter, r.RedTurn, r.MimeDone, r.IsRunning, r.IsOver, r.TeamWon, r.RoomLink) return err } -func (p *RepoProvider) DeleteRoomByID(ctx context.Context, id string) error { +func (p *RepoProvider) RoomDeleteByID(ctx context.Context, id string) error { _, err := p.DB.ExecContext(ctx, `DELETE FROM rooms WHERE id = ?`, id) return err } -func (p *RepoProvider) UpdateRoom(ctx context.Context, r *models.Room) error { +func (p *RepoProvider) RoomUpdate(ctx context.Context, r *models.Room) error { _, err := p.DB.ExecContext(ctx, `UPDATE rooms SET team_turn = ?, this_turn_limit = ?, opened_this_turn = ?, blue_counter = ?, red_counter = ?, red_turn = ?, mime_done = ?, = ?, is_running = ?, is_over = ?, team_won = ?, room_link = ? WHERE id = ?`, r.TeamTurn, r.ThisTurnLimit, r.OpenedThisTurn, r.BlueCounter, r.RedCounter, r.RedTurn, r.MimeDone, r.IsRunning, r.IsOver, r.TeamWon, r.RoomLink, r.ID) return err } -func (p *RepoProvider) GetRoomExtended(ctx context.Context, id string) (*models.Room, error) { +func (p *RepoProvider) RoomGetExtended(ctx context.Context, id string) (*models.Room, error) { room := &models.Room{} err := p.DB.GetContext(ctx, room, `SELECT * FROM rooms WHERE id = ?`, id) if err != nil { return nil, err } - // Get players players := []*models.Player{} err = p.DB.SelectContext(ctx, &players, `SELECT * FROM players WHERE room_id = ?`, id) @@ -86,23 +85,20 @@ func (p *RepoProvider) GetRoomExtended(ctx context.Context, id string) (*models. } } } - // Get word cards - wordCards := []*models.WordCard{} + wordCards := []models.WordCard{} err = p.DB.SelectContext(ctx, &wordCards, `SELECT * FROM word_cards WHERE room_id = ?`, id) if err != nil { return nil, err } room.Cards = wordCards - // Get actions - actions := []*models.Action{} + actions := []models.Action{} err = p.DB.SelectContext(ctx, &actions, `SELECT * FROM actions WHERE room_id = ? ORDER BY created_at ASC`, id) if err != nil { return nil, err } room.ActionHistory = actions - // Get settings settings := &models.GameSettings{} err = p.DB.GetContext(ctx, settings, `SELECT * FROM settings WHERE room_id = ?`, id) @@ -110,6 +106,5 @@ func (p *RepoProvider) GetRoomExtended(ctx context.Context, id string) (*models. return nil, err } room.Settings = *settings - return room, nil }