-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcontroller.go
134 lines (114 loc) · 4.35 KB
/
controller.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 helloworld
import (
"github.com/mojura/mojura"
"github.com/mojura/mojura/filters"
)
// Relationship key const block
const (
// relationshipUsers represents the key for the UserID relationship
relationshipUsers = "users"
)
// relationships is a collection of all the supported relationship keys
// Note: Utilizing this pattern makes it easier to expand the relationship list in the future
var relationships = []string{
relationshipUsers,
}
// New will return a new instance of the Controller
func New(dir string) (cc *Controller, err error) {
var c Controller
// Make options with:
// - Database name
// - Data directory
opts := mojura.MakeOpts("helloWorld", dir)
// Initialize a new instance of mojura.Mojura, we pass it the following values:
// - Options
// - Appended list of relationship keys
if c.c, err = mojura.New[*Entry](opts, relationships...); err != nil {
return
}
// Assign pointer reference to our controller
cc = &c
return
}
// Controller represents a management layer to facilitate the retrieval and modification of Entries
type Controller struct {
// Mojura will manage the data layer and will utilize the underlying back-end
c *mojura.Mojura[*Entry]
}
// New will insert a new Entry to the back-end
// Note: ID, CreatedAt, UpdatedAt will all be auto-set by mojura.Mojura
func (c *Controller) New(e Entry) (created *Entry, err error) {
// Attempt to validate Entry
if err = e.Validate(); err != nil {
// Entry is not valid, return validation error
return
}
// Entry is valid!
// Insert Entry into mojura.Mojura and return the results
return c.c.New(&e)
}
// Get will retrieve an Entry which has the same ID as the provided entryID
func (c *Controller) Get(entryID string) (entry *Entry, err error) {
// Attempt to get Entry with the provided ID, if no entry exists mojura.ErrEntryNotFound will be returned
return c.c.Get(entryID)
}
// GetByUser will retrieve all Entries related to the provided userID by way of the Users relationship
func (c *Controller) GetByUser(userID string) (entries []*Entry, err error) {
// Create user relationship match filter for provided user ID
ownedByUser := filters.Match(relationshipUsers, userID)
// Initialize opts with the user filter
opts := mojura.NewFilteringOpts(ownedByUser)
// Get all matching entries
if entries, _, err = c.c.GetFiltered(opts); err != nil {
return
}
// No matches will still yield no error
return
}
// ForEach without any filters will iterate through all Entries
// Note: The error constant mojura.Break can returned by the iterating func to end the iteration early
func (c *Controller) ForEach(fn func(*Entry) error, filters ...mojura.Filter) (err error) {
// Initialize opts with the provided filters
opts := mojura.NewFilteringOpts(filters...)
// Iterate through all entries
err = c.c.ForEach(func(key string, e *Entry) (err error) {
// Pass iterating Entry to iterating function
return fn(e)
}, opts)
return
}
// ForEachByUser will iterate through all Entries for a provided userID
// Note: The error constant mojura.Break can returned by the iterating func to end the iteration early
func (c *Controller) ForEachByUser(userID string, fn func(*Entry) error) (err error) {
// Create user relationship match filter for provided user ID
ownedByUser := filters.Match(relationshipUsers, userID)
// Call ForEach with the ownedByUser filter
return c.ForEach(fn, ownedByUser)
}
// Update will update the Entry for a given entryID
func (c *Controller) Update(entryID string, e Entry) (updated *Entry, err error) {
// Attempt to validate Entry
if err = e.Validate(); err != nil {
// Entry is not valid, return validation error
return
}
// Insert Entry into mojura.Mojura and return the results
return c.c.Update(entryID, func(orig *Entry) (err error) {
// It's safer to manually update each field, instead of replacing the entire entry.
// This helps to ensure that we don't trust the client fully and allow only specific
// fields to be updated
orig.FavoriteTimeOfDay = e.FavoriteTimeOfDay
orig.Greeting = e.Greeting
return
})
}
// Delete will remove an Entry for a given entryID
func (c *Controller) Delete(entryID string) (deleted *Entry, err error) {
// Remove Entry from mojura.Mojura
return c.c.Delete(entryID)
}
// Close will close the controller and it's underlying dependencies
func (c *Controller) Close() (err error) {
// Close database
return c.c.Close()
}