diff options
Diffstat (limited to 'redis_commands.c')
-rw-r--r-- | redis_commands.c | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/redis_commands.c b/redis_commands.c index 2861a134..e17fce1f 100644 --- a/redis_commands.c +++ b/redis_commands.c @@ -3927,6 +3927,79 @@ int redis_object_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, return SUCCESS; } +int +redis_geoadd_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, + char **cmd, int *cmd_len, short *slot, void **ctx) +{ + zval *z_args, *z_ele; + smart_string cmdstr = {0}; + zend_bool ch = 0; + zend_string *zstr; + char *mode = NULL; + int argc, i; + + // We at least need a key and one value + if ((argc = ZEND_NUM_ARGS()) < 5 || argc % 3 != 2) { + zend_wrong_param_count(); + return FAILURE; + } + + // Make sure we at least have a key, and we can get other args + z_args = ecalloc(argc, sizeof(*z_args)); + if (zend_get_parameters_array(ht, argc, z_args) == FAILURE) { + efree(z_args); + return FAILURE; + } + + if (Z_TYPE(z_args[1]) != IS_NULL) { + if (Z_TYPE(z_args[1]) != IS_ARRAY) { + php_error_docref(NULL, E_WARNING, "Invalid options value"); + efree(z_args); + return FAILURE; + } + ZEND_HASH_FOREACH_VAL(Z_ARRVAL(z_args[1]), z_ele) { + ZVAL_DEREF(z_ele); + if (Z_TYPE_P(z_ele) == IS_STRING) { + if (zend_string_equals_literal_ci(Z_STR_P(z_ele), "NX") || + zend_string_equals_literal_ci(Z_STR_P(z_ele), "XX")) + { + mode = Z_STRVAL_P(z_ele); + } else if (zend_string_equals_literal_ci(Z_STR_P(z_ele), "CH")) { + ch = 1; + } + } + } ZEND_HASH_FOREACH_END(); + } + + /* Initialize our command */ + REDIS_CMD_INIT_SSTR_STATIC(&cmdstr, argc - 1 + (mode != NULL) + ch, "GEOADD"); + + /* Append key */ + zstr = zval_get_string(&z_args[0]); + redis_cmd_append_sstr_key(&cmdstr, ZSTR_VAL(zstr), ZSTR_LEN(zstr), redis_sock, slot); + zend_string_release(zstr); + + /* Append options */ + if (mode != NULL) { + redis_cmd_append_sstr(&cmdstr, mode, strlen(mode)); + } + REDIS_CMD_APPEND_SSTR_OPT_STATIC(&cmdstr, ch, "CH"); + + /* Append members */ + for (i = 2; i < argc; ++i) { + redis_cmd_append_sstr_zval(&cmdstr, &z_args[i], redis_sock); + } + + // Cleanup arg array + efree(z_args); + + // Push out values + *cmd = cmdstr.c; + *cmd_len = cmdstr.len; + + return SUCCESS; +} + /* GEODIST */ int redis_geodist_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, char **cmd, int *cmd_len, short *slot, void **ctx) |