// NGnius 2020-02-11 package main import ( "database/sql" "fmt" "time" _ "github.com/mattn/go-sqlite3" ) const ( sqlServerDefault = "sqlite3" sqlConnectionDefault = "test.sqlite" ) var ( // command line arguments sqlServer string sqlConnection string buildTables bool populateTables bool // internal variables db *sql.DB ) func sqlInit() error { var dbOpenErr error db, dbOpenErr = sql.Open(sqlServer, sqlConnection) if dbOpenErr != nil { return dbOpenErr } if buildTables { fmt.Println("Building tables in database...") sqlBuildTables() } if populateTables { fmt.Println("Populating tables in database...") sqlPopulateTables() } return nil } func sqlClose() error { if db != nil { err := db.Close() if err != nil { return err } db = nil } return nil } func boardByName(name string) (*Board, error) { b := &Board{} return b, db.QueryRow("SELECT * FROM Boards WHERE name=? LIMIT 1", name).Scan(b.Intake()...) } func playerByName(name string) (*Player, error) { p := &Player{} return p, db.QueryRow("SELECT * FROM Players WHERE name=? LIMTI 1", name).Scan(p.Intake()...) } func newEntrySql(score, player, board int64) error { tx, _ := db.Begin() stmt, _ := tx.Prepare("INSERT INTO Entries(score, player, board, time) VALUES (?, ?, ?, ?)") _, err := stmt.Exec(score, player, board, time.Now().Unix()) if err != nil { tx.Rollback() return err } tx.Commit() return nil } // internal operations func sqlBuildTables() { transaction, txErr := db.Begin() if txErr != nil { return } // test table //transaction.Exec("CREATE TABLE IF NOT EXISTS Test (Sometext VARCHAR, Somenumber);") //transaction.Exec("INSERT INTO Test (Sometext, Somenumber) VALUES (?,?);", "Hello sqlite", 123) // build real tables transaction.Exec("CREATE TABLE IF NOT EXISTS Players (id INTEGER PRIMARY KEY, name TEXT NOT NULL);") transaction.Exec("CREATE TABLE IF NOT EXISTS Boards (id INTEGER PRIMARY KEY, name TEXT NOT NULL, description TEXT NOT NULL);") transaction.Exec("CREATE TABLE IF NOT EXISTS Entries (id INTEGER PRIMARY KEY, rank INTEGER NOT NULL DEFAULT -1, score INTEGER NOT NULL, player INTEGER NOT NULL, board INTEGER NOT NULL, time INTEGER NOT NULL, metadata BLOB NOT NULL DEFAULT 0, FOREIGN KEY(player) REFERENCES Players(id), FOREIGN KEY(board) REFERENCES Boards(id));") transaction.Commit() } func sqlPopulateTables() { boards := []*Board{ &Board{ID: 1, Name: "main-test", Description: "Overall best (test data)"}, &Board{ID: 2, Name: "coolest-test", Description: "Coolest score (test data)"}, &Board{ID: 3, Name: "fastest-test", Description: "Fastest time (test data)"}, } for _, b := range boards { err := b.Commit() if err != nil { fmt.Printf("Error creating board %d: %s\n", b.ID, err) } } players := []*Player{ &Player{ID: 1, Name: "NGnius (test)"}, &Player{ID: 2, Name: "Also NGnius (test)"}, &Player{ID: 3, Name: ".xX||eDgY TeeNaGeR||Xx. (test)"}, &Player{ID: 4, Name: "New username who dis? (test)"}, &Player{ID: 5, Name: "Extremely Ridiculously Long Name to break things (test)"}, &Player{ID: 6, Name: "P|P3 |o|z (test)"}, &Player{ID: 7, Name: "Waldo (test)"}, &Player{ID: 8, Name: "Zettagram.com (test)"}, &Player{ID: 9, Name: "The Doctor (test)"}, &Player{ID: 10, Name: "Marvin the Paranoid Android (test)"}, &Player{ID: 11, Name: "IDK HOW (test)"}, &Player{ID: 12, Name: "If you can read this your API may be wrong (test)"}, &Player{ID: 13, Name: "Unlucky 7 (test)"}, } for _, p := range players { err := p.Commit() if err != nil { fmt.Printf("Error creating player %d: %s\n", p.ID, err) } } now := time.Now().Unix() entries := []*Entry{ &Entry{ID: 1, Rank: 1, Score: 1000, Player: players[0].ID, Board: boards[0].ID, Time: now}, &Entry{ID: 2, Rank: 2, Score: 900, Player: players[1].ID, Board: boards[0].ID, Time: now}, &Entry{ID: 3, Rank: 3, Score: 400, Player: players[2].ID, Board: boards[0].ID, Time: now}, &Entry{ID: 4, Rank: 4, Score: 350, Player: players[3].ID, Board: boards[0].ID, Time: now}, &Entry{ID: 5, Rank: 5, Score: 350, Player: players[4].ID, Board: boards[0].ID, Time: now}, &Entry{ID: 6, Rank: 6, Score: 250, Player: players[5].ID, Board: boards[0].ID, Time: now}, &Entry{ID: 7, Rank: 7, Score: 200, Player: players[6].ID, Board: boards[0].ID, Time: now}, &Entry{ID: 8, Rank: 8, Score: 175, Player: players[7].ID, Board: boards[0].ID, Time: now}, &Entry{ID: 9, Rank: 9, Score: 150, Player: players[8].ID, Board: boards[0].ID, Time: now}, &Entry{ID: 10, Rank: 10, Score: 140, Player: players[9].ID, Board: boards[0].ID, Time: now}, &Entry{ID: 11, Rank: 11, Score: 10, Player: players[10].ID, Board: boards[0].ID, Time: now}, &Entry{ID: 12, Rank: 12, Score: 60, Player: players[11].ID, Board: boards[0].ID, Time: now}, &Entry{ID: 13, Rank: 13, Score: 13, Player: players[12].ID, Board: boards[0].ID, Time: now}, } for _, e := range entries { err := e.Commit() if err != nil { fmt.Printf("Error creating entry %d: %s\n", e.ID, err) } } }