From c4e0044269ac025de8eb6d392f90db00cda16e67 Mon Sep 17 00:00:00 2001 From: Daniele Alessandri Date: Tue, 24 May 2016 16:04:44 +0200 Subject: [PATCH] Add new command: GEOPOS (Redis 3.2.0). --- src/ClientContextInterface.php | 1 + src/ClientInterface.php | 1 + src/Cluster/ClusterStrategy.php | 1 + src/Command/GeospatialGeoPos.php | 41 +++++++ src/Command/Processor/KeyPrefixProcessor.php | 1 + src/Profile/RedisVersion320.php | 1 + src/Replication/ReplicationStrategy.php | 1 + tests/Predis/Cluster/PredisStrategyTest.php | 1 + tests/Predis/Cluster/RedisStrategyTest.php | 1 + tests/Predis/Command/GeospatialGeoPosTest.php | 112 ++++++++++++++++++ .../Processor/KeyPrefixProcessorTest.php | 4 + tests/Predis/Profile/RedisUnstableTest.php | 1 + tests/Predis/Profile/RedisVersion320Test.php | 1 + .../Replication/ReplicationStrategyTest.php | 1 + 14 files changed, 168 insertions(+) create mode 100644 src/Command/GeospatialGeoPos.php create mode 100644 tests/Predis/Command/GeospatialGeoPosTest.php diff --git a/src/ClientContextInterface.php b/src/ClientContextInterface.php index bdf1d756..73a52848 100644 --- a/src/ClientContextInterface.php +++ b/src/ClientContextInterface.php @@ -158,6 +158,7 @@ use Predis\Command\CommandInterface; * @method $this command() * @method $this geoadd($key, $longitude, $latitude, $member) * @method $this geohash($key, array $members) + * @method $this geopos($key, array $members) * * @author Daniele Alessandri */ diff --git a/src/ClientInterface.php b/src/ClientInterface.php index 6154f2fc..1d7a5da0 100644 --- a/src/ClientInterface.php +++ b/src/ClientInterface.php @@ -166,6 +166,7 @@ use Predis\Profile\ProfileInterface; * @method array command() * @method int geoadd($key, $longitude, $latitude, $member) * @method array geohash($key, array $members) + * @method array geopos($key, array $members) * * @author Daniele Alessandri */ diff --git a/src/Cluster/ClusterStrategy.php b/src/Cluster/ClusterStrategy.php index bdc4dd13..3180cb39 100644 --- a/src/Cluster/ClusterStrategy.php +++ b/src/Cluster/ClusterStrategy.php @@ -169,6 +169,7 @@ abstract class ClusterStrategy implements StrategyInterface /* commands performing geospatial operations */ 'GEOADD' => $getKeyFromFirstArgument, 'GEOHASH' => $getKeyFromFirstArgument, + 'GEOPOS' => $getKeyFromFirstArgument, ); } diff --git a/src/Command/GeospatialGeoPos.php b/src/Command/GeospatialGeoPos.php new file mode 100644 index 00000000..6b7a9a3d --- /dev/null +++ b/src/Command/GeospatialGeoPos.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/geopos + * + * @author Daniele Alessandri + */ +class GeospatialGeoPos extends Command +{ + /** + * {@inheritdoc} + */ + public function getId() + { + return 'GEOPOS'; + } + + /** + * {@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 57113eed..fd217408 100644 --- a/src/Command/Processor/KeyPrefixProcessor.php +++ b/src/Command/Processor/KeyPrefixProcessor.php @@ -162,6 +162,7 @@ class KeyPrefixProcessor implements ProcessorInterface 'BITFIELD' => 'static::first', 'GEOADD' => 'static::first', 'GEOHASH' => 'static::first', + 'GEOPOS' => 'static::first', ); } diff --git a/src/Profile/RedisVersion320.php b/src/Profile/RedisVersion320.php index 6a575834..4e135718 100644 --- a/src/Profile/RedisVersion320.php +++ b/src/Profile/RedisVersion320.php @@ -272,6 +272,7 @@ class RedisVersion320 extends RedisProfile /* commands performing geospatial operations */ 'GEOADD' => 'Predis\Command\GeospatialGeoAdd', 'GEOHASH' => 'Predis\Command\GeospatialGeoHash', + 'GEOPOS' => 'Predis\Command\GeospatialGeoPos', ); } } diff --git a/src/Replication/ReplicationStrategy.php b/src/Replication/ReplicationStrategy.php index 7b768a4a..38245c32 100644 --- a/src/Replication/ReplicationStrategy.php +++ b/src/Replication/ReplicationStrategy.php @@ -259,6 +259,7 @@ class ReplicationStrategy 'SORT' => array($this, 'isSortReadOnly'), 'BITFIELD' => array($this, 'isBitfieldReadOnly'), 'GEOHASH' => true, + 'GEOPOS' => true, ); } } diff --git a/tests/Predis/Cluster/PredisStrategyTest.php b/tests/Predis/Cluster/PredisStrategyTest.php index c76d8bd9..68ad69f3 100644 --- a/tests/Predis/Cluster/PredisStrategyTest.php +++ b/tests/Predis/Cluster/PredisStrategyTest.php @@ -381,6 +381,7 @@ class PredisStrategyTest extends PredisTestCase /* commands performing geospatial operations */ 'GEOADD' => 'keys-first', 'GEOHASH' => 'keys-first', + 'GEOPOS' => 'keys-first', ); if (isset($type)) { diff --git a/tests/Predis/Cluster/RedisStrategyTest.php b/tests/Predis/Cluster/RedisStrategyTest.php index 4a5f6794..25c9d352 100644 --- a/tests/Predis/Cluster/RedisStrategyTest.php +++ b/tests/Predis/Cluster/RedisStrategyTest.php @@ -391,6 +391,7 @@ class RedisStrategyTest extends PredisTestCase /* commands performing geospatial operations */ 'GEOADD' => 'keys-first', 'GEOHASH' => 'keys-first', + 'GEOPOS' => 'keys-first', ); if (isset($type)) { diff --git a/tests/Predis/Command/GeospatialGeoPosTest.php b/tests/Predis/Command/GeospatialGeoPosTest.php new file mode 100644 index 00000000..18c87638 --- /dev/null +++ b/tests/Predis/Command/GeospatialGeoPosTest.php @@ -0,0 +1,112 @@ + + * + * 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 GeospatialGeoPosTest extends PredisCommandTestCase +{ + /** + * {@inheritdoc} + */ + protected function getExpectedCommand() + { + return 'Predis\Command\GeospatialGeoPos'; + } + + /** + * {@inheritdoc} + */ + protected function getExpectedId() + { + return 'GEOPOS'; + } + + /** + * @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( + array("13.361389338970184", "38.115556395496299"), + array("15.087267458438873", "37.50266842333162"), + ); + + $expected = array( + array("13.361389338970184", "38.115556395496299"), + array("15.087267458438873", "37.50266842333162"), + ); + + $command = $this->getCommand(); + + $this->assertSame($expected, $command->parseResponse($raw)); + } + + /** + * @group connected + * @requiresRedisVersion >= 3.2.0 + */ + public function testCommandReturnsGeoPositions() + { + $redis = $this->getClient(); + + $redis->geoadd('Sicily', '13.361389', '38.115556', 'Palermo', '15.087269', '37.502669', 'Catania'); + $this->assertEquals(array( + array("13.361389338970184", "38.115556395496299"), + array("15.087267458438873", "37.50266842333162"), + ), $redis->geopos('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->geopos('Sicily', 'Palermo'); + } +} diff --git a/tests/Predis/Command/Processor/KeyPrefixProcessorTest.php b/tests/Predis/Command/Processor/KeyPrefixProcessorTest.php index 72ec7928..d2d2f777 100644 --- a/tests/Predis/Command/Processor/KeyPrefixProcessorTest.php +++ b/tests/Predis/Command/Processor/KeyPrefixProcessorTest.php @@ -881,6 +881,10 @@ class KeyPrefixProcessorTest extends PredisTestCase array('key', 'member:1', 'member:2'), array('prefix:key', 'member:1', 'member:2'), ), + array('GEOPOS', + 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 75990e3c..5e07bccd 100644 --- a/tests/Predis/Profile/RedisUnstableTest.php +++ b/tests/Predis/Profile/RedisUnstableTest.php @@ -193,6 +193,7 @@ class RedisUnstableTest extends PredisProfileTestCase 152 => 'BITFIELD', 153 => 'GEOADD', 154 => 'GEOHASH', + 155 => 'GEOPOS', ); } } diff --git a/tests/Predis/Profile/RedisVersion320Test.php b/tests/Predis/Profile/RedisVersion320Test.php index a9ab0608..d9346ad7 100644 --- a/tests/Predis/Profile/RedisVersion320Test.php +++ b/tests/Predis/Profile/RedisVersion320Test.php @@ -193,6 +193,7 @@ class RedisVersion320Test extends PredisProfileTestCase 152 => 'BITFIELD', 153 => 'GEOADD', 154 => 'GEOHASH', + 155 => 'GEOPOS', ); } } diff --git a/tests/Predis/Replication/ReplicationStrategyTest.php b/tests/Predis/Replication/ReplicationStrategyTest.php index 8ff2bcac..b7cedaf8 100644 --- a/tests/Predis/Replication/ReplicationStrategyTest.php +++ b/tests/Predis/Replication/ReplicationStrategyTest.php @@ -442,6 +442,7 @@ class ReplicationStrategyTest extends PredisTestCase /* commands performing geospatial operations */ 'GEOADD' => 'write', 'GEOHASH' => 'read', + 'GEOPOS' => 'read', ); if (isset($type)) {