diff --git a/CHANGELOG.md b/CHANGELOG.md index 5fb3de6a3..e93d17690 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ Yii Framework 2 redis extension Change Log - Bug #37: Fixed detection of open socket (mirocow) - Chg #14: Added missing `BLPOP` to `$redisCommands` (samdark) - +- Enh #39: Work with redis hashes as php arrays 2.0.4 May 10, 2015 ------------------ diff --git a/Connection.php b/Connection.php index 91f6fb2f2..2287e4731 100644 --- a/Connection.php +++ b/Connection.php @@ -225,7 +225,7 @@ class Connection extends Component /** * @var resource redis socket connection */ - private $_socket = false; + private $_socket; /** @@ -245,7 +245,7 @@ public function __sleep() */ public function getIsActive() { - return $this->_socket !== false; + return $this->_socket !== null; } /** @@ -255,7 +255,7 @@ public function getIsActive() */ public function open() { - if ($this->_socket !== false) { + if ($this->_socket !== null) { return; } $connection = ($this->unixSocket ?: $this->hostname . ':' . $this->port) . ', database=' . $this->database; @@ -288,7 +288,7 @@ public function open() */ public function close() { - if ($this->_socket !== false) { + if ($this->_socket !== null) { $connection = ($this->unixSocket ?: $this->hostname . ':' . $this->port) . ', database=' . $this->database; \Yii::trace('Closing DB connection: ' . $connection, __METHOD__); $this->executeCommand('QUIT'); @@ -432,4 +432,58 @@ private function parseResponse($command) throw new Exception('Received illegal data from redis: ' . $line . "\nRedis command was: " . $command); } } + + /** + * See [http://redis.io/commands/hset](http://redis.io/commands/hset) + * @param string $key + * @param array $data - ['field' => 'value'] + */ + public function hSet($key, array $data) + { + + return $this->executeCommand('HSET', [$key, key($data), reset($data)]); + } + + /** + * See [http://redis.io/commands/hmset](http://redis.io/commands/hmset) + * @param string $key + * @param array $data - ['field' => 'value', 'field2' => 'value'] + */ + public function hmSet($key, array $data) + { + $command = [$key]; + + foreach ($data as $field => $value) { + array_push($command, $field); + array_push($command, $value); + } + + return $this->executeCommand('HMSET', $command); + } + + /** + * [http://redis.io/commands/hgetall](http://redis.io/commands/hgetall) + * @param string $key + * @return array + */ + public function hGetAll($key) + { + $response = $this->executeCommand('HGETALL', [$key]); + return $this->modifyHashResponse($response); + } + + /** + * @param array $response + * @return array + */ + private function modifyHashResponse(array $response) + { + $data = []; + + for ($i = 0; $i < count($response); $i += 2) { + $data[$response[$i]] = $response[$i + 1]; + } + + return $data; + } } diff --git a/tests/RedisConnectionTest.php b/tests/RedisConnectionTest.php index e54fddce0..4ab8e1c8f 100644 --- a/tests/RedisConnectionTest.php +++ b/tests/RedisConnectionTest.php @@ -80,4 +80,50 @@ public function testReturnType() $this->assertEquals($expected[$key], $redis->executeCommand('TYPE',[$key])); } } + + public function hashSetData() + { + return [ + ['hash2', ['hello' => 'world']], + ['hash3', ['good' => 'day']], + ['hash4', [4 => 'world']], + ['hash5', ['world' => 15]], + ['hash6', ['world' => null]], + ['hash7', ['world' => true]] + ]; + } + + public function hashMSetData() + { + return [ + ['hashMSet2', ['hello' => 'world', 'test' => 'case']], + ['hashMSet3', ['hello' => 13, 'test' => null]], + ]; + } + + /** + * @dataProvider hashSetData + */ + public function testHSet($key, $data) + { + $redis = $this->getConnection(); + + $redis->hSet($key, $data); + + $this->assertEquals('hash', $redis->executeCommand('TYPE', [$key])); + $this->assertEquals($data, $redis->hGetAll($key)); + } + + /** + * @dataProvider hashMSetData + */ + public function testHMSet($key, $data) + { + $redis = $this->getConnection(); + + $redis->hmSet($key, $data); + + $this->assertEquals('hash', $redis->executeCommand('TYPE', [$key])); + $this->assertEquals($data, $redis->hGetAll($key)); + } }