diff --git a/src/ClientContextInterface.php b/src/ClientContextInterface.php index 0095bcb9..bdf1d756 100644 --- a/src/ClientContextInterface.php +++ b/src/ClientContextInterface.php @@ -157,6 +157,7 @@ use Predis\Command\CommandInterface; * @method $this time() * @method $this command() * @method $this geoadd($key, $longitude, $latitude, $member) + * @method $this geohash($key, array $members) * * @author Daniele Alessandri */ diff --git a/src/ClientInterface.php b/src/ClientInterface.php index 8d76bc5c..6154f2fc 100644 --- a/src/ClientInterface.php +++ b/src/ClientInterface.php @@ -165,6 +165,7 @@ use Predis\Profile\ProfileInterface; * @method array time() * @method array command() * @method int geoadd($key, $longitude, $latitude, $member) + * @method array geohash($key, array $members) * * @author Daniele Alessandri */ diff --git a/src/Cluster/ClusterStrategy.php b/src/Cluster/ClusterStrategy.php index b89b0a32..bdc4dd13 100644 --- a/src/Cluster/ClusterStrategy.php +++ b/src/Cluster/ClusterStrategy.php @@ -168,6 +168,7 @@ abstract class ClusterStrategy implements StrategyInterface /* commands performing geospatial operations */ 'GEOADD' => $getKeyFromFirstArgument, + 'GEOHASH' => $getKeyFromFirstArgument, ); } diff --git a/src/Command/GeospatialGeoHash.php b/src/Command/GeospatialGeoHash.php new file mode 100644 index 00000000..2eccaf4f --- /dev/null +++ b/src/Command/GeospatialGeoHash.php @@ -0,0 +1,41 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Predis\Command; + +/** + * @link http://redis.io/commands/geohash + * + * @author Daniele Alessandri + */ +class GeospatialGeoHash extends Command +{ + /** + * {@inheritdoc} + */ + public function getId() + { + return 'GEOHASH'; + } + + /** + * {@inheritdoc} + */ + protected function filterArguments(array $arguments) + { + if (count($arguments) === 2 && is_array($arguments[1])) { + $members = array_pop($arguments); + $arguments = array_merge($arguments, $members); + } + + return $arguments; + } +} diff --git a/src/Command/Processor/KeyPrefixProcessor.php b/src/Command/Processor/KeyPrefixProcessor.php index 4ac371d8..57113eed 100644 --- a/src/Command/Processor/KeyPrefixProcessor.php +++ b/src/Command/Processor/KeyPrefixProcessor.php @@ -161,6 +161,7 @@ class KeyPrefixProcessor implements ProcessorInterface 'HSTRLEN' => 'static::first', 'BITFIELD' => 'static::first', 'GEOADD' => 'static::first', + 'GEOHASH' => 'static::first', ); } diff --git a/src/Profile/RedisVersion320.php b/src/Profile/RedisVersion320.php index e66ac1da..6a575834 100644 --- a/src/Profile/RedisVersion320.php +++ b/src/Profile/RedisVersion320.php @@ -271,6 +271,7 @@ class RedisVersion320 extends RedisProfile /* commands performing geospatial operations */ 'GEOADD' => 'Predis\Command\GeospatialGeoAdd', + 'GEOHASH' => 'Predis\Command\GeospatialGeoHash', ); } } diff --git a/src/Replication/ReplicationStrategy.php b/src/Replication/ReplicationStrategy.php index a1c5840f..7b768a4a 100644 --- a/src/Replication/ReplicationStrategy.php +++ b/src/Replication/ReplicationStrategy.php @@ -258,6 +258,7 @@ class ReplicationStrategy 'PFCOUNT' => true, 'SORT' => array($this, 'isSortReadOnly'), 'BITFIELD' => array($this, 'isBitfieldReadOnly'), + 'GEOHASH' => true, ); } } diff --git a/tests/Predis/Cluster/PredisStrategyTest.php b/tests/Predis/Cluster/PredisStrategyTest.php index db8d49ce..c76d8bd9 100644 --- a/tests/Predis/Cluster/PredisStrategyTest.php +++ b/tests/Predis/Cluster/PredisStrategyTest.php @@ -380,6 +380,7 @@ class PredisStrategyTest extends PredisTestCase /* commands performing geospatial operations */ 'GEOADD' => 'keys-first', + 'GEOHASH' => 'keys-first', ); if (isset($type)) { diff --git a/tests/Predis/Cluster/RedisStrategyTest.php b/tests/Predis/Cluster/RedisStrategyTest.php index 649fc9e0..4a5f6794 100644 --- a/tests/Predis/Cluster/RedisStrategyTest.php +++ b/tests/Predis/Cluster/RedisStrategyTest.php @@ -390,6 +390,7 @@ class RedisStrategyTest extends PredisTestCase /* commands performing geospatial operations */ 'GEOADD' => 'keys-first', + 'GEOHASH' => 'keys-first', ); if (isset($type)) { diff --git a/tests/Predis/Command/GeospatialGeoHashTest.php b/tests/Predis/Command/GeospatialGeoHashTest.php new file mode 100644 index 00000000..bd354146 --- /dev/null +++ b/tests/Predis/Command/GeospatialGeoHashTest.php @@ -0,0 +1,102 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Predis\Command; + +/** + * @group commands + * @group realm-geospatial + */ +class GeospatialGeoHashTest extends PredisCommandTestCase +{ + /** + * {@inheritdoc} + */ + protected function getExpectedCommand() + { + return 'Predis\Command\GeospatialGeoHash'; + } + + /** + * {@inheritdoc} + */ + protected function getExpectedId() + { + return 'GEOHASH'; + } + + /** + * @group disconnected + */ + public function testFilterArguments() + { + $arguments = array('key', 'member:1', 'member:2'); + $expected = array('key', 'member:1', 'member:2'); + + $command = $this->getCommand(); + $command->setArguments($arguments); + + $this->assertSame($expected, $command->getArguments()); + } + + /** + * @group disconnected + */ + public function testFilterArgumentsWithMembersAsSingleArray() + { + $arguments = array('key', array('member:1', 'member:2')); + $expected = array('key', 'member:1', 'member:2'); + + $command = $this->getCommand(); + $command->setArguments($arguments); + + $this->assertSame($expected, $command->getArguments()); + } + + /** + * @group disconnected + */ + public function testParseResponse() + { + $raw = array('sqc8b49rny0', 'sqdtr74hyu0'); + $expected = array('sqc8b49rny0', 'sqdtr74hyu0'); + + $command = $this->getCommand(); + + $this->assertSame($expected, $command->parseResponse($raw)); + } + + /** + * @group connected + * @requiresRedisVersion >= 3.2.0 + */ + public function testCommandReturnsGeoHashes() + { + $redis = $this->getClient(); + + $redis->geoadd('Sicily', '13.361389', '38.115556', 'Palermo', '15.087269', '37.502669', 'Catania'); + $this->assertSame(array('sqc8b49rny0', 'sqdtr74hyu0'), $redis->geohash('Sicily', 'Palermo', 'Catania')); + } + + /** + * @group connected + * @requiresRedisVersion >= 3.2.0 + * @expectedException \Predis\Response\ServerException + * @expectedExceptionMessage Operation against a key holding the wrong kind of value + */ + public function testThrowsExceptionOnWrongType() + { + $redis = $this->getClient(); + + $redis->lpush('Sicily', 'Palermo'); + $redis->geohash('Sicily', 'Palermo'); + } +} diff --git a/tests/Predis/Command/Processor/KeyPrefixProcessorTest.php b/tests/Predis/Command/Processor/KeyPrefixProcessorTest.php index 5b883a4a..72ec7928 100644 --- a/tests/Predis/Command/Processor/KeyPrefixProcessorTest.php +++ b/tests/Predis/Command/Processor/KeyPrefixProcessorTest.php @@ -877,6 +877,10 @@ class KeyPrefixProcessorTest extends PredisTestCase array('key', '13.361389', '38.115556', 'member:1', '15.087269', '37.502669', 'member:2'), array('prefix:key', '13.361389', '38.115556', 'member:1', '15.087269', '37.502669', 'member:2'), ), + array('GEOHASH', + array('key', 'member:1', 'member:2'), + array('prefix:key', 'member:1', 'member:2'), + ), ); } } diff --git a/tests/Predis/Profile/RedisUnstableTest.php b/tests/Predis/Profile/RedisUnstableTest.php index 5966f5ec..75990e3c 100644 --- a/tests/Predis/Profile/RedisUnstableTest.php +++ b/tests/Predis/Profile/RedisUnstableTest.php @@ -192,6 +192,7 @@ class RedisUnstableTest extends PredisProfileTestCase 151 => 'HSTRLEN', 152 => 'BITFIELD', 153 => 'GEOADD', + 154 => 'GEOHASH', ); } } diff --git a/tests/Predis/Profile/RedisVersion320Test.php b/tests/Predis/Profile/RedisVersion320Test.php index 51b48b91..a9ab0608 100644 --- a/tests/Predis/Profile/RedisVersion320Test.php +++ b/tests/Predis/Profile/RedisVersion320Test.php @@ -192,6 +192,7 @@ class RedisVersion320Test extends PredisProfileTestCase 151 => 'HSTRLEN', 152 => 'BITFIELD', 153 => 'GEOADD', + 154 => 'GEOHASH', ); } } diff --git a/tests/Predis/Replication/ReplicationStrategyTest.php b/tests/Predis/Replication/ReplicationStrategyTest.php index 1ad30755..8ff2bcac 100644 --- a/tests/Predis/Replication/ReplicationStrategyTest.php +++ b/tests/Predis/Replication/ReplicationStrategyTest.php @@ -441,6 +441,7 @@ class ReplicationStrategyTest extends PredisTestCase /* commands performing geospatial operations */ 'GEOADD' => 'write', + 'GEOHASH' => 'read', ); if (isset($type)) {