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.

sql_structs.go 6.2KB

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