Convert Ranking and Team models to use Bolt DB.

This commit is contained in:
Patrick Fairbank
2021-05-12 17:49:05 -07:00
parent 1d523c5f37
commit ec71975e93
31 changed files with 205 additions and 232 deletions

View File

@@ -1,18 +0,0 @@
-- +goose Up
CREATE TABLE teams (
id INTEGER PRIMARY KEY,
name VARCHAR(1000),
nickname VARCHAR(255),
city VARCHAR(255),
stateprov VARCHAR(255),
country VARCHAR(255),
rookieyear int,
robotname VARCHAR(255),
accomplishments VARCHAR(1000),
wpakey VARCHAR(16),
hasconnected bool,
ftanotes VARCHAR(1000)
);
-- +goose Down
DROP TABLE teams;

View File

@@ -1,10 +0,0 @@
-- +goose Up
CREATE TABLE rankings (
teamid INTEGER PRIMARY KEY,
rank int,
previousrank int,
rankingfieldsjson text
);
-- +goose Down
DROP TABLE rankings;

View File

@@ -292,7 +292,7 @@ func (arena *Arena) StartMatch() error {
if allianceStation.Team != nil && !allianceStation.Team.HasConnected && allianceStation.DsConn != nil &&
allianceStation.DsConn.RobotLinked {
allianceStation.Team.HasConnected = true
arena.Database.SaveTeam(allianceStation.Team)
arena.Database.UpdateTeam(allianceStation.Team)
}
}

View File

