Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit f3a4083

Browse files
EVAL_RO and EVALSHA_RO
Implement Redis 7.0.0's readonly eval variants See: #2068
1 parent 5dcf3f8 commit f3a4083

9 files changed

Lines changed: 131 additions & 12 deletions

redis.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2877,16 +2877,25 @@ PHP_METHOD(Redis, pubsub) {
28772877
}
28782878

28792879
/* {{{ proto variant Redis::eval(string script, [array keys, long num_keys]) */
2880-
PHP_METHOD(Redis, eval)
2881-
{
2880+
PHP_METHOD(Redis, eval) {
28822881
REDIS_PROCESS_KW_CMD("EVAL", redis_eval_cmd, redis_read_raw_variant_reply);
28832882
}
28842883

2884+
/* {{{ proto variant Redis::eval_ro(string script, [array keys, long num_keys]) */
2885+
PHP_METHOD(Redis, eval_ro) {
2886+
REDIS_PROCESS_KW_CMD("EVAL_RO", redis_eval_cmd, redis_read_raw_variant_reply);
2887+
}
2888+
28852889
/* {{{ proto variant Redis::evalsha(string sha1, [array keys, long num_keys]) */
28862890
PHP_METHOD(Redis, evalsha) {
28872891
REDIS_PROCESS_KW_CMD("EVALSHA", redis_eval_cmd, redis_read_raw_variant_reply);
28882892
}
28892893

2894+
/* {{{ proto variant Redis::evalsha_ro(string sha1, [array keys, long num_keys]) */
2895+
PHP_METHOD(Redis, evalsha_ro) {
2896+
REDIS_PROCESS_KW_CMD("EVALSHA_RO", redis_eval_cmd, redis_read_raw_variant_reply);
2897+
}
2898+
28902899
/* {{{ proto status Redis::script('flush')
28912900
* {{{ proto status Redis::script('kill')
28922901
* {{{ proto string Redis::script('load', lua_script)

redis.stub.php

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,9 +131,53 @@ public function dump(string $key): Redis|string;
131131

132132
public function echo(string $str): Redis|string|false;
133133

134-
public function eval(string $script, array $keys = null, int $num_keys = 0): mixed;
134+
/**
135+
* Execute a LUA script on the redis server.
136+
*
137+
* @see https://redis.io/commands/eval/
138+
*
139+
* @param string $script A string containing the lua script
140+
* @param array $args An array of arguments to pass to this script
141+
* @param int $num_keys How many of the arguments are keys. This is needed
142+
* as redis distinguishes between key name arguments
143+
* and other data.
144+
*
145+
* @return mixed LUA scripts may return arbitrary data so this method can return
146+
* strings, arrays, nested arrays, etc.
147+
*/
148+
public function eval(string $script, array $args = [], int $num_keys = 0): mixed;
149+
150+
/**
151+
* This is simply the read-only variant of eval, meaning the unerlying script
152+
* may not modify data in redis.
153+
*
154+
* @see Redis::eval()
155+
*/
156+
public function eval_ro(string $script_sha, array $args = [], int $num_keys = 0): mixed;
135157

136-
public function evalsha(string $sha1, array $keys = null, int $num_keys = 0): mixed;
158+
/**
159+
* Execute a LUA script on the server but instead of sending the script, send
160+
* the sha1 hash of the script.
161+
*
162+
* @see https://redis.io/commands/evalsha/
163+
* @see Redis::eval();
164+
*
165+
* @param string $script_sha The sha1() hash of the lua code. Note that the script
166+
* must already exist on the server, either having been
167+
* loaded with `SCRIPT LOAD` or having been executed directly
168+
* with `EVAL` first.
169+
* @param array $args Arguments to send to the script.
170+
* @param int $num_keys The number of arguments that are keys
171+
*/
172+
public function evalsha(string $sha1, array $args = [], int $num_keys = 0): mixed;
173+
174+
/**
175+
* This is simply the read-only variant of evalsha, meaning the unerlying script
176+
* may not modify data in redis.
177+
*
178+
* @see Redis::evalsha()
179+
*/
180+
public function evalsha_ro(string $sha1, array $args = [], int $num_keys = 0): mixed;
137181

138182
public function exec(): Redis|array|false;
139183

redis_arginfo.h

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* This is a generated file, edit the .stub.php file instead.
2-
* Stub hash: 3ffe58fd2c74dcb474adf0b983f503d798c975d8 */
2+
* Stub hash: a27d28648f2d1a77237305083f36abc5e071f5b1 */
33

44
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Redis___construct, 0, 0, 0)
55
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, options, IS_ARRAY, 0, "null")
@@ -181,16 +181,24 @@ ZEND_END_ARG_INFO()
181181

