Skip to content

Commit

Permalink
JSON serializer
Browse files Browse the repository at this point in the history
  • Loading branch information
yatsukhnenko committed May 12, 2019
1 parent 8a45d18 commit 98bd288
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 15 deletions.
13 changes: 8 additions & 5 deletions common.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,13 @@ typedef enum _PUBSUB_TYPE {
#define REDIS_FAILOVER_DISTRIBUTE 2
#define REDIS_FAILOVER_DISTRIBUTE_SLAVES 3
/* serializers */
#define REDIS_SERIALIZER_NONE 0
#define REDIS_SERIALIZER_PHP 1
#define REDIS_SERIALIZER_IGBINARY 2
#define REDIS_SERIALIZER_MSGPACK 3
typedef enum {
REDIS_SERIALIZER_NONE,
REDIS_SERIALIZER_PHP,
REDIS_SERIALIZER_IGBINARY,
REDIS_SERIALIZER_MSGPACK,
REDIS_SERIALIZER_JSON
} redis_serializer;
/* compression */
#define REDIS_COMPRESSION_NONE 0
#define REDIS_COMPRESSION_LZF 1
Expand Down Expand Up @@ -252,7 +255,7 @@ typedef struct {
int watching;
zend_string *persistent_id;

int serializer;
redis_serializer serializer;
int compression;
long dbNumber;

Expand Down
20 changes: 17 additions & 3 deletions library.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "php_redis.h"
#include "library.h"
#include "redis_commands.h"
#include <ext/json/php_json.h>
#include <ext/standard/php_rand.h>

#define UNSERIALIZE_NONE 0
Expand Down Expand Up @@ -2165,7 +2166,6 @@ redis_serialize(RedisSock *redis_sock, zval *z, char **val, size_t *val_len
switch(redis_sock->serializer) {
case REDIS_SERIALIZER_NONE:
switch(Z_TYPE_P(z)) {

case IS_STRING:
*val = Z_STRVAL_P(z);
*val_len = Z_STRLEN_P(z);
Expand Down Expand Up @@ -2205,8 +2205,8 @@ redis_serialize(RedisSock *redis_sock, zval *z, char **val, size_t *val_len
case REDIS_SERIALIZER_MSGPACK:
#ifdef HAVE_REDIS_MSGPACK
php_msgpack_serialize(&sstr, z TSRMLS_CC);
*val = estrndup(sstr.s->val, sstr.s->len);
*val_len = sstr.s->len;
*val = estrndup(ZSTR_VAL(sstr.s), ZSTR_LEN(sstr.s));
*val_len = ZSTR_LEN(sstr.s);
smart_str_free(&sstr);

return 1;
Expand All @@ -2221,6 +2221,13 @@ redis_serialize(RedisSock *redis_sock, zval *z, char **val, size_t *val_len
}
#endif
break;
case REDIS_SERIALIZER_JSON:
php_json_encode(&sstr, z, PHP_JSON_OBJECT_AS_ARRAY);
*val = estrndup(ZSTR_VAL(sstr.s), ZSTR_LEN(sstr.s));
*val_len = ZSTR_LEN(sstr.s);
smart_str_free(&sstr);
return 1;
EMPTY_SWITCH_DEFAULT_CASE()
}

return 0;
Expand All @@ -2235,6 +2242,9 @@ redis_unserialize(RedisSock* redis_sock, const char *val, int val_len,
int ret = 0;

switch(redis_sock->serializer) {
case REDIS_SERIALIZER_NONE:
/* Nothing to do */
break;
case REDIS_SERIALIZER_PHP:
PHP_VAR_UNSERIALIZE_INIT(var_hash);

Expand Down Expand Up @@ -2280,6 +2290,10 @@ redis_unserialize(RedisSock* redis_sock, const char *val, int val_len,
ret = !igbinary_unserialize((const uint8_t *)val, (size_t)val_len, z_ret TSRMLS_CC);
#endif
break;
case REDIS_SERIALIZER_JSON:
ret = !php_json_decode(z_ret, (char *)val, val_len, 1, PHP_JSON_PARSER_DEFAULT_DEPTH);
break;
EMPTY_SWITCH_DEFAULT_CASE()
}

return ret;
Expand Down
8 changes: 4 additions & 4 deletions redis.c
Original file line number Diff line number Diff line change
Expand Up @@ -673,6 +673,10 @@ static void add_class_constants(zend_class_entry *ce, int is_cluster TSRMLS_DC)
#ifdef HAVE_REDIS_IGBINARY
zend_declare_class_constant_long(ce, ZEND_STRL("SERIALIZER_IGBINARY"), REDIS_SERIALIZER_IGBINARY TSRMLS_CC);
#endif
#ifdef HAVE_REDIS_MSGPACK
zend_declare_class_constant_long(ce, ZEND_STRL("SERIALIZER_MSGPACK"), REDIS_SERIALIZER_MSGPACK TSRMLS_CC);
#endif
zend_declare_class_constant_long(ce, ZEND_STRL("SERIALIZER_JSON"), REDIS_SERIALIZER_JSON TSRMLS_CC);

/* compression */
zend_declare_class_constant_long(ce, ZEND_STRL("COMPRESSION_NONE"), REDIS_COMPRESSION_NONE TSRMLS_CC);
Expand All @@ -694,10 +698,6 @@ static void add_class_constants(zend_class_entry *ce, int is_cluster TSRMLS_DC)
zend_declare_class_constant_long(ce, ZEND_STRL("FAILOVER_DISTRIBUTE_SLAVES"), REDIS_FAILOVER_DISTRIBUTE_SLAVES TSRMLS_CC);
}

#ifdef HAVE_REDIS_MSGPACK
zend_declare_class_constant_long(ce, ZEND_STRL("SERIALIZER_MSGPACK"), REDIS_SERIALIZER_MSGPACK TSRMLS_CC);
#endif

zend_declare_class_constant_stringl(ce, "AFTER", 5, "after", 5 TSRMLS_CC);
zend_declare_class_constant_stringl(ce, "BEFORE", 6, "before", 6 TSRMLS_CC);
}
Expand Down
4 changes: 3 additions & 1 deletion redis_commands.c
Original file line number Diff line number Diff line change
Expand Up @@ -3882,7 +3882,9 @@ void redis_setoption_handler(INTERNAL_FUNCTION_PARAMETERS,
switch(option) {
case REDIS_OPT_SERIALIZER:
val_long = zval_get_long(val);
if (val_long == REDIS_SERIALIZER_NONE || val_long == REDIS_SERIALIZER_PHP
if (val_long == REDIS_SERIALIZER_NONE
|| val_long == REDIS_SERIALIZER_PHP
|| val_long == REDIS_SERIALIZER_JSON
#ifdef HAVE_REDIS_IGBINARY
|| val_long == REDIS_SERIALIZER_IGBINARY
#endif
Expand Down
19 changes: 17 additions & 2 deletions tests/RedisTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4244,6 +4244,16 @@ public function testSerializerMsgPack() {
}
}

public function testSerializerJSON()
{
$this->checkSerializer(Redis::SERIALIZER_JSON);

// with prefix
$this->redis->setOption(Redis::OPT_PREFIX, "test:");
$this->checkSerializer(Redis::SERIALIZER_JSON);
$this->redis->setOption(Redis::OPT_PREFIX, "");
}

private function checkSerializer($mode) {

$this->redis->del('key');
Expand Down Expand Up @@ -4452,8 +4462,13 @@ private function checkSerializer($mode) {
$this->redis->set('x', [new stdClass, new stdClass]);
$x = $this->redis->get('x');
$this->assertTrue(is_array($x));
$this->assertTrue(is_object($x[0]) && get_class($x[0]) === 'stdClass');
$this->assertTrue(is_object($x[1]) && get_class($x[1]) === 'stdClass');
if ($mode === Redis::SERIALIZER_JSON) {
$this->assertTrue(is_array($x[0]));
$this->assertTrue(is_array($x[1]));
} else {
$this->assertTrue(is_object($x[0]) && get_class($x[0]) === 'stdClass');
$this->assertTrue(is_object($x[1]) && get_class($x[1]) === 'stdClass');
}

// revert
$this->assertTrue($this->redis->setOption(Redis::OPT_SERIALIZER, Redis::SERIALIZER_NONE) === TRUE); // set ok
Expand Down

0 comments on commit 98bd288

Please sign in to comment.