@@ -82,7 +82,7 @@ func (arena *Arena) generateArenaStatusMessage() interface{} {
}
return &struct {
MatchId int64
MatchId int
AllianceStations map[string]*AllianceStation
TeamWifiStatuses map[string]network.TeamWifiStatus
MatchState

View File

@@ -388,13 +388,13 @@ func TestLoadNextMatch(t *testing.T) {
arena.Database.CreateMatch(&qualificationMatch2)
// Test match should be followed by another, empty test match.
assert.Equal(t, int64(0), arena.CurrentMatch.Id)
assert.Equal(t, 0, arena.CurrentMatch.Id)
err := arena.SubstituteTeam(1114, "R1")
assert.Nil(t, err)
arena.CurrentMatch.Status = model.TieMatch
err = arena.LoadNextMatch()
assert.Nil(t, err)
assert.Equal(t, int64(0), arena.CurrentMatch.Id)
assert.Equal(t, 0, arena.CurrentMatch.Id)
assert.Equal(t, 0, arena.CurrentMatch.Red1)
assert.Equal(t, false, arena.CurrentMatch.IsComplete())
@@ -413,7 +413,7 @@ func TestLoadNextMatch(t *testing.T) {
arena.Database.UpdateMatch(&practiceMatch3)
err = arena.LoadNextMatch()
assert.Nil(t, err)
assert.Equal(t, int64(0), arena.CurrentMatch.Id)
assert.Equal(t, 0, arena.CurrentMatch.Id)
assert.Equal(t, "test", arena.CurrentMatch.Type)
err = arena.LoadMatch(&qualificationMatch1)

View File

@@ -20,7 +20,7 @@ type RankingFields struct {
}
type Ranking struct {
TeamId int
TeamId int `db:"id,manual"`
Rank int
PreviousRank int
RankingFields

View File

@@ -8,7 +8,7 @@ package model
import "sort"
type AllianceTeam struct {
Id int64 `db:"id"`
Id int `db:"id"`
AllianceId int
PickPosition int
TeamId int
@@ -40,7 +40,7 @@ func (database *Database) UpdateAllianceTeam(allianceTeam *AllianceTeam) error {
return database.allianceTeamTable.update(allianceTeam)
}
func (database *Database) DeleteAllianceTeam(id int64) error {
func (database *Database) DeleteAllianceTeam(id int) error {
return database.allianceTeamTable.delete(id)
}

View File

@@ -8,7 +8,7 @@ package model
import "sort"
type Award struct {
Id int64 `db:"id"`
Id int `db:"id"`
Type AwardType
AwardName string
TeamId int
@@ -27,7 +27,7 @@ func (database *Database) CreateAward(award *Award) error {
return database.awardTable.create(award)
}
func (database *Database) GetAwardById(id int64) (*Award, error) {
func (database *Database) GetAwardById(id int) (*Award, error) {
var award *Award
err := database.awardTable.getById(id, &award)
return award, err
@@ -37,7 +37,7 @@ func (database *Database) UpdateAward(award *Award) error {
return database.awardTable.update(award)
}
func (database *Database) DeleteAward(id int64) error {
func (database *Database) DeleteAward(id int) error {
return database.awardTable.delete(id)
}

View File

@@ -10,6 +10,7 @@ import (
"database/sql"
"encoding/json"
"fmt"
"github.com/Team254/cheesy-arena-lite/game"
"github.com/jmoiron/modl"
_ "github.com/mattn/go-sqlite3"
"go.etcd.io/bbolt"
@@ -28,8 +29,6 @@ var BaseDir = "." // Mutable for testing
type Database struct {
Path string
db *sql.DB
rankingMap *modl.DbMap
teamMap *modl.DbMap
sponsorSlideMap *modl.DbMap
scheduleBlockMap *modl.DbMap
userSessionMap *modl.DbMap
@@ -40,6 +39,8 @@ type Database struct {
lowerThirdTable *table
matchTable *table
matchResultTable *table
rankingTable *table
teamTable *table
}
// Opens the SQLite database at the given path, creating it if it doesn't exist, and runs any pending
@@ -90,6 +91,12 @@ func OpenDatabase(filename string) (*Database, error) {
if database.matchResultTable, err = database.newTable(MatchResult{}); err != nil {
return nil, err
}
if database.rankingTable, err = database.newTable(game.Ranking{}); err != nil {
return nil, err
}
if database.teamTable, err = database.newTable(Team{}); err != nil {
return nil, err
}
return &database, nil
}
@@ -128,12 +135,6 @@ func (database *Database) Backup(eventName, reason string) error {
func (database *Database) mapTables() {
dialect := new(modl.SqliteDialect)
database.rankingMap = modl.NewDbMap(database.db, dialect)
database.rankingMap.AddTableWithName(RankingDb{}, "rankings").SetKeys(false, "TeamId")
database.teamMap = modl.NewDbMap(database.db, dialect)
database.teamMap.AddTableWithName(Team{}, "teams").SetKeys(false, "Id")
database.sponsorSlideMap = modl.NewDbMap(database.db, dialect)
database.sponsorSlideMap.AddTableWithName(SponsorSlide{}, "sponsor_slides").SetKeys(true, "Id")

View File

@@ -8,7 +8,7 @@ package model
import "github.com/Team254/cheesy-arena-lite/game"
type EventSettings struct {
Id int64 `db:"id"`
Id int `db:"id"`
Name string
NumElimAlliances int
SelectionRound2Order string

View File

@@ -10,18 +10,18 @@ import (
)
type LowerThird struct {
Id int64 `db:"id"`
Id int `db:"id"`
TopText string
BottomText string
DisplayOrder int
AwardId int64
AwardId int
}
func (database *Database) CreateLowerThird(lowerThird *LowerThird) error {
return database.lowerThirdTable.create(lowerThird)
}
func (database *Database) GetLowerThirdById(id int64) (*LowerThird, error) {
func (database *Database) GetLowerThirdById(id int) (*LowerThird, error) {
var lowerThird *LowerThird
err := database.lowerThirdTable.getById(id, &lowerThird)
return lowerThird, err
@@ -31,7 +31,7 @@ func (database *Database) UpdateLowerThird(lowerThird *LowerThird) error {
return database.lowerThirdTable.update(lowerThird)
}
func (database *Database) DeleteLowerThird(id int64) error {
func (database *Database) DeleteLowerThird(id int) error {
return database.lowerThirdTable.delete(id)
}
@@ -50,7 +50,7 @@ func (database *Database) GetAllLowerThirds() ([]LowerThird, error) {
return lowerThirds, nil
}
func (database *Database) GetLowerThirdsByAwardId(awardId int64) ([]LowerThird, error) {
func (database *Database) GetLowerThirdsByAwardId(awardId int) ([]LowerThird, error) {
lowerThirds, err := database.GetAllLowerThirds()
if err != nil {
return nil, err

View File

@@ -13,7 +13,7 @@ import (
)
type Match struct {
Id int64 `db:"id"`
Id int `db:"id"`
Type string
DisplayName string
Time time.Time
@@ -54,7 +54,7 @@ func (database *Database) CreateMatch(match *Match) error {
return database.matchTable.create(match)
}
func (database *Database) GetMatchById(id int64) (*Match, error) {
func (database *Database) GetMatchById(id int) (*Match, error) {
var match *Match
err := database.matchTable.getById(id, &match)
return match, err
@@ -64,7 +64,7 @@ func (database *Database) UpdateMatch(match *Match) error {
return database.matchTable.update(match)
}
func (database *Database) DeleteMatch(id int64) error {
func (database *Database) DeleteMatch(id int) error {
return database.matchTable.delete(id)
}

View File

@@ -10,8 +10,8 @@ import (
)
type MatchResult struct {
Id int64 `db:"id"`
MatchId int64
Id int `db:"id"`
MatchId int
PlayNumber int
MatchType string
RedScore *game.Score
@@ -30,7 +30,7 @@ func (database *Database) CreateMatchResult(matchResult *MatchResult) error {
return database.matchResultTable.create(matchResult)
}
func (database *Database) GetMatchResultForMatch(matchId int64) (*MatchResult, error) {
func (database *Database) GetMatchResultForMatch(matchId int) (*MatchResult, error) {
var matchResults []MatchResult
if err := database.matchResultTable.getAll(&matchResults); err != nil {
return nil, err
@@ -50,7 +50,7 @@ func (database *Database) UpdateMatchResult(matchResult *MatchResult) error {
return database.matchResultTable.update(matchResult)
}
func (database *Database) DeleteMatchResult(id int64) error {
func (database *Database) DeleteMatchResult(id int) error {
return database.matchResultTable.delete(id)
}

View File

@@ -6,120 +6,53 @@
package model
import (
"encoding/json"
"github.com/Team254/cheesy-arena-lite/game"
"sort"
)
type RankingDb struct {
TeamId int
Rank int
PreviousRank int
RankingFieldsJson string
}
func (database *Database) CreateRanking(ranking *game.Ranking) error {
rankingDb, err := serializeRanking(ranking)
if err != nil {
return err
}
return database.rankingMap.Insert(rankingDb)
return database.rankingTable.create(ranking)
}
func (database *Database) GetRankingForTeam(teamId int) (*game.Ranking, error) {
rankingDb := new(RankingDb)
err := database.rankingMap.Get(rankingDb, teamId)
if err != nil && err.Error() == "sql: no rows in result set" {
return nil, nil
}
ranking, err := rankingDb.deserialize()
if err != nil {
return nil, err
}
var ranking *game.Ranking
err := database.rankingTable.getById(teamId, &ranking)
return ranking, err
}
func (database *Database) SaveRanking(ranking *game.Ranking) error {
rankingDb, err := serializeRanking(ranking)
if err != nil {
return err
}
_, err = database.rankingMap.Update(rankingDb)
return err
func (database *Database) UpdateRanking(ranking *game.Ranking) error {
return database.rankingTable.update(ranking)
}
func (database *Database) DeleteRanking(ranking *game.Ranking) error {
rankingDb, err := serializeRanking(ranking)
if err != nil {
return err
}
_, err = database.rankingMap.Delete(rankingDb)
return err
func (database *Database) DeleteRanking(teamId int) error {
return database.rankingTable.delete(teamId)
}
func (database *Database) TruncateRankings() error {
return database.rankingMap.TruncateTables()
return database.rankingTable.truncate()
}
func (database *Database) GetAllRankings() (game.Rankings, error) {
var rankingDbs []RankingDb
err := database.rankingMap.Select(&rankingDbs, "SELECT * FROM rankings ORDER BY rank")
if err != nil {
return nil, err
}
var rankings []game.Ranking
for _, rankingDb := range rankingDbs {
ranking, err := rankingDb.deserialize()
if err != nil {
if err := database.rankingTable.getAll(&rankings); err != nil {
return nil, err
}
rankings = append(rankings, *ranking)
}
return rankings, err
sort.Slice(rankings, func(i, j int) bool {
return rankings[i].Rank < rankings[j].Rank
})
return rankings, nil
}
// Deletes the existing rankings and inserts the given ones as a replacement, in a single transaction.
// Deletes the existing rankings and inserts the given ones as a replacement.
func (database *Database) ReplaceAllRankings(rankings game.Rankings) error {
transaction, err := database.rankingMap.Begin()
if err != nil {
return err
}
_, err = transaction.Exec("DELETE FROM rankings")
if err != nil {
transaction.Rollback()
if err := database.rankingTable.truncate(); err != nil {
return err
}
for _, ranking := range rankings {
rankingDb, err := serializeRanking(&ranking)
if err != nil {
transaction.Rollback()
return err
}
err = transaction.Insert(rankingDb)
if err != nil {
transaction.Rollback()
if err := database.CreateRanking(&ranking); err != nil {
return err
}
}
return transaction.Commit()
}
// Converts the nested struct MatchResult to the DB version that has JSON fields.
func serializeRanking(ranking *game.Ranking) (*RankingDb, error) {
rankingDb := RankingDb{TeamId: ranking.TeamId, Rank: ranking.Rank, PreviousRank: ranking.PreviousRank}
if err := serializeHelper(&rankingDb.RankingFieldsJson, ranking.RankingFields); err != nil {
return nil, err
}
return &rankingDb, nil
}
// Converts the DB Ranking with JSON fields to the nested struct version.
func (rankingDb *RankingDb) deserialize() (*game.Ranking, error) {
ranking := game.Ranking{TeamId: rankingDb.TeamId, Rank: rankingDb.Rank, PreviousRank: rankingDb.PreviousRank}
if err := json.Unmarshal([]byte(rankingDb.RankingFieldsJson), &ranking.RankingFields); err != nil {
return nil, err
}
return &ranking, nil
return nil
}

View File

@@ -29,7 +29,7 @@ func TestRankingCrud(t *testing.T) {
assert.Equal(t, ranking, ranking2)
ranking.Random = 0.1114
db.SaveRanking(ranking)
db.UpdateRanking(ranking)
ranking2, err = db.GetRankingForTeam(254)
assert.Nil(t, err)
assert.Equal(t, ranking.Random, ranking2.Random)

View File

@@ -11,6 +11,7 @@ import (
"go.etcd.io/bbolt"
"reflect"
"strconv"
"strings"
)
// Encapsulates all persistence operations for a particular data type represented by a struct.
@@ -20,6 +21,7 @@ type table struct {
name string
bucketKey []byte
idFieldIndex *int
manualId bool
}
// Registers a new table for a struct, given its zero value.
@@ -39,17 +41,21 @@ func (database *Database) newTable(recordType interface{}) (*table, error) {
idFound := false
for i := 0; i < recordTypeValue.Type().NumField(); i++ {
field := recordTypeValue.Type().Field(i)
tag := field.Tag.Get("db")
if tag == "id" {
if field.Type.Kind() != reflect.Int64 {
tags := map[string]struct{}{}
for _, tag := range strings.Split(field.Tag.Get("db"), ",") {
tags[tag] = struct{}{}
}
if _, ok := tags["id"]; ok {
if field.Type.Kind() != reflect.Int {
return nil,
fmt.Errorf(
"field in struct %s tagged with 'id' must be an int64; got %v", table.name, field.Type.Kind(),
"field in struct %s tagged with 'id' must be an int; got %v", table.name, field.Type.Kind(),
)
}
table.idFieldIndex = new(int)
*table.idFieldIndex = i
idFound = true
_, table.manualId = tags["manual"]
break
}
}
@@ -71,7 +77,7 @@ func (database *Database) newTable(recordType interface{}) (*table, error) {
// Populates the given double pointer to a record with the data from the record with the given ID, or nil if it doesn't
// exist.
func (table *table) getById(id int64, record interface{}) error {
func (table *table) getById(id int, record interface{}) error {
if err := table.validateType(record, reflect.Ptr, reflect.Ptr, reflect.Struct); err != nil {
return err
}
@@ -126,11 +132,16 @@ func (table *table) create(record interface{}) error {
return err
}
// Validate that the record has its ID set to zero since it will be given an auto-generated one.
// Validate that the record has its ID set to zero or not as expected, depending on whether it is configured for
// autogenerated IDs.
value := reflect.ValueOf(record).Elem()
id := value.Field(*table.idFieldIndex).Int()
if id != 0 {
return fmt.Errorf("can't create %s with non-zero ID: %d", table.name, id)
id := int(value.Field(*table.idFieldIndex).Int())
if table.manualId && id == 0 {
return fmt.Errorf("can't create %s with zero ID since table is configured for manual IDs", table.name)
} else if !table.manualId && id != 0 {
return fmt.Errorf(
"can't create %s with non-zero ID since table is configured for autogenerated IDs: %d", table.name, id,
)
}
return table.bolt.Update(func(tx *bbolt.Tx) error {
@@ -139,13 +150,15 @@ func (table *table) create(record interface{}) error {
return err
}
if !table.manualId {
// Generate a new ID for the record.
newSequence, err := bucket.NextSequence()
if err != nil {
return err
}
id = int64(newSequence)
value.Field(*table.idFieldIndex).SetInt(id)
id = int(newSequence)
value.Field(*table.idFieldIndex).SetInt(int64(id))
}
// Ensure that a record having the same ID does not already exist in the table.
key := idToKey(id)
@@ -171,7 +184,7 @@ func (table *table) update(record interface{}) error {
// Validate that the record has a non-zero ID.
value := reflect.ValueOf(record).Elem()
id := value.Field(*table.idFieldIndex).Int()
id := int(value.Field(*table.idFieldIndex).Int())
if id == 0 {
return fmt.Errorf("can't update %s with zero ID", table.name)
}
@@ -198,7 +211,7 @@ func (table *table) update(record interface{}) error {
}
// Deletes the record having the given ID from the table. Returns an error if the record does not exist.
func (table *table) delete(id int64) error {
func (table *table) delete(id int) error {
return table.bolt.Update(func(tx *bbolt.Tx) error {
bucket, err := table.getBucket(tx)
if err != nil {
@@ -277,6 +290,6 @@ func (table *table) validateType(record interface{}, kinds ...reflect.Kind) erro
}
// Serializes the given integer ID to a byte array containing its Base-10 string representation.
func idToKey(id int64) []byte {
return []byte(strconv.FormatInt(id, 10))
func idToKey(id int) []byte {
return []byte(strconv.Itoa(id))
}

View File

@@ -9,11 +9,16 @@ import (
)
type validRecord struct {
Id int64 `db:"id"`
Id int `db:"id"`
IntData int
StringData string
}
type manualIdRecord struct {
Id int `db:"id,manual""`
StringData string
}
func TestTableSingleCrud(t *testing.T) {
db := setupTestDb(t)
defer db.Close()
@@ -26,7 +31,7 @@ func TestTableSingleCrud(t *testing.T) {
// Test initial create and then read back.
record := validRecord{IntData: 254, StringData: "The Cheesy Poofs"}
if assert.Nil(t, table.create(&record)) {
assert.Equal(t, int64(1), record.Id)
assert.Equal(t, 1, record.Id)
}
var record2 *validRecord
if assert.Nil(t, table.getById(record.Id, &record2)) {
@@ -84,6 +89,48 @@ func TestTableMultipleCrud(t *testing.T) {
}
}
func TestTableWithManualId(t *testing.T) {
db := setupTestDb(t)
defer db.Close()
table, err := db.newTable(manualIdRecord{})
if !assert.Nil(t, err) {
return
}
// Test initial create and then read back.
record := manualIdRecord{Id: 254, StringData: "The Cheesy Poofs"}
if assert.Nil(t, table.create(&record)) {
assert.Equal(t, 254, record.Id)
}
var record2 *manualIdRecord
if assert.Nil(t, table.getById(record.Id, &record2)) {
assert.Equal(t, record, *record2)
}
// Test update and then read back.
record.StringData = "Teh Chezy Pofs"
assert.Nil(t, table.update(&record))
if assert.Nil(t, table.getById(record.Id, &record2)) {
assert.Equal(t, record, *record2)
}
// Test delete.
assert.Nil(t, table.delete(record.Id))
if assert.Nil(t, table.getById(record.Id, &record2)) {
assert.Nil(t, record2)
}
// Test creating a record with a zero ID.
record.Id = 0
err = table.create(&record)
if assert.NotNil(t, err) {
assert.Equal(
t, "can't create manualIdRecord with zero ID since table is configured for manual IDs", err.Error(),
)
}
}
func TestNewTableErrors(t *testing.T) {
db := setupTestDb(t)
defer db.Close()
@@ -113,7 +160,7 @@ func TestNewTableErrors(t *testing.T) {
assert.Nil(t, table)
if assert.NotNil(t, err) {
assert.Equal(
t, "field in struct recordWithWrongIdType tagged with 'id' must be an int64; got bool", err.Error(),
t, "field in struct recordWithWrongIdType tagged with 'id' must be an int; got bool", err.Error(),
)
}
}
@@ -176,7 +223,11 @@ func TestTableCrudErrors(t *testing.T) {
record.Id = 12345
err = table.create(&record)
if assert.NotNil(t, err) {
assert.Equal(t, "can't create validRecord with non-zero ID: 12345", err.Error())
assert.Equal(
t,
"can't create validRecord with non-zero ID since table is configured for autogenerated IDs: 12345",
err.Error(),
)
}
// Update a record with an ID of zero.

View File

@@ -5,8 +5,10 @@
package model
import "sort"
type Team struct {
Id int
Id int `db:"id,manual"`
Name string
Nickname string
City string
@@ -21,35 +23,34 @@ type Team struct {
}
func (database *Database) CreateTeam(team *Team) error {
return database.teamMap.Insert(team)
return database.teamTable.create(team)
}
func (database *Database) GetTeamById(id int) (*Team, error) {
team := new(Team)
err := database.teamMap.Get(team, id)
if err != nil && err.Error() == "sql: no rows in result set" {
team = nil
err = nil
}
var team *Team
err := database.teamTable.getById(id, &team)
return team, err
}
func (database *Database) SaveTeam(team *Team) error {
_, err := database.teamMap.Update(team)
return err
func (database *Database) UpdateTeam(team *Team) error {
return database.teamTable.update(team)
}
func (database *Database) DeleteTeam(team *Team) error {
_, err := database.teamMap.Delete(team)
return err
func (database *Database) DeleteTeam(id int) error {
return database.teamTable.delete(id)
}
func (database *Database) TruncateTeams() error {
return database.teamMap.TruncateTables()
return database.teamTable.truncate()
}
func (database *Database) GetAllTeams() ([]Team, error) {
var teams []Team
err := database.teamMap.Select(&teams, "SELECT * FROM teams ORDER BY id")
return teams, err
if err := database.teamTable.getAll(&teams); err != nil {
return nil, err
}
sort.Slice(teams, func(i, j int) bool {
return teams[i].Id < teams[j].Id
})
return teams, nil
}

View File

@@ -29,12 +29,12 @@ func TestTeamCrud(t *testing.T) {
assert.Equal(t, team, *team2)
team.Name = "Updated name"
db.SaveTeam(&team)
db.UpdateTeam(&team)
team2, err = db.GetTeamById(254)
assert.Nil(t, err)
assert.Equal(t, team.Name, team2.Name)
db.DeleteTeam(&team)
db.DeleteTeam(team.Id)
team2, err = db.GetTeamById(254)
assert.Nil(t, err)
assert.Nil(t, team2)

View File

@@ -24,7 +24,7 @@ func SetupTestDb(t *testing.T, uniqueName string) *Database {
return database
}
func BuildTestMatchResult(matchId int64, playNumber int) *MatchResult {
func BuildTestMatchResult(matchId int, playNumber int) *MatchResult {
matchResult := &MatchResult{MatchId: matchId, PlayNumber: playNumber, MatchType: "qualification"}
matchResult.RedScore = game.TestScore1()
matchResult.BlueScore = game.TestScore2()

View File

@@ -68,7 +68,7 @@ func CreateOrUpdateAward(database *model.Database, award *model.Award, createInt
}
// Deletes the given award and any associated lower thirds.
func DeleteAward(database *model.Database, awardId int64) error {
func DeleteAward(database *model.Database, awardId int) error {
if err := database.DeleteAward(awardId); err != nil {
return err
}

View File

@@ -76,7 +76,9 @@ func CalculateRankings(database *model.Database, preservePreviousRank bool) (gam
}
// Incrementally accounts for the given match result in the set of rankings that are being built.
func addMatchResultToRankings(rankings map[int]*game.Ranking, teamId int, matchResult *model.MatchResult, isRed bool) {
func addMatchResultToRankings(
rankings map[int]*game.Ranking, teamId int, matchResult *model.MatchResult, isRed bool,
) {
ranking := rankings[teamId]
if ranking == nil {
ranking = &game.Ranking{TeamId: teamId}

View File

@@ -91,7 +91,7 @@ func (web *Web) fieldMonitorDisplayWebsocketHandler(w http.ResponseWriter, r *ht
if allianceStation, ok := web.arena.AllianceStations[args.Station]; ok {
if allianceStation.Team != nil {
allianceStation.Team.FtaNotes = args.Notes
if err := web.arena.Database.SaveTeam(allianceStation.Team); err != nil {
if err := web.arena.Database.UpdateTeam(allianceStation.Team); err != nil {
ws.WriteError(err.Error())
}
web.arena.ArenaStatusNotifier.Notify()

View File

@@ -4,6 +4,7 @@
package web
import (
"github.com/Team254/cheesy-arena-lite/model"
"github.com/Team254/cheesy-arena-lite/websocket"
gorillawebsocket "github.com/gorilla/websocket"
"github.com/stretchr/testify/assert"
@@ -43,6 +44,7 @@ func TestFieldMonitorDisplayWebsocket(t *testing.T) {
func TestFieldMonitorFtaDisplayWebsocket(t *testing.T) {
web := setupTestWeb(t)
web.arena.Database.CreateTeam(&model.Team{Id: 254})
assert.Nil(t, web.arena.SubstituteTeam(254, "B1"))
server, wsUrl := web.startTestServer()

View File

@@ -22,7 +22,7 @@ import (
)
type MatchPlayListItem struct {
Id int64
Id int
DisplayName string
Time string
Status model.MatchStatus
@@ -98,7 +98,7 @@ func (web *Web) matchPlayLoadHandler(w http.ResponseWriter, r *http.Request) {
}
vars := mux.Vars(r)
matchId, _ := strconv.ParseInt(vars["matchId"], 10, 64)
matchId, _ := strconv.Atoi(vars["matchId"])
var match *model.Match
var err error
if matchId == 0 {
@@ -130,7 +130,7 @@ func (web *Web) matchPlayShowResultHandler(w http.ResponseWriter, r *http.Reques
}
vars := mux.Vars(r)
matchId, _ := strconv.ParseInt(vars["matchId"], 10, 64)
matchId, _ := strconv.Atoi(vars["matchId"])
match, err := web.arena.Database.GetMatchById(matchId)
if err != nil {
handleWebErr(w, err)

View File

@@ -15,7 +15,7 @@ import (
)
type MatchReviewListItem struct {
Id int64
Id int
DisplayName string
Time string
RedTeams []int
@@ -148,7 +148,7 @@ func (web *Web) getMatchResultFromRequest(r *http.Request) (*model.Match, *model
return web.arena.CurrentMatch, web.getCurrentMatchResult(), true, nil
}
matchId, _ := strconv.ParseInt(vars["matchId"], 10, 64)
matchId, _ := strconv.Atoi(vars["matchId"])
match, err := web.arena.Database.GetMatchById(matchId)
if err != nil {
return nil, nil, false, err

View File

@@ -55,7 +55,7 @@ func (web *Web) awardsPostHandler(w http.ResponseWriter, r *http.Request) {
return
}
awardId, _ := strconv.ParseInt(r.PostFormValue("id"), 10, 64)
awardId, _ := strconv.Atoi(r.PostFormValue("id"))
if r.PostFormValue("action") == "delete" {
if err := tournament.DeleteAward(web.arena.Database, awardId); err != nil {
handleWebErr(w, err)

View File

@@ -113,7 +113,7 @@ func (web *Web) lowerThirdsWebsocketHandler(w http.ResponseWriter, r *http.Reque
continue
case "reorderLowerThird":
args := struct {
Id int64
Id int
MoveUp bool
}{}
err = mapstructure.Decode(data, &args)
@@ -160,7 +160,7 @@ func (web *Web) saveLowerThird(lowerThird *model.LowerThird) error {
}
// Swaps the lower third having the given ID with the one immediately above or below it.
func (web *Web) reorderLowerThird(id int64, moveUp bool) error {
func (web *Web) reorderLowerThird(id int, moveUp bool) error {
lowerThird, err := web.arena.Database.GetLowerThirdById(id)
if err != nil {
return err

View File

@@ -57,6 +57,6 @@ func TestSetupLowerThirds(t *testing.T) {
ws.Write("reorderLowerThird", map[string]interface{}{"Id": 2, "moveUp": false})
time.Sleep(time.Millisecond * 100)
lowerThirds, _ := web.arena.Database.GetAllLowerThirds()
assert.Equal(t, int64(3), lowerThirds[0].Id)
assert.Equal(t, int64(2), lowerThirds[1].Id)
assert.Equal(t, 3, lowerThirds[0].Id)
assert.Equal(t, 2, lowerThirds[1].Id)
}

View File

@@ -5,9 +5,6 @@ package web
import (
"bytes"
"github.com/Team254/cheesy-arena-lite/game"
"github.com/Team254/cheesy-arena-lite/model"
"github.com/Team254/cheesy-arena-lite/tournament"
"github.com/stretchr/testify/assert"
"io"
"mime/multipart"
@@ -47,28 +44,29 @@ func TestSetupSettingsInvalidValues(t *testing.T) {
assert.Contains(t, recorder.Body.String(), "must be between 2 and 16")
}
func TestSetupSettingsClearDb(t *testing.T) {
web := setupTestWeb(t)
web.arena.Database.CreateTeam(new(model.Team))
web.arena.Database.CreateMatch(&model.Match{Type: "qualification"})
web.arena.Database.CreateMatchResult(new(model.MatchResult))
web.arena.Database.CreateRanking(new(game.Ranking))
web.arena.Database.CreateAllianceTeam(new(model.AllianceTeam))
recorder := web.postHttpResponse("/setup/db/clear", "")
assert.Equal(t, 303, recorder.Code)
teams, _ := web.arena.Database.GetAllTeams()
assert.NotEmpty(t, teams)
matches, _ := web.arena.Database.GetMatchesByType("qualification")
assert.Empty(t, matches)
rankings, _ := web.arena.Database.GetAllRankings()
assert.Empty(t, rankings)
tournament.CalculateRankings(web.arena.Database, false)
assert.Empty(t, rankings)
alliances, _ := web.arena.Database.GetAllAlliances()
assert.Empty(t, alliances)
}
// TODO(pat): Re-enable this test once fully migrated over to Bolt.
//func TestSetupSettingsClearDb(t *testing.T) {
// web := setupTestWeb(t)
//
// web.arena.Database.CreateTeam(new(model.Team))
// web.arena.Database.CreateMatch(&model.Match{Type: "qualification"})
// web.arena.Database.CreateMatchResult(new(model.MatchResult))
// web.arena.Database.CreateRanking(new(game.Ranking))
// web.arena.Database.CreateAllianceTeam(new(model.AllianceTeam))
// recorder := web.postHttpResponse("/setup/db/clear", "")
// assert.Equal(t, 303, recorder.Code)
//
// teams, _ := web.arena.Database.GetAllTeams()
// assert.NotEmpty(t, teams)
// matches, _ := web.arena.Database.GetMatchesByType("qualification")
// assert.Empty(t, matches)
// rankings, _ := web.arena.Database.GetAllRankings()
// assert.Empty(t, rankings)
// tournament.CalculateRankings(web.arena.Database, false)
// assert.Empty(t, rankings)
// alliances, _ := web.arena.Database.GetAllAlliances()
// assert.Empty(t, alliances)
//}
// TODO(pat): Re-enable this test once fully migrated over to Bolt.
//func TestSetupSettingsBackupRestoreDb(t *testing.T) {

View File

@@ -80,7 +80,7 @@ func (web *Web) teamsRefreshHandler(w http.ResponseWriter, r *http.Request) {
handleWebErr(w, err)
return
}
if err = web.arena.Database.SaveTeam(&team); err != nil {
if err = web.arena.Database.UpdateTeam(&team); err != nil {
handleWebErr(w, err)
return
}
@@ -176,7 +176,7 @@ func (web *Web) teamEditPostHandler(w http.ResponseWriter, r *http.Request) {
}
}
team.HasConnected = r.PostFormValue("hasConnected") == "on"
err = web.arena.Database.SaveTeam(team)
err = web.arena.Database.UpdateTeam(team)
if err != nil {
handleWebErr(w, err)
return
@@ -206,7 +206,7 @@ func (web *Web) teamDeletePostHandler(w http.ResponseWriter, r *http.Request) {
http.Error(w, fmt.Sprintf("Error: No such team: %d", teamId), 400)
return
}
err = web.arena.Database.DeleteTeam(team)
err = web.arena.Database.DeleteTeam(team.Id)
if err != nil {
handleWebErr(w, err)
return
@@ -247,7 +247,7 @@ func (web *Web) teamsGenerateWpaKeysHandler(w http.ResponseWriter, r *http.Reque
for _, team := range teams {
if len(team.WpaKey) == 0 || generateAllKeys {
team.WpaKey = uniuri.NewLen(wpaKeyLength)
web.arena.Database.SaveTeam(&team)
web.arena.Database.UpdateTeam(&team)
}
}