forked from ghetzel/pivot
-
Notifications
You must be signed in to change notification settings - Fork 0
/
caching-backend.go
120 lines (93 loc) · 3.21 KB
/
caching-backend.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
package backends
import (
"sync"
"time"
"github.com/PerformLine/go-stockutil/typeutil"
"github.com/PerformLine/pivot/v3/dal"
"github.com/PerformLine/pivot/v3/filter"
)
type CachingBackend struct {
backend Backend
cache sync.Map
}
func NewCachingBackend(parent Backend) *CachingBackend {
return &CachingBackend{
backend: parent,
}
}
func (self *CachingBackend) ResetCache() {
self.cache = sync.Map{}
}
func (self *CachingBackend) Retrieve(collection string, id interface{}, fields ...string) (*dal.Record, error) {
cacheset := make(map[interface{}]interface{})
if c, ok := self.cache.LoadOrStore(collection, cacheset); ok {
cacheset = c.(map[interface{}]interface{})
}
if typeutil.IsScalar(id) {
if recordI, ok := cacheset[id]; ok {
return recordI.(*dal.Record), nil
}
}
if record, err := self.backend.Retrieve(collection, id, fields...); err == nil {
cacheset[id] = record
return record, nil
} else {
return nil, err
}
}
// passthrough the remaining functions to fulfill the Backend interface
// -------------------------------------------------------------------------------------------------
func (self *CachingBackend) Exists(collection string, id interface{}) bool {
return self.backend.Exists(collection, id)
}
func (self *CachingBackend) Initialize() error {
return self.backend.Initialize()
}
func (self *CachingBackend) SetIndexer(cs dal.ConnectionString) error {
return self.backend.SetIndexer(cs)
}
func (self *CachingBackend) RegisterCollection(c *dal.Collection) {
self.backend.RegisterCollection(c)
}
func (self *CachingBackend) GetConnectionString() *dal.ConnectionString {
return self.backend.GetConnectionString()
}
func (self *CachingBackend) Insert(collection string, records *dal.RecordSet) error {
return self.backend.Insert(collection, records)
}
func (self *CachingBackend) Update(collection string, records *dal.RecordSet, target ...string) error {
return self.backend.Update(collection, records, target...)
}
func (self *CachingBackend) Delete(collection string, ids ...interface{}) error {
return self.backend.Delete(collection, ids...)
}
func (self *CachingBackend) CreateCollection(definition *dal.Collection) error {
return self.backend.CreateCollection(definition)
}
func (self *CachingBackend) DeleteCollection(collection string) error {
return self.backend.DeleteCollection(collection)
}
func (self *CachingBackend) ListCollections() ([]string, error) {
return self.backend.ListCollections()
}
func (self *CachingBackend) GetCollection(collection string) (*dal.Collection, error) {
return self.backend.GetCollection(collection)
}
func (self *CachingBackend) WithSearch(collection *dal.Collection, filters ...*filter.Filter) Indexer {
return self.backend.WithSearch(collection, filters...)
}
func (self *CachingBackend) WithAggregator(collection *dal.Collection) Aggregator {
return self.backend.WithAggregator(collection)
}
func (self *CachingBackend) Flush() error {
return self.backend.Flush()
}
func (self *CachingBackend) Ping(d time.Duration) error {
return self.backend.Ping(d)
}
func (self *CachingBackend) String() string {
return self.backend.String()
}
func (self *CachingBackend) Supports(feature ...BackendFeature) bool {
return self.backend.Supports(feature...)
}