mirror of
https://github.com/Team254/cheesy-arena-lite.git
synced 2026-03-10 06:06:47 -04:00
Convert ScheduleBlock, SponsorSlide, and UserSession models to use Bolt DB and clean up remaining SQLite artifacts.
This commit is contained in:
@@ -1,4 +0,0 @@
|
||||
# This file must exist to be able to create migration boilerplate with `goose create MigrationName sql`.
|
||||
development:
|
||||
driver: sqlite3
|
||||
open: placeholder.db # Doesn't matter what this value is; the file won't be created.
|
||||
@@ -1,13 +0,0 @@
|
||||
-- +goose Up
|
||||
CREATE TABLE sponsor_slides (
|
||||
id INTEGER PRIMARY KEY,
|
||||
subtitle VARCHAR(255),
|
||||
line1 VARCHAR(255),
|
||||
line2 VARCHAR(255),
|
||||
image VARCHAR(255),
|
||||
displaytimesec int,
|
||||
displayorder int
|
||||
);
|
||||
|
||||
-- +goose Down
|
||||
DROP TABLE sponsor_slides;
|
||||
@@ -1,11 +0,0 @@
|
||||
-- +goose Up
|
||||
CREATE TABLE schedule_blocks (
|
||||
id INTEGER PRIMARY KEY,
|
||||
matchtype VARCHAR(16),
|
||||
starttime DATETIME,
|
||||
nummatches int,
|
||||
matchspacingsec int
|
||||
);
|
||||
|
||||
-- +goose Down
|
||||
DROP TABLE schedule_blocks;
|
||||
@@ -1,11 +0,0 @@
|
||||
-- +goose Up
|
||||
CREATE TABLE user_sessions (
|
||||
id INTEGER PRIMARY KEY,
|
||||
token VARCHAR(255),
|
||||
username VARCHAR(255),
|
||||
createdat DATETIME
|
||||
);
|
||||
CREATE UNIQUE INDEX token ON user_sessions(token);
|
||||
|
||||
-- +goose Down
|
||||
DROP TABLE user_sessions;
|
||||
@@ -21,7 +21,6 @@ func SetupTestArena(t *testing.T, uniqueName string) *Arena {
|
||||
model.BaseDir = ".."
|
||||
dbPath := filepath.Join(model.BaseDir, fmt.Sprintf("%s_test.db", uniqueName))
|
||||
os.Remove(dbPath)
|
||||
os.Remove(dbPath + ".bolt")
|
||||
arena, err := NewArena(dbPath)
|
||||
assert.Nil(t, err)
|
||||
return arena
|
||||
|
||||
9
go.mod
9
go.mod
@@ -3,22 +3,15 @@ module github.com/Team254/cheesy-arena-lite
|
||||
go 1.16
|
||||
|
||||
require (
|
||||
bitbucket.org/liamstask/goose v0.0.0-20150115234039-8488cc47d90c
|
||||
github.com/dchest/uniuri v0.0.0-20200228104902-7aecb25e1fe5
|
||||
github.com/goburrow/modbus v0.1.0
|
||||
github.com/goburrow/serial v0.1.0 // indirect
|
||||
github.com/google/uuid v1.2.0
|
||||
github.com/gorilla/mux v1.8.0
|
||||
github.com/gorilla/websocket v1.4.2
|
||||
github.com/jmoiron/modl v0.0.0-20160417153729-99654d091ece
|
||||
github.com/jmoiron/sqlx v1.3.1 // indirect
|
||||
github.com/jung-kurt/gofpdf v1.16.2
|
||||
github.com/kylelemons/go-gypsy v1.0.0 // indirect
|
||||
github.com/lib/pq v1.10.0 // indirect
|
||||
github.com/mattn/go-sqlite3 v1.14.6
|
||||
github.com/mitchellh/mapstructure v1.4.1
|
||||
github.com/stretchr/testify v1.7.0
|
||||
github.com/ziutek/mymysql v1.5.4 // indirect
|
||||
go.etcd.io/bbolt v1.3.5 // indirect
|
||||
go.etcd.io/bbolt v1.3.5
|
||||
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83
|
||||
)
|
||||
|
||||
18
go.sum
18
go.sum
@@ -1,12 +1,8 @@
|
||||
bitbucket.org/liamstask/goose v0.0.0-20150115234039-8488cc47d90c h1:bkb2NMGo3/Du52wvYj9Whth5KZfMV6d3O0Vbr3nz/UE=
|
||||
bitbucket.org/liamstask/goose v0.0.0-20150115234039-8488cc47d90c/go.mod h1:hSVuE3qU7grINVSwrmzHfpg9k87ALBk+XaualNyUzI4=
|
||||
github.com/boombuler/barcode v1.0.0/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
|
||||
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dchest/uniuri v0.0.0-20200228104902-7aecb25e1fe5 h1:RAV05c0xOkJ3dZGS0JFybxFKZ2WMLabgx3uXnd7rpGs=
|
||||
github.com/dchest/uniuri v0.0.0-20200228104902-7aecb25e1fe5/go.mod h1:GgB8SF9nRG+GqaDtLcwJZsQFhcogVCJ79j4EdT0c2V4=
|
||||
github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs=
|
||||
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||
github.com/goburrow/modbus v0.1.0 h1:DejRZY73nEM6+bt5JSP6IsFolJ9dVcqxsYbpLbeW/ro=
|
||||
github.com/goburrow/modbus v0.1.0/go.mod h1:Kx552D5rLIS8E7TyUwQ/UdHEqvX5T8tyiGBTlzMcZBg=
|
||||
github.com/goburrow/serial v0.1.0 h1:v2T1SQa/dlUqQiYIT8+Cu7YolfqAi3K96UmhwYyuSrA=
|
||||
@@ -17,20 +13,9 @@ github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
|
||||
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
|
||||
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
|
||||
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/jmoiron/modl v0.0.0-20160417153729-99654d091ece h1:qQnxwLnhKw20aVL0y1pBcgrYRHQsQ7AjP1tVMHCvW/k=
|
||||
github.com/jmoiron/modl v0.0.0-20160417153729-99654d091ece/go.mod h1:SPl18BowAOUHDzGHpUepQ9OJICtoL27Rbz3K+kJoQ6I=
|
||||
github.com/jmoiron/sqlx v1.3.1 h1:aLN7YINNZ7cYOPK3QC83dbM6KT0NMqVMw961TqrejlE=
|
||||
github.com/jmoiron/sqlx v1.3.1/go.mod h1:2BljVx/86SuTyjE+aPYlHCTNvZrnJXghYGpNiXLBMCQ=
|
||||
github.com/jung-kurt/gofpdf v1.0.0/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes=
|
||||
github.com/jung-kurt/gofpdf v1.16.2 h1:jgbatWHfRlPYiK85qgevsZTHviWXKwB1TTiKdz5PtRc=
|
||||
github.com/jung-kurt/gofpdf v1.16.2/go.mod h1:1hl7y57EsiPAkLbOwzpzqgx1A30nQCk/YmFV8S2vmK0=
|
||||
github.com/kylelemons/go-gypsy v1.0.0 h1:7/wQ7A3UL1bnqRMnZ6T8cwCOArfZCxFmb1iTxaOOo1s=
|
||||
github.com/kylelemons/go-gypsy v1.0.0/go.mod h1:chkXM0zjdpXOiqkCW1XcCHDfjfk14PH2KKkQWxfJUcU=
|
||||
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.10.0 h1:Zx5DJFEYQXio93kgXnQ09fXNiUKsqv4OUEu2UtGcB1E=
|
||||
github.com/lib/pq v1.10.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/mattn/go-sqlite3 v1.14.6 h1:dNPt6NO46WmLVt2DLNpwczCmdV5boIZ6g/tlDrlRUbg=
|
||||
github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||
github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag=
|
||||
github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/phpdave11/gofpdi v1.0.7/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI=
|
||||
@@ -42,8 +27,6 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/ziutek/mymysql v1.5.4 h1:GB0qdRGsTwQSBVYuVShFBKaXSnSnYYC2d9knnE1LHFs=
|
||||
github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0=
|
||||
go.etcd.io/bbolt v1.3.5 h1:XAzx9gjCb0Rxj7EoqcClPD1d5ZBxZJk0jbuoPHenBt0=
|
||||
go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
@@ -52,7 +35,6 @@ golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWP
|
||||
golang.org/x/image v0.0.0-20190910094157-69e4b8554b2a/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5 h1:LfCXLvNmTYH9kEmVgqbnsWfruoXZIrh4YBgqVHtDvw0=
|
||||
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
|
||||
@@ -1,18 +1,13 @@
|
||||
// Copyright 2014 Team 254. All Rights Reserved.
|
||||
// Author: pat@patfairbank.com (Patrick Fairbank)
|
||||
//
|
||||
// Functions for manipulating the per-event SQLite datastore.
|
||||
// Functions for manipulating the per-event Bolt datastore.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"bitbucket.org/liamstask/goose/lib/goose"
|
||||
"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"
|
||||
"io"
|
||||
"os"
|
||||
@@ -22,16 +17,11 @@ import (
|
||||
)
|
||||
|
||||
const backupsDir = "db/backups"
|
||||
const migrationsDir = "db/migrations"
|
||||
|
||||
var BaseDir = "." // Mutable for testing
|
||||
|
||||
type Database struct {
|
||||
Path string
|
||||
db *sql.DB
|
||||
sponsorSlideMap *modl.DbMap
|
||||
scheduleBlockMap *modl.DbMap
|
||||
userSessionMap *modl.DbMap
|
||||
bolt *bbolt.DB
|
||||
allianceTeamTable *table
|
||||
awardTable *table
|
||||
@@ -40,34 +30,17 @@ type Database struct {
|
||||
matchTable *table
|
||||
matchResultTable *table
|
||||
rankingTable *table
|
||||
scheduleBlockTable *table
|
||||
sponsorSlideTable *table
|
||||
teamTable *table
|
||||
userSessionTable *table
|
||||
}
|
||||
|
||||
// Opens the SQLite database at the given path, creating it if it doesn't exist, and runs any pending
|
||||
// migrations.
|
||||
// Opens the Bolt database at the given path, creating it if it doesn't exist.
|
||||
func OpenDatabase(filename string) (*Database, error) {
|
||||
// Find and run the migrations using goose. This also auto-creates the DB.
|
||||
database := Database{Path: filename}
|
||||
migrationsPath := filepath.Join(BaseDir, migrationsDir)
|
||||
dbDriver := goose.DBDriver{"sqlite3", database.Path, "github.com/mattn/go-sqlite3", &goose.Sqlite3Dialect{}}
|
||||
dbConf := goose.DBConf{MigrationsDir: migrationsPath, Env: "prod", Driver: dbDriver}
|
||||
target, err := goose.GetMostRecentDBVersion(migrationsPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = goose.RunMigrations(&dbConf, migrationsPath, target)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
db, err := sql.Open("sqlite3", database.Path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
database.db = db
|
||||
database.mapTables()
|
||||
|
||||
database.bolt, err = bbolt.Open(database.Path+".bolt", 0644, &bbolt.Options{NoSync: true, Timeout: time.Second})
|
||||
var err error
|
||||
database.bolt, err = bbolt.Open(database.Path, 0644, &bbolt.Options{NoSync: true, Timeout: time.Second})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -94,15 +67,23 @@ func OpenDatabase(filename string) (*Database, error) {
|
||||
if database.rankingTable, err = database.newTable(game.Ranking{}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if database.scheduleBlockTable, err = database.newTable(ScheduleBlock{}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if database.sponsorSlideTable, err = database.newTable(SponsorSlide{}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if database.teamTable, err = database.newTable(Team{}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if database.userSessionTable, err = database.newTable(UserSession{}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &database, nil
|
||||
}
|
||||
|
||||
func (database *Database) Close() error {
|
||||
database.db.Close()
|
||||
return database.bolt.Close()
|
||||
}
|
||||
|
||||
@@ -130,26 +111,3 @@ func (database *Database) Backup(eventName, reason string) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Sets up table-object associations.
|
||||
func (database *Database) mapTables() {
|
||||
dialect := new(modl.SqliteDialect)
|
||||
|
||||
database.sponsorSlideMap = modl.NewDbMap(database.db, dialect)
|
||||
database.sponsorSlideMap.AddTableWithName(SponsorSlide{}, "sponsor_slides").SetKeys(true, "Id")
|
||||
|
||||
database.scheduleBlockMap = modl.NewDbMap(database.db, dialect)
|
||||
database.scheduleBlockMap.AddTableWithName(ScheduleBlock{}, "schedule_blocks").SetKeys(true, "Id")
|
||||
|
||||
database.userSessionMap = modl.NewDbMap(database.db, dialect)
|
||||
database.userSessionMap.AddTableWithName(UserSession{}, "user_sessions").SetKeys(true, "Id")
|
||||
}
|
||||
|
||||
func serializeHelper(target *string, source interface{}) error {
|
||||
bytes, err := json.Marshal(source)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*target = string(bytes)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -6,11 +6,12 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"sort"
|
||||
"time"
|
||||
)
|
||||
|
||||
type ScheduleBlock struct {
|
||||
Id int
|
||||
Id int `db:"id"`
|
||||
MatchType string
|
||||
StartTime time.Time
|
||||
NumMatches int
|
||||
@@ -18,21 +19,42 @@ type ScheduleBlock struct {
|
||||
}
|
||||
|
||||
func (database *Database) CreateScheduleBlock(block *ScheduleBlock) error {
|
||||
return database.scheduleBlockMap.Insert(block)
|
||||
return database.scheduleBlockTable.create(block)
|
||||
}
|
||||
|
||||
func (database *Database) GetScheduleBlocksByMatchType(matchType string) ([]ScheduleBlock, error) {
|
||||
var blocks []ScheduleBlock
|
||||
err := database.scheduleBlockMap.Select(&blocks, "SELECT * FROM schedule_blocks WHERE matchtype = ? ORDER BY "+
|
||||
"starttime ", matchType)
|
||||
return blocks, err
|
||||
var scheduleBlocks []ScheduleBlock
|
||||
if err := database.scheduleBlockTable.getAll(&scheduleBlocks); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var matchingScheduleBlocks []ScheduleBlock
|
||||
for _, scheduleBlock := range scheduleBlocks {
|
||||
if scheduleBlock.MatchType == matchType {
|
||||
matchingScheduleBlocks = append(matchingScheduleBlocks, scheduleBlock)
|
||||
}
|
||||
}
|
||||
|
||||
sort.Slice(matchingScheduleBlocks, func(i, j int) bool {
|
||||
return matchingScheduleBlocks[i].StartTime.Before(matchingScheduleBlocks[j].StartTime)
|
||||
})
|
||||
return matchingScheduleBlocks, nil
|
||||
}
|
||||
|
||||
func (database *Database) DeleteScheduleBlocksByMatchType(matchType string) error {
|
||||
_, err := database.scheduleBlockMap.Exec("DELETE FROM schedule_blocks WHERE matchtype = ?", matchType)
|
||||
return err
|
||||
scheduleBlocks, err := database.GetScheduleBlocksByMatchType(matchType)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, scheduleBlock := range scheduleBlocks {
|
||||
if err = database.scheduleBlockTable.delete(scheduleBlock.Id); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (database *Database) TruncateScheduleBlocks() error {
|
||||
return database.scheduleBlockMap.TruncateTables()
|
||||
return database.scheduleBlockTable.truncate()
|
||||
}
|
||||
|
||||
@@ -5,8 +5,10 @@
|
||||
|
||||
package model
|
||||
|
||||
import "sort"
|
||||
|
||||
type SponsorSlide struct {
|
||||
Id int
|
||||
Id int `db:"id"`
|
||||
Subtitle string
|
||||
Line1 string
|
||||
Line2 string
|
||||
@@ -16,41 +18,45 @@ type SponsorSlide struct {
|
||||
}
|
||||
|
||||
func (database *Database) CreateSponsorSlide(sponsorSlide *SponsorSlide) error {
|
||||
return database.sponsorSlideMap.Insert(sponsorSlide)
|
||||
return database.sponsorSlideTable.create(sponsorSlide)
|
||||
}
|
||||
|
||||
func (database *Database) GetSponsorSlideById(id int) (*SponsorSlide, error) {
|
||||
sponsorSlide := new(SponsorSlide)
|
||||
err := database.sponsorSlideMap.Get(sponsorSlide, id)
|
||||
if err != nil && err.Error() == "sql: no rows in result set" {
|
||||
sponsorSlide = nil
|
||||
err = nil
|
||||
}
|
||||
var sponsorSlide *SponsorSlide
|
||||
err := database.sponsorSlideTable.getById(id, &sponsorSlide)
|
||||
return sponsorSlide, err
|
||||
}
|
||||
|
||||
func (database *Database) SaveSponsorSlide(sponsorSlide *SponsorSlide) error {
|
||||
_, err := database.sponsorSlideMap.Update(sponsorSlide)
|
||||
return err
|
||||
func (database *Database) UpdateSponsorSlide(sponsorSlide *SponsorSlide) error {
|
||||
return database.sponsorSlideTable.update(sponsorSlide)
|
||||
}
|
||||
|
||||
func (database *Database) DeleteSponsorSlide(sponsorSlide *SponsorSlide) error {
|
||||
_, err := database.sponsorSlideMap.Delete(sponsorSlide)
|
||||
return err
|
||||
func (database *Database) DeleteSponsorSlide(id int) error {
|
||||
return database.sponsorSlideTable.delete(id)
|
||||
}
|
||||
|
||||
func (database *Database) TruncateSponsorSlides() error {
|
||||
return database.sponsorSlideMap.TruncateTables()
|
||||
return database.sponsorSlideTable.truncate()
|
||||
}
|
||||
|
||||
func (database *Database) GetAllSponsorSlides() ([]SponsorSlide, error) {
|
||||
var sponsorSlides []SponsorSlide
|
||||
err := database.sponsorSlideMap.Select(&sponsorSlides, "SELECT * FROM sponsor_slides ORDER BY displayorder")
|
||||
return sponsorSlides, err
|
||||
if err := database.sponsorSlideTable.getAll(&sponsorSlides); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sort.Slice(sponsorSlides, func(i, j int) bool {
|
||||
return sponsorSlides[i].DisplayOrder < sponsorSlides[j].DisplayOrder
|
||||
})
|
||||
return sponsorSlides, nil
|
||||
}
|
||||
|
||||
func (database *Database) GetNextSponsorSlideDisplayOrder() int {
|
||||
var count int
|
||||
_ = database.sponsorSlideMap.SelectOne(&count, "SELECT MAX(displayorder) + 1 FROM sponsor_slides")
|
||||
return count
|
||||
sponsorSlides, err := database.GetAllSponsorSlides()
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
if len(sponsorSlides) == 0 {
|
||||
return 1
|
||||
}
|
||||
return sponsorSlides[len(sponsorSlides)-1].DisplayOrder + 1
|
||||
}
|
||||
|
||||
@@ -21,22 +21,22 @@ func TestSponsorSlideCrud(t *testing.T) {
|
||||
db := setupTestDb(t)
|
||||
defer db.Close()
|
||||
|
||||
assert.Equal(t, 0, db.GetNextSponsorSlideDisplayOrder())
|
||||
assert.Equal(t, 1, db.GetNextSponsorSlideDisplayOrder())
|
||||
|
||||
sponsorSlide := SponsorSlide{0, "Subtitle", "Line 1", "Line 2", "", 10, 0}
|
||||
sponsorSlide := SponsorSlide{0, "Subtitle", "Line 1", "Line 2", "", 10, 1}
|
||||
assert.Nil(t, db.CreateSponsorSlide(&sponsorSlide))
|
||||
sponsorSlide2, err := db.GetSponsorSlideById(1)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, sponsorSlide, *sponsorSlide2)
|
||||
assert.Equal(t, 1, db.GetNextSponsorSlideDisplayOrder())
|
||||
assert.Equal(t, 2, db.GetNextSponsorSlideDisplayOrder())
|
||||
|
||||
sponsorSlide.Line1 = "Blorpy"
|
||||
db.SaveSponsorSlide(&sponsorSlide)
|
||||
db.UpdateSponsorSlide(&sponsorSlide)
|
||||
sponsorSlide2, err = db.GetSponsorSlideById(1)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, sponsorSlide.Line1, sponsorSlide2.Line1)
|
||||
|
||||
db.DeleteSponsorSlide(&sponsorSlide)
|
||||
db.DeleteSponsorSlide(sponsorSlide.Id)
|
||||
sponsorSlide2, err = db.GetSponsorSlideById(1)
|
||||
assert.Nil(t, err)
|
||||
assert.Nil(t, sponsorSlide2)
|
||||
@@ -52,5 +52,5 @@ func TestTruncateSponsorSlides(t *testing.T) {
|
||||
sponsorSlide2, err := db.GetSponsorSlideById(1)
|
||||
assert.Nil(t, err)
|
||||
assert.Nil(t, sponsorSlide2)
|
||||
assert.Equal(t, 0, db.GetNextSponsorSlideDisplayOrder())
|
||||
assert.Equal(t, 1, db.GetNextSponsorSlideDisplayOrder())
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@ func SetupTestDb(t *testing.T, uniqueName string) *Database {
|
||||
BaseDir = ".."
|
||||
dbPath := filepath.Join(BaseDir, fmt.Sprintf("%s_test.db", uniqueName))
|
||||
os.Remove(dbPath)
|
||||
os.Remove(dbPath + ".bolt")
|
||||
database, err := OpenDatabase(dbPath)
|
||||
assert.Nil(t, err)
|
||||
return database
|
||||
|
||||
@@ -8,31 +8,34 @@ package model
|
||||
import "time"
|
||||
|
||||
type UserSession struct {
|
||||
Id int
|
||||
Id int `db:"id"`
|
||||
Token string
|
||||
Username string
|
||||
CreatedAt time.Time
|
||||
}
|
||||
|
||||
func (database *Database) CreateUserSession(session *UserSession) error {
|
||||
return database.userSessionMap.Insert(session)
|
||||
return database.userSessionTable.create(session)
|
||||
}
|
||||
|
||||
func (database *Database) GetUserSessionByToken(token string) (*UserSession, error) {
|
||||
session := new(UserSession)
|
||||
err := database.userSessionMap.SelectOne(session, "SELECT * FROM user_sessions WHERE token = ?", token)
|
||||
if err != nil && err.Error() == "sql: no rows in result set" {
|
||||
session = nil
|
||||
err = nil
|
||||
var userSessions []UserSession
|
||||
if err := database.userSessionTable.getAll(&userSessions); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return session, err
|
||||
|
||||
for _, userSession := range userSessions {
|
||||
if userSession.Token == token {
|
||||
return &userSession, nil
|
||||
}
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (database *Database) DeleteUserSession(session *UserSession) error {
|
||||
_, err := database.userSessionMap.Delete(session)
|
||||
return err
|
||||
func (database *Database) DeleteUserSession(id int) error {
|
||||
return database.userSessionTable.delete(id)
|
||||
}
|
||||
|
||||
func (database *Database) TruncateUserSessions() error {
|
||||
return database.userSessionMap.TruncateTables()
|
||||
return database.userSessionTable.truncate()
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ func TestUserSessionCrud(t *testing.T) {
|
||||
assert.Equal(t, session.Username, session2.Username)
|
||||
assert.True(t, session.CreatedAt.Equal(session2.CreatedAt))
|
||||
|
||||
db.DeleteUserSession(&session)
|
||||
db.DeleteUserSession(session.Id)
|
||||
session2, err = db.GetUserSessionByToken("token1")
|
||||
assert.Nil(t, err)
|
||||
assert.Nil(t, session2)
|
||||
|
||||
@@ -84,10 +84,10 @@ func TestRankingsApi(t *testing.T) {
|
||||
func TestSponsorSlidesApi(t *testing.T) {
|
||||
web := setupTestWeb(t)
|
||||
|
||||
slide1 := model.SponsorSlide{1, "subtitle", "line1", "line2", "image", 2, 0}
|
||||
slide2 := model.SponsorSlide{2, "Chezy Sponsaur", "Teh", "Chezy Pofs", "ejface.jpg", 54, 1}
|
||||
web.arena.Database.CreateSponsorSlide(&slide1)
|
||||
web.arena.Database.CreateSponsorSlide(&slide2)
|
||||
slide1 := model.SponsorSlide{0, "subtitle", "line1", "line2", "image", 2, 1}
|
||||
slide2 := model.SponsorSlide{0, "Chezy Sponsaur", "Teh", "Chezy Pofs", "ejface.jpg", 54, 2}
|
||||
assert.Nil(t, web.arena.Database.CreateSponsorSlide(&slide1))
|
||||
assert.Nil(t, web.arena.Database.CreateSponsorSlide(&slide2))
|
||||
|
||||
recorder := web.getHttpResponse("/api/sponsor_slides")
|
||||
assert.Equal(t, 200, recorder.Code)
|
||||
|
||||
@@ -5,6 +5,9 @@ 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"
|
||||
@@ -44,63 +47,61 @@ func TestSetupSettingsInvalidValues(t *testing.T) {
|
||||
assert.Contains(t, recorder.Body.String(), "must be between 2 and 16")
|
||||
}
|
||||
|
||||
// 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)
|
||||
//}
|
||||
func TestSetupSettingsClearDb(t *testing.T) {
|
||||
web := setupTestWeb(t)
|
||||
|
||||
// TODO(pat): Re-enable this test once fully migrated over to Bolt.
|
||||
//func TestSetupSettingsBackupRestoreDb(t *testing.T) {
|
||||
// web := setupTestWeb(t)
|
||||
//
|
||||
// // Modify a parameter so that we know when the database has been restored.
|
||||
// web.arena.EventSettings.Name = "Chezy Champs"
|
||||
// assert.Nil(t, web.arena.Database.UpdateEventSettings(web.arena.EventSettings))
|
||||
//
|
||||
// // Back up the database.
|
||||
// recorder := web.getHttpResponse("/setup/db/save")
|
||||
// assert.Equal(t, 200, recorder.Code)
|
||||
// assert.Equal(t, "application/octet-stream", recorder.HeaderMap["Content-Type"][0])
|
||||
// backupBody := recorder.Body
|
||||
//
|
||||
// // Wipe the database to reset the defaults.
|
||||
// web = setupTestWeb(t)
|
||||
// assert.NotEqual(t, "Chezy Champs", web.arena.EventSettings.Name)
|
||||
//
|
||||
// // Check restoring with a missing file.
|
||||
// recorder = web.postHttpResponse("/setup/db/restore", "")
|
||||
// assert.Contains(t, recorder.Body.String(), "No database backup file was specified")
|
||||
// assert.NotEqual(t, "Chezy Champs", web.arena.EventSettings.Name)
|
||||
//
|
||||
// // Check restoring with a corrupt file.
|
||||
// recorder = web.postFileHttpResponse("/setup/db/restore", "databaseFile",
|
||||
// bytes.NewBufferString("invalid"))
|
||||
// assert.Contains(t, recorder.Body.String(), "Could not read uploaded database backup file")
|
||||
// assert.NotEqual(t, "Chezy Champs", web.arena.EventSettings.Name)
|
||||
//
|
||||
// // Check restoring with the backup retrieved before.
|
||||
// recorder = web.postFileHttpResponse("/setup/db/restore", "databaseFile", backupBody)
|
||||
// assert.Equal(t, "Chezy Champs", web.arena.EventSettings.Name)
|
||||
//}
|
||||
assert.Nil(t, web.arena.Database.CreateTeam(&model.Team{Id: 254}))
|
||||
assert.Nil(t, web.arena.Database.CreateMatch(&model.Match{Type: "qualification"}))
|
||||
assert.Nil(t, web.arena.Database.CreateMatchResult(new(model.MatchResult)))
|
||||
assert.Nil(t, web.arena.Database.CreateRanking(&game.Ranking{TeamId: 254}))
|
||||
assert.Nil(t, 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)
|
||||
}
|
||||
|
||||
func TestSetupSettingsBackupRestoreDb(t *testing.T) {
|
||||
web := setupTestWeb(t)
|
||||
|
||||
// Modify a parameter so that we know when the database has been restored.
|
||||
web.arena.EventSettings.Name = "Chezy Champs"
|
||||
assert.Nil(t, web.arena.Database.UpdateEventSettings(web.arena.EventSettings))
|
||||
|
||||
// Back up the database.
|
||||
recorder := web.getHttpResponse("/setup/db/save")
|
||||
assert.Equal(t, 200, recorder.Code)
|
||||
assert.Equal(t, "application/octet-stream", recorder.HeaderMap["Content-Type"][0])
|
||||
backupBody := recorder.Body
|
||||
|
||||
// Wipe the database to reset the defaults.
|
||||
web = setupTestWeb(t)
|
||||
assert.NotEqual(t, "Chezy Champs", web.arena.EventSettings.Name)
|
||||
|
||||
// Check restoring with a missing file.
|
||||
recorder = web.postHttpResponse("/setup/db/restore", "")
|
||||
assert.Contains(t, recorder.Body.String(), "No database backup file was specified")
|
||||
assert.NotEqual(t, "Chezy Champs", web.arena.EventSettings.Name)
|
||||
|
||||
// Check restoring with a corrupt file.
|
||||
recorder = web.postFileHttpResponse("/setup/db/restore", "databaseFile",
|
||||
bytes.NewBufferString("invalid"))
|
||||
assert.Contains(t, recorder.Body.String(), "Could not read uploaded database backup file")
|
||||
assert.NotEqual(t, "Chezy Champs", web.arena.EventSettings.Name)
|
||||
|
||||
// Check restoring with the backup retrieved before.
|
||||
recorder = web.postFileHttpResponse("/setup/db/restore", "databaseFile", backupBody)
|
||||
assert.Equal(t, "Chezy Champs", web.arena.EventSettings.Name)
|
||||
}
|
||||
|
||||
func (web *Web) postFileHttpResponse(path string, paramName string, file *bytes.Buffer) *httptest.ResponseRecorder {
|
||||
body := new(bytes.Buffer)
|
||||
|
||||
@@ -56,7 +56,7 @@ func (web *Web) sponsorSlidesPostHandler(w http.ResponseWriter, r *http.Request)
|
||||
}
|
||||
switch r.PostFormValue("action") {
|
||||
case "delete":
|
||||
err := web.arena.Database.DeleteSponsorSlide(sponsorSlide)
|
||||
err := web.arena.Database.DeleteSponsorSlide(sponsorSlide.Id)
|
||||
if err != nil {
|
||||
handleWebErr(w, err)
|
||||
return
|
||||
@@ -76,7 +76,7 @@ func (web *Web) sponsorSlidesPostHandler(w http.ResponseWriter, r *http.Request)
|
||||
sponsorSlide.Line2 = r.PostFormValue("line2")
|
||||
sponsorSlide.Image = r.PostFormValue("image")
|
||||
sponsorSlide.DisplayTimeSec = displayTimeSec
|
||||
err = web.arena.Database.SaveSponsorSlide(sponsorSlide)
|
||||
err = web.arena.Database.UpdateSponsorSlide(sponsorSlide)
|
||||
}
|
||||
if err != nil {
|
||||
handleWebErr(w, err)
|
||||
@@ -133,11 +133,11 @@ func (web *Web) reorderSponsorSlide(id int, moveUp bool) error {
|
||||
// Swap their display orders and save.
|
||||
sponsorSlide.DisplayOrder, adjacentSponsorSlide.DisplayOrder =
|
||||
adjacentSponsorSlide.DisplayOrder, sponsorSlide.DisplayOrder
|
||||
err = web.arena.Database.SaveSponsorSlide(sponsorSlide)
|
||||
err = web.arena.Database.UpdateSponsorSlide(sponsorSlide)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = web.arena.Database.SaveSponsorSlide(adjacentSponsorSlide)
|
||||
err = web.arena.Database.UpdateSponsorSlide(adjacentSponsorSlide)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user