1 /*
2 +----------------------------------------------------------------------+
3 | Swoole |
4 +----------------------------------------------------------------------+
5 | This source file is subject to version 2.0 of the Apache license, |
6 | that is bundled with this package in the file LICENSE, and is |
7 | available through the world-wide-web at the following url: |
8 | http://www.apache.org/licenses/LICENSE-2.0.html |
9 | If you did not receive a copy of the Apache2.0 license and are unable|
10 | to obtain it through the world-wide-web, please send a note to |
11 | license@swoole.com so we can mail you a copy immediately. |
12 +----------------------------------------------------------------------+
13 | Author: Tianfeng Han <mikan.tenny@gmail.com> |
14 +----------------------------------------------------------------------+
15 */
16
17 #include "php_swoole_cxx.h"
18
19 #include "thirdparty/hiredis/hiredis.h"
20
21 #include "ext/standard/php_var.h"
22
23 using swoole::coroutine::Socket;
24 using namespace swoole;
25
26 #define SW_REDIS_COMMAND_ALLOC_ARGS_ARR zval *z_args = (zval *) emalloc(argc * sizeof(zval));
27 #define SW_REDIS_COMMAND_ARGS_TYPE(arg) Z_TYPE(arg)
28 #define SW_REDIS_COMMAND_ARGS_LVAL(arg) Z_LVAL(arg)
29 #define SW_REDIS_COMMAND_ARGS_DVAL(arg) Z_DVAL(arg)
30 #define SW_REDIS_COMMAND_ARGS_ARRVAL(arg) Z_ARRVAL(arg)
31 #define SW_REDIS_COMMAND_ARGS_STRVAL(arg) Z_STRVAL(arg)
32 #define SW_REDIS_COMMAND_ARGS_STRLEN(arg) Z_STRLEN(arg)
33 #define SW_REDIS_COMMAND_ARGS_REF(arg) &arg
34
35 #define SW_REDIS_COMMAND_BUFFER_SIZE 64
36 #define SW_BITOP_MIN_OFFSET 0
37 #define SW_BITOP_MAX_OFFSET 4294967295
38 #define SW_REDIS_TYPE_NOT_FOUND 0
39 #define SW_REDIS_TYPE_STRING 1
40 #define SW_REDIS_TYPE_SET 2
41 #define SW_REDIS_TYPE_LIST 3
42 #define SW_REDIS_TYPE_ZSET 4
43 #define SW_REDIS_TYPE_HASH 5
44
45 /* The same errCode define with hiredis */
46 enum swRedisError {
47 SW_REDIS_ERR_IO = 1, /* Error in read or write */
48 SW_REDIS_ERR_OTHER = 2, /* Everything else... */
49 SW_REDIS_ERR_EOF = 3, /* End of file */
50 SW_REDIS_ERR_PROTOCOL = 4, /* Protocol error */
51 SW_REDIS_ERR_OOM = 5, /* Out of memory */
52 SW_REDIS_ERR_CLOSED = 6, /* Closed */
53 SW_REDIS_ERR_NOAUTH = 7, /* Authentication required */
54 SW_REDIS_ERR_ALLOC = 8, /* Alloc failed */
55 };
56
57 /* Extended SET argument detection */
58 // clang-format off
59 #define IS_EX_ARG(a) \
60 ((a[0]=='e' || a[0]=='E') && (a[1]=='x' || a[1]=='X') && a[2]=='\0')
61 #define IS_PX_ARG(a) \
62 ((a[0]=='p' || a[0]=='P') && (a[1]=='x' || a[1]=='X') && a[2]=='\0')
63 #define IS_NX_ARG(a) \
64 ((a[0]=='n' || a[0]=='N') && (a[1]=='x' || a[1]=='X') && a[2]=='\0')
65 #define IS_XX_ARG(a) \
66 ((a[0]=='x' || a[0]=='X') && (a[1]=='x' || a[1]=='X') && a[2]=='\0')
67
68 static zend_class_entry *swoole_redis_coro_ce;
69 static zend_object_handlers swoole_redis_coro_handlers;
70
71 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_construct, 0, 0, 0)
72 ZEND_ARG_INFO(0, config)
73 ZEND_END_ARG_INFO()
74
75 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_connect, 0, 0, 1)
76 ZEND_ARG_INFO(0, host)
77 ZEND_ARG_INFO(0, port)
78 ZEND_ARG_INFO(0, serialize)
79 ZEND_END_ARG_INFO()
80
81 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_setOptions, 0, 0, 1)
82 ZEND_ARG_INFO(0, options)
83 ZEND_END_ARG_INFO()
84
85 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_setDefer, 0, 0, 1)
86 ZEND_ARG_INFO(0, defer)
87 ZEND_END_ARG_INFO()
88
89 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_void, 0, 0, 0)
90 ZEND_END_ARG_INFO()
91
92 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_key, 0, 0, 1)
93 ZEND_ARG_INFO(0, key)
94 ZEND_END_ARG_INFO()
95
96 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_key_value, 0, 0, 2)
97 ZEND_ARG_INFO(0, key)
98 ZEND_ARG_INFO(0, value)
99 ZEND_END_ARG_INFO()
100
101 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_key_long, 0, 0, 2)
102 ZEND_ARG_INFO(0, key)
103 ZEND_ARG_INFO(0, integer)
104 ZEND_END_ARG_INFO()
105
106 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_request, 0, 0, 1)
107 ZEND_ARG_ARRAY_INFO(0, params, 0)
108 ZEND_END_ARG_INFO()
109
110 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_append, 0, 0, 2)
111 ZEND_ARG_INFO(0, key)
112 ZEND_ARG_INFO(0, value)
113 ZEND_END_ARG_INFO()
114
115 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_auth, 0, 0, 1)
116 ZEND_ARG_INFO(0, password)
117 ZEND_END_ARG_INFO()
118
119 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_bgSave, 0, 0, 0)
120 ZEND_END_ARG_INFO()
121
122 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_bgrewriteaof, 0, 0, 0)
123 ZEND_END_ARG_INFO()
124
125 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_bitcount, 0, 0, 1)
126 ZEND_ARG_INFO(0, key)
127 ZEND_END_ARG_INFO()
128
129 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_bitop, 0, 0, 3)
130 ZEND_ARG_INFO(0, operation)
131 ZEND_ARG_INFO(0, ret_key)
132 ZEND_ARG_INFO(0, key)
133 ZEND_ARG_INFO(0, other_keys)
134 ZEND_END_ARG_INFO()
135
136 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_blPop, 0, 0, 2)
137 ZEND_ARG_INFO(0, key)
138 ZEND_ARG_INFO(0, timeout_or_key)
139 ZEND_ARG_INFO(0, extra_args)
140 ZEND_END_ARG_INFO()
141
142 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_brPop, 0, 0, 2)
143 ZEND_ARG_INFO(0, key)
144 ZEND_ARG_INFO(0, timeout_or_key)
145 ZEND_ARG_INFO(0, extra_args)
146 ZEND_END_ARG_INFO()
147
148 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_brpoplpush, 0, 0, 3)
149 ZEND_ARG_INFO(0, src)
150 ZEND_ARG_INFO(0, dst)
151 ZEND_ARG_INFO(0, timeout)
152 ZEND_END_ARG_INFO()
153
154 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_close, 0, 0, 0)
155 ZEND_END_ARG_INFO()
156
157 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_dbSize, 0, 0, 0)
158 ZEND_END_ARG_INFO()
159
160 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_debug, 0, 0, 1)
161 ZEND_ARG_INFO(0, key)
162 ZEND_END_ARG_INFO()
163
164 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_decr, 0, 0, 1)
165 ZEND_ARG_INFO(0, key)
166 ZEND_END_ARG_INFO()
167
168 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_decrBy, 0, 0, 2)
169 ZEND_ARG_INFO(0, key)
170 ZEND_ARG_INFO(0, value)
171 ZEND_END_ARG_INFO()
172
173 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_dump, 0, 0, 1)
174 ZEND_ARG_INFO(0, key)
175 ZEND_END_ARG_INFO()
176
177 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_eval, 0, 0, 1)
178 ZEND_ARG_INFO(0, script)
179 ZEND_ARG_INFO(0, args)
180 ZEND_ARG_INFO(0, num_keys)
181 ZEND_END_ARG_INFO()
182
183 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_evalsha, 0, 0, 1)
184 ZEND_ARG_INFO(0, script_sha)
185 ZEND_ARG_INFO(0, args)
186 ZEND_ARG_INFO(0, num_keys)
187 ZEND_END_ARG_INFO()
188
189 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_exec, 0, 0, 0)
190 ZEND_END_ARG_INFO()
191
192 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_exists, 0, 0, 1)
193 ZEND_ARG_INFO(0, key)
194 ZEND_ARG_INFO(0, other_keys)
195 ZEND_END_ARG_INFO()
196
197 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_expireAt, 0, 0, 2)
198 ZEND_ARG_INFO(0, key)
199 ZEND_ARG_INFO(0, timestamp)
200 ZEND_END_ARG_INFO()
201
202 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_flushAll, 0, 0, 0)
203 ZEND_END_ARG_INFO()
204
205 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_flushDB, 0, 0, 0)
206 ZEND_END_ARG_INFO()
207
208 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_get, 0, 0, 1)
209 ZEND_ARG_INFO(0, key)
210 ZEND_END_ARG_INFO()
211
212 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_getBit, 0, 0, 2)
213 ZEND_ARG_INFO(0, key)
214 ZEND_ARG_INFO(0, offset)
215 ZEND_END_ARG_INFO()
216
217 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_getKeys, 0, 0, 1)
218 ZEND_ARG_INFO(0, pattern)
219 ZEND_END_ARG_INFO()
220
221 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_getRange, 0, 0, 3)
222 ZEND_ARG_INFO(0, key)
223 ZEND_ARG_INFO(0, start)
224 ZEND_ARG_INFO(0, end)
225 ZEND_END_ARG_INFO()
226
227 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_getSet, 0, 0, 2)
228 ZEND_ARG_INFO(0, key)
229 ZEND_ARG_INFO(0, value)
230 ZEND_END_ARG_INFO()
231
232 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_hDel, 0, 0, 2)
233 ZEND_ARG_INFO(0, key)
234 ZEND_ARG_INFO(0, member)
235 ZEND_ARG_INFO(0, other_members)
236 ZEND_END_ARG_INFO()
237
238 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_hExists, 0, 0, 2)
239 ZEND_ARG_INFO(0, key)
240 ZEND_ARG_INFO(0, member)
241 ZEND_END_ARG_INFO()
242
243 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_hGet, 0, 0, 2)
244 ZEND_ARG_INFO(0, key)
245 ZEND_ARG_INFO(0, member)
246 ZEND_END_ARG_INFO()
247
248 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_hGetAll, 0, 0, 1)
249 ZEND_ARG_INFO(0, key)
250 ZEND_END_ARG_INFO()
251
252 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_hIncrBy, 0, 0, 3)
253 ZEND_ARG_INFO(0, key)
254 ZEND_ARG_INFO(0, member)
255 ZEND_ARG_INFO(0, value)
256 ZEND_END_ARG_INFO()
257
258 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_hIncrByFloat, 0, 0, 3)
259 ZEND_ARG_INFO(0, key)
260 ZEND_ARG_INFO(0, member)
261 ZEND_ARG_INFO(0, value)
262 ZEND_END_ARG_INFO()
263
264 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_hKeys, 0, 0, 1)
265 ZEND_ARG_INFO(0, key)
266 ZEND_END_ARG_INFO()
267
268 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_hLen, 0, 0, 1)
269 ZEND_ARG_INFO(0, key)
270 ZEND_END_ARG_INFO()
271
272 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_hMget, 0, 0, 2)
273 ZEND_ARG_INFO(0, key)
274 ZEND_ARG_INFO(0, keys)
275 ZEND_END_ARG_INFO()
276
277 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_hMset, 0, 0, 2)
278 ZEND_ARG_INFO(0, key)
279 ZEND_ARG_INFO(0, pairs)
280 ZEND_END_ARG_INFO()
281
282 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_hSet, 0, 0, 3)
283 ZEND_ARG_INFO(0, key)
284 ZEND_ARG_INFO(0, member)
285 ZEND_ARG_INFO(0, value)
286 ZEND_END_ARG_INFO()
287
288 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_hSetNx, 0, 0, 3)
289 ZEND_ARG_INFO(0, key)
290 ZEND_ARG_INFO(0, member)
291 ZEND_ARG_INFO(0, value)
292 ZEND_END_ARG_INFO()
293
294 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_hVals, 0, 0, 1)
295 ZEND_ARG_INFO(0, key)
296 ZEND_END_ARG_INFO()
297
298 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_incr, 0, 0, 1)
299 ZEND_ARG_INFO(0, key)
300 ZEND_END_ARG_INFO()
301
302 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_incrBy, 0, 0, 2)
303 ZEND_ARG_INFO(0, key)
304 ZEND_ARG_INFO(0, value)
305 ZEND_END_ARG_INFO()
306
307 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_incrByFloat, 0, 0, 2)
308 ZEND_ARG_INFO(0, key)
309 ZEND_ARG_INFO(0, value)
310 ZEND_END_ARG_INFO()
311
312 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_lGet, 0, 0, 2)
313 ZEND_ARG_INFO(0, key)
314 ZEND_ARG_INFO(0, index)
315 ZEND_END_ARG_INFO()
316
317 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_lGetRange, 0, 0, 3)
318 ZEND_ARG_INFO(0, key)
319 ZEND_ARG_INFO(0, start)
320 ZEND_ARG_INFO(0, end)
321 ZEND_END_ARG_INFO()
322
323 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_lInsert, 0, 0, 4)
324 ZEND_ARG_INFO(0, key)
325 ZEND_ARG_INFO(0, position)
326 ZEND_ARG_INFO(0, pivot)
327 ZEND_ARG_INFO(0, value)
328 ZEND_END_ARG_INFO()
329
330 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_lPop, 0, 0, 1)
331 ZEND_ARG_INFO(0, key)
332 ZEND_END_ARG_INFO()
333
334 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_lPush, 0, 0, 2)
335 ZEND_ARG_INFO(0, key)
336 ZEND_ARG_INFO(0, value)
337 ZEND_END_ARG_INFO()
338
339 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_lPushx, 0, 0, 2)
340 ZEND_ARG_INFO(0, key)
341 ZEND_ARG_INFO(0, value)
342 ZEND_END_ARG_INFO()
343
344 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_lRemove, 0, 0, 3)
345 ZEND_ARG_INFO(0, key)
346 ZEND_ARG_INFO(0, value)
347 ZEND_ARG_INFO(0, count)
348 ZEND_END_ARG_INFO()
349
350 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_lSet, 0, 0, 3)
351 ZEND_ARG_INFO(0, key)
352 ZEND_ARG_INFO(0, index)
353 ZEND_ARG_INFO(0, value)
354 ZEND_END_ARG_INFO()
355
356 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_lSize, 0, 0, 1)
357 ZEND_ARG_INFO(0, key)
358 ZEND_END_ARG_INFO()
359
360 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_lastSave, 0, 0, 0)
361 ZEND_END_ARG_INFO()
362
363 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_listTrim, 0, 0, 3)
364 ZEND_ARG_INFO(0, key)
365 ZEND_ARG_INFO(0, start)
366 ZEND_ARG_INFO(0, stop)
367 ZEND_END_ARG_INFO()
368
369 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_move, 0, 0, 2)
370 ZEND_ARG_INFO(0, key)
371 ZEND_ARG_INFO(0, dbindex)
372 ZEND_END_ARG_INFO()
373
374 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_mset, 0, 0, 1)
375 ZEND_ARG_INFO(0, pairs)
376 ZEND_END_ARG_INFO()
377
378 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_msetnx, 0, 0, 1)
379 ZEND_ARG_INFO(0, pairs)
380 ZEND_END_ARG_INFO()
381
382 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_multi, 0, 0, 0)
383 ZEND_END_ARG_INFO()
384
385 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_persist, 0, 0, 1)
386 ZEND_ARG_INFO(0, key)
387 ZEND_END_ARG_INFO()
388
389 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_pexpire, 0, 0, 2)
390 ZEND_ARG_INFO(0, key)
391 ZEND_ARG_INFO(0, timestamp)
392 ZEND_END_ARG_INFO()
393
394 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_pexpireAt, 0, 0, 2)
395 ZEND_ARG_INFO(0, key)
396 ZEND_ARG_INFO(0, timestamp)
397 ZEND_END_ARG_INFO()
398
399 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_pfadd, 0, 0, 2)
400 ZEND_ARG_INFO(0, key)
401 ZEND_ARG_INFO(0, elements)
402 ZEND_END_ARG_INFO()
403
404 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_pfcount, 0, 0, 1)
405 ZEND_ARG_INFO(0, key)
406 ZEND_END_ARG_INFO()
407
408 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_pfmerge, 0, 0, 2)
409 ZEND_ARG_INFO(0, dstkey)
410 ZEND_ARG_INFO(0, keys)
411 ZEND_END_ARG_INFO()
412
413 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_ping, 0, 0, 0)
414 ZEND_END_ARG_INFO()
415
416 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_psetex, 0, 0, 3)
417 ZEND_ARG_INFO(0, key)
418 ZEND_ARG_INFO(0, expire)
419 ZEND_ARG_INFO(0, value)
420 ZEND_END_ARG_INFO()
421
422 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_psubscribe, 0, 0, 1)
423 ZEND_ARG_INFO(0, patterns)
424 ZEND_END_ARG_INFO()
425
426 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_punsubscribe, 0, 0, 1)
427 ZEND_ARG_INFO(0, patterns)
428 ZEND_END_ARG_INFO()
429
430 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_pttl, 0, 0, 1)
431 ZEND_ARG_INFO(0, key)
432 ZEND_END_ARG_INFO()
433
434 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_publish, 0, 0, 2)
435 ZEND_ARG_INFO(0, channel)
436 ZEND_ARG_INFO(0, message)
437 ZEND_END_ARG_INFO()
438
439 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_rPop, 0, 0, 1)
440 ZEND_ARG_INFO(0, key)
441 ZEND_END_ARG_INFO()
442
443 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_rPush, 0, 0, 2)
444 ZEND_ARG_INFO(0, key)
445 ZEND_ARG_INFO(0, value)
446 ZEND_END_ARG_INFO()
447
448 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_rPushx, 0, 0, 2)
449 ZEND_ARG_INFO(0, key)
450 ZEND_ARG_INFO(0, value)
451 ZEND_END_ARG_INFO()
452
453 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_randomKey, 0, 0, 0)
454 ZEND_END_ARG_INFO()
455
456 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_renameKey, 0, 0, 2)
457 ZEND_ARG_INFO(0, key)
458 ZEND_ARG_INFO(0, newkey)
459 ZEND_END_ARG_INFO()
460
461 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_renameNx, 0, 0, 2)
462 ZEND_ARG_INFO(0, key)
463 ZEND_ARG_INFO(0, newkey)
464 ZEND_END_ARG_INFO()
465
466 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_restore, 0, 0, 3)
467 ZEND_ARG_INFO(0, ttl)
468 ZEND_ARG_INFO(0, key)
469 ZEND_ARG_INFO(0, value)
470 ZEND_END_ARG_INFO()
471
472 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_role, 0, 0, 0)
473 ZEND_END_ARG_INFO()
474
475 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_rpoplpush, 0, 0, 2)
476 ZEND_ARG_INFO(0, src)
477 ZEND_ARG_INFO(0, dst)
478 ZEND_END_ARG_INFO()
479
480 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_sAdd, 0, 0, 2)
481 ZEND_ARG_INFO(0, key)
482 ZEND_ARG_INFO(0, value)
483 ZEND_END_ARG_INFO()
484
485 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_sContains, 0, 0, 2)
486 ZEND_ARG_INFO(0, key)
487 ZEND_ARG_INFO(0, value)
488 ZEND_END_ARG_INFO()
489
490 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_sDiff, 0, 0, 1)
491 ZEND_ARG_INFO(0, key)
492 ZEND_ARG_INFO(0, other_keys)
493 ZEND_END_ARG_INFO()
494
495 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_sDiffStore, 0, 0, 2)
496 ZEND_ARG_INFO(0, dst)
497 ZEND_ARG_INFO(0, key)
498 ZEND_ARG_INFO(0, other_keys)
499 ZEND_END_ARG_INFO()
500
501 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_sInter, 0, 0, 1)
502 ZEND_ARG_INFO(0, key)
503 ZEND_ARG_INFO(0, other_keys)
504 ZEND_END_ARG_INFO()
505
506 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_sInterStore, 0, 0, 2)
507 ZEND_ARG_INFO(0, dst)
508 ZEND_ARG_INFO(0, key)
509 ZEND_ARG_INFO(0, other_keys)
510 ZEND_END_ARG_INFO()
511
512 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_sMembers, 0, 0, 1)
513 ZEND_ARG_INFO(0, key)
514 ZEND_END_ARG_INFO()
515
516 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_sMove, 0, 0, 3)
517 ZEND_ARG_INFO(0, src)
518 ZEND_ARG_INFO(0, dst)
519 ZEND_ARG_INFO(0, value)
520 ZEND_END_ARG_INFO()
521
522 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_sPop, 0, 0, 1)
523 ZEND_ARG_INFO(0, key)
524 ZEND_END_ARG_INFO()
525
526 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_sRandMember, 0, 0, 1)
527 ZEND_ARG_INFO(0, key)
528 ZEND_ARG_INFO(0, count)
529 ZEND_END_ARG_INFO()
530
531 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_sRemove, 0, 0, 2)
532 ZEND_ARG_INFO(0, key)
533 ZEND_ARG_INFO(0, value)
534 ZEND_END_ARG_INFO()
535
536 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_sSize, 0, 0, 1)
537 ZEND_ARG_INFO(0, key)
538 ZEND_END_ARG_INFO()
539
540 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_sUnion, 0, 0, 1)
541 ZEND_ARG_INFO(0, key)
542 ZEND_ARG_INFO(0, other_keys)
543 ZEND_END_ARG_INFO()
544
545 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_sUnionStore, 0, 0, 2)
546 ZEND_ARG_INFO(0, dst)
547 ZEND_ARG_INFO(0, key)
548 ZEND_ARG_INFO(0, other_keys)
549 ZEND_END_ARG_INFO()
550
551 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_save, 0, 0, 0)
552 ZEND_END_ARG_INFO()
553
554 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_script, 0, 0, 1)
555 ZEND_ARG_INFO(0, cmd)
556 ZEND_ARG_INFO(0, args)
557 ZEND_END_ARG_INFO()
558
559 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_select, 0, 0, 1)
560 ZEND_ARG_INFO(0, dbindex)
561 ZEND_END_ARG_INFO()
562
563 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_set, 0, 0, 2)
564 ZEND_ARG_INFO(0, key)
565 ZEND_ARG_INFO(0, value)
566 ZEND_ARG_INFO(0, timeout)
567 ZEND_ARG_INFO(0, opt)
568 ZEND_END_ARG_INFO()
569
570 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_setBit, 0, 0, 3)
571 ZEND_ARG_INFO(0, key)
572 ZEND_ARG_INFO(0, offset)
573 ZEND_ARG_INFO(0, value)
574 ZEND_END_ARG_INFO()
575
576 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_setRange, 0, 0, 3)
577 ZEND_ARG_INFO(0, key)
578 ZEND_ARG_INFO(0, offset)
579 ZEND_ARG_INFO(0, value)
580 ZEND_END_ARG_INFO()
581
582 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_setTimeout, 0, 0, 2)
583 ZEND_ARG_INFO(0, key)
584 ZEND_ARG_INFO(0, timeout)
585 ZEND_END_ARG_INFO()
586
587 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_setex, 0, 0, 3)
588 ZEND_ARG_INFO(0, key)
589 ZEND_ARG_INFO(0, expire)
590 ZEND_ARG_INFO(0, value)
591 ZEND_END_ARG_INFO()
592
593 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_setnx, 0, 0, 2)
594 ZEND_ARG_INFO(0, key)
595 ZEND_ARG_INFO(0, value)
596 ZEND_END_ARG_INFO()
597
598 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_strlen, 0, 0, 1)
599 ZEND_ARG_INFO(0, key)
600 ZEND_END_ARG_INFO()
601
602 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_subscribe, 0, 0, 1)
603 ZEND_ARG_INFO(0, channels)
604 ZEND_END_ARG_INFO()
605
606 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_unsubscribe, 0, 0, 1)
607 ZEND_ARG_INFO(0, channels)
608 ZEND_END_ARG_INFO()
609
610 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_time, 0, 0, 0)
611 ZEND_END_ARG_INFO()
612
613 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_ttl, 0, 0, 1)
614 ZEND_ARG_INFO(0, key)
615 ZEND_END_ARG_INFO()
616
617 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_type, 0, 0, 1)
618 ZEND_ARG_INFO(0, key)
619 ZEND_END_ARG_INFO()
620
621 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_unwatch, 0, 0, 0)
622 ZEND_END_ARG_INFO()
623
624 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_watch, 0, 0, 1)
625 ZEND_ARG_INFO(0, key)
626 ZEND_ARG_INFO(0, other_keys)
627 ZEND_END_ARG_INFO()
628
629 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_zAdd, 0, 0, 3)
630 ZEND_ARG_INFO(0, key)
631 ZEND_ARG_INFO(0, score)
632 ZEND_ARG_INFO(0, value)
633 ZEND_END_ARG_INFO()
634
635 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_zPopMin, 0, 0, 2)
636 ZEND_ARG_INFO(0, key)
637 ZEND_ARG_INFO(0, count)
638 ZEND_END_ARG_INFO()
639
640 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_zPopMax, 0, 0, 2)
641 ZEND_ARG_INFO(0, key)
642 ZEND_ARG_INFO(0, count)
643 ZEND_END_ARG_INFO()
644
645 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_bzPopMin, 0, 0, 2)
646 ZEND_ARG_INFO(0, key)
647 ZEND_ARG_INFO(0, timeout_or_key)
648 ZEND_ARG_INFO(0, extra_args)
649 ZEND_END_ARG_INFO()
650
651 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_bzPopMax, 0, 0, 2)
652 ZEND_ARG_INFO(0, key)
653 ZEND_ARG_INFO(0, timeout_or_key)
654 ZEND_ARG_INFO(0, extra_args)
655 ZEND_END_ARG_INFO()
656
657 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_zCard, 0, 0, 1)
658 ZEND_ARG_INFO(0, key)
659 ZEND_END_ARG_INFO()
660
661 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_zCount, 0, 0, 3)
662 ZEND_ARG_INFO(0, key)
663 ZEND_ARG_INFO(0, min)
664 ZEND_ARG_INFO(0, max)
665 ZEND_END_ARG_INFO()
666
667 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_zDelete, 0, 0, 2)
668 ZEND_ARG_INFO(0, key)
669 ZEND_ARG_INFO(0, member)
670 ZEND_ARG_INFO(0, other_members)
671 ZEND_END_ARG_INFO()
672
673 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_zDeleteRangeByRank, 0, 0, 3)
674 ZEND_ARG_INFO(0, key)
675 ZEND_ARG_INFO(0, start)
676 ZEND_ARG_INFO(0, end)
677 ZEND_END_ARG_INFO()
678
679 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_zDeleteRangeByScore, 0, 0, 3)
680 ZEND_ARG_INFO(0, key)
681 ZEND_ARG_INFO(0, min)
682 ZEND_ARG_INFO(0, max)
683 ZEND_END_ARG_INFO()
684
685 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_zIncrBy, 0, 0, 3)
686 ZEND_ARG_INFO(0, key)
687 ZEND_ARG_INFO(0, value)
688 ZEND_ARG_INFO(0, member)
689 ZEND_END_ARG_INFO()
690
691 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_zInter, 0, 0, 2)
692 ZEND_ARG_INFO(0, key)
693 ZEND_ARG_INFO(0, keys)
694 ZEND_ARG_INFO(0, weights)
695 ZEND_ARG_INFO(0, aggregate)
696 ZEND_END_ARG_INFO()
697
698 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_zRange, 0, 0, 3)
699 ZEND_ARG_INFO(0, key)
700 ZEND_ARG_INFO(0, start)
701 ZEND_ARG_INFO(0, end)
702 ZEND_ARG_INFO(0, scores)
703 ZEND_END_ARG_INFO()
704
705 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_zRangeByLex, 0, 0, 3)
706 ZEND_ARG_INFO(0, key)
707 ZEND_ARG_INFO(0, min)
708 ZEND_ARG_INFO(0, max)
709 ZEND_ARG_INFO(0, offset)
710 ZEND_ARG_INFO(0, limit)
711 ZEND_END_ARG_INFO()
712
713 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_zRangeByScore, 0, 0, 3)
714 ZEND_ARG_INFO(0, key)
715 ZEND_ARG_INFO(0, start)
716 ZEND_ARG_INFO(0, end)
717 ZEND_ARG_INFO(0, options)
718 ZEND_END_ARG_INFO()
719
720 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_zRank, 0, 0, 2)
721 ZEND_ARG_INFO(0, key)
722 ZEND_ARG_INFO(0, member)
723 ZEND_END_ARG_INFO()
724
725 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_zRevRange, 0, 0, 3)
726 ZEND_ARG_INFO(0, key)
727 ZEND_ARG_INFO(0, start)
728 ZEND_ARG_INFO(0, end)
729 ZEND_ARG_INFO(0, scores)
730 ZEND_END_ARG_INFO()
731
732 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_zRevRangeByLex, 0, 0, 3)
733 ZEND_ARG_INFO(0, key)
734 ZEND_ARG_INFO(0, min)
735 ZEND_ARG_INFO(0, max)
736 ZEND_ARG_INFO(0, offset)
737 ZEND_ARG_INFO(0, limit)
738 ZEND_END_ARG_INFO()
739
740 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_zRevRangeByScore, 0, 0, 3)
741 ZEND_ARG_INFO(0, key)
742 ZEND_ARG_INFO(0, start)
743 ZEND_ARG_INFO(0, end)
744 ZEND_ARG_INFO(0, options)
745 ZEND_END_ARG_INFO()
746
747 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_zRevRank, 0, 0, 2)
748 ZEND_ARG_INFO(0, key)
749 ZEND_ARG_INFO(0, member)
750 ZEND_END_ARG_INFO()
751
752 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_zScore, 0, 0, 2)
753 ZEND_ARG_INFO(0, key)
754 ZEND_ARG_INFO(0, member)
755 ZEND_END_ARG_INFO()
756
757 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_zUnion, 0, 0, 2)
758 ZEND_ARG_INFO(0, key)
759 ZEND_ARG_INFO(0, keys)
760 ZEND_ARG_INFO(0, weights)
761 ZEND_ARG_INFO(0, aggregate)
762 ZEND_END_ARG_INFO()
763
764 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_del, 0, 0, 1)
765 ZEND_ARG_INFO(0, key)
766 ZEND_ARG_INFO(0, other_keys)
767 ZEND_END_ARG_INFO()
768
769 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_lLen, 0, 0, 1)
770 ZEND_ARG_INFO(0, key)
771 ZEND_END_ARG_INFO()
772
773 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_lrange, 0, 0, 3)
774 ZEND_ARG_INFO(0, key)
775 ZEND_ARG_INFO(0, start)
776 ZEND_ARG_INFO(0, end)
777 ZEND_END_ARG_INFO()
778
779 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_lrem, 0, 0, 3)
780 ZEND_ARG_INFO(0, key)
781 ZEND_ARG_INFO(0, value)
782 ZEND_ARG_INFO(0, count)
783 ZEND_END_ARG_INFO()
784
785 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_ltrim, 0, 0, 3)
786 ZEND_ARG_INFO(0, key)
787 ZEND_ARG_INFO(0, start)
788 ZEND_ARG_INFO(0, stop)
789 ZEND_END_ARG_INFO()
790
791 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_mget, 0, 0, 1)
792 ZEND_ARG_INFO(0, keys)
793 ZEND_END_ARG_INFO()
794
795 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_rename, 0, 0, 2)
796 ZEND_ARG_INFO(0, key)
797 ZEND_ARG_INFO(0, newkey)
798 ZEND_END_ARG_INFO()
799
800 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_scard, 0, 0, 1)
801 ZEND_ARG_INFO(0, key)
802 ZEND_END_ARG_INFO()
803
804 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_zRem, 0, 0, 2)
805 ZEND_ARG_INFO(0, key)
806 ZEND_ARG_INFO(0, member)
807 ZEND_ARG_INFO(0, other_members)
808 ZEND_END_ARG_INFO()
809
810 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_zRemRangeByRank, 0, 0, 3)
811 ZEND_ARG_INFO(0, key)
812 ZEND_ARG_INFO(0, min)
813 ZEND_ARG_INFO(0, max)
814 ZEND_END_ARG_INFO()
815
816 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_zRemRangeByScore, 0, 0, 3)
817 ZEND_ARG_INFO(0, key)
818 ZEND_ARG_INFO(0, min)
819 ZEND_ARG_INFO(0, max)
820 ZEND_END_ARG_INFO()
821
822 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_zRemove, 0, 0, 2)
823 ZEND_ARG_INFO(0, key)
824 ZEND_ARG_INFO(0, member)
825 ZEND_ARG_INFO(0, other_members)
826 ZEND_END_ARG_INFO()
827
828 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_zSize, 0, 0, 1)
829 ZEND_ARG_INFO(0, key)
830 ZEND_END_ARG_INFO()
831
832 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_zinterstore, 0, 0, 2)
833 ZEND_ARG_INFO(0, key)
834 ZEND_ARG_INFO(0, keys)
835 ZEND_ARG_INFO(0, weights)
836 ZEND_ARG_INFO(0, aggregate)
837 ZEND_END_ARG_INFO()
838
839 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_zunionstore, 0, 0, 2)
840 ZEND_ARG_INFO(0, key)
841 ZEND_ARG_INFO(0, keys)
842 ZEND_ARG_INFO(0, weights)
843 ZEND_ARG_INFO(0, aggregate)
844 ZEND_END_ARG_INFO()
845
846 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_xLen, 0, 0, 1)
847 ZEND_ARG_INFO(0, key)
848 ZEND_END_ARG_INFO()
849
850 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_xAdd, 0, 0, 3)
851 ZEND_ARG_INFO(0, key)
852 ZEND_ARG_INFO(0, id)
853 ZEND_ARG_INFO(0, pairs)
854 ZEND_ARG_INFO(0, options)
855 ZEND_END_ARG_INFO()
856
857 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_xRead, 0, 0, 1)
858 ZEND_ARG_INFO(0, streams)
859 ZEND_ARG_INFO(0, options)
860 ZEND_END_ARG_INFO()
861
862 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_xDel, 0, 0, 2)
863 ZEND_ARG_INFO(0, key)
864 ZEND_ARG_INFO(0, id)
865 ZEND_END_ARG_INFO()
866
867 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_xRange, 0, 0, 3)
868 ZEND_ARG_INFO(0, key)
869 ZEND_ARG_INFO(0, start)
870 ZEND_ARG_INFO(0, end)
871 ZEND_ARG_INFO(0, count)
872 ZEND_END_ARG_INFO()
873
874 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_xRevRange, 0, 0, 3)
875 ZEND_ARG_INFO(0, key)
876 ZEND_ARG_INFO(0, start)
877 ZEND_ARG_INFO(0, end)
878 ZEND_ARG_INFO(0, count)
879 ZEND_END_ARG_INFO()
880
881 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_xTrim, 0, 0, 1)
882 ZEND_ARG_INFO(0, key)
883 ZEND_ARG_INFO(0, options)
884 ZEND_END_ARG_INFO()
885
886 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_xGroupCreate, 0, 0, 3)
887 ZEND_ARG_INFO(0, key)
888 ZEND_ARG_INFO(0, group_name)
889 ZEND_ARG_INFO(0, id)
890 ZEND_ARG_INFO(0, mkstream)
891 ZEND_END_ARG_INFO()
892
893 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_xGroupSetId, 0, 0, 3)
894 ZEND_ARG_INFO(0, key)
895 ZEND_ARG_INFO(0, group_name)
896 ZEND_ARG_INFO(0, id)
897 ZEND_END_ARG_INFO()
898
899 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_xGroupDestroy, 0, 0, 2)
900 ZEND_ARG_INFO(0, key)
901 ZEND_ARG_INFO(0, group_name)
902 ZEND_END_ARG_INFO()
903
904 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_xGroupCreateConsumer, 0, 0, 3)
905 ZEND_ARG_INFO(0, key)
906 ZEND_ARG_INFO(0, group_name)
907 ZEND_ARG_INFO(0, consumer_name)
908 ZEND_END_ARG_INFO()
909
910 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_xGroupDelConsumer, 0, 0, 3)
911 ZEND_ARG_INFO(0, key)
912 ZEND_ARG_INFO(0, group_name)
913 ZEND_ARG_INFO(0, consumer_name)
914 ZEND_END_ARG_INFO()
915
916 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_xReadGroup, 0, 0, 3)
917 ZEND_ARG_INFO(0, group_name)
918 ZEND_ARG_INFO(0, consumer_name)
919 ZEND_ARG_INFO(0, streams)
920 ZEND_ARG_INFO(0, options)
921 ZEND_END_ARG_INFO()
922
923 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_xPending, 0, 0, 2)
924 ZEND_ARG_INFO(0, key)
925 ZEND_ARG_INFO(0, group_name)
926 ZEND_ARG_INFO(0, options)
927 ZEND_END_ARG_INFO()
928
929 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_xAck, 0, 0, 3)
930 ZEND_ARG_INFO(0, key)
931 ZEND_ARG_INFO(0, group_name)
932 ZEND_ARG_INFO(0, id)
933 ZEND_END_ARG_INFO()
934
935 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_xClaim, 0, 0, 5)
936 ZEND_ARG_INFO(0, key)
937 ZEND_ARG_INFO(0, group_name)
938 ZEND_ARG_INFO(0, consumer_name)
939 ZEND_ARG_INFO(0, min_idle_time)
940 ZEND_ARG_INFO(0, id)
941 ZEND_ARG_INFO(0, options)
942 ZEND_END_ARG_INFO()
943
944 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_xAutoClaim, 0, 0, 5)
945 ZEND_ARG_INFO(0, key)
946 ZEND_ARG_INFO(0, group_name)
947 ZEND_ARG_INFO(0, consumer_name)
948 ZEND_ARG_INFO(0, min_idle_time)
949 ZEND_ARG_INFO(0, start)
950 ZEND_ARG_INFO(0, options)
951 ZEND_END_ARG_INFO()
952
953 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_xInfoConsumers, 0, 0, 2)
954 ZEND_ARG_INFO(0, key)
955 ZEND_ARG_INFO(0, group_name)
956 ZEND_END_ARG_INFO()
957
958 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_xInfoGroups, 0, 0, 1)
959 ZEND_ARG_INFO(0, key)
960 ZEND_END_ARG_INFO()
961
962 ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_xInfoStream, 0, 0, 1)
963 ZEND_ARG_INFO(0, key)
964 ZEND_END_ARG_INFO()
965 // clang-format on
966
967 #define IS_EX_PX_ARG(a) (IS_EX_ARG(a) || IS_PX_ARG(a))
968 #define IS_NX_XX_ARG(a) (IS_NX_ARG(a) || IS_XX_ARG(a))
969
970 struct RedisClient {
971 redisContext *context;
972 struct {
973 bool auth;
974 long db_num;
975 bool subscribe;
976 } session;
977 double connect_timeout;
978 double timeout;
979 bool serialize;
980 bool defer;
981 uint8_t reconnect_interval;
982 uint8_t reconnected_count;
983 bool auth;
984 bool compatibility_mode;
985 long database;
986 zval *zobject;
987 zval _zobject;
988 zend_object std;
989 };
990
991 #define SW_REDIS_COMMAND_CHECK \
992 Coroutine::get_current_safe(); \
993 RedisClient *redis = php_swoole_get_redis_client(ZEND_THIS);
994
995 #define SW_REDIS_COMMAND_ARGV_FILL(str, str_len) \
996 argvlen[i] = str_len; \
997 argv[i] = estrndup(str, str_len); \
998 i++;
999
1000 #define SW_REDIS_COMMAND_ARGV_FILL_WITH_SERIALIZE(_val) \
1001 if (redis->serialize) { \
1002 smart_str sstr = {}; \
1003 php_serialize_data_t s_ht; \
1004 PHP_VAR_SERIALIZE_INIT(s_ht); \
1005 php_var_serialize(&sstr, _val, &s_ht); \
1006 argvlen[i] = (size_t) sstr.s->len; \
1007 argv[i] = estrndup(sstr.s->val, sstr.s->len); \
1008 zend_string_release(sstr.s); \
1009 PHP_VAR_SERIALIZE_DESTROY(s_ht); \
1010 } else { \
1011 zend_string *convert_str = zval_get_string(_val); \
1012 argvlen[i] = ZSTR_LEN(convert_str); \
1013 argv[i] = estrndup(ZSTR_VAL(convert_str), ZSTR_LEN(convert_str)); \
1014 zend_string_release(convert_str); \
1015 } \
1016 i++;
1017
1018 #define SW_REDIS_COMMAND_ALLOC_ARGV \
1019 size_t stack_argvlen[SW_REDIS_COMMAND_BUFFER_SIZE]; \
1020 char *stack_argv[SW_REDIS_COMMAND_BUFFER_SIZE]; \
1021 size_t *argvlen; \
1022 char **argv; \
1023 if (argc > SW_REDIS_COMMAND_BUFFER_SIZE) { \
1024 argvlen = (size_t *) emalloc(sizeof(size_t) * (argc)); \
1025 argv = (char **) emalloc(sizeof(char *) * (argc)); \
1026 } else { \
1027 argvlen = stack_argvlen; \
1028 argv = stack_argv; \
1029 }
1030
1031 #define SW_REDIS_COMMAND_INCREASE_ARGV(_new_argc) \
1032 if (_new_argc > SW_REDIS_COMMAND_BUFFER_SIZE && _new_argc > argc) { \
1033 size_t *tmp_argvlen; \
1034 char **tmp_argv; \
1035 tmp_argvlen = (size_t *) emalloc(sizeof(size_t) * (_new_argc)); \
1036 tmp_argv = (char **) emalloc(sizeof(char *) * (_new_argc)); \
1037 for (int argc_i = 0; argc_i < argc; argc_i++) { \
1038 tmp_argvlen[argc_i] = argvlen[argc_i]; \
1039 tmp_argv[argc_i] = argv[argc_i]; \
1040 } \
1041 argvlen = tmp_argvlen; \
1042 argv = tmp_argv; \
1043 } \
1044 argc = _new_argc;
1045
1046 #define SW_REDIS_COMMAND_FREE_ARGV \
1047 if (argv != stack_argv) { \
1048 efree(argvlen); \
1049 efree(argv); \
1050 }
1051
1052 enum { SW_REDIS_MODE_MULTI, SW_REDIS_MODE_PIPELINE };
1053
1054 static void swoole_redis_coro_parse_result(RedisClient *redis, zval *return_value, redisReply *reply);
1055
php_swoole_redis_coro_fetch_object(zend_object * obj)1056 static sw_inline RedisClient *php_swoole_redis_coro_fetch_object(zend_object *obj) {
1057 return (RedisClient *) ((char *) obj - swoole_redis_coro_handlers.offset);
1058 }
1059
php_swoole_get_redis_client(zval * zobject)1060 static sw_inline RedisClient *php_swoole_get_redis_client(zval *zobject) {
1061 RedisClient *redis = (RedisClient *) php_swoole_redis_coro_fetch_object(Z_OBJ_P(zobject));
1062 if (UNEXPECTED(!redis)) {
1063 php_swoole_fatal_error(E_ERROR, "you must call Redis constructor first");
1064 }
1065 return redis;
1066 }
1067
swoole_redis_coro_get_socket(redisContext * context)1068 static sw_inline Socket *swoole_redis_coro_get_socket(redisContext *context) {
1069 if (context->fd > 0 && SwooleTG.reactor) {
1070 return swoole_coroutine_get_socket_object(context->fd);
1071 }
1072 return nullptr;
1073 }
1074
swoole_redis_coro_close(RedisClient * redis)1075 static sw_inline bool swoole_redis_coro_close(RedisClient *redis) {
1076 if (redis->context) {
1077 int sockfd = redis->context->fd;
1078 Socket *socket = swoole_redis_coro_get_socket(redis->context);
1079 swoole_trace_log(SW_TRACE_REDIS_CLIENT, "redis connection closed, fd=%d", sockfd);
1080 zend_update_property_bool(swoole_redis_coro_ce, SW_Z8_OBJ_P(redis->zobject), ZEND_STRL("connected"), 0);
1081 if (!(socket && socket->has_bound())) {
1082 redisFreeKeepFd(redis->context);
1083 redis->context = nullptr;
1084 redis->session = {false, 0, false};
1085 }
1086 if (socket) {
1087 swoole_coroutine_close(sockfd);
1088 }
1089 return true;
1090 }
1091 return false;
1092 }
1093
php_swoole_redis_coro_free_object(zend_object * object)1094 static void php_swoole_redis_coro_free_object(zend_object *object) {
1095 RedisClient *redis = php_swoole_redis_coro_fetch_object(object);
1096
1097 if (redis && redis->context) {
1098 swoole_redis_coro_close(redis);
1099 }
1100
1101 zend_object_std_dtor(&redis->std);
1102 }
1103
php_swoole_redis_coro_create_object(zend_class_entry * ce)1104 static zend_object *php_swoole_redis_coro_create_object(zend_class_entry *ce) {
1105 RedisClient *redis = (RedisClient *) zend_object_alloc(sizeof(RedisClient), ce);
1106 zend_object_std_init(&redis->std, ce);
1107 object_properties_init(&redis->std, ce);
1108 redis->std.handlers = &swoole_redis_coro_handlers;
1109 return &redis->std;
1110 }
1111
sw_redis_convert_err(int err)1112 static sw_inline int sw_redis_convert_err(int err) {
1113 switch (err) {
1114 case SW_REDIS_ERR_IO:
1115 return errno;
1116 case SW_REDIS_ERR_EOF:
1117 case SW_REDIS_ERR_CLOSED:
1118 return ECONNRESET;
1119 case SW_REDIS_ERR_OTHER:
1120 return EINVAL;
1121 case SW_REDIS_ERR_OOM:
1122 case SW_REDIS_ERR_ALLOC:
1123 return ENOMEM;
1124 case SW_REDIS_ERR_PROTOCOL:
1125 return EPROTO;
1126 case SW_REDIS_ERR_NOAUTH:
1127 return EACCES;
1128 case 0:
1129 return 0;
1130 default:
1131 return errno;
1132 }
1133 }
1134
swoole_redis_handle_assoc_array_result(zval * return_value,bool str2double)1135 static sw_inline void swoole_redis_handle_assoc_array_result(zval *return_value, bool str2double) {
1136 zval *zkey, *zvalue;
1137 zval zret;
1138 bool is_key = false;
1139
1140 array_init(&zret);
1141 ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(return_value), zvalue) {
1142 if ((is_key = !is_key)) {
1143 zkey = zvalue;
1144 } else {
1145 if (str2double) {
1146 convert_to_double(zvalue);
1147 } else {
1148 Z_ADDREF_P(zvalue);
1149 }
1150 add_assoc_zval_ex(&zret, Z_STRVAL_P(zkey), Z_STRLEN_P(zkey), zvalue);
1151 }
1152 }
1153 ZEND_HASH_FOREACH_END();
1154
1155 zval_ptr_dtor(return_value);
1156 RETVAL_ZVAL(&zret, 1, 1);
1157 }
1158
1159 static bool redis_auth(RedisClient *redis, char *pw, size_t pw_len);
1160 static bool redis_select_db(RedisClient *redis, long db_number);
1161 static void redis_request(
1162 RedisClient *redis, int argc, char **argv, size_t *argvlen, zval *return_value, bool retry = false);
1163
swoole_redis_coro_connect(RedisClient * redis)1164 static bool swoole_redis_coro_connect(RedisClient *redis) {
1165 zval *zobject = redis->zobject;
1166 redisContext *context;
1167 Socket *socket;
1168 struct timeval tv;
1169 zval *ztmp;
1170 zval *zhost = sw_zend_read_property_ex(swoole_redis_coro_ce, zobject, SW_ZSTR_KNOWN(SW_ZEND_STR_HOST), 0);
1171 zval *zport = sw_zend_read_property_ex(swoole_redis_coro_ce, zobject, SW_ZSTR_KNOWN(SW_ZEND_STR_PORT), 0);
1172 zend::String host(zhost);
1173 zend_long port = zval_get_long(zport);
1174
1175 if (host.len() == 0) {
1176 php_swoole_fatal_error(E_WARNING, "The host is empty");
1177 return false;
1178 }
1179
1180 if (redis->context) {
1181 context = redis->context;
1182 if (context->connection_type == REDIS_CONN_TCP && strcmp(context->tcp.host, host.val()) == 0 &&
1183 context->tcp.port == port) {
1184 return true;
1185 } else if (context->connection_type == REDIS_CONN_UNIX &&
1186 (strstr(host.val(), context->unix_sock.path) - host.val()) + strlen(context->unix_sock.path) ==
1187 host.len()) {
1188 return true;
1189 } else {
1190 swoole_redis_coro_close(redis);
1191 }
1192 }
1193
1194 php_swoole_check_reactor();
1195
1196 if (redis->connect_timeout > 0) {
1197 tv.tv_sec = redis->connect_timeout;
1198 tv.tv_usec = (redis->connect_timeout - (double) tv.tv_sec) * 1000 * 1000;
1199 }
1200 if (SW_STRCASECT(host.val(), host.len(), "unix:/")) {
1201 context = redisConnectUnixWithTimeout(host.val() + 5 + strspn(host.val() + 5, "/") - 1, tv);
1202 } else {
1203 if (port <= 0 || port > SW_CLIENT_MAX_PORT) {
1204 php_swoole_fatal_error(E_WARNING, "The port " ZEND_LONG_FMT " is invalid", port);
1205 return false;
1206 }
1207 context = redisConnectWithTimeout(host.val(), (int) port, tv);
1208 }
1209
1210 redis->context = context;
1211
1212 if (!context) {
1213 zend_update_property_long(swoole_redis_coro_ce, SW_Z8_OBJ_P(zobject), ZEND_STRL("errType"), SW_REDIS_ERR_ALLOC);
1214 zend_update_property_long(
1215 swoole_redis_coro_ce, SW_Z8_OBJ_P(zobject), ZEND_STRL("errCode"), sw_redis_convert_err(SW_REDIS_ERR_ALLOC));
1216 zend_update_property_string(
1217 swoole_redis_coro_ce, SW_Z8_OBJ_P(zobject), ZEND_STRL("errMsg"), "cannot allocate redis context");
1218 return false;
1219 }
1220 if (context->err) {
1221 zend_update_property_long(swoole_redis_coro_ce, SW_Z8_OBJ_P(zobject), ZEND_STRL("errType"), context->err);
1222 zend_update_property_long(
1223 swoole_redis_coro_ce, SW_Z8_OBJ_P(zobject), ZEND_STRL("errCode"), sw_redis_convert_err(context->err));
1224 zend_update_property_string(swoole_redis_coro_ce, SW_Z8_OBJ_P(zobject), ZEND_STRL("errMsg"), context->errstr);
1225 swoole_redis_coro_close(redis);
1226 return false;
1227 }
1228 if (!(socket = swoole_redis_coro_get_socket(context))) {
1229 zend_update_property_long(swoole_redis_coro_ce, SW_Z8_OBJ_P(zobject), ZEND_STRL("errType"), SW_REDIS_ERR_OTHER);
1230 zend_update_property_long(
1231 swoole_redis_coro_ce, SW_Z8_OBJ_P(zobject), ZEND_STRL("errCode"), sw_redis_convert_err(SW_REDIS_ERR_OTHER));
1232 zend_update_property_string(
1233 swoole_redis_coro_ce, SW_Z8_OBJ_P(zobject), ZEND_STRL("errMsg"), "Can not found the connection");
1234 swoole_redis_coro_close(redis);
1235 return false;
1236 }
1237
1238 socket->set_timeout(redis->timeout, Socket::TIMEOUT_RDWR);
1239 redis->reconnected_count = 0;
1240 zend_update_property_bool(swoole_redis_coro_ce, SW_Z8_OBJ_P(zobject), ZEND_STRL("connected"), 1);
1241 zend_update_property_long(swoole_redis_coro_ce, SW_Z8_OBJ_P(zobject), ZEND_STRL("sock"), context->fd);
1242
1243 // auth and select db after connected
1244 zval *zsetting =
1245 sw_zend_read_and_convert_property_array(swoole_redis_coro_ce, redis->zobject, ZEND_STRL("setting"), 0);
1246 HashTable *vht = Z_ARRVAL_P(zsetting);
1247
1248 if (php_swoole_array_get_value(vht, "password", ztmp)) {
1249 zend::String passowrd(ztmp);
1250 if (passowrd.len() > 0 && !redis_auth(redis, passowrd.val(), passowrd.len())) {
1251 swoole_redis_coro_close(redis);
1252 return false;
1253 }
1254 }
1255 if (php_swoole_array_get_value(vht, "database", ztmp)) {
1256 zend_long db_number = zval_get_long(ztmp);
1257 // default is 0, don't need select
1258 if (db_number > 0 && !redis_select_db(redis, db_number)) {
1259 swoole_redis_coro_close(redis);
1260 return false;
1261 }
1262 }
1263 return true;
1264 }
1265
swoole_redis_coro_keep_liveness(RedisClient * redis)1266 static sw_inline bool swoole_redis_coro_keep_liveness(RedisClient *redis) {
1267 Socket *socket = nullptr;
1268 if (!redis->context || !(socket = swoole_redis_coro_get_socket(redis->context)) || !socket->check_liveness()) {
1269 if (socket) {
1270 zend_update_property_long(
1271 swoole_redis_coro_ce, SW_Z8_OBJ_P(redis->zobject), ZEND_STRL("errType"), SW_REDIS_ERR_CLOSED);
1272 zend_update_property_long(
1273 swoole_redis_coro_ce, SW_Z8_OBJ_P(redis->zobject), ZEND_STRL("errCode"), socket->errCode);
1274 zend_update_property_string(
1275 swoole_redis_coro_ce, SW_Z8_OBJ_P(redis->zobject), ZEND_STRL("errMsg"), socket->errMsg);
1276 }
1277 swoole_redis_coro_close(redis);
1278 for (; redis->reconnected_count < redis->reconnect_interval; redis->reconnected_count++) {
1279 if (swoole_redis_coro_connect(redis)) {
1280 return true;
1281 }
1282 }
1283 zend_update_property_long(
1284 swoole_redis_coro_ce, SW_Z8_OBJ_P(redis->zobject), ZEND_STRL("errType"), SW_REDIS_ERR_CLOSED);
1285 // Notice: do not update errCode
1286 zend_update_property_string(
1287 swoole_redis_coro_ce, SW_Z8_OBJ_P(redis->zobject), ZEND_STRL("errMsg"), "connection is not available");
1288 return false;
1289 }
1290 return true;
1291 }
1292
redis_auth(RedisClient * redis,char * pw,size_t pw_len)1293 static bool redis_auth(RedisClient *redis, char *pw, size_t pw_len) {
1294 int i = 0;
1295 size_t argvlen[2];
1296 char *argv[2];
1297 bool ret;
1298 zval retval;
1299
1300 SW_REDIS_COMMAND_ARGV_FILL("AUTH", 4)
1301 SW_REDIS_COMMAND_ARGV_FILL(pw, pw_len)
1302 redis_request(redis, 2, argv, argvlen, &retval);
1303 ret = Z_BVAL_P(&retval);
1304 if (ret) {
1305 redis->session.auth = true;
1306 }
1307 return ret;
1308 }
1309
redis_select_db(RedisClient * redis,long db_number)1310 static bool redis_select_db(RedisClient *redis, long db_number) {
1311 int i = 0;
1312 size_t argvlen[2];
1313 char *argv[2];
1314 char str[32];
1315 bool ret;
1316 zval retval;
1317
1318 SW_REDIS_COMMAND_ARGV_FILL("SELECT", 6)
1319 sprintf(str, "%ld", db_number);
1320 SW_REDIS_COMMAND_ARGV_FILL(str, strlen(str))
1321 redis_request(redis, 2, argv, argvlen, &retval);
1322 ret = Z_BVAL_P(&retval);
1323 if (ret) {
1324 redis->session.db_num = db_number;
1325 }
1326 return ret;
1327 }
1328
redis_request(RedisClient * redis,int argc,char ** argv,size_t * argvlen,zval * return_value,bool retry)1329 static void redis_request(
1330 RedisClient *redis, int argc, char **argv, size_t *argvlen, zval *return_value, bool retry) {
1331 redisReply *reply = nullptr;
1332 if (!swoole_redis_coro_keep_liveness(redis)) {
1333 ZVAL_FALSE(return_value);
1334 } else {
1335 // must clear err before request
1336 redis->context->err = 0;
1337 zend_update_property_long(swoole_redis_coro_ce, SW_Z8_OBJ_P(redis->zobject), ZEND_STRL("errType"), 0);
1338 zend_update_property_long(swoole_redis_coro_ce, SW_Z8_OBJ_P(redis->zobject), ZEND_STRL("errCode"), 0);
1339 zend_update_property_string(swoole_redis_coro_ce, SW_Z8_OBJ_P(redis->zobject), ZEND_STRL("errMsg"), "");
1340 if (redis->defer) {
1341 if (redisAppendCommandArgv(redis->context, argc, (const char **) argv, (const size_t *) argvlen) ==
1342 REDIS_ERR) {
1343 goto _error;
1344 } else {
1345 ZVAL_TRUE(return_value);
1346 }
1347 } else {
1348 reply =
1349 (redisReply *) redisCommandArgv(redis->context, argc, (const char **) argv, (const size_t *) argvlen);
1350 if (reply == nullptr) {
1351 _error:
1352 zend_update_property_long(
1353 swoole_redis_coro_ce, SW_Z8_OBJ_P(redis->zobject), ZEND_STRL("errType"), redis->context->err);
1354 zend_update_property_long(swoole_redis_coro_ce,
1355 SW_Z8_OBJ_P(redis->zobject),
1356 ZEND_STRL("errCode"),
1357 sw_redis_convert_err(redis->context->err));
1358 zend_update_property_string(
1359 swoole_redis_coro_ce, SW_Z8_OBJ_P(redis->zobject), ZEND_STRL("errMsg"), redis->context->errstr);
1360 ZVAL_FALSE(return_value);
1361 swoole_redis_coro_close(redis);
1362 } else {
1363 // Redis Cluster
1364 if (reply->type == REDIS_REPLY_ERROR &&
1365 (!strncmp(reply->str, "MOVED", 5) || !strcmp(reply->str, "ASK"))) {
1366 char *p1, *p2;
1367 // MOVED 1234 127.0.0.1:1234
1368 p1 = strrchr(reply->str, ' ') + 1; // MOVED 1234 [p1]27.0.0.1:1234
1369 p2 = strrchr(p1, ':'); // MOVED 1234 [p1]27.0.0.1[p2]1234
1370 *p2 = '\0';
1371 int port = atoi(p2 + 1);
1372 zend_update_property_string(
1373 swoole_redis_coro_ce, SW_Z8_OBJ_P(redis->zobject), ZEND_STRL("host"), p1);
1374 zend_update_property_long(
1375 swoole_redis_coro_ce, SW_Z8_OBJ_P(redis->zobject), ZEND_STRL("port"), port);
1376
1377 if (swoole_redis_coro_connect(redis) > 0) {
1378 freeReplyObject(reply);
1379 redis_request(redis, argc, argv, argvlen, return_value, retry);
1380 return;
1381 } else {
1382 ZVAL_FALSE(return_value);
1383 }
1384 }
1385 // Normal Response
1386 else {
1387 swoole_redis_coro_parse_result(redis, return_value, reply);
1388 }
1389 freeReplyObject(reply);
1390 }
1391 }
1392 }
1393 SW_LOOP_N(argc) {
1394 efree(argv[i]);
1395 }
1396 }
1397
sw_redis_command_empty(INTERNAL_FUNCTION_PARAMETERS,const char * cmd,int cmd_len)1398 static sw_inline void sw_redis_command_empty(INTERNAL_FUNCTION_PARAMETERS, const char *cmd, int cmd_len) {
1399 SW_REDIS_COMMAND_CHECK
1400 int i = 0;
1401 size_t argvlen[1];
1402 char *argv[1];
1403 SW_REDIS_COMMAND_ARGV_FILL(cmd, cmd_len)
1404 redis_request(redis, 1, argv, argvlen, return_value);
1405 }
1406
sw_redis_command_var_key(INTERNAL_FUNCTION_PARAMETERS,const char * cmd,int cmd_len,int min_argc,int has_timeout)1407 static sw_inline void sw_redis_command_var_key(
1408 INTERNAL_FUNCTION_PARAMETERS, const char *cmd, int cmd_len, int min_argc, int has_timeout) {
1409 long timeout;
1410 int argc = ZEND_NUM_ARGS();
1411 if (argc < min_argc) {
1412 RETURN_FALSE;
1413 }
1414 SW_REDIS_COMMAND_CHECK
1415 SW_REDIS_COMMAND_ALLOC_ARGS_ARR
1416 if (argc == 0 || zend_get_parameters_array(ht, argc, z_args) == FAILURE) {
1417 efree(z_args);
1418 RETURN_FALSE;
1419 }
1420 zend_bool single_array = 0;
1421 if (has_timeout == 0) {
1422 single_array = argc == 1 && SW_REDIS_COMMAND_ARGS_TYPE(z_args[0]) == IS_ARRAY;
1423 } else {
1424 single_array = argc == 2 && SW_REDIS_COMMAND_ARGS_TYPE(z_args[0]) == IS_ARRAY &&
1425 SW_REDIS_COMMAND_ARGS_TYPE(z_args[1]) == IS_LONG;
1426 timeout = SW_REDIS_COMMAND_ARGS_LVAL(z_args[1]);
1427 }
1428 if (single_array) {
1429 argc = zend_hash_num_elements(SW_REDIS_COMMAND_ARGS_ARRVAL(z_args[0])) + 1;
1430 } else {
1431 argc++;
1432 }
1433
1434 SW_REDIS_COMMAND_ALLOC_ARGV
1435 int i = 0;
1436 SW_REDIS_COMMAND_ARGV_FILL(cmd, cmd_len)
1437 char buf[32];
1438 size_t buf_len;
1439 if (single_array) {
1440 zval *value;
1441 SW_HASHTABLE_FOREACH_START(SW_REDIS_COMMAND_ARGS_ARRVAL(z_args[0]), value)
1442 zend_string *convert_str = zval_get_string(value);
1443 SW_REDIS_COMMAND_ARGV_FILL(ZSTR_VAL(convert_str), ZSTR_LEN(convert_str))
1444 zend_string_release(convert_str);
1445 SW_HASHTABLE_FOREACH_END();
1446 if (has_timeout) {
1447 buf_len = sw_snprintf(buf, sizeof(buf), "%ld", timeout);
1448 SW_REDIS_COMMAND_ARGV_FILL((char *) buf, buf_len);
1449 }
1450 } else {
1451 if (has_timeout && SW_REDIS_COMMAND_ARGS_TYPE(z_args[argc - 2]) != IS_LONG) {
1452 zend_update_property_long(
1453 swoole_redis_coro_ce, SW_Z8_OBJ_P(redis->zobject), ZEND_STRL("errType"), SW_REDIS_ERR_OTHER);
1454 zend_update_property_long(swoole_redis_coro_ce,
1455 SW_Z8_OBJ_P(redis->zobject),
1456 ZEND_STRL("errCode"),
1457 sw_redis_convert_err(SW_REDIS_ERR_OTHER));
1458 zend_update_property_string(
1459 swoole_redis_coro_ce, SW_Z8_OBJ_P(redis->zobject), ZEND_STRL("errMsg"), "Timeout value must be a LONG");
1460 efree(z_args);
1461 RETURN_FALSE;
1462 }
1463 int j, tail;
1464 tail = has_timeout ? argc - 2 : argc - 1;
1465 for (j = 0; j < tail; ++j) {
1466 zend_string *convert_str = zval_get_string(&z_args[j]);
1467 SW_REDIS_COMMAND_ARGV_FILL(ZSTR_VAL(convert_str), ZSTR_LEN(convert_str))
1468 zend_string_release(convert_str);
1469 }
1470 if (has_timeout) {
1471 buf_len = sw_snprintf(buf, sizeof(buf), ZEND_LONG_FMT, SW_REDIS_COMMAND_ARGS_LVAL(z_args[tail]));
1472 SW_REDIS_COMMAND_ARGV_FILL((char *) buf, buf_len);
1473 }
1474 }
1475 efree(z_args);
1476
1477 redis_request(redis, argc, argv, argvlen, return_value);
1478 }
1479
sw_redis_command_key(INTERNAL_FUNCTION_PARAMETERS,const char * cmd,int cmd_len)1480 static inline void sw_redis_command_key(INTERNAL_FUNCTION_PARAMETERS, const char *cmd, int cmd_len) {
1481 char *key;
1482 size_t key_len;
1483 if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &key, &key_len) == FAILURE) {
1484 RETURN_FALSE;
1485 }
1486 SW_REDIS_COMMAND_CHECK
1487 int i = 0;
1488 size_t argvlen[2];
1489 char *argv[2];
1490 int argc = 2;
1491 SW_REDIS_COMMAND_ARGV_FILL(cmd, cmd_len)
1492 SW_REDIS_COMMAND_ARGV_FILL(key, key_len)
1493 redis_request(redis, argc, argv, argvlen, return_value);
1494
1495 if (redis->compatibility_mode) {
1496 if (ZVAL_IS_ARRAY(return_value) && sw_mem_equal(ZEND_STRL("HGETALL"), cmd, cmd_len)) {
1497 swoole_redis_handle_assoc_array_result(return_value, false);
1498 } else if (ZVAL_IS_NULL(return_value) && sw_mem_equal(ZEND_STRL("GET"), cmd, cmd_len)) {
1499 RETURN_FALSE;
1500 }
1501 }
1502 }
1503
sw_redis_command_key_var_val(INTERNAL_FUNCTION_PARAMETERS,const char * cmd,int cmd_len)1504 static sw_inline void sw_redis_command_key_var_val(INTERNAL_FUNCTION_PARAMETERS, const char *cmd, int cmd_len) {
1505 int argc = ZEND_NUM_ARGS();
1506 // We at least need a key and one value
1507 if (argc < 2) {
1508 RETURN_FALSE;
1509 }
1510 SW_REDIS_COMMAND_CHECK
1511 // Make sure we at least have a key, and we can get other args
1512 SW_REDIS_COMMAND_ALLOC_ARGS_ARR
1513 if (zend_get_parameters_array(ht, argc, z_args) == FAILURE) {
1514 efree(z_args);
1515 RETURN_FALSE;
1516 }
1517
1518 int i = 0, j;
1519 argc++;
1520 SW_REDIS_COMMAND_ALLOC_ARGV
1521 SW_REDIS_COMMAND_ARGV_FILL(cmd, cmd_len)
1522 zend_string *convert_str = zval_get_string(&z_args[0]);
1523 SW_REDIS_COMMAND_ARGV_FILL(ZSTR_VAL(convert_str), ZSTR_LEN(convert_str))
1524 zend_string_release(convert_str);
1525 for (j = 1; j < argc - 1; ++j) {
1526 SW_REDIS_COMMAND_ARGV_FILL_WITH_SERIALIZE(SW_REDIS_COMMAND_ARGS_REF(z_args[j]))
1527 }
1528 efree(z_args);
1529 redis_request(redis, argc, argv, argvlen, return_value);
1530 }
1531
sw_redis_command_key_long_val(INTERNAL_FUNCTION_PARAMETERS,const char * cmd,int cmd_len)1532 static sw_inline void sw_redis_command_key_long_val(INTERNAL_FUNCTION_PARAMETERS, const char *cmd, int cmd_len) {
1533 char *key;
1534 size_t key_len;
1535 long l_val;
1536 zval *z_value;
1537 if (zend_parse_parameters(ZEND_NUM_ARGS(), "slz", &key, &key_len, &l_val, &z_value) == FAILURE) {
1538 RETURN_FALSE;
1539 }
1540 SW_REDIS_COMMAND_CHECK
1541 int i = 0;
1542 size_t argvlen[4];
1543 char *argv[4];
1544 int argc = 4;
1545 SW_REDIS_COMMAND_ARGV_FILL(cmd, cmd_len)
1546 SW_REDIS_COMMAND_ARGV_FILL(key, key_len)
1547 char str[32];
1548 sprintf(str, "%ld", l_val);
1549 SW_REDIS_COMMAND_ARGV_FILL(str, strlen(str))
1550 SW_REDIS_COMMAND_ARGV_FILL_WITH_SERIALIZE(z_value)
1551 redis_request(redis, argc, argv, argvlen, return_value);
1552 }
1553
sw_redis_command_key_long_str(INTERNAL_FUNCTION_PARAMETERS,const char * cmd,int cmd_len)1554 static sw_inline void sw_redis_command_key_long_str(INTERNAL_FUNCTION_PARAMETERS, const char *cmd, int cmd_len) {
1555 char *key, *val;
1556 size_t key_len, val_len;
1557 long l_val;
1558 if (zend_parse_parameters(ZEND_NUM_ARGS(), "sls", &key, &key_len, &l_val, &val, &val_len) == FAILURE) {
1559 return;
1560 }
1561 SW_REDIS_COMMAND_CHECK
1562 int i = 0;
1563 size_t argvlen[4];
1564 char *argv[4];
1565 int argc = 4;
1566 SW_REDIS_COMMAND_ARGV_FILL(cmd, cmd_len)
1567 SW_REDIS_COMMAND_ARGV_FILL(key, key_len)
1568 char str[32];
1569 sprintf(str, "%ld", l_val);
1570 SW_REDIS_COMMAND_ARGV_FILL(str, strlen(str))
1571 SW_REDIS_COMMAND_ARGV_FILL(val, val_len)
1572 redis_request(redis, argc, argv, argvlen, return_value);
1573 }
1574
sw_redis_command_key_long(INTERNAL_FUNCTION_PARAMETERS,const char * cmd,int cmd_len)1575 static sw_inline void sw_redis_command_key_long(INTERNAL_FUNCTION_PARAMETERS, const char *cmd, int cmd_len) {
1576 char *key;
1577 size_t key_len;
1578 long l_val;
1579 if (zend_parse_parameters(ZEND_NUM_ARGS(), "sl", &key, &key_len, &l_val) == FAILURE) {
1580 return;
1581 }
1582 SW_REDIS_COMMAND_CHECK
1583 int i = 0;
1584 size_t argvlen[3];
1585 char *argv[3];
1586 int argc = 3;
1587 SW_REDIS_COMMAND_ARGV_FILL(cmd, cmd_len)
1588 SW_REDIS_COMMAND_ARGV_FILL(key, key_len)
1589 char str[32];
1590 sprintf(str, "%ld", l_val);
1591 SW_REDIS_COMMAND_ARGV_FILL(str, strlen(str))
1592 redis_request(redis, argc, argv, argvlen, return_value);
1593 }
1594
sw_redis_command_key_long_long(INTERNAL_FUNCTION_PARAMETERS,const char * cmd,int cmd_len)1595 static sw_inline void sw_redis_command_key_long_long(INTERNAL_FUNCTION_PARAMETERS, const char *cmd, int cmd_len) {
1596 char *key;
1597 size_t key_len;
1598 long l1_val, l2_val;
1599 if (zend_parse_parameters(ZEND_NUM_ARGS(), "sll", &key, &key_len, &l1_val, &l2_val) == FAILURE) {
1600 return;
1601 }
1602 SW_REDIS_COMMAND_CHECK
1603 int i = 0;
1604 size_t argvlen[4];
1605 char *argv[4];
1606 int argc = 4;
1607 SW_REDIS_COMMAND_ARGV_FILL(cmd, cmd_len)
1608 SW_REDIS_COMMAND_ARGV_FILL(key, key_len)
1609 char str[32];
1610 sprintf(str, "%ld", l1_val);
1611 SW_REDIS_COMMAND_ARGV_FILL(str, strlen(str))
1612 sprintf(str, "%ld", l2_val);
1613 SW_REDIS_COMMAND_ARGV_FILL(str, strlen(str))
1614 redis_request(redis, argc, argv, argvlen, return_value);
1615 }
1616
sw_redis_command_key_dbl(INTERNAL_FUNCTION_PARAMETERS,const char * cmd,int cmd_len)1617 static sw_inline void sw_redis_command_key_dbl(INTERNAL_FUNCTION_PARAMETERS, const char *cmd, int cmd_len) {
1618 char *key;
1619 size_t key_len;
1620 double d_val;
1621 if (zend_parse_parameters(ZEND_NUM_ARGS(), "sd", &key, &key_len, &d_val) == FAILURE) {
1622 RETURN_FALSE;
1623 }
1624 SW_REDIS_COMMAND_CHECK
1625 int i = 0;
1626 size_t argvlen[3];
1627 char *argv[3];
1628 int argc = 3;
1629 SW_REDIS_COMMAND_ARGV_FILL(cmd, cmd_len)
1630 SW_REDIS_COMMAND_ARGV_FILL(key, key_len)
1631 char str[32];
1632 sprintf(str, "%f", d_val);
1633 SW_REDIS_COMMAND_ARGV_FILL(str, strlen(str))
1634 redis_request(redis, argc, argv, argvlen, return_value);
1635 }
1636
sw_redis_command_key_key(INTERNAL_FUNCTION_PARAMETERS,const char * cmd,int cmd_len)1637 static sw_inline void sw_redis_command_key_key(INTERNAL_FUNCTION_PARAMETERS, const char *cmd, int cmd_len) {
1638 char *key1, *key2;
1639 size_t key1_len, key2_len;
1640 if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss", &key1, &key1_len, &key2, &key2_len) == FAILURE) {
1641 RETURN_FALSE;
1642 }
1643 SW_REDIS_COMMAND_CHECK
1644 int i = 0;
1645 size_t argvlen[3];
1646 char *argv[3];
1647 int argc = 3;
1648 SW_REDIS_COMMAND_ARGV_FILL(cmd, cmd_len)
1649 SW_REDIS_COMMAND_ARGV_FILL(key1, key1_len)
1650 SW_REDIS_COMMAND_ARGV_FILL(key2, key2_len)
1651 redis_request(redis, argc, argv, argvlen, return_value);
1652 }
1653
sw_redis_command_key_val(INTERNAL_FUNCTION_PARAMETERS,const char * cmd,int cmd_len)1654 static sw_inline void sw_redis_command_key_val(INTERNAL_FUNCTION_PARAMETERS, const char *cmd, int cmd_len) {
1655 char *key;
1656 size_t key_len;
1657 zval *z_value;
1658 if (zend_parse_parameters(ZEND_NUM_ARGS(), "sz", &key, &key_len, &z_value) == FAILURE) {
1659 RETURN_FALSE;
1660 }
1661 SW_REDIS_COMMAND_CHECK
1662 int i = 0;
1663 size_t argvlen[3];
1664 char *argv[3];
1665 SW_REDIS_COMMAND_ARGV_FILL(cmd, cmd_len)
1666 SW_REDIS_COMMAND_ARGV_FILL(key, key_len)
1667 SW_REDIS_COMMAND_ARGV_FILL_WITH_SERIALIZE(z_value)
1668 redis_request(redis, 3, argv, argvlen, return_value);
1669
1670 if (redis->compatibility_mode && ZVAL_IS_NULL(return_value) && strncmp("ZRANK", cmd, cmd_len) == 0) {
1671 RETURN_FALSE;
1672 }
1673 }
1674
sw_redis_command_key_str(INTERNAL_FUNCTION_PARAMETERS,const char * cmd,int cmd_len)1675 static sw_inline void sw_redis_command_key_str(INTERNAL_FUNCTION_PARAMETERS, const char *cmd, int cmd_len) {
1676 char *key, *val;
1677 size_t key_len, val_len;
1678 if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss", &key, &key_len, &val, &val_len) == FAILURE) {
1679 RETURN_FALSE;
1680 }
1681 SW_REDIS_COMMAND_CHECK
1682 int i = 0;
1683 size_t argvlen[3];
1684 char *argv[3];
1685 SW_REDIS_COMMAND_ARGV_FILL(cmd, cmd_len)
1686 SW_REDIS_COMMAND_ARGV_FILL(key, key_len)
1687 SW_REDIS_COMMAND_ARGV_FILL(val, val_len)
1688 redis_request(redis, 3, argv, argvlen, return_value);
1689 }
1690
sw_redis_command_key_str_str(INTERNAL_FUNCTION_PARAMETERS,const char * cmd,int cmd_len)1691 static sw_inline void sw_redis_command_key_str_str(INTERNAL_FUNCTION_PARAMETERS, const char *cmd, int cmd_len) {
1692 char *key, *val1, *val2;
1693 size_t key_len, val1_len, val2_len;
1694 if (zend_parse_parameters(ZEND_NUM_ARGS(), "sss", &key, &key_len, &val1, &val1_len, &val2, &val2_len) == FAILURE) {
1695 RETURN_FALSE;
1696 }
1697 SW_REDIS_COMMAND_CHECK
1698 int i = 0;
1699 size_t argvlen[4];
1700 char *argv[4];
1701 SW_REDIS_COMMAND_ARGV_FILL(cmd, cmd_len)
1702 SW_REDIS_COMMAND_ARGV_FILL(key, key_len)
1703 SW_REDIS_COMMAND_ARGV_FILL(val1, val1_len)
1704 SW_REDIS_COMMAND_ARGV_FILL(val2, val2_len)
1705 redis_request(redis, 4, argv, argvlen, return_value);
1706 }
1707
sw_redis_command_xrange(INTERNAL_FUNCTION_PARAMETERS,const char * cmd,int cmd_len)1708 static sw_inline void sw_redis_command_xrange(INTERNAL_FUNCTION_PARAMETERS, const char *cmd, int cmd_len) {
1709 char *key, *val1, *val2;
1710 size_t key_len, val1_len, val2_len;
1711 zend_long count = 0;
1712
1713 if (zend_parse_parameters(ZEND_NUM_ARGS(), "sss|l", &key, &key_len, &val1, &val1_len, &val2, &val2_len, &count) == FAILURE) {
1714 RETURN_FALSE;
1715 }
1716 SW_REDIS_COMMAND_CHECK
1717
1718 int i = 0, argc;
1719 argc = ZEND_NUM_ARGS() == 4 ? 6 : 4;
1720 SW_REDIS_COMMAND_ALLOC_ARGV
1721 SW_REDIS_COMMAND_ARGV_FILL(cmd, cmd_len)
1722 SW_REDIS_COMMAND_ARGV_FILL(key, key_len)
1723 SW_REDIS_COMMAND_ARGV_FILL(val1, val1_len)
1724 SW_REDIS_COMMAND_ARGV_FILL(val2, val2_len)
1725 if (count > 0) {
1726 SW_REDIS_COMMAND_ARGV_FILL("COUNT", 5)
1727 char buf[32];
1728 size_t buf_len;
1729 buf_len = sprintf(buf, ZEND_LONG_FMT, count);
1730 SW_REDIS_COMMAND_ARGV_FILL((char *) buf, buf_len)
1731 }
1732
1733 redis_request(redis, argc, argv, argvlen, return_value);
1734
1735 if (redis->compatibility_mode && ZVAL_IS_ARRAY(return_value)) {
1736 swoole_redis_handle_assoc_array_result(return_value, true);
1737 }
1738
1739 SW_REDIS_COMMAND_FREE_ARGV
1740 }
1741
1742 SW_EXTERN_C_BEGIN
1743 static PHP_METHOD(swoole_redis_coro, __construct);
1744 static PHP_METHOD(swoole_redis_coro, __destruct);
1745 static PHP_METHOD(swoole_redis_coro, connect);
1746 static PHP_METHOD(swoole_redis_coro, getAuth);
1747 static PHP_METHOD(swoole_redis_coro, getDBNum);
1748 static PHP_METHOD(swoole_redis_coro, getOptions);
1749 static PHP_METHOD(swoole_redis_coro, setOptions);
1750 static PHP_METHOD(swoole_redis_coro, getDefer);
1751 static PHP_METHOD(swoole_redis_coro, setDefer);
1752 static PHP_METHOD(swoole_redis_coro, recv);
1753 static PHP_METHOD(swoole_redis_coro, request);
1754 static PHP_METHOD(swoole_redis_coro, close);
1755 /*---------------------Redis Command------------------------*/
1756 static PHP_METHOD(swoole_redis_coro, set);
1757 static PHP_METHOD(swoole_redis_coro, setBit);
1758 static PHP_METHOD(swoole_redis_coro, setEx);
1759 static PHP_METHOD(swoole_redis_coro, psetEx);
1760 static PHP_METHOD(swoole_redis_coro, lSet);
1761 static PHP_METHOD(swoole_redis_coro, get);
1762 static PHP_METHOD(swoole_redis_coro, mGet);
1763 static PHP_METHOD(swoole_redis_coro, del);
1764 static PHP_METHOD(swoole_redis_coro, hDel);
1765 static PHP_METHOD(swoole_redis_coro, hSet);
1766 static PHP_METHOD(swoole_redis_coro, hMSet);
1767 static PHP_METHOD(swoole_redis_coro, hSetNx);
1768 static PHP_METHOD(swoole_redis_coro, mSet);
1769 static PHP_METHOD(swoole_redis_coro, mSetNx);
1770 static PHP_METHOD(swoole_redis_coro, getKeys);
1771 static PHP_METHOD(swoole_redis_coro, exists);
1772 static PHP_METHOD(swoole_redis_coro, type);
1773 static PHP_METHOD(swoole_redis_coro, strLen);
1774 static PHP_METHOD(swoole_redis_coro, lPop);
1775 static PHP_METHOD(swoole_redis_coro, blPop);
1776 static PHP_METHOD(swoole_redis_coro, rPop);
1777 static PHP_METHOD(swoole_redis_coro, brPop);
1778 static PHP_METHOD(swoole_redis_coro, bRPopLPush);
1779 static PHP_METHOD(swoole_redis_coro, lSize);
1780 static PHP_METHOD(swoole_redis_coro, sSize);
1781 static PHP_METHOD(swoole_redis_coro, sPop);
1782 static PHP_METHOD(swoole_redis_coro, sMembers);
1783 static PHP_METHOD(swoole_redis_coro, sRandMember);
1784 static PHP_METHOD(swoole_redis_coro, persist);
1785 static PHP_METHOD(swoole_redis_coro, ttl);
1786 static PHP_METHOD(swoole_redis_coro, pttl);
1787 static PHP_METHOD(swoole_redis_coro, zCard);
1788 static PHP_METHOD(swoole_redis_coro, hLen);
1789 static PHP_METHOD(swoole_redis_coro, hKeys);
1790 static PHP_METHOD(swoole_redis_coro, hVals);
1791 static PHP_METHOD(swoole_redis_coro, hGetAll);
1792 static PHP_METHOD(swoole_redis_coro, restore);
1793 static PHP_METHOD(swoole_redis_coro, dump);
1794 static PHP_METHOD(swoole_redis_coro, debug);
1795 static PHP_METHOD(swoole_redis_coro, renameKey);
1796 static PHP_METHOD(swoole_redis_coro, renameNx);
1797 static PHP_METHOD(swoole_redis_coro, rpoplpush);
1798 static PHP_METHOD(swoole_redis_coro, randomKey);
1799 static PHP_METHOD(swoole_redis_coro, pfadd);
1800 static PHP_METHOD(swoole_redis_coro, pfcount);
1801 static PHP_METHOD(swoole_redis_coro, pfmerge);
1802 static PHP_METHOD(swoole_redis_coro, ping);
1803 static PHP_METHOD(swoole_redis_coro, auth);
1804 static PHP_METHOD(swoole_redis_coro, unwatch);
1805 static PHP_METHOD(swoole_redis_coro, watch);
1806 static PHP_METHOD(swoole_redis_coro, save);
1807 static PHP_METHOD(swoole_redis_coro, bgSave);
1808 static PHP_METHOD(swoole_redis_coro, lastSave);
1809 static PHP_METHOD(swoole_redis_coro, flushDB);
1810 static PHP_METHOD(swoole_redis_coro, flushAll);
1811 static PHP_METHOD(swoole_redis_coro, dbSize);
1812 static PHP_METHOD(swoole_redis_coro, bgrewriteaof);
1813 static PHP_METHOD(swoole_redis_coro, time);
1814 static PHP_METHOD(swoole_redis_coro, role);
1815 static PHP_METHOD(swoole_redis_coro, setRange);
1816 static PHP_METHOD(swoole_redis_coro, setNx);
1817 static PHP_METHOD(swoole_redis_coro, getSet);
1818 static PHP_METHOD(swoole_redis_coro, append);
1819 static PHP_METHOD(swoole_redis_coro, lPushx);
1820 static PHP_METHOD(swoole_redis_coro, lPush);
1821 static PHP_METHOD(swoole_redis_coro, rPush);
1822 static PHP_METHOD(swoole_redis_coro, rPushx);
1823 static PHP_METHOD(swoole_redis_coro, sContains);
1824 static PHP_METHOD(swoole_redis_coro, zScore);
1825 static PHP_METHOD(swoole_redis_coro, zRank);
1826 static PHP_METHOD(swoole_redis_coro, zRevRank);
1827 static PHP_METHOD(swoole_redis_coro, hGet);
1828 static PHP_METHOD(swoole_redis_coro, hMGet);
1829 static PHP_METHOD(swoole_redis_coro, hExists);
1830 static PHP_METHOD(swoole_redis_coro, publish);
1831 static PHP_METHOD(swoole_redis_coro, zIncrBy);
1832 static PHP_METHOD(swoole_redis_coro, zAdd);
1833 static PHP_METHOD(swoole_redis_coro, zPopMin);
1834 static PHP_METHOD(swoole_redis_coro, zPopMax);
1835 static PHP_METHOD(swoole_redis_coro, bzPopMin);
1836 static PHP_METHOD(swoole_redis_coro, bzPopMax);
1837 static PHP_METHOD(swoole_redis_coro, zDeleteRangeByScore);
1838 static PHP_METHOD(swoole_redis_coro, zCount);
1839 static PHP_METHOD(swoole_redis_coro, zRange);
1840 static PHP_METHOD(swoole_redis_coro, zRevRange);
1841 static PHP_METHOD(swoole_redis_coro, zRangeByScore);
1842 static PHP_METHOD(swoole_redis_coro, zRevRangeByScore);
1843 static PHP_METHOD(swoole_redis_coro, zRangeByLex);
1844 static PHP_METHOD(swoole_redis_coro, zRevRangeByLex);
1845 static PHP_METHOD(swoole_redis_coro, zInter);
1846 static PHP_METHOD(swoole_redis_coro, zUnion);
1847 static PHP_METHOD(swoole_redis_coro, incrBy);
1848 static PHP_METHOD(swoole_redis_coro, hIncrBy);
1849 static PHP_METHOD(swoole_redis_coro, incr);
1850 static PHP_METHOD(swoole_redis_coro, decrBy);
1851 static PHP_METHOD(swoole_redis_coro, decr);
1852 static PHP_METHOD(swoole_redis_coro, getBit);
1853 static PHP_METHOD(swoole_redis_coro, lGet);
1854 static PHP_METHOD(swoole_redis_coro, lInsert);
1855 static PHP_METHOD(swoole_redis_coro, setTimeout);
1856 static PHP_METHOD(swoole_redis_coro, pexpire);
1857 static PHP_METHOD(swoole_redis_coro, expireAt);
1858 static PHP_METHOD(swoole_redis_coro, pexpireAt);
1859 static PHP_METHOD(swoole_redis_coro, move);
1860 static PHP_METHOD(swoole_redis_coro, select);
1861 static PHP_METHOD(swoole_redis_coro, getRange);
1862 static PHP_METHOD(swoole_redis_coro, listTrim);
1863 static PHP_METHOD(swoole_redis_coro, lGetRange);
1864 static PHP_METHOD(swoole_redis_coro, lRem);
1865 static PHP_METHOD(swoole_redis_coro, zDeleteRangeByRank);
1866 static PHP_METHOD(swoole_redis_coro, incrByFloat);
1867 static PHP_METHOD(swoole_redis_coro, hIncrByFloat);
1868 static PHP_METHOD(swoole_redis_coro, bitCount);
1869 static PHP_METHOD(swoole_redis_coro, bitOp);
1870 static PHP_METHOD(swoole_redis_coro, sAdd);
1871 static PHP_METHOD(swoole_redis_coro, sMove);
1872 static PHP_METHOD(swoole_redis_coro, sDiff);
1873 static PHP_METHOD(swoole_redis_coro, sDiffStore);
1874 static PHP_METHOD(swoole_redis_coro, sUnion);
1875 static PHP_METHOD(swoole_redis_coro, sUnionStore);
1876 static PHP_METHOD(swoole_redis_coro, sInter);
1877 static PHP_METHOD(swoole_redis_coro, sInterStore);
1878 static PHP_METHOD(swoole_redis_coro, sRemove);
1879 static PHP_METHOD(swoole_redis_coro, zDelete);
1880 static PHP_METHOD(swoole_redis_coro, subscribe);
1881 static PHP_METHOD(swoole_redis_coro, pSubscribe);
1882 static PHP_METHOD(swoole_redis_coro, unsubscribe);
1883 static PHP_METHOD(swoole_redis_coro, pUnSubscribe);
1884 static PHP_METHOD(swoole_redis_coro, multi);
1885 static PHP_METHOD(swoole_redis_coro, exec);
1886 static PHP_METHOD(swoole_redis_coro, eval);
1887 static PHP_METHOD(swoole_redis_coro, evalSha);
1888 static PHP_METHOD(swoole_redis_coro, script);
1889 static PHP_METHOD(swoole_redis_coro, xLen);
1890 static PHP_METHOD(swoole_redis_coro, xAdd);
1891 static PHP_METHOD(swoole_redis_coro, xRead);
1892 static PHP_METHOD(swoole_redis_coro, xDel);
1893 static PHP_METHOD(swoole_redis_coro, xRange);
1894 static PHP_METHOD(swoole_redis_coro, xRevRange);
1895 static PHP_METHOD(swoole_redis_coro, xTrim);
1896 static PHP_METHOD(swoole_redis_coro, xGroupCreate);
1897 static PHP_METHOD(swoole_redis_coro, xGroupSetId);
1898 static PHP_METHOD(swoole_redis_coro, xGroupDestroy);
1899 static PHP_METHOD(swoole_redis_coro, xGroupCreateConsumer);
1900 static PHP_METHOD(swoole_redis_coro, xGroupDelConsumer);
1901 static PHP_METHOD(swoole_redis_coro, xReadGroup);
1902 static PHP_METHOD(swoole_redis_coro, xPending);
1903 static PHP_METHOD(swoole_redis_coro, xAck);
1904 static PHP_METHOD(swoole_redis_coro, xClaim);
1905 static PHP_METHOD(swoole_redis_coro, xAutoClaim);
1906 static PHP_METHOD(swoole_redis_coro, xInfoConsumers);
1907 static PHP_METHOD(swoole_redis_coro, xInfoGroups);
1908 static PHP_METHOD(swoole_redis_coro, xInfoStream);
1909 SW_EXTERN_C_END
1910 /*---------------------Redis Command End------------------------*/
1911 // clang-format off
1912 static const zend_function_entry swoole_redis_coro_methods[] =
1913 {
1914 PHP_ME(swoole_redis_coro, __construct, arginfo_swoole_redis_coro_construct, ZEND_ACC_PUBLIC)
1915 PHP_ME(swoole_redis_coro, __destruct, arginfo_swoole_redis_coro_void, ZEND_ACC_PUBLIC)
1916 PHP_ME(swoole_redis_coro, connect, arginfo_swoole_redis_coro_connect, ZEND_ACC_PUBLIC)
1917 PHP_ME(swoole_redis_coro, getAuth, arginfo_swoole_redis_coro_void, ZEND_ACC_PUBLIC)
1918 PHP_ME(swoole_redis_coro, getDBNum, arginfo_swoole_redis_coro_void, ZEND_ACC_PUBLIC)
1919 PHP_ME(swoole_redis_coro, getOptions, arginfo_swoole_redis_coro_void, ZEND_ACC_PUBLIC)
1920 PHP_ME(swoole_redis_coro, setOptions, arginfo_swoole_redis_coro_setOptions, ZEND_ACC_PUBLIC)
1921 PHP_ME(swoole_redis_coro, getDefer, arginfo_swoole_redis_coro_void, ZEND_ACC_PUBLIC)
1922 PHP_ME(swoole_redis_coro, setDefer, arginfo_swoole_redis_coro_setDefer, ZEND_ACC_PUBLIC)
1923 PHP_ME(swoole_redis_coro, recv, arginfo_swoole_redis_coro_void, ZEND_ACC_PUBLIC)
1924 PHP_ME(swoole_redis_coro, request, arginfo_swoole_redis_coro_request, ZEND_ACC_PUBLIC)
1925 PHP_ME(swoole_redis_coro, close, arginfo_swoole_redis_coro_close, ZEND_ACC_PUBLIC)
1926 /*---------------------Redis Command------------------------*/
1927 PHP_ME(swoole_redis_coro, set, arginfo_swoole_redis_coro_set, ZEND_ACC_PUBLIC)
1928 PHP_ME(swoole_redis_coro, setBit, arginfo_swoole_redis_coro_setBit, ZEND_ACC_PUBLIC)
1929 PHP_ME(swoole_redis_coro, setEx, arginfo_swoole_redis_coro_setex, ZEND_ACC_PUBLIC)
1930 PHP_ME(swoole_redis_coro, psetEx, arginfo_swoole_redis_coro_psetex, ZEND_ACC_PUBLIC)
1931 PHP_ME(swoole_redis_coro, lSet, arginfo_swoole_redis_coro_lSet, ZEND_ACC_PUBLIC)
1932 PHP_ME(swoole_redis_coro, get, arginfo_swoole_redis_coro_get, ZEND_ACC_PUBLIC)
1933 PHP_ME(swoole_redis_coro, mGet, arginfo_swoole_redis_coro_mget, ZEND_ACC_PUBLIC)
1934 PHP_ME(swoole_redis_coro, del, arginfo_swoole_redis_coro_del, ZEND_ACC_PUBLIC)
1935 PHP_ME(swoole_redis_coro, hDel, arginfo_swoole_redis_coro_hDel, ZEND_ACC_PUBLIC)
1936 PHP_ME(swoole_redis_coro, hSet, arginfo_swoole_redis_coro_hSet, ZEND_ACC_PUBLIC)
1937 PHP_ME(swoole_redis_coro, hMSet, arginfo_swoole_redis_coro_hMset, ZEND_ACC_PUBLIC)
1938 PHP_ME(swoole_redis_coro, hSetNx, arginfo_swoole_redis_coro_hSetNx, ZEND_ACC_PUBLIC)
1939 PHP_MALIAS(swoole_redis_coro, delete, del, arginfo_swoole_redis_coro_del, ZEND_ACC_PUBLIC)
1940 PHP_ME(swoole_redis_coro, mSet, arginfo_swoole_redis_coro_mset, ZEND_ACC_PUBLIC)
1941 PHP_ME(swoole_redis_coro, mSetNx, arginfo_swoole_redis_coro_msetnx, ZEND_ACC_PUBLIC)
1942 PHP_ME(swoole_redis_coro, getKeys, arginfo_swoole_redis_coro_getKeys, ZEND_ACC_PUBLIC)
1943 PHP_MALIAS(swoole_redis_coro, keys, getKeys, arginfo_swoole_redis_coro_getKeys, ZEND_ACC_PUBLIC)
1944 PHP_ME(swoole_redis_coro, exists, arginfo_swoole_redis_coro_exists, ZEND_ACC_PUBLIC)
1945 PHP_ME(swoole_redis_coro, type, arginfo_swoole_redis_coro_type, ZEND_ACC_PUBLIC)
1946 PHP_ME(swoole_redis_coro, strLen, arginfo_swoole_redis_coro_strlen, ZEND_ACC_PUBLIC)
1947 PHP_ME(swoole_redis_coro, lPop, arginfo_swoole_redis_coro_lPop, ZEND_ACC_PUBLIC)
1948 PHP_ME(swoole_redis_coro, blPop, arginfo_swoole_redis_coro_blPop, ZEND_ACC_PUBLIC)
1949 PHP_ME(swoole_redis_coro, rPop, arginfo_swoole_redis_coro_rPop, ZEND_ACC_PUBLIC)
1950 PHP_ME(swoole_redis_coro, brPop, arginfo_swoole_redis_coro_brPop, ZEND_ACC_PUBLIC)
1951 PHP_ME(swoole_redis_coro, bRPopLPush, arginfo_swoole_redis_coro_brpoplpush, ZEND_ACC_PUBLIC)
1952 PHP_ME(swoole_redis_coro, lSize, arginfo_swoole_redis_coro_lSize, ZEND_ACC_PUBLIC)
1953 PHP_MALIAS(swoole_redis_coro, lLen, lSize, arginfo_swoole_redis_coro_lLen, ZEND_ACC_PUBLIC)
1954 PHP_ME(swoole_redis_coro, sSize, arginfo_swoole_redis_coro_sSize, ZEND_ACC_PUBLIC)
1955 PHP_MALIAS(swoole_redis_coro, scard, sSize, arginfo_swoole_redis_coro_scard, ZEND_ACC_PUBLIC)
1956 PHP_ME(swoole_redis_coro, sPop, arginfo_swoole_redis_coro_sPop, ZEND_ACC_PUBLIC)
1957 PHP_ME(swoole_redis_coro, sMembers, arginfo_swoole_redis_coro_sMembers, ZEND_ACC_PUBLIC)
1958 PHP_MALIAS(swoole_redis_coro, sGetMembers, sMembers, arginfo_swoole_redis_coro_key, ZEND_ACC_PUBLIC)
1959 PHP_ME(swoole_redis_coro, sRandMember, arginfo_swoole_redis_coro_sRandMember, ZEND_ACC_PUBLIC)
1960 PHP_ME(swoole_redis_coro, persist, arginfo_swoole_redis_coro_persist, ZEND_ACC_PUBLIC)
1961 PHP_ME(swoole_redis_coro, ttl, arginfo_swoole_redis_coro_ttl, ZEND_ACC_PUBLIC)
1962 PHP_ME(swoole_redis_coro, pttl, arginfo_swoole_redis_coro_pttl, ZEND_ACC_PUBLIC)
1963 PHP_ME(swoole_redis_coro, zCard, arginfo_swoole_redis_coro_zCard, ZEND_ACC_PUBLIC)
1964 PHP_MALIAS(swoole_redis_coro, zSize, zCard, arginfo_swoole_redis_coro_zSize, ZEND_ACC_PUBLIC)
1965 PHP_ME(swoole_redis_coro, hLen, arginfo_swoole_redis_coro_hLen, ZEND_ACC_PUBLIC)
1966 PHP_ME(swoole_redis_coro, hKeys, arginfo_swoole_redis_coro_hKeys, ZEND_ACC_PUBLIC)
1967 PHP_ME(swoole_redis_coro, hVals, arginfo_swoole_redis_coro_hVals, ZEND_ACC_PUBLIC)
1968 PHP_ME(swoole_redis_coro, hGetAll, arginfo_swoole_redis_coro_hGetAll, ZEND_ACC_PUBLIC)
1969 PHP_ME(swoole_redis_coro, debug, arginfo_swoole_redis_coro_debug, ZEND_ACC_PUBLIC)
1970 PHP_ME(swoole_redis_coro, restore, arginfo_swoole_redis_coro_restore, ZEND_ACC_PUBLIC)
1971 PHP_ME(swoole_redis_coro, dump, arginfo_swoole_redis_coro_dump, ZEND_ACC_PUBLIC)
1972 PHP_ME(swoole_redis_coro, renameKey, arginfo_swoole_redis_coro_renameKey, ZEND_ACC_PUBLIC)
1973 PHP_MALIAS(swoole_redis_coro, rename, renameKey, arginfo_swoole_redis_coro_rename, ZEND_ACC_PUBLIC)
1974 PHP_ME(swoole_redis_coro, renameNx, arginfo_swoole_redis_coro_renameNx, ZEND_ACC_PUBLIC)
1975 PHP_ME(swoole_redis_coro, rpoplpush, arginfo_swoole_redis_coro_rpoplpush, ZEND_ACC_PUBLIC)
1976 PHP_ME(swoole_redis_coro, randomKey, arginfo_swoole_redis_coro_randomKey, ZEND_ACC_PUBLIC)
1977 PHP_ME(swoole_redis_coro, pfadd, arginfo_swoole_redis_coro_pfadd, ZEND_ACC_PUBLIC)
1978 PHP_ME(swoole_redis_coro, pfcount, arginfo_swoole_redis_coro_pfcount, ZEND_ACC_PUBLIC)
1979 PHP_ME(swoole_redis_coro, pfmerge, arginfo_swoole_redis_coro_pfmerge, ZEND_ACC_PUBLIC)
1980 PHP_ME(swoole_redis_coro, ping, arginfo_swoole_redis_coro_ping, ZEND_ACC_PUBLIC)
1981 PHP_ME(swoole_redis_coro, auth, arginfo_swoole_redis_coro_auth, ZEND_ACC_PUBLIC)
1982 PHP_ME(swoole_redis_coro, unwatch, arginfo_swoole_redis_coro_unwatch, ZEND_ACC_PUBLIC)
1983 PHP_ME(swoole_redis_coro, watch, arginfo_swoole_redis_coro_watch, ZEND_ACC_PUBLIC)
1984 PHP_ME(swoole_redis_coro, save, arginfo_swoole_redis_coro_save, ZEND_ACC_PUBLIC)
1985 PHP_ME(swoole_redis_coro, bgSave, arginfo_swoole_redis_coro_bgSave, ZEND_ACC_PUBLIC)
1986 PHP_ME(swoole_redis_coro, lastSave, arginfo_swoole_redis_coro_lastSave, ZEND_ACC_PUBLIC)
1987 PHP_ME(swoole_redis_coro, flushDB, arginfo_swoole_redis_coro_flushDB, ZEND_ACC_PUBLIC)
1988 PHP_ME(swoole_redis_coro, flushAll, arginfo_swoole_redis_coro_flushAll, ZEND_ACC_PUBLIC)
1989 PHP_ME(swoole_redis_coro, dbSize, arginfo_swoole_redis_coro_dbSize, ZEND_ACC_PUBLIC)
1990 PHP_ME(swoole_redis_coro, bgrewriteaof, arginfo_swoole_redis_coro_bgrewriteaof, ZEND_ACC_PUBLIC)
1991 PHP_ME(swoole_redis_coro, time, arginfo_swoole_redis_coro_time, ZEND_ACC_PUBLIC)
1992 PHP_ME(swoole_redis_coro, role, arginfo_swoole_redis_coro_role, ZEND_ACC_PUBLIC)
1993 PHP_ME(swoole_redis_coro, setRange, arginfo_swoole_redis_coro_setRange, ZEND_ACC_PUBLIC)
1994 PHP_ME(swoole_redis_coro, setNx, arginfo_swoole_redis_coro_setnx, ZEND_ACC_PUBLIC)
1995 PHP_ME(swoole_redis_coro, getSet, arginfo_swoole_redis_coro_getSet, ZEND_ACC_PUBLIC)
1996 PHP_ME(swoole_redis_coro, append, arginfo_swoole_redis_coro_append, ZEND_ACC_PUBLIC)
1997 PHP_ME(swoole_redis_coro, lPushx, arginfo_swoole_redis_coro_lPushx, ZEND_ACC_PUBLIC)
1998 PHP_ME(swoole_redis_coro, lPush, arginfo_swoole_redis_coro_lPush, ZEND_ACC_PUBLIC)
1999 PHP_ME(swoole_redis_coro, rPush, arginfo_swoole_redis_coro_rPush, ZEND_ACC_PUBLIC)
2000 PHP_ME(swoole_redis_coro, rPushx, arginfo_swoole_redis_coro_rPushx, ZEND_ACC_PUBLIC)
2001 PHP_ME(swoole_redis_coro, sContains, arginfo_swoole_redis_coro_sContains, ZEND_ACC_PUBLIC)
2002 PHP_MALIAS(swoole_redis_coro, sismember, sContains, arginfo_swoole_redis_coro_key_value, ZEND_ACC_PUBLIC)
2003 PHP_ME(swoole_redis_coro, zScore, arginfo_swoole_redis_coro_zScore, ZEND_ACC_PUBLIC)
2004 PHP_ME(swoole_redis_coro, zRank, arginfo_swoole_redis_coro_zRank, ZEND_ACC_PUBLIC)
2005 PHP_ME(swoole_redis_coro, zRevRank, arginfo_swoole_redis_coro_zRevRank, ZEND_ACC_PUBLIC)
2006 PHP_ME(swoole_redis_coro, hGet, arginfo_swoole_redis_coro_hGet, ZEND_ACC_PUBLIC)
2007 PHP_ME(swoole_redis_coro, hMGet, arginfo_swoole_redis_coro_hMget, ZEND_ACC_PUBLIC)
2008 PHP_ME(swoole_redis_coro, hExists, arginfo_swoole_redis_coro_hExists, ZEND_ACC_PUBLIC)
2009 PHP_ME(swoole_redis_coro, publish, arginfo_swoole_redis_coro_publish, ZEND_ACC_PUBLIC)
2010 PHP_ME(swoole_redis_coro, zIncrBy, arginfo_swoole_redis_coro_zIncrBy, ZEND_ACC_PUBLIC)
2011 PHP_ME(swoole_redis_coro, zAdd, arginfo_swoole_redis_coro_zAdd, ZEND_ACC_PUBLIC)
2012 PHP_ME(swoole_redis_coro, zPopMin, arginfo_swoole_redis_coro_zPopMin, ZEND_ACC_PUBLIC)
2013 PHP_ME(swoole_redis_coro, zPopMax, arginfo_swoole_redis_coro_zPopMax, ZEND_ACC_PUBLIC)
2014 PHP_ME(swoole_redis_coro, bzPopMin, arginfo_swoole_redis_coro_bzPopMin, ZEND_ACC_PUBLIC)
2015 PHP_ME(swoole_redis_coro, bzPopMax, arginfo_swoole_redis_coro_bzPopMax, ZEND_ACC_PUBLIC)
2016 PHP_ME(swoole_redis_coro, zDeleteRangeByScore, arginfo_swoole_redis_coro_zDeleteRangeByScore, ZEND_ACC_PUBLIC)
2017 PHP_MALIAS(swoole_redis_coro, zRemRangeByScore, zDeleteRangeByScore, arginfo_swoole_redis_coro_zRemRangeByScore, ZEND_ACC_PUBLIC)
2018 PHP_ME(swoole_redis_coro, zCount, arginfo_swoole_redis_coro_zCount, ZEND_ACC_PUBLIC)
2019 PHP_ME(swoole_redis_coro, zRange, arginfo_swoole_redis_coro_zRange, ZEND_ACC_PUBLIC)
2020 PHP_ME(swoole_redis_coro, zRevRange, arginfo_swoole_redis_coro_zRevRange, ZEND_ACC_PUBLIC)
2021 PHP_ME(swoole_redis_coro, zRangeByScore, arginfo_swoole_redis_coro_zRangeByScore, ZEND_ACC_PUBLIC)
2022 PHP_ME(swoole_redis_coro, zRevRangeByScore, arginfo_swoole_redis_coro_zRevRangeByScore, ZEND_ACC_PUBLIC)
2023 PHP_ME(swoole_redis_coro, zRangeByLex, arginfo_swoole_redis_coro_zRangeByLex, ZEND_ACC_PUBLIC)
2024 PHP_ME(swoole_redis_coro, zRevRangeByLex, arginfo_swoole_redis_coro_zRevRangeByLex, ZEND_ACC_PUBLIC)
2025 PHP_ME(swoole_redis_coro, zInter, arginfo_swoole_redis_coro_zInter, ZEND_ACC_PUBLIC)
2026 PHP_MALIAS(swoole_redis_coro, zinterstore, zInter, arginfo_swoole_redis_coro_zinterstore, ZEND_ACC_PUBLIC)
2027 PHP_ME(swoole_redis_coro, zUnion, arginfo_swoole_redis_coro_zUnion, ZEND_ACC_PUBLIC)
2028 PHP_MALIAS(swoole_redis_coro, zunionstore, zUnion, arginfo_swoole_redis_coro_zunionstore, ZEND_ACC_PUBLIC)
2029 PHP_ME(swoole_redis_coro, incrBy, arginfo_swoole_redis_coro_incrBy, ZEND_ACC_PUBLIC)
2030 PHP_ME(swoole_redis_coro, hIncrBy, arginfo_swoole_redis_coro_hIncrBy, ZEND_ACC_PUBLIC)
2031 PHP_ME(swoole_redis_coro, incr, arginfo_swoole_redis_coro_incr, ZEND_ACC_PUBLIC)
2032 PHP_ME(swoole_redis_coro, decrBy, arginfo_swoole_redis_coro_decrBy, ZEND_ACC_PUBLIC)
2033 PHP_ME(swoole_redis_coro, decr, arginfo_swoole_redis_coro_decr, ZEND_ACC_PUBLIC)
2034 PHP_ME(swoole_redis_coro, getBit, arginfo_swoole_redis_coro_getBit, ZEND_ACC_PUBLIC)
2035 PHP_ME(swoole_redis_coro, lInsert, arginfo_swoole_redis_coro_lInsert, ZEND_ACC_PUBLIC)
2036 PHP_ME(swoole_redis_coro, lGet, arginfo_swoole_redis_coro_lGet, ZEND_ACC_PUBLIC)
2037 PHP_MALIAS(swoole_redis_coro, lIndex, lGet, arginfo_swoole_redis_coro_key_long, ZEND_ACC_PUBLIC)
2038 PHP_ME(swoole_redis_coro, setTimeout, arginfo_swoole_redis_coro_setTimeout, ZEND_ACC_PUBLIC)
2039 PHP_MALIAS(swoole_redis_coro, expire, setTimeout, arginfo_swoole_redis_coro_key_long, ZEND_ACC_PUBLIC)
2040 PHP_ME(swoole_redis_coro, pexpire, arginfo_swoole_redis_coro_pexpire, ZEND_ACC_PUBLIC)
2041 PHP_ME(swoole_redis_coro, expireAt, arginfo_swoole_redis_coro_expireAt, ZEND_ACC_PUBLIC)
2042 PHP_ME(swoole_redis_coro, pexpireAt, arginfo_swoole_redis_coro_pexpireAt, ZEND_ACC_PUBLIC)
2043 PHP_ME(swoole_redis_coro, move, arginfo_swoole_redis_coro_move, ZEND_ACC_PUBLIC)
2044 PHP_ME(swoole_redis_coro, select, arginfo_swoole_redis_coro_select, ZEND_ACC_PUBLIC)
2045 PHP_ME(swoole_redis_coro, getRange, arginfo_swoole_redis_coro_getRange, ZEND_ACC_PUBLIC)
2046 PHP_ME(swoole_redis_coro, listTrim, arginfo_swoole_redis_coro_listTrim, ZEND_ACC_PUBLIC)
2047 PHP_MALIAS(swoole_redis_coro, ltrim, listTrim, arginfo_swoole_redis_coro_ltrim, ZEND_ACC_PUBLIC)
2048 PHP_ME(swoole_redis_coro, lGetRange, arginfo_swoole_redis_coro_lGetRange, ZEND_ACC_PUBLIC)
2049 PHP_MALIAS(swoole_redis_coro, lRange, lGetRange, arginfo_swoole_redis_coro_lrange, ZEND_ACC_PUBLIC)
2050 PHP_ME(swoole_redis_coro, lRem, arginfo_swoole_redis_coro_lrem, ZEND_ACC_PUBLIC)
2051 PHP_MALIAS(swoole_redis_coro, lRemove,lRem, arginfo_swoole_redis_coro_lRemove, ZEND_ACC_PUBLIC)
2052 PHP_ME(swoole_redis_coro, zDeleteRangeByRank, arginfo_swoole_redis_coro_zDeleteRangeByRank, ZEND_ACC_PUBLIC)
2053 PHP_MALIAS(swoole_redis_coro, zRemRangeByRank, zDeleteRangeByRank, arginfo_swoole_redis_coro_zRemRangeByRank, ZEND_ACC_PUBLIC)
2054 PHP_ME(swoole_redis_coro, incrByFloat, arginfo_swoole_redis_coro_incrByFloat, ZEND_ACC_PUBLIC)
2055 PHP_ME(swoole_redis_coro, hIncrByFloat, arginfo_swoole_redis_coro_hIncrByFloat, ZEND_ACC_PUBLIC)
2056 PHP_ME(swoole_redis_coro, bitCount, arginfo_swoole_redis_coro_bitcount, ZEND_ACC_PUBLIC)
2057 PHP_ME(swoole_redis_coro, bitOp, arginfo_swoole_redis_coro_bitop, ZEND_ACC_PUBLIC)
2058 PHP_ME(swoole_redis_coro, sAdd, arginfo_swoole_redis_coro_sAdd, ZEND_ACC_PUBLIC)
2059 PHP_ME(swoole_redis_coro, sMove, arginfo_swoole_redis_coro_sMove, ZEND_ACC_PUBLIC)
2060 PHP_ME(swoole_redis_coro, sDiff, arginfo_swoole_redis_coro_sDiff, ZEND_ACC_PUBLIC)
2061 PHP_ME(swoole_redis_coro, sDiffStore, arginfo_swoole_redis_coro_sDiffStore, ZEND_ACC_PUBLIC)
2062 PHP_ME(swoole_redis_coro, sUnion, arginfo_swoole_redis_coro_sUnion, ZEND_ACC_PUBLIC)
2063 PHP_ME(swoole_redis_coro, sUnionStore, arginfo_swoole_redis_coro_sUnionStore, ZEND_ACC_PUBLIC)
2064 PHP_ME(swoole_redis_coro, sInter, arginfo_swoole_redis_coro_sInter, ZEND_ACC_PUBLIC)
2065 PHP_ME(swoole_redis_coro, sInterStore, arginfo_swoole_redis_coro_sInterStore, ZEND_ACC_PUBLIC)
2066 PHP_ME(swoole_redis_coro, sRemove, arginfo_swoole_redis_coro_sRemove, ZEND_ACC_PUBLIC)
2067 PHP_MALIAS(swoole_redis_coro, srem, sRemove, arginfo_swoole_redis_coro_key_value, ZEND_ACC_PUBLIC)
2068 PHP_ME(swoole_redis_coro, zDelete, arginfo_swoole_redis_coro_zDelete, ZEND_ACC_PUBLIC)
2069 PHP_MALIAS(swoole_redis_coro, zRemove, zDelete, arginfo_swoole_redis_coro_zRemove, ZEND_ACC_PUBLIC)
2070 PHP_MALIAS(swoole_redis_coro, zRem, zDelete, arginfo_swoole_redis_coro_zRem, ZEND_ACC_PUBLIC)
2071 PHP_ME(swoole_redis_coro, pSubscribe, arginfo_swoole_redis_coro_psubscribe, ZEND_ACC_PUBLIC)
2072 PHP_ME(swoole_redis_coro, subscribe, arginfo_swoole_redis_coro_subscribe, ZEND_ACC_PUBLIC)
2073 PHP_ME(swoole_redis_coro, unsubscribe, arginfo_swoole_redis_coro_unsubscribe, ZEND_ACC_PUBLIC)
2074 PHP_ME(swoole_redis_coro, pUnSubscribe, arginfo_swoole_redis_coro_punsubscribe, ZEND_ACC_PUBLIC)
2075 PHP_ME(swoole_redis_coro, multi, arginfo_swoole_redis_coro_multi, ZEND_ACC_PUBLIC)
2076 PHP_ME(swoole_redis_coro, exec, arginfo_swoole_redis_coro_exec, ZEND_ACC_PUBLIC)
2077 PHP_ME(swoole_redis_coro, eval, arginfo_swoole_redis_coro_eval, ZEND_ACC_PUBLIC)
2078 PHP_ME(swoole_redis_coro, evalSha, arginfo_swoole_redis_coro_evalsha, ZEND_ACC_PUBLIC)
2079 PHP_ME(swoole_redis_coro, script, arginfo_swoole_redis_coro_script, ZEND_ACC_PUBLIC)
2080 PHP_ME(swoole_redis_coro, xLen, arginfo_swoole_redis_coro_xLen, ZEND_ACC_PUBLIC)
2081 PHP_ME(swoole_redis_coro, xAdd, arginfo_swoole_redis_coro_xAdd, ZEND_ACC_PUBLIC)
2082 PHP_ME(swoole_redis_coro, xRead, arginfo_swoole_redis_coro_xRead, ZEND_ACC_PUBLIC)
2083 PHP_ME(swoole_redis_coro, xDel, arginfo_swoole_redis_coro_xDel, ZEND_ACC_PUBLIC)
2084 PHP_ME(swoole_redis_coro, xRange, arginfo_swoole_redis_coro_xRange, ZEND_ACC_PUBLIC)
2085 PHP_ME(swoole_redis_coro, xRevRange, arginfo_swoole_redis_coro_xRevRange, ZEND_ACC_PUBLIC)
2086 PHP_ME(swoole_redis_coro, xTrim, arginfo_swoole_redis_coro_xTrim, ZEND_ACC_PUBLIC)
2087 PHP_ME(swoole_redis_coro, xGroupCreate, arginfo_swoole_redis_coro_xGroupCreate, ZEND_ACC_PUBLIC)
2088 PHP_ME(swoole_redis_coro, xGroupSetId, arginfo_swoole_redis_coro_xGroupSetId, ZEND_ACC_PUBLIC)
2089 PHP_ME(swoole_redis_coro, xGroupDestroy, arginfo_swoole_redis_coro_xGroupDestroy, ZEND_ACC_PUBLIC)
2090 PHP_ME(swoole_redis_coro, xGroupCreateConsumer, arginfo_swoole_redis_coro_xGroupCreateConsumer, ZEND_ACC_PUBLIC)
2091 PHP_ME(swoole_redis_coro, xGroupDelConsumer, arginfo_swoole_redis_coro_xGroupDelConsumer, ZEND_ACC_PUBLIC)
2092 PHP_ME(swoole_redis_coro, xReadGroup, arginfo_swoole_redis_coro_xReadGroup, ZEND_ACC_PUBLIC)
2093 PHP_ME(swoole_redis_coro, xPending, arginfo_swoole_redis_coro_xPending, ZEND_ACC_PUBLIC)
2094 PHP_ME(swoole_redis_coro, xAck, arginfo_swoole_redis_coro_xAck, ZEND_ACC_PUBLIC)
2095 PHP_ME(swoole_redis_coro, xClaim, arginfo_swoole_redis_coro_xClaim, ZEND_ACC_PUBLIC)
2096 PHP_ME(swoole_redis_coro, xAutoClaim, arginfo_swoole_redis_coro_xAutoClaim, ZEND_ACC_PUBLIC)
2097 PHP_ME(swoole_redis_coro, xInfoConsumers, arginfo_swoole_redis_coro_xInfoConsumers, ZEND_ACC_PUBLIC)
2098 PHP_ME(swoole_redis_coro, xInfoGroups, arginfo_swoole_redis_coro_xInfoGroups, ZEND_ACC_PUBLIC)
2099 PHP_ME(swoole_redis_coro, xInfoStream, arginfo_swoole_redis_coro_xInfoStream, ZEND_ACC_PUBLIC)
2100 /*---------------------Redis Command End------------------------*/
2101 PHP_FE_END
2102 };
2103 // clang-format on
2104
php_swoole_redis_coro_minit(int module_number)2105 void php_swoole_redis_coro_minit(int module_number) {
2106 SW_INIT_CLASS_ENTRY(swoole_redis_coro, "Swoole\\Coroutine\\Redis", nullptr, "Co\\Redis", swoole_redis_coro_methods);
2107 SW_SET_CLASS_NOT_SERIALIZABLE(swoole_redis_coro);
2108 SW_SET_CLASS_CLONEABLE(swoole_redis_coro, sw_zend_class_clone_deny);
2109 SW_SET_CLASS_UNSET_PROPERTY_HANDLER(swoole_redis_coro, sw_zend_class_unset_property_deny);
2110 SW_SET_CLASS_CREATE_WITH_ITS_OWN_HANDLERS(swoole_redis_coro);
2111 SW_SET_CLASS_CUSTOM_OBJECT(
2112 swoole_redis_coro, php_swoole_redis_coro_create_object, php_swoole_redis_coro_free_object, RedisClient, std);
2113
2114 zend_declare_property_string(swoole_redis_coro_ce, ZEND_STRL("host"), "", ZEND_ACC_PUBLIC);
2115 zend_declare_property_long(swoole_redis_coro_ce, ZEND_STRL("port"), 0, ZEND_ACC_PUBLIC);
2116 zend_declare_property_null(swoole_redis_coro_ce, ZEND_STRL("setting"), ZEND_ACC_PUBLIC);
2117 zend_declare_property_long(swoole_redis_coro_ce, ZEND_STRL("sock"), -1, ZEND_ACC_PUBLIC);
2118 zend_declare_property_bool(swoole_redis_coro_ce, ZEND_STRL("connected"), 0, ZEND_ACC_PUBLIC);
2119 zend_declare_property_long(swoole_redis_coro_ce, ZEND_STRL("errType"), 0, ZEND_ACC_PUBLIC);
2120 zend_declare_property_long(swoole_redis_coro_ce, ZEND_STRL("errCode"), 0, ZEND_ACC_PUBLIC);
2121 zend_declare_property_string(swoole_redis_coro_ce, ZEND_STRL("errMsg"), "", ZEND_ACC_PUBLIC);
2122
2123 SW_REGISTER_LONG_CONSTANT("SWOOLE_REDIS_MODE_MULTI", SW_REDIS_MODE_MULTI);
2124 SW_REGISTER_LONG_CONSTANT("SWOOLE_REDIS_MODE_PIPELINE", SW_REDIS_MODE_PIPELINE);
2125
2126 SW_REGISTER_LONG_CONSTANT("SWOOLE_REDIS_TYPE_NOT_FOUND", SW_REDIS_TYPE_NOT_FOUND);
2127 SW_REGISTER_LONG_CONSTANT("SWOOLE_REDIS_TYPE_STRING", SW_REDIS_TYPE_STRING);
2128 SW_REGISTER_LONG_CONSTANT("SWOOLE_REDIS_TYPE_SET", SW_REDIS_TYPE_SET);
2129 SW_REGISTER_LONG_CONSTANT("SWOOLE_REDIS_TYPE_LIST", SW_REDIS_TYPE_LIST);
2130 SW_REGISTER_LONG_CONSTANT("SWOOLE_REDIS_TYPE_ZSET", SW_REDIS_TYPE_ZSET);
2131 SW_REGISTER_LONG_CONSTANT("SWOOLE_REDIS_TYPE_HASH", SW_REDIS_TYPE_HASH);
2132
2133 SW_REGISTER_LONG_CONSTANT("SWOOLE_REDIS_ERR_IO", SW_REDIS_ERR_IO);
2134 SW_REGISTER_LONG_CONSTANT("SWOOLE_REDIS_ERR_OTHER", SW_REDIS_ERR_OTHER);
2135 SW_REGISTER_LONG_CONSTANT("SWOOLE_REDIS_ERR_EOF", SW_REDIS_ERR_EOF);
2136 SW_REGISTER_LONG_CONSTANT("SWOOLE_REDIS_ERR_PROTOCOL", SW_REDIS_ERR_PROTOCOL);
2137 SW_REGISTER_LONG_CONSTANT("SWOOLE_REDIS_ERR_OOM", SW_REDIS_ERR_OOM);
2138 SW_REGISTER_LONG_CONSTANT("SWOOLE_REDIS_ERR_CLOSED", SW_REDIS_ERR_CLOSED);
2139 SW_REGISTER_LONG_CONSTANT("SWOOLE_REDIS_ERR_NOAUTH", SW_REDIS_ERR_NOAUTH);
2140 SW_REGISTER_LONG_CONSTANT("SWOOLE_REDIS_ERR_ALLOC", SW_REDIS_ERR_ALLOC);
2141 }
2142
swoole_redis_coro_set_options(RedisClient * redis,zval * zoptions,bool backward_compatibility=false)2143 static void swoole_redis_coro_set_options(RedisClient *redis, zval *zoptions, bool backward_compatibility = false) {
2144 zval *zsettings =
2145 sw_zend_read_and_convert_property_array(swoole_redis_coro_ce, redis->zobject, ZEND_STRL("setting"), 0);
2146 HashTable *vht = Z_ARRVAL_P(zoptions);
2147 zval *ztmp;
2148
2149 php_array_merge(Z_ARRVAL_P(zsettings), vht);
2150
2151 if (php_swoole_array_get_value(vht, "connect_timeout", ztmp)) {
2152 redis->connect_timeout = zval_get_double(ztmp);
2153 if (redis->connect_timeout <= 0) {
2154 redis->connect_timeout = SW_TIMER_MAX_SEC;
2155 }
2156 }
2157 if (php_swoole_array_get_value(vht, "timeout", ztmp)) {
2158 redis->timeout = zval_get_double(ztmp);
2159 if (backward_compatibility) {
2160 redis->connect_timeout = redis->timeout;
2161 if (redis->connect_timeout <= 0) {
2162 redis->connect_timeout = SW_TIMER_MAX_SEC;
2163 }
2164 }
2165 if (redis->context) {
2166 Socket *socket = swoole_redis_coro_get_socket(redis->context);
2167 if (socket) {
2168 socket->set_timeout(redis->timeout, Socket::TIMEOUT_RDWR);
2169 }
2170 }
2171 }
2172 if (php_swoole_array_get_value(vht, "serialize", ztmp)) {
2173 redis->serialize = zval_is_true(ztmp);
2174 }
2175 if (php_swoole_array_get_value(vht, "reconnect", ztmp)) {
2176 redis->reconnect_interval = (uint8_t) SW_MIN(zval_get_long(ztmp), UINT8_MAX);
2177 }
2178 if (php_swoole_array_get_value(vht, "compatibility_mode", ztmp)) {
2179 redis->compatibility_mode = zval_is_true(ztmp);
2180 }
2181 }
2182
PHP_METHOD(swoole_redis_coro,__construct)2183 static PHP_METHOD(swoole_redis_coro, __construct) {
2184 RedisClient *redis = php_swoole_get_redis_client(ZEND_THIS);
2185 zval *zsettings = sw_zend_read_and_convert_property_array(swoole_redis_coro_ce, ZEND_THIS, ZEND_STRL("setting"), 0);
2186 zval *zset = nullptr;
2187
2188 ZEND_PARSE_PARAMETERS_START_EX(ZEND_PARSE_PARAMS_THROW, 0, 1)
2189 Z_PARAM_OPTIONAL
2190 Z_PARAM_ARRAY(zset)
2191 ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE);
2192
2193 if (redis->zobject) {
2194 php_swoole_fatal_error(E_ERROR, "Constructor of %s can only be called once", SW_Z_OBJCE_NAME_VAL_P(ZEND_THIS));
2195 RETURN_FALSE;
2196 }
2197
2198 redis->zobject = &redis->_zobject;
2199 redis->_zobject = *ZEND_THIS;
2200
2201 redis->connect_timeout = network::Socket::default_connect_timeout;
2202 redis->timeout = network::Socket::default_read_timeout;
2203 redis->reconnect_interval = 1;
2204
2205 // settings init
2206 add_assoc_double(zsettings, "connect_timeout", redis->connect_timeout);
2207 add_assoc_double(zsettings, "timeout", redis->timeout);
2208 add_assoc_bool(zsettings, "serialize", redis->serialize);
2209 add_assoc_long(zsettings, "reconnect", redis->reconnect_interval);
2210 // after connected
2211 add_assoc_string(zsettings, "password", (char *) "");
2212 add_assoc_long(zsettings, "database", 0);
2213
2214 if (zset) {
2215 swoole_redis_coro_set_options(redis, zset, true);
2216 }
2217 }
2218
PHP_METHOD(swoole_redis_coro,connect)2219 static PHP_METHOD(swoole_redis_coro, connect) {
2220 zval *zobject = ZEND_THIS;
2221 char *host = nullptr;
2222 size_t host_len = 0;
2223 zend_long port = 0;
2224 zend_bool serialize = 0;
2225
2226 SW_REDIS_COMMAND_CHECK
2227
2228 if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|lb", &host, &host_len, &port, &serialize) == FAILURE) {
2229 RETURN_FALSE;
2230 }
2231
2232 zend_update_property_string(swoole_redis_coro_ce, SW_Z8_OBJ_P(zobject), ZEND_STRL("host"), host);
2233 zend_update_property_long(swoole_redis_coro_ce, SW_Z8_OBJ_P(zobject), ZEND_STRL("port"), port);
2234 redis->serialize = serialize;
2235
2236 if (swoole_redis_coro_connect(redis) > 0) {
2237 // clear the error code only when the developer manually tries to connect successfully
2238 // if the kernel retries automatically, keep silent.
2239 zend_update_property_long(swoole_redis_coro_ce, SW_Z8_OBJ_P(zobject), ZEND_STRL("errType"), 0);
2240 zend_update_property_long(swoole_redis_coro_ce, SW_Z8_OBJ_P(zobject), ZEND_STRL("errCode"), 0);
2241 zend_update_property_string(swoole_redis_coro_ce, SW_Z8_OBJ_P(zobject), ZEND_STRL("errMsg"), "");
2242 RETURN_TRUE;
2243 } else {
2244 RETURN_FALSE;
2245 }
2246 }
2247
PHP_METHOD(swoole_redis_coro,getAuth)2248 static PHP_METHOD(swoole_redis_coro, getAuth) {
2249 RedisClient *redis = php_swoole_get_redis_client(ZEND_THIS);
2250 if (redis->session.auth) {
2251 zval *ztmp = sw_zend_read_and_convert_property_array(swoole_redis_coro_ce, ZEND_THIS, ZEND_STRL("setting"), 0);
2252 if (php_swoole_array_get_value(Z_ARRVAL_P(ztmp), "password", ztmp)) {
2253 RETURN_ZVAL(ztmp, 1, 0);
2254 }
2255 RETURN_EMPTY_STRING();
2256 }
2257 RETURN_FALSE;
2258 }
2259
PHP_METHOD(swoole_redis_coro,getDBNum)2260 static PHP_METHOD(swoole_redis_coro, getDBNum) {
2261 RedisClient *redis = php_swoole_get_redis_client(ZEND_THIS);
2262 if (!redis->context) {
2263 RETURN_FALSE;
2264 }
2265 RETURN_LONG(redis->session.db_num);
2266 }
2267
PHP_METHOD(swoole_redis_coro,getOptions)2268 static PHP_METHOD(swoole_redis_coro, getOptions) {
2269 RETURN_ZVAL(
2270 sw_zend_read_and_convert_property_array(swoole_redis_coro_ce, ZEND_THIS, ZEND_STRL("setting"), 0), 1, 0);
2271 }
2272
PHP_METHOD(swoole_redis_coro,setOptions)2273 static PHP_METHOD(swoole_redis_coro, setOptions) {
2274 RedisClient *redis = php_swoole_get_redis_client(ZEND_THIS);
2275 zval *zoptions;
2276
2277 ZEND_PARSE_PARAMETERS_START(1, 1)
2278 Z_PARAM_ARRAY(zoptions)
2279 ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE);
2280
2281 swoole_redis_coro_set_options(redis, zoptions);
2282
2283 RETURN_TRUE;
2284 }
2285
PHP_METHOD(swoole_redis_coro,getDefer)2286 static PHP_METHOD(swoole_redis_coro, getDefer) {
2287 RedisClient *redis = php_swoole_get_redis_client(ZEND_THIS);
2288
2289 RETURN_BOOL(redis->defer);
2290 }
2291
PHP_METHOD(swoole_redis_coro,setDefer)2292 static PHP_METHOD(swoole_redis_coro, setDefer) {
2293 RedisClient *redis = php_swoole_get_redis_client(ZEND_THIS);
2294 zend_bool defer = 1;
2295
2296 if (redis->session.subscribe) {
2297 php_swoole_fatal_error(E_WARNING, "you should not use setDefer after subscribe");
2298 RETURN_FALSE;
2299 }
2300 if (zend_parse_parameters(ZEND_NUM_ARGS(), "|b", &defer) == FAILURE) {
2301 RETURN_FALSE;
2302 }
2303 redis->defer = defer;
2304
2305 RETURN_TRUE;
2306 }
2307
PHP_METHOD(swoole_redis_coro,recv)2308 static PHP_METHOD(swoole_redis_coro, recv) {
2309 SW_REDIS_COMMAND_CHECK
2310
2311 if (UNEXPECTED(!redis->context)) {
2312 RETURN_FALSE;
2313 }
2314 if (UNEXPECTED(!redis->defer && !redis->session.subscribe)) {
2315 php_swoole_fatal_error(E_WARNING, "you should not use recv without defer or subscribe");
2316 RETURN_FALSE;
2317 }
2318
2319 redisReply *reply;
2320 _recv:
2321 if (redisGetReply(redis->context, (void **) &reply) == REDIS_OK) {
2322 swoole_redis_coro_parse_result(redis, return_value, reply);
2323 freeReplyObject(reply);
2324
2325 if (redis->session.subscribe) {
2326 zval *ztype;
2327
2328 if (!ZVAL_IS_ARRAY(return_value)) {
2329 zval_ptr_dtor(return_value);
2330 goto _error;
2331 }
2332
2333 ztype = zend_hash_index_find(Z_ARRVAL_P(return_value), 0);
2334 if (Z_TYPE_P(ztype) == IS_STRING) {
2335 char *type = Z_STRVAL_P(ztype);
2336
2337 if (!strcmp(type, "unsubscribe") || !strcmp(type, "punsubscribe")) {
2338 zval *znum = zend_hash_index_find(Z_ARRVAL_P(return_value), 2);
2339 if (Z_LVAL_P(znum) == 0) {
2340 redis->session.subscribe = false;
2341 }
2342
2343 return;
2344 } else if (!strcmp(type, "message") || !strcmp(type, "pmessage") || !strcmp(type, "subscribe") ||
2345 !strcmp(type, "psubscribe")) {
2346 return;
2347 }
2348 }
2349
2350 zval_ptr_dtor(return_value);
2351 goto _recv;
2352 }
2353 } else {
2354 _error:
2355 zend_update_property_long(
2356 swoole_redis_coro_ce, SW_Z8_OBJ_P(redis->zobject), ZEND_STRL("errType"), redis->context->err);
2357 zend_update_property_long(swoole_redis_coro_ce,
2358 SW_Z8_OBJ_P(redis->zobject),
2359 ZEND_STRL("errCode"),
2360 sw_redis_convert_err(redis->context->err));
2361 zend_update_property_string(
2362 swoole_redis_coro_ce, SW_Z8_OBJ_P(redis->zobject), ZEND_STRL("errMsg"), redis->context->errstr);
2363
2364 swoole_redis_coro_close(redis);
2365 RETURN_FALSE;
2366 }
2367 }
2368
PHP_METHOD(swoole_redis_coro,close)2369 static PHP_METHOD(swoole_redis_coro, close) {
2370 RedisClient *redis = php_swoole_get_redis_client(ZEND_THIS);
2371 RETURN_BOOL(swoole_redis_coro_close(redis));
2372 }
2373
PHP_METHOD(swoole_redis_coro,__destruct)2374 static PHP_METHOD(swoole_redis_coro, __destruct) {
2375 SW_PREVENT_USER_DESTRUCT();
2376 }
2377
PHP_METHOD(swoole_redis_coro,set)2378 static PHP_METHOD(swoole_redis_coro, set) {
2379 char *key, *exp_type = nullptr, *set_type = nullptr;
2380 size_t key_len, argc = 3;
2381 zval *z_value, *z_opts = nullptr;
2382 zend_long expire = -1;
2383
2384 if (zend_parse_parameters(ZEND_NUM_ARGS(), "sz|z", &key, &key_len, &z_value, &z_opts) == FAILURE) {
2385 RETURN_FALSE;
2386 }
2387
2388 SW_REDIS_COMMAND_CHECK
2389
2390 if (z_opts && Z_TYPE_P(z_opts) != IS_LONG && Z_TYPE_P(z_opts) != IS_ARRAY && Z_TYPE_P(z_opts) != IS_NULL) {
2391 RETURN_FALSE;
2392 }
2393
2394 if (z_opts && ZVAL_IS_ARRAY(z_opts)) {
2395 HashTable *kt = Z_ARRVAL_P(z_opts);
2396
2397 zend_string *zkey;
2398 zend_ulong idx;
2399 zval *zv;
2400
2401 /* Iterate our option array */
2402 ZEND_HASH_FOREACH_KEY_VAL(kt, idx, zkey, zv) {
2403 /* Detect PX or EX argument and validate timeout */
2404 if (!exp_type && zkey && IS_EX_PX_ARG(ZSTR_VAL(zkey))) {
2405 /* Set expire type */
2406 exp_type = ZSTR_VAL(zkey);
2407
2408 /* Try to extract timeout */
2409 if (Z_TYPE_P(zv) == IS_LONG) {
2410 expire = Z_LVAL_P(zv);
2411 } else if (Z_TYPE_P(zv) == IS_STRING) {
2412 expire = atol(Z_STRVAL_P(zv));
2413 }
2414
2415 /* Expiry can't be set < 1 */
2416 if (expire < 1) {
2417 RETURN_FALSE;
2418 }
2419 argc += 2;
2420 } else if (!set_type && Z_TYPE_P(zv) == IS_STRING && IS_NX_XX_ARG(Z_STRVAL_P(zv))) {
2421 argc += 1;
2422 set_type = Z_STRVAL_P(zv);
2423 }
2424 (void) idx;
2425 }
2426 ZEND_HASH_FOREACH_END();
2427 } else if (z_opts && Z_TYPE_P(z_opts) == IS_LONG) {
2428 /* Grab expiry and fail if it's < 1 */
2429 expire = Z_LVAL_P(z_opts);
2430 /* Expiry can't be set < 1 */
2431 if (expire < 1) {
2432 RETURN_FALSE;
2433 }
2434 argc += 1;
2435 }
2436
2437 SW_REDIS_COMMAND_ALLOC_ARGV
2438
2439 int i = 0;
2440 if (exp_type || set_type) {
2441 SW_REDIS_COMMAND_ARGV_FILL("SET", 3)
2442 SW_REDIS_COMMAND_ARGV_FILL(key, key_len)
2443 SW_REDIS_COMMAND_ARGV_FILL_WITH_SERIALIZE(z_value)
2444
2445 if (set_type) {
2446 SW_REDIS_COMMAND_ARGV_FILL(set_type, (size_t) strlen(set_type))
2447 }
2448
2449 if (exp_type) {
2450 SW_REDIS_COMMAND_ARGV_FILL(exp_type, (size_t) strlen(exp_type))
2451
2452 char str[32];
2453 sprintf(str, ZEND_LONG_FMT, expire);
2454 SW_REDIS_COMMAND_ARGV_FILL(str, (size_t) strlen(str))
2455 }
2456 } else if (expire > 0) {
2457 SW_REDIS_COMMAND_ARGV_FILL("SETEX", 5)
2458 SW_REDIS_COMMAND_ARGV_FILL(key, key_len)
2459
2460 char str[32];
2461 sprintf(str, ZEND_LONG_FMT, expire);
2462 SW_REDIS_COMMAND_ARGV_FILL(str, (size_t) strlen(str))
2463
2464 SW_REDIS_COMMAND_ARGV_FILL_WITH_SERIALIZE(z_value)
2465 } else {
2466 SW_REDIS_COMMAND_ARGV_FILL("SET", 3)
2467 SW_REDIS_COMMAND_ARGV_FILL(key, key_len)
2468 SW_REDIS_COMMAND_ARGV_FILL_WITH_SERIALIZE(z_value)
2469 }
2470
2471 redis_request(redis, argc, argv, argvlen, return_value);
2472
2473 SW_REDIS_COMMAND_FREE_ARGV
2474 }
2475
PHP_METHOD(swoole_redis_coro,setBit)2476 static PHP_METHOD(swoole_redis_coro, setBit) {
2477 char *key;
2478 size_t key_len;
2479 long offset;
2480 zend_bool val;
2481
2482 if (zend_parse_parameters(ZEND_NUM_ARGS(), "slb", &key, &key_len, &offset, &val) == FAILURE) {
2483 return;
2484 }
2485
2486 // Validate our offset
2487 if (offset < SW_BITOP_MIN_OFFSET || offset > SW_BITOP_MAX_OFFSET) {
2488 zend_update_property_long(
2489 swoole_redis_coro_ce, SW_Z8_OBJ_P(ZEND_THIS), ZEND_STRL("errType"), SW_REDIS_ERR_OTHER);
2490 zend_update_property_long(swoole_redis_coro_ce,
2491 SW_Z8_OBJ_P(ZEND_THIS),
2492 ZEND_STRL("errCode"),
2493 sw_redis_convert_err(SW_REDIS_ERR_OTHER));
2494 zend_update_property_string(swoole_redis_coro_ce,
2495 SW_Z8_OBJ_P(ZEND_THIS),
2496 ZEND_STRL("errMsg"),
2497 "Invalid OFFSET for bitop command (must be between 0-2^32-1)");
2498 RETURN_FALSE;
2499 }
2500
2501 SW_REDIS_COMMAND_CHECK
2502
2503 int i = 0;
2504 size_t argvlen[4];
2505 char *argv[4];
2506
2507 SW_REDIS_COMMAND_ARGV_FILL("SETBIT", 6)
2508 SW_REDIS_COMMAND_ARGV_FILL(key, key_len)
2509
2510 char str[32];
2511 sprintf(str, "%ld", offset);
2512 SW_REDIS_COMMAND_ARGV_FILL(str, strlen(str))
2513
2514 SW_REDIS_COMMAND_ARGV_FILL(val ? "1" : "0", 1)
2515 redis_request(redis, 4, argv, argvlen, return_value);
2516 }
2517
PHP_METHOD(swoole_redis_coro,setEx)2518 static PHP_METHOD(swoole_redis_coro, setEx) {
2519 sw_redis_command_key_long_val(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("SETEX"));
2520 }
2521
PHP_METHOD(swoole_redis_coro,psetEx)2522 static PHP_METHOD(swoole_redis_coro, psetEx) {
2523 sw_redis_command_key_long_val(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("PSETEX"));
2524 }
2525
PHP_METHOD(swoole_redis_coro,lSet)2526 static PHP_METHOD(swoole_redis_coro, lSet) {
2527 sw_redis_command_key_long_val(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("LSET"));
2528 }
2529
PHP_METHOD(swoole_redis_coro,restore)2530 static PHP_METHOD(swoole_redis_coro, restore) {
2531 sw_redis_command_key_long_val(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("RESTORE"));
2532 }
2533
PHP_METHOD(swoole_redis_coro,dump)2534 static PHP_METHOD(swoole_redis_coro, dump) {
2535 sw_redis_command_key(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("DUMP"));
2536 }
2537
PHP_METHOD(swoole_redis_coro,debug)2538 static PHP_METHOD(swoole_redis_coro, debug) {
2539 sw_redis_command_key(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("DEBUG"));
2540 }
2541
PHP_METHOD(swoole_redis_coro,get)2542 static PHP_METHOD(swoole_redis_coro, get) {
2543 sw_redis_command_key(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("GET"));
2544 }
2545
PHP_METHOD(swoole_redis_coro,mGet)2546 static PHP_METHOD(swoole_redis_coro, mGet) {
2547 zval *z_args;
2548 if (zend_parse_parameters(ZEND_NUM_ARGS(), "a", &z_args) == FAILURE) {
2549 RETURN_FALSE;
2550 }
2551 int argc;
2552 argc = zend_hash_num_elements(Z_ARRVAL_P(z_args));
2553 if (argc == 0) {
2554 RETURN_FALSE;
2555 }
2556 SW_REDIS_COMMAND_CHECK
2557 argc++;
2558 SW_REDIS_COMMAND_ALLOC_ARGV
2559 int i = 0;
2560 zval *value;
2561 SW_REDIS_COMMAND_ARGV_FILL("MGET", 4)
2562 SW_HASHTABLE_FOREACH_START(Z_ARRVAL_P(z_args), value)
2563 zend_string *convert_str = zval_get_string(value);
2564 SW_REDIS_COMMAND_ARGV_FILL(ZSTR_VAL(convert_str), ZSTR_LEN(convert_str))
2565 zend_string_release(convert_str);
2566 SW_HASHTABLE_FOREACH_END();
2567
2568 redis_request(redis, argc, argv, argvlen, return_value);
2569 SW_REDIS_COMMAND_FREE_ARGV
2570 }
2571
PHP_METHOD(swoole_redis_coro,hSet)2572 static PHP_METHOD(swoole_redis_coro, hSet) {
2573 char *key, *field;
2574 size_t key_len, field_len;
2575 zval *z_val;
2576
2577 if (zend_parse_parameters(ZEND_NUM_ARGS(), "ssz", &key, &key_len, &field, &field_len, &z_val) == FAILURE) {
2578 return;
2579 }
2580 SW_REDIS_COMMAND_CHECK
2581 int i = 0;
2582 size_t argvlen[4];
2583 char *argv[4];
2584 SW_REDIS_COMMAND_ARGV_FILL("HSET", 4)
2585 SW_REDIS_COMMAND_ARGV_FILL(key, key_len)
2586 SW_REDIS_COMMAND_ARGV_FILL(field, field_len)
2587 SW_REDIS_COMMAND_ARGV_FILL_WITH_SERIALIZE(z_val)
2588
2589 redis_request(redis, 4, argv, argvlen, return_value);
2590 }
2591
PHP_METHOD(swoole_redis_coro,hMSet)2592 static PHP_METHOD(swoole_redis_coro, hMSet) {
2593 char *key;
2594 size_t key_len, argc;
2595 zval *z_arr;
2596
2597 if (zend_parse_parameters(ZEND_NUM_ARGS(), "sa", &key, &key_len, &z_arr) == FAILURE) {
2598 return;
2599 }
2600 if ((argc = zend_hash_num_elements(Z_ARRVAL_P(z_arr))) == 0) {
2601 RETURN_FALSE;
2602 }
2603 SW_REDIS_COMMAND_CHECK
2604 int i = 0;
2605 argc = argc * 2 + 2;
2606 zval *value;
2607 char buf[32];
2608 SW_REDIS_COMMAND_ALLOC_ARGV
2609 SW_REDIS_COMMAND_ARGV_FILL("HMSET", 5)
2610 SW_REDIS_COMMAND_ARGV_FILL(key, key_len)
2611 zend_ulong idx;
2612 zend_string *_key;
2613 ZEND_HASH_FOREACH_KEY_VAL_IND(Z_ARRVAL_P(z_arr), idx, _key, value) {
2614 if (_key == nullptr) {
2615 key_len = sw_snprintf(buf, sizeof(buf), "%ld", (long) idx);
2616 key = (char *) buf;
2617 } else {
2618 key_len = ZSTR_LEN(_key);
2619 key = ZSTR_VAL(_key);
2620 }
2621 SW_REDIS_COMMAND_ARGV_FILL(key, key_len)
2622 SW_REDIS_COMMAND_ARGV_FILL_WITH_SERIALIZE(value)
2623 }
2624 ZEND_HASH_FOREACH_END();
2625
2626 redis_request(redis, argc, argv, argvlen, return_value);
2627 SW_REDIS_COMMAND_FREE_ARGV
2628 }
2629
PHP_METHOD(swoole_redis_coro,hSetNx)2630 static PHP_METHOD(swoole_redis_coro, hSetNx) {
2631 char *key, *field;
2632 size_t key_len, field_len;
2633 zval *z_val;
2634
2635 if (zend_parse_parameters(ZEND_NUM_ARGS(), "ssz", &key, &key_len, &field, &field_len, &z_val) == FAILURE) {
2636 return;
2637 }
2638 SW_REDIS_COMMAND_CHECK
2639 int i = 0;
2640 size_t argvlen[4];
2641 char *argv[4];
2642 convert_to_string(z_val);
2643 SW_REDIS_COMMAND_ARGV_FILL("HSETNX", 6)
2644 SW_REDIS_COMMAND_ARGV_FILL(key, key_len)
2645 SW_REDIS_COMMAND_ARGV_FILL(field, field_len)
2646 SW_REDIS_COMMAND_ARGV_FILL(Z_STRVAL_P(z_val), Z_STRLEN_P(z_val))
2647
2648 redis_request(redis, 4, argv, argvlen, return_value);
2649 }
2650
PHP_METHOD(swoole_redis_coro,hDel)2651 static PHP_METHOD(swoole_redis_coro, hDel) {
2652 int argc = ZEND_NUM_ARGS();
2653 SW_REDIS_COMMAND_CHECK
2654 SW_REDIS_COMMAND_ALLOC_ARGS_ARR
2655 if (argc < 2 || zend_get_parameters_array(ht, argc, z_args) == FAILURE) {
2656 efree(z_args);
2657 RETURN_FALSE;
2658 }
2659 argc++;
2660 int i = 0, j;
2661 SW_REDIS_COMMAND_ALLOC_ARGV
2662 SW_REDIS_COMMAND_ARGV_FILL("HDEL", 4)
2663 for (j = 0; j < argc - 1; ++j) {
2664 zend_string *convert_str = zval_get_string(&z_args[j]);
2665 SW_REDIS_COMMAND_ARGV_FILL(ZSTR_VAL(convert_str), ZSTR_LEN(convert_str))
2666 zend_string_release(convert_str);
2667 }
2668 efree(z_args);
2669 redis_request(redis, argc, argv, argvlen, return_value);
2670 SW_REDIS_COMMAND_FREE_ARGV
2671 }
2672
PHP_METHOD(swoole_redis_coro,watch)2673 static PHP_METHOD(swoole_redis_coro, watch) {
2674 sw_redis_command_var_key(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("WATCH"), 1, 0);
2675 }
2676
PHP_METHOD(swoole_redis_coro,del)2677 static PHP_METHOD(swoole_redis_coro, del) {
2678 sw_redis_command_var_key(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("DEL"), 1, 0);
2679 }
2680
PHP_METHOD(swoole_redis_coro,sDiff)2681 static PHP_METHOD(swoole_redis_coro, sDiff) {
2682 sw_redis_command_var_key(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("SDIFF"), 1, 0);
2683 }
2684
PHP_METHOD(swoole_redis_coro,sDiffStore)2685 static PHP_METHOD(swoole_redis_coro, sDiffStore) {
2686 sw_redis_command_var_key(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("SDIFFSTORE"), 1, 0);
2687 }
2688
PHP_METHOD(swoole_redis_coro,sUnion)2689 static PHP_METHOD(swoole_redis_coro, sUnion) {
2690 sw_redis_command_var_key(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("SUNION"), 1, 0);
2691 }
2692
PHP_METHOD(swoole_redis_coro,sUnionStore)2693 static PHP_METHOD(swoole_redis_coro, sUnionStore) {
2694 sw_redis_command_var_key(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("SUNIONSTORE"), 1, 0);
2695 }
2696
PHP_METHOD(swoole_redis_coro,sInter)2697 static PHP_METHOD(swoole_redis_coro, sInter) {
2698 sw_redis_command_var_key(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("SINTER"), 1, 0);
2699 }
2700
PHP_METHOD(swoole_redis_coro,sInterStore)2701 static PHP_METHOD(swoole_redis_coro, sInterStore) {
2702 sw_redis_command_var_key(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("SINTERSTORE"), 1, 0);
2703 }
2704
PHP_METHOD(swoole_redis_coro,mSet)2705 static PHP_METHOD(swoole_redis_coro, mSet) {
2706 zval *z_args;
2707 if (zend_parse_parameters(ZEND_NUM_ARGS(), "a", &z_args) == FAILURE) {
2708 RETURN_FALSE;
2709 }
2710 int argc;
2711 argc = zend_hash_num_elements(Z_ARRVAL_P(z_args));
2712 if (argc == 0) {
2713 RETURN_FALSE;
2714 }
2715 SW_REDIS_COMMAND_CHECK
2716 argc *= 2;
2717 argc++;
2718 SW_REDIS_COMMAND_ALLOC_ARGV
2719 int i = 0;
2720 SW_REDIS_COMMAND_ARGV_FILL("MSET", 4)
2721 zval *value;
2722 char buf[32];
2723 char *key;
2724 uint32_t key_len;
2725 zend_ulong idx;
2726 zend_string *_key;
2727 ZEND_HASH_FOREACH_KEY_VAL_IND(Z_ARRVAL_P(z_args), idx, _key, value) {
2728 if (_key == nullptr) {
2729 key_len = sw_snprintf(buf, sizeof(buf), "%ld", (long) idx);
2730 key = (char *) buf;
2731 } else {
2732 key_len = ZSTR_LEN(_key);
2733 key = ZSTR_VAL(_key);
2734 }
2735 SW_REDIS_COMMAND_ARGV_FILL(key, key_len)
2736 SW_REDIS_COMMAND_ARGV_FILL_WITH_SERIALIZE(value)
2737 }
2738 ZEND_HASH_FOREACH_END();
2739
2740 redis_request(redis, argc, argv, argvlen, return_value);
2741 SW_REDIS_COMMAND_FREE_ARGV
2742 }
2743
PHP_METHOD(swoole_redis_coro,mSetNx)2744 static PHP_METHOD(swoole_redis_coro, mSetNx) {
2745 zval *z_args;
2746 if (zend_parse_parameters(ZEND_NUM_ARGS(), "a", &z_args) == FAILURE) {
2747 return;
2748 }
2749 int argc;
2750 argc = zend_hash_num_elements(Z_ARRVAL_P(z_args));
2751 if (argc == 0) {
2752 RETURN_FALSE;
2753 }
2754 SW_REDIS_COMMAND_CHECK
2755 argc *= 2;
2756 argc++;
2757 SW_REDIS_COMMAND_ALLOC_ARGV
2758 int i = 0;
2759 SW_REDIS_COMMAND_ARGV_FILL("MSETNX", 6)
2760 zval *value;
2761 char buf[32];
2762 char *key;
2763 uint32_t key_len;
2764 zend_ulong idx;
2765 zend_string *_key;
2766 ZEND_HASH_FOREACH_KEY_VAL_IND(Z_ARRVAL_P(z_args), idx, _key, value) {
2767 if (_key == nullptr) {
2768 key_len = sw_snprintf(buf, sizeof(buf), "%ld", (long) idx);
2769 key = (char *) buf;
2770 } else {
2771 key_len = ZSTR_LEN(_key);
2772 key = ZSTR_VAL(_key);
2773 }
2774 SW_REDIS_COMMAND_ARGV_FILL(key, key_len)
2775 SW_REDIS_COMMAND_ARGV_FILL_WITH_SERIALIZE(value)
2776 }
2777 ZEND_HASH_FOREACH_END();
2778
2779 redis_request(redis, argc, argv, argvlen, return_value);
2780 SW_REDIS_COMMAND_FREE_ARGV
2781 }
2782
PHP_METHOD(swoole_redis_coro,getKeys)2783 static PHP_METHOD(swoole_redis_coro, getKeys) {
2784 sw_redis_command_key(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("KEYS"));
2785 }
2786
PHP_METHOD(swoole_redis_coro,exists)2787 static PHP_METHOD(swoole_redis_coro, exists) {
2788 sw_redis_command_key(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("EXISTS"));
2789 }
2790
PHP_METHOD(swoole_redis_coro,type)2791 static PHP_METHOD(swoole_redis_coro, type) {
2792 sw_redis_command_key(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("TYPE"));
2793 }
2794
PHP_METHOD(swoole_redis_coro,strLen)2795 static PHP_METHOD(swoole_redis_coro, strLen) {
2796 sw_redis_command_key(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("STRLEN"));
2797 }
2798
PHP_METHOD(swoole_redis_coro,lPop)2799 static PHP_METHOD(swoole_redis_coro, lPop) {
2800 sw_redis_command_key(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("LPOP"));
2801 }
2802
PHP_METHOD(swoole_redis_coro,bRPopLPush)2803 static PHP_METHOD(swoole_redis_coro, bRPopLPush) {
2804 char *key1, *key2;
2805 size_t key1_len, key2_len;
2806 long timeout;
2807
2808 if (zend_parse_parameters(ZEND_NUM_ARGS(), "ssl", &key1, &key1_len, &key2, &key2_len, &timeout) == FAILURE) {
2809 return;
2810 }
2811 SW_REDIS_COMMAND_CHECK
2812 int argc, i = 0;
2813 argc = timeout < 0 ? 3 : 4;
2814 SW_REDIS_COMMAND_ALLOC_ARGV
2815 if (timeout < 0) {
2816 SW_REDIS_COMMAND_ARGV_FILL("RPOPLPUSH", 9)
2817 SW_REDIS_COMMAND_ARGV_FILL(key1, key1_len)
2818 SW_REDIS_COMMAND_ARGV_FILL(key2, key2_len)
2819 } else {
2820 SW_REDIS_COMMAND_ARGV_FILL("BRPOPLPUSH", 10)
2821 SW_REDIS_COMMAND_ARGV_FILL(key1, key1_len)
2822 SW_REDIS_COMMAND_ARGV_FILL(key2, key2_len)
2823 char str[32];
2824 sprintf(str, "%ld", timeout);
2825 SW_REDIS_COMMAND_ARGV_FILL(str, strlen(str))
2826 }
2827
2828 redis_request(redis, argc, argv, argvlen, return_value);
2829 SW_REDIS_COMMAND_FREE_ARGV
2830 }
2831
PHP_METHOD(swoole_redis_coro,blPop)2832 static PHP_METHOD(swoole_redis_coro, blPop) {
2833 int argc = ZEND_NUM_ARGS();
2834 SW_REDIS_COMMAND_CHECK
2835 SW_REDIS_COMMAND_ALLOC_ARGS_ARR
2836 if (zend_get_parameters_array(ht, argc, z_args) == FAILURE || argc < 1) {
2837 efree(z_args);
2838 return;
2839 }
2840
2841 zend_bool single_array = 0;
2842 if (argc == 2 && SW_REDIS_COMMAND_ARGS_TYPE(z_args[0]) == IS_ARRAY) {
2843 argc = zend_hash_num_elements(SW_REDIS_COMMAND_ARGS_ARRVAL(z_args[0])) + 2;
2844 single_array = 1;
2845 } else {
2846 argc += 1;
2847 }
2848 int i = 0;
2849 SW_REDIS_COMMAND_ALLOC_ARGV
2850 SW_REDIS_COMMAND_ARGV_FILL("BLPOP", 5)
2851 if (single_array) {
2852 zval *value;
2853 SW_HASHTABLE_FOREACH_START(SW_REDIS_COMMAND_ARGS_ARRVAL(z_args[0]), value)
2854 zend_string *convert_str = zval_get_string(value);
2855 SW_REDIS_COMMAND_ARGV_FILL(ZSTR_VAL(convert_str), ZSTR_LEN(convert_str))
2856 zend_string_release(convert_str);
2857 SW_HASHTABLE_FOREACH_END();
2858 zend_string *convert_str = zval_get_string(&z_args[1]);
2859 SW_REDIS_COMMAND_ARGV_FILL(ZSTR_VAL(convert_str), ZSTR_LEN(convert_str))
2860 zend_string_release(convert_str);
2861 } else {
2862 int j;
2863 for (j = 0; j < argc - 1; ++j) {
2864 zend_string *convert_str = zval_get_string(&z_args[j]);
2865 SW_REDIS_COMMAND_ARGV_FILL(ZSTR_VAL(convert_str), ZSTR_LEN(convert_str))
2866 zend_string_release(convert_str);
2867 }
2868 }
2869 efree(z_args);
2870
2871 redis_request(redis, argc, argv, argvlen, return_value);
2872 SW_REDIS_COMMAND_FREE_ARGV
2873 }
2874
PHP_METHOD(swoole_redis_coro,brPop)2875 static PHP_METHOD(swoole_redis_coro, brPop) {
2876 int argc = ZEND_NUM_ARGS();
2877 SW_REDIS_COMMAND_CHECK
2878 SW_REDIS_COMMAND_ALLOC_ARGS_ARR
2879 if (zend_get_parameters_array(ht, argc, z_args) == FAILURE || argc < 1) {
2880 efree(z_args);
2881 return;
2882 }
2883
2884 zend_bool single_array = 0;
2885 if (argc == 2 && SW_REDIS_COMMAND_ARGS_TYPE(z_args[0]) == IS_ARRAY) {
2886 argc = zend_hash_num_elements(SW_REDIS_COMMAND_ARGS_ARRVAL(z_args[0])) + 2;
2887 single_array = 1;
2888 } else {
2889 argc += 1;
2890 }
2891 int i = 0;
2892 SW_REDIS_COMMAND_ALLOC_ARGV
2893 SW_REDIS_COMMAND_ARGV_FILL("BRPOP", 5)
2894 if (single_array) {
2895 zval *value;
2896 SW_HASHTABLE_FOREACH_START(SW_REDIS_COMMAND_ARGS_ARRVAL(z_args[0]), value)
2897 zend_string *convert_str = zval_get_string(value);
2898 SW_REDIS_COMMAND_ARGV_FILL(ZSTR_VAL(convert_str), ZSTR_LEN(convert_str))
2899 zend_string_release(convert_str);
2900 SW_HASHTABLE_FOREACH_END();
2901 zend_string *convert_str = zval_get_string(&z_args[1]);
2902 SW_REDIS_COMMAND_ARGV_FILL(ZSTR_VAL(convert_str), ZSTR_LEN(convert_str))
2903 zend_string_release(convert_str);
2904 } else {
2905 int j;
2906 for (j = 0; j < argc - 1; ++j) {
2907 zend_string *convert_str = zval_get_string(&z_args[j]);
2908 SW_REDIS_COMMAND_ARGV_FILL(ZSTR_VAL(convert_str), ZSTR_LEN(convert_str))
2909 zend_string_release(convert_str);
2910 }
2911 }
2912 efree(z_args);
2913
2914 redis_request(redis, argc, argv, argvlen, return_value);
2915 SW_REDIS_COMMAND_FREE_ARGV
2916 }
2917
PHP_METHOD(swoole_redis_coro,rPop)2918 static PHP_METHOD(swoole_redis_coro, rPop) {
2919 sw_redis_command_key(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("RPOP"));
2920 }
2921
PHP_METHOD(swoole_redis_coro,lSize)2922 static PHP_METHOD(swoole_redis_coro, lSize) {
2923 sw_redis_command_key(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("LLEN"));
2924 }
2925
PHP_METHOD(swoole_redis_coro,sSize)2926 static PHP_METHOD(swoole_redis_coro, sSize) {
2927 sw_redis_command_key(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("SCARD"));
2928 }
2929
PHP_METHOD(swoole_redis_coro,sPop)2930 static PHP_METHOD(swoole_redis_coro, sPop) {
2931 sw_redis_command_key(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("SPOP"));
2932 }
2933
PHP_METHOD(swoole_redis_coro,sMembers)2934 static PHP_METHOD(swoole_redis_coro, sMembers) {
2935 sw_redis_command_key(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("SMEMBERS"));
2936 }
2937
PHP_METHOD(swoole_redis_coro,sRandMember)2938 static PHP_METHOD(swoole_redis_coro, sRandMember) {
2939 char *key;
2940 size_t key_len;
2941 zend_long count = 0;
2942
2943 if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|l", &key, &key_len, &count) == FAILURE) {
2944 RETURN_FALSE;
2945 }
2946 SW_REDIS_COMMAND_CHECK
2947
2948 int i = 0, argc, buf_len;
2949 char buf[32];
2950 argc = ZEND_NUM_ARGS() == 2 ? 3 : 2;
2951 SW_REDIS_COMMAND_ALLOC_ARGV
2952 SW_REDIS_COMMAND_ARGV_FILL("SRANDMEMBER", 11);
2953 SW_REDIS_COMMAND_ARGV_FILL(key, key_len);
2954 if (argc == 3) {
2955 buf_len = sw_snprintf(buf, sizeof(buf), "%" PRId64 "", count);
2956 SW_REDIS_COMMAND_ARGV_FILL((char *) buf, buf_len);
2957 }
2958 redis_request(redis, argc, argv, argvlen, return_value);
2959 SW_REDIS_COMMAND_FREE_ARGV
2960 }
2961
PHP_METHOD(swoole_redis_coro,persist)2962 static PHP_METHOD(swoole_redis_coro, persist) {
2963 sw_redis_command_key(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("PERSIST"));
2964 }
2965
PHP_METHOD(swoole_redis_coro,ttl)2966 static PHP_METHOD(swoole_redis_coro, ttl) {
2967 sw_redis_command_key(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("TTL"));
2968 }
2969
PHP_METHOD(swoole_redis_coro,pttl)2970 static PHP_METHOD(swoole_redis_coro, pttl) {
2971 sw_redis_command_key(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("PTTL"));
2972 }
2973
PHP_METHOD(swoole_redis_coro,zCard)2974 static PHP_METHOD(swoole_redis_coro, zCard) {
2975 sw_redis_command_key(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("ZCARD"));
2976 }
2977
PHP_METHOD(swoole_redis_coro,hLen)2978 static PHP_METHOD(swoole_redis_coro, hLen) {
2979 sw_redis_command_key(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("HLEN"));
2980 }
2981
PHP_METHOD(swoole_redis_coro,hKeys)2982 static PHP_METHOD(swoole_redis_coro, hKeys) {
2983 sw_redis_command_key(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("HKEYS"));
2984 }
2985
PHP_METHOD(swoole_redis_coro,hVals)2986 static PHP_METHOD(swoole_redis_coro, hVals) {
2987 sw_redis_command_key(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("HVALS"));
2988 }
2989
PHP_METHOD(swoole_redis_coro,hGetAll)2990 static PHP_METHOD(swoole_redis_coro, hGetAll) {
2991 sw_redis_command_key(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("HGETALL"));
2992 }
2993
PHP_METHOD(swoole_redis_coro,renameKey)2994 static PHP_METHOD(swoole_redis_coro, renameKey) {
2995 sw_redis_command_key_key(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("RENAME"));
2996 }
2997
PHP_METHOD(swoole_redis_coro,renameNx)2998 static PHP_METHOD(swoole_redis_coro, renameNx) {
2999 sw_redis_command_key_key(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("RENAMENX"));
3000 }
3001
PHP_METHOD(swoole_redis_coro,rpoplpush)3002 static PHP_METHOD(swoole_redis_coro, rpoplpush) {
3003 sw_redis_command_key_key(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("RPOPLPUSH"));
3004 }
3005
PHP_METHOD(swoole_redis_coro,randomKey)3006 static PHP_METHOD(swoole_redis_coro, randomKey) {
3007 sw_redis_command_empty(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("RANDOMKEY"));
3008 }
3009
PHP_METHOD(swoole_redis_coro,unwatch)3010 static PHP_METHOD(swoole_redis_coro, unwatch) {
3011 sw_redis_command_empty(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("UNWATCH"));
3012 }
3013
PHP_METHOD(swoole_redis_coro,pfadd)3014 static PHP_METHOD(swoole_redis_coro, pfadd) {
3015 char *key;
3016 size_t key_len, argc;
3017 zval *z_arr;
3018
3019 if (zend_parse_parameters(ZEND_NUM_ARGS(), "sa", &key, &key_len, &z_arr) == FAILURE) {
3020 return;
3021 }
3022 if ((argc = zend_hash_num_elements(Z_ARRVAL_P(z_arr))) == 0) {
3023 RETURN_FALSE;
3024 }
3025 SW_REDIS_COMMAND_CHECK
3026 int i = 0;
3027 argc = argc + 2;
3028 zval *value;
3029 SW_REDIS_COMMAND_ALLOC_ARGV
3030 SW_REDIS_COMMAND_ARGV_FILL("PFADD", 5)
3031 SW_REDIS_COMMAND_ARGV_FILL(key, key_len)
3032 SW_HASHTABLE_FOREACH_START(Z_ARRVAL_P(z_arr), value) {
3033 zend_string *convert_str = zval_get_string(value);
3034 SW_REDIS_COMMAND_ARGV_FILL(ZSTR_VAL(convert_str), ZSTR_LEN(convert_str));
3035 zend_string_release(convert_str);
3036 }
3037 SW_HASHTABLE_FOREACH_END()
3038
3039 redis_request(redis, argc, argv, argvlen, return_value);
3040 SW_REDIS_COMMAND_FREE_ARGV
3041 }
3042
PHP_METHOD(swoole_redis_coro,pfcount)3043 static PHP_METHOD(swoole_redis_coro, pfcount) {
3044 int argc = ZEND_NUM_ARGS();
3045 SW_REDIS_COMMAND_CHECK
3046 SW_REDIS_COMMAND_ALLOC_ARGS_ARR
3047 if (zend_get_parameters_array(ht, argc, z_args) == FAILURE || argc != 1) {
3048 efree(z_args);
3049 RETURN_FALSE;
3050 }
3051
3052 zend_bool single_array = 0;
3053 if (SW_REDIS_COMMAND_ARGS_TYPE(z_args[0]) == IS_ARRAY) {
3054 argc = zend_hash_num_elements(SW_REDIS_COMMAND_ARGS_ARRVAL(z_args[0]));
3055 single_array = 1;
3056 }
3057
3058 argc += 1;
3059 int i = 0;
3060 SW_REDIS_COMMAND_ALLOC_ARGV
3061 SW_REDIS_COMMAND_ARGV_FILL("PFCOUNT", 7)
3062 if (single_array) {
3063 zval *value;
3064 SW_HASHTABLE_FOREACH_START(SW_REDIS_COMMAND_ARGS_ARRVAL(z_args[0]), value)
3065 zend_string *convert_str = zval_get_string(value);
3066 SW_REDIS_COMMAND_ARGV_FILL(ZSTR_VAL(convert_str), ZSTR_LEN(convert_str))
3067 zend_string_release(convert_str);
3068 SW_HASHTABLE_FOREACH_END()
3069 } else {
3070 zend_string *convert_str = zval_get_string(&z_args[0]);
3071 SW_REDIS_COMMAND_ARGV_FILL(ZSTR_VAL(convert_str), ZSTR_LEN(convert_str))
3072 zend_string_release(convert_str);
3073 }
3074 efree(z_args);
3075
3076 redis_request(redis, argc, argv, argvlen, return_value);
3077 SW_REDIS_COMMAND_FREE_ARGV
3078 }
3079
PHP_METHOD(swoole_redis_coro,pfmerge)3080 static PHP_METHOD(swoole_redis_coro, pfmerge) {
3081 char *key;
3082 size_t key_len, argc;
3083 zval *z_arr;
3084
3085 if (zend_parse_parameters(ZEND_NUM_ARGS(), "sa", &key, &key_len, &z_arr) == FAILURE) {
3086 RETURN_FALSE;
3087 }
3088 if ((argc = zend_hash_num_elements(Z_ARRVAL_P(z_arr))) == 0) {
3089 RETURN_FALSE;
3090 }
3091 SW_REDIS_COMMAND_CHECK
3092 int i = 0;
3093 argc = argc + 2;
3094 zval *value;
3095 SW_REDIS_COMMAND_ALLOC_ARGV
3096 SW_REDIS_COMMAND_ARGV_FILL("PFMERGE", 7)
3097 SW_REDIS_COMMAND_ARGV_FILL(key, key_len)
3098 SW_HASHTABLE_FOREACH_START(Z_ARRVAL_P(z_arr), value) {
3099 zend_string *convert_str = zval_get_string(value);
3100 SW_REDIS_COMMAND_ARGV_FILL(ZSTR_VAL(convert_str), ZSTR_LEN(convert_str));
3101 zend_string_release(convert_str);
3102 }
3103 SW_HASHTABLE_FOREACH_END()
3104
3105 redis_request(redis, argc, argv, argvlen, return_value);
3106 SW_REDIS_COMMAND_FREE_ARGV
3107 }
3108
PHP_METHOD(swoole_redis_coro,ping)3109 static PHP_METHOD(swoole_redis_coro, ping) {
3110 sw_redis_command_empty(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("PING"));
3111 }
3112
PHP_METHOD(swoole_redis_coro,auth)3113 static PHP_METHOD(swoole_redis_coro, auth) {
3114 char *pw;
3115 size_t pw_len;
3116 if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &pw, &pw_len) == FAILURE) {
3117 RETURN_FALSE;
3118 }
3119
3120 SW_REDIS_COMMAND_CHECK
3121 zval *zsetting = sw_zend_read_and_convert_property_array(swoole_redis_coro_ce, ZEND_THIS, ZEND_STRL("setting"), 0);
3122 add_assoc_stringl(zsetting, "password", pw, pw_len);
3123 RETURN_BOOL(redis_auth(redis, pw, pw_len));
3124 }
3125
PHP_METHOD(swoole_redis_coro,save)3126 static PHP_METHOD(swoole_redis_coro, save) {
3127 sw_redis_command_empty(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("SAVE"));
3128 }
3129
PHP_METHOD(swoole_redis_coro,bgSave)3130 static PHP_METHOD(swoole_redis_coro, bgSave) {
3131 sw_redis_command_empty(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("BGSAVE"));
3132 }
3133
PHP_METHOD(swoole_redis_coro,lastSave)3134 static PHP_METHOD(swoole_redis_coro, lastSave) {
3135 sw_redis_command_empty(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("LASTSAVE"));
3136 }
3137
PHP_METHOD(swoole_redis_coro,flushDB)3138 static PHP_METHOD(swoole_redis_coro, flushDB) {
3139 sw_redis_command_empty(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("FLUSHDB"));
3140 }
3141
PHP_METHOD(swoole_redis_coro,flushAll)3142 static PHP_METHOD(swoole_redis_coro, flushAll) {
3143 sw_redis_command_empty(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("FLUSHALL"));
3144 }
3145
PHP_METHOD(swoole_redis_coro,dbSize)3146 static PHP_METHOD(swoole_redis_coro, dbSize) {
3147 sw_redis_command_empty(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("DBSIZE"));
3148 }
3149
PHP_METHOD(swoole_redis_coro,bgrewriteaof)3150 static PHP_METHOD(swoole_redis_coro, bgrewriteaof) {
3151 sw_redis_command_empty(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("BGREWRITEAOF"));
3152 }
3153
PHP_METHOD(swoole_redis_coro,time)3154 static PHP_METHOD(swoole_redis_coro, time) {
3155 sw_redis_command_empty(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("TIME"));
3156 }
3157
PHP_METHOD(swoole_redis_coro,role)3158 static PHP_METHOD(swoole_redis_coro, role) {
3159 sw_redis_command_empty(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("ROLE"));
3160 }
3161
PHP_METHOD(swoole_redis_coro,setRange)3162 static PHP_METHOD(swoole_redis_coro, setRange) {
3163 sw_redis_command_key_long_str(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("SETRANGE"));
3164 }
3165
PHP_METHOD(swoole_redis_coro,setNx)3166 static PHP_METHOD(swoole_redis_coro, setNx) {
3167 sw_redis_command_key_val(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("SETNX"));
3168 }
3169
PHP_METHOD(swoole_redis_coro,getSet)3170 static PHP_METHOD(swoole_redis_coro, getSet) {
3171 sw_redis_command_key_val(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("GETSET"));
3172 }
3173
PHP_METHOD(swoole_redis_coro,append)3174 static PHP_METHOD(swoole_redis_coro, append) {
3175 sw_redis_command_key_val(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("APPEND"));
3176 }
3177
PHP_METHOD(swoole_redis_coro,lPushx)3178 static PHP_METHOD(swoole_redis_coro, lPushx) {
3179 sw_redis_command_key_val(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("LPUSHX"));
3180 }
3181
PHP_METHOD(swoole_redis_coro,lPush)3182 static PHP_METHOD(swoole_redis_coro, lPush) {
3183 sw_redis_command_key_var_val(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("LPUSH"));
3184 }
3185
PHP_METHOD(swoole_redis_coro,rPush)3186 static PHP_METHOD(swoole_redis_coro, rPush) {
3187 sw_redis_command_key_var_val(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("RPUSH"));
3188 }
3189
PHP_METHOD(swoole_redis_coro,rPushx)3190 static PHP_METHOD(swoole_redis_coro, rPushx) {
3191 sw_redis_command_key_val(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("RPUSHX"));
3192 }
3193
PHP_METHOD(swoole_redis_coro,sContains)3194 static PHP_METHOD(swoole_redis_coro, sContains) {
3195 sw_redis_command_key_val(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("SISMEMBER"));
3196 }
3197
PHP_METHOD(swoole_redis_coro,zRange)3198 static PHP_METHOD(swoole_redis_coro, zRange) {
3199 char *key;
3200 size_t key_len;
3201 zend_long start, end;
3202 zend_bool ws = 0;
3203
3204 if (zend_parse_parameters(ZEND_NUM_ARGS(), "sll|b", &key, &key_len, &start, &end, &ws) == FAILURE) {
3205 RETURN_FALSE;
3206 }
3207 SW_REDIS_COMMAND_CHECK
3208
3209 int i = 0, argc;
3210 argc = ZEND_NUM_ARGS() + 1;
3211 SW_REDIS_COMMAND_ALLOC_ARGV
3212 SW_REDIS_COMMAND_ARGV_FILL("ZRANGE", 6)
3213 SW_REDIS_COMMAND_ARGV_FILL(key, key_len)
3214 char buf[32];
3215 size_t buf_len;
3216 buf_len = sw_snprintf(buf, sizeof(buf), "%" PRId64 "", start);
3217 SW_REDIS_COMMAND_ARGV_FILL((char *) buf, buf_len)
3218 buf_len = sw_snprintf(buf, sizeof(buf), "%" PRId64 "", end);
3219 SW_REDIS_COMMAND_ARGV_FILL((char *) buf, buf_len)
3220 if (ws) {
3221 SW_REDIS_COMMAND_ARGV_FILL("WITHSCORES", 10)
3222 } else {
3223 argc = 4;
3224 }
3225
3226 redis_request(redis, argc, argv, argvlen, return_value);
3227
3228 if (ws && redis->compatibility_mode && ZVAL_IS_ARRAY(return_value)) {
3229 swoole_redis_handle_assoc_array_result(return_value, true);
3230 }
3231
3232 SW_REDIS_COMMAND_FREE_ARGV
3233 }
3234
PHP_METHOD(swoole_redis_coro,zRevRange)3235 static PHP_METHOD(swoole_redis_coro, zRevRange) {
3236 char *key;
3237 size_t key_len;
3238 zend_long start, end;
3239 zend_bool ws = 0;
3240
3241 if (zend_parse_parameters(ZEND_NUM_ARGS(), "sll|b", &key, &key_len, &start, &end, &ws) == FAILURE) {
3242 RETURN_FALSE;
3243 }
3244 SW_REDIS_COMMAND_CHECK
3245
3246 int i = 0, argc;
3247 argc = ZEND_NUM_ARGS() + 1;
3248 SW_REDIS_COMMAND_ALLOC_ARGV
3249 SW_REDIS_COMMAND_ARGV_FILL("ZREVRANGE", 9)
3250 SW_REDIS_COMMAND_ARGV_FILL(key, key_len)
3251 char buf[32];
3252 size_t buf_len;
3253 buf_len = sw_snprintf(buf, sizeof(buf), "%" PRId64 "", start);
3254 SW_REDIS_COMMAND_ARGV_FILL((char *) buf, buf_len)
3255 buf_len = sw_snprintf(buf, sizeof(buf), "%" PRId64 "", end);
3256 SW_REDIS_COMMAND_ARGV_FILL((char *) buf, buf_len)
3257 if (ws) {
3258 SW_REDIS_COMMAND_ARGV_FILL("WITHSCORES", 10)
3259 } else {
3260 argc = 4;
3261 }
3262
3263 redis_request(redis, argc, argv, argvlen, return_value);
3264
3265 if (ws && redis->compatibility_mode && ZVAL_IS_ARRAY(return_value)) {
3266 swoole_redis_handle_assoc_array_result(return_value, true);
3267 }
3268
3269 SW_REDIS_COMMAND_FREE_ARGV
3270 }
3271
PHP_METHOD(swoole_redis_coro,zUnion)3272 static PHP_METHOD(swoole_redis_coro, zUnion) {
3273 char *key, *agg_op;
3274 size_t key_len;
3275 zval *z_keys, *z_weights = nullptr;
3276 HashTable *ht_keys, *ht_weights = nullptr;
3277 size_t argc = 2, agg_op_len = 0, keys_count;
3278
3279 if (zend_parse_parameters(ZEND_NUM_ARGS(), "sa|a!s", &key, &key_len, &z_keys, &z_weights, &agg_op, &agg_op_len) ==
3280 FAILURE) {
3281 RETURN_FALSE;
3282 }
3283
3284 ht_keys = Z_ARRVAL_P(z_keys);
3285
3286 if ((keys_count = zend_hash_num_elements(ht_keys)) == 0) {
3287 RETURN_FALSE;
3288 } else {
3289 argc += keys_count + 1;
3290 }
3291
3292 if (z_weights != nullptr) {
3293 ht_weights = Z_ARRVAL_P(z_weights);
3294 if (zend_hash_num_elements(ht_weights) != keys_count) {
3295 zend_update_property_long(
3296 swoole_redis_coro_ce, SW_Z8_OBJ_P(ZEND_THIS), ZEND_STRL("errType"), SW_REDIS_ERR_OTHER);
3297 zend_update_property_long(swoole_redis_coro_ce,
3298 SW_Z8_OBJ_P(ZEND_THIS),
3299 ZEND_STRL("errCode"),
3300 sw_redis_convert_err(SW_REDIS_ERR_OTHER));
3301 zend_update_property_string(swoole_redis_coro_ce,
3302 SW_Z8_OBJ_P(ZEND_THIS),
3303 ZEND_STRL("errMsg"),
3304 "WEIGHTS and keys array should be the same size!");
3305 RETURN_FALSE;
3306 }
3307 argc += keys_count + 1;
3308 }
3309
3310 // AGGREGATE option
3311 if (agg_op_len != 0) {
3312 if (strncasecmp(agg_op, "SUM", sizeof("SUM")) && strncasecmp(agg_op, "MIN", sizeof("MIN")) &&
3313 strncasecmp(agg_op, "MAX", sizeof("MAX"))) {
3314 zend_update_property_long(
3315 swoole_redis_coro_ce, SW_Z8_OBJ_P(ZEND_THIS), ZEND_STRL("errType"), SW_REDIS_ERR_OTHER);
3316 zend_update_property_long(swoole_redis_coro_ce,
3317 SW_Z8_OBJ_P(ZEND_THIS),
3318 ZEND_STRL("errCode"),
3319 sw_redis_convert_err(SW_REDIS_ERR_OTHER));
3320 zend_update_property_string(swoole_redis_coro_ce,
3321 SW_Z8_OBJ_P(ZEND_THIS),
3322 ZEND_STRL("errMsg"),
3323 "Invalid AGGREGATE option provided!");
3324 RETURN_FALSE;
3325 }
3326
3327 // "AGGREGATE" + type
3328 argc += 2;
3329 }
3330 SW_REDIS_COMMAND_CHECK
3331
3332 int i = 0, j;
3333 SW_REDIS_COMMAND_ALLOC_ARGV
3334 SW_REDIS_COMMAND_ARGV_FILL("ZUNIONSTORE", 11)
3335 SW_REDIS_COMMAND_ARGV_FILL(key, key_len)
3336 char buf[32];
3337 size_t buf_len;
3338 buf_len = sprintf(buf, "%zu", keys_count);
3339 SW_REDIS_COMMAND_ARGV_FILL(buf, buf_len)
3340
3341 // Process input keys
3342 zval *value;
3343 SW_HASHTABLE_FOREACH_START(ht_keys, value)
3344 zend_string *convert_str = zval_get_string(value);
3345 SW_REDIS_COMMAND_ARGV_FILL(ZSTR_VAL(convert_str), ZSTR_LEN(convert_str))
3346 zend_string_release(convert_str);
3347 SW_HASHTABLE_FOREACH_END();
3348
3349 // Weights
3350 if (ht_weights != nullptr) {
3351 SW_REDIS_COMMAND_ARGV_FILL("WEIGHTS", 7)
3352
3353 SW_HASHTABLE_FOREACH_START(ht_weights, value)
3354 if (Z_TYPE_P(value) != IS_LONG && Z_TYPE_P(value) != IS_DOUBLE &&
3355 strncasecmp(Z_STRVAL_P(value), "inf", sizeof("inf")) != 0 &&
3356 strncasecmp(Z_STRVAL_P(value), "-inf", sizeof("-inf")) != 0 &&
3357 strncasecmp(Z_STRVAL_P(value), "+inf", sizeof("+inf")) != 0) {
3358 zend_update_property_long(
3359 swoole_redis_coro_ce, SW_Z8_OBJ_P(redis->zobject), ZEND_STRL("errType"), SW_REDIS_ERR_OTHER);
3360 zend_update_property_long(swoole_redis_coro_ce,
3361 SW_Z8_OBJ_P(redis->zobject),
3362 ZEND_STRL("errCode"),
3363 sw_redis_convert_err(SW_REDIS_ERR_OTHER));
3364 zend_update_property_string(swoole_redis_coro_ce,
3365 SW_Z8_OBJ_P(redis->zobject),
3366 ZEND_STRL("errMsg"),
3367 "Weights must be numeric or '-inf','inf','+inf'");
3368 for (j = 0; j < i; j++) {
3369 efree((void *) argv[j]);
3370 }
3371 SW_REDIS_COMMAND_FREE_ARGV
3372 RETURN_FALSE;
3373 }
3374 switch (Z_TYPE_P(value)) {
3375 case IS_LONG:
3376 buf_len = sprintf(buf, ZEND_LONG_FMT, Z_LVAL_P(value));
3377 SW_REDIS_COMMAND_ARGV_FILL(buf, buf_len)
3378 break;
3379 case IS_DOUBLE:
3380 buf_len = sprintf(buf, "%f", Z_DVAL_P(value));
3381 SW_REDIS_COMMAND_ARGV_FILL(buf, buf_len)
3382 break;
3383 case IS_STRING:
3384 SW_REDIS_COMMAND_ARGV_FILL(Z_STRVAL_P(value), Z_STRLEN_P(value))
3385 break;
3386 }
3387 SW_HASHTABLE_FOREACH_END();
3388 }
3389
3390 // AGGREGATE
3391 if (agg_op_len != 0) {
3392 SW_REDIS_COMMAND_ARGV_FILL("AGGREGATE", 9)
3393 SW_REDIS_COMMAND_ARGV_FILL(agg_op, agg_op_len)
3394 }
3395
3396 redis_request(redis, argc, argv, argvlen, return_value);
3397 SW_REDIS_COMMAND_FREE_ARGV
3398 }
3399
PHP_METHOD(swoole_redis_coro,zInter)3400 static PHP_METHOD(swoole_redis_coro, zInter) {
3401 char *key, *agg_op;
3402 size_t key_len;
3403 zval *z_keys, *z_weights = nullptr;
3404 HashTable *ht_keys, *ht_weights = nullptr;
3405 size_t argc = 2, agg_op_len = 0, keys_count;
3406
3407 if (zend_parse_parameters(ZEND_NUM_ARGS(), "sa|a!s", &key, &key_len, &z_keys, &z_weights, &agg_op, &agg_op_len) ==
3408 FAILURE) {
3409 RETURN_FALSE;
3410 }
3411
3412 ht_keys = Z_ARRVAL_P(z_keys);
3413
3414 if ((keys_count = zend_hash_num_elements(ht_keys)) == 0) {
3415 RETURN_FALSE;
3416 } else {
3417 argc += keys_count + 1;
3418 }
3419
3420 if (z_weights != nullptr) {
3421 ht_weights = Z_ARRVAL_P(z_weights);
3422 if (zend_hash_num_elements(ht_weights) != keys_count) {
3423 zend_update_property_long(
3424 swoole_redis_coro_ce, SW_Z8_OBJ_P(ZEND_THIS), ZEND_STRL("errType"), SW_REDIS_ERR_OTHER);
3425 zend_update_property_long(swoole_redis_coro_ce,
3426 SW_Z8_OBJ_P(ZEND_THIS),
3427 ZEND_STRL("errCode"),
3428 sw_redis_convert_err(SW_REDIS_ERR_OTHER));
3429 zend_update_property_string(swoole_redis_coro_ce,
3430 SW_Z8_OBJ_P(ZEND_THIS),
3431 ZEND_STRL("errMsg"),
3432 "WEIGHTS and keys array should be the same size!");
3433 RETURN_FALSE;
3434 }
3435
3436 argc += keys_count + 1;
3437 }
3438
3439 // AGGREGATE option
3440 if (agg_op_len != 0) {
3441 if (strncasecmp(agg_op, "SUM", sizeof("SUM")) && strncasecmp(agg_op, "MIN", sizeof("MIN")) &&
3442 strncasecmp(agg_op, "MAX", sizeof("MAX"))) {
3443 zend_update_property_long(
3444 swoole_redis_coro_ce, SW_Z8_OBJ_P(ZEND_THIS), ZEND_STRL("errType"), SW_REDIS_ERR_OTHER);
3445 zend_update_property_long(swoole_redis_coro_ce,
3446 SW_Z8_OBJ_P(ZEND_THIS),
3447 ZEND_STRL("errCode"),
3448 sw_redis_convert_err(SW_REDIS_ERR_OTHER));
3449 zend_update_property_string(swoole_redis_coro_ce,
3450 SW_Z8_OBJ_P(ZEND_THIS),
3451 ZEND_STRL("errMsg"),
3452 "Invalid AGGREGATE option provided!");
3453 RETURN_FALSE;
3454 }
3455
3456 // "AGGREGATE" + type
3457 argc += 2;
3458 }
3459 SW_REDIS_COMMAND_CHECK
3460
3461 int i = 0, j;
3462 SW_REDIS_COMMAND_ALLOC_ARGV
3463 SW_REDIS_COMMAND_ARGV_FILL("ZINTERSTORE", 11)
3464 SW_REDIS_COMMAND_ARGV_FILL(key, key_len)
3465 char buf[32];
3466 size_t buf_len;
3467 buf_len = sprintf(buf, "%zu", keys_count);
3468 SW_REDIS_COMMAND_ARGV_FILL(buf, buf_len)
3469
3470 // Process input keys
3471 zval *value;
3472 SW_HASHTABLE_FOREACH_START(ht_keys, value)
3473 zend_string *convert_str = zval_get_string(value);
3474 SW_REDIS_COMMAND_ARGV_FILL(ZSTR_VAL(convert_str), ZSTR_LEN(convert_str))
3475 zend_string_release(convert_str);
3476 SW_HASHTABLE_FOREACH_END();
3477
3478 // Weights
3479 if (ht_weights != nullptr) {
3480 SW_REDIS_COMMAND_ARGV_FILL("WEIGHTS", 7)
3481
3482 SW_HASHTABLE_FOREACH_START(ht_weights, value)
3483 if (Z_TYPE_P(value) != IS_LONG && Z_TYPE_P(value) != IS_DOUBLE &&
3484 strncasecmp(Z_STRVAL_P(value), "inf", sizeof("inf")) != 0 &&
3485 strncasecmp(Z_STRVAL_P(value), "-inf", sizeof("-inf")) != 0 &&
3486 strncasecmp(Z_STRVAL_P(value), "+inf", sizeof("+inf")) != 0) {
3487 zend_update_property_long(
3488 swoole_redis_coro_ce, SW_Z8_OBJ_P(ZEND_THIS), ZEND_STRL("errType"), SW_REDIS_ERR_OTHER);
3489 zend_update_property_long(swoole_redis_coro_ce,
3490 SW_Z8_OBJ_P(ZEND_THIS),
3491 ZEND_STRL("errCode"),
3492 sw_redis_convert_err(SW_REDIS_ERR_OTHER));
3493 zend_update_property_string(swoole_redis_coro_ce,
3494 SW_Z8_OBJ_P(ZEND_THIS),
3495 ZEND_STRL("errMsg"),
3496 "Weights must be numeric or '-inf','inf','+inf'");
3497 for (j = 0; j < i; j++) {
3498 efree((void *) argv[j]);
3499 }
3500 SW_REDIS_COMMAND_FREE_ARGV
3501 RETURN_FALSE;
3502 }
3503 switch (Z_TYPE_P(value)) {
3504 case IS_LONG:
3505 buf_len = sprintf(buf, ZEND_LONG_FMT, Z_LVAL_P(value));
3506 SW_REDIS_COMMAND_ARGV_FILL(buf, buf_len)
3507 break;
3508 case IS_DOUBLE:
3509 buf_len = sprintf(buf, "%f", Z_DVAL_P(value));
3510 SW_REDIS_COMMAND_ARGV_FILL(buf, buf_len)
3511 break;
3512 case IS_STRING:
3513 SW_REDIS_COMMAND_ARGV_FILL(Z_STRVAL_P(value), Z_STRLEN_P(value))
3514 break;
3515 }
3516 SW_HASHTABLE_FOREACH_END();
3517 }
3518
3519 // AGGREGATE
3520 if (agg_op_len != 0) {
3521 SW_REDIS_COMMAND_ARGV_FILL("AGGREGATE", 9)
3522 SW_REDIS_COMMAND_ARGV_FILL(agg_op, agg_op_len)
3523 }
3524
3525 redis_request(redis, argc, argv, argvlen, return_value);
3526 SW_REDIS_COMMAND_FREE_ARGV
3527 }
3528
PHP_METHOD(swoole_redis_coro,zRangeByLex)3529 static PHP_METHOD(swoole_redis_coro, zRangeByLex) {
3530 char *key, *min, *max;
3531 size_t key_len, min_len, max_len;
3532 zend_long offset = 0, count = 0;
3533 size_t argc = ZEND_NUM_ARGS();
3534
3535 /* We need either 3 or 5 arguments for this to be valid */
3536 if (argc != 3 && argc != 5) {
3537 zend_update_property_long(
3538 swoole_redis_coro_ce, SW_Z8_OBJ_P(ZEND_THIS), ZEND_STRL("errType"), SW_REDIS_ERR_OTHER);
3539 zend_update_property_long(swoole_redis_coro_ce,
3540 SW_Z8_OBJ_P(ZEND_THIS),
3541 ZEND_STRL("errCode"),
3542 sw_redis_convert_err(SW_REDIS_ERR_OTHER));
3543 zend_update_property_string(
3544 swoole_redis_coro_ce, SW_Z8_OBJ_P(ZEND_THIS), ZEND_STRL("errMsg"), "Must pass either 3 or 5 arguments");
3545 RETURN_FALSE;
3546 }
3547
3548 if (zend_parse_parameters(argc, "sss|ll", &key, &key_len, &min, &min_len, &max, &max_len, &offset, &count) ==
3549 FAILURE) {
3550 RETURN_FALSE;
3551 }
3552
3553 /* min and max must start with '(' or '[', or be either '-' or '+' */
3554 if (min_len < 1 || max_len < 1 ||
3555 (min[0] != '(' && min[0] != '[' && (min[0] != '-' || min_len > 1) && (min[0] != '+' || min_len > 1)) ||
3556 (max[0] != '(' && max[0] != '[' && (max[0] != '-' || max_len > 1) && (max[0] != '+' || max_len > 1))) {
3557 zend_update_property_long(
3558 swoole_redis_coro_ce, SW_Z8_OBJ_P(ZEND_THIS), ZEND_STRL("errType"), SW_REDIS_ERR_OTHER);
3559 zend_update_property_long(swoole_redis_coro_ce,
3560 SW_Z8_OBJ_P(ZEND_THIS),
3561 ZEND_STRL("errCode"),
3562 sw_redis_convert_err(SW_REDIS_ERR_OTHER));
3563 zend_update_property_string(swoole_redis_coro_ce,
3564 SW_Z8_OBJ_P(ZEND_THIS),
3565 ZEND_STRL("errMsg"),
3566 "min and max arguments must start with '[' or '('");
3567 RETURN_FALSE;
3568 }
3569 SW_REDIS_COMMAND_CHECK
3570
3571 argc = argc == 3 ? 4 : 7;
3572 int i = 0;
3573 SW_REDIS_COMMAND_ALLOC_ARGV
3574 SW_REDIS_COMMAND_ARGV_FILL("ZRANGEBYLEX", 11)
3575 SW_REDIS_COMMAND_ARGV_FILL(key, key_len)
3576 SW_REDIS_COMMAND_ARGV_FILL(min, min_len)
3577 SW_REDIS_COMMAND_ARGV_FILL(max, max_len)
3578 if (argc == 7) {
3579 SW_REDIS_COMMAND_ARGV_FILL("LIMIT", 5)
3580 char buf[32];
3581 size_t buf_len;
3582 buf_len = sprintf(buf, ZEND_LONG_FMT, offset);
3583 SW_REDIS_COMMAND_ARGV_FILL(buf, buf_len)
3584 buf_len = sprintf(buf, ZEND_LONG_FMT, count);
3585 SW_REDIS_COMMAND_ARGV_FILL(buf, buf_len)
3586 }
3587
3588 redis_request(redis, argc, argv, argvlen, return_value);
3589 SW_REDIS_COMMAND_FREE_ARGV
3590 }
3591
PHP_METHOD(swoole_redis_coro,zRevRangeByLex)3592 static PHP_METHOD(swoole_redis_coro, zRevRangeByLex) {
3593 char *key, *min, *max;
3594 size_t key_len, min_len, max_len;
3595 zend_long offset = 0, count = 0;
3596 int argc = ZEND_NUM_ARGS();
3597
3598 /* We need either 3 or 5 arguments for this to be valid */
3599 if (argc != 3 && argc != 5) {
3600 zend_update_property_long(
3601 swoole_redis_coro_ce, SW_Z8_OBJ_P(ZEND_THIS), ZEND_STRL("errType"), SW_REDIS_ERR_OTHER);
3602 zend_update_property_long(swoole_redis_coro_ce,
3603 SW_Z8_OBJ_P(ZEND_THIS),
3604 ZEND_STRL("errCode"),
3605 sw_redis_convert_err(SW_REDIS_ERR_OTHER));
3606 zend_update_property_string(
3607 swoole_redis_coro_ce, SW_Z8_OBJ_P(ZEND_THIS), ZEND_STRL("errMsg"), "Must pass either 3 or 5 arguments");
3608 RETURN_FALSE;
3609 }
3610
3611 if (zend_parse_parameters(argc, "sss|ll", &key, &key_len, &min, &min_len, &max, &max_len, &offset, &count) ==
3612 FAILURE) {
3613 RETURN_FALSE;
3614 }
3615
3616 /* min and max must start with '(' or '[', or be either '-' or '+' */
3617 if (min_len < 1 || max_len < 1 ||
3618 (min[0] != '(' && min[0] != '[' && (min[0] != '-' || min_len > 1) && (min[0] != '+' || min_len > 1)) ||
3619 (max[0] != '(' && max[0] != '[' && (max[0] != '-' || max_len > 1) && (max[0] != '+' || max_len > 1))) {
3620 zend_update_property_long(
3621 swoole_redis_coro_ce, SW_Z8_OBJ_P(ZEND_THIS), ZEND_STRL("errType"), SW_REDIS_ERR_OTHER);
3622 zend_update_property_long(swoole_redis_coro_ce,
3623 SW_Z8_OBJ_P(ZEND_THIS),
3624 ZEND_STRL("errCode"),
3625 sw_redis_convert_err(SW_REDIS_ERR_OTHER));
3626 zend_update_property_string(swoole_redis_coro_ce,
3627 SW_Z8_OBJ_P(ZEND_THIS),
3628 ZEND_STRL("errMsg"),
3629 "min and max arguments must start with '[' or '('");
3630 RETURN_FALSE;
3631 }
3632 SW_REDIS_COMMAND_CHECK
3633
3634 argc = argc == 3 ? 4 : 7;
3635 int i = 0;
3636 SW_REDIS_COMMAND_ALLOC_ARGV
3637 SW_REDIS_COMMAND_ARGV_FILL("ZREVRANGEBYLEX", 14)
3638 SW_REDIS_COMMAND_ARGV_FILL(key, key_len)
3639 SW_REDIS_COMMAND_ARGV_FILL(min, min_len)
3640 SW_REDIS_COMMAND_ARGV_FILL(max, max_len)
3641 if (argc == 7) {
3642 SW_REDIS_COMMAND_ARGV_FILL("LIMIT", 5)
3643 char buf[32];
3644 size_t buf_len;
3645 buf_len = sprintf(buf, ZEND_LONG_FMT, offset);
3646 SW_REDIS_COMMAND_ARGV_FILL(buf, buf_len)
3647 buf_len = sprintf(buf, ZEND_LONG_FMT, count);
3648 SW_REDIS_COMMAND_ARGV_FILL(buf, buf_len)
3649 }
3650
3651 redis_request(redis, argc, argv, argvlen, return_value);
3652 SW_REDIS_COMMAND_FREE_ARGV
3653 }
3654
PHP_METHOD(swoole_redis_coro,zRangeByScore)3655 static PHP_METHOD(swoole_redis_coro, zRangeByScore) {
3656 char *key;
3657 size_t key_len;
3658 char *start, *end;
3659 size_t start_len, end_len;
3660 long limit_low, limit_high;
3661 zval *z_opt = nullptr, *z_ele;
3662 zend_bool withscores = 0, has_limit = 0;
3663 HashTable *ht_opt;
3664
3665 if (zend_parse_parameters(ZEND_NUM_ARGS(), "sss|a", &key, &key_len, &start, &start_len, &end, &end_len, &z_opt) ==
3666 FAILURE) {
3667 RETURN_FALSE;
3668 }
3669 SW_REDIS_COMMAND_CHECK
3670
3671 int argc = 4, i = 0;
3672 // Check for an options array
3673 if (z_opt && ZVAL_IS_ARRAY(z_opt)) {
3674 ht_opt = Z_ARRVAL_P(z_opt);
3675
3676 // Check for WITHSCORES
3677 if ((z_ele = zend_hash_str_find(ht_opt, ZEND_STRL("withscores"))) && Z_TYPE_P(z_ele) == IS_TRUE) {
3678 withscores = 1;
3679 argc++;
3680 }
3681
3682 // LIMIT
3683 if ((z_ele = zend_hash_str_find(ht_opt, ZEND_STRL("limit")))) {
3684 HashTable *ht_limit = Z_ARRVAL_P(z_ele);
3685 zval *z_off, *z_cnt;
3686 z_off = zend_hash_index_find(ht_limit, 0);
3687 z_cnt = zend_hash_index_find(ht_limit, 1);
3688 if (z_off && z_cnt && Z_TYPE_P(z_off) == IS_LONG && Z_TYPE_P(z_cnt) == IS_LONG) {
3689 has_limit = 1;
3690 limit_low = Z_LVAL_P(z_off);
3691 limit_high = Z_LVAL_P(z_cnt);
3692 argc += 3;
3693 }
3694 }
3695 }
3696 SW_REDIS_COMMAND_ALLOC_ARGV
3697 SW_REDIS_COMMAND_ARGV_FILL("ZRANGEBYSCORE", 13)
3698 SW_REDIS_COMMAND_ARGV_FILL(key, key_len)
3699 SW_REDIS_COMMAND_ARGV_FILL(start, start_len)
3700 SW_REDIS_COMMAND_ARGV_FILL(end, end_len)
3701
3702 if (withscores) {
3703 SW_REDIS_COMMAND_ARGV_FILL("WITHSCORES", 10)
3704 }
3705 if (has_limit) {
3706 SW_REDIS_COMMAND_ARGV_FILL("LIMIT", 5)
3707 char buf[32];
3708 size_t buf_len;
3709 buf_len = sprintf(buf, "%ld", limit_low);
3710 SW_REDIS_COMMAND_ARGV_FILL(buf, buf_len)
3711 buf_len = sprintf(buf, "%ld", limit_high);
3712 SW_REDIS_COMMAND_ARGV_FILL(buf, buf_len)
3713 }
3714
3715 redis_request(redis, argc, argv, argvlen, return_value);
3716
3717 if (withscores && redis->compatibility_mode && ZVAL_IS_ARRAY(return_value)) {
3718 swoole_redis_handle_assoc_array_result(return_value, true);
3719 }
3720
3721 SW_REDIS_COMMAND_FREE_ARGV
3722 }
3723
PHP_METHOD(swoole_redis_coro,zRevRangeByScore)3724 static PHP_METHOD(swoole_redis_coro, zRevRangeByScore) {
3725 char *key;
3726 size_t key_len;
3727 char *start, *end;
3728 size_t start_len, end_len;
3729 long limit_low, limit_high;
3730 zval *z_opt = nullptr, *z_ele;
3731 zend_bool withscores = 0, has_limit = 0;
3732 HashTable *ht_opt;
3733
3734 if (zend_parse_parameters(ZEND_NUM_ARGS(), "sss|a", &key, &key_len, &start, &start_len, &end, &end_len, &z_opt) ==
3735 FAILURE) {
3736 RETURN_FALSE;
3737 }
3738 SW_REDIS_COMMAND_CHECK
3739
3740 int argc = 4, i = 0;
3741 // Check for an options array
3742 if (z_opt && ZVAL_IS_ARRAY(z_opt)) {
3743 ht_opt = Z_ARRVAL_P(z_opt);
3744
3745 // Check for WITHSCORES
3746 if ((z_ele = zend_hash_str_find(ht_opt, ZEND_STRL("withscores"))) && Z_TYPE_P(z_ele) == IS_TRUE) {
3747 withscores = 1;
3748 argc++;
3749 }
3750
3751 // LIMIT
3752 if ((z_ele = zend_hash_str_find(ht_opt, ZEND_STRL("limit")))) {
3753 HashTable *ht_limit = Z_ARRVAL_P(z_ele);
3754 zval *z_off, *z_cnt;
3755 z_off = zend_hash_index_find(ht_limit, 0);
3756 z_cnt = zend_hash_index_find(ht_limit, 1);
3757 if (z_off && z_cnt && Z_TYPE_P(z_off) == IS_LONG && Z_TYPE_P(z_cnt) == IS_LONG) {
3758 has_limit = 1;
3759 limit_low = Z_LVAL_P(z_off);
3760 limit_high = Z_LVAL_P(z_cnt);
3761 argc += 3;
3762 }
3763 }
3764 }
3765 SW_REDIS_COMMAND_ALLOC_ARGV
3766 SW_REDIS_COMMAND_ARGV_FILL("ZREVRANGEBYSCORE", 16)
3767 SW_REDIS_COMMAND_ARGV_FILL(key, key_len)
3768 SW_REDIS_COMMAND_ARGV_FILL(start, start_len)
3769 SW_REDIS_COMMAND_ARGV_FILL(end, end_len)
3770
3771 if (withscores) {
3772 SW_REDIS_COMMAND_ARGV_FILL("WITHSCORES", 10)
3773 }
3774 if (has_limit) {
3775 SW_REDIS_COMMAND_ARGV_FILL("LIMIT", 5)
3776 char buf[32];
3777 size_t buf_len;
3778 buf_len = sprintf(buf, "%ld", limit_low);
3779 SW_REDIS_COMMAND_ARGV_FILL(buf, buf_len)
3780 buf_len = sprintf(buf, "%ld", limit_high);
3781 SW_REDIS_COMMAND_ARGV_FILL(buf, buf_len)
3782 }
3783
3784 redis_request(redis, argc, argv, argvlen, return_value);
3785
3786 if (withscores && redis->compatibility_mode && ZVAL_IS_ARRAY(return_value)) {
3787 swoole_redis_handle_assoc_array_result(return_value, true);
3788 }
3789
3790 SW_REDIS_COMMAND_FREE_ARGV
3791 }
3792
PHP_METHOD(swoole_redis_coro,zIncrBy)3793 static PHP_METHOD(swoole_redis_coro, zIncrBy) {
3794 char *key;
3795 size_t key_len;
3796 double incrby;
3797 zval *z_val;
3798
3799 if (zend_parse_parameters(ZEND_NUM_ARGS(), "sdz", &key, &key_len, &incrby, &z_val) == FAILURE) {
3800 RETURN_FALSE;
3801 }
3802
3803 SW_REDIS_COMMAND_CHECK;
3804
3805 int i = 0;
3806 size_t argvlen[4];
3807 char *argv[4];
3808 SW_REDIS_COMMAND_ARGV_FILL("ZINCRBY", 7)
3809 SW_REDIS_COMMAND_ARGV_FILL(key, key_len)
3810 char buf[32];
3811 size_t buf_len;
3812 buf_len = sprintf(buf, "%f", incrby);
3813 SW_REDIS_COMMAND_ARGV_FILL(buf, buf_len)
3814 SW_REDIS_COMMAND_ARGV_FILL_WITH_SERIALIZE(z_val)
3815 redis_request(redis, 4, argv, argvlen, return_value);
3816 }
3817
PHP_METHOD(swoole_redis_coro,zAdd)3818 static PHP_METHOD(swoole_redis_coro, zAdd) {
3819 int argc = ZEND_NUM_ARGS();
3820 SW_REDIS_COMMAND_CHECK
3821 SW_REDIS_COMMAND_ALLOC_ARGS_ARR
3822
3823 if (zend_get_parameters_array(ht, argc, z_args) == FAILURE) {
3824 efree(z_args);
3825 RETURN_FALSE;
3826 }
3827
3828 if (argc > 0) {
3829 convert_to_string(&z_args[0]);
3830 }
3831 if (argc < 3 || SW_REDIS_COMMAND_ARGS_TYPE(z_args[0]) != IS_STRING) {
3832 efree(z_args);
3833 RETURN_FALSE;
3834 }
3835
3836 int i = 0, j, k, valid_params;
3837 valid_params = argc - 1;
3838 argc++;
3839 SW_REDIS_COMMAND_ALLOC_ARGV
3840 SW_REDIS_COMMAND_ARGV_FILL("ZADD", 4)
3841 SW_REDIS_COMMAND_ARGV_FILL(SW_REDIS_COMMAND_ARGS_STRVAL(z_args[0]),
3842 (size_t) SW_REDIS_COMMAND_ARGS_STRLEN(z_args[0]))
3843 k = 1;
3844
3845 if (SW_REDIS_COMMAND_ARGS_TYPE(z_args[k]) == IS_STRING && IS_NX_XX_ARG(SW_REDIS_COMMAND_ARGS_STRVAL(z_args[k]))) {
3846 SW_REDIS_COMMAND_ARGV_FILL(SW_REDIS_COMMAND_ARGS_STRVAL(z_args[k]),
3847 (size_t) SW_REDIS_COMMAND_ARGS_STRLEN(z_args[k]))
3848 k++;
3849 valid_params--;
3850 }
3851
3852 if (SW_REDIS_COMMAND_ARGS_TYPE(z_args[k]) == IS_STRING &&
3853 strncasecmp(SW_REDIS_COMMAND_ARGS_STRVAL(z_args[k]), "CH", 2) == 0) {
3854 SW_REDIS_COMMAND_ARGV_FILL("CH", 2)
3855 k++;
3856 valid_params--;
3857 }
3858
3859 if (SW_REDIS_COMMAND_ARGS_TYPE(z_args[k]) == IS_STRING &&
3860 strncasecmp(SW_REDIS_COMMAND_ARGS_STRVAL(z_args[k]), "INCR", 4) == 0) {
3861 SW_REDIS_COMMAND_ARGV_FILL("INCR", 4)
3862 k++;
3863 valid_params--;
3864 }
3865
3866 if (valid_params % 2 != 0) {
3867 for (i = 0; i < 1 + k; i++) {
3868 efree((void *) argv[i]);
3869 }
3870 SW_REDIS_COMMAND_FREE_ARGV
3871 efree(z_args);
3872 RETURN_FALSE;
3873 }
3874
3875 char buf[32];
3876 size_t buf_len;
3877 for (j = k; j < argc - 1; j += 2) {
3878 buf_len = sw_snprintf(buf, sizeof(buf), "%f", zval_get_double(&z_args[j]));
3879 SW_REDIS_COMMAND_ARGV_FILL((char *) buf, buf_len)
3880 SW_REDIS_COMMAND_ARGV_FILL_WITH_SERIALIZE(SW_REDIS_COMMAND_ARGS_REF(z_args[j + 1]))
3881 }
3882 efree(z_args);
3883
3884 redis_request(redis, argc, argv, argvlen, return_value);
3885 SW_REDIS_COMMAND_FREE_ARGV
3886 }
3887
PHP_METHOD(swoole_redis_coro,zPopMin)3888 static PHP_METHOD(swoole_redis_coro, zPopMin) {
3889 char *key;
3890 size_t key_len;
3891 zend_long count = 0;
3892
3893 if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|l", &key, &key_len, &count) == FAILURE) {
3894 RETURN_FALSE;
3895 }
3896 SW_REDIS_COMMAND_CHECK
3897
3898 int i = 0, argc, buf_len;
3899 char buf[32];
3900 argc = ZEND_NUM_ARGS() == 2 ? 3 : 2;
3901 SW_REDIS_COMMAND_ALLOC_ARGV
3902 SW_REDIS_COMMAND_ARGV_FILL("ZPOPMIN", 7);
3903 SW_REDIS_COMMAND_ARGV_FILL(key, key_len);
3904 if (argc == 3) {
3905 buf_len = sw_snprintf(buf, sizeof(buf), "%" PRId64 "", count);
3906 SW_REDIS_COMMAND_ARGV_FILL((char *) buf, buf_len);
3907 }
3908 redis_request(redis, argc, argv, argvlen, return_value);
3909 SW_REDIS_COMMAND_FREE_ARGV
3910 }
3911
PHP_METHOD(swoole_redis_coro,zPopMax)3912 static PHP_METHOD(swoole_redis_coro, zPopMax) {
3913 char *key;
3914 size_t key_len;
3915 zend_long count = 0;
3916
3917 if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|l", &key, &key_len, &count) == FAILURE) {
3918 RETURN_FALSE;
3919 }
3920 SW_REDIS_COMMAND_CHECK
3921
3922 int i = 0, argc, buf_len;
3923 char buf[32];
3924 argc = ZEND_NUM_ARGS() == 2 ? 3 : 2;
3925 SW_REDIS_COMMAND_ALLOC_ARGV
3926 SW_REDIS_COMMAND_ARGV_FILL("ZPOPMAX", 7);
3927 SW_REDIS_COMMAND_ARGV_FILL(key, key_len);
3928 if (argc == 3) {
3929 buf_len = sw_snprintf(buf, sizeof(buf), "%" PRId64 "", count);
3930 SW_REDIS_COMMAND_ARGV_FILL((char *) buf, buf_len);
3931 }
3932 redis_request(redis, argc, argv, argvlen, return_value);
3933 SW_REDIS_COMMAND_FREE_ARGV
3934 }
3935
PHP_METHOD(swoole_redis_coro,bzPopMin)3936 static PHP_METHOD(swoole_redis_coro, bzPopMin) {
3937 int argc = ZEND_NUM_ARGS();
3938 SW_REDIS_COMMAND_CHECK
3939 SW_REDIS_COMMAND_ALLOC_ARGS_ARR
3940 if (zend_get_parameters_array(ht, argc, z_args) == FAILURE || argc < 1) {
3941 efree(z_args);
3942 return;
3943 }
3944
3945 zend_bool single_array = 0;
3946 if (argc == 2 && SW_REDIS_COMMAND_ARGS_TYPE(z_args[0]) == IS_ARRAY) {
3947 argc = zend_hash_num_elements(SW_REDIS_COMMAND_ARGS_ARRVAL(z_args[0])) + 2;
3948 single_array = 1;
3949 } else {
3950 argc += 1;
3951 }
3952 int i = 0;
3953 SW_REDIS_COMMAND_ALLOC_ARGV
3954 SW_REDIS_COMMAND_ARGV_FILL("BZPOPMIN", 8)
3955 if (single_array) {
3956 zval *value;
3957 SW_HASHTABLE_FOREACH_START(SW_REDIS_COMMAND_ARGS_ARRVAL(z_args[0]), value)
3958 zend_string *convert_str = zval_get_string(value);
3959 SW_REDIS_COMMAND_ARGV_FILL(ZSTR_VAL(convert_str), ZSTR_LEN(convert_str))
3960 zend_string_release(convert_str);
3961 SW_HASHTABLE_FOREACH_END();
3962 zend_string *convert_str = zval_get_string(&z_args[1]);
3963 SW_REDIS_COMMAND_ARGV_FILL(ZSTR_VAL(convert_str), ZSTR_LEN(convert_str))
3964 zend_string_release(convert_str);
3965 } else {
3966 int j;
3967 for (j = 0; j < argc - 1; ++j) {
3968 zend_string *convert_str = zval_get_string(&z_args[j]);
3969 SW_REDIS_COMMAND_ARGV_FILL(ZSTR_VAL(convert_str), ZSTR_LEN(convert_str))
3970 zend_string_release(convert_str);
3971 }
3972 }
3973 efree(z_args);
3974
3975 redis_request(redis, argc, argv, argvlen, return_value);
3976 SW_REDIS_COMMAND_FREE_ARGV
3977 }
3978
PHP_METHOD(swoole_redis_coro,bzPopMax)3979 static PHP_METHOD(swoole_redis_coro, bzPopMax) {
3980 int argc = ZEND_NUM_ARGS();
3981 SW_REDIS_COMMAND_CHECK
3982 SW_REDIS_COMMAND_ALLOC_ARGS_ARR
3983 if (zend_get_parameters_array(ht, argc, z_args) == FAILURE || argc < 1) {
3984 efree(z_args);
3985 return;
3986 }
3987
3988 zend_bool single_array = 0;
3989 if (argc == 2 && SW_REDIS_COMMAND_ARGS_TYPE(z_args[0]) == IS_ARRAY) {
3990 argc = zend_hash_num_elements(SW_REDIS_COMMAND_ARGS_ARRVAL(z_args[0])) + 2;
3991 single_array = 1;
3992 } else {
3993 argc += 1;
3994 }
3995 int i = 0;
3996 SW_REDIS_COMMAND_ALLOC_ARGV
3997 SW_REDIS_COMMAND_ARGV_FILL("BZPOPMAX", 8)
3998 if (single_array) {
3999 zval *value;
4000 SW_HASHTABLE_FOREACH_START(SW_REDIS_COMMAND_ARGS_ARRVAL(z_args[0]), value)
4001 zend_string *convert_str = zval_get_string(value);
4002 SW_REDIS_COMMAND_ARGV_FILL(ZSTR_VAL(convert_str), ZSTR_LEN(convert_str))
4003 zend_string_release(convert_str);
4004 SW_HASHTABLE_FOREACH_END();
4005 zend_string *convert_str = zval_get_string(&z_args[1]);
4006 SW_REDIS_COMMAND_ARGV_FILL(ZSTR_VAL(convert_str), ZSTR_LEN(convert_str))
4007 zend_string_release(convert_str);
4008 } else {
4009 int j;
4010 for (j = 0; j < argc - 1; ++j) {
4011 zend_string *convert_str = zval_get_string(&z_args[j]);
4012 SW_REDIS_COMMAND_ARGV_FILL(ZSTR_VAL(convert_str), ZSTR_LEN(convert_str))
4013 zend_string_release(convert_str);
4014 }
4015 }
4016 efree(z_args);
4017
4018 redis_request(redis, argc, argv, argvlen, return_value);
4019 SW_REDIS_COMMAND_FREE_ARGV
4020 }
4021
PHP_METHOD(swoole_redis_coro,zScore)4022 static PHP_METHOD(swoole_redis_coro, zScore) {
4023 sw_redis_command_key_val(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("ZSCORE"));
4024 }
4025
PHP_METHOD(swoole_redis_coro,zRank)4026 static PHP_METHOD(swoole_redis_coro, zRank) {
4027 sw_redis_command_key_val(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("ZRANK"));
4028 }
4029
PHP_METHOD(swoole_redis_coro,zRevRank)4030 static PHP_METHOD(swoole_redis_coro, zRevRank) {
4031 sw_redis_command_key_val(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("ZREVRANK"));
4032 }
4033
PHP_METHOD(swoole_redis_coro,hGet)4034 static PHP_METHOD(swoole_redis_coro, hGet) {
4035 sw_redis_command_key_str(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("HGET"));
4036 }
4037
PHP_METHOD(swoole_redis_coro,hMGet)4038 static PHP_METHOD(swoole_redis_coro, hMGet) {
4039 char *key;
4040 zval *z_arr;
4041 size_t argc, key_len;
4042 HashTable *ht_chan;
4043
4044 if (zend_parse_parameters(ZEND_NUM_ARGS(), "sa", &key, &key_len, &z_arr) == FAILURE) {
4045 return;
4046 }
4047
4048 ht_chan = Z_ARRVAL_P(z_arr);
4049
4050 if ((argc = zend_hash_num_elements(ht_chan)) == 0) {
4051 RETURN_FALSE;
4052 }
4053 SW_REDIS_COMMAND_CHECK
4054
4055 zval *value;
4056 int i = 0;
4057 argc = argc + 2;
4058 SW_REDIS_COMMAND_ALLOC_ARGV
4059 SW_REDIS_COMMAND_ARGV_FILL("HMGET", 5)
4060 SW_REDIS_COMMAND_ARGV_FILL(key, key_len)
4061 SW_HASHTABLE_FOREACH_START(ht_chan, value)
4062 zend_string *convert_str = zval_get_string(value);
4063 SW_REDIS_COMMAND_ARGV_FILL(ZSTR_VAL(convert_str), ZSTR_LEN(convert_str))
4064 zend_string_release(convert_str);
4065 SW_HASHTABLE_FOREACH_END();
4066 redis_request(redis, argc, argv, argvlen, return_value);
4067 SW_REDIS_COMMAND_FREE_ARGV
4068
4069 if (redis->compatibility_mode && ZVAL_IS_ARRAY(return_value)) {
4070 size_t index = 0;
4071 zval *zkey, *zvalue;
4072 zval zret;
4073 array_init(&zret);
4074
4075 ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(z_arr), zkey) {
4076 zend::String zkey_str(zkey);
4077
4078 zvalue = zend_hash_index_find(Z_ARRVAL_P(return_value), index++);
4079 if (ZVAL_IS_NULL(zvalue)) {
4080 add_assoc_bool_ex(&zret, zkey_str.val(), zkey_str.len(), 0);
4081 } else {
4082 Z_ADDREF_P(zvalue);
4083 add_assoc_zval_ex(&zret, zkey_str.val(), zkey_str.len(), zvalue);
4084 }
4085 }
4086 ZEND_HASH_FOREACH_END();
4087
4088 zval_ptr_dtor(return_value);
4089 RETVAL_ZVAL(&zret, 1, 1);
4090 }
4091 }
4092
PHP_METHOD(swoole_redis_coro,hExists)4093 static PHP_METHOD(swoole_redis_coro, hExists) {
4094 sw_redis_command_key_str(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("HEXISTS"));
4095
4096 RedisClient *redis = php_swoole_get_redis_client(ZEND_THIS);
4097 if (redis->compatibility_mode && ZVAL_IS_LONG(return_value)) {
4098 RETURN_BOOL(zval_get_long(return_value));
4099 }
4100 }
4101
PHP_METHOD(swoole_redis_coro,publish)4102 static PHP_METHOD(swoole_redis_coro, publish) {
4103 sw_redis_command_key_str(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("PUBLISH"));
4104 }
4105
PHP_METHOD(swoole_redis_coro,zDeleteRangeByScore)4106 static PHP_METHOD(swoole_redis_coro, zDeleteRangeByScore) {
4107 sw_redis_command_key_str_str(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("ZREMRANGEBYSCORE"));
4108 }
4109
PHP_METHOD(swoole_redis_coro,zCount)4110 static PHP_METHOD(swoole_redis_coro, zCount) {
4111 sw_redis_command_key_str_str(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("ZCOUNT"));
4112 }
4113
PHP_METHOD(swoole_redis_coro,incrBy)4114 static PHP_METHOD(swoole_redis_coro, incrBy) {
4115 sw_redis_command_key_long(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("INCRBY"));
4116 }
4117
PHP_METHOD(swoole_redis_coro,hIncrBy)4118 static PHP_METHOD(swoole_redis_coro, hIncrBy) {
4119 char *key, *mem;
4120 size_t key_len, mem_len;
4121 long byval;
4122
4123 if (zend_parse_parameters(ZEND_NUM_ARGS(), "ssl", &key, &key_len, &mem, &mem_len, &byval) == FAILURE) {
4124 return;
4125 }
4126 SW_REDIS_COMMAND_CHECK
4127
4128 int i = 0;
4129 size_t argvlen[4];
4130 char *argv[4];
4131 SW_REDIS_COMMAND_ARGV_FILL("HINCRBY", 7)
4132 SW_REDIS_COMMAND_ARGV_FILL(key, key_len)
4133 SW_REDIS_COMMAND_ARGV_FILL(mem, mem_len)
4134 char str[32];
4135 sprintf(str, "%ld", byval);
4136 SW_REDIS_COMMAND_ARGV_FILL(str, strlen(str))
4137
4138 redis_request(redis, 4, argv, argvlen, return_value);
4139 }
4140
PHP_METHOD(swoole_redis_coro,hIncrByFloat)4141 static PHP_METHOD(swoole_redis_coro, hIncrByFloat) {
4142 char *key, *mem;
4143 size_t key_len, mem_len;
4144 double byval;
4145
4146 if (zend_parse_parameters(ZEND_NUM_ARGS(), "ssd", &key, &key_len, &mem, &mem_len, &byval) == FAILURE) {
4147 return;
4148 }
4149 SW_REDIS_COMMAND_CHECK
4150
4151 int i = 0;
4152 size_t argvlen[4];
4153 char *argv[4];
4154 SW_REDIS_COMMAND_ARGV_FILL("HINCRBYFLOAT", 12)
4155 SW_REDIS_COMMAND_ARGV_FILL(key, key_len)
4156 SW_REDIS_COMMAND_ARGV_FILL(mem, mem_len)
4157 char str[32];
4158 sprintf(str, "%f", byval);
4159 SW_REDIS_COMMAND_ARGV_FILL(str, strlen(str))
4160
4161 redis_request(redis, 4, argv, argvlen, return_value);
4162 }
4163
PHP_METHOD(swoole_redis_coro,incr)4164 static PHP_METHOD(swoole_redis_coro, incr) {
4165 sw_redis_command_key(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("INCR"));
4166 }
4167
PHP_METHOD(swoole_redis_coro,decrBy)4168 static PHP_METHOD(swoole_redis_coro, decrBy) {
4169 sw_redis_command_key_long(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("DECRBY"));
4170 }
4171
PHP_METHOD(swoole_redis_coro,decr)4172 static PHP_METHOD(swoole_redis_coro, decr) {
4173 sw_redis_command_key(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("DECR"));
4174 }
4175
PHP_METHOD(swoole_redis_coro,getBit)4176 static PHP_METHOD(swoole_redis_coro, getBit) {
4177 sw_redis_command_key_long(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("GETBIT"));
4178 }
4179
PHP_METHOD(swoole_redis_coro,lInsert)4180 static PHP_METHOD(swoole_redis_coro, lInsert) {
4181 char *key, *pos;
4182 size_t key_len, pos_len;
4183 zval *z_val, *z_pivot;
4184
4185 if (zend_parse_parameters(ZEND_NUM_ARGS(), "sszz", &key, &key_len, &pos, &pos_len, &z_pivot, &z_val) == FAILURE) {
4186 return;
4187 }
4188
4189 if (strncasecmp(pos, "after", 5) && strncasecmp(pos, "before", 6)) {
4190 php_swoole_error(E_WARNING, "Position must be either 'BEFORE' or 'AFTER'");
4191 RETURN_FALSE;
4192 }
4193
4194 SW_REDIS_COMMAND_CHECK
4195
4196 int i = 0;
4197 size_t argvlen[5];
4198 char *argv[5];
4199
4200 SW_REDIS_COMMAND_ARGV_FILL("LINSERT", 7)
4201 SW_REDIS_COMMAND_ARGV_FILL(key, key_len)
4202 SW_REDIS_COMMAND_ARGV_FILL(pos, pos_len)
4203 SW_REDIS_COMMAND_ARGV_FILL_WITH_SERIALIZE(z_pivot)
4204 SW_REDIS_COMMAND_ARGV_FILL_WITH_SERIALIZE(z_val)
4205 redis_request(redis, 5, argv, argvlen, return_value);
4206 }
4207
PHP_METHOD(swoole_redis_coro,lGet)4208 static PHP_METHOD(swoole_redis_coro, lGet) {
4209 sw_redis_command_key_long(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("LINDEX"));
4210 }
4211
PHP_METHOD(swoole_redis_coro,setTimeout)4212 static PHP_METHOD(swoole_redis_coro, setTimeout) {
4213 sw_redis_command_key_long(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("EXPIRE"));
4214 }
4215
PHP_METHOD(swoole_redis_coro,pexpire)4216 static PHP_METHOD(swoole_redis_coro, pexpire) {
4217 sw_redis_command_key_long(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("PEXPIRE"));
4218 }
4219
PHP_METHOD(swoole_redis_coro,expireAt)4220 static PHP_METHOD(swoole_redis_coro, expireAt) {
4221 sw_redis_command_key_long(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("EXPIREAT"));
4222 }
4223
PHP_METHOD(swoole_redis_coro,pexpireAt)4224 static PHP_METHOD(swoole_redis_coro, pexpireAt) {
4225 sw_redis_command_key_long(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("PEXPIREAT"));
4226 }
4227
PHP_METHOD(swoole_redis_coro,move)4228 static PHP_METHOD(swoole_redis_coro, move) {
4229 sw_redis_command_key_long(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("MOVE"));
4230 }
4231
PHP_METHOD(swoole_redis_coro,select)4232 static PHP_METHOD(swoole_redis_coro, select) {
4233 zend_long db_number;
4234
4235 ZEND_PARSE_PARAMETERS_START(1, 1)
4236 Z_PARAM_LONG(db_number)
4237 ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE);
4238
4239 SW_REDIS_COMMAND_CHECK
4240 zval *zsetting = sw_zend_read_and_convert_property_array(swoole_redis_coro_ce, ZEND_THIS, ZEND_STRL("setting"), 0);
4241 add_assoc_long(zsetting, "database", db_number);
4242 RETURN_BOOL(redis_select_db(redis, db_number));
4243 }
4244
PHP_METHOD(swoole_redis_coro,getRange)4245 static PHP_METHOD(swoole_redis_coro, getRange) {
4246 sw_redis_command_key_long_long(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("GETRANGE"));
4247 }
4248
PHP_METHOD(swoole_redis_coro,listTrim)4249 static PHP_METHOD(swoole_redis_coro, listTrim) {
4250 sw_redis_command_key_long_long(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("LTRIM"));
4251 }
4252
PHP_METHOD(swoole_redis_coro,lGetRange)4253 static PHP_METHOD(swoole_redis_coro, lGetRange) {
4254 sw_redis_command_key_long_long(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("LRANGE"));
4255 }
4256
PHP_METHOD(swoole_redis_coro,lRem)4257 static PHP_METHOD(swoole_redis_coro, lRem) {
4258 char *key;
4259 size_t key_len;
4260 zend_long count = 0;
4261 zval *z_val;
4262
4263 if (zend_parse_parameters(ZEND_NUM_ARGS(), "sz|l", &key, &key_len, &z_val, &count) == FAILURE) {
4264 RETURN_FALSE;
4265 }
4266 SW_REDIS_COMMAND_CHECK
4267
4268 int i = 0;
4269 size_t argvlen[4];
4270 char *argv[4];
4271 SW_REDIS_COMMAND_ARGV_FILL("LREM", 4)
4272 SW_REDIS_COMMAND_ARGV_FILL(key, key_len)
4273 char str[32];
4274 sprintf(str, "%d", (int) count);
4275 SW_REDIS_COMMAND_ARGV_FILL(str, strlen(str))
4276 SW_REDIS_COMMAND_ARGV_FILL_WITH_SERIALIZE(z_val)
4277
4278 redis_request(redis, 4, argv, argvlen, return_value);
4279 }
4280
PHP_METHOD(swoole_redis_coro,zDeleteRangeByRank)4281 static PHP_METHOD(swoole_redis_coro, zDeleteRangeByRank) {
4282 sw_redis_command_key_long_long(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("ZREMRANGEBYRANK"));
4283 }
4284
PHP_METHOD(swoole_redis_coro,incrByFloat)4285 static PHP_METHOD(swoole_redis_coro, incrByFloat) {
4286 sw_redis_command_key_dbl(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("INCRBYFLOAT"));
4287 }
4288
PHP_METHOD(swoole_redis_coro,bitCount)4289 static PHP_METHOD(swoole_redis_coro, bitCount) {
4290 char *key;
4291 size_t key_len;
4292 zend_long start = 0, end = -1;
4293
4294 if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|ll", &key, &key_len, &start, &end) == FAILURE) {
4295 return;
4296 }
4297
4298 SW_REDIS_COMMAND_CHECK
4299
4300 int i = 0;
4301 size_t argvlen[4];
4302 char *argv[4];
4303 SW_REDIS_COMMAND_ARGV_FILL("BITCOUNT", 8)
4304 SW_REDIS_COMMAND_ARGV_FILL(key, key_len)
4305 char str[32];
4306 sprintf(str, "%d", (int) start);
4307 SW_REDIS_COMMAND_ARGV_FILL(str, strlen(str))
4308 sprintf(str, "%d", (int) end);
4309 SW_REDIS_COMMAND_ARGV_FILL(str, strlen(str))
4310
4311 redis_request(redis, 4, argv, argvlen, return_value);
4312 }
4313
PHP_METHOD(swoole_redis_coro,bitOp)4314 static PHP_METHOD(swoole_redis_coro, bitOp) {
4315 int argc = ZEND_NUM_ARGS();
4316 SW_REDIS_COMMAND_CHECK
4317 SW_REDIS_COMMAND_ALLOC_ARGS_ARR
4318 if (zend_get_parameters_array(ht, argc, z_args) == FAILURE || argc < 3 ||
4319 SW_REDIS_COMMAND_ARGS_TYPE(z_args[0]) != IS_STRING) {
4320 efree(z_args);
4321 return;
4322 }
4323
4324 int j, i = 0;
4325 argc++;
4326 SW_REDIS_COMMAND_ALLOC_ARGV
4327 SW_REDIS_COMMAND_ARGV_FILL("BITOP", 5)
4328 SW_REDIS_COMMAND_ARGV_FILL(SW_REDIS_COMMAND_ARGS_STRVAL(z_args[0]), SW_REDIS_COMMAND_ARGS_STRLEN(z_args[0]))
4329 for (j = 1; j < argc - 1; j++) {
4330 zend_string *convert_str = zval_get_string(&z_args[j]);
4331 SW_REDIS_COMMAND_ARGV_FILL(ZSTR_VAL(convert_str), ZSTR_LEN(convert_str))
4332 zend_string_release(convert_str);
4333 }
4334
4335 redis_request(redis, argc, argv, argvlen, return_value);
4336 SW_REDIS_COMMAND_FREE_ARGV
4337 efree(z_args);
4338 }
4339
PHP_METHOD(swoole_redis_coro,sMove)4340 static PHP_METHOD(swoole_redis_coro, sMove) {
4341 char *src, *dst;
4342 size_t src_len, dst_len;
4343 zval *z_val;
4344
4345 if (zend_parse_parameters(ZEND_NUM_ARGS(), "ssz", &src, &src_len, &dst, &dst_len, &z_val) == FAILURE) {
4346 return;
4347 }
4348 SW_REDIS_COMMAND_CHECK
4349
4350 int i = 0;
4351 size_t argvlen[4];
4352 char *argv[4];
4353 SW_REDIS_COMMAND_ARGV_FILL("SMOVE", 5)
4354 SW_REDIS_COMMAND_ARGV_FILL(src, src_len)
4355 SW_REDIS_COMMAND_ARGV_FILL(dst, dst_len)
4356 SW_REDIS_COMMAND_ARGV_FILL_WITH_SERIALIZE(z_val)
4357 redis_request(redis, 4, argv, argvlen, return_value);
4358 }
4359
PHP_METHOD(swoole_redis_coro,sAdd)4360 static PHP_METHOD(swoole_redis_coro, sAdd) {
4361 sw_redis_command_key_var_val(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("SADD"));
4362 }
4363
PHP_METHOD(swoole_redis_coro,sRemove)4364 static PHP_METHOD(swoole_redis_coro, sRemove) {
4365 sw_redis_command_key_var_val(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("SREM"));
4366 }
4367
PHP_METHOD(swoole_redis_coro,zDelete)4368 static PHP_METHOD(swoole_redis_coro, zDelete) {
4369 sw_redis_command_key_var_val(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("ZREM"));
4370 }
4371
redis_subscribe(INTERNAL_FUNCTION_PARAMETERS,const char * cmd)4372 static sw_inline void redis_subscribe(INTERNAL_FUNCTION_PARAMETERS, const char *cmd) {
4373 zval *z_arr;
4374 if (zend_parse_parameters(ZEND_NUM_ARGS(), "a", &z_arr) == FAILURE) {
4375 RETURN_FALSE;
4376 }
4377
4378 SW_REDIS_COMMAND_CHECK
4379 if (redis->defer) {
4380 zend_update_property_long(
4381 swoole_redis_coro_ce, SW_Z8_OBJ_P(ZEND_THIS), ZEND_STRL("errType"), SW_REDIS_ERR_OTHER);
4382 zend_update_property_long(swoole_redis_coro_ce,
4383 SW_Z8_OBJ_P(ZEND_THIS),
4384 ZEND_STRL("errCode"),
4385 sw_redis_convert_err(SW_REDIS_ERR_OTHER));
4386 zend_update_property_string(swoole_redis_coro_ce,
4387 SW_Z8_OBJ_P(ZEND_THIS),
4388 ZEND_STRL("errMsg"),
4389 "subscribe cannot be used with defer enabled");
4390 RETURN_FALSE;
4391 }
4392
4393 HashTable *ht_chan = Z_ARRVAL_P(z_arr);
4394 size_t chan_num = zend_hash_num_elements(ht_chan);
4395 int argc = 1 + chan_num, i = 0;
4396 SW_REDIS_COMMAND_ALLOC_ARGV
4397
4398 SW_REDIS_COMMAND_ARGV_FILL(cmd, strlen(cmd));
4399
4400 zval *value;
4401 SW_HASHTABLE_FOREACH_START(ht_chan, value)
4402 zend_string *convert_str = zval_get_string(value);
4403 SW_REDIS_COMMAND_ARGV_FILL(ZSTR_VAL(convert_str), ZSTR_LEN(convert_str))
4404 zend_string_release(convert_str);
4405 SW_HASHTABLE_FOREACH_END();
4406
4407 redis->defer = true;
4408 redis_request(redis, argc, argv, argvlen, return_value);
4409 redis->defer = false;
4410 SW_REDIS_COMMAND_FREE_ARGV
4411
4412 if (Z_TYPE_P(return_value) == IS_TRUE) {
4413 redis->session.subscribe = true;
4414 }
4415 }
4416
PHP_METHOD(swoole_redis_coro,subscribe)4417 static PHP_METHOD(swoole_redis_coro, subscribe) {
4418 redis_subscribe(INTERNAL_FUNCTION_PARAM_PASSTHRU, "SUBSCRIBE");
4419 }
4420
PHP_METHOD(swoole_redis_coro,pSubscribe)4421 static PHP_METHOD(swoole_redis_coro, pSubscribe) {
4422 redis_subscribe(INTERNAL_FUNCTION_PARAM_PASSTHRU, "PSUBSCRIBE");
4423 }
4424
PHP_METHOD(swoole_redis_coro,unsubscribe)4425 static PHP_METHOD(swoole_redis_coro, unsubscribe) {
4426 redis_subscribe(INTERNAL_FUNCTION_PARAM_PASSTHRU, "UNSUBSCRIBE");
4427 }
4428
PHP_METHOD(swoole_redis_coro,pUnSubscribe)4429 static PHP_METHOD(swoole_redis_coro, pUnSubscribe) {
4430 redis_subscribe(INTERNAL_FUNCTION_PARAM_PASSTHRU, "PUNSUBSCRIBE");
4431 }
4432
PHP_METHOD(swoole_redis_coro,multi)4433 static PHP_METHOD(swoole_redis_coro, multi) {
4434 sw_redis_command_empty(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("MULTI"));
4435 }
4436
PHP_METHOD(swoole_redis_coro,exec)4437 static PHP_METHOD(swoole_redis_coro, exec) {
4438 sw_redis_command_empty(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("EXEC"));
4439 }
4440
PHP_METHOD(swoole_redis_coro,request)4441 static PHP_METHOD(swoole_redis_coro, request) {
4442 SW_REDIS_COMMAND_CHECK
4443
4444 zval *params = nullptr;
4445 if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", ¶ms) == FAILURE) {
4446 RETURN_FALSE;
4447 }
4448
4449 int argc = zend_hash_num_elements(Z_ARRVAL_P(params));
4450 int i = 0;
4451 zval *value;
4452
4453 SW_REDIS_COMMAND_ALLOC_ARGV
4454
4455 SW_HASHTABLE_FOREACH_START(Z_ARRVAL_P(params), value)
4456 if (i == argc) {
4457 break;
4458 }
4459 zend_string *convert_str = zval_get_string(value);
4460 argvlen[i] = ZSTR_LEN(convert_str);
4461 argv[i] = estrndup(ZSTR_VAL(convert_str), ZSTR_LEN(convert_str));
4462 zend_string_release(convert_str);
4463 i++;
4464 SW_HASHTABLE_FOREACH_END();
4465
4466 redis_request(redis, argc, argv, argvlen, return_value);
4467 SW_REDIS_COMMAND_FREE_ARGV
4468 }
4469
PHP_METHOD(swoole_redis_coro,eval)4470 static PHP_METHOD(swoole_redis_coro, eval) {
4471 char *script;
4472 size_t script_len;
4473 zval *params = nullptr;
4474 zend_long keys_num = 0;
4475
4476 if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|al", &script, &script_len, ¶ms, &keys_num) == FAILURE) {
4477 RETURN_FALSE;
4478 }
4479
4480 HashTable *params_ht = nullptr;
4481 uint32_t params_num = 0;
4482 if (params) {
4483 params_ht = Z_ARRVAL_P(params);
4484 params_num = zend_hash_num_elements(params_ht);
4485 }
4486
4487 SW_REDIS_COMMAND_CHECK
4488 int i = 0;
4489 size_t *argvlen = (size_t *) emalloc(sizeof(size_t) * (params_num + 3));
4490 char **argv = (char **) emalloc(sizeof(char *) * (params_num + 3));
4491
4492 SW_REDIS_COMMAND_ARGV_FILL("EVAL", 4)
4493 SW_REDIS_COMMAND_ARGV_FILL(script, script_len)
4494
4495 char keys_num_str[32] = {};
4496 sprintf(keys_num_str, ZEND_LONG_FMT, keys_num);
4497 SW_REDIS_COMMAND_ARGV_FILL(keys_num_str, strlen(keys_num_str));
4498
4499 if (params_ht) {
4500 zval *param;
4501 SW_HASHTABLE_FOREACH_START(params_ht, param)
4502 zend_string *param_str = zval_get_string(param);
4503 SW_REDIS_COMMAND_ARGV_FILL(ZSTR_VAL(param_str), ZSTR_LEN(param_str))
4504 zend_string_release(param_str);
4505 SW_HASHTABLE_FOREACH_END();
4506 }
4507
4508 redis_request(redis, params_num + 3, argv, argvlen, return_value);
4509 efree(argvlen);
4510 efree(argv);
4511 }
4512
PHP_METHOD(swoole_redis_coro,evalSha)4513 static PHP_METHOD(swoole_redis_coro, evalSha) {
4514 char *sha;
4515 size_t sha_len;
4516 zval *params = nullptr;
4517 long keys_num = 0;
4518 if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|al", &sha, &sha_len, ¶ms, &keys_num) == FAILURE) {
4519 RETURN_FALSE;
4520 }
4521
4522 HashTable *params_ht = nullptr;
4523 uint32_t params_num = 0;
4524 if (params) {
4525 params_ht = Z_ARRVAL_P(params);
4526 params_num = zend_hash_num_elements(params_ht);
4527 }
4528
4529 SW_REDIS_COMMAND_CHECK
4530 int i = 0;
4531 size_t *argvlen = (size_t *) emalloc(sizeof(size_t) * (params_num + 3));
4532 char **argv = (char **) emalloc(sizeof(char *) * (params_num + 3));
4533
4534 SW_REDIS_COMMAND_ARGV_FILL("EVALSHA", 7)
4535 SW_REDIS_COMMAND_ARGV_FILL(sha, sha_len)
4536
4537 char keys_num_str[32] = {};
4538 sprintf(keys_num_str, "%ld", keys_num);
4539 SW_REDIS_COMMAND_ARGV_FILL(keys_num_str, strlen(keys_num_str));
4540
4541 if (params) {
4542 zval *param;
4543 SW_HASHTABLE_FOREACH_START(params_ht, param)
4544 zend_string *param_str = zval_get_string(param);
4545 SW_REDIS_COMMAND_ARGV_FILL(ZSTR_VAL(param_str), ZSTR_LEN(param_str))
4546 zend_string_release(param_str);
4547 SW_HASHTABLE_FOREACH_END();
4548 }
4549
4550 redis_request(redis, params_num + 3, argv, argvlen, return_value);
4551 efree(argvlen);
4552 efree(argv);
4553 }
4554
PHP_METHOD(swoole_redis_coro,script)4555 static PHP_METHOD(swoole_redis_coro, script) {
4556 int argc = ZEND_NUM_ARGS();
4557 if (argc < 1) {
4558 RETURN_FALSE;
4559 }
4560 SW_REDIS_COMMAND_CHECK
4561 SW_REDIS_COMMAND_ALLOC_ARGS_ARR
4562 if (zend_get_parameters_array(ht, argc, z_args) == FAILURE || SW_REDIS_COMMAND_ARGS_TYPE(z_args[0]) != IS_STRING) {
4563 efree(z_args);
4564 RETURN_FALSE;
4565 }
4566
4567 int i = 0;
4568 if (!strcasecmp(SW_REDIS_COMMAND_ARGS_STRVAL(z_args[0]), "flush") ||
4569 !strcasecmp(SW_REDIS_COMMAND_ARGS_STRVAL(z_args[0]), "kill")) {
4570 size_t argvlen[2];
4571 char *argv[2];
4572 SW_REDIS_COMMAND_ARGV_FILL("SCRIPT", 6)
4573 SW_REDIS_COMMAND_ARGV_FILL(SW_REDIS_COMMAND_ARGS_STRVAL(z_args[0]), SW_REDIS_COMMAND_ARGS_STRLEN(z_args[0]))
4574 redis_request(redis, 2, argv, argvlen, return_value);
4575 efree(z_args);
4576 } else if (!strcasecmp(SW_REDIS_COMMAND_ARGS_STRVAL(z_args[0]), "exists")) {
4577 if (argc < 2) {
4578 efree(z_args);
4579 RETURN_FALSE;
4580 } else {
4581 size_t *argvlen = (size_t *) emalloc(sizeof(size_t) * (argc + 1));
4582 char **argv = (char **) emalloc(sizeof(char *) * (argc + 1));
4583 SW_REDIS_COMMAND_ARGV_FILL("SCRIPT", 6)
4584 SW_REDIS_COMMAND_ARGV_FILL("EXISTS", 6)
4585 int j = 1;
4586 for (; j < argc; j++) {
4587 zend_string *z_arg_str = zval_get_string(&z_args[j]);
4588 SW_REDIS_COMMAND_ARGV_FILL(ZSTR_VAL(z_arg_str), ZSTR_LEN(z_arg_str))
4589 zend_string_release(z_arg_str);
4590 }
4591
4592 redis_request(redis, argc + 1, argv, argvlen, return_value);
4593 efree(argvlen);
4594 efree(argv);
4595 efree(z_args);
4596 }
4597 } else if (!strcasecmp(SW_REDIS_COMMAND_ARGS_STRVAL(z_args[0]), "load")) {
4598 if (argc < 2 || SW_REDIS_COMMAND_ARGS_TYPE(z_args[1]) != IS_STRING) {
4599 efree(z_args);
4600 RETURN_FALSE;
4601 } else {
4602 size_t argvlen[3];
4603 char *argv[3];
4604 SW_REDIS_COMMAND_ARGV_FILL("SCRIPT", 6)
4605 SW_REDIS_COMMAND_ARGV_FILL("LOAD", 4)
4606 SW_REDIS_COMMAND_ARGV_FILL(SW_REDIS_COMMAND_ARGS_STRVAL(z_args[1]), SW_REDIS_COMMAND_ARGS_STRLEN(z_args[1]))
4607 redis_request(redis, 3, argv, argvlen, return_value);
4608 efree(z_args);
4609 }
4610 } else {
4611 efree(z_args);
4612 RETURN_FALSE;
4613 }
4614 }
4615
PHP_METHOD(swoole_redis_coro,xLen)4616 static PHP_METHOD(swoole_redis_coro, xLen) {
4617 sw_redis_command_key(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("XLEN"));
4618 }
4619
PHP_METHOD(swoole_redis_coro,xAdd)4620 static PHP_METHOD(swoole_redis_coro, xAdd) {
4621 zval *z_options = nullptr, *z_ele;
4622 HashTable *ht_opt, *ht_ele;
4623 char *key, *id;
4624 size_t key_len, id_len;
4625 zval *z_arr;
4626 int argc, options_argc = 0;
4627
4628 if (zend_parse_parameters(ZEND_NUM_ARGS(), "ssa|a", &key, &key_len, &id, &id_len, &z_arr, &z_options) == FAILURE) {
4629 return;
4630 }
4631 if ((argc = zend_hash_num_elements(Z_ARRVAL_P(z_arr))) == 0) {
4632 RETURN_FALSE;
4633 }
4634 SW_REDIS_COMMAND_CHECK
4635 int i = 0;
4636 argc = argc * 2 + 3;
4637 zval *value;
4638 char buf[32];
4639 size_t buf_len;
4640 SW_REDIS_COMMAND_ALLOC_ARGV
4641 SW_REDIS_COMMAND_ARGV_FILL("XADD", 4)
4642 SW_REDIS_COMMAND_ARGV_FILL(key, key_len)
4643
4644 // options
4645 if (z_options && ZVAL_IS_ARRAY(z_options)) {
4646 ht_opt = Z_ARRVAL_P(z_options);
4647 int has_maxlen_minid = 0;
4648 int can_limit = 0;
4649 // NOMKSTREAM
4650 if ((z_ele = zend_hash_str_find(ht_opt, ZEND_STRL("nomkstream"))) && Z_TYPE_P(z_ele) == IS_TRUE) {
4651 SW_REDIS_COMMAND_ARGV_FILL("NOMKSTREAM", 10)
4652 options_argc++;
4653 }
4654 // MAXLEN
4655 if (has_maxlen_minid == 0 && (z_ele = zend_hash_str_find(ht_opt, ZEND_STRL("maxlen")))) {
4656 has_maxlen_minid = 1;
4657 if (Z_TYPE_P(z_ele) == IS_LONG) {
4658 SW_REDIS_COMMAND_ARGV_FILL("MAXLEN", 6)
4659 buf_len = sprintf(buf, ZEND_LONG_FMT, Z_LVAL_P(z_ele));
4660 SW_REDIS_COMMAND_ARGV_FILL(buf, buf_len)
4661 options_argc += 2;
4662 } else if (Z_TYPE_P(z_ele) == IS_ARRAY) {
4663 ht_ele = Z_ARRVAL_P(z_ele);
4664 zval *z_maxlen_p1 = zend_hash_index_find(ht_ele, 0);
4665 zval *z_maxlen_p2 = zend_hash_index_find(ht_ele, 1);
4666 if (Z_TYPE_P(z_maxlen_p1) == IS_STRING && Z_TYPE_P(z_maxlen_p2) == IS_LONG) {
4667 char *maxlen_p1 = Z_STRVAL_P(z_maxlen_p1);
4668 zend_long maxlen_p2 = Z_LVAL_P(z_maxlen_p2);
4669 if ((strcmp(maxlen_p1, "=") == 0 || strcmp(maxlen_p1, "~") == 0) && maxlen_p2 >= 0) {
4670 if ((strcmp(maxlen_p1, "~") == 0)) {
4671 can_limit = 1;
4672 }
4673 SW_REDIS_COMMAND_ARGV_FILL("MAXLEN", 6)
4674 SW_REDIS_COMMAND_ARGV_FILL(maxlen_p1, 1)
4675 buf_len = sprintf(buf, ZEND_LONG_FMT, maxlen_p2);
4676 SW_REDIS_COMMAND_ARGV_FILL(buf, buf_len)
4677 options_argc += 3;
4678 }
4679 }
4680 }
4681 }
4682 // MINID
4683 if (has_maxlen_minid == 0 && (z_ele = zend_hash_str_find(ht_opt, ZEND_STRL("minid")))) {
4684 has_maxlen_minid = 1;
4685 if (Z_TYPE_P(z_ele) == IS_STRING && Z_STRLEN_P(z_ele) > 0) {
4686 SW_REDIS_COMMAND_ARGV_FILL("MINID", 5)
4687 SW_REDIS_COMMAND_ARGV_FILL(Z_STRVAL_P(z_ele), Z_STRLEN_P(z_ele))
4688 options_argc += 2;
4689 } else if (Z_TYPE_P(z_ele) == IS_ARRAY) {
4690 ht_ele = Z_ARRVAL_P(z_ele);
4691 zval *z_minid_p1 = zend_hash_index_find(ht_ele, 0);
4692 zval *z_minid_p2 = zend_hash_index_find(ht_ele, 1);
4693 if (Z_TYPE_P(z_minid_p1) == IS_STRING && Z_TYPE_P(z_minid_p2) == IS_STRING) {
4694 char *minid_p1 = Z_STRVAL_P(z_minid_p1);
4695 char *minid_p2 = Z_STRVAL_P(z_minid_p2);
4696 if ((strcmp(minid_p1, "=") == 0 || strcmp(minid_p1, "~") == 0) && strlen(minid_p2) > 0) {
4697 if ((strcmp(minid_p1, "~") == 0)) {
4698 can_limit = 1;
4699 }
4700 SW_REDIS_COMMAND_ARGV_FILL("MINID", 5)
4701 SW_REDIS_COMMAND_ARGV_FILL(minid_p1, 1)
4702 SW_REDIS_COMMAND_ARGV_FILL(minid_p2, strlen(minid_p2))
4703 options_argc += 3;
4704 }
4705 }
4706 }
4707 }
4708 // LIMIT
4709 if (can_limit == 1 && (z_ele = zend_hash_str_find(ht_opt, ZEND_STRL("limit"))) && Z_TYPE_P(z_ele) == IS_LONG) {
4710 SW_REDIS_COMMAND_ARGV_FILL("LIMIT", 5)
4711 buf_len = sprintf(buf, ZEND_LONG_FMT, Z_LVAL_P(z_ele));
4712 SW_REDIS_COMMAND_ARGV_FILL(buf, buf_len)
4713 options_argc += 2;
4714 }
4715 }
4716
4717 SW_REDIS_COMMAND_INCREASE_ARGV(argc + options_argc)
4718
4719 // id
4720 SW_REDIS_COMMAND_ARGV_FILL(id, id_len)
4721
4722 // k-v
4723 zend_ulong idx;
4724 zend_string *_key;
4725 ZEND_HASH_FOREACH_KEY_VAL_IND(Z_ARRVAL_P(z_arr), idx, _key, value) {
4726 if (_key == nullptr) {
4727 key_len = sw_snprintf(buf, sizeof(buf), ZEND_LONG_FMT, idx);
4728 key = (char *) buf;
4729 } else {
4730 key_len = ZSTR_LEN(_key);
4731 key = ZSTR_VAL(_key);
4732 }
4733 SW_REDIS_COMMAND_ARGV_FILL(key, key_len)
4734 SW_REDIS_COMMAND_ARGV_FILL_WITH_SERIALIZE(value)
4735 }
4736 ZEND_HASH_FOREACH_END();
4737
4738 redis_request(redis, argc, argv, argvlen, return_value);
4739 SW_REDIS_COMMAND_FREE_ARGV
4740 }
4741
PHP_METHOD(swoole_redis_coro,xRead)4742 static PHP_METHOD(swoole_redis_coro, xRead) {
4743 zval *z_streams = nullptr, *z_options = nullptr, *z_ele;
4744 HashTable *ht_opt;
4745 int i = 0, argc = 0, options_argc = 0;
4746
4747 if (zend_parse_parameters(ZEND_NUM_ARGS(), "a|a", &z_streams, &z_options) == FAILURE) {
4748 RETURN_FALSE;
4749 }
4750 if ((argc = zend_hash_num_elements(Z_ARRVAL_P(z_streams))) == 0) {
4751 RETURN_FALSE;
4752 }
4753 SW_REDIS_COMMAND_CHECK
4754
4755 argc = argc * 2 + 2;
4756 char buf[32];
4757 size_t buf_len;
4758 SW_REDIS_COMMAND_ALLOC_ARGV
4759 SW_REDIS_COMMAND_ARGV_FILL("XREAD", 5)
4760
4761 // options
4762 if (z_options && ZVAL_IS_ARRAY(z_options)) {
4763 ht_opt = Z_ARRVAL_P(z_options);
4764 // COUNT
4765 if ((z_ele = zend_hash_str_find(ht_opt, ZEND_STRL("count"))) && Z_TYPE_P(z_ele) == IS_LONG) {
4766 SW_REDIS_COMMAND_ARGV_FILL("COUNT", 5)
4767 buf_len = sprintf(buf, ZEND_LONG_FMT, Z_LVAL_P(z_ele));
4768 SW_REDIS_COMMAND_ARGV_FILL(buf, buf_len)
4769 options_argc += 2;
4770 }
4771 // BLOCK
4772 if ((z_ele = zend_hash_str_find(ht_opt, ZEND_STRL("block"))) && Z_TYPE_P(z_ele) == IS_LONG) {
4773 SW_REDIS_COMMAND_ARGV_FILL("BLOCK", 5)
4774 buf_len = sprintf(buf, ZEND_LONG_FMT, Z_LVAL_P(z_ele));
4775 SW_REDIS_COMMAND_ARGV_FILL(buf, buf_len)
4776 options_argc += 2;
4777 }
4778 }
4779
4780 SW_REDIS_COMMAND_INCREASE_ARGV(argc + options_argc)
4781
4782 // streams
4783 SW_REDIS_COMMAND_ARGV_FILL("STREAMS", 7)
4784 zend_long _num_key;
4785 zend_string *_str_key;
4786 zval *_val;
4787 ZEND_HASH_FOREACH_KEY(Z_ARRVAL_P(z_streams), _num_key, _str_key) {
4788 if (_str_key == NULL) {
4789 _str_key = zend_long_to_str(_num_key);
4790 }
4791 SW_REDIS_COMMAND_ARGV_FILL(ZSTR_VAL(_str_key), ZSTR_LEN(_str_key))
4792 }
4793 ZEND_HASH_FOREACH_END();
4794 ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(z_streams), _val) {
4795 convert_to_string(_val);
4796 SW_REDIS_COMMAND_ARGV_FILL(Z_STRVAL_P(_val), Z_STRLEN_P(_val))
4797 }
4798 ZEND_HASH_FOREACH_END();
4799
4800 redis_request(redis, argc, argv, argvlen, return_value);
4801
4802 if (redis->compatibility_mode && ZVAL_IS_ARRAY(return_value)) {
4803 swoole_redis_handle_assoc_array_result(return_value, true);
4804 }
4805
4806 SW_REDIS_COMMAND_FREE_ARGV
4807 }
4808
PHP_METHOD(swoole_redis_coro,xRange)4809 static PHP_METHOD(swoole_redis_coro, xRange) {
4810 sw_redis_command_xrange(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("XRANGE"));
4811 }
4812
PHP_METHOD(swoole_redis_coro,xRevRange)4813 static PHP_METHOD(swoole_redis_coro, xRevRange) {
4814 sw_redis_command_xrange(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("XREVRANGE"));
4815 }
4816
PHP_METHOD(swoole_redis_coro,xTrim)4817 static PHP_METHOD(swoole_redis_coro, xTrim) {
4818 zval *z_options = nullptr, *z_ele;
4819 HashTable *ht_opt, *ht_ele;
4820 int i = 0, argc = 2, options_argc = 0;
4821 char buf[32], *key;
4822 size_t buf_len, key_len;
4823
4824 if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|a", &key, &key_len, &z_options) == FAILURE) {
4825 RETURN_FALSE;
4826 }
4827 if (php_swoole_array_length_safe(z_options) < 1) {
4828 RETURN_FALSE;
4829 }
4830
4831 SW_REDIS_COMMAND_CHECK
4832 SW_REDIS_COMMAND_ALLOC_ARGV
4833 SW_REDIS_COMMAND_ARGV_FILL("XTRIM", 5)
4834 SW_REDIS_COMMAND_ARGV_FILL(key, key_len)
4835
4836 // options
4837 if (z_options && ZVAL_IS_ARRAY(z_options)) {
4838 ht_opt = Z_ARRVAL_P(z_options);
4839 int has_maxlen_minid = 0;
4840 int can_limit = 0;
4841 // MAXLEN
4842 if (has_maxlen_minid == 0 && (z_ele = zend_hash_str_find(ht_opt, ZEND_STRL("maxlen")))) {
4843 has_maxlen_minid = 1;
4844 if (Z_TYPE_P(z_ele) == IS_LONG) {
4845 SW_REDIS_COMMAND_ARGV_FILL("MAXLEN", 6)
4846 buf_len = sprintf(buf, ZEND_LONG_FMT, Z_LVAL_P(z_ele));
4847 SW_REDIS_COMMAND_ARGV_FILL(buf, buf_len)
4848 options_argc += 2;
4849 } else if (Z_TYPE_P(z_ele) == IS_ARRAY) {
4850 ht_ele = Z_ARRVAL_P(z_ele);
4851 zval *z_maxlen_p1 = zend_hash_index_find(ht_ele, 0);
4852 zval *z_maxlen_p2 = zend_hash_index_find(ht_ele, 1);
4853 if (Z_TYPE_P(z_maxlen_p1) == IS_STRING && Z_TYPE_P(z_maxlen_p2) == IS_LONG) {
4854 char *maxlen_p1 = Z_STRVAL_P(z_maxlen_p1);
4855 zend_long maxlen_p2 = Z_LVAL_P(z_maxlen_p2);
4856 if ((strcmp(maxlen_p1, "=") == 0 || strcmp(maxlen_p1, "~") == 0) && maxlen_p2 >= 0) {
4857 if ((strcmp(maxlen_p1, "~") == 0)) {
4858 can_limit = 1;
4859 }
4860 SW_REDIS_COMMAND_ARGV_FILL("MAXLEN", 6)
4861 SW_REDIS_COMMAND_ARGV_FILL(maxlen_p1, 1)
4862 buf_len = sprintf(buf, ZEND_LONG_FMT, maxlen_p2);
4863 SW_REDIS_COMMAND_ARGV_FILL(buf, buf_len)
4864 options_argc += 3;
4865 }
4866 }
4867 }
4868 }
4869 // MINID
4870 if (has_maxlen_minid == 0 && (z_ele = zend_hash_str_find(ht_opt, ZEND_STRL("minid")))) {
4871 has_maxlen_minid = 1;
4872 if (Z_TYPE_P(z_ele) == IS_STRING && Z_STRLEN_P(z_ele) > 0) {
4873 SW_REDIS_COMMAND_ARGV_FILL("MINID", 5)
4874 SW_REDIS_COMMAND_ARGV_FILL(Z_STRVAL_P(z_ele), Z_STRLEN_P(z_ele))
4875 options_argc += 2;
4876 } else if (Z_TYPE_P(z_ele) == IS_ARRAY) {
4877 ht_ele = Z_ARRVAL_P(z_ele);
4878 zval *z_minid_p1 = zend_hash_index_find(ht_ele, 0);
4879 zval *z_minid_p2 = zend_hash_index_find(ht_ele, 1);
4880 if (Z_TYPE_P(z_minid_p1) == IS_STRING && Z_TYPE_P(z_minid_p2) == IS_STRING) {
4881 char *minid_p1 = Z_STRVAL_P(z_minid_p1);
4882 char *minid_p2 = Z_STRVAL_P(z_minid_p2);
4883 if ((strcmp(minid_p1, "=") == 0 || strcmp(minid_p1, "~") == 0) && strlen(minid_p2) > 0) {
4884 if ((strcmp(minid_p1, "~") == 0)) {
4885 can_limit = 1;
4886 }
4887 SW_REDIS_COMMAND_ARGV_FILL("MINID", 5)
4888 SW_REDIS_COMMAND_ARGV_FILL(minid_p1, 1)
4889 SW_REDIS_COMMAND_ARGV_FILL(minid_p2, strlen(minid_p2))
4890 options_argc += 3;
4891 }
4892 }
4893 }
4894 }
4895 // LIMIT
4896 if (can_limit == 1 && (z_ele = zend_hash_str_find(ht_opt, ZEND_STRL("limit"))) && Z_TYPE_P(z_ele) == IS_LONG) {
4897 SW_REDIS_COMMAND_ARGV_FILL("LIMIT", 5)
4898 buf_len = sprintf(buf, ZEND_LONG_FMT, Z_LVAL_P(z_ele));
4899 SW_REDIS_COMMAND_ARGV_FILL(buf, buf_len)
4900 options_argc += 2;
4901 }
4902 }
4903
4904 SW_REDIS_COMMAND_INCREASE_ARGV(argc + options_argc)
4905
4906 redis_request(redis, argc, argv, argvlen, return_value);
4907
4908 if (redis->compatibility_mode && ZVAL_IS_ARRAY(return_value)) {
4909 swoole_redis_handle_assoc_array_result(return_value, true);
4910 }
4911
4912 SW_REDIS_COMMAND_FREE_ARGV
4913 }
4914
PHP_METHOD(swoole_redis_coro,xDel)4915 static PHP_METHOD(swoole_redis_coro, xDel) {
4916 sw_redis_command_key_var_val(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("XDEL"));
4917 }
4918
PHP_METHOD(swoole_redis_coro,xGroupCreate)4919 static PHP_METHOD(swoole_redis_coro, xGroupCreate) {
4920 char *key, *group_name, *id;
4921 size_t key_len, group_name_len, id_len;
4922 zend_bool mkstream = 0;
4923
4924 if (zend_parse_parameters(ZEND_NUM_ARGS(), "sss|b", &key, &key_len, &group_name, &group_name_len, &id, &id_len, &mkstream) == FAILURE) {
4925 return;
4926 }
4927 SW_REDIS_COMMAND_CHECK
4928 int i = 0, argc = 5;
4929 size_t argvlen[6];
4930 char *argv[6];
4931 SW_REDIS_COMMAND_ARGV_FILL("XGROUP", 6)
4932 SW_REDIS_COMMAND_ARGV_FILL("CREATE", 6)
4933 SW_REDIS_COMMAND_ARGV_FILL(key, key_len)
4934 SW_REDIS_COMMAND_ARGV_FILL(group_name, group_name_len)
4935 SW_REDIS_COMMAND_ARGV_FILL(id, id_len)
4936 if (mkstream) {
4937 SW_REDIS_COMMAND_ARGV_FILL("MKSTREAM", 8)
4938 argc = 6;
4939 }
4940
4941 redis_request(redis, argc, argv, argvlen, return_value);
4942 }
4943
PHP_METHOD(swoole_redis_coro,xGroupSetId)4944 static PHP_METHOD(swoole_redis_coro, xGroupSetId) {
4945 char *key, *group_name, *id;
4946 size_t key_len, group_name_len, id_len;
4947
4948 if (zend_parse_parameters(ZEND_NUM_ARGS(), "sss", &key, &key_len, &group_name, &group_name_len, &id, &id_len) == FAILURE) {
4949 return;
4950 }
4951 SW_REDIS_COMMAND_CHECK
4952 int i = 0, argc = 5;
4953 size_t argvlen[5];
4954 char *argv[5];
4955 SW_REDIS_COMMAND_ARGV_FILL("XGROUP", 6)
4956 SW_REDIS_COMMAND_ARGV_FILL("CREATECONSUMER", 14)
4957 SW_REDIS_COMMAND_ARGV_FILL(key, key_len)
4958 SW_REDIS_COMMAND_ARGV_FILL(group_name, group_name_len)
4959 SW_REDIS_COMMAND_ARGV_FILL(id, id_len)
4960
4961 redis_request(redis, argc, argv, argvlen, return_value);
4962 }
4963
PHP_METHOD(swoole_redis_coro,xGroupDestroy)4964 static PHP_METHOD(swoole_redis_coro, xGroupDestroy) {
4965 char *key, *group_name;
4966 size_t key_len, group_name_len;
4967
4968 if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss", &key, &key_len, &group_name, &group_name_len) == FAILURE) {
4969 return;
4970 }
4971 SW_REDIS_COMMAND_CHECK
4972 int i = 0, argc = 4;
4973 size_t argvlen[4];
4974 char *argv[4];
4975 SW_REDIS_COMMAND_ARGV_FILL("XGROUP", 6)
4976 SW_REDIS_COMMAND_ARGV_FILL("DESTROY", 7)
4977 SW_REDIS_COMMAND_ARGV_FILL(key, key_len)
4978 SW_REDIS_COMMAND_ARGV_FILL(group_name, group_name_len)
4979
4980 redis_request(redis, argc, argv, argvlen, return_value);
4981 }
4982
PHP_METHOD(swoole_redis_coro,xGroupCreateConsumer)4983 static PHP_METHOD(swoole_redis_coro, xGroupCreateConsumer) {
4984 char *key, *group_name, *consumer_name;
4985 size_t key_len, group_name_len, consumer_name_len;
4986
4987 if (zend_parse_parameters(ZEND_NUM_ARGS(), "sss", &key, &key_len, &group_name, &group_name_len, &consumer_name, &consumer_name_len) == FAILURE) {
4988 return;
4989 }
4990 SW_REDIS_COMMAND_CHECK
4991 int i = 0, argc = 5;
4992 size_t argvlen[5];
4993 char *argv[5];
4994 SW_REDIS_COMMAND_ARGV_FILL("XGROUP", 6)
4995 SW_REDIS_COMMAND_ARGV_FILL("CREATECONSUMER", 14)
4996 SW_REDIS_COMMAND_ARGV_FILL(key, key_len)
4997 SW_REDIS_COMMAND_ARGV_FILL(group_name, group_name_len)
4998 SW_REDIS_COMMAND_ARGV_FILL(consumer_name, consumer_name_len)
4999
5000 redis_request(redis, argc, argv, argvlen, return_value);
5001 }
5002
PHP_METHOD(swoole_redis_coro,xGroupDelConsumer)5003 static PHP_METHOD(swoole_redis_coro, xGroupDelConsumer) {
5004 char *key, *group_name, *consumer_name;
5005 size_t key_len, group_name_len, consumer_name_len;
5006
5007 if (zend_parse_parameters(ZEND_NUM_ARGS(), "sss", &key, &key_len, &group_name, &group_name_len, &consumer_name, &consumer_name_len) == FAILURE) {
5008 return;
5009 }
5010 SW_REDIS_COMMAND_CHECK
5011 int i = 0, argc = 5;
5012 size_t argvlen[5];
5013 char *argv[5];
5014 SW_REDIS_COMMAND_ARGV_FILL("XGROUP", 6)
5015 SW_REDIS_COMMAND_ARGV_FILL("DELCONSUMER", 11)
5016 SW_REDIS_COMMAND_ARGV_FILL(key, key_len)
5017 SW_REDIS_COMMAND_ARGV_FILL(group_name, group_name_len)
5018 SW_REDIS_COMMAND_ARGV_FILL(consumer_name, consumer_name_len)
5019
5020 redis_request(redis, argc, argv, argvlen, return_value);
5021 }
5022
PHP_METHOD(swoole_redis_coro,xReadGroup)5023 static PHP_METHOD(swoole_redis_coro, xReadGroup) {
5024 char *group_name, *consumer_name;
5025 size_t group_name_len, consumer_name_len;
5026 zval *z_streams = nullptr, *z_options = nullptr, *z_ele;
5027 HashTable *ht_opt;
5028 int i = 0, argc = 0, options_argc = 0;
5029 char buf[32];
5030 size_t buf_len;
5031
5032 if (zend_parse_parameters(ZEND_NUM_ARGS(), "ssa|a", &group_name, &group_name_len, &consumer_name, &consumer_name_len, &z_streams, &z_options) == FAILURE) {
5033 RETURN_FALSE;
5034 }
5035 if ((argc = zend_hash_num_elements(Z_ARRVAL_P(z_streams))) == 0) {
5036 RETURN_FALSE;
5037 }
5038 SW_REDIS_COMMAND_CHECK
5039 argc = argc * 2 + 5;
5040 SW_REDIS_COMMAND_ALLOC_ARGV
5041 SW_REDIS_COMMAND_ARGV_FILL("XREADGROUP", 10)
5042 SW_REDIS_COMMAND_ARGV_FILL("GROUP", 5)
5043 SW_REDIS_COMMAND_ARGV_FILL(group_name, group_name_len)
5044 SW_REDIS_COMMAND_ARGV_FILL(consumer_name, consumer_name_len)
5045
5046 // options
5047 if (z_options && ZVAL_IS_ARRAY(z_options)) {
5048 ht_opt = Z_ARRVAL_P(z_options);
5049 // COUNT
5050 if ((z_ele = zend_hash_str_find(ht_opt, ZEND_STRL("count"))) && Z_TYPE_P(z_ele) == IS_LONG) {
5051 SW_REDIS_COMMAND_ARGV_FILL("COUNT", 5)
5052 buf_len = sprintf(buf, ZEND_LONG_FMT, Z_LVAL_P(z_ele));
5053 SW_REDIS_COMMAND_ARGV_FILL(buf, buf_len)
5054 options_argc += 2;
5055 }
5056 // BLOCK
5057 if ((z_ele = zend_hash_str_find(ht_opt, ZEND_STRL("block"))) && Z_TYPE_P(z_ele) == IS_LONG) {
5058 SW_REDIS_COMMAND_ARGV_FILL("BLOCK", 5)
5059 buf_len = sprintf(buf, ZEND_LONG_FMT, Z_LVAL_P(z_ele));
5060 SW_REDIS_COMMAND_ARGV_FILL(buf, buf_len)
5061 options_argc += 2;
5062 }
5063 // NOACK
5064 if ((z_ele = zend_hash_str_find(ht_opt, ZEND_STRL("noack"))) && Z_TYPE_P(z_ele) == IS_TRUE) {
5065 SW_REDIS_COMMAND_ARGV_FILL("NOACK", 5)
5066 options_argc++;
5067 }
5068 }
5069
5070 SW_REDIS_COMMAND_INCREASE_ARGV(argc + options_argc)
5071
5072 // streams
5073 SW_REDIS_COMMAND_ARGV_FILL("STREAMS", 7)
5074 zend_long _num_key;
5075 zend_string *_str_key;
5076 zval *_val;
5077 ZEND_HASH_FOREACH_KEY(Z_ARRVAL_P(z_streams), _num_key, _str_key) {
5078 if (_str_key == NULL) {
5079 _str_key = zend_long_to_str(_num_key);
5080 }
5081 SW_REDIS_COMMAND_ARGV_FILL(ZSTR_VAL(_str_key), ZSTR_LEN(_str_key))
5082 }
5083 ZEND_HASH_FOREACH_END();
5084 ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(z_streams), _val) {
5085 convert_to_string(_val);
5086 SW_REDIS_COMMAND_ARGV_FILL(Z_STRVAL_P(_val), Z_STRLEN_P(_val))
5087 }
5088 ZEND_HASH_FOREACH_END();
5089
5090 redis_request(redis, argc, argv, argvlen, return_value);
5091
5092 if (redis->compatibility_mode && ZVAL_IS_ARRAY(return_value)) {
5093 swoole_redis_handle_assoc_array_result(return_value, true);
5094 }
5095
5096 SW_REDIS_COMMAND_FREE_ARGV
5097 }
5098
PHP_METHOD(swoole_redis_coro,xPending)5099 static PHP_METHOD(swoole_redis_coro, xPending) {
5100 char *key, *group_name;
5101 size_t key_len, group_name_len;
5102 zval *z_options = nullptr, *z_ele;
5103 HashTable *ht_opt;
5104 int i = 0, argc = 3, options_argc = 0;
5105
5106 if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss|a", &key, &key_len, &group_name, &group_name_len, &z_options) == FAILURE) {
5107 RETURN_FALSE;
5108 }
5109
5110 char buf[32];
5111 size_t buf_len;
5112 SW_REDIS_COMMAND_CHECK
5113 SW_REDIS_COMMAND_ALLOC_ARGV
5114 SW_REDIS_COMMAND_ARGV_FILL("XPENDING", 8)
5115 SW_REDIS_COMMAND_ARGV_FILL(key, key_len)
5116 SW_REDIS_COMMAND_ARGV_FILL(group_name, group_name_len)
5117
5118 // options
5119 if (z_options && ZVAL_IS_ARRAY(z_options)) {
5120 ht_opt = Z_ARRVAL_P(z_options);
5121 // IDLE
5122 if ((z_ele = zend_hash_str_find(ht_opt, ZEND_STRL("idle"))) && Z_TYPE_P(z_ele) == IS_LONG) {
5123 SW_REDIS_COMMAND_ARGV_FILL("IDLE", 4)
5124 buf_len = sprintf(buf, ZEND_LONG_FMT, Z_LVAL_P(z_ele));
5125 SW_REDIS_COMMAND_ARGV_FILL(buf, buf_len)
5126 options_argc += 2;
5127 }
5128 // START
5129 if ((z_ele = zend_hash_str_find(ht_opt, ZEND_STRL("start"))) && Z_TYPE_P(z_ele) == IS_STRING) {
5130 SW_REDIS_COMMAND_ARGV_FILL(Z_STRVAL_P(z_ele), Z_STRLEN_P(z_ele))
5131 options_argc++;
5132 }
5133 // END
5134 if ((z_ele = zend_hash_str_find(ht_opt, ZEND_STRL("end"))) && Z_TYPE_P(z_ele) == IS_STRING) {
5135 SW_REDIS_COMMAND_ARGV_FILL(Z_STRVAL_P(z_ele), Z_STRLEN_P(z_ele))
5136 options_argc++;
5137 }
5138 // COUNT
5139 if ((z_ele = zend_hash_str_find(ht_opt, ZEND_STRL("count"))) && Z_TYPE_P(z_ele) == IS_LONG) {
5140 buf_len = sprintf(buf, ZEND_LONG_FMT, Z_LVAL_P(z_ele));
5141 SW_REDIS_COMMAND_ARGV_FILL(buf, buf_len)
5142 options_argc++;
5143 }
5144 // CONSUMER
5145 if ((z_ele = zend_hash_str_find(ht_opt, ZEND_STRL("consumer"))) && Z_TYPE_P(z_ele) == IS_TRUE) {
5146 SW_REDIS_COMMAND_ARGV_FILL(Z_STRVAL_P(z_ele), Z_STRLEN_P(z_ele))
5147 options_argc++;
5148 }
5149 }
5150
5151 SW_REDIS_COMMAND_INCREASE_ARGV(argc + options_argc)
5152
5153 redis_request(redis, argc, argv, argvlen, return_value);
5154
5155 if (redis->compatibility_mode && ZVAL_IS_ARRAY(return_value)) {
5156 swoole_redis_handle_assoc_array_result(return_value, true);
5157 }
5158
5159 SW_REDIS_COMMAND_FREE_ARGV
5160 }
5161
PHP_METHOD(swoole_redis_coro,xAck)5162 static PHP_METHOD(swoole_redis_coro, xAck) {
5163 char *key, *group_name;
5164 size_t key_len, group_name_len;
5165 zval *z_id = nullptr;
5166 int i = 0, argc = 3, id_argc = 0;
5167
5168 if (zend_parse_parameters(ZEND_NUM_ARGS(), "ssa", &key, &key_len, &group_name, &group_name_len, &z_id) == FAILURE) {
5169 RETURN_FALSE;
5170 }
5171 if ((id_argc = zend_hash_num_elements(Z_ARRVAL_P(z_id))) == 0) {
5172 RETURN_FALSE;
5173 }
5174 argc += id_argc;
5175 SW_REDIS_COMMAND_CHECK
5176 SW_REDIS_COMMAND_ALLOC_ARGV
5177 SW_REDIS_COMMAND_ARGV_FILL("XACK", 4)
5178 SW_REDIS_COMMAND_ARGV_FILL(key, key_len)
5179 SW_REDIS_COMMAND_ARGV_FILL(group_name, group_name_len)
5180
5181 // id
5182 zval *_id;
5183 ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(z_id), _id) {
5184 convert_to_string(_id);
5185 SW_REDIS_COMMAND_ARGV_FILL(Z_STRVAL_P(_id), Z_STRLEN_P(_id))
5186 }
5187 ZEND_HASH_FOREACH_END();
5188
5189 redis_request(redis, argc, argv, argvlen, return_value);
5190
5191 if (redis->compatibility_mode && ZVAL_IS_ARRAY(return_value)) {
5192 swoole_redis_handle_assoc_array_result(return_value, true);
5193 }
5194
5195 SW_REDIS_COMMAND_FREE_ARGV
5196 }
5197
PHP_METHOD(swoole_redis_coro,xClaim)5198 static PHP_METHOD(swoole_redis_coro, xClaim) {
5199 char *key, *group_name, *consumer_name;
5200 size_t key_len, group_name_len, consumer_name_len;
5201 zend_long min_idle_time = 0;
5202 zval *z_id = nullptr, *z_options = nullptr, *z_ele;
5203 HashTable *ht_opt;
5204 int i = 0, argc = 5, id_argc = 0, options_argc = 0;
5205
5206 if (zend_parse_parameters(ZEND_NUM_ARGS(), "sssla|a", &key, &key_len, &group_name, &group_name_len, &consumer_name, &consumer_name_len, &min_idle_time, &z_id, &z_options) == FAILURE) {
5207 RETURN_FALSE;
5208 }
5209
5210 SW_REDIS_COMMAND_CHECK
5211 id_argc = zend_hash_num_elements(Z_ARRVAL_P(z_id));
5212 argc += id_argc;
5213 char buf[32];
5214 size_t buf_len;
5215 SW_REDIS_COMMAND_ALLOC_ARGV
5216 SW_REDIS_COMMAND_ARGV_FILL("XCLAIM", 6)
5217 SW_REDIS_COMMAND_ARGV_FILL(key, key_len)
5218 SW_REDIS_COMMAND_ARGV_FILL(group_name, group_name_len)
5219 SW_REDIS_COMMAND_ARGV_FILL(consumer_name, consumer_name_len)
5220 buf_len = sprintf(buf, ZEND_LONG_FMT, min_idle_time);
5221 SW_REDIS_COMMAND_ARGV_FILL(buf, buf_len)
5222
5223 // id
5224 zval *_id;
5225 ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(z_id), _id) {
5226 convert_to_string(_id);
5227 SW_REDIS_COMMAND_ARGV_FILL(Z_STRVAL_P(_id), Z_STRLEN_P(_id))
5228 }
5229 ZEND_HASH_FOREACH_END();
5230
5231 // options
5232 if (z_options && ZVAL_IS_ARRAY(z_options)) {
5233 ht_opt = Z_ARRVAL_P(z_options);
5234 // IDLE
5235 if ((z_ele = zend_hash_str_find(ht_opt, ZEND_STRL("idle"))) && Z_TYPE_P(z_ele) == IS_LONG) {
5236 SW_REDIS_COMMAND_ARGV_FILL("IDLE", 4)
5237 buf_len = sprintf(buf, ZEND_LONG_FMT, Z_LVAL_P(z_ele));
5238 SW_REDIS_COMMAND_ARGV_FILL(buf, buf_len)
5239 options_argc += 2;
5240 }
5241 // TIME
5242 if ((z_ele = zend_hash_str_find(ht_opt, ZEND_STRL("time"))) && Z_TYPE_P(z_ele) == IS_LONG) {
5243 SW_REDIS_COMMAND_ARGV_FILL("TIME", 4)
5244 buf_len = sprintf(buf, ZEND_LONG_FMT, Z_LVAL_P(z_ele));
5245 SW_REDIS_COMMAND_ARGV_FILL(buf, buf_len)
5246 options_argc += 2;
5247 }
5248 // RETRYCOUNT
5249 if ((z_ele = zend_hash_str_find(ht_opt, ZEND_STRL("retrycount"))) && Z_TYPE_P(z_ele) == IS_LONG) {
5250 SW_REDIS_COMMAND_ARGV_FILL("RETRYCOUNT", 10)
5251 buf_len = sprintf(buf, ZEND_LONG_FMT, Z_LVAL_P(z_ele));
5252 SW_REDIS_COMMAND_ARGV_FILL(buf, buf_len)
5253 options_argc += 2;
5254 }
5255 // FORCE
5256 if ((z_ele = zend_hash_str_find(ht_opt, ZEND_STRL("force"))) && Z_TYPE_P(z_ele) == IS_TRUE) {
5257 SW_REDIS_COMMAND_ARGV_FILL("FORCE", 5)
5258 options_argc++;
5259 }
5260 // JUSTID
5261 if ((z_ele = zend_hash_str_find(ht_opt, ZEND_STRL("justid"))) && Z_TYPE_P(z_ele) == IS_TRUE) {
5262 SW_REDIS_COMMAND_ARGV_FILL("JUSTID", 6)
5263 options_argc++;
5264 }
5265 }
5266
5267 SW_REDIS_COMMAND_INCREASE_ARGV(argc + options_argc)
5268
5269 redis_request(redis, argc, argv, argvlen, return_value);
5270
5271 if (redis->compatibility_mode && ZVAL_IS_ARRAY(return_value)) {
5272 swoole_redis_handle_assoc_array_result(return_value, true);
5273 }
5274
5275 SW_REDIS_COMMAND_FREE_ARGV
5276 }
5277
PHP_METHOD(swoole_redis_coro,xAutoClaim)5278 static PHP_METHOD(swoole_redis_coro, xAutoClaim) {
5279 char *key, *group_name, *consumer_name, *start;
5280 size_t key_len, group_name_len, consumer_name_len, start_len;
5281 zend_long min_idle_time = 0;
5282 zval *z_options = nullptr, *z_ele;
5283 HashTable *ht_opt;
5284 int i = 0, argc = 6, options_argc = 0;
5285
5286 if (zend_parse_parameters(ZEND_NUM_ARGS(), "sssls|a", &key, &key_len, &group_name, &group_name_len, &consumer_name, &consumer_name_len, &min_idle_time, &start, &start_len, &z_options) == FAILURE) {
5287 RETURN_FALSE;
5288 }
5289
5290 SW_REDIS_COMMAND_CHECK
5291 char buf[32];
5292 size_t buf_len;
5293 SW_REDIS_COMMAND_ALLOC_ARGV
5294 SW_REDIS_COMMAND_ARGV_FILL("XAUTOCLAIM", 10)
5295 SW_REDIS_COMMAND_ARGV_FILL(key, key_len)
5296 SW_REDIS_COMMAND_ARGV_FILL(group_name, group_name_len)
5297 SW_REDIS_COMMAND_ARGV_FILL(consumer_name, consumer_name_len)
5298 buf_len = sprintf(buf, ZEND_LONG_FMT, min_idle_time);
5299 SW_REDIS_COMMAND_ARGV_FILL(buf, buf_len)
5300 SW_REDIS_COMMAND_ARGV_FILL(start, start_len)
5301
5302 // options
5303 if (z_options && ZVAL_IS_ARRAY(z_options)) {
5304 ht_opt = Z_ARRVAL_P(z_options);
5305 // COUNT
5306 if ((z_ele = zend_hash_str_find(ht_opt, ZEND_STRL("count"))) && Z_TYPE_P(z_ele) == IS_LONG) {
5307 SW_REDIS_COMMAND_ARGV_FILL("COUNT", 5)
5308 buf_len = sprintf(buf, ZEND_LONG_FMT, Z_LVAL_P(z_ele));
5309 SW_REDIS_COMMAND_ARGV_FILL(buf, buf_len)
5310 options_argc += 2;
5311 }
5312 // JUSTID
5313 if ((z_ele = zend_hash_str_find(ht_opt, ZEND_STRL("justid"))) && Z_TYPE_P(z_ele) == IS_TRUE) {
5314 SW_REDIS_COMMAND_ARGV_FILL("JUSTID", 6)
5315 options_argc++;
5316 }
5317 }
5318
5319 SW_REDIS_COMMAND_INCREASE_ARGV(argc + options_argc)
5320
5321 redis_request(redis, argc, argv, argvlen, return_value);
5322
5323 if (redis->compatibility_mode && ZVAL_IS_ARRAY(return_value)) {
5324 swoole_redis_handle_assoc_array_result(return_value, true);
5325 }
5326
5327 SW_REDIS_COMMAND_FREE_ARGV
5328 }
5329
PHP_METHOD(swoole_redis_coro,xInfoConsumers)5330 static PHP_METHOD(swoole_redis_coro, xInfoConsumers) {
5331 char *key, *group_name;
5332 size_t key_len, group_name_len;
5333
5334 if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss", &key, &key_len, &group_name, &group_name_len) == FAILURE) {
5335 return;
5336 }
5337
5338 SW_REDIS_COMMAND_CHECK
5339 int i = 0, argc = 4;
5340 size_t argvlen[4];
5341 char *argv[4];
5342 SW_REDIS_COMMAND_ARGV_FILL("XINFO", 5)
5343 SW_REDIS_COMMAND_ARGV_FILL("CONSUMERS", 9)
5344 SW_REDIS_COMMAND_ARGV_FILL(key, key_len)
5345 SW_REDIS_COMMAND_ARGV_FILL(group_name, group_name_len)
5346
5347 redis_request(redis, argc, argv, argvlen, return_value);
5348
5349 if (redis->compatibility_mode && ZVAL_IS_ARRAY(return_value)) {
5350 swoole_redis_handle_assoc_array_result(return_value, true);
5351 }
5352 }
5353
PHP_METHOD(swoole_redis_coro,xInfoGroups)5354 static PHP_METHOD(swoole_redis_coro, xInfoGroups) {
5355 char *key;
5356 size_t key_len;
5357
5358 if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &key, &key_len) == FAILURE) {
5359 return;
5360 }
5361
5362 SW_REDIS_COMMAND_CHECK
5363 int i = 0, argc = 3;
5364 size_t argvlen[3];
5365 char *argv[3];
5366 SW_REDIS_COMMAND_ARGV_FILL("XINFO", 5)
5367 SW_REDIS_COMMAND_ARGV_FILL("GROUPS", 6)
5368 SW_REDIS_COMMAND_ARGV_FILL(key, key_len)
5369
5370 redis_request(redis, argc, argv, argvlen, return_value);
5371
5372 if (redis->compatibility_mode && ZVAL_IS_ARRAY(return_value)) {
5373 swoole_redis_handle_assoc_array_result(return_value, true);
5374 }
5375 }
5376
PHP_METHOD(swoole_redis_coro,xInfoStream)5377 static PHP_METHOD(swoole_redis_coro, xInfoStream) {
5378 char *key;
5379 size_t key_len;
5380
5381 if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &key, &key_len) == FAILURE) {
5382 return;
5383 }
5384 SW_REDIS_COMMAND_CHECK
5385 int i = 0, argc = 3;
5386 size_t argvlen[3];
5387 char *argv[3];
5388 SW_REDIS_COMMAND_ARGV_FILL("XINFO", 5)
5389 SW_REDIS_COMMAND_ARGV_FILL("STREAM", 6)
5390 SW_REDIS_COMMAND_ARGV_FILL(key, key_len)
5391
5392 redis_request(redis, argc, argv, argvlen, return_value);
5393
5394 if (redis->compatibility_mode && ZVAL_IS_ARRAY(return_value)) {
5395 swoole_redis_handle_assoc_array_result(return_value, true);
5396 }
5397 }
5398
swoole_redis_coro_parse_result(RedisClient * redis,zval * return_value,redisReply * reply)5399 static void swoole_redis_coro_parse_result(RedisClient *redis, zval *return_value, redisReply *reply) {
5400 int j;
5401 zval _val, *val = &_val;
5402
5403 switch (reply->type) {
5404 case REDIS_REPLY_INTEGER:
5405 ZVAL_LONG(return_value, reply->integer);
5406 break;
5407
5408 case REDIS_REPLY_DOUBLE:
5409 ZVAL_DOUBLE(return_value, reply->dval);
5410 break;
5411
5412 case REDIS_REPLY_BOOL:
5413 ZVAL_BOOL(return_value, reply->integer);
5414 break;
5415
5416 case REDIS_REPLY_ERROR:
5417 ZVAL_FALSE(return_value);
5418 if (redis->context->err == 0) {
5419 if (strncmp(reply->str, "NOAUTH", 6) == 0) {
5420 redis->context->err = SW_REDIS_ERR_NOAUTH;
5421 } else {
5422 redis->context->err = SW_REDIS_ERR_OTHER;
5423 }
5424 size_t str_len = strlen(reply->str);
5425 memcpy(redis->context->errstr, reply->str, SW_MIN(str_len, sizeof(redis->context->errstr) - 1));
5426 }
5427 zend_update_property_long(
5428 swoole_redis_coro_ce, SW_Z8_OBJ_P(redis->zobject), ZEND_STRL("errType"), redis->context->err);
5429 zend_update_property_long(swoole_redis_coro_ce,
5430 SW_Z8_OBJ_P(redis->zobject),
5431 ZEND_STRL("errCode"),
5432 sw_redis_convert_err(redis->context->err));
5433 zend_update_property_string(
5434 swoole_redis_coro_ce, SW_Z8_OBJ_P(redis->zobject), ZEND_STRL("errMsg"), redis->context->errstr);
5435 break;
5436
5437 case REDIS_REPLY_STATUS:
5438 if (redis->context->err == 0) {
5439 if (reply->len > 0) {
5440 if (strncmp(reply->str, "OK", 2) == 0) {
5441 ZVAL_TRUE(return_value);
5442 break;
5443 }
5444 long l;
5445 if (strncmp(reply->str, "string", 6) == 0) {
5446 l = SW_REDIS_TYPE_STRING;
5447 } else if (strncmp(reply->str, "set", 3) == 0) {
5448 l = SW_REDIS_TYPE_SET;
5449 } else if (strncmp(reply->str, "list", 4) == 0) {
5450 l = SW_REDIS_TYPE_LIST;
5451 } else if (strncmp(reply->str, "zset", 4) == 0) {
5452 l = SW_REDIS_TYPE_ZSET;
5453 } else if (strncmp(reply->str, "hash", 4) == 0) {
5454 l = SW_REDIS_TYPE_HASH;
5455 } else {
5456 l = SW_REDIS_TYPE_NOT_FOUND;
5457 }
5458 ZVAL_LONG(return_value, l);
5459 } else {
5460 ZVAL_TRUE(return_value);
5461 }
5462 } else {
5463 ZVAL_FALSE(return_value);
5464 zend_update_property_long(
5465 swoole_redis_coro_ce, SW_Z8_OBJ_P(redis->zobject), ZEND_STRL("errType"), redis->context->err);
5466 zend_update_property_long(swoole_redis_coro_ce,
5467 SW_Z8_OBJ_P(redis->zobject),
5468 ZEND_STRL("errCode"),
5469 sw_redis_convert_err(redis->context->err));
5470 zend_update_property_string(
5471 swoole_redis_coro_ce, SW_Z8_OBJ_P(redis->zobject), ZEND_STRL("errMsg"), redis->context->errstr);
5472 }
5473 break;
5474
5475 case REDIS_REPLY_STRING:
5476 if (redis->serialize) {
5477 char *reserve_str = reply->str;
5478 php_unserialize_data_t s_ht;
5479 PHP_VAR_UNSERIALIZE_INIT(s_ht);
5480 if (!php_var_unserialize(return_value,
5481 (const unsigned char **) &reply->str,
5482 (const unsigned char *) reply->str + reply->len,
5483 &s_ht)) {
5484 ZVAL_STRINGL(return_value, reply->str, reply->len);
5485 }
5486 PHP_VAR_UNSERIALIZE_DESTROY(s_ht);
5487 reply->str = reserve_str;
5488 } else {
5489 ZVAL_STRINGL(return_value, reply->str, reply->len);
5490 }
5491 break;
5492
5493 case REDIS_REPLY_ARRAY:
5494 array_init(return_value);
5495 for (j = 0; j < (int) reply->elements; j++) {
5496 swoole_redis_coro_parse_result(redis, val, reply->element[j]);
5497 (void) add_next_index_zval(return_value, val);
5498 }
5499 break;
5500
5501 case REDIS_REPLY_NIL:
5502 default:
5503 ZVAL_NULL(return_value);
5504 return;
5505 }
5506 }
5507