-
Notifications
You must be signed in to change notification settings - Fork 2
/
nosql-keyvalue-redis.go
146 lines (121 loc) · 3.63 KB
/
nosql-keyvalue-redis.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
package storage
import (
"encoding/json"
"errors"
"log"
"net/http"
"time"
"github.com/go-redis/redis"
"github.com/labstack/echo/v4"
"github.com/golang-common-packages/hash"
)
// RedisClient manage all redis actions
type RedisClient struct {
Client *redis.Client
}
var (
// redisClientSessionMapping singleton pattern
redisClientSessionMapping = make(map[string]*RedisClient)
)
// newRedis init new instance
func newRedis(config *Redis) INoSQLKeyValue {
hasher := &hash.Client{}
configAsJSON, err := json.Marshal(config)
if err != nil {
log.Fatalln("Unable to marshal Redis configuration: ", err)
}
configAsString := hasher.SHA1(string(configAsJSON))
currentRedisClientSession := redisClientSessionMapping[configAsString]
if currentRedisClientSession == nil {
currentRedisClientSession = &RedisClient{nil}
client, err := currentRedisClientSession.connect(config)
if err != nil {
log.Fatalln("Unable to connect to Redis: ", err)
} else {
currentRedisClientSession.Client = client
redisClientSessionMapping[configAsString] = currentRedisClientSession
log.Println("Connected to Redis")
}
}
return currentRedisClientSession
}
func (r *RedisClient) connect(data *Redis) (client *redis.Client, err error) {
if r.Client == nil {
client = redis.NewClient(&redis.Options{
Addr: data.Host,
Password: data.Password,
DB: data.DB,
MaxRetries: data.MaxRetries,
})
_, err := client.Ping().Result()
if err != nil {
log.Fatalln("Unable to connect to Redis: ", err)
return nil, err
}
} else {
client = r.Client
err = nil
}
return
}
// Middleware for echo framework
func (r *RedisClient) 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)
if val, err := r.Get(key); err != nil {
log.Println("Can not get accesstoken from redis in echo middleware: ", err)
return echo.NewHTTPError(http.StatusInternalServerError, err)
} else if val == "" {
return c.NoContent(http.StatusUnauthorized)
}
return next(c)
}
}
}
// Get return value based on the key provided
func (r *RedisClient) Get(key string) (interface{}, error) {
return r.Client.Get(key).Result()
}
// Set new record set key and value
func (r *RedisClient) Set(key string, value interface{}, expire time.Duration) error {
return r.Client.Set(key, value, expire).Err()
}
// Update new value over the key provided
func (r *RedisClient) Update(key string, value interface{}, expire time.Duration) error {
_, err := r.Client.Get(key).Result()
if err != nil {
log.Println("Unable to get value: ", err)
return err
}
return r.Client.Set(key, value, expire).Err()
}
// Append new value over the key provided
func (r *RedisClient) Append(key string, value interface{}) error {
b, err := json.Marshal(value)
if err != nil {
log.Println("Unable to marshal value: ", err)
return errors.New("can not marshal value")
}
var v string
json.Unmarshal(b, &v)
return r.Client.Append(key, v).Err()
}
// Delete method delete value based on the key provided
func (r *RedisClient) Delete(key string) error {
return r.Client.Del(key).Err()
}
// GetNumberOfRecords return number of records
func (r *RedisClient) GetNumberOfRecords() int {
return len(r.Client.Do("KEYS", "*").Args())
}
// GetCapacity method return redis database size
func (r *RedisClient) GetCapacity() (interface{}, error) {
IntCmd := r.Client.DBSize()
return IntCmd.Result()
}
// Close method will close redis connection
func (r *RedisClient) Close() error {
return r.Client.Close()
}