A collection of worker programs for server tasks
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.

109 lines
2.8KB

  1. // NGnius 2020-01-30
  2. package main // leadercraft-server
  3. import (
  4. "flag"
  5. "fmt"
  6. "os"
  7. "os/signal"
  8. )
  9. const (
  10. // Version the current version
  11. Version = "0.1"
  12. // Name the program name
  13. Name = "leadercraft-s"
  14. )
  15. var (
  16. isClosing bool
  17. printVersionAndExit bool
  18. )
  19. func init() {
  20. initArgs()
  21. }
  22. func main() {
  23. parseArgs()
  24. sqlInitErr := sqlInit()
  25. if sqlInitErr != nil {
  26. fmt.Printf("Failed to initialise SQL connection: %s\n", sqlInitErr)
  27. os.Exit(1)
  28. }
  29. // handle interrupt (terminate) signal
  30. signalChan := make(chan os.Signal)
  31. signal.Notify(signalChan, os.Interrupt)
  32. go func() {
  33. s := <-signalChan
  34. fmt.Println("Received terminate signal " + s.String())
  35. isClosing = true
  36. sqlClose()
  37. }()
  38. // get new rankings
  39. rows, err := db.Query("SELECT * FROM Entries WHERE rank=-1 ORDER BY time ASC;")
  40. if err == nil {
  41. var entries []*Entry
  42. count := 0
  43. for rows.Next() {
  44. entries = append(entries, &Entry{})
  45. scanErr := rows.Scan(entries[count].Intake()...)
  46. if scanErr == nil {
  47. updateBoardEntries(entries[count])
  48. count++
  49. } else {
  50. fmt.Println(scanErr)
  51. }
  52. }
  53. } else {
  54. fmt.Println(err)
  55. }
  56. }
  57. func initArgs() {
  58. flag.BoolVar(&printVersionAndExit, "version", false, "Print version and exit")
  59. flag.StringVar(&sqlConnection, "conn", sqlConnectionDefault, "Database connection string")
  60. flag.StringVar(&sqlServer, "sql", sqlServerDefault, "SQL Database type")
  61. }
  62. func parseArgs() {
  63. flag.Parse()
  64. if printVersionAndExit {
  65. fmt.Println(Name + " v" + Version)
  66. os.Exit(0)
  67. }
  68. }
  69. func updateBoardEntries(entry *Entry) {
  70. // get nearest entry that's lower and steal it's rank
  71. nearestEntry := &Entry{}
  72. scanErr := db.QueryRow("SELECT * FROM Entries WHERE score < $1 AND rank!= -1 AND board=$2 ORDER BY score DESC LIMIT 1;", entry.Score, entry.Board).Scan(nearestEntry.Intake()...)
  73. if (scanErr == nil) {
  74. entry.Rank = nearestEntry.Rank
  75. entry.Commit()
  76. // update all ranks lower than itself
  77. tx, _ := db.Begin()
  78. stmt, _ := tx.Prepare("UPDATE Entries SET rank=rank+1 WHERE rank >=$1 AND id!=$2 AND board=$3;")
  79. _, err := stmt.Exec(entry.Rank, entry.ID, entry.Board)
  80. if err != nil {
  81. tx.Rollback()
  82. fmt.Println(err)
  83. } else {
  84. tx.Commit()
  85. }
  86. } else {
  87. // nothing to beat
  88. scanErr = db.QueryRow("SELECT * FROM Entries WHERE score >= $1 AND rank!= -1 AND board=$2 ORDER BY score ASC LIMIT 1;", entry.Score, entry.Board).Scan(nearestEntry.Intake()...)
  89. if (scanErr == nil) {
  90. entry.Rank = nearestEntry.Rank + 1
  91. entry.Commit()
  92. } else {
  93. // no other entries
  94. entry.Rank = 1
  95. entry.Commit()
  96. //fmt.Println(scanErr)
  97. }
  98. }
  99. }