-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtodos.go
188 lines (166 loc) · 3.91 KB
/
todos.go
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
180
181
182
183
184
185
186
187
188
package main
import (
"encoding/json"
"log"
"net/http"
"strings"
"time"
)
type Todo struct {
TodoId int64
Description string
HasDueDate bool
DueDate time.Time
HasReminder bool
Reminder time.Time
Tags string //tags are joined together by newlines \n
Notes string
Completed bool
UserId int64 `json:"-"`
}
type TodoList struct {
Todos *[]Todo `json:"todos"`
}
func (t *Todo) Write(w http.ResponseWriter) error {
enc := json.NewEncoder(w)
return enc.Encode(t)
}
func (t *Todo) Read(json_str string) error {
dec := json.NewDecoder(strings.NewReader(json_str))
return dec.Decode(t)
}
func (t *Todo) MarkReminded() error {
_, err := DB.Exec("UPDATE todos SET HasReminder=? WHERE UserId=? AND TodoId=? AND Reminder=?;", false, t.UserId, t.TodoId, t.Reminder)
return err
}
func (tl *TodoList) Write(w http.ResponseWriter) error {
enc := json.NewEncoder(w)
return enc.Encode(tl)
}
func GetTodo(todoid int64, userid int64) (*Todo, error) {
var t Todo
err := DB.SelectOne(&t, "SELECT * from todos where UserId=? AND TodoId=?", userid, todoid)
if err != nil {
return nil, err
}
return &t, nil
}
/*
* Use sparingly, and only when you're sure you're checking if the user has the
* authentication necessary to access this todo.
*/
func GetTodoNoUserId(todoid int64) (*Todo, error) {
var t Todo
err := DB.SelectOne(&t, "SELECT * from todos where TodoId=?", todoid)
if err != nil {
return nil, err
}
return &t, nil
}
func GetTodos(userid int64) (*[]Todo, error) {
var todos []Todo
_, err := DB.Select(&todos, "SELECT * from todos where UserId=?", userid)
if err != nil {
return nil, err
}
return &todos, nil
}
func TodoHandler(w http.ResponseWriter, r *http.Request) {
user, err := GetUserFromSession(r)
if err != nil {
WriteError(w, 1 /*Not Signed In*/)
return
}
if r.Method == "POST" {
todo_json := r.PostFormValue("todo")
if todo_json == "" {
WriteError(w, 3 /*Invalid Request*/)
return
}
var todo Todo
err := todo.Read(todo_json)
if err != nil {
WriteError(w, 3 /*Invalid Request*/)
return
}
todo.TodoId = -1
todo.UserId = user.UserId
err = DB.Insert(&todo)
if err != nil {
WriteError(w, 999 /*Internal Error*/)
log.Print(err)
return
}
WriteSuccess(w)
} else if r.Method == "GET" {
todoid, err := GetURLID(r.URL.Path)
if err != nil {
//Return all TODOs
var tl TodoList
todos, err := GetTodos(user.UserId)
if err != nil {
WriteError(w, 999 /*Internal Error*/)
log.Print(err)
return
}
tl.Todos = todos
err = (&tl).Write(w)
if err != nil {
WriteError(w, 999 /*Internal Error*/)
log.Print(err)
return
}
} else {
//Return Todo with this Id
todo, err := GetTodo(todoid, user.UserId)
if err != nil {
WriteError(w, 3 /*Invalid Request*/)
return
}
err = todo.Write(w)
if err != nil {
WriteError(w, 999 /*Internal Error*/)
log.Print(err)
return
}
}
} else {
todoid, err := GetURLID(r.URL.Path)
if err != nil {
WriteError(w, 3 /*Invalid Request*/)
return
}
if r.Method == "PUT" {
todo_json := r.PostFormValue("todo")
if todo_json == "" {
WriteError(w, 3 /*Invalid Request*/)
return
}
var todo Todo
err := todo.Read(todo_json)
if err != nil || todo.TodoId != todoid {
WriteError(w, 3 /*Invalid Request*/)
return
}
todo.UserId = user.UserId
count, err := DB.Update(&todo)
if count != 1 || err != nil {
WriteError(w, 999 /*Internal Error*/)
log.Print(err)
return
}
WriteSuccess(w)
} else if r.Method == "DELETE" {
var todo Todo
todo.TodoId = todoid
count, err := DB.Delete(&todo)
//TODO detect if this error was due to the key missing or something else, we could be returning an internal error here when the TodoId was just supplied wrong
if count != 1 || err != nil {
WriteError(w, 999 /*Internal Error*/)
log.Print(err)
return
}
WriteSuccess(w)
}
}
}