182182
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Redis_eval, 0, 1, IS_MIXED, 0)
183183
ZEND_ARG_TYPE_INFO(0, script, IS_STRING, 0)
184-
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, keys, IS_ARRAY, 0, "null")
184+
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, args, IS_ARRAY, 0, "[]")
185+
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, num_keys, IS_LONG, 0, "0")
186+
ZEND_END_ARG_INFO()
187+
188+
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Redis_eval_ro, 0, 1, IS_MIXED, 0)
189+
ZEND_ARG_TYPE_INFO(0, script_sha, IS_STRING, 0)
190+
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, args, IS_ARRAY, 0, "[]")
185191
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, num_keys, IS_LONG, 0, "0")
186192
ZEND_END_ARG_INFO()
187193

188194
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Redis_evalsha, 0, 1, IS_MIXED, 0)
189195
ZEND_ARG_TYPE_INFO(0, sha1, IS_STRING, 0)
190-
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, keys, IS_ARRAY, 0, "null")
196+
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, args, IS_ARRAY, 0, "[]")
191197
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, num_keys, IS_LONG, 0, "0")
192198
ZEND_END_ARG_INFO()
193199

200+
#define arginfo_class_Redis_evalsha_ro arginfo_class_Redis_evalsha
201+
194202
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_Redis_exec, 0, 0, Redis, MAY_BE_ARRAY|MAY_BE_FALSE)
195203
ZEND_END_ARG_INFO()
196204

@@ -1128,7 +1136,9 @@ ZEND_METHOD(Redis, discard);
11281136
ZEND_METHOD(Redis, dump);
11291137
ZEND_METHOD(Redis, echo);
11301138
ZEND_METHOD(Redis, eval);
1139+
ZEND_METHOD(Redis, eval_ro);
11311140
ZEND_METHOD(Redis, evalsha);
1141+
ZEND_METHOD(Redis, evalsha_ro);
11321142
ZEND_METHOD(Redis, exec);
11331143
ZEND_METHOD(Redis, exists);
11341144
ZEND_METHOD(Redis, expire);
@@ -1369,7 +1379,9 @@ static const zend_function_entry class_Redis_methods[] = {
13691379
ZEND_ME(Redis, dump, arginfo_class_Redis_dump, ZEND_ACC_PUBLIC)
13701380
ZEND_ME(Redis, echo, arginfo_class_Redis_echo, ZEND_ACC_PUBLIC)
13711381
ZEND_ME(Redis, eval, arginfo_class_Redis_eval, ZEND_ACC_PUBLIC)
1382+
ZEND_ME(Redis, eval_ro, arginfo_class_Redis_eval_ro, ZEND_ACC_PUBLIC)
13721383
ZEND_ME(Redis, evalsha, arginfo_class_Redis_evalsha, ZEND_ACC_PUBLIC)
1384+
ZEND_ME(Redis, evalsha_ro, arginfo_class_Redis_evalsha_ro, ZEND_ACC_PUBLIC)
13731385
ZEND_ME(Redis, exec, arginfo_class_Redis_exec, ZEND_ACC_PUBLIC)
13741386
ZEND_ME(Redis, exists, arginfo_class_Redis_exists, ZEND_ACC_PUBLIC)
13751387
ZEND_ME(Redis, expire, arginfo_class_Redis_expire, ZEND_ACC_PUBLIC)

redis_cluster.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1707,12 +1707,24 @@ PHP_METHOD(RedisCluster, eval) {
17071707
}
17081708
/* }}} */
17091709

1710+
/* {{{ proto mixed RedisCluster::eval_ro(string script, [array args, int numkeys) */
1711+
PHP_METHOD(RedisCluster, eval_ro) {
1712+
CLUSTER_PROCESS_KW_CMD("EVAL_RO", redis_eval_cmd, cluster_variant_raw_resp, 1);
1713+
}
1714+
/* }}} */
1715+
17101716
/* {{{ proto mixed RedisCluster::evalsha(string sha, [array args, int numkeys]) */
17111717
PHP_METHOD(RedisCluster, evalsha) {
17121718
CLUSTER_PROCESS_KW_CMD("EVALSHA", redis_eval_cmd, cluster_variant_raw_resp, 0);
17131719
}
17141720
/* }}} */
17151721

1722+
/* {{{ proto mixed RedisCluster::evalsha_ro(string sha, [array args, int numkeys]) */
1723+
PHP_METHOD(RedisCluster, evalsha_ro) {
1724+
CLUSTER_PROCESS_KW_CMD("EVALSHA_RO", redis_eval_cmd, cluster_variant_raw_resp, 1);
1725+
}
1726+
1727+
/* }}} */
17161728
/* Commands that do not interact with Redis, but just report stuff about
17171729
* various options, etc */
17181730

redis_cluster.stub.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,12 @@ public function echo(string|array $key_or_address, string $msg): RedisCluster|st
101101

102102
public function eval(string $script, array $args = [], int $num_keys = 0): mixed;
103103

104+
public function eval_ro(string $script, array $args = [], int $num_keys = 0): mixed;
105+
104106
public function evalsha(string $script_sha, array $args = [], int $num_keys = 0): mixed;
105107

108+
public function evalsha_ro(string $script_sha, array $args = [], int $num_keys = 0): mixed;
109+
106110
public function exec(): array|false;
107111

108112
public function exists(mixed $key, mixed ...$other_keys): RedisCluster|int|bool;

redis_cluster_arginfo.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* This is a generated file, edit the .stub.php file instead.
2-
* Stub hash: d3d58cb90bf0884a4153cd01f3d0850b42fcd910 */
2+
* Stub hash: 7a2f14794870618a17273a2ed9f60d81449c82af */
33

44
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_RedisCluster___construct, 0, 0, 1)
55
ZEND_ARG_TYPE_INFO(0, name, IS_STRING, 1)
@@ -187,12 +187,16 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_RedisCluster_eval, 0, 1, I
187187
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, num_keys, IS_LONG, 0, "0")
188188
ZEND_END_ARG_INFO()
189189

