Skip to content
Browse files

Bugfix for hgetall used with serializer.

Fixes issue #62.
Also started removing phpunit, it is such a pain to use.
  • Loading branch information...
1 parent ccc916d commit 27fc7c79a2937365bce5984a820cc6a607314dad @nicolasff nicolasff committed
Showing with 86 additions and 25 deletions.
  1. +13 −6 library.c
  2. +1 −1 library.h
  3. +72 −18 tests/TestRedis.php
View
19 library.c
@@ -14,6 +14,9 @@
#include "library.h"
#include <ext/standard/php_math.h>
+#define UNSERIALIZE_ONLY_VALUES 0
+#define UNSERIALIZE_ALL 1
+
extern zend_class_entry *redis_ce;
extern zend_class_entry *redis_exception_ce;
extern zend_class_entry *spl_ce_RuntimeException;
@@ -82,7 +85,7 @@ PHPAPI zval *redis_sock_read_multibulk_reply_zval(INTERNAL_FUNCTION_PARAMETERS,
array_init(z_tab);
redis_sock_read_multibulk_reply_loop(INTERNAL_FUNCTION_PARAM_PASSTHRU,
- redis_sock, z_tab, numElems, 1);
+ redis_sock, z_tab, numElems, 1, UNSERIALIZE_ALL);
return z_tab;
}
@@ -556,7 +559,7 @@ PHPAPI int redis_sock_read_multibulk_reply_zipped_with_flag(INTERNAL_FUNCTION_PA
array_init(z_multi_result); /* pre-allocate array for multi's results. */
redis_sock_read_multibulk_reply_loop(INTERNAL_FUNCTION_PARAM_PASSTHRU,
- redis_sock, z_multi_result, numElems, 1);
+ redis_sock, z_multi_result, numElems, 1, flag ? UNSERIALIZE_ALL : UNSERIALIZE_ONLY_VALUES);
array_zip_values_and_scores(redis_sock, z_multi_result, 0 TSRMLS_CC);
@@ -855,7 +858,7 @@ PHPAPI int redis_sock_read_multibulk_reply(INTERNAL_FUNCTION_PARAMETERS, RedisSo
array_init(z_multi_result); /* pre-allocate array for multi's results. */
redis_sock_read_multibulk_reply_loop(INTERNAL_FUNCTION_PARAM_PASSTHRU,
- redis_sock, z_multi_result, numElems, 1);
+ redis_sock, z_multi_result, numElems, 1, UNSERIALIZE_ALL);
IF_MULTI_OR_PIPELINE() {
add_next_index_zval(z_tab, z_multi_result);
@@ -896,7 +899,7 @@ PHPAPI int redis_sock_read_multibulk_reply_raw(INTERNAL_FUNCTION_PARAMETERS, Red
array_init(z_multi_result); /* pre-allocate array for multi's results. */
redis_sock_read_multibulk_reply_loop(INTERNAL_FUNCTION_PARAM_PASSTHRU,
- redis_sock, z_multi_result, numElems, 0);
+ redis_sock, z_multi_result, numElems, 0, UNSERIALIZE_ALL);
IF_MULTI_OR_PIPELINE() {
add_next_index_zval(z_tab, z_multi_result);
@@ -910,7 +913,7 @@ PHPAPI int redis_sock_read_multibulk_reply_raw(INTERNAL_FUNCTION_PARAMETERS, Red
PHPAPI int
redis_sock_read_multibulk_reply_loop(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
- zval *z_tab, int numElems, int unwrap_key)
+ zval *z_tab, int numElems, int unwrap_key, int unserialize_even_only)
{
char *response;
int response_len;
@@ -919,7 +922,11 @@ redis_sock_read_multibulk_reply_loop(INTERNAL_FUNCTION_PARAMETERS, RedisSock *re
response = redis_sock_read(redis_sock, &response_len TSRMLS_CC);
if(response != NULL) {
zval *z = NULL;
- if(unwrap_key && redis_unserialize(redis_sock, response, response_len, &z TSRMLS_CC) == 1) {
+ int can_unserialize = unwrap_key;
+ if(unserialize_even_only == UNSERIALIZE_ONLY_VALUES && numElems % 2 == 0)
+ can_unserialize = 0;
+
+ if(can_unserialize && redis_unserialize(redis_sock, response, response_len, &z TSRMLS_CC) == 1) {
efree(response);
add_next_index_zval(z_tab, z);
} else {
View
2 library.h
@@ -21,7 +21,7 @@ PHPAPI zval *redis_sock_read_multibulk_reply_zval(INTERNAL_FUNCTION_PARAMETERS,
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);
+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);
View
90 tests/TestRedis.php
@@ -1,14 +1,17 @@
<?php
-require_once 'PHPUnit.php';
+
+// phpunit is such a pain to install, we're going with pure-PHP here.
echo "Note: these tests might take up to a minute. Don't worry :-)\n";
-class Redis_Test extends PHPUnit_TestCase
+class Redis_Test
{
const HOST = '127.0.0.1';
const PORT = 6379;
const AUTH = NULL; //replace with a string to use Redis authentication
+ public static $errors = array();
+
/**
* @var Redis
*/
@@ -19,6 +22,31 @@ public function setUp()
$this->redis = $this->newInstance();
}
+ private function assertFalse($bool) {
+ $this->assertTrue(!$bool);
+ }
+
+ private function assertTrue($bool) {
+ if($bool)
+ return;
+
+ $bt = debug_backtrace(false);
+ $count = count($bt);
+ self::$errors []= sprintf("Assertion failed: %s:%d (%s)\n",
+ $bt[$count - 2]["file"], $bt[$count - 3]["line"], $bt[$count - 1]["function"]);
+ }
+
+ private function assertEquals($a, $b) {
+ if($a === $b)
+ return;
+
+ $bt = debug_backtrace(false);
+ $count = count($bt);
+ self::$errors []= sprintf("Assertion failed (%s !== %s): %s:%d (%s)\n",
+ print_r($a, true), print_r($b, true),
+ $bt[$count - 2]["file"], $bt[$count - 3]["line"], $bt[$count - 1]["function"]);
+ }
+
private function newInstance() {
$r = new Redis();
$r->connect(self::HOST, self::PORT);
@@ -333,22 +361,22 @@ public function testIncr()
$this->redis->set('key', 0);
$this->redis->incr('key');
- $this->assertEquals(1, $this->redis->get('key'));
+ $this->assertEquals(1, (int)$this->redis->get('key'));
$this->redis->incr('key');
- $this->assertEquals(2, $this->redis->get('key'));
+ $this->assertEquals(2, (int)$this->redis->get('key'));
$this->redis->incr('key', 3);
- $this->assertEquals(5, $this->redis->get('key'));
+ $this->assertEquals(5, (int)$this->redis->get('key'));
$this->redis->incrBy('key', 3);
- $this->assertEquals(8, $this->redis->get('key'));
+ $this->assertEquals(8, (int)$this->redis->get('key'));
$this->redis->incrBy('key', 1);
- $this->assertEquals(9, $this->redis->get('key'));
+ $this->assertEquals(9, (int)$this->redis->get('key'));
$this->redis->incrBy('key', -1);
- $this->assertEquals(8, $this->redis->get('key'));
+ $this->assertEquals(8, (int)$this->redis->get('key'));
$this->redis->delete('key');
@@ -367,25 +395,25 @@ public function testDecr()
$this->redis->set('key', 5);
$this->redis->decr('key');
- $this->assertEquals(4, $this->redis->get('key'));
+ $this->assertEquals(4, (int)$this->redis->get('key'));
$this->redis->decr('key');
- $this->assertEquals(3, $this->redis->get('key'));
+ $this->assertEquals(3, (int)$this->redis->get('key'));
$this->redis->decr('key', 2);
- $this->assertEquals(1, $this->redis->get('key'));
+ $this->assertEquals(1, (int)$this->redis->get('key'));
$this->redis->decr('key', 2);
- $this->assertEquals(-1, $this->redis->get('key'));
+ $this->assertEquals(-1, (int)$this->redis->get('key'));
$this->redis->decrBy('key', 2);
- $this->assertEquals(-3, $this->redis->get('key'));
+ $this->assertEquals(-3, (int)$this->redis->get('key'));
$this->redis->decrBy('key', 1);
- $this->assertEquals(-4, $this->redis->get('key'));
+ $this->assertEquals(-4, (int)$this->redis->get('key'));
$this->redis->decr('key', -10);
- $this->assertEquals(6, $this->redis->get('key'));
+ $this->assertEquals(6, (int)$this->redis->get('key'));
}
public function testExists()
@@ -2766,16 +2794,42 @@ private function checkSerializer($mode) {
// keys
$this->assertTrue(is_array($this->redis->keys('*')));
+ // issue #62, hgetall
+ $this->redis->del('hash1');
+ $this->redis->hSet('hash1','data', 'test 1');
+ $this->redis->hSet('hash1','session_id', 'test 2');
+
+ $data = $this->redis->hGetAll('hash1');
+ $this->assertTrue($data['data'] === 'test 1');
+ $this->assertTrue($data['session_id'] === 'test 2');
+
// revert
$this->assertTrue($this->redis->setOption(Redis::OPT_SERIALIZER, Redis::SERIALIZER_NONE) === TRUE); // set ok
$this->assertTrue($this->redis->getOption(Redis::OPT_SERIALIZER) === Redis::SERIALIZER_NONE); // get ok
}
}
-$suite = new PHPUnit_TestSuite("Redis_Test");
-$result = PHPUnit::run($suite);
+$rc = new ReflectionClass("Redis_Test");
+$methods = $rc->GetMethods(ReflectionMethod::IS_PUBLIC);
-echo $result->toString();
+foreach($methods as $m) {
+ $name = $m->name;
+ if(substr($name, 0, 4) !== 'test')
+ continue;
+
+ $count = count(Redis_Test::$errors);
+ $rt = new Redis_Test;
+ $rt->setUp();
+ $rt->$name();
+ echo ($count === count(Redis_Test::$errors)) ? "." : "F";
+}
+echo "\n";
+
+if(empty(Redis_Test::$errors)) {
+ echo "All tests passed.\n";
+ exit(0);
+}
+echo implode('', Redis_Test::$errors);
?>

0 comments on commit 27fc7c7

Please sign in to comment.
Something went wrong with that request. Please try again.