280 lines
6.4 KiB
Go
280 lines
6.4 KiB
Go
package repo
|
|
|
|
import (
|
|
"database/sql"
|
|
"fmt"
|
|
"time"
|
|
|
|
"git.kapelle.org/niklas/beerpong-elo/internal/model"
|
|
_ "github.com/go-sql-driver/mysql"
|
|
)
|
|
|
|
type SQLRepo struct {
|
|
db *sql.DB
|
|
}
|
|
|
|
func NewSQLRepo(host, username, password, dbName string) (Repo, error) {
|
|
db, err := sql.Open("mysql", fmt.Sprintf("%s:%s@tcp(%s)/%s?parseTime=true", username, password, host, dbName))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
db.SetConnMaxLifetime(time.Minute * 3)
|
|
db.SetMaxOpenConns(10)
|
|
db.SetMaxIdleConns(10)
|
|
|
|
return &SQLRepo{
|
|
db: db,
|
|
}, nil
|
|
}
|
|
|
|
func (s *SQLRepo) AddGame(game model.Game) (model.GameID, error) {
|
|
stmt, err := s.db.Prepare("INSERT INTO Games(added,score,overtime,author,team0player0,team0player1,team1player0,team1player1) VALUES (?,?,?,?,?,?,?,?)")
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
res, err := stmt.Exec(game.Added, game.Score, game.Overtime, game.Author, game.Team0Player0, game.Team0Player1, game.Team1Player0, game.Team1Player1)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
id, err := res.LastInsertId()
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
var gameID model.GameID
|
|
gameID.Scan(id)
|
|
|
|
return gameID, nil
|
|
}
|
|
|
|
func (s *SQLRepo) AddGameResult(gameResult model.GameResult) (model.GameResultID, error) {
|
|
stms, err := s.db.Prepare("INSERT INTO GameResults(game,player,startElo,endElo) VALUES (?,?,?,?)")
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
res, err := stms.Exec(gameResult.Game, gameResult.Player, gameResult.StartElo, gameResult.EndElo)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
id, err := res.LastInsertId()
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
var gameResultID model.GameResultID
|
|
gameResultID.Scan(id)
|
|
|
|
return gameResultID, nil
|
|
}
|
|
|
|
func (s *SQLRepo) GetGame(id model.GameID) (*model.Game, error) {
|
|
rows := s.db.QueryRow("SELECT id,added, score,overtime,author,team0player0,team0player1,team1player0,team1player1 FROM Games WHERE id = ? ", id)
|
|
|
|
var game model.Game
|
|
|
|
if err := rows.Scan(&game.ID, &game.Added, &game.Score, &game.Overtime, &game.Author, &game.Team0Player0, &game.Team0Player1, &game.Team1Player0, &game.Team1Player1); err != nil {
|
|
if err == sql.ErrNoRows {
|
|
return nil, nil
|
|
}
|
|
return nil, err
|
|
}
|
|
|
|
return &game, nil
|
|
}
|
|
|
|
func (s *SQLRepo) GetGameResult(id model.GameResultID) (*model.GameResult, error) {
|
|
rows := s.db.QueryRow("SELECT game,player,startElo,endElo FROM GameResults WHERE id = ? ", id)
|
|
|
|
var gameResult model.GameResult
|
|
gameResult.ID = id
|
|
|
|
if err := rows.Scan(&gameResult.Game, &gameResult.Player, &gameResult.StartElo, &gameResult.EndElo); err != nil {
|
|
if err == sql.ErrNoRows {
|
|
return nil, nil
|
|
}
|
|
return nil, err
|
|
}
|
|
|
|
return &gameResult, nil
|
|
}
|
|
|
|
func (s *SQLRepo) playerWithNameExists(name string) (*model.PlayerID, error) {
|
|
rows := s.db.QueryRow("SELECT id FROM Players WHERE name = ?", name)
|
|
|
|
var id model.PlayerID
|
|
|
|
if err := rows.Scan(&id); err != nil {
|
|
if err == sql.ErrNoRows {
|
|
return nil, nil
|
|
}
|
|
return nil, err
|
|
}
|
|
|
|
return &id, nil
|
|
}
|
|
|
|
func (s *SQLRepo) GetOrCreatePlayerID(name string) (model.PlayerID, error) {
|
|
foundID, err := s.playerWithNameExists(name)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
if foundID != nil {
|
|
return *foundID, nil
|
|
}
|
|
|
|
stmt, err := s.db.Prepare("INSERT INTO Players(name,elo) VALUES (?,?)")
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
newPlayer := model.NewPlayer(name)
|
|
|
|
res, err := stmt.Exec(newPlayer.Name, newPlayer.Elo)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
id, err := res.LastInsertId()
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
var playerID model.PlayerID
|
|
playerID.Scan(id)
|
|
|
|
return playerID, nil
|
|
}
|
|
|
|
func (s *SQLRepo) GetPlayer(id model.PlayerID) (*model.Player, error) {
|
|
rows := s.db.QueryRow("SELECT name,elo from Players WHERE id = ?", id)
|
|
|
|
var player model.Player
|
|
player.ID = id
|
|
|
|
if err := rows.Scan(&player.Name, &player.Elo); err != nil {
|
|
if err == sql.ErrNoRows {
|
|
return nil, nil
|
|
}
|
|
return nil, err
|
|
}
|
|
|
|
return &player, nil
|
|
}
|
|
|
|
func (s *SQLRepo) GetGamesForPlayer(id model.PlayerID) ([]*model.Game, error) {
|
|
rows, err := s.db.Query(`
|
|
SELECT id,added, score,overtime,author,team0player0,team0player1,team1player0,team1player1
|
|
FROM Games
|
|
WHERE team0player0 = ? OR team0player1 = ? OR team1player0 = ? OR team1player1 = ?
|
|
`, id, id, id, id)
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
defer rows.Close()
|
|
|
|
rtn := []*model.Game{}
|
|
|
|
for rows.Next() {
|
|
var game model.Game
|
|
err = rows.Scan(&game.ID, &game.Added, &game.Score, &game.Overtime, &game.Author, &game.Team0Player0, &game.Team0Player1, &game.Team1Player0, &game.Team1Player1)
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
rtn = append(rtn, &game)
|
|
}
|
|
|
|
return rtn, nil
|
|
}
|
|
|
|
func (s *SQLRepo) GetGameResultForPlayerAndGame(gameID model.GameID, playerID model.PlayerID) (*model.GameResult, error) {
|
|
rows := s.db.QueryRow("SELECT id,game,player,startElo,endElo FROM GameResults WHERE game = ? AND player = ? ", gameID, playerID)
|
|
|
|
var gameResult model.GameResult
|
|
|
|
if err := rows.Scan(&gameResult.ID, &gameResult.Game, &gameResult.Player, &gameResult.StartElo, &gameResult.EndElo); err != nil {
|
|
if err == sql.ErrNoRows {
|
|
return nil, nil
|
|
}
|
|
return nil, err
|
|
}
|
|
|
|
return &gameResult, nil
|
|
}
|
|
|
|
func (s *SQLRepo) GetGameResultsForPlayer(id model.PlayerID) ([]*model.GameResult, error) {
|
|
rows, err := s.db.Query("SELECT id,game,player,startElo,endElo FROM GameResults WHERE player = ? ", id)
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
rtn := []*model.GameResult{}
|
|
|
|
for rows.Next() {
|
|
var gameResult model.GameResult
|
|
|
|
err = rows.Scan(&gameResult.ID, &gameResult.Game, &gameResult.Player, &gameResult.StartElo, &gameResult.EndElo)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
rtn = append(rtn, &gameResult)
|
|
}
|
|
|
|
return rtn, nil
|
|
}
|
|
|
|
func (s *SQLRepo) GetPlayers() ([]*model.Player, error) {
|
|
rows, err := s.db.Query("SELECT id, name, elo FROM Players")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
rtn := []*model.Player{}
|
|
|
|
for rows.Next() {
|
|
var player model.Player
|
|
|
|
err = rows.Scan(&player.ID, &player.Name, &player.Elo)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
rtn = append(rtn, &player)
|
|
}
|
|
|
|
return rtn, nil
|
|
}
|
|
|
|
func (s *SQLRepo) GetGames() ([]*model.Game, error) {
|
|
rows, err := s.db.Query("SELECT id,added, score,overtime,author,team0player0,team0player1,team1player0,team1player1 FROM Games")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
rtn := []*model.Game{}
|
|
|
|
for rows.Next() {
|
|
var game model.Game
|
|
err = rows.Scan(&game.ID, &game.Added, &game.Score, &game.Overtime, &game.Author, &game.Team0Player0, &game.Team0Player1, &game.Team1Player0, &game.Team1Player1)
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
rtn = append(rtn, &game)
|
|
}
|
|
|
|
return rtn, nil
|
|
}
|