package db import ( "errors" "time" "TerraOceanBot/common" ) 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 CreateInviteVote(messageID, username, reason string) (int, error) { result, err := db.Exec("INSERT INTO vote(messageId, name, type, finished) VALUES(?, ?, ?, ?)", messageID, username+":"+reason, "invite", 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) ([]common.VoteChoice, error) { rows, err := db.Query("SELECT userId, value FROM choices WHERE voteId=?", voteID) if err != nil { return []common.VoteChoice{}, err } defer rows.Close() array := make([]common.VoteChoice, 0) for rows.Next() { var userID string var value int rows.Scan(&userID, &value) array = append(array, common.VoteChoice{ UserID: userID, Value: value, }) } return array, nil }