1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
|
package main
// import "blavote"
import "fmt"
import "github.com/mxk/go-sqlite/sqlite3"
import "github.com/jessevdk/go-flags"
import "os"
import "io/ioutil"
import "strings"
import "strconv"
import "errors"
var version string
func main() {
version = "0.5"
//Command line arguments
var opts struct {
Version bool `short:"v" long:"version" description:"Show program version"`
Add string `short:"a" long:"add" description:"Title for a new poll"`
New string `short:"n" long:"new" description:"Title for a new poll"`
Username string `short:"u" long:"username" description:"Username of user adding poll"`
Remove int `short:"r" long:"remove" description:"ID of a poll to delete"`
Args struct {
Rest []string
} `positional-args:"yes"`
}
var args []string
//If there are no command line arguments, read them from stdin
if (len(os.Args) > 1) {
flags.Parse(&opts)
} else {
bytes, err := ioutil.ReadAll(os.Stdin)
if (err == nil) {
args = strings.Split(strings.Split(string(bytes),"\n")[0], " ")
flags.ParseArgs(&opts, args)
} else {
fmt.Println(err)
//No args given, deal with it
}
}
db, err := connectDb("blavote.db")
if (err != nil) {
fmt.Print("Could not connect to vote database: ")
fmt.Println(err)
return
}
if (opts.Version) {
fmt.Println("v" + version)
} else if (opts.Add != "") {
fmt.Println(opts.Args.Rest)
pollId, err := addPoll(db, opts.Add, opts.Args.Rest, opts.Username)
if (err == nil) {
fmt.Print("Poll added with ID ")
fmt.Println(pollId)
} else {
fmt.Println(err)
}
} else if (opts.New != "") {
pollId, err := addPoll(db, opts.New, opts.Args.Rest, opts.Username)
if (err == nil) {
fmt.Print("Poll added with ID ")
fmt.Println(pollId)
} else {
fmt.Println(err)
}
} else if (opts.Remove > 0) {
err = deletePoll(db, opts.Remove, opts.Username)
if (err == nil) {
fmt.Print("Poll removed with ID ")
fmt.Println(opts.Remove)
} else {
fmt.Println(err)
}
} else {
err = vote(db, opts.Username, opts.Args.Rest)
if (err != nil) {
fmt.Println(err)
}
}
}
func connectDb(name string) (*sqlite3.Conn, error) {
db, err := sqlite3.Open(name)
if (err != nil) {
return nil, err
}
//Check the version in the DB, if it doesn't exist we'll create it
//Can use this later to update the DB if needed
sql := "select * from info where key = 'version'"
_, err = db.Query(sql)
if (err != nil) {
fmt.Println("info table does not exist, creating database")
initTables(db)
return nil, err
}
return db, err
}
func initTables(db *sqlite3.Conn) {
db.Exec("create table info(id int, key text, value text)")
db.Exec("insert into info (key, value) values('version', '$a')", version)
db.Exec("create table users(id integer primary key autoincrement, name text, admin boolean)")
db.Exec("create table polls(id integer primary key autoincrement, title text, user_id int)")
db.Exec("create table options(id integer primary key autoincrement, text text, poll_id int)")
db.Exec("create table votes(id integer primary key autoincrement, user_id int, poll_id int, option_id int)")
}
func vote(db *sqlite3.Conn, nick string, options []string) error {
pollId, err := strconv.Atoi(options[0])
if (err != nil) {
return errors.New("Poll ID must be a number")
}
poll, err := getPollFromId(db, pollId)
if (err != nil) {
return err
}
option, err := getOptionFromText(db, options[1])
if (err != nil) {
return err
}
user := getUserForName(db, nick)
//Record the user in the DB if they aren't already
if (user.id == 0) {
user, err = createUser(db, nick, false)
if (err != nil) {
return err
}
}
if (!hasUserVotedInPoll(db, poll, user)) {
args := sqlite3.NamedArgs{"$a": user.id, "$b": poll.id, "$c": option.id}
sql := "INSERT INTO votes (user_id, poll_id, option_id) VALUES ($a, $b, $c)"
err = db.Exec(sql, args)
if (err != nil ) {
return err
} else {
fmt.Println("Vote added")
return nil
}
} else {
return errors.New("You have already voted in this poll")
}
}
|