-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathnosql-keyvalue-bigcache.go
150 lines (123 loc) · 3.8 KB
/
nosql-keyvalue-bigcache.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
package storage
import (
"encoding/json"
"errors"
"log"
"net/http"
"time"
"github.com/allegro/bigcache/v2"
"github.com/labstack/echo/v4"
"github.com/golang-common-packages/hash"
)
// BigCacheClient manage all BigCache actions
type BigCacheClient struct {
Client *bigcache.BigCache
}
var (
// bigCacheClientSessionMapping singleton pattern
bigCacheClientSessionMapping = make(map[string]*BigCacheClient)
)
// newBigCache init new instance
func newBigCache(config *bigcache.Config) INoSQLKeyValue {
hasher := &hash.Client{}
configAsJSON, err := json.Marshal(config)
if err != nil {
log.Fatalln("Unable to marshal BigCache configuration: ", err)
}
configAsString := hasher.SHA1(string(configAsJSON))
currentBigCacheClientSession := bigCacheClientSessionMapping[configAsString]
if currentBigCacheClientSession == nil {
currentBigCacheClientSession = &BigCacheClient{nil}
client, err := bigcache.NewBigCache(*config)
if err != nil {
log.Fatalln("Unable to connect to BigCache: ", err)
} else {
currentBigCacheClientSession.Client = client
bigCacheClientSessionMapping[configAsString] = currentBigCacheClientSession
log.Println("Connected to BigCache")
}
}
return currentBigCacheClientSession
}
// Middleware for echo framework
func (bc *BigCacheClient) Middleware(hash hash.IHash) echo.MiddlewareFunc {
return func(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
token := c.Request().Header.Get(echo.HeaderAuthorization)
key := hash.SHA512(token)
val, err := bc.Get(key)
if err != nil {
if err.Error() == "Entry not found" {
return c.NoContent(http.StatusUnauthorized)
}
return c.NoContent(http.StatusInternalServerError)
} else if val == "" {
return c.NoContent(http.StatusUnauthorized)
}
return next(c)
}
}
}
// Set new record set key and value
func (bc *BigCacheClient) Set(key string, value interface{}, expire time.Duration) error {
b, err := json.Marshal(value)
if err != nil {
log.Println("Unable to marshal value to []byte: ", err)
return errors.New("Unable to marshal value")
}
return bc.Client.Set(key, b)
}
// Get return value based on the key provided
func (bc *BigCacheClient) Get(key string) (interface{}, error) {
b, err := bc.Client.Get(key)
if err != nil {
log.Println("Unable to get value: ", err)
return nil, err
}
var value interface{}
json.Unmarshal(b, value)
return value, nil
}
// Update new value over the key provided
func (bc *BigCacheClient) Update(key string, value interface{}, expire time.Duration) error {
_, err := bc.Client.Get(key)
if err != nil {
log.Println("Unable to get value: ", err)
return err
}
if err := bc.Client.Delete(key); err != nil {
log.Println("Unable to delete value: ", err)
return err
}
b, err := json.Marshal(value)
if err != nil {
log.Println("Unable to Marshal value: ", err)
return err
}
return bc.Client.Set(key, b)
}
// Append new value base on the key provide, With Append() you can concatenate multiple entries under the same key in an lock optimized way.
func (bc *BigCacheClient) Append(key string, value interface{}) error {
b, err := json.Marshal(value)
if err != nil {
log.Println("Unable to Marshal value: ", err)
return errors.New("Unable to Marshal value")
}
return bc.Client.Append(key, b)
}
// Delete function will delete value based on the key provided
func (bc *BigCacheClient) Delete(key string) error {
return bc.Client.Delete(key)
}
// GetNumberOfRecords return number of records
func (bc *BigCacheClient) GetNumberOfRecords() int {
return bc.Client.Len()
}
// GetCapacity method return redis database size
func (bc *BigCacheClient) GetCapacity() (interface{}, error) {
return bc.Client.Capacity(), nil
}
// Close function will close BigCache connection
func (bc *BigCacheClient) Close() error {
return bc.Client.Close()
}