mirror of
https://github.com/Team254/cheesy-arena-lite.git
synced 2026-03-09 13:46:44 -04:00
133 lines
3.8 KiB
Go
133 lines
3.8 KiB
Go
// Copyright 2014 Team 254. All Rights Reserved.
|
|
// Author: pat@patfairbank.com (Patrick Fairbank)
|
|
//
|
|
// Functions for manipulating the per-event SQLite datastore.
|
|
|
|
package model
|
|
|
|
import (
|
|
"bitbucket.org/liamstask/goose/lib/goose"
|
|
"database/sql"
|
|
"encoding/json"
|
|
"fmt"
|
|
"github.com/jmoiron/modl"
|
|
_ "github.com/mattn/go-sqlite3"
|
|
"io"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
const backupsDir = "db/backups"
|
|
const migrationsDir = "db/migrations"
|
|
|
|
var BaseDir = "." // Mutable for testing
|
|
|
|
type Database struct {
|
|
Path string
|
|
db *sql.DB
|
|
eventSettingsMap *modl.DbMap
|
|
matchMap *modl.DbMap
|
|
matchResultMap *modl.DbMap
|
|
rankingMap *modl.DbMap
|
|
teamMap *modl.DbMap
|
|
allianceTeamMap *modl.DbMap
|
|
lowerThirdMap *modl.DbMap
|
|
sponsorSlideMap *modl.DbMap
|
|
}
|
|
|
|
// Opens the SQLite database at the given path, creating it if it doesn't exist, and runs any pending
|
|
// migrations.
|
|
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()
|
|
|
|
return &database, nil
|
|
}
|
|
|
|
func (database *Database) Close() {
|
|
database.db.Close()
|
|
}
|
|
|
|
// Creates a copy of the current database and saves it to the backups directory.
|
|
func (database *Database) Backup(eventName, reason string) error {
|
|
backupsPath := filepath.Join(BaseDir, backupsDir)
|
|
err := os.MkdirAll(backupsPath, 0755)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
filename := fmt.Sprintf("%s/%s_%s_%s.db", backupsPath, strings.Replace(eventName, " ", "_", -1),
|
|
time.Now().Format("20060102150405"), reason)
|
|
src, err := os.Open(database.Path)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer src.Close()
|
|
dest, err := os.Create(filename)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer dest.Close()
|
|
if _, err := io.Copy(dest, src); err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// Sets up table-object associations.
|
|
func (database *Database) mapTables() {
|
|
dialect := new(modl.SqliteDialect)
|
|
|
|
database.eventSettingsMap = modl.NewDbMap(database.db, dialect)
|
|
database.eventSettingsMap.AddTableWithName(EventSettings{}, "event_settings").SetKeys(false, "Id")
|
|
|
|
database.matchMap = modl.NewDbMap(database.db, dialect)
|
|
database.matchMap.AddTableWithName(Match{}, "matches").SetKeys(true, "Id")
|
|
|
|
database.matchResultMap = modl.NewDbMap(database.db, dialect)
|
|
database.matchResultMap.AddTableWithName(MatchResultDb{}, "match_results").SetKeys(true, "Id")
|
|
|
|
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.allianceTeamMap = modl.NewDbMap(database.db, dialect)
|
|
database.allianceTeamMap.AddTableWithName(AllianceTeam{}, "alliance_teams").SetKeys(true, "Id")
|
|
|
|
database.lowerThirdMap = modl.NewDbMap(database.db, dialect)
|
|
database.lowerThirdMap.AddTableWithName(LowerThird{}, "lower_thirds").SetKeys(true, "Id")
|
|
|
|
database.sponsorSlideMap = modl.NewDbMap(database.db, dialect)
|
|
database.sponsorSlideMap.AddTableWithName(SponsorSlide{}, "sponsor_slides").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
|
|
}
|