Skip to content

Commit

Permalink
getLastError method
Browse files Browse the repository at this point in the history
  • Loading branch information
michael-grunder committed May 12, 2012
1 parent dc36368 commit 048e4b2
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 4 deletions.
3 changes: 3 additions & 0 deletions common.h
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,9 @@ typedef struct {

request_item *pipeline_head;
request_item *pipeline_current;

char *err;
int err_len;
} RedisSock;
/* }}} */

Expand Down
49 changes: 47 additions & 2 deletions library.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down Expand Up @@ -972,6 +975,37 @@ PHPAPI void redis_send_discard(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_so
RETURN_FALSE;
}

/**
* 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
*/
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -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;
Expand All @@ -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;
}
Expand Down Expand Up @@ -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) {
Expand All @@ -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 {
Expand Down
1 change: 1 addition & 0 deletions library.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
2 changes: 2 additions & 0 deletions php_redis.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
33 changes: 31 additions & 2 deletions redis.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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: */

0 comments on commit 048e4b2

Please sign in to comment.