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 getMessageIDFromVote(voteID int) (string, error) { rows, err := db.Query("SELECT messageId FROM vote WHERE id=?", voteID) if err != nil { return "", err } defer rows.Close() if rows.Next() { var id string err := rows.Scan(&id) if err != nil { return "", err } return id, nil } return "", errNotFound } func getVoteType(voteID int) (string, error) { rows, err := db.Query("SELECT type FROM vote WHERE id=?", voteID) if err != nil { return "", err } defer rows.Close() if rows.Next() { var messageType string err := rows.Scan(&messageType) if err != nil { return "", err } return messageType, nil } return "", 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 } func finishVote(voteID int) error { _, err := db.Exec("UPDATE vote SET finished=true WHERE id=?", voteID) return err } func getAllVoteChoices(voteID int) ([]voteChoice, error) { rows, err := db.Query("SELECT userId, value FROM choices WHERE voteId=?", voteID) if err != nil { return []voteChoice{}, err } defer rows.Close() array := make([]voteChoice, 0) for rows.Next() { var userID string var value int rows.Scan(&userID, &value) array = append(array, voteChoice{ UserID: userID, Value: value, }) } return array, nil }