Follow the leader with help from a server
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.

224 line
4.6KB

  1. // NGnius 2020-02-12
  2. package main
  3. import (
  4. "encoding/json"
  5. "strconv"
  6. )
  7. type Jsonable interface {
  8. Json() ([]byte, error)
  9. JsonPretty() ([]byte, error)
  10. Unjson([]byte) error
  11. JsonObject() (interface{}, error)
  12. }
  13. type Rower interface {
  14. Intake() []interface{}
  15. Output() []interface{}
  16. }
  17. type Board struct {
  18. ID int64
  19. Name string
  20. Description string
  21. }
  22. func LoadBoard(id int64) *Board {
  23. b := &Board{ID: id}
  24. b.Load()
  25. return b
  26. }
  27. func (b *Board) Load() error {
  28. return db.QueryRow("SELECT * FROM Boards WHERE id=?", b.ID).Scan(b.Intake()...)
  29. }
  30. func (b *Board) Commit() error {
  31. tx, _ := db.Begin()
  32. statement, _ := tx.Prepare("INSERT OR REPLACE INTO Boards(id, name, description) VALUES (?, ?, ?);")
  33. _, err := statement.Exec(b.Output()...)
  34. if err != nil {
  35. tx.Rollback()
  36. return err
  37. }
  38. return tx.Commit()
  39. }
  40. func (b *Board) Entries() ([]*Entry, error) {
  41. var entries []*Entry
  42. rows, err := db.Query("SELECT * FROM Entries WHERE board=?", b.ID)
  43. if err != nil {
  44. return entries, err
  45. }
  46. count := 0
  47. for rows.Next() {
  48. entries = append(entries, &Entry{})
  49. rows.Scan(entries[count].Intake()...)
  50. count++
  51. }
  52. return entries, nil
  53. }
  54. func (b *Board) SomeEntries(start, end int64) ([]*Entry, error) {
  55. var entries []*Entry
  56. rows, err := db.Query("SELECT * FROM Entries WHERE board=? and rank >= ? and rank <= ? ORDER BY rank ASC;", b.ID, start, end)
  57. if err != nil {
  58. return entries, err
  59. }
  60. count := 0
  61. for rows.Next() {
  62. entries = append(entries, &Entry{})
  63. rows.Scan(entries[count].Intake()...)
  64. count++
  65. }
  66. return entries, nil
  67. }
  68. func (b *Board) Intake() []interface{} {
  69. return []interface{}{&b.ID, &b.Name, &b.Description}
  70. }
  71. func (b *Board) Output() []interface{} {
  72. return []interface{}{b.ID, b.Name, b.Description}
  73. }
  74. type Player struct {
  75. ID int64
  76. Name string
  77. }
  78. func LoadPlayer(id int64) *Player {
  79. p := &Player{ID: id}
  80. p.Load()
  81. return p
  82. }
  83. func (p *Player) Load() error {
  84. return db.QueryRow("SELECT * FROM Players WHERE id=? LIMIT 1;", p.ID).Scan(p.Intake()...)
  85. }
  86. func (p *Player) Commit() error {
  87. tx, _ := db.Begin()
  88. statement, _ := tx.Prepare("INSERT OR REPLACE INTO Players(id, name) VALUES (?, ?);")
  89. _, err := statement.Exec(p.Output()...)
  90. if err != nil {
  91. tx.Rollback()
  92. return err
  93. }
  94. return tx.Commit()
  95. }
  96. func (p *Player) Entries() ([]*Entry, error) {
  97. var entries []*Entry
  98. rows, err := db.Query("SELECT * FROM Entries WHERE player=?", p.ID)
  99. if err != nil {
  100. return entries, err
  101. }
  102. count := 0
  103. for rows.Next() {
  104. entries = append(entries, &Entry{})
  105. rows.Scan(entries[count].Intake()...)
  106. count++
  107. }
  108. return entries, nil
  109. }
  110. func (p *Player) SomeEntries(limit int64) ([]*Entry, error) {
  111. var entries []*Entry
  112. rows, err := db.Query("SELECT * FROM Entries WHERE player=? ORDER BY rank ASC LIMIT ?;", p.ID, limit)
  113. if err != nil {
  114. return entries, err
  115. }
  116. count := 0
  117. for rows.Next() {
  118. entries = append(entries, &Entry{})
  119. rows.Scan(entries[count].Intake()...)
  120. count++
  121. }
  122. return entries, nil
  123. }
  124. func (p *Player) Url() string {
  125. return "/player/" + strconv.Itoa(int(p.ID))
  126. }
  127. // implementation of Rower
  128. func (p *Player) Intake() []interface{} {
  129. return []interface{}{&p.ID, &p.Name}
  130. }
  131. func (p *Player) Output() []interface{} {
  132. return []interface{}{p.ID, p.Name}
  133. }
  134. type Entry struct {
  135. ID int64
  136. Rank int64
  137. Score int64
  138. Player int64
  139. Board int64
  140. }
  141. func LoadEntry(id int64) *Entry {
  142. e := &Entry{ID: id}
  143. e.Load()
  144. return e
  145. }
  146. func (e *Entry) Load() error {
  147. return db.QueryRow("SELECT * FROM Entries WHERE id=? LIMIT 1;", e.ID).Scan(e.Intake()...)
  148. }
  149. func (e *Entry) Commit() error {
  150. tx, _ := db.Begin()
  151. statement, _ := tx.Prepare("INSERT OR REPLACE INTO Entries(id, rank, score, player, board) VALUES (?, ?, ?, ?, ?);")
  152. _, err := statement.Exec(e.Output()...)
  153. if err != nil {
  154. tx.Rollback()
  155. return err
  156. }
  157. return tx.Commit()
  158. }
  159. // implementation of Jsonable
  160. func (e *Entry) Json() ([]byte, error) {
  161. var data []byte
  162. jsonObj, err := e.JsonObject()
  163. if err != nil {
  164. return data, err
  165. }
  166. return json.Marshal(jsonObj)
  167. }
  168. func (e *Entry) JsonPretty() ([]byte, error) {
  169. var data []byte
  170. jsonObj, err := e.JsonObject()
  171. if err != nil {
  172. return data, err
  173. }
  174. return json.MarshalIndent(jsonObj, "", " ")
  175. }
  176. func (e *Entry) JsonObject() (interface{}, error) {
  177. jsonObj := EntryJSON{ID: e.ID, Rank: e.Rank, Score: e.Score}
  178. ePlayer := &Player{ID: e.Player}
  179. err := ePlayer.Load()
  180. if err != nil {
  181. return jsonObj, err
  182. }
  183. jsonObj.PlayerName = ePlayer.Name
  184. jsonObj.PlayerURL = ePlayer.Url()
  185. return jsonObj, nil
  186. }
  187. // implementation of Rower
  188. func (e *Entry) Intake() []interface{} {
  189. return []interface{}{&e.ID, &e.Rank, &e.Score, &e.Player, &e.Board}
  190. }
  191. func (e *Entry) Output() []interface{} {
  192. return []interface{}{e.ID, e.Rank, e.Score, e.Player, e.Board}
  193. }