|
32 | 32 | #include "ext/session/php_session.h"
|
33 | 33 | #endif
|
34 | 34 |
|
| 35 | +#include <ext/standard/php_smart_str.h> |
| 36 | +#include <ext/standard/php_var.h> |
| 37 | +#include <ext/standard/php_math.h> |
| 38 | + |
35 | 39 | #include "library.h"
|
36 | 40 |
|
37 | 41 | #define R_SUB_CALLBACK_CLASS_TYPE 1
|
@@ -3191,22 +3195,83 @@ PHP_METHOD(Redis, zAdd) {
|
3191 | 3195 | char *key, *val;
|
3192 | 3196 | int val_free, key_free = 0;
|
3193 | 3197 | zval *z_value;
|
| 3198 | + char *dbl_str; |
| 3199 | + int dbl_len; |
3194 | 3200 |
|
3195 |
| - if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Osdz", |
3196 |
| - &object, redis_ce, &key, &key_len, &score, &z_value) == FAILURE) { |
| 3201 | + zval ***args; |
| 3202 | + int argc, i; |
| 3203 | + |
| 3204 | + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os*", |
| 3205 | + &object, redis_ce, &key, &key_len, &args, &argc) == FAILURE) { |
3197 | 3206 | RETURN_FALSE;
|
3198 | 3207 | }
|
3199 | 3208 |
|
3200 | 3209 | if (redis_sock_get(object, &redis_sock TSRMLS_CC) < 0) {
|
3201 | 3210 | RETURN_FALSE;
|
3202 | 3211 | }
|
3203 | 3212 |
|
3204 |
| - val_free = redis_serialize(redis_sock, z_value, &val, &val_len TSRMLS_CC); |
| 3213 | + /* need (score, value, score, value...) */ |
| 3214 | + if (argc % 2 != 0) { |
| 3215 | + RETURN_FALSE; |
| 3216 | + } |
| 3217 | + |
3205 | 3218 | key_free = redis_key_prefix(redis_sock, &key, &key_len TSRMLS_CC);
|
3206 |
| - cmd_len = redis_cmd_format_static(&cmd, "ZADD", "sfs", key, key_len, score, val, val_len); |
3207 |
| - if(val_free) efree(val); |
| 3219 | + |
| 3220 | + /* start building the command */ |
| 3221 | + smart_str buf = {0}; |
| 3222 | + smart_str_appendc(&buf, '*'); |
| 3223 | + smart_str_append_long(&buf, argc + 2); /* +1 for command and +1 for key */ |
| 3224 | + smart_str_appendl(&buf, _NL, sizeof(_NL) - 1); |
| 3225 | + |
| 3226 | + /* add command name */ |
| 3227 | + smart_str_appendc(&buf, '$'); |
| 3228 | + smart_str_append_long(&buf, 4); |
| 3229 | + smart_str_appendl(&buf, _NL, sizeof(_NL) - 1); |
| 3230 | + smart_str_appendl(&buf, "ZADD", 4); |
| 3231 | + smart_str_appendl(&buf, _NL, sizeof(_NL) - 1); |
| 3232 | + |
| 3233 | + /* add key */ |
| 3234 | + smart_str_appendc(&buf, '$'); |
| 3235 | + smart_str_append_long(&buf, key_len); |
| 3236 | + smart_str_appendl(&buf, _NL, sizeof(_NL) - 1); |
| 3237 | + smart_str_appendl(&buf, key, key_len); |
| 3238 | + smart_str_appendl(&buf, _NL, sizeof(_NL) - 1); |
| 3239 | + |
| 3240 | + for(i = 0; i < argc; i +=2) { |
| 3241 | + convert_to_double(*args[i]); // convert score to double |
| 3242 | + val_free = redis_serialize(redis_sock, *args[i+1], &val, &val_len TSRMLS_CC); // possibly serialize value. |
| 3243 | + |
| 3244 | + /* add score */ |
| 3245 | + score = Z_DVAL_PP(args[i]); |
| 3246 | + dbl_str = _php_math_number_format(score, 8, '.', '\x00'); |
| 3247 | + dbl_len = strlen(dbl_str); |
| 3248 | + smart_str_appendc(&buf, '$'); |
| 3249 | + smart_str_append_long(&buf, dbl_len); |
| 3250 | + smart_str_appendl(&buf, _NL, sizeof(_NL) - 1); |
| 3251 | + smart_str_appendl(&buf, dbl_str, dbl_len); |
| 3252 | + smart_str_appendl(&buf, _NL, sizeof(_NL) - 1); |
| 3253 | + efree(dbl_str); |
| 3254 | + |
| 3255 | + /* add value */ |
| 3256 | + smart_str_appendc(&buf, '$'); |
| 3257 | + smart_str_append_long(&buf, val_len); |
| 3258 | + smart_str_appendl(&buf, _NL, sizeof(_NL) - 1); |
| 3259 | + smart_str_appendl(&buf, val, val_len); |
| 3260 | + smart_str_appendl(&buf, _NL, sizeof(_NL) - 1); |
| 3261 | + |
| 3262 | + if(val_free) efree(val); |
| 3263 | + } |
| 3264 | + |
| 3265 | + /* end string */ |
| 3266 | + smart_str_0(&buf); |
| 3267 | + cmd = buf.c; |
| 3268 | + cmd_len = buf.len; |
3208 | 3269 | if(key_free) efree(key);
|
3209 | 3270 |
|
| 3271 | + if(args) { |
| 3272 | + efree(args); |
| 3273 | + } |
| 3274 | + |
3210 | 3275 | REDIS_PROCESS_REQUEST(redis_sock, cmd, cmd_len);
|
3211 | 3276 | IF_ATOMIC() {
|
3212 | 3277 | redis_long_response(INTERNAL_FUNCTION_PARAM_PASSTHRU, redis_sock, NULL, NULL);
|
|
0 commit comments