-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathexample.go
134 lines (122 loc) · 2.83 KB
/
example.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
package fir
import (
"errors"
"time"
"github.com/timshannon/bolthold"
)
type Todo struct {
ID uint64 `json:"id" boltholdKey:"ID"`
Text string `json:"text"`
Done bool `json:"done"`
CreatedAt time.Time `json:"created_at"`
}
func insertTodo(ctx RouteContext, db *bolthold.Store) (*Todo, error) {
todo := new(Todo)
if err := ctx.Bind(todo); err != nil {
return nil, err
}
if len(todo.Text) < 3 {
return nil, ctx.FieldError("text", errors.New("todo is too short"))
}
todo.CreatedAt = time.Now()
if err := db.Insert(bolthold.NextSequence(), todo); err != nil {
return nil, err
}
return todo, nil
}
type queryReq struct {
Order string `json:"order" schema:"order"`
Search string `json:"search" schema:"search"`
Offset int `json:"offset" schema:"offset"`
Limit int `json:"limit" schema:"limit"`
}
func load(db *bolthold.Store) OnEventFunc {
return func(ctx RouteContext) error {
var req queryReq
if err := ctx.Bind(&req); err != nil {
return err
}
var todos []Todo
if err := db.Find(&todos, &bolthold.Query{}); err != nil {
return err
}
return ctx.Data(map[string]any{"todos": todos})
}
}
func createTodo(db *bolthold.Store) OnEventFunc {
return func(ctx RouteContext) error {
todo, err := insertTodo(ctx, db)
if err != nil {
return err
}
return ctx.Data(todo)
}
}
func updateTodo(db *bolthold.Store) OnEventFunc {
type updateReq struct {
TodoID uint64 `json:"todoID"`
Text string `json:"text"`
}
return func(ctx RouteContext) error {
req := new(updateReq)
if err := ctx.Bind(req); err != nil {
return err
}
var todo Todo
if err := db.Get(req.TodoID, &todo); err != nil {
return err
}
todo.Text = req.Text
if err := db.Update(req.TodoID, &todo); err != nil {
return err
}
return ctx.Data(todo)
}
}
func toggleDone(db *bolthold.Store) OnEventFunc {
type doneReq struct {
TodoID uint64 `json:"todoID"`
}
return func(ctx RouteContext) error {
req := new(doneReq)
if err := ctx.Bind(req); err != nil {
return err
}
var todo Todo
if err := db.Get(req.TodoID, &todo); err != nil {
return err
}
todo.Done = !todo.Done
if err := db.Update(req.TodoID, &todo); err != nil {
return err
}
return ctx.Data(todo)
}
}
func deleteTodo(db *bolthold.Store) OnEventFunc {
type deleteReq struct {
TodoID uint64 `json:"todoID"`
}
return func(ctx RouteContext) error {
req := new(deleteReq)
if err := ctx.Bind(req); err != nil {
return err
}
if err := db.Delete(req.TodoID, &Todo{}); err != nil {
return err
}
return nil
}
}
func todosRoute(db *bolthold.Store) RouteFunc {
return func() RouteOptions {
return RouteOptions{
ID("todos"),
Content("example.html"),
OnLoad(load(db)),
OnEvent("create", createTodo(db)),
OnEvent("delete", deleteTodo(db)),
OnEvent("toggle-done", toggleDone(db)),
}
}
}