// NGnius 2020-01-30 package main // leadercraft-server import ( "flag" "fmt" "os" "os/signal" ) const ( // Version the current version Version = "0.1" // Name the program name Name = "leadercraft-s" ) var ( isClosing bool printVersionAndExit bool ) func init() { initArgs() } func main() { parseArgs() sqlInitErr := sqlInit() if sqlInitErr != nil { fmt.Printf("Failed to initialise SQL connection: %s\n", sqlInitErr) os.Exit(1) } // handle interrupt (terminate) signal signalChan := make(chan os.Signal) signal.Notify(signalChan, os.Interrupt) go func() { s := <-signalChan fmt.Println("Received terminate signal " + s.String()) isClosing = true sqlClose() }() // get new rankings rows, err := db.Query("SELECT * FROM Entries WHERE rank=-1 ORDER BY time ASC;") if err == nil { var entries []*Entry count := 0 for rows.Next() { entries = append(entries, &Entry{}) scanErr := rows.Scan(entries[count].Intake()...) if scanErr == nil { updateBoardEntries(entries[count]) count++ } else { fmt.Println(scanErr) } } } else { fmt.Println(err) } } func initArgs() { flag.BoolVar(&printVersionAndExit, "version", false, "Print version and exit") flag.StringVar(&sqlConnection, "conn", sqlConnectionDefault, "Database connection string") flag.StringVar(&sqlServer, "sql", sqlServerDefault, "SQL Database type") } func parseArgs() { flag.Parse() if printVersionAndExit { fmt.Println(Name + " v" + Version) os.Exit(0) } } func updateBoardEntries(entry *Entry) { // get nearest entry that's lower and steal it's rank nearestEntry := &Entry{} 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()...) if (scanErr == nil) { entry.Rank = nearestEntry.Rank entry.Commit() // update all ranks lower than itself tx, _ := db.Begin() stmt, _ := tx.Prepare("UPDATE Entries SET rank=rank+1 WHERE rank >=$1 AND id!=$2 AND board=$3;") _, err := stmt.Exec(entry.Rank, entry.ID, entry.Board) if err != nil { tx.Rollback() fmt.Println(err) } else { tx.Commit() } } else { // nothing to beat 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()...) if (scanErr == nil) { entry.Rank = nearestEntry.Rank + 1 entry.Commit() } else { // no other entries entry.Rank = 1 entry.Commit() //fmt.Println(scanErr) } } }