Merge remote-tracking branch 'vostok4/master'

Conflicts:
	CREDITS
	README.markdown
	config.w32
	library.c
	library.h
	package.xml
	redis.c
	redis_array.c
	redis_array.h
	redis_array_impl.c
	redis_array_impl.h
	tests/TestRedis.php
This commit is contained in:
Anatol Belski
2014-07-01 16:45:09 +02:00
12 changed files with 673 additions and 589 deletions
+4 -1
View File
@@ -1,2 +1,5 @@
Redis client extension for PHP
Alfonso Jimenez, Nasreddine Bouafif, Nicolas Favre-Felix, Michael Grunder
Alfonso Jimenez (yo@alfonsojimenez.com)
Nasreddine Bouafif (n.bouafif@owlient.eu)
Nicolas Favre-Felix (n.favre-felix@owlient.eu)
Michael Grunder (michael.grunder@gmail.com)
+34 -31
View File
@@ -1,31 +1,34 @@
// vim: ft=javascript:
ARG_ENABLE("redis", "whether to enable redis support", "yes");
ARG_ENABLE("redis-session", "whether to enable sessions", "yes");
ARG_ENABLE("redis-igbinary", "whether to enable igbinary serializer support", "no");
if (PHP_REDIS != "no") {
EXTENSION("redis", "redis.c library.c redis_array_impl.c redis_array.c");
AC_DEFINE("HAVE_REDIS", 1);
ADD_FLAG("CFLAGS_REDIS", ' /D PHP_EXPORTS=1 ');
if (PHP_REDIS_SESSION != "no") {
ADD_SOURCES(configure_module_dirname, "redis_session.c", "redis");
ADD_EXTENSION_DEP("redis", "session");
ADD_FLAG("CFLAGS_REDIS", ' /D PHP_SESSION=1 ');
AC_DEFINE("HAVE_REDIS_SESSION", 1);
}
if (PHP_REDIS_IGBINARY != "no") {
if (CHECK_HEADER_ADD_INCLUDE("igbinary.h", "CFLAGS_REDIS", configure_module_dirname + "\\..\\igbinary")) {
ADD_EXTENSION_DEP("redis", "igbinary");
AC_DEFINE("HAVE_REDIS_IGBINARY", 1);
} else {
WARNING("redis igbinary support not enabled");
}
}
}
// vim: ft=javascript:
ARG_ENABLE("redis", "whether to enable redis support", "yes");
ARG_ENABLE("redis-session", "whether to enable sessions", "yes");
ARG_ENABLE("redis-igbinary", "whether to enable igbinary serializer support", "no");
if (PHP_REDIS != "no") {
var sources = "redis.c library.c redis_array.c redis_array_impl.c";
if (PHP_REDIS_SESSION != "no") {
ADD_SOURCES(configure_module_dirname, "redis_session.c", "redis");
ADD_EXTENSION_DEP("redis", "session");
ADD_FLAG("CFLAGS_REDIS", ' /D PHP_SESSION=1 ');
AC_DEFINE("HAVE_REDIS_SESSION", 1);
}
if (PHP_REDIS_IGBINARY != "no") {
if (CHECK_HEADER_ADD_INCLUDE("igbinary.h", "CFLAGS_REDIS", configure_module_dirname + "\\..\\igbinary")) {
ADD_EXTENSION_DEP("redis", "igbinary");
AC_DEFINE("HAVE_REDIS_IGBINARY", 1);
} else {
WARNING("redis igbinary support not enabled");
}
}
if (PHP_REDIS_IGBINARY != "no") {
CHECK_HEADER_ADD_INCLUDE("igbinary.h", "CFLAGS_REDIS", "ext\\igbinary");
AC_DEFINE('HAVE_REDIS_IGBINARY', 1);
ADD_EXTENSION_DEP('redis', 'igbinary');
}
EXTENSION("redis", sources);
}
+151 -141
View File
@@ -26,6 +26,12 @@ PHPAPI int usleep(unsigned int useconds);
# endif
#endif
#ifdef _MSC_VER
#define atoll _atoi64
#define random rand
#define usleep Sleep
#endif
#define UNSERIALIZE_ONLY_VALUES 0
#define UNSERIALIZE_ALL 1
@@ -33,7 +39,7 @@ extern zend_class_entry *redis_ce;
extern zend_class_entry *redis_exception_ce;
extern zend_class_entry *spl_ce_RuntimeException;
PHPAPI void redis_stream_close(RedisSock *redis_sock TSRMLS_DC) {
PHP_REDIS_API void redis_stream_close(RedisSock *redis_sock TSRMLS_DC) {
if (!redis_sock->persistent) {
php_stream_close(redis_sock->stream);
} else {
@@ -41,7 +47,7 @@ PHPAPI void redis_stream_close(RedisSock *redis_sock TSRMLS_DC) {
}
}
PHPAPI int redis_check_eof(RedisSock *redis_sock TSRMLS_DC)
PHP_REDIS_API int redis_check_eof(RedisSock *redis_sock TSRMLS_DC)
{
int eof;
int count = 0;
@@ -69,7 +75,7 @@ PHPAPI int redis_check_eof(RedisSock *redis_sock TSRMLS_DC)
redis_sock->mode = ATOMIC;
redis_sock->watching = 0;
}
// Wait for a while before trying to reconnect
/* Wait for a while before trying to reconnect */
if (redis_sock->retry_interval) {
// Random factor to avoid having several (or many) concurrent connections trying to reconnect at the same time
long retry_interval = (count ? redis_sock->retry_interval : (php_rand(TSRMLS_C) % redis_sock->retry_interval));
@@ -81,7 +87,7 @@ PHPAPI int redis_check_eof(RedisSock *redis_sock TSRMLS_DC)
}
}
// Reselect the DB.
/* Reselect the DB. */
if (count && redis_sock->dbNumber) {
char *cmd, *response;
int cmd_len, response_len;
@@ -109,7 +115,7 @@ PHPAPI int redis_check_eof(RedisSock *redis_sock TSRMLS_DC)
}
PHPAPI int
PHP_REDIS_API int
redis_sock_read_scan_reply(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
REDIS_SCAN_TYPE type, long *iter)
{
@@ -117,31 +123,31 @@ redis_sock_read_scan_reply(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
int reply_info;
char *p_iter;
// Our response should have two multibulk replies
/* Our response should have two multibulk replies */
if(redis_read_reply_type(redis_sock, &reply_type, &reply_info TSRMLS_CC)<0
|| reply_type != TYPE_MULTIBULK || reply_info != 2)
{
return -1;
}
// The BULK response iterator
/* The BULK response iterator */
if(redis_read_reply_type(redis_sock, &reply_type, &reply_info TSRMLS_CC)<0
|| reply_type != TYPE_BULK)
{
return -1;
}
// Attempt to read the iterator
/* Attempt to read the iterator */
if(!(p_iter = redis_sock_read_bulk_reply(redis_sock, reply_info TSRMLS_CC))) {
return -1;
}
// Push the iterator out to the caller
/* Push the iterator out to the caller */
*iter = atol(p_iter);
efree(p_iter);
// Read our actual keys/members/etc differently depending on what kind of
// scan command this is. They all come back in slightly different ways
/* Read our actual keys/members/etc differently depending on what kind of
scan command this is. They all come back in slightly different ways */
switch(type) {
case TYPE_SCAN:
return redis_sock_read_multibulk_reply_raw(INTERNAL_FUNCTION_PARAM_PASSTHRU, redis_sock, NULL, NULL);
@@ -156,7 +162,7 @@ redis_sock_read_scan_reply(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
}
}
PHPAPI zval *redis_sock_read_multibulk_reply_zval(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock) {
PHP_REDIS_API zval *redis_sock_read_multibulk_reply_zval(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock) {
char inbuf[1024];
int numElems;
zval *z_tab;
@@ -191,7 +197,7 @@ PHPAPI zval *redis_sock_read_multibulk_reply_zval(INTERNAL_FUNCTION_PARAMETERS,
/**
* redis_sock_read_bulk_reply
*/
PHPAPI char *redis_sock_read_bulk_reply(RedisSock *redis_sock, int bytes TSRMLS_DC)
PHP_REDIS_API char *redis_sock_read_bulk_reply(RedisSock *redis_sock, int bytes TSRMLS_DC)
{
int offset = 0;
size_t got;
@@ -207,7 +213,7 @@ PHPAPI char *redis_sock_read_bulk_reply(RedisSock *redis_sock, int bytes TSRMLS_
} else {
char c;
int i;
reply = emalloc(bytes+1);
while(offset < bytes) {
@@ -231,7 +237,7 @@ PHPAPI char *redis_sock_read_bulk_reply(RedisSock *redis_sock, int bytes TSRMLS_
/**
* redis_sock_read
*/
PHPAPI char *redis_sock_read(RedisSock *redis_sock, int *buf_len TSRMLS_DC)
PHP_REDIS_API char *redis_sock_read(RedisSock *redis_sock, int *buf_len TSRMLS_DC)
{
char inbuf[1024];
char *resp = NULL;
@@ -275,7 +281,7 @@ PHPAPI char *redis_sock_read(RedisSock *redis_sock, int *buf_len TSRMLS_DC)
case '+':
case ':':
// Single Line Reply
/* Single Line Reply */
/* :123\r\n */
*buf_len = strlen(inbuf) - 2;
if(*buf_len >= 2) {
@@ -324,10 +330,10 @@ integer_length(int i) {
int
redis_cmd_format_header(char **ret, char *keyword, int arg_count) {
// Our return buffer
/* Our return buffer */
smart_str buf = {0};
// Keyword length
/* Keyword length */
int l = strlen(keyword);
smart_str_appendc(&buf, '*');
@@ -339,10 +345,10 @@ redis_cmd_format_header(char **ret, char *keyword, int arg_count) {
smart_str_appendl(&buf, keyword, l);
smart_str_appendl(&buf, _NL, sizeof(_NL) - 1);
// Set our return pointer
/* Set our return pointer */
*ret = buf.c;
// Return the length
/* Return the length */
return buf.len;
}
@@ -354,6 +360,7 @@ redis_cmd_format_static(char **ret, char *keyword, char *format, ...) {
smart_str buf = {0};
int l = strlen(keyword);
char *dbl_str;
char dbl_decsep;
int dbl_len;
va_start(ap, format);
@@ -435,6 +442,7 @@ redis_cmd_format(char **ret, char *format, ...) {
va_list ap;
char *p = format;
char *dbl_str;
char dbl_decsep;
int dbl_len;
va_start(ap, format);
@@ -487,26 +495,26 @@ redis_cmd_format(char **ret, char *format, ...) {
* Append a command sequence to a Redis command
*/
int redis_cmd_append_str(char **cmd, int cmd_len, char *append, int append_len) {
// Smart string buffer
/* Smart string buffer */
smart_str buf = {0};
// Append the current command to our smart_str
/* Append the current command to our smart_str */
smart_str_appendl(&buf, *cmd, cmd_len);
// Append our new command sequence
/* Append our new command sequence */
smart_str_appendc(&buf, '$');
smart_str_append_long(&buf, append_len);
smart_str_appendl(&buf, _NL, sizeof(_NL) -1);
smart_str_appendl(&buf, append, append_len);
smart_str_appendl(&buf, _NL, sizeof(_NL) -1);
// Free our old command
/* Free our old command */
efree(*cmd);
// Set our return pointer
/* Set our return pointer */
*cmd = buf.c;
// Return new command length
/* Return new command length */
return buf.len;
}
@@ -536,7 +544,7 @@ int redis_cmd_append_sstr(smart_str *str, char *append, int append_len) {
smart_str_appendl(str, append, append_len);
smart_str_appendl(str, _NL, sizeof(_NL) - 1);
// Return our new length
/* Return our new length */
return str->len;
}
@@ -566,16 +574,16 @@ int redis_cmd_append_sstr_dbl(smart_str *str, double value) {
int dbl_len;
int retval;
/// Convert to double
/* Convert to double */
REDIS_DOUBLE_TO_STRING(dbl_str, dbl_len, value);
// Append the string
/* Append the string */
retval = redis_cmd_append_sstr(str, dbl_str, dbl_len);
// Free our double string
/* Free our double string */
efree(dbl_str);
// Return new length
/* Return new length */
return retval;
}
@@ -586,14 +594,14 @@ int redis_cmd_append_int(char **cmd, int cmd_len, int append) {
char int_buf[32];
int int_len;
// Conver to an int, capture length
/* Conver to an int, capture length */
int_len = snprintf(int_buf, sizeof(int_buf), "%d", append);
// Return the new length
/* Return the new length */
return redis_cmd_append_str(cmd, cmd_len, int_buf, int_len);
}
PHPAPI void redis_bulk_double_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx) {
PHP_REDIS_API void redis_bulk_double_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx) {
char *response;
int response_len;
@@ -617,7 +625,7 @@ PHPAPI void redis_bulk_double_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *
}
}
PHPAPI void redis_type_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx) {
PHP_REDIS_API void redis_type_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx) {
char *response;
int response_len;
long l;
@@ -652,7 +660,7 @@ PHPAPI void redis_type_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_s
}
}
PHPAPI void redis_info_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx) {
PHP_REDIS_API void redis_info_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx) {
char *response;
int response_len;
char *pos, *cur;
@@ -731,34 +739,36 @@ PHPAPI void redis_info_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_s
* Specialized handling of the CLIENT LIST output so it comes out in a simple way for PHP userland code
* to handle.
*/
PHPAPI void redis_client_list_reply(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab) {
PHP_REDIS_API void redis_client_list_reply(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab) {
char *resp;
int resp_len;
zval *z_result, *z_sub_result;
// Pointers for parsing
/* Pointers for parsing */
char *p, *lpos, *kpos = NULL, *vpos = NULL, *p2, *key, *value;
// Key length, done flag
int klen = 0, done = 0, is_numeric;
// Make sure we can read a response from Redis
/* Key length, done flag */
int klen, done = 0, is_numeric;
/* Make sure we can read a response from Redis */
if((resp = redis_sock_read(redis_sock, &resp_len TSRMLS_CC)) == NULL) {
RETURN_FALSE;
}
// Allocate memory for our response
/* Allocate memory for our response */
MAKE_STD_ZVAL(z_result);
array_init(z_result);
// Allocate memory for one user (there should be at least one, namely us!)
/* Allocate memory for one user (there should be at least one, namely us!) */
ALLOC_INIT_ZVAL(z_sub_result);
array_init(z_sub_result);
p = resp;
lpos = resp;
// While we've got more to parse
/* While we've got more to parse */
while(!done) {
// What character are we on
/* What character are we on */
switch(*p) {
/* We're done */
case '\0':
@@ -767,23 +777,23 @@ PHPAPI void redis_client_list_reply(INTERNAL_FUNCTION_PARAMETERS, RedisSock *red
/* \n, ' ' mean we can pull a k/v pair */
case '\n':
case ' ':
// Grab our value
/* Grab our value */
vpos = lpos;
// There is some communication error or Redis bug if we don't
// have a key and value, but check anyway.
/* There is some communication error or Redis bug if we don't
have a key and value, but check anyway. */
if(kpos && vpos) {
// Allocate, copy in our key
/* Allocate, copy in our key */
key = emalloc(klen + 1);
strncpy(key, kpos, klen);
key[klen] = 0;
// Allocate, copy in our value
/* Allocate, copy in our value */
value = emalloc(p-lpos+1);
strncpy(value,lpos,p-lpos+1);
value[p-lpos]=0;
// Treat numbers as numbers, strings as strings
/* Treat numbers as numbers, strings as strings */
is_numeric = 1;
for(p2 = value; *p2; ++p2) {
if(*p2 < '0' || *p2 > '9') {
@@ -792,7 +802,7 @@ PHPAPI void redis_client_list_reply(INTERNAL_FUNCTION_PARAMETERS, RedisSock *red
}
}
// Add as a long or string, depending
/* Add as a long or string, depending */
if(is_numeric == 1) {
add_assoc_long(z_sub_result, key, atol(value));
efree(value);
@@ -800,57 +810,57 @@ PHPAPI void redis_client_list_reply(INTERNAL_FUNCTION_PARAMETERS, RedisSock *red
add_assoc_string(z_sub_result, key, value, 0);
}
// If we hit a '\n', then we can add this user to our list
/* If we hit a '\n', then we can add this user to our list */
if(*p == '\n') {
// Add our user
/* Add our user */
add_next_index_zval(z_result, z_sub_result);
// If we have another user, make another one
/* If we have another user, make another one */
if(*(p+1) != '\0') {
ALLOC_INIT_ZVAL(z_sub_result);
array_init(z_sub_result);
}
}
// Free our key
/* Free our key */
efree(key);
} else {
// Something is wrong
/* Something is wrong */
efree(resp);
RETURN_FALSE;
}
// Move forward
/* Move forward */
lpos = p + 1;
break;
/* We can pull the key and null terminate at our sep */
case '=':
// Key, key length
/* Key, key length */
kpos = lpos;
klen = p - lpos;
// Move forward
/* Move forward */
lpos = p + 1;
break;
}
// Increment
/* Increment */
p++;
}
// Free our respoonse
/* Free our respoonse */
efree(resp);
IF_MULTI_OR_PIPELINE() {
IF_MULTI_OR_PIPELINE() {
add_next_index_zval(z_tab, z_result);
} else {
RETVAL_ZVAL(z_result, 0, 1);
}
}
PHPAPI void redis_boolean_response_impl(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx, SuccessCallback success_callback) {
PHP_REDIS_API void redis_boolean_response_impl(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx, SuccessCallback success_callback) {
char *response;
int response_len;
@@ -887,11 +897,11 @@ PHPAPI void redis_boolean_response_impl(INTERNAL_FUNCTION_PARAMETERS, RedisSock
}
}
PHPAPI void redis_boolean_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx) {
PHP_REDIS_API void redis_boolean_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx) {
redis_boolean_response_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, redis_sock, z_tab, ctx, NULL);
}
PHPAPI void redis_long_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval * z_tab, void *ctx) {
PHP_REDIS_API void redis_long_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval * z_tab, void *ctx) {
char *response;
int response_len;
@@ -938,7 +948,7 @@ PHPAPI void redis_long_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_s
PHPAPI int redis_sock_read_multibulk_reply_zipped_with_flag(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, int flag) {
PHP_REDIS_API int redis_sock_read_multibulk_reply_zipped_with_flag(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, int flag) {
/*
int ret = redis_sock_read_multibulk_reply(INTERNAL_FUNCTION_PARAM_PASSTHRU, redis_sock, z_tab TSRMLS_CC);
@@ -991,16 +1001,16 @@ PHPAPI int redis_sock_read_multibulk_reply_zipped_with_flag(INTERNAL_FUNCTION_PA
return 0;
}
PHPAPI int redis_sock_read_multibulk_reply_zipped(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx) {
PHP_REDIS_API int redis_sock_read_multibulk_reply_zipped(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx) {
return redis_sock_read_multibulk_reply_zipped_with_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, redis_sock, z_tab, 1);
}
PHPAPI int redis_sock_read_multibulk_reply_zipped_strings(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx) {
PHP_REDIS_API int redis_sock_read_multibulk_reply_zipped_strings(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx) {
return redis_sock_read_multibulk_reply_zipped_with_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, redis_sock, z_tab, 0);
}
PHPAPI void redis_1_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx) {
PHP_REDIS_API void redis_1_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx) {
char *response;
int response_len;
@@ -1032,7 +1042,7 @@ PHPAPI void redis_1_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock
}
}
PHPAPI void redis_string_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx) {
PHP_REDIS_API void redis_string_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx) {
char *response;
int response_len;
@@ -1062,7 +1072,7 @@ PHPAPI void redis_string_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis
}
/* like string response, but never unserialized. */
PHPAPI void redis_ping_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx) {
PHP_REDIS_API void redis_ping_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx) {
char *response;
int response_len;
@@ -1085,7 +1095,7 @@ PHPAPI void redis_ping_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_s
/**
* redis_sock_create
*/
PHPAPI RedisSock* redis_sock_create(char *host, int host_len, unsigned short port,
PHP_REDIS_API RedisSock* redis_sock_create(char *host, int host_len, unsigned short port,
double timeout, int persistent, char *persistent_id,
long retry_interval,
zend_bool lazy_connect)
@@ -1135,7 +1145,7 @@ PHPAPI RedisSock* redis_sock_create(char *host, int host_len, unsigned short por
/**
* redis_sock_connect
*/
PHPAPI int redis_sock_connect(RedisSock *redis_sock TSRMLS_DC)
PHP_REDIS_API int redis_sock_connect(RedisSock *redis_sock TSRMLS_DC)
{
struct timeval tv, read_tv, *tv_ptr = NULL;
char *host = NULL, *persistent_id = NULL, *errstr = NULL;
@@ -1211,7 +1221,7 @@ PHPAPI int redis_sock_connect(RedisSock *redis_sock TSRMLS_DC)
/**
* redis_sock_server_open
*/
PHPAPI int redis_sock_server_open(RedisSock *redis_sock, int force_connect TSRMLS_DC)
PHP_REDIS_API int redis_sock_server_open(RedisSock *redis_sock, int force_connect TSRMLS_DC)
{
int res = -1;
@@ -1238,7 +1248,7 @@ PHPAPI int redis_sock_server_open(RedisSock *redis_sock, int force_connect TSRML
/**
* redis_sock_disconnect
*/
PHPAPI int redis_sock_disconnect(RedisSock *redis_sock TSRMLS_DC)
PHP_REDIS_API int redis_sock_disconnect(RedisSock *redis_sock TSRMLS_DC)
{
if (redis_sock == NULL) {
return 1;
@@ -1263,7 +1273,7 @@ PHPAPI int redis_sock_disconnect(RedisSock *redis_sock TSRMLS_DC)
return 0;
}
PHPAPI void redis_send_discard(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock)
PHP_REDIS_API void redis_send_discard(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock)
{
char *cmd;
int response_len, cmd_len;
@@ -1290,8 +1300,8 @@ PHPAPI void redis_send_discard(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_so
/**
* redis_sock_set_err
*/
PHPAPI int redis_sock_set_err(RedisSock *redis_sock, const char *msg, int msg_len) {
// Allocate/Reallocate our last error member
PHP_REDIS_API int redis_sock_set_err(RedisSock *redis_sock, const char *msg, int msg_len) {
/* Allocate/Reallocate our last error member */
if(msg != NULL && msg_len > 0) {
if(redis_sock->err == NULL) {
redis_sock->err = emalloc(msg_len + 1);
@@ -1299,29 +1309,29 @@ PHPAPI int redis_sock_set_err(RedisSock *redis_sock, const char *msg, int msg_le
redis_sock->err = erealloc(redis_sock->err, msg_len +1);
}
// Copy in our new error message, set new length, and null terminate
/* Copy in our new error message, set new length, and null terminate */
memcpy(redis_sock->err, msg, msg_len);
redis_sock->err[msg_len] = '\0';
redis_sock->err_len = msg_len;
} else {
// Free our last error
/* Free our last error */
if(redis_sock->err != NULL) {
efree(redis_sock->err);
}
// Set to null, with zero length
/* Set to null, with zero length */
redis_sock->err = NULL;
redis_sock->err_len = 0;
}
// Success
/* Success */
return 0;
}
/**
* redis_sock_read_multibulk_reply
*/
PHPAPI int redis_sock_read_multibulk_reply(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx)
PHP_REDIS_API int redis_sock_read_multibulk_reply(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx)
{
char inbuf[1024];
int numElems;
@@ -1361,14 +1371,14 @@ PHPAPI int redis_sock_read_multibulk_reply(INTERNAL_FUNCTION_PARAMETERS, RedisSo
*return_value = *z_multi_result;
efree(z_multi_result);
}
//zval_copy_ctor(return_value);
/*zval_copy_ctor(return_value); */
return 0;
}
/**
* Like multibulk reply, but don't touch the values, they won't be compressed. (this is used by HKEYS).
*/
PHPAPI int redis_sock_read_multibulk_reply_raw(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx)
PHP_REDIS_API int redis_sock_read_multibulk_reply_raw(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx)
{
char inbuf[1024];
int numElems;
@@ -1408,11 +1418,11 @@ PHPAPI int redis_sock_read_multibulk_reply_raw(INTERNAL_FUNCTION_PARAMETERS, Red
*return_value = *z_multi_result;
efree(z_multi_result);
}
//zval_copy_ctor(return_value);
/*zval_copy_ctor(return_value); */
return 0;
}
PHPAPI int
PHP_REDIS_API int
redis_sock_read_multibulk_reply_loop(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
zval *z_tab, int numElems, int unwrap_key, int unserialize_even_only)
{
@@ -1444,7 +1454,7 @@ redis_sock_read_multibulk_reply_loop(INTERNAL_FUNCTION_PARAMETERS, RedisSock *re
/**
* redis_sock_read_multibulk_reply_assoc
*/
PHPAPI int redis_sock_read_multibulk_reply_assoc(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx)
PHP_REDIS_API int redis_sock_read_multibulk_reply_assoc(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx)
{
char inbuf[1024], *response;
int response_len;
@@ -1511,7 +1521,7 @@ PHPAPI int redis_sock_read_multibulk_reply_assoc(INTERNAL_FUNCTION_PARAMETERS, R
/**
* redis_sock_write
*/
PHPAPI int redis_sock_write(RedisSock *redis_sock, char *cmd, size_t sz TSRMLS_DC)
PHP_REDIS_API int redis_sock_write(RedisSock *redis_sock, char *cmd, size_t sz TSRMLS_DC)
{
if(redis_sock && redis_sock->status == REDIS_SOCK_STATUS_DISCONNECTED) {
zend_throw_exception(redis_exception_ce, "Connection closed", 0 TSRMLS_CC);
@@ -1526,7 +1536,7 @@ PHPAPI int redis_sock_write(RedisSock *redis_sock, char *cmd, size_t sz TSRMLS_D
/**
* redis_free_socket
*/
PHPAPI void redis_free_socket(RedisSock *redis_sock)
PHP_REDIS_API void redis_free_socket(RedisSock *redis_sock)
{
if(redis_sock->prefix) {
efree(redis_sock->prefix);
@@ -1544,7 +1554,7 @@ PHPAPI void redis_free_socket(RedisSock *redis_sock)
efree(redis_sock);
}
PHPAPI int
PHP_REDIS_API int
redis_serialize(RedisSock *redis_sock, zval *z, char **val, int *val_len TSRMLS_DC) {
#if ZEND_MODULE_API_NO >= 20100000
php_serialize_data_t ht;
@@ -1622,7 +1632,7 @@ redis_serialize(RedisSock *redis_sock, zval *z, char **val, int *val_len TSRMLS_
return 0;
}
PHPAPI int
PHP_REDIS_API int
redis_unserialize(RedisSock *redis_sock, const char *val, int val_len, zval **return_value TSRMLS_DC) {
php_unserialize_data_t var_hash;
@@ -1673,11 +1683,11 @@ redis_unserialize(RedisSock *redis_sock, const char *val, int val_len, zval **re
return 0;
}
PHPAPI int
PHP_REDIS_API int
redis_key_prefix(RedisSock *redis_sock, char **key, int *key_len TSRMLS_DC) {
int ret_len;
char *ret;
if(redis_sock->prefix == NULL || redis_sock->prefix_len == 0) {
return 0;
}
@@ -1696,104 +1706,104 @@ redis_key_prefix(RedisSock *redis_sock, char **key, int *key_len TSRMLS_DC) {
* Processing for variant reply types (think EVAL)
*/
PHPAPI int
PHP_REDIS_API int
redis_sock_gets(RedisSock *redis_sock, char *buf, int buf_size, size_t *line_size TSRMLS_DC) {
// Handle EOF
/* Handle EOF */
if(-1 == redis_check_eof(redis_sock TSRMLS_CC)) {
return -1;
}
if(php_stream_get_line(redis_sock->stream, buf, buf_size, line_size) == NULL) {
// Close, put our socket state into error
/* Close, put our socket state into error */
redis_stream_close(redis_sock TSRMLS_CC);
redis_sock->stream = NULL;
redis_sock->status = REDIS_SOCK_STATUS_FAILED;
redis_sock->mode = ATOMIC;
redis_sock->watching = 0;
// Throw a read error exception
/* Throw a read error exception */
zend_throw_exception(redis_exception_ce, "read error on connection", 0 TSRMLS_CC);
}
// We don't need \r\n
/* We don't need \r\n */
*line_size-=2;
buf[*line_size]='\0';
// Success!
/* Success! */
return 0;
}
PHPAPI int
PHP_REDIS_API int
redis_read_reply_type(RedisSock *redis_sock, REDIS_REPLY_TYPE *reply_type, int *reply_info TSRMLS_DC) {
// Make sure we haven't lost the connection, even trying to reconnect
/* Make sure we haven't lost the connection, even trying to reconnect */
if(-1 == redis_check_eof(redis_sock TSRMLS_CC)) {
// Failure
/* Failure */
return -1;
}
// Attempt to read the reply-type byte
/* Attempt to read the reply-type byte */
if((*reply_type = php_stream_getc(redis_sock->stream)) == EOF) {
zend_throw_exception(redis_exception_ce, "socket error on read socket", 0 TSRMLS_CC);
}
// If this is a BULK, MULTI BULK, or simply an INTEGER response, we can extract the value or size info here
/* If this is a BULK, MULTI BULK, or simply an INTEGER response, we can extract the value or size info here */
if(*reply_type == TYPE_INT || *reply_type == TYPE_BULK || *reply_type == TYPE_MULTIBULK) {
// Buffer to hold size information
/* Buffer to hold size information */
char inbuf[255];
// Read up to our newline
/* Read up to our newline */
if(php_stream_gets(redis_sock->stream, inbuf, sizeof(inbuf)) < 0) {
return -1;
}
// Set our size response
/* Set our size response */
*reply_info = atoi(inbuf);
}
// Success!
/* Success! */
return 0;
}
/*
* Read a single line response, having already consumed the reply-type byte
*/
PHPAPI int
PHP_REDIS_API int
redis_read_variant_line(RedisSock *redis_sock, REDIS_REPLY_TYPE reply_type, zval **z_ret TSRMLS_DC) {
// Buffer to read our single line reply
/* Buffer to read our single line reply */
char inbuf[1024];
size_t line_size;
// Attempt to read our single line reply
/* Attempt to read our single line reply */
if(redis_sock_gets(redis_sock, inbuf, sizeof(inbuf), &line_size TSRMLS_CC) < 0) {
return -1;
}
// If this is an error response, check if it is a SYNC error, and throw in that case
/* If this is an error response, check if it is a SYNC error, and throw in that case */
if(reply_type == TYPE_ERR) {
if(memcmp(inbuf, "ERR SYNC", 9) == 0) {
zend_throw_exception(redis_exception_ce, "SYNC with master in progress", 0 TSRMLS_CC);
}
// Set our last error
/* Set our last error */
redis_sock_set_err(redis_sock, inbuf, line_size);
// Set our response to FALSE
/* Set our response to FALSE */
ZVAL_FALSE(*z_ret);
} else {
// Set our response to TRUE
/* Set our response to TRUE */
ZVAL_TRUE(*z_ret);
}
return 0;
}
PHPAPI int
PHP_REDIS_API int
redis_read_variant_bulk(RedisSock *redis_sock, int size, zval **z_ret TSRMLS_DC) {
// Attempt to read the bulk reply
/* Attempt to read the bulk reply */
char *bulk_resp = redis_sock_read_bulk_reply(redis_sock, size TSRMLS_CC);
// Set our reply to FALSE on failure, and the string on success
/* Set our reply to FALSE on failure, and the string on success */
if(bulk_resp == NULL) {
ZVAL_FALSE(*z_ret);
return -1;
@@ -1803,21 +1813,21 @@ redis_read_variant_bulk(RedisSock *redis_sock, int size, zval **z_ret TSRMLS_DC)
}
}
PHPAPI int
PHP_REDIS_API int
redis_read_multibulk_recursive(RedisSock *redis_sock, int elements, zval **z_ret TSRMLS_DC) {
int reply_info;
REDIS_REPLY_TYPE reply_type;
zval *z_subelem;
// Iterate while we have elements
/* Iterate while we have elements */
while(elements > 0) {
// Attempt to read our reply type
/* Attempt to read our reply type */
if(redis_read_reply_type(redis_sock, &reply_type, &reply_info TSRMLS_CC) < 0) {
zend_throw_exception_ex(redis_exception_ce, 0 TSRMLS_CC, "protocol error, couldn't parse MULTI-BULK response\n", reply_type);
return -1;
}
// Switch on our reply-type byte
/* Switch on our reply-type byte */
switch(reply_type) {
case TYPE_ERR:
case TYPE_LINE:
@@ -1826,17 +1836,17 @@ redis_read_multibulk_recursive(RedisSock *redis_sock, int elements, zval **z_ret
add_next_index_zval(*z_ret, z_subelem);
break;
case TYPE_INT:
// Add our long value
/* Add our long value */
add_next_index_long(*z_ret, reply_info);
break;
case TYPE_BULK:
// Init a zval for our bulk response, read and add it
/* Init a zval for our bulk response, read and add it */
ALLOC_INIT_ZVAL(z_subelem);
redis_read_variant_bulk(redis_sock, reply_info, &z_subelem TSRMLS_CC);
add_next_index_zval(*z_ret, z_subelem);
break;
case TYPE_MULTIBULK:
// Construct an array for our sub element, and add it, and recurse
/* Construct an array for our sub element, and add it, and recurse */
ALLOC_INIT_ZVAL(z_subelem);
array_init(z_subelem);
add_next_index_zval(*z_ret, z_subelem);
@@ -1844,30 +1854,30 @@ redis_read_multibulk_recursive(RedisSock *redis_sock, int elements, zval **z_ret
break;
}
// Decrement our element counter
/* Decrement our element counter */
elements--;
}
return 0;
}
PHPAPI int
PHP_REDIS_API int
redis_read_variant_reply(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab) {
// Reply type, and reply size vars
/* Reply type, and reply size vars */
REDIS_REPLY_TYPE reply_type;
int reply_info;
//char *bulk_resp;
/*char *bulk_resp; */
zval *z_ret;
// Attempt to read our header
/* Attempt to read our header */
if(redis_read_reply_type(redis_sock, &reply_type, &reply_info TSRMLS_CC) < 0) {
return -1;
}
// Our return ZVAL
/* Our return ZVAL */
MAKE_STD_ZVAL(z_ret);
// Switch based on our top level reply type
/* Switch based on our top level reply type */
switch(reply_type) {
case TYPE_ERR:
case TYPE_LINE:
@@ -1880,16 +1890,16 @@ redis_read_variant_reply(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zv
redis_read_variant_bulk(redis_sock, reply_info, &z_ret TSRMLS_CC);
break;
case TYPE_MULTIBULK:
// Initialize an array for our multi-bulk response
/* Initialize an array for our multi-bulk response */
array_init(z_ret);
// If we've got more than zero elements, parse our multi bulk respoinse recursively
/* If we've got more than zero elements, parse our multi bulk respoinse recursively */
if(reply_info > -1) {
redis_read_multibulk_recursive(redis_sock, reply_info, &z_ret TSRMLS_CC);
}
break;
default:
// Protocol error
/* Protocol error */
zend_throw_exception_ex(redis_exception_ce, 0 TSRMLS_CC, "protocol error, got '%c' as reply-type byte\n", reply_type);
return FAILURE;
}
@@ -1897,14 +1907,14 @@ redis_read_variant_reply(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zv
IF_MULTI_OR_PIPELINE() {
add_next_index_zval(z_tab, z_ret);
} else {
// Set our return value
/* Set our return value */
*return_value = *z_ret;
zval_copy_ctor(return_value);
zval_dtor(z_ret);
efree(z_ret);
}
// Success
/* Success */
return 0;
}
+47 -39
View File
@@ -11,46 +11,54 @@ int redis_cmd_append_sstr_long(smart_str *str, long append);
int redis_cmd_append_int(char **cmd, int cmd_len, int append);
int redis_cmd_append_sstr_dbl(smart_str *str, double value);
PHPAPI char * redis_sock_read(RedisSock *redis_sock, int *buf_len TSRMLS_DC);
PHP_REDIS_API char * redis_sock_read(RedisSock *redis_sock, int *buf_len TSRMLS_DC);
PHPAPI void redis_1_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
PHPAPI void redis_long_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval* z_tab, void *ctx);
PHP_REDIS_API void redis_1_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
PHP_REDIS_API void redis_long_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval* z_tab, void *ctx);
typedef void (*SuccessCallback)(RedisSock *redis_sock);
PHPAPI void redis_boolean_response_impl(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx, SuccessCallback success_callback);
PHPAPI void redis_boolean_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
PHPAPI void redis_bulk_double_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
PHPAPI void redis_string_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
PHPAPI void redis_ping_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
PHPAPI void redis_info_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
PHPAPI void redis_type_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
PHPAPI RedisSock* redis_sock_create(char *host, int host_len, unsigned short port, double timeout, int persistent, char *persistent_id, long retry_interval, zend_bool lazy_connect);
PHPAPI int redis_sock_connect(RedisSock *redis_sock TSRMLS_DC);
PHPAPI int redis_sock_server_open(RedisSock *redis_sock, int force_connect TSRMLS_DC);
PHPAPI int redis_sock_disconnect(RedisSock *redis_sock TSRMLS_DC);
PHPAPI zval *redis_sock_read_multibulk_reply_zval(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock);
PHPAPI char *redis_sock_read_bulk_reply(RedisSock *redis_sock, int bytes TSRMLS_DC);
PHPAPI int redis_sock_read_multibulk_reply(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *_z_tab, void *ctx);
PHPAPI int redis_sock_read_multibulk_reply_raw(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
PHPAPI int redis_sock_read_multibulk_reply_loop(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, int numElems, int unwrap_key, int unserialize_even_only);
PHPAPI int redis_sock_read_multibulk_reply_zipped(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
PHPAPI int redis_sock_read_multibulk_reply_zipped_strings(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
PHPAPI int redis_sock_read_multibulk_reply_assoc(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
PHPAPI int redis_sock_read_scan_reply(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, REDIS_SCAN_TYPE type, long *iter);
PHP_REDIS_API void redis_boolean_response_impl(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx, SuccessCallback success_callback);
PHP_REDIS_API void redis_boolean_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
PHP_REDIS_API void redis_bulk_double_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
PHP_REDIS_API void redis_string_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
PHP_REDIS_API void redis_ping_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
PHP_REDIS_API void redis_info_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
PHP_REDIS_API void redis_type_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
PHP_REDIS_API RedisSock* redis_sock_create(char *host, int host_len, unsigned short port, double timeout, int persistent, char *persistent_id, long retry_interval, zend_bool lazy_connect);
PHP_REDIS_API int redis_sock_connect(RedisSock *redis_sock TSRMLS_DC);
PHP_REDIS_API int redis_sock_server_open(RedisSock *redis_sock, int force_connect TSRMLS_DC);
PHP_REDIS_API int redis_sock_disconnect(RedisSock *redis_sock TSRMLS_DC);
PHP_REDIS_API zval *redis_sock_read_multibulk_reply_zval(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock);
PHP_REDIS_API char *redis_sock_read_bulk_reply(RedisSock *redis_sock, int bytes TSRMLS_DC);
PHP_REDIS_API int redis_sock_read_multibulk_reply(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *_z_tab, void *ctx);
PHP_REDIS_API int redis_sock_read_multibulk_reply_raw(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
PHP_REDIS_API int redis_sock_read_multibulk_reply_loop(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, int numElems, int unwrap_key, int unserialize_even_only);
PHP_REDIS_API int redis_sock_read_multibulk_reply_zipped(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
PHP_REDIS_API int redis_sock_read_multibulk_reply_zipped_strings(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
PHP_REDIS_API int redis_sock_read_multibulk_reply_assoc(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
PHP_REDIS_API int redis_sock_read_scan_reply(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, REDIS_SCAN_TYPE type, long *iter);
PHPAPI int redis_sock_write(RedisSock *redis_sock, char *cmd, size_t sz TSRMLS_DC);
PHPAPI void redis_stream_close(RedisSock *redis_sock TSRMLS_DC);
PHPAPI int redis_check_eof(RedisSock *redis_sock TSRMLS_DC);
//PHPAPI int redis_sock_get(zval *id, RedisSock **redis_sock TSRMLS_DC);
PHPAPI void redis_free_socket(RedisSock *redis_sock);
PHPAPI void redis_send_discard(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock);
PHPAPI int redis_sock_set_err(RedisSock *redis_sock, const char *msg, int msg_len);
PHP_REDIS_API int redis_sock_write(RedisSock *redis_sock, char *cmd, size_t sz TSRMLS_DC);
PHP_REDIS_API void redis_stream_close(RedisSock *redis_sock TSRMLS_DC);
PHP_REDIS_API int redis_check_eof(RedisSock *redis_sock TSRMLS_DC);
/*PHP_REDIS_API int redis_sock_get(zval *id, RedisSock **redis_sock TSRMLS_DC);*/
PHP_REDIS_API void redis_free_socket(RedisSock *redis_sock);
PHP_REDIS_API void redis_send_discard(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock);
PHP_REDIS_API int redis_sock_set_err(RedisSock *redis_sock, const char *msg, int msg_len);
PHPAPI int
PHP_REDIS_API int redis_sock_write(RedisSock *redis_sock, char *cmd, size_t sz TSRMLS_DC);
PHP_REDIS_API void redis_stream_close(RedisSock *redis_sock TSRMLS_DC);
PHP_REDIS_API int redis_check_eof(RedisSock *redis_sock TSRMLS_DC);
/* PHP_REDIS_API int redis_sock_get(zval *id, RedisSock **redis_sock TSRMLS_DC); */
PHP_REDIS_API void redis_free_socket(RedisSock *redis_sock);
PHP_REDIS_API void redis_send_discard(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock);
PHP_REDIS_API int redis_sock_set_err(RedisSock *redis_sock, const char *msg, int msg_len);
PHP_REDIS_API int
redis_serialize(RedisSock *redis_sock, zval *z, char **val, int *val_len TSRMLS_DC);
PHPAPI int
PHP_REDIS_API int
redis_key_prefix(RedisSock *redis_sock, char **key, int *key_len TSRMLS_DC);
PHPAPI int
PHP_REDIS_API int
redis_unserialize(RedisSock *redis_sock, const char *val, int val_len, zval **return_value TSRMLS_DC);
@@ -58,13 +66,13 @@ redis_unserialize(RedisSock *redis_sock, const char *val, int val_len, zval **re
* Variant Read methods, mostly to implement eval
*/
PHPAPI int redis_read_reply_type(RedisSock *redis_sock, REDIS_REPLY_TYPE *reply_type, int *reply_info TSRMLS_DC);
PHPAPI int redis_read_variant_line(RedisSock *redis_sock, REDIS_REPLY_TYPE reply_type, zval **z_ret TSRMLS_DC);
PHPAPI int redis_read_variant_bulk(RedisSock *redis_sock, int size, zval **z_ret TSRMLS_DC);
PHPAPI int redis_read_multibulk_recursive(RedisSock *redis_sock, int elements, zval **z_ret TSRMLS_DC);
PHPAPI int redis_read_variant_reply(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab);
PHP_REDIS_API int redis_read_reply_type(RedisSock *redis_sock, REDIS_REPLY_TYPE *reply_type, int *reply_info TSRMLS_DC);
PHP_REDIS_API int redis_read_variant_line(RedisSock *redis_sock, REDIS_REPLY_TYPE reply_type, zval **z_ret TSRMLS_DC);
PHP_REDIS_API int redis_read_variant_bulk(RedisSock *redis_sock, int size, zval **z_ret TSRMLS_DC);
PHP_REDIS_API int redis_read_multibulk_recursive(RedisSock *redis_sock, int elements, zval **z_ret TSRMLS_DC);
PHP_REDIS_API int redis_read_variant_reply(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab);
PHPAPI void redis_client_list_reply(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab);
PHP_REDIS_API void redis_client_list_reply(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab);
#if ZEND_MODULE_API_NO >= 20100000
#define REDIS_DOUBLE_TO_STRING(dbl_str, dbl_len, dbl) do { \
+18 -18
View File
@@ -221,32 +221,32 @@ PHP_RINIT_FUNCTION(redis);
PHP_RSHUTDOWN_FUNCTION(redis);
PHP_MINFO_FUNCTION(redis);
PHPAPI int redis_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent);
PHPAPI void redis_atomic_increment(INTERNAL_FUNCTION_PARAMETERS, char *keyword, int count);
PHPAPI int generic_multiple_args_cmd(INTERNAL_FUNCTION_PARAMETERS, char *keyword, int keyword_len,
PHP_REDIS_API int redis_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent);
PHP_REDIS_API void redis_atomic_increment(INTERNAL_FUNCTION_PARAMETERS, char *keyword, int count);
PHP_REDIS_API int generic_multiple_args_cmd(INTERNAL_FUNCTION_PARAMETERS, char *keyword, int keyword_len,
int min_argc, RedisSock **redis_sock, int has_timeout, int all_keys, int can_serialize);
PHPAPI void generic_sort_cmd(INTERNAL_FUNCTION_PARAMETERS, char *sort, int use_alpha);
PHP_REDIS_API void generic_sort_cmd(INTERNAL_FUNCTION_PARAMETERS, char *sort, int use_alpha);
typedef void (*ResultCallback)(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
PHPAPI void generic_empty_cmd_impl(INTERNAL_FUNCTION_PARAMETERS, char *cmd, int cmd_len, ResultCallback result_callback);
PHPAPI void generic_empty_cmd(INTERNAL_FUNCTION_PARAMETERS, char *cmd, int cmd_len, ...);
PHPAPI void generic_empty_long_cmd(INTERNAL_FUNCTION_PARAMETERS, char *cmd, int cmd_len, ...);
PHP_REDIS_API void generic_empty_cmd_impl(INTERNAL_FUNCTION_PARAMETERS, char *cmd, int cmd_len, ResultCallback result_callback);
PHP_REDIS_API void generic_empty_cmd(INTERNAL_FUNCTION_PARAMETERS, char *cmd, int cmd_len, ...);
PHP_REDIS_API void generic_empty_long_cmd(INTERNAL_FUNCTION_PARAMETERS, char *cmd, int cmd_len, ...);
PHPAPI void generic_subscribe_cmd(INTERNAL_FUNCTION_PARAMETERS, char *sub_cmd);
PHPAPI void generic_unsubscribe_cmd(INTERNAL_FUNCTION_PARAMETERS, char *unsub_cmd);
PHP_REDIS_API void generic_subscribe_cmd(INTERNAL_FUNCTION_PARAMETERS, char *sub_cmd);
PHP_REDIS_API void generic_unsubscribe_cmd(INTERNAL_FUNCTION_PARAMETERS, char *unsub_cmd);
PHPAPI void array_zip_values_and_scores(RedisSock *redis_sock, zval *z_tab, int use_atof TSRMLS_DC);
PHPAPI int redis_response_enqueued(RedisSock *redis_sock TSRMLS_DC);
PHP_REDIS_API void array_zip_values_and_scores(RedisSock *redis_sock, zval *z_tab, int use_atof TSRMLS_DC);
PHP_REDIS_API int redis_response_enqueued(RedisSock *redis_sock TSRMLS_DC);
PHPAPI int get_flag(zval *object TSRMLS_DC);
PHPAPI void set_flag(zval *object, int new_flag TSRMLS_DC);
PHP_REDIS_API int get_flag(zval *object TSRMLS_DC);
PHP_REDIS_API void set_flag(zval *object, int new_flag TSRMLS_DC);
PHPAPI int redis_sock_read_multibulk_multi_reply_loop(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, int numElems);
PHP_REDIS_API int redis_sock_read_multibulk_multi_reply_loop(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, int numElems);
/* pipeline */
PHPAPI request_item* get_pipeline_head(zval *object);
PHPAPI void set_pipeline_head(zval *object, request_item *head);
PHPAPI request_item* get_pipeline_current(zval *object);
PHPAPI void set_pipeline_current(zval *object, request_item *current);
PHP_REDIS_API request_item* get_pipeline_head(zval *object);
PHP_REDIS_API void set_pipeline_head(zval *object, request_item *head);
PHP_REDIS_API request_item* get_pipeline_current(zval *object);
PHP_REDIS_API void set_pipeline_current(zval *object, request_item *current);
#ifndef _MSC_VER
ZEND_BEGIN_MODULE_GLOBALS(redis)
+319 -314
View File
File diff suppressed because it is too large Load Diff
+31 -17
View File
@@ -85,7 +85,7 @@ zend_function_entry redis_array_functions[] = {
static void redis_array_free(RedisArray *ra) {
int i;
// Redis objects
/* Redis objects */
for(i=0;i<ra->count;i++) {
zval_dtor(ra->redis[i]);
efree(ra->redis[i]);
@@ -110,7 +110,7 @@ static void redis_array_free(RedisArray *ra) {
zval_dtor(ra->z_pure_cmds);
efree(ra->z_pure_cmds);
// Free structure itself
/* Free structure itself */
efree(ra);
}
@@ -126,10 +126,22 @@ void redis_destructor_redis_array(zend_rsrc_list_entry * rsrc TSRMLS_DC)
redis_array_free(ra);
}
int le_redis_array;
void redis_destructor_redis_array(zend_rsrc_list_entry * rsrc TSRMLS_DC)
{
RedisArray *ra = (RedisArray*)rsrc->ptr;
/* Free previous ring if it's set */
if(ra->prev) redis_array_free(ra->prev);
/* Free parent array */
redis_array_free(ra);
}
/**
* redis_array_get
*/
PHPAPI int redis_array_get(zval *id, RedisArray **ra TSRMLS_DC)
PHP_REDIS_API int redis_array_get(zval *id, RedisArray **ra TSRMLS_DC)
{
zval **socket;
@@ -277,7 +289,7 @@ PHP_METHOD(RedisArray, __construct)
b_lazy_connect = Z_BVAL_PP(zpData);
}
/* extract connect_timeout option */
/* extract connect_timeout option */
if (FAILURE != zend_hash_find(hOpts, "connect_timeout", sizeof("connect_timeout"), (void**)&z_connect_timeout_pp)) {
if (Z_TYPE_PP(z_connect_timeout_pp) == IS_DOUBLE || Z_TYPE_PP(z_connect_timeout_pp) == IS_STRING) {
if (Z_TYPE_PP(z_connect_timeout_pp) == IS_DOUBLE) {
@@ -322,7 +334,7 @@ static void
ra_forward_call(INTERNAL_FUNCTION_PARAMETERS, RedisArray *ra, const char *cmd, int cmd_len, zval *z_args, zval *z_new_target) {
zval **zp_tmp, z_tmp;
char *key = NULL; // set to avoid "unused-but-set-variable"
char *key = NULL; /* set to avoid "unused-but-set-variable" */
int key_len;
int i;
zval *redis_inst;
@@ -396,7 +408,7 @@ ra_forward_call(INTERNAL_FUNCTION_PARAMETERS, RedisArray *ra, const char *cmd, i
/* check if we have an error. */
if(RA_CALL_FAILED(return_value,cmd) && ra->prev && !b_write_cmd) { /* there was an error reading, try with prev ring. */
/* ERROR, FALLBACK TO PREVIOUS RING and forward a reference to the first redis instance we were looking at. */
/* ERROR, FALLBACK TO PREVIOUS RING and forward a reference to the first redis instance we were looking at. */
ra_forward_call(INTERNAL_FUNCTION_PARAM_PASSTHRU, ra->prev, cmd, cmd_len, z_args, z_new_target?z_new_target:redis_inst);
}
@@ -627,41 +639,41 @@ PHP_METHOD(RedisArray, keys)
char *pattern;
int pattern_len, i;
// Make sure the prototype is correct
/* Make sure the prototype is correct */
if(zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os",
&object, redis_array_ce, &pattern, &pattern_len) == FAILURE)
{
RETURN_FALSE;
}
// Make sure we can grab our RedisArray object
/* Make sure we can grab our RedisArray object */
if(redis_array_get(object, &ra TSRMLS_CC) < 0) {
RETURN_FALSE;
}
// Set up our function call (KEYS)
/* Set up our function call (KEYS) */
ZVAL_STRING(&z_fun, "KEYS", 0);
// We will be passing with one string argument (the pattern)
/* We will be passing with one string argument (the pattern) */
MAKE_STD_ZVAL(z_args[0]);
ZVAL_STRINGL(z_args[0], pattern, pattern_len, 0);
// Init our array return
/* Init our array return */
array_init(return_value);
// Iterate our RedisArray nodes
/* Iterate our RedisArray nodes */
for(i=0; i<ra->count; ++i) {
// Return for this node
/* Return for this node */
MAKE_STD_ZVAL(z_tmp);
// Call KEYS on each node
/* Call KEYS on each node */
call_user_function(&redis_ce->function_table, &ra->redis[i], &z_fun, z_tmp, 1, z_args TSRMLS_CC);
// Add the result for this host
/* Add the result for this host */
add_assoc_zval(return_value, ra->hosts[i], z_tmp);
}
// Free arg array
/* Free arg array */
efree(z_args[0]);
}
@@ -984,6 +996,8 @@ PHP_METHOD(RedisArray, mset)
unsigned int key_len, free_idx = 0;
int type, *key_lens;
unsigned long idx;
int found;
zval *z_tmp;
/* Multi/exec support */
HANDLE_MULTI_EXEC("MSET");
@@ -1209,7 +1223,7 @@ PHP_METHOD(RedisArray, del)
found++;
}
if(!found) { // don't run empty DELs
if(!found) { /* don't run empty DELs */
zval_dtor(z_argarray);
efree(z_argarray);
continue;
+1 -1
View File
@@ -38,7 +38,7 @@ PHP_METHOD(RedisArray, unwatch);
typedef struct RedisArray_ {
int count;
char **hosts; /* array of host:port strings */
zval **redis; /* array of Redis instances */
+15 -15
View File
@@ -373,7 +373,7 @@ ra_call_extractor(RedisArray *ra, const char *key, int key_len, int *out_len TSR
php_error_docref(NULL TSRMLS_CC, E_ERROR, "Could not call extractor function");
return NULL;
}
//convert_to_string(ra->z_fun);
/* convert_to_string(ra->z_fun); */
/* call extraction function */
MAKE_STD_ZVAL(z_argv0);
@@ -433,7 +433,7 @@ ra_call_distributor(RedisArray *ra, const char *key, int key_len, int *pos TSRML
php_error_docref(NULL TSRMLS_CC, E_ERROR, "Could not call distributor function");
return 0;
}
//convert_to_string(ra->z_fun);
/* convert_to_string(ra->z_fun); */
/* call extraction function */
MAKE_STD_ZVAL(z_argv0);
@@ -455,6 +455,7 @@ zval *
ra_find_node(RedisArray *ra, const char *key, int key_len, int *out_pos TSRMLS_DC) {
uint32_t hash;
uint64_t h64;
char *out;
int pos, out_len;
@@ -474,7 +475,7 @@ ra_find_node(RedisArray *ra, const char *key, int key_len, int *out_pos TSRMLS_D
/* hash */
hash = rcrc32(out, out_len);
efree(out);
/* get position on ring */
h64 = hash;
h64 *= ra->count;
@@ -528,7 +529,7 @@ ra_index_multi(zval *z_redis, long multi_value TSRMLS_DC) {
ZVAL_LONG(z_args[0], multi_value);
call_user_function(&redis_ce->function_table, &z_redis, &z_fun_multi, &z_ret, 1, z_args TSRMLS_CC);
efree(z_args[0]);
//zval_dtor(&z_ret);
/* zval_dtor(&z_ret); */
}
static void
@@ -572,7 +573,6 @@ ra_index_keys(zval *z_pairs, zval *z_redis TSRMLS_DC) {
/* Initialize key array */
zval *z_keys, **z_entry_pp;
HashPosition pos;
MAKE_STD_ZVAL(z_keys);
#if PHP_VERSION_ID > 50300
array_init_size(z_keys, zend_hash_num_elements(Z_ARRVAL_P(z_pairs)));
@@ -658,8 +658,8 @@ ra_index_exec(zval *z_redis, zval *return_value, int keep_all TSRMLS_DC) {
zval_dtor(&z_ret);
}
//zval *zptr = &z_ret;
//php_var_dump(&zptr, 0 TSRMLS_CC);
/* zval *zptr = &z_ret; */
/* php_var_dump(&zptr, 0 TSRMLS_CC); */
}
void
@@ -801,7 +801,7 @@ ra_get_key_type(zval *z_redis, const char *key, int key_len, zval *z_from, long
if(zend_hash_get_current_data(retHash, (void**)&z_data) == FAILURE) {
success = 0;
break;
}
}
if(Z_TYPE_PP(z_data) != IS_LONG) {
success = 0;
break;
@@ -893,7 +893,7 @@ ra_move_zset(const char *key, int key_len, zval *z_from, zval *z_to, long ttl TS
unsigned int val_len;
int i;
unsigned long idx;
/* run ZRANGE key 0 -1 WITHSCORES on source */
ZVAL_STRINGL(&z_fun_zrange, "ZRANGE", 6, 0);
for(i = 0; i < 4; ++i) {
@@ -945,7 +945,7 @@ ra_move_zset(const char *key, int key_len, zval *z_from, zval *z_to, long ttl TS
ZVAL_LONG(z_zadd_args[i+1], (long)idx);
break;
default:
return -1; // Todo: log error
return -1; /* Todo: log error */
break;
}
i += 2;
@@ -1153,23 +1153,23 @@ ra_move_key(const char *key, int key_len, zval *z_from, zval *z_to TSRMLS_DC) {
case REDIS_STRING:
success = ra_move_string(key, key_len, z_from, z_to, ttl TSRMLS_CC);
break;
case REDIS_SET:
success = ra_move_set(key, key_len, z_from, z_to, ttl TSRMLS_CC);
break;
case REDIS_LIST:
success = ra_move_list(key, key_len, z_from, z_to, ttl TSRMLS_CC);
break;
case REDIS_ZSET:
success = ra_move_zset(key, key_len, z_from, z_to, ttl TSRMLS_CC);
break;
case REDIS_HASH:
success = ra_move_hash(key, key_len, z_from, z_to, ttl TSRMLS_CC);
break;
default:
/* TODO: report? */
break;
-1
View File
@@ -7,7 +7,6 @@
#include <stdint.h>
#endif
#include "common.h"
#include "common.h"
#include "redis_array.h"
RedisArray *ra_load_hosts(RedisArray *ra, HashTable *hosts, long retry_interval, zend_bool b_lazy_connect TSRMLS_DC);
+6 -5
View File
@@ -70,12 +70,12 @@ typedef struct {
} redis_pool;
PHPAPI redis_pool*
PHP_REDIS_API redis_pool*
redis_pool_new(TSRMLS_D) {
return ecalloc(1, sizeof(redis_pool));
}
PHPAPI void
PHP_REDIS_API void
redis_pool_add(redis_pool *pool, RedisSock *redis_sock, int weight,
int database, char *prefix, char *auth TSRMLS_DC) {
@@ -96,7 +96,7 @@ redis_pool_add(redis_pool *pool, RedisSock *redis_sock, int weight,
pool->totalWeight += weight;
}
PHPAPI void
PHP_REDIS_API void
redis_pool_free(redis_pool *pool TSRMLS_DC) {
redis_pool_member *rpm, *next;
@@ -148,9 +148,9 @@ redis_pool_member_select(redis_pool_member *rpm TSRMLS_DC) {
efree(cmd);
}
PHPAPI redis_pool_member *
PHP_REDIS_API redis_pool_member *
redis_pool_get_sock(redis_pool *pool, const char *key TSRMLS_DC) {
redis_pool_member *rpm = pool->head;
unsigned int pos, i;
redis_pool_member *rpm = pool->head;
@@ -188,6 +188,7 @@ PS_OPEN_FUNC(redis)
php_url *url;
zval *params, **param;
int i, j, path_len;
RedisSock *redis_sock;
redis_pool *pool = redis_pool_new(TSRMLS_C);
+47 -6
View File
@@ -113,6 +113,47 @@ class Redis_Test extends TestSuite
$this->assertFalse($this->redis->pubsub("numsub", "not-an-array"));
}
// Run some simple tests against the PUBSUB command. This is problematic, as we
// can't be sure what's going on in the instance, but we can do some things.
public function testPubSub() {
// Only available since 2.8.0
if(version_compare($this->version, "2.8.0", "lt")) {
$this->markTestSkipped();
return;
}
// PUBSUB CHANNELS ...
$result = $this->redis->pubsub("channels", "*");
$this->assertTrue(is_array($result));
$result = $this->redis->pubsub("channels");
$this->assertTrue(is_array($result));
// PUBSUB NUMSUB
$c1 = uniqid() . '-' . rand(1,100);
$c2 = uniqid() . '-' . rand(1,100);
$result = $this->redis->pubsub("numsub", Array($c1, $c2));
// Should get an array back, with two elements
$this->assertTrue(is_array($result));
$this->assertEquals(count($result), 2);
// Make sure the elements are correct, and have zero counts
foreach(Array($c1,$c2) as $channel) {
$this->assertTrue(isset($result[$channel]));
$this->assertEquals($result[$channel], "0");
}
// PUBSUB NUMPAT
$result = $this->redis->pubsub("numpat");
$this->assertTrue(is_int($result));
// Invalid calls
$this->assertFalse($this->redis->pubsub("notacommand"));
$this->assertFalse($this->redis->pubsub("numsub", "not-an-array"));
}
public function testBitsets() {
$this->redis->delete('key');
@@ -150,7 +191,7 @@ class Redis_Test extends TestSuite
// values above 1 are changed to 1 but don't overflow on bits to the right.
$this->assertTrue(0 === $this->redis->setBit('key', 0, 0xff));
$this->assertTrue("\x9f" === $this->redis->get('key'));
$this->assertTrue("\x9f" === $this->redis->get('key'));
// Verify valid offset ranges
$this->assertFalse($this->redis->getBit('key', -1));
@@ -1221,11 +1262,11 @@ class Redis_Test extends TestSuite
$this->assertTrue(2 === $this->redis->sSize('set0')); // no change.
$this->assertTrue($v === 'val' || $v === 'val2');
$got[$v] = $v;
if(count($got) == 2) {
break;
}
}
$got[$v] = $v;
if(count($got) == 2) {
break;
}
}
//
// With and without count, while serializing