/
core.go
204 lines (178 loc) · 5.14 KB
/
core.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
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
package todolist
import (
"database/sql"
"errors"
"fmt"
)
// Generic error messages
var (
ErrNotFound = errors.New("list not found")
ErrItemNotFound = errors.New("item not found")
)
// Core ...
type Core struct {
db *sql.DB
}
// NewCore implements Todo List Management Core Logic
func NewCore(db *sql.DB) *Core {
return &Core{db}
}
// Ex create user
func (c *Core) Ex(name string) error {
if err := c.db.Ping(); err == nil {
fmt.Println("pinging")
return err
}
fmt.Println("yes", name)
return nil
}
// TodoItem ...
type TodoItem struct {
ID int64 `json:"id"`
Value string `json:"value"`
Completed bool `json:"completed"`
}
// TodoList ...
type TodoList struct {
ID int64 `json:"id"`
Items []*TodoItem `json:"items"`
Name string `json:"name"`
}
// AddTodoList creates a todo list with it's items
func (c *Core) AddTodoList(list *TodoList) (*TodoList, error) {
const listQuery = `INSERT INTO todolist_management.todo_lists (name) VALUES($1) returning id`
const itemQuery = `INSERT INTO todolist_management.todo_items (value, list_id, completed) VALUES($1, $2, $3) returning id`
tx, err := c.db.Begin()
if err != nil {
return nil, err
}
defer tx.Rollback()
if err := tx.QueryRow(listQuery, list.Name).Scan(&list.ID); err != nil {
return nil, err
}
stmt, err := tx.Prepare(itemQuery)
if err != nil {
return nil, err
}
defer stmt.Close()
for _, item := range list.Items {
if err := stmt.QueryRow(item.Value, list.ID, item.Completed).Scan(&item.ID); err != nil {
return nil, err
}
}
if err := tx.Commit(); err != nil {
return nil, err
}
return list, nil
}
// DeleteTodoList removes a todo list with it's items
func (c *Core) DeleteTodoList(id int64) error {
const check = `SELECT id FROM todolist_management.todo_lists WHERE id = $1`
cid := int64(0)
if err := c.db.QueryRow(check, id).Scan(&cid); err != nil {
if err != sql.ErrNoRows {
return err
}
return ErrNotFound
}
const listQuery = `DELETE FROM todolist_management.todo_lists WHERE id = $1`
const itemQuery = `DELETE FROM todolist_management.todo_items WHERE list_id = $1`
tx, err := c.db.Begin()
if err != nil {
return err
}
defer tx.Rollback()
if _, err := tx.Exec(listQuery, id); err != nil {
return err
}
if _, err := tx.Exec(itemQuery, id); err != nil {
return err
}
if err := tx.Commit(); err != nil {
return err
}
return nil
}
// EditTodoListName updates the name of the list
func (c *Core) EditTodoListName(id int64, name string) error {
const check = `SELECT id FROM todolist_management.todo_lists WHERE id = $1`
cid := int64(0)
if err := c.db.QueryRow(check, id).Scan(&cid); err != nil {
if err != sql.ErrNoRows {
return err
}
return ErrNotFound
}
const query = `UPDATE todolist_management.todo_lists SET name = $2 WHERE id = $1`
if _, err := c.db.Exec(query, id, name); err != nil {
return err
}
return nil
}
// AddTodoItem adds item to the list
func (c *Core) AddTodoItem(lid int64, item *TodoItem) (*TodoItem, error) {
const check = `SELECT id FROM todolist_management.todo_lists WHERE id = $1`
cid := int64(0)
if err := c.db.QueryRow(check, lid).Scan(&cid); err != nil {
if err != sql.ErrNoRows {
return nil, err
}
return nil, ErrNotFound
}
const query = `INSERT INTO todolist_management.todo_items (value, list_id, completed) VALUES($1, $2, $3) returning id`
if err := c.db.QueryRow(query, item.Value, lid, item.Completed).Scan(&item.ID); err != nil {
return nil, err
}
return item, nil
}
// DeleteTodoListItem removes items from the list
func (c *Core) DeleteTodoListItem(id int64) error {
const query = `DELETE FROM todolist_management.todo_items WHERE id = $1`
if _, err := c.db.Exec(query, id); err != nil {
return err
}
return nil
}
// GetTodoListItem returns a todolist item
func (c *Core) GetTodoListItem(id int64) (*TodoItem, error) {
const query = `SELECT id, value, completed FROM todolist_management.todo_items WHERE id = $1`
item := &TodoItem{}
if err := c.db.QueryRow(query, id).Scan(&item.ID, &item.Value, &item.Completed); err != nil {
if err == sql.ErrNoRows {
return nil, ErrItemNotFound
}
return nil, err
}
return item, nil
}
// UpdateTodoItem updates an item
func (c *Core) UpdateTodoItem(item *TodoItem) error {
const query = `UPDATE todolist_management.todo_items SET value = $1, completed = $2 WHERE id = $3`
if _, err := c.db.Exec(query, item.Value, item.Completed, item.ID); err != nil {
return err
}
return nil
}
// GetTodoList returns whole todolist
func (c *Core) GetTodoList(id int64) (*TodoList, error) {
const query = `SELECT * FROM todolist_management.todo_lists INNER JOIN todolist_management.todo_items ON todolist_management.todo_items.list_id = todolist_management.todo_lists.id AND todolist_management.todo_lists.id = $1`
rows, err := c.db.Query(query, id)
if err != nil {
if err == sql.ErrNoRows {
return nil, ErrNotFound
}
return nil, err
}
defer rows.Close()
list := &TodoList{
Items: []*TodoItem{},
}
for rows.Next() {
item := &TodoItem{}
if err = rows.Scan(&list.ID, &list.Name, &item.ID, &item.Value, &list.ID, &item.Completed); err != nil {
return nil, err
}
list.Items = append(list.Items, item)
}
return list, nil
}