-
Notifications
You must be signed in to change notification settings - Fork 0
/
storage.go
85 lines (73 loc) · 2.51 KB
/
storage.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
package enforcer
import (
"context"
"time"
)
// Store implementation provides storage layer for campaigns and enrolments.
type Store interface {
CampaignStore
EnrolmentStore
}
// CampaignStore implementation provides storage layer for campaigns.
type CampaignStore interface {
GetCampaign(ctx context.Context, id string) (*Campaign, error)
ListCampaigns(ctx context.Context, q Query) ([]Campaign, error)
CreateCampaign(ctx context.Context, camp Campaign) error
UpdateCampaign(ctx context.Context, id string, updateFn UpdateFn) (*Campaign, error)
DeleteCampaign(ctx context.Context, id string) error
}
// EnrolmentStore implementation provides storage layer for enrolments.
type EnrolmentStore interface {
GetEnrolment(ctx context.Context, actorID, campaignID string) (*Enrolment, error)
ListEnrolments(ctx context.Context, actorID string) ([]Enrolment, error)
UpsertEnrolment(ctx context.Context, enrolment Enrolment) error
}
// UpdateFn typed func value is used by campaign store to update
// an existing campaign atomically. UpdateFn should apply updates
// directly to the given campaign pointer.
type UpdateFn func(ctx context.Context, actual *Campaign) error
// Query represents filtering options for listing campaigns.
// Following criteria must be realised as:
// `Include + (SearchIn AND OnlyActive AND HavingTags)`
type Query struct {
// Include campaigns with given ids unconditionally (i.e., other
// filters do not apply to this).
Include []string `json:"include,omitempty"`
// SearchIn limits the search-space to given campaign IDs and
// returns campaigns that match all other filters within this
// list.
SearchIn []string `json:"search_in,omitempty"`
// OnlyActive signals to return only active campaigns.
OnlyActive bool `json:"only_active,omitempty"`
// HavingTags returns only those campaigns that have all the
// given tags.
HavingTags []string `json:"having_tags,omitempty"`
}
func (q Query) filterCampaigns(arr []Campaign) []Campaign {
searchSet := map[string]struct{}{}
for _, id := range q.SearchIn {
searchSet[id] = struct{}{}
}
var res []Campaign
for _, camp := range arr {
if q.matchQuery(camp) {
res = append(res, camp)
}
}
return res
}
func (q Query) matchQuery(c Campaign) bool {
isMatch := !q.OnlyActive || c.IsActive(time.Now())
if len(q.SearchIn) > 0 {
found := false
for _, id := range q.SearchIn {
if id == c.ID {
found = true
break
}
}
isMatch = isMatch && found
}
isMatch = isMatch && (len(q.HavingTags) == 0 || c.HasTags(q.HavingTags))
return isMatch
}