190+
#define arginfo_class_RedisCluster_eval_ro arginfo_class_RedisCluster_eval
191+
190192
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_RedisCluster_evalsha, 0, 1, IS_MIXED, 0)
191193
ZEND_ARG_TYPE_INFO(0, script_sha, IS_STRING, 0)
192194
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, args, IS_ARRAY, 0, "[]")
193195
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, num_keys, IS_LONG, 0, "0")
194196
ZEND_END_ARG_INFO()
195197

198+
#define arginfo_class_RedisCluster_evalsha_ro arginfo_class_RedisCluster_evalsha
199+
196200
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_class_RedisCluster_exec, 0, 0, MAY_BE_ARRAY|MAY_BE_FALSE)
197201
ZEND_END_ARG_INFO()
198202

@@ -971,7 +975,9 @@ ZEND_METHOD(RedisCluster, discard);
971975
ZEND_METHOD(RedisCluster, dump);
972976
ZEND_METHOD(RedisCluster, echo);
973977
ZEND_METHOD(RedisCluster, eval);
978+
ZEND_METHOD(RedisCluster, eval_ro);
974979
ZEND_METHOD(RedisCluster, evalsha);
980+
ZEND_METHOD(RedisCluster, evalsha_ro);
975981
ZEND_METHOD(RedisCluster, exec);
976982
ZEND_METHOD(RedisCluster, exists);
977983
ZEND_METHOD(RedisCluster, expire);
@@ -1174,7 +1180,9 @@ static const zend_function_entry class_RedisCluster_methods[] = {
11741180
ZEND_ME(RedisCluster, dump, arginfo_class_RedisCluster_dump, ZEND_ACC_PUBLIC)
11751181
ZEND_ME(RedisCluster, echo, arginfo_class_RedisCluster_echo, ZEND_ACC_PUBLIC)
11761182
ZEND_ME(RedisCluster, eval, arginfo_class_RedisCluster_eval, ZEND_ACC_PUBLIC)
1183+
ZEND_ME(RedisCluster, eval_ro, arginfo_class_RedisCluster_eval_ro, ZEND_ACC_PUBLIC)
11771184
ZEND_ME(RedisCluster, evalsha, arginfo_class_RedisCluster_evalsha, ZEND_ACC_PUBLIC)
1185+
ZEND_ME(RedisCluster, evalsha_ro, arginfo_class_RedisCluster_evalsha_ro, ZEND_ACC_PUBLIC)
11781186
ZEND_ME(RedisCluster, exec, arginfo_class_RedisCluster_exec, ZEND_ACC_PUBLIC)
11791187
ZEND_ME(RedisCluster, exists, arginfo_class_RedisCluster_exists, ZEND_ACC_PUBLIC)
11801188
ZEND_ME(RedisCluster, expire, arginfo_class_RedisCluster_expire, ZEND_ACC_PUBLIC)

redis_cluster_legacy_arginfo.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* This is a generated file, edit the .stub.php file instead.
2-
* Stub hash: d3d58cb90bf0884a4153cd01f3d0850b42fcd910 */
2+
* Stub hash: 7a2f14794870618a17273a2ed9f60d81449c82af */
33

44
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_RedisCluster___construct, 0, 0, 1)
55
ZEND_ARG_INFO(0, name)
@@ -165,12 +165,16 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_RedisCluster_eval, 0, 0, 1)
165165
ZEND_ARG_INFO(0, num_keys)
166166
ZEND_END_ARG_INFO()
167167

