diff --git a/db/dbconf.yml b/db/dbconf.yml deleted file mode 100644 index ec359db..0000000 --- a/db/dbconf.yml +++ /dev/null @@ -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. diff --git a/db/migrations/20140823193501_CreateSponsorSlides.sql b/db/migrations/20140823193501_CreateSponsorSlides.sql deleted file mode 100644 index d31a51f..0000000 --- a/db/migrations/20140823193501_CreateSponsorSlides.sql +++ /dev/null @@ -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; diff --git a/db/migrations/20180824200145_CreateScheduleBlocks.sql b/db/migrations/20180824200145_CreateScheduleBlocks.sql deleted file mode 100644 index 07b95e8..0000000 --- a/db/migrations/20180824200145_CreateScheduleBlocks.sql +++ /dev/null @@ -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; diff --git a/db/migrations/20190819192917_CreateUserSessions.sql b/db/migrations/20190819192917_CreateUserSessions.sql deleted file mode 100644 index aa4ca38..0000000 --- a/db/migrations/20190819192917_CreateUserSessions.sql +++ /dev/null @@ -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; diff --git a/field/test_helpers.go b/field/test_helpers.go index f4038d1..ad643a0 100644 --- a/field/test_helpers.go +++ b/field/test_helpers.go @@ -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 diff --git a/go.mod b/go.mod index d19e964..d523d6f 100644 --- a/go.mod +++ b/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 ) diff --git a/go.sum b/go.sum index 880aeab..01ae663 100644 --- a/go.sum +++ b/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= diff --git a/model/database.go b/model/database.go index b032785..06675dc 100644 --- a/model/database.go +++ b/model/database.go @@ -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 -} diff --git a/model/schedule_block.go b/model/schedule_block.go index c0bda84..6277e67 100644 --- a/model/schedule_block.go +++ b/model/schedule_block.go @@ -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() } diff --git a/model/sponsor_slide.go b/model/sponsor_slide.go index e28fc23..92b58ba 100644 --- a/model/sponsor_slide.go +++ b/model/sponsor_slide.go @@ -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 } diff --git a/model/sponsor_slide_test.go b/model/sponsor_slide_test.go index 7bfcbeb..835df57 100644 --- a/model/sponsor_slide_test.go +++ b/model/sponsor_slide_test.go @@ -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()) } diff --git a/model/test_helpers.go b/model/test_helpers.go index abaa322..6a5604f 100755 --- a/model/test_helpers.go +++ b/model/test_helpers.go @@ -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 diff --git a/model/user_session.go b/model/user_session.go index 9dcaafd..c835eab 100644 --- a/model/user_session.go +++ b/model/user_session.go @@ -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() } diff --git a/model/user_session_test.go b/model/user_session_test.go index 7ac5444..4a9a0f1 100644 --- a/model/user_session_test.go +++ b/model/user_session_test.go @@ -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) diff --git a/web/api_test.go b/web/api_test.go index 433268b..cb908ea 100644 --- a/web/api_test.go +++ b/web/api_test.go @@ -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) diff --git a/web/setup_settings_test.go b/web/setup_settings_test.go index ff1b1ed..dfb673d 100644 --- a/web/setup_settings_test.go +++ b/web/setup_settings_test.go @@ -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) diff --git a/web/setup_sponsor_slides.go b/web/setup_sponsor_slides.go index c85125a..4399a34 100644 --- a/web/setup_sponsor_slides.go +++ b/web/setup_sponsor_slides.go @@ -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 }