package main import ( "errors" "time" ) const ( forceRejectionVote = -1 nuclearOptionVote = 10 ) var errForceRejectionVoteReuse = errors.New("db: the user has used force rejection vote in the last month") var errVoteIsOver = errors.New("db: the vote cannot be changed once it's over") func createCustomVote(messageID, text string) (int, error) { result, err := db.Exec("INSERT INTO vote(messageId, name, type, finished) VALUES(?, ?, ?, ?)", messageID, text, "custom", false) if err != nil { return 0, err } lastID, err := result.LastInsertId() return int(lastID), nil } func getVoteName(id int) (string, error) { rows, err := db.Query("SELECT name FROM vote WHERE id=?", id) if err != nil { return "", err } defer rows.Close() if rows.Next() { var name string err := rows.Scan(&name) if err != nil { return "", err } return name, nil } return "", errNotFound } func getVoteFromMessageID(msgID string) (int, error) { rows, err := db.Query("SELECT id FROM vote WHERE messageId=?", msgID) if err != nil { return 0, err } defer rows.Close() if rows.Next() { var id int err := rows.Scan(&id) if err != nil { return 0, err } return id, nil } return 0, errNotFound } func updateVote(voteID int, userID string, voteValue int) error { if voteValue == forceRejectionVote { //Check if they used it within a month. rows, err := db.Query("SELECT voteId FROM choices WHERE date >= ? AND value=?", time.Now().AddDate(0, -1, 0)) if err != nil { return err } if rows.Next() { return errForceRejectionVoteReuse } rows.Close() } //Check if the vote is finished and don't allow change of vote that way. rows, err := db.Query("SELECT finished FROM vote WHERE id=? AND finished=?", voteID, true) defer rows.Close() if rows.Next() { return errVoteIsOver } _, err = db.Exec("REPLACE INTO choices (voteId, userId, date, value) VALUES (?, ?, ?, ?)", voteID, userID, time.Now(), voteValue) return err }