diff --git a/json_structs.go b/json_structs.go index a7a1d3c..f416441 100644 --- a/json_structs.go +++ b/json_structs.go @@ -14,6 +14,7 @@ type BoardJSON struct { Entries []EntryJSON Name string Description string + Url string } // EntryJSON an entry in a leaderboard @@ -24,6 +25,8 @@ type EntryJSON struct { PlayerName string PlayerURL string PlayerID int64 + BoardName string + BoardURL string BoardID int64 } @@ -47,6 +50,7 @@ func UnmarshalNewEntryJSON(data []byte) (NewEntryJSON, error) { type PlayerJSON struct { ID int64 Name string + Url string Entries []EntryJSON } diff --git a/sql_service.go b/sql_service.go index fbe8c42..530874c 100644 --- a/sql_service.go +++ b/sql_service.go @@ -87,7 +87,7 @@ func sqlBuildTables() { // 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, FOREIGN KEY(player) REFERENCES Players(id), FOREIGN KEY(board) REFERENCES Boards(id));") + 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() } @@ -143,7 +143,7 @@ func sqlPopulateTables() { for _, e := range entries { err := e.Commit() if err != nil { - fmt.Printf("Error creating entry %d: %s", e.ID, err) + fmt.Printf("Error creating entry %d: %s\n", e.ID, err) } } } diff --git a/sql_structs.go b/sql_structs.go index 33be50d..d7108ab 100644 --- a/sql_structs.go +++ b/sql_structs.go @@ -5,9 +5,8 @@ package main import ( "encoding/json" "strconv" - // test - "fmt" + //"fmt" ) type Jsonable interface { @@ -61,7 +60,10 @@ func (b *Board) Entries() ([]*Entry, error) { count := 0 for rows.Next() { entries = append(entries, &Entry{}) - rows.Scan(entries[count].Intake()...) + scanErr := rows.Scan(entries[count].Intake()...) + if scanErr != nil { + return entries, scanErr + } count++ } return entries, nil @@ -76,12 +78,19 @@ func (b *Board) SomeEntries(start, end int64) ([]*Entry, error) { count := 0 for rows.Next() { entries = append(entries, &Entry{}) - rows.Scan(entries[count].Intake()...) + scanErr := rows.Scan(entries[count].Intake()...) + if scanErr != nil { + return entries, scanErr + } count++ } return entries, nil } +func (b *Board) Url() string { + return "/board?name=" + b.Name +} + // implementation of Jsonable func (b *Board) Json() ([]byte, error) { var data []byte @@ -102,7 +111,7 @@ func (b *Board) JsonPretty() ([]byte, error) { } func (b *Board) JsonObject() (interface{}, error) { - jsonObj := BoardJSON{ID: b.ID, Name: b.Name, Description: b.Description} + jsonObj := BoardJSON{ID: b.ID, Name: b.Name, Description: b.Description, Url: b.Url()} return jsonObj, nil } @@ -153,7 +162,10 @@ func (p *Player) Entries() ([]*Entry, error) { count := 0 for rows.Next() { entries = append(entries, &Entry{}) - rows.Scan(entries[count].Intake()...) + scanErr := rows.Scan(entries[count].Intake()...) + if scanErr != nil { + return entries, scanErr + } count++ } return entries, nil @@ -168,10 +180,9 @@ func (p *Player) SomeEntries(limit int64) ([]*Entry, error) { count := 0 for rows.Next() { entries = append(entries, &Entry{}) - //rows.Scan(entries[count].Intake()...) - scanErr := rows.Scan(&entries[count].ID, &entries[count].Rank, &entries[count].Score, &entries[count].Player, &entries[count].Board, &entries[count].Time) + scanErr := rows.Scan(entries[count].Intake()...) if scanErr != nil { - fmt.Println(scanErr) + return entries, scanErr } count++ } @@ -202,7 +213,7 @@ func (p *Player) JsonPretty() ([]byte, error) { } func (p *Player) JsonObject() (interface{}, error) { - jsonObj := PlayerJSON{ID: p.ID, Name: p.Name} + jsonObj := PlayerJSON{ID: p.ID, Name: p.Name, Url: p.Url()} return jsonObj, nil } @@ -216,12 +227,13 @@ func (p *Player) Output() []interface{} { } type Entry struct { - ID int64 - Rank int64 - Score int64 - Player int64 - Board int64 - Time int64 // Created time (seconds since Unix epoch) + ID int64 + Rank int64 + Score int64 + Player int64 + Board int64 + Time int64 // Created time (seconds since Unix epoch) + Metadata []byte } func LoadEntry(id int64) *Entry { @@ -239,7 +251,7 @@ func (e *Entry) Load() error { func (e *Entry) Commit() error { tx, _ := db.Begin() - statement, _ := tx.Prepare("INSERT OR REPLACE INTO Entries(id, rank, score, player, board, time) VALUES (?, ?, ?, ?, ?, ?);") + statement, _ := tx.Prepare("INSERT OR REPLACE INTO Entries(id, rank, score, player, board, time, metadata) VALUES (?, ?, ?, ?, ?, ?, ?);") _, err := statement.Exec(e.Output()...) if err != nil { tx.Rollback() @@ -276,14 +288,21 @@ func (e *Entry) JsonObject() (interface{}, error) { } jsonObj.PlayerName = ePlayer.Name jsonObj.PlayerURL = ePlayer.Url() + eBoard := &Board{ID: e.Board} + err = eBoard.Load() + if err != nil { + return jsonObj, err + } + jsonObj.BoardName = eBoard.Name + jsonObj.BoardURL = eBoard.Url() return jsonObj, nil } // implementation of Rower func (e *Entry) Intake() []interface{} { - return []interface{}{&e.ID, &e.Rank, &e.Score, &e.Player, &e.Board, &e.Time} + return []interface{}{&e.ID, &e.Rank, &e.Score, &e.Player, &e.Board, &e.Time, &e.Metadata} } func (e *Entry) Output() []interface{} { - return []interface{}{e.ID, e.Rank, e.Score, e.Player, e.Board, e.Time} + return []interface{}{e.ID, e.Rank, e.Score, e.Player, e.Board, e.Time, e.Metadata} }