Game store and create store functions

This commit is contained in:
Miguel de la Cruz 2021-09-13 15:21:37 +02:00
parent 3c7c32423e
commit f280c0701f
5 changed files with 139 additions and 44 deletions

View file

@ -1,7 +1,7 @@
package model package model
type Game struct { type Game struct {
ID int ID int `json:"id"`
UserID int UserID int `json:"user_id"`
Name string Name string `json:"name"`
} }

View file

@ -6,7 +6,7 @@ const (
) )
type GameMember struct { type GameMember struct {
GameID int GameID int `json:"game_id"`
UserID int UserID int `json:"user_id"`
Role string Role string `json:"role"`
} }

View file

@ -0,0 +1,113 @@
package store
import (
"database/sql"
sq "github.com/Masterminds/squirrel"
"git.ctrlz.es/mgdelacroix/craban/model"
)
var gameColumns = []string{"id", "user_id", "name"}
var gameMemberColumns = []string{"game_id", "user_id", "role"}
type GameStore struct {
Conn *sql.DB
}
func NewGameStore(s *Store) *GameStore {
return &GameStore{Conn: s.Conn}
}
func (gs *GameStore) Q() sq.StatementBuilderType {
return sq.StatementBuilder.RunWith(gs.Conn)
}
func (gs *GameStore) gamesFromRows(rows *sql.Rows) ([]*model.Game, error) {
games := []*model.Game{}
for rows.Next() {
var game model.Game
err := rows.Scan(
&game.ID,
&game.UserID,
&game.Name,
)
if err != nil {
return nil, err
}
games = append(games, &game)
}
return games, nil
}
func (gs *GameStore) getGameByCondition(condition sq.Eq) (*model.Game, error) {
games, err := gs.getGamesByCondition(condition)
if err != nil {
return nil, err
}
return games[0], nil
}
func (gs *GameStore) getGamesByCondition(condition sq.Eq) ([]*model.Game, error) {
rows, err := gs.Q().Select(userColumns...).
From("games").
Where(condition).
Query()
if err != nil {
return nil, err
}
defer rows.Close()
games, err := gs.gamesFromRows(rows)
if err != nil {
return nil, err
}
if len(games) == 0 {
return nil, sql.ErrNoRows
}
return games, nil
}
func (gs *GameStore) GetByID(id int) (*model.Game, error) {
return gs.getGameByCondition(sq.Eq{"id": id})
}
func (gs *GameStore) Create(name string, userID int) (*model.Game, error) {
// ToDo: generate transaction
// ToDo: add tests
res, err := gs.Q().Insert("games").
Columns(gameColumns[1:]...).
Values(name, userID).
Exec()
if err != nil {
return nil, err
}
id, err := res.LastInsertId()
if err != nil {
return nil, err
}
game, err := gs.GetByID(int(id))
if err != nil {
return nil, err
}
res, err = gs.Q().Insert("gamemember").
Columns(gameMemberColumns...).
Values(game.ID, userID, model.RoleGameMaster).
Exec()
if err != nil {
return nil, err
}
return game, nil
}

View file

@ -13,6 +13,7 @@ type Store struct {
Conn *sql.DB Conn *sql.DB
userStore *UserStore userStore *UserStore
gameStore *GameStore
} }
func addPathOptions(path string) string { func addPathOptions(path string) string {
@ -38,6 +39,7 @@ func NewStore(path string) (*Store, error) {
// init stores // init stores
s.userStore = NewUserStore(s) s.userStore = NewUserStore(s)
s.gameStore = NewGameStore(s)
return s, nil return s, nil
} }
@ -50,6 +52,10 @@ func (s *Store) User() *UserStore {
return s.userStore return s.userStore
} }
func (s *Store) Game() *GameStore {
return s.gameStore
}
func (s *Store) EnsureSchema() error { func (s *Store) EnsureSchema() error {
schema := ` schema := `
CREATE TABLE IF NOT EXISTS users ( CREATE TABLE IF NOT EXISTS users (

View file

@ -47,34 +47,27 @@ func (us *UserStore) usersFromRows(rows *sql.Rows) ([]*model.User, error) {
} }
func (us *UserStore) GetByID(id int) (*model.User, error) { func (us *UserStore) GetByID(id int) (*model.User, error) {
query := us.Q().Select(userColumns...). return us.getUserByCondition(sq.Eq{"id": id})
From("users"). }
Where(sq.Eq{"id": id})
rows, err := query.Query() func (us *UserStore) GetByUsername(username string) (*model.User, error) {
return us.getUserByCondition(sq.Eq{"username": username})
}
func (us *UserStore) getUserByCondition(condition sq.Eq) (*model.User, error) {
users, err := us.getUsersByCondition(condition)
if err != nil { if err != nil {
return nil, err return nil, err
} }
defer rows.Close()
users, err := us.usersFromRows(rows)
if err != nil {
return nil, err
}
if len(users) == 0 {
return nil, sql.ErrNoRows
}
return users[0], nil return users[0], nil
} }
func (us *UserStore) GetByUsername(username string) (*model.User, error) { func (us *UserStore) getUsersByCondition(condition sq.Eq) ([]*model.User, error) {
query := us.Q().Select(userColumns...). rows, err := us.Q().Select(userColumns...).
From("users"). From("users").
Where(sq.Eq{"username": username}) Where(condition).
Query()
rows, err := query.Query()
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -89,7 +82,7 @@ func (us *UserStore) GetByUsername(username string) (*model.User, error) {
return nil, sql.ErrNoRows return nil, sql.ErrNoRows
} }
return users[0], nil return users, nil
} }
func (us *UserStore) Create(user *model.User) (*model.User, error) { func (us *UserStore) Create(user *model.User) (*model.User, error) {
@ -112,24 +105,7 @@ func (us *UserStore) Create(user *model.User) (*model.User, error) {
// ToDo: add pagination and filtering // ToDo: add pagination and filtering
func (us *UserStore) List() ([]*model.User, error) { func (us *UserStore) List() ([]*model.User, error) {
rows, err := us.Q().Select(userColumns...). return us.getUsersByCondition(sq.Eq{})
From("users").
Query()
if err != nil {
return nil, err
}
defer rows.Close()
users, err := us.usersFromRows(rows)
if err != nil {
return nil, err
}
if len(users) == 0 {
return nil, sql.ErrNoRows
}
return users, nil
} }
func (us *UserStore) DeleteByUsername(username string) error { func (us *UserStore) DeleteByUsername(username string) error {