@@ -209,6 +209,7 @@ zend_function_entry redis_cluster_functions[] = {
209
209
PHP_ME (RedisCluster , randomkey , NULL , ZEND_ACC_PUBLIC )
210
210
PHP_ME (RedisCluster , ping , NULL , ZEND_ACC_PUBLIC )
211
211
PHP_ME (RedisCluster , echo , NULL , ZEND_ACC_PUBLIC )
212
+ PHP_ME (RedisCluster , command , NULL , ZEND_ACC_PUBLIC )
212
213
PHP_ME (RedisCluster , rawcommand , NULL , ZEND_ACC_PUBLIC )
213
214
PHP_ME (RedisCluster , cluster , NULL , ZEND_ACC_PUBLIC )
214
215
PHP_ME (RedisCluster , client , NULL , ZEND_ACC_PUBLIC )
@@ -2199,27 +2200,8 @@ PHP_METHOD(RedisCluster, exec) {
2199
2200
CLUSTER_RESET_MULTI (c );
2200
2201
}
2201
2202
2202
- /* {{{ proto bool RedisCluster::discard() */
2203
- PHP_METHOD (RedisCluster , discard ) {
2204
- redisCluster * c = GET_CONTEXT ();
2205
-
2206
- if (CLUSTER_IS_ATOMIC (c )) {
2207
- php_error_docref (NULL TSRMLS_CC , E_WARNING , "Cluster is not in MULTI mode" );
2208
- RETURN_FALSE ;
2209
- }
2210
-
2211
- if (cluster_abort_exec (c TSRMLS_CC )< 0 ) {
2212
- CLUSTER_RESET_MULTI (c );
2213
- }
2214
-
2215
- CLUSTER_FREE_QUEUE (c );
2216
-
2217
- RETURN_TRUE ;
2218
- }
2219
-
2220
2203
/* Get a slot either by key (string) or host/port array */
2221
- static short
2222
- cluster_cmd_get_slot (redisCluster * c , zval * z_arg TSRMLS_DC )
2204
+ static short cluster_cmd_get_slot (redisCluster * c , zval * z_arg TSRMLS_DC )
2223
2205
{
2224
2206
int key_len , key_free ;
2225
2207
zval * * z_host , * * z_port , * z_tmp = NULL ;
@@ -2229,7 +2211,7 @@ cluster_cmd_get_slot(redisCluster *c, zval *z_arg TSRMLS_DC)
2229
2211
/* If it's a string, treat it as a key. Otherwise, look for a two
2230
2212
* element array */
2231
2213
if (Z_TYPE_P (z_arg )== IS_STRING || Z_TYPE_P (z_arg )== IS_LONG ||
2232
- Z_TYPE_P (z_arg )== IS_DOUBLE )
2214
+ Z_TYPE_P (z_arg )== IS_DOUBLE )
2233
2215
{
2234
2216
/* Allow for any scalar here */
2235
2217
if (Z_TYPE_P (z_arg ) != IS_STRING ) {
@@ -2253,7 +2235,7 @@ cluster_cmd_get_slot(redisCluster *c, zval *z_arg TSRMLS_DC)
2253
2235
zval_dtor (z_tmp );
2254
2236
efree (z_tmp );
2255
2237
}
2256
- } else if (Z_TYPE_P (z_arg ) == IS_ARRAY &&
2238
+ } else if (Z_TYPE_P (z_arg ) == IS_ARRAY &&
2257
2239
zend_hash_index_find (Z_ARRVAL_P (z_arg ),0 ,(void * * )& z_host )!= FAILURE &&
2258
2240
zend_hash_index_find (Z_ARRVAL_P (z_arg ),1 ,(void * * )& z_port )!= FAILURE &&
2259
2241
Z_TYPE_PP (z_host )== IS_STRING && Z_TYPE_PP (z_port )== IS_LONG )
@@ -2263,7 +2245,7 @@ cluster_cmd_get_slot(redisCluster *c, zval *z_arg TSRMLS_DC)
2263
2245
(unsigned short )Z_LVAL_PP (z_port ));
2264
2246
2265
2247
/* Inform the caller if they've passed bad data */
2266
- if (slot < 0 ) {
2248
+ if (slot < 0 ) {
2267
2249
php_error_docref (0 TSRMLS_CC , E_WARNING , "Unknown node %s:%ld" ,
2268
2250
Z_STRVAL_PP (z_host ), Z_LVAL_PP (z_port ));
2269
2251
}
@@ -2276,6 +2258,24 @@ cluster_cmd_get_slot(redisCluster *c, zval *z_arg TSRMLS_DC)
2276
2258
return slot ;
2277
2259
}
2278
2260
2261
+ /* {{{ proto bool RedisCluster::discard() */
2262
+ PHP_METHOD (RedisCluster , discard ) {
2263
+ redisCluster * c = GET_CONTEXT ();
2264
+
2265
+ if (CLUSTER_IS_ATOMIC (c )) {
2266
+ php_error_docref (NULL TSRMLS_CC , E_WARNING , "Cluster is not in MULTI mode" );
2267
+ RETURN_FALSE ;
2268
+ }
2269
+
2270
+ if (cluster_abort_exec (c TSRMLS_CC )< 0 ) {
2271
+ CLUSTER_RESET_MULTI (c );
2272
+ }
2273
+
2274
+ CLUSTER_FREE_QUEUE (c );
2275
+
2276
+ RETURN_TRUE ;
2277
+ }
2278
+
2279
2279
/* Generic handler for things we want directed at a given node, like SAVE,
2280
2280
* BGSAVE, FLUSHDB, FLUSHALL, etc */
2281
2281
static void
@@ -2856,7 +2856,7 @@ PHP_METHOD(RedisCluster, echo) {
2856
2856
rtype = CLUSTER_IS_ATOMIC (c ) ? TYPE_BULK : TYPE_LINE ;
2857
2857
if (cluster_send_slot (c ,slot ,cmd ,cmd_len ,rtype TSRMLS_CC )< 0 ) {
2858
2858
zend_throw_exception (redis_cluster_exception_ce ,
2859
- "Unable to send commnad at the specificed node" , 0 TSRMLS_CC );
2859
+ "Unable to send command at the specificed node" , 0 TSRMLS_CC );
2860
2860
efree (cmd );
2861
2861
RETURN_FALSE ;
2862
2862
}
@@ -2873,11 +2873,66 @@ PHP_METHOD(RedisCluster, echo) {
2873
2873
}
2874
2874
/* }}} */
2875
2875
2876
- /* {{{ proto array RedisCluster::rawcommand()
2877
- * proto array RedisCluster::rawcommand('INFO', string cmd)
2878
- * proto array RedisCluster::rawcommand('GETKEYS', array cmd_args) */
2876
+ /* {{{ proto mixed RedisCluster::rawcommand(string $key, string $cmd, [ $argv1 .. $argvN])
2877
+ * proto mixed RedisCluster::rawcommand(array $host_port, string $cmd, [ $argv1 .. $argvN]) */
2879
2878
PHP_METHOD (RedisCluster , rawcommand ) {
2880
- CLUSTER_PROCESS_CMD (rawcommand , cluster_variant_resp , 0 );
2879
+ REDIS_REPLY_TYPE rtype ;
2880
+ int argc = ZEND_NUM_ARGS (), cmd_len ;
2881
+ redisCluster * c = GET_CONTEXT ();
2882
+ char * cmd = NULL ;
2883
+ zval * * z_args ;
2884
+ short slot ;
2885
+
2886
+ /* Sanity check on our arguments */
2887
+ z_args = emalloc (argc * sizeof (zval * ));
2888
+ if (argc < 2 ) {
2889
+ php_error_docref (NULL TSRMLS_CC , E_WARNING ,
2890
+ "You must pass at least node information as well as at least a command." );
2891
+ efree (z_args );
2892
+ RETURN_FALSE ;
2893
+ } else if (zend_get_parameters_array (ht , argc , z_args ) == FAILURE ) {
2894
+ php_error_docref (NULL TSRMLS_CC , E_WARNING ,
2895
+ "Internal PHP error parsing method parameters." );
2896
+ efree (z_args );
2897
+ RETURN_FALSE ;
2898
+ } else if (redis_build_raw_cmd (z_args + 1 , argc - 1 , & cmd , & cmd_len TSRMLS_CC ) ||
2899
+ (slot = cluster_cmd_get_slot (c , z_args [0 ] TSRMLS_CC ))< 0 )
2900
+ {
2901
+ if (cmd ) efree (cmd );
2902
+ efree (z_args );
2903
+ RETURN_FALSE ;
2904
+ }
2905
+
2906
+ /* Free argument array */
2907
+ efree (z_args );
2908
+
2909
+ /* Direct the command */
2910
+ rtype = CLUSTER_IS_ATOMIC (c ) ? TYPE_EOF : TYPE_LINE ;
2911
+ if (cluster_send_slot (c ,slot ,cmd ,cmd_len ,rtype TSRMLS_CC )< 0 ) {
2912
+ zend_throw_exception (redis_cluster_exception_ce ,
2913
+ "Unable to send command to the specified node" , 0 TSRMLS_CC );
2914
+ efree (cmd );
2915
+ efree (z_args );
2916
+ RETURN_FALSE ;
2917
+ }
2918
+
2919
+ /* Process variant response */
2920
+ if (CLUSTER_IS_ATOMIC (c )) {
2921
+ cluster_variant_resp (INTERNAL_FUNCTION_PARAM_PASSTHRU , c , NULL );
2922
+ } else {
2923
+ void * ctx = NULL ;
2924
+ CLUSTER_ENQUEUE_RESPONSE (c , slot , cluster_variant_resp , ctx );
2925
+ }
2926
+
2927
+ efree (cmd );
2928
+ }
2929
+ /* }}} */
2930
+
2931
+ /* {{{ proto array RedisCluster::command()
2932
+ * proto array RedisCluster::command('INFO', string cmd)
2933
+ * proto array RedisCluster::command('GETKEYS', array cmd_args) */
2934
+ PHP_METHOD (RedisCluster , command ) {
2935
+ CLUSTER_PROCESS_CMD (command , cluster_variant_resp , 0 );
2881
2936
}
2882
2937
/* }}} */
2883
2938
0 commit comments