@@ -6,9 +6,48 @@ package redis
66import "C"
77import (
88 "errors"
9+ "fmt"
910 "unsafe"
1011)
1112
13+ // argumentKind represents a type of a argument for executing a Redis command.
14+ type argumentKind uint8
15+
16+ const (
17+ argumentKindInt argumentKind = iota
18+ argumentKindBinary
19+ )
20+
21+ // argument represents an argument for a Redis command.
22+ type argument struct {
23+ kind argumentKind
24+ val any
25+ }
26+
27+ func createParameter (x any ) (* argument , error ) {
28+ var p argument
29+ switch v := x .(type ) {
30+ case int :
31+ p .kind = argumentKindInt
32+ p .val = int64 (v )
33+ case int32 :
34+ p .kind = argumentKindInt
35+ p .val = int64 (v )
36+ case int64 :
37+ p .kind = argumentKindInt
38+ p .val = v
39+ case string :
40+ p .kind = argumentKindBinary
41+ p .val = []byte (v )
42+ case []byte :
43+ p .kind = argumentKindBinary
44+ p .val = v
45+ default :
46+ return & p , fmt .Errorf ("unsupported parameter type: %T" , x )
47+ }
48+ return & p , nil
49+ }
50+
1251//export spin_redis_handle_redis_message
1352func handleRedisMessage (payload * C.spin_redis_payload_t ) C.spin_redis_error_t {
1453 bytes := C .GoBytes (unsafe .Pointer (payload .ptr ), C .int (payload .len ))
@@ -68,7 +107,7 @@ func del(addr string, keys []string) (int64, error) {
68107 return int64 (cpayload ), toErr (err )
69108}
70109
71- func sadd (addr string , key string , values []string ) (int64 , error ) {
110+ func sadd (addr , key string , values []string ) (int64 , error ) {
72111 caddr := redisStr (addr )
73112 ckey := redisStr (key )
74113 cvalues := redisListStr (values )
@@ -79,7 +118,7 @@ func sadd(addr string, key string, values []string) (int64, error) {
79118 return int64 (cpayload ), toErr (err )
80119}
81120
82- func smembers (addr string , key string ) ([]string , error ) {
121+ func smembers (addr , key string ) ([]string , error ) {
83122 caddr := redisStr (addr )
84123 ckey := redisStr (key )
85124
@@ -89,7 +128,7 @@ func smembers(addr string, key string) ([]string, error) {
89128 return fromRedisListStr (& cpayload ), toErr (err )
90129}
91130
92- func srem (addr string , key string , values []string ) (int64 , error ) {
131+ func srem (addr , key string , values []string ) (int64 , error ) {
93132 caddr := redisStr (addr )
94133 ckey := redisStr (key )
95134 cvalues := redisListStr (values )
@@ -100,33 +139,7 @@ func srem(addr string, key string, values []string) (int64, error) {
100139 return int64 (cpayload ), toErr (err )
101140}
102141
103- type RedisParameterKind uint8
104-
105- const (
106- RedisParameterKindInt64 = iota
107- RedisParameterKindBinary
108- )
109-
110- type RedisParameter struct {
111- Kind RedisParameterKind
112- Val interface {}
113- }
114-
115- type RedisResultKind uint8
116-
117- const (
118- RedisResultKindNil = iota
119- RedisResultKindStatus
120- RedisResultKindInt64
121- RedisResultKindBinary
122- )
123-
124- type RedisResult struct {
125- Kind RedisResultKind
126- Val interface {}
127- }
128-
129- func execute (addr string , command string , arguments []RedisParameter ) ([]RedisResult , error ) {
142+ func execute (addr , command string , arguments []* argument ) ([]* Result , error ) {
130143 caddr := redisStr (addr )
131144 ccommand := redisStr (command )
132145 carguments := redisListParameter (arguments )
@@ -142,8 +155,10 @@ func redisStr(x string) C.outbound_redis_string_t {
142155}
143156
144157func redisListStr (xs []string ) C.outbound_redis_list_string_t {
145- var cxs []C.outbound_redis_string_t
146-
158+ if len (xs ) == 0 {
159+ return C.outbound_redis_list_string_t {}
160+ }
161+ cxs := make ([]C.outbound_redis_string_t , 0 , len (xs ))
147162 for i := 0 ; i < len (xs ); i ++ {
148163 cxs = append (cxs , redisStr (xs [i ]))
149164 }
@@ -152,62 +167,63 @@ func redisListStr(xs []string) C.outbound_redis_list_string_t {
152167
153168func fromRedisListStr (list * C.outbound_redis_list_string_t ) []string {
154169 listLen := int (list .len )
155- var result []string
170+ result := make ( []string , 0 , listLen )
156171
157172 slice := unsafe .Slice (list .ptr , listLen )
158173 for i := 0 ; i < listLen ; i ++ {
159- string := slice [i ]
160- result = append (result , C .GoStringN (string .ptr , C .int (string .len )))
174+ str := slice [i ]
175+ result = append (result , C .GoStringN (str .ptr , C .int (str .len )))
161176 }
162-
163177 return result
164178}
165179
166- func redisParameter (x RedisParameter ) C.outbound_redis_redis_parameter_t {
167-
180+ func redisParameter (x * argument ) C.outbound_redis_redis_parameter_t {
168181 var ret C.outbound_redis_redis_parameter_t
169- switch x .Kind {
170- case RedisParameterKindInt64 :
171- * (* C .int64_t )(unsafe .Pointer (& ret .val )) = x .Val .(int64 )
172- case RedisParameterKindBinary :
173- value := x .Val .([]byte )
182+ switch x .kind {
183+ case argumentKindInt :
184+ * (* C .int64_t )(unsafe .Pointer (& ret .val )) = x .val .(int64 )
185+ case argumentKindBinary :
186+ value := x .val .([]byte )
174187 payload := C.outbound_redis_payload_t {ptr : & value [0 ], len : C .size_t (len (value ))}
175188 * (* C .outbound_redis_payload_t )(unsafe .Pointer (& ret .val )) = payload
176189 }
177- ret .tag = C .uint8_t (x .Kind )
190+ ret .tag = C .uint8_t (x .kind )
178191 return ret
179192}
180193
181- func redisListParameter (xs []RedisParameter ) C.outbound_redis_list_redis_parameter_t {
182- var cxs []C.outbound_redis_redis_parameter_t
194+ func redisListParameter (xs []* argument ) C.outbound_redis_list_redis_parameter_t {
195+ if len (xs ) == 0 {
196+ return C.outbound_redis_list_redis_parameter_t {}
197+ }
183198
199+ cxs := make ([]C.outbound_redis_redis_parameter_t , 0 , len (xs ))
184200 for i := 0 ; i < len (xs ); i ++ {
185201 cxs = append (cxs , redisParameter (xs [i ]))
186202 }
187203 return C.outbound_redis_list_redis_parameter_t {ptr : & cxs [0 ], len : C .size_t (len (cxs ))}
188204}
189205
190- func fromRedisResult (result * C.outbound_redis_redis_result_t ) RedisResult {
191- var val interface {}
192- switch result .tag {
193- case 0 : val = nil
194- case 1 : {
195- string := (* C .outbound_redis_string_t )(unsafe .Pointer (& result .val ))
196- val = C .GoStringN (string .ptr , C .int (string .len ))
197- }
198- case 2 : val = int64 (* (* C .int64_t )(unsafe .Pointer (& result .val )))
199- case 3 : {
206+ func fromRedisResult (result * C.outbound_redis_redis_result_t ) * Result {
207+ var val any
208+ switch ResultKind (result .tag ) {
209+ case ResultKindNil :
210+ val = nil
211+ case ResultKindStatus :
212+ str := (* C .outbound_redis_string_t )(unsafe .Pointer (& result .val ))
213+ val = C .GoStringN (str .ptr , C .int (str .len ))
214+ case ResultKindInt64 :
215+ val = int64 (* (* C .int64_t )(unsafe .Pointer (& result .val )))
216+ case ResultKindBinary :
200217 payload := (* C .outbound_redis_payload_t )(unsafe .Pointer (& result .val ))
201218 val = C .GoBytes (unsafe .Pointer (payload .ptr ), C .int (payload .len ))
202219 }
203- }
204220
205- return RedisResult {Kind : RedisResultKind (result .tag ), Val : val }
221+ return & Result {Kind : ResultKind (result .tag ), Val : val }
206222}
207223
208- func fromRedisListResult (list * C.outbound_redis_list_redis_result_t ) []RedisResult {
224+ func fromRedisListResult (list * C.outbound_redis_list_redis_result_t ) []* Result {
209225 listLen := int (list .len )
210- var result [] RedisResult
226+ result := make ([] * Result , 0 , listLen )
211227
212228 slice := unsafe .Slice (list .ptr , listLen )
213229 for i := 0 ; i < listLen ; i ++ {
0 commit comments