package main import "github.com/mxk/go-sqlite/sqlite3" import "errors" import "strconv" type Poll struct { id int64 title string userId int64 } func addPoll(db *sqlite3.Conn, title string, options []string, nick string) (int64, error) { user := getUserForName(db, nick) if (user.id == 0) { var err error user, err = createUser(db, nick, false) if (err != nil) { return 0, err } } args := sqlite3.NamedArgs{"$a": title, "$b": user.id} sql := "INSERT INTO polls (title, user_id) VALUES ($a, $b)" err := db.Exec(sql, args) if (err != nil ) { return 0, err } pollId := db.LastInsertId() for _,option := range options { addOption(db, option, pollId) if (err != nil ) { return 0, err } } return pollId, nil } func addOption(db *sqlite3.Conn, text string, pollId int64) error { args := sqlite3.NamedArgs{"$a": text, "$b": pollId} sql := "INSERT INTO options (text, poll_id) VALUES ($a, $b)" err := db.Exec(sql, args) if (err != nil ) { return err } return nil } func getPollFromTitle(db *sqlite3.Conn, title string) (Poll, error) { args := sqlite3.NamedArgs{"$a": title} sql := "SELECT * FROM polls WHERE title = $a" s, err := db.Query(sql, args) row := make(sqlite3.RowMap) for ; err == nil ; err = s.Next() { var rowid int64 s.Scan(&rowid, row) // Assigns 1st column to rowid, the rest to row poll := Poll{id:rowid, title:row["title"].(string), userId:row["user_id"].(int64)} return poll, nil } //If we get here there are no matching polls, return an error return Poll{id:0, title:"", userId:0}, errors.New("No poll found with title '" + title +"'") } func getPollFromId(db *sqlite3.Conn, id int) (Poll, error) { args := sqlite3.NamedArgs{"$a": id} sql := "SELECT * FROM polls WHERE id = $a" s, err := db.Query(sql, args) row := make(sqlite3.RowMap) for ; err == nil ; err = s.Next() { var rowid int64 s.Scan(&rowid, row) // Assigns 1st column to rowid, the rest to row poll := Poll{id:rowid, title:row["title"].(string), userId:row["user_id"].(int64)} return poll, nil } //If we get here there are no matching polls, return an error return Poll{id:0, title:"", userId:0}, errors.New("No poll found with ID " + strconv.Itoa(id)) } func deletePoll(db *sqlite3.Conn, id int, nick string) error { user := getUserForName(db, nick) poll, err := getPollFromId(db, id) if (err != nil) { return err } if (user.isAdmin || poll.userId == user.id) { if (poll.id == 0) { return nil } else { sql := "DELETE FROM polls WHERE id = $a" args := sqlite3.NamedArgs{"$a": id} db.Exec(sql, args) return nil } } else { return errors.New("You do not have permission to delete this poll") } } func hasUserVotedInPoll(db *sqlite3.Conn, poll Poll, user User) bool { args := sqlite3.NamedArgs{"$a": poll.id, "$b": user.id} sql := "SELECT count(*) FROM votes WHERE poll_id = $a AND user_id = $b" s, err := db.Query(sql, args) for ; err == nil ; err = s.Next() { var count int64 s.Scan(&count) // Assigns 1st column to rowid, the rest to row if (count == 0) { return false } else { return true } } //Not sure why we'd get here, but we probably don't want to record a vote if we did return true } func getRecentPolls(db *sqlite3.Conn) ([]Poll, error) { sql := "SELECT * FROM polls LIMIT 5" s, err := db.Query(sql) row := make(sqlite3.RowMap) var polls = make([]Poll, 5) i := 0 for ; err == nil ; err = s.Next() { var rowid int64 s.Scan(&rowid, row) // Assigns 1st column to rowid, the rest to row poll := Poll{id:rowid, title:row["title"].(string), userId:row["user_id"].(int64)} polls[i] = poll i++ } //If we get here there are no matching polls, return an error return polls, err }