Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commita2eef77

Browse files
Implement Valkey >= 8.1 IFEQ set option
Implement the new `IFEQ` `SET` option that will be included in `Valkey`8.1.See:valkey-io/valkey#1324
1 parentfaa4bc2 commita2eef77

File tree

4 files changed

+45
-4
lines changed

4 files changed

+45
-4
lines changed

‎redis_commands.c‎

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2293,7 +2293,8 @@ int redis_set_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
22932293
char**cmd,int*cmd_len,short*slot,void**ctx)
22942294
{
22952295
char*key=NULL,*exp_type=NULL,*set_type=NULL;
2296-
zval*z_value,*z_opts=NULL;
2296+
zend_string*ifeq=NULL,*tmp=NULL;
2297+
zval*z_value,*z_opts=NULL;
22972298
smart_stringcmdstr= {0};
22982299
zend_longexpire=-1;
22992300
zend_boolget=0;
@@ -2312,7 +2313,6 @@ int redis_set_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
23122313
returnFAILURE;
23132314
}
23142315

2315-
23162316
// Check for an options array
23172317
if (z_opts&&Z_TYPE_P(z_opts)==IS_ARRAY) {
23182318
HashTable*kt=Z_ARRVAL_P(z_opts);
@@ -2329,11 +2329,14 @@ int redis_set_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
23292329
zend_string_equals_literal_ci(zkey,"PXAT"))
23302330
) {
23312331
if (redis_try_get_expiry(v,&expire)==FAILURE||expire<1) {
2332+
zend_tmp_string_release(tmp);
23322333
setExpiryWarning(v);
23332334
returnFAILURE;
23342335
}
23352336

23362337
exp_type=ZSTR_VAL(zkey);
2338+
}elseif (zkey&& !ifeq&&zend_string_equals_literal_ci(zkey,"IFEQ")) {
2339+
ifeq=zval_get_tmp_string(v,&tmp);
23372340
}elseif (Z_TYPE_P(v)==IS_STRING) {
23382341
if (zend_string_equals_literal_ci(Z_STR_P(v),"KEEPTTL")) {
23392342
keep_ttl=1;
@@ -2348,6 +2351,7 @@ int redis_set_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
23482351
}ZEND_HASH_FOREACH_END();
23492352
}elseif (z_opts&&Z_TYPE_P(z_opts)!=IS_NULL) {
23502353
if (redis_try_get_expiry(z_opts,&expire)==FAILURE||expire<1) {
2354+
zend_tmp_string_release(tmp);
23512355
setExpiryWarning(z_opts);
23522356
returnFAILURE;
23532357
}
@@ -2356,18 +2360,28 @@ int redis_set_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
23562360
/* Protect the user from syntax errors but give them some info about what's wrong */
23572361
if (exp_type&&keep_ttl) {
23582362
php_error_docref(NULL,E_WARNING,"KEEPTTL can't be combined with EX or PX option");
2363+
zend_tmp_string_release(tmp);
2364+
returnFAILURE;
2365+
}
2366+
2367+
/* You can't use IFEQ with NX or XX */
2368+
if (set_type&&ifeq) {
2369+
php_error_docref(NULL,E_WARNING,"IFEQ can't be combined with NX or XX option");
2370+
zend_tmp_string_release(tmp);
23592371
returnFAILURE;
23602372
}
23612373

23622374
/* Backward compatibility: If we are passed no options except an EXPIRE ttl, we
23632375
* actually execute a SETEX command */
23642376
if (expire>0&& !exp_type&& !set_type&& !keep_ttl) {
23652377
*cmd_len=REDIS_CMD_SPPRINTF(cmd,"SETEX","klv",key,key_len,expire,z_value);
2378+
zend_tmp_string_release(tmp);
23662379
returnSUCCESS;
23672380
}
23682381

23692382
/* Calculate argc based on options set */
2370-
intargc=2+ (exp_type ?2 :0)+ (set_type!=NULL)+ (keep_ttl!=0)+get;
2383+
intargc=2+ (ifeq ?2 :0)+ (exp_type ?2 :0)+ (set_type!=NULL)+
2384+
(keep_ttl!=0)+get;
23712385

23722386
/* Initial SET <key> <value> */
23732387
redis_cmd_init_sstr(&cmdstr,argc,"SET",3);
@@ -2379,15 +2393,22 @@ int redis_set_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
23792393
redis_cmd_append_sstr_long(&cmdstr, (long)expire);
23802394
}
23812395

