Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

getLastError method

  • Loading branch information...
commit 048e4b2de8679222f1bfa6d834695568ab807210 1 parent dc36368
@michael-grunder michael-grunder authored
Showing with 84 additions and 4 deletions.
  1. +3 −0  common.h
  2. +47 −2 library.c
  3. +1 −0  library.h
  4. +2 −0  php_redis.h
  5. +31 −2 redis.c
View
3  common.h
@@ -184,6 +184,9 @@ typedef struct {
request_item *pipeline_head;
request_item *pipeline_current;
+
+ char *err;
+ int err_len;
} RedisSock;
/* }}} */
View
49 library.c
@@ -818,6 +818,9 @@ PHPAPI RedisSock* redis_sock_create(char *host, int host_len, unsigned short por
redis_sock->pipeline_head = NULL;
redis_sock->pipeline_current = NULL;
+ redis_sock->err = NULL;
+ redis_sock->err_len = 0;
+
return redis_sock;
}
@@ -973,6 +976,37 @@ 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
+ if(msg != NULL && msg_len > 0) {
+ if(redis_sock->err == NULL) {
+ redis_sock->err = emalloc(msg_len + 1);
+ } else if(msg_len > redis_sock->err_len) {
+ redis_sock->err = erealloc(redis_sock->err, msg_len +1);
+ }
+
+ // 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
+ if(redis_sock->err != NULL) {
+ efree(redis_sock->err);
+ }
+
+ // Set to null, with zero length
+ redis_sock->err = NULL;
+ redis_sock->err_len = 0;
+ }
+
+ // 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)
@@ -1170,6 +1204,9 @@ PHPAPI void redis_free_socket(RedisSock *redis_sock)
if(redis_sock->prefix) {
efree(redis_sock->prefix);
}
+ if(redis_sock->err) {
+ efree(redis_sock->err);
+ }
efree(redis_sock->host);
efree(redis_sock);
}
@@ -1310,7 +1347,7 @@ redis_key_prefix(RedisSock *redis_sock, char **key, int *key_len TSRMLS_DC) {
*/
PHPAPI int
-redis_sock_gets(RedisSock *redis_sock, char *buf, int buf_size, int *line_size) {
+redis_sock_gets(RedisSock *redis_sock, char *buf, int buf_size, size_t *line_size) {
// Handle EOF
if(-1 == redis_check_eof(redis_sock TSRMLS_CC)) {
return -1;
@@ -1328,6 +1365,11 @@ redis_sock_gets(RedisSock *redis_sock, char *buf, int buf_size, int *line_size)
zend_throw_exception(redis_exception_ce, "read error on connection", 0 TSRMLS_CC);
}
+ // We don't need \r\n
+ *line_size-=2;
+ buf[*line_size]='\0';
+
+
// Success!
return 0;
}
@@ -1370,7 +1412,7 @@ PHPAPI int
redis_read_variant_line(RedisSock *redis_sock, REDIS_REPLY_TYPE reply_type, zval **z_ret) {
// Buffer to read our single line reply
char inbuf[1024];
- int line_size;
+ size_t line_size;
// Attempt to read our single line reply
if(redis_sock_gets(redis_sock, inbuf, sizeof(inbuf), &line_size) < 0) {
@@ -1383,6 +1425,9 @@ redis_read_variant_line(RedisSock *redis_sock, REDIS_REPLY_TYPE reply_type, zval
zend_throw_exception(redis_exception_ce, "SYNC with master in progress", 0 TSRMLS_CC);
}
+ // Set our last error
+ redis_sock_set_err(redis_sock, inbuf, line_size);
+
// Set our response to FALSE
ZVAL_FALSE(*z_ret);
} else {
View
1  library.h
@@ -37,6 +37,7 @@ 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);
PHPAPI int
redis_serialize(RedisSock *redis_sock, zval *z, char **val, int *val_len TSRMLS_DC);
View
2  php_redis.h
@@ -133,6 +133,8 @@ PHP_METHOD(Redis, script);
PHP_METHOD(Redis, dump);
PHP_METHOD(Redis, restore);
+PHP_METHOD(Redis, getLastError);
+
PHP_METHOD(Redis, _prefix);
PHP_METHOD(Redis, _unserialize);
View
33 redis.c
@@ -161,6 +161,8 @@ static zend_function_entry redis_functions[] = {
PHP_ME(Redis, dump, NULL, ZEND_ACC_PUBLIC)
PHP_ME(Redis, restore, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Redis, getLastError, NULL, ZEND_ACC_PUBLIC)
+
PHP_ME(Redis, _prefix, NULL, ZEND_ACC_PUBLIC)
PHP_ME(Redis, _unserialize, NULL, ZEND_ACC_PUBLIC)
@@ -5607,7 +5609,7 @@ redis_build_eval_cmd(RedisSock *redis_sock, char **ret, char *keyword, char *val
zval **elem;
HashTable *args_hash;
HashPosition hash_pos;
- int cmd_len, args_count;
+ int cmd_len, args_count = 0;
int eval_cmd_count = 2;
// If we've been provided arguments, we'll want to include those in our eval command
@@ -5946,15 +5948,42 @@ PHP_METHOD(Redis, _unserialize) {
// We only need to attempt unserialization if we have a serializer running
if(redis_sock->serializer != REDIS_SERIALIZER_NONE) {
- if(redis_unserialize(redis_sock, value, value_len, &return_value TSRMLS_CC) == 0) {
+ zval *z_ret = NULL;
+ if(redis_unserialize(redis_sock, value, value_len, &z_ret TSRMLS_CC) == 0) {
zend_throw_exception(redis_exception_ce, "Invalid serialized data, or unserialization error", 0 TSRMLS_CC);
RETURN_FALSE;
}
+ RETURN_ZVAL(z_ret, 0, 0);
} else {
// Just return the value that was passed to us
RETURN_STRINGL(value, value_len, 1);
}
}
+/*
+ * {{{ proto Redis::getLastError()
+ */
+PHP_METHOD(Redis, getLastError) {
+ zval *object;
+ RedisSock *redis_sock;
+
+ // Grab our object
+ if(zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &object, redis_ce) == FAILURE) {
+ RETURN_FALSE;
+ }
+ // Grab socket
+ if(redis_sock_get(object, &redis_sock TSRMLS_CC, 0) < 0) {
+ RETURN_FALSE;
+ }
+
+ // Return our last error or NULL if we don't have one
+ if(redis_sock->err != NULL && redis_sock->err_len > 0) {
+ RETURN_STRING(redis_sock->err, 1);
+ //RETURN_STRING(redis_sock->err); // , redis_sock->err_len-1, 1);
+ } else {
+ RETURN_NULL();
+ }
+}
+
/* vim: set tabstop=4 softtabstop=4 noexpandtab shiftwidth=4: */
Please sign in to comment.
Something went wrong with that request. Please try again.