168+
#define arginfo_class_RedisCluster_eval_ro arginfo_class_RedisCluster_eval
169+
168170
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_RedisCluster_evalsha, 0, 0, 1)
169171
ZEND_ARG_INFO(0, script_sha)
170172
ZEND_ARG_INFO(0, args)
171173
ZEND_ARG_INFO(0, num_keys)
172174
ZEND_END_ARG_INFO()
173175

176+
#define arginfo_class_RedisCluster_evalsha_ro arginfo_class_RedisCluster_evalsha
177+
174178
#define arginfo_class_RedisCluster_exec arginfo_class_RedisCluster__masters
175179

176180
#define arginfo_class_RedisCluster_exists arginfo_class_RedisCluster_del
@@ -828,7 +832,9 @@ ZEND_METHOD(RedisCluster, discard);
828832
ZEND_METHOD(RedisCluster, dump);
829833
ZEND_METHOD(RedisCluster, echo);
830834
ZEND_METHOD(RedisCluster, eval);
835+
ZEND_METHOD(RedisCluster, eval_ro);
831836
ZEND_METHOD(RedisCluster, evalsha);
837+
ZEND_METHOD(RedisCluster, evalsha_ro);
832838
ZEND_METHOD(RedisCluster, exec);
833839
ZEND_METHOD(RedisCluster, exists);
834840
ZEND_METHOD(RedisCluster, expire);
@@ -1031,7 +1037,9 @@ static const zend_function_entry class_RedisCluster_methods[] = {
10311037
ZEND_ME(RedisCluster, dump, arginfo_class_RedisCluster_dump, ZEND_ACC_PUBLIC)
10321038
ZEND_ME(RedisCluster, echo, arginfo_class_RedisCluster_echo, ZEND_ACC_PUBLIC)
10331039
ZEND_ME(RedisCluster, eval, arginfo_class_RedisCluster_eval, ZEND_ACC_PUBLIC)
1040+
ZEND_ME(RedisCluster, eval_ro, arginfo_class_RedisCluster_eval_ro, ZEND_ACC_PUBLIC)
10341041
ZEND_ME(RedisCluster, evalsha, arginfo_class_RedisCluster_evalsha, ZEND_ACC_PUBLIC)
1042+
ZEND_ME(RedisCluster, evalsha_ro, arginfo_class_RedisCluster_evalsha_ro, ZEND_ACC_PUBLIC)
10351043
ZEND_ME(RedisCluster, exec, arginfo_class_RedisCluster_exec, ZEND_ACC_PUBLIC)
10361044
ZEND_ME(RedisCluster, exists, arginfo_class_RedisCluster_exists, ZEND_ACC_PUBLIC)
10371045
ZEND_ME(RedisCluster, expire, arginfo_class_RedisCluster_expire, ZEND_ACC_PUBLIC)

redis_legacy_arginfo.h

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* This is a generated file, edit the .stub.php file instead.
2-
* Stub hash: 3ffe58fd2c74dcb474adf0b983f503d798c975d8 */
2+
* Stub hash: a27d28648f2d1a77237305083f36abc5e071f5b1 */
33

44
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Redis___construct, 0, 0, 0)
55
ZEND_ARG_INFO(0, options)
@@ -165,16 +165,24 @@ ZEND_END_ARG_INFO()
165165

166166
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Redis_eval, 0, 0, 1)
167167
ZEND_ARG_INFO(0, script)
168-
ZEND_ARG_INFO(0, keys)
168+
ZEND_ARG_INFO(0, args)
169+
ZEND_ARG_INFO(0, num_keys)
170+
ZEND_END_ARG_INFO()
171+
172+
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Redis_eval_ro, 0, 0, 1)
173+
ZEND_ARG_INFO(0, script_sha)
174+
ZEND_ARG_INFO(0, args)
169175
ZEND_ARG_INFO(0, num_keys)
170176
ZEND_END_ARG_INFO()
171177

172178
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Redis_evalsha, 0, 0, 1)
173179
ZEND_ARG_INFO(0, sha1)
174-
ZEND_ARG_INFO(0, keys)
180+
ZEND_ARG_INFO(0, args)
175181
ZEND_ARG_INFO(0, num_keys)
176182
ZEND_END_ARG_INFO()
177183

184+
#define arginfo_class_Redis_evalsha_ro arginfo_class_Redis_evalsha
185+
178186
#define arginfo_class_Redis_exec arginfo_class_Redis___destruct
179187

180188
#define arginfo_class_Redis_exists arginfo_class_Redis_del
@@ -965,7 +973,9 @@ ZEND_METHOD(Redis, discard);
965973
ZEND_METHOD(Redis, dump);
966974
ZEND_METHOD(Redis, echo);
967975
ZEND_METHOD(Redis, eval);
976+
ZEND_METHOD(Redis, eval_ro);
968977
ZEND_METHOD(Redis, evalsha);
978+
ZEND_METHOD(Redis, evalsha_ro);
969979
ZEND_METHOD(Redis, exec);
970980
ZEND_METHOD(Redis, exists);
971981
ZEND_METHOD(Redis, expire);
@@ -1206,7 +1216,9 @@ static const zend_function_entry class_Redis_methods[] = {
12061216
ZEND_ME(Redis, dump, arginfo_class_Redis_dump, ZEND_ACC_PUBLIC)
12071217
ZEND_ME(Redis, echo, arginfo_class_Redis_echo, ZEND_ACC_PUBLIC)
12081218
ZEND_ME(Redis, eval, arginfo_class_Redis_eval, ZEND_ACC_PUBLIC)
1219+
ZEND_ME(Redis, eval_ro, arginfo_class_Redis_eval_ro, ZEND_ACC_PUBLIC)
12091220
ZEND_ME(Redis, evalsha, arginfo_class_Redis_evalsha, ZEND_ACC_PUBLIC)
1221+
ZEND_ME(Redis, evalsha_ro, arginfo_class_Redis_evalsha_ro, ZEND_ACC_PUBLIC)
12101222
ZEND_ME(Redis, exec, arginfo_class_Redis_exec, ZEND_ACC_PUBLIC)
12111223
ZEND_ME(Redis, exists, arginfo_class_Redis_exists, ZEND_ACC_PUBLIC)
12121224
ZEND_ME(Redis, expire, arginfo_class_Redis_expire, ZEND_ACC_PUBLIC)

tests/RedisTest.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5247,6 +5247,11 @@ public function testEval() {
52475247
$this->markTestSkipped();
52485248
}
52495249

5250+
/* The eval_ro method uses the same underlying handlers as eval so we
5251+
only need to verify we can call it. */
5252+
if ($this->minVersionCheck('7.0.0'))
5253+
$this->assertEquals('1.55', $this->redis->eval_ro("return '1.55'"));
5254+
52505255
// Basic single line response tests
52515256
$this->assertTrue(1 == $this->redis->eval('return 1'));
52525257
$this->assertTrue(1.55 == $this->redis->eval("return '1.55'"));
@@ -5383,6 +5388,11 @@ public function testEvalSHA() {
53835388
$this->assertTrue(false === $this->redis->evalsha($scr));
53845389
$this->assertTrue(1 === $this->redis->eval($scr));
53855390
$this->assertTrue(1 === $this->redis->evalsha($sha));
5391+
5392+
/* Our evalsha_ro handler is the same as evalsha so just make sure
5393+
we can invoke the command */
5394+
if ($this->minVersionCheck('7.0.0'))
5395+
$this->assertEquals(1, $this->redis->evalsha_ro($sha));
53865396
}
53875397

53885398
public function testSerialize() {

0 commit comments

Comments
 (0)