2382-
if (set_type)
2396+
if (ifeq) {
2397+
REDIS_CMD_APPEND_SSTR_STATIC(&cmdstr,"IFEQ");
2398+
redis_cmd_append_sstr_zstr(&cmdstr,ifeq);
2399+
}elseif (set_type) {
23832400
redis_cmd_append_sstr(&cmdstr,set_type,strlen(set_type));
2401+
}
2402+
23842403
if (keep_ttl)
23852404
redis_cmd_append_sstr(&cmdstr,"KEEPTTL",7);
23862405
if (get) {
23872406
REDIS_CMD_APPEND_SSTR_STATIC(&cmdstr,"GET");
23882407
*ctx=PHPREDIS_CTX_PTR;
23892408
}
23902409

2410+
zend_tmp_string_release(tmp);
2411+
23912412
/* Push command and length to the caller */
23922413
*cmd=cmdstr.c;
23932414
*cmd_len=cmdstr.len;

‎tests/RedisClusterTest.php‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ public function setUp() {
133133
$info =$this->redis->info(uniqid());
134134
$this->version =$info['redis_version'] ??'0.0.0';
135135
$this->is_keydb =$this->detectKeyDB($info);
136+
$this->is_valkey =$this->detectValkey($info);
136137
}
137138

138139
/* Override newInstance as we want a RedisCluster object */

‎tests/RedisTest.php‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,11 +67,16 @@ protected function detectKeyDB(array $info) {
6767
isset($info['mvcc_depth']);
6868
}
6969

70+
protectedfunctiondetectValkey(array$info) {
71+
returnisset($info['server_name']) &&$info['server_name'] ==='valkey';
72+
}
73+
7074
publicfunctionsetUp() {
7175
$this->redis =$this->newInstance();
7276
$info =$this->redis->info();
7377
$this->version = (isset($info['redis_version'])?$info['redis_version']:'0.0.0');
7478
$this->is_keydb =$this->detectKeyDB($info);
79+
$this->is_valkey =$this->detectValKey($info);
7580
}
7681

7782
protectedfunctionminVersionCheck($version) {
@@ -629,6 +634,19 @@ public function testExtendedSet() {
629634
$this->assertEquals('bar',$this->redis->set('foo','baz', ['GET']));
630635
}
631636

637+
/* Test Valkey >= 8.1 IFEQ SET option */
638+
publicfunctiontestValkeyIfEq() {
639+
if ( !$this->is_valkey || !$this->minVersionCheck('8.1.0'))
640+
$this->markTestSkipped();
641+
642+
$this->redis->del('foo');
643+
$this->assertTrue($this->redis->set('foo','bar'));
644+
$this->assertTrue($this->redis->set('foo','bar2', ['IFEQ' =>'bar']));
645+
$this->assertFalse($this->redis->set('foo','bar4', ['IFEQ' =>'bar3']));
646+
647+
$this->assertEquals('bar2',$this->redis->set('foo','bar3', ['IFEQ' =>'bar2','GET']));
648+
}
649+
632650
publicfunctiontestGetSet() {
633651
$this->redis->del('key');
634652
$this->assertFalse($this->redis->getSet('key','42'));

‎tests/TestSuite.php‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ class TestSuite
1616
/* Redis server version */
1717
protected$version;
1818
protectedbool$is_keydb;
19+
protectedbool$is_valkey;
1920

2021
privatestaticbool$colorize =false;
2122

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp