-
Notifications
You must be signed in to change notification settings - Fork 75
/
Copy pathredis.go
148 lines (123 loc) Β· 3.06 KB
/
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
147
148
package redis
import (
"context"
"fmt"
"time"
"github.com/redis/go-redis/v9"
)
// Storage interface that is implemented by storage providers
type Storage struct {
db redis.UniversalClient
}
// New creates a new redis storage
func New(config ...Config) *Storage {
// Set default config
cfg := configDefault(config...)
// Create new redis universal client
var db redis.UniversalClient
// Parse the URL and update config values accordingly
if cfg.URL != "" {
options, err := redis.ParseURL(cfg.URL)
if err != nil {
panic(err)
}
// Update the config values with the parsed URL values
cfg.Username = options.Username
cfg.Password = options.Password
cfg.Database = options.DB
cfg.Addrs = []string{options.Addr}
// If cfg.TLSConfig is not provided, and options returns one, use it.
if cfg.TLSConfig == nil && options.TLSConfig != nil {
cfg.TLSConfig = options.TLSConfig
}
} else if len(cfg.Addrs) == 0 {
// Fallback to Host and Port values if Addrs is empty
cfg.Addrs = []string{fmt.Sprintf("%s:%d", cfg.Host, cfg.Port)}
}
// Create Universal Client
db = redis.NewUniversalClient(&redis.UniversalOptions{
Addrs: cfg.Addrs,
MasterName: cfg.MasterName,
ClientName: cfg.ClientName,
SentinelUsername: cfg.SentinelUsername,
SentinelPassword: cfg.SentinelPassword,
DB: cfg.Database,
Username: cfg.Username,
Password: cfg.Password,
TLSConfig: cfg.TLSConfig,
PoolSize: cfg.PoolSize,
})
// Test connection
if err := db.Ping(context.Background()).Err(); err != nil {
panic(err)
}
// Empty collection if Clear is true
if cfg.Reset {
if err := db.FlushDB(context.Background()).Err(); err != nil {
panic(err)
}
}
// Create new store
return &Storage{
db: db,
}
}
// Get value by key
func (s *Storage) Get(key string) ([]byte, error) {
if len(key) <= 0 {
return nil, nil
}
val, err := s.db.Get(context.Background(), key).Bytes()
if err == redis.Nil {
return nil, nil
}
return val, err
}
// Set key with value
func (s *Storage) Set(key string, val []byte, exp time.Duration) error {
if len(key) <= 0 || len(val) <= 0 {
return nil
}
return s.db.Set(context.Background(), key, val, exp).Err()
}
// Delete key by key
func (s *Storage) Delete(key string) error {
if len(key) <= 0 {
return nil
}
return s.db.Del(context.Background(), key).Err()
}
// Reset all keys
func (s *Storage) Reset() error {
return s.db.FlushDB(context.Background()).Err()
}
// Close the database
func (s *Storage) Close() error {
return s.db.Close()
}
// Return database client
func (s *Storage) Conn() redis.UniversalClient {
return s.db
}
// Return all the keys
func (s *Storage) Keys() ([][]byte, error) {
var keys [][]byte
var cursor uint64
var err error
for {
var batch []string
if batch, cursor, err = s.db.Scan(context.Background(), cursor, "*", 10).Result(); err != nil {
return nil, err
}
for _, key := range batch {
keys = append(keys, []byte(key))
}
if cursor == 0 {
break
}
}
if len(keys) == 0 {
return nil, nil
}
return keys, nil
}