-
Notifications
You must be signed in to change notification settings - Fork 1
/
scriptor.go
127 lines (104 loc) · 3.16 KB
/
scriptor.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
package goscriptor
import (
"context"
"errors"
"sync"
"github.com/go-redis/redis/v8"
)
// redis script defination
// the hash key definition that is used to store the script
var (
scriptDefinition = "scriptor_v.0.0.0"
)
// Scriptor - the script manager
type Scriptor struct {
Client redis.UniversalClient
sRedisClientSyncOnce sync.Once
scripts map[string]string
redisScriptDB int
redisScriptDefinition string
CTX context.Context
}
// New - create a new scriptor with the redis client
func New(client redis.UniversalClient, scriptDB int, redisScriptDefinition string, scripts *map[string]string) (*Scriptor, error) {
if client == nil {
return nil, errors.New("'client' cannot be nil")
}
// new scriptor
s := &Scriptor{}
s.sRedisClientSyncOnce.Do(func() {
s.Client = client
s.scripts = make(map[string]string)
s.redisScriptDB = scriptDB
// if redisScriptDefinition is not empty, use the default
if redisScriptDefinition != "" {
s.redisScriptDefinition = redisScriptDefinition
} else {
s.redisScriptDefinition = scriptDefinition
}
})
s.CTX = context.Background()
// ping the redis server
_, err := s.Client.Ping(s.CTX).Result()
if err != nil {
return nil, err
}
// load all scripts or register scripts
scriptDescriptor, err := NewScriptDescriptor(s.CTX, s.Client, scripts, s.redisScriptDefinition, s.redisScriptDB)
if err != nil {
return nil, err
}
s.scripts = scriptDescriptor.contrainer
return s, nil
}
// NewDB - create a new Scriptor with a new redis client
func NewDB(opt *Option, scriptDB int, redisScriptDefinition string, scripts *map[string]string) (*Scriptor, error) {
if opt == nil {
return nil, errors.New("'option' cannot be nil")
}
// new scriptor
s := &Scriptor{}
s.sRedisClientSyncOnce.Do(func() {
s.Client = opt.Create()
s.scripts = make(map[string]string)
s.redisScriptDB = scriptDB
// if redisScriptDefinition is not empty, use the default
if redisScriptDefinition != "" {
s.redisScriptDefinition = redisScriptDefinition
} else {
s.redisScriptDefinition = scriptDefinition
}
})
s.CTX = context.Background()
// ping the redis server
_, err := s.Client.Ping(s.CTX).Result()
if err != nil {
return nil, err
}
// load all scripts or register scripts
scriptDescriptor, err := NewScriptDescriptor(s.CTX, s.Client, scripts, s.redisScriptDefinition, s.redisScriptDB)
if err != nil {
return nil, err
}
s.scripts = scriptDescriptor.contrainer
return s, nil
}
// Exec - execute the script
func (s *Scriptor) Exec(script string, keys []string, args ...interface{}) (interface{}, error) {
if script == "" {
return nil, errors.New("script not found")
}
res, err := s.Client.Eval(s.CTX, script, keys, args...).Result()
return res, err
}
// ExecSha - execute the script
func (s *Scriptor) ExecSha(scriptname string, keys []string, args ...interface{}) (interface{}, error) {
if s.scripts[scriptname] == "" || s.scripts == nil || len(s.scripts) == 0 {
return nil, errors.New("script not found.")
}
return s.Client.EvalSha(s.CTX, s.scripts[scriptname], keys, args...).Result()
}
// stop - stop the scriptor
func (s *Scriptor) stop() {
s.Client.Close()
}