From 7ef9619f5cfc49d133f1e9b7ad5baa4ff93a6100 Mon Sep 17 00:00:00 2001 From: Daniele Alessandri Date: Tue, 24 May 2016 12:24:30 +0200 Subject: [PATCH] Add new command: GEOADD (Redis 3.2.0). --- src/ClientContextInterface.php | 1 + src/ClientInterface.php | 1 + src/Cluster/ClusterStrategy.php | 3 + src/Command/GeospatialGeoAdd.php | 42 +++++++ src/Command/Processor/KeyPrefixProcessor.php | 1 + src/Profile/RedisVersion320.php | 3 + tests/Predis/Cluster/PredisStrategyTest.php | 3 + tests/Predis/Cluster/RedisStrategyTest.php | 3 + tests/Predis/Command/GeospatialGeoAddTest.php | 106 ++++++++++++++++++ .../Processor/KeyPrefixProcessorTest.php | 4 + tests/Predis/Profile/RedisUnstableTest.php | 1 + tests/Predis/Profile/RedisVersion320Test.php | 1 + .../Replication/ReplicationStrategyTest.php | 3 + 13 files changed, 172 insertions(+) create mode 100644 src/Command/GeospatialGeoAdd.php create mode 100644 tests/Predis/Command/GeospatialGeoAddTest.php diff --git a/src/ClientContextInterface.php b/src/ClientContextInterface.php index e2625bcc..0095bcb9 100644 --- a/src/ClientContextInterface.php +++ b/src/ClientContextInterface.php @@ -156,6 +156,7 @@ use Predis\Command\CommandInterface; * @method $this slowlog($subcommand, $argument = null) * @method $this time() * @method $this command() + * @method $this geoadd($key, $longitude, $latitude, $member) * * @author Daniele Alessandri */ diff --git a/src/ClientInterface.php b/src/ClientInterface.php index 4c65df0e..8d76bc5c 100644 --- a/src/ClientInterface.php +++ b/src/ClientInterface.php @@ -164,6 +164,7 @@ use Predis\Profile\ProfileInterface; * @method mixed slowlog($subcommand, $argument = null) * @method array time() * @method array command() + * @method int geoadd($key, $longitude, $latitude, $member) * * @author Daniele Alessandri */ diff --git a/src/Cluster/ClusterStrategy.php b/src/Cluster/ClusterStrategy.php index b07eb333..b89b0a32 100644 --- a/src/Cluster/ClusterStrategy.php +++ b/src/Cluster/ClusterStrategy.php @@ -165,6 +165,9 @@ abstract class ClusterStrategy implements StrategyInterface /* scripting */ 'EVAL' => array($this, 'getKeyFromScriptingCommands'), 'EVALSHA' => array($this, 'getKeyFromScriptingCommands'), + + /* commands performing geospatial operations */ + 'GEOADD' => $getKeyFromFirstArgument, ); } diff --git a/src/Command/GeospatialGeoAdd.php b/src/Command/GeospatialGeoAdd.php new file mode 100644 index 00000000..adca2ca5 --- /dev/null +++ b/src/Command/GeospatialGeoAdd.php @@ -0,0 +1,42 @@ + + * + * 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/geoadd + * + * @author Daniele Alessandri + */ +class GeospatialGeoAdd extends Command +{ + /** + * {@inheritdoc} + */ + public function getId() + { + return 'GEOADD'; + } + + /** + * {@inheritdoc} + */ + protected function filterArguments(array $arguments) + { + if (count($arguments) === 2 && is_array($arguments[1])) { + foreach (array_pop($arguments) as $item) { + $arguments = array_merge($arguments, $item); + } + } + + return $arguments; + } +} diff --git a/src/Command/Processor/KeyPrefixProcessor.php b/src/Command/Processor/KeyPrefixProcessor.php index d20078df..4ac371d8 100644 --- a/src/Command/Processor/KeyPrefixProcessor.php +++ b/src/Command/Processor/KeyPrefixProcessor.php @@ -160,6 +160,7 @@ class KeyPrefixProcessor implements ProcessorInterface /* ---------------- Redis 3.2 ---------------- */ 'HSTRLEN' => 'static::first', 'BITFIELD' => 'static::first', + 'GEOADD' => 'static::first', ); } diff --git a/src/Profile/RedisVersion320.php b/src/Profile/RedisVersion320.php index 7c7a4342..e66ac1da 100644 --- a/src/Profile/RedisVersion320.php +++ b/src/Profile/RedisVersion320.php @@ -268,6 +268,9 @@ class RedisVersion320 extends RedisProfile /* commands operating on hashes */ 'HSTRLEN' => 'Predis\Command\HashStringLength', 'BITFIELD' => 'Predis\Command\StringBitField', + + /* commands performing geospatial operations */ + 'GEOADD' => 'Predis\Command\GeospatialGeoAdd', ); } } diff --git a/tests/Predis/Cluster/PredisStrategyTest.php b/tests/Predis/Cluster/PredisStrategyTest.php index 43d6b155..db8d49ce 100644 --- a/tests/Predis/Cluster/PredisStrategyTest.php +++ b/tests/Predis/Cluster/PredisStrategyTest.php @@ -377,6 +377,9 @@ class PredisStrategyTest extends PredisTestCase /* scripting */ 'EVAL' => 'keys-script', 'EVALSHA' => 'keys-script', + + /* commands performing geospatial operations */ + 'GEOADD' => 'keys-first', ); if (isset($type)) { diff --git a/tests/Predis/Cluster/RedisStrategyTest.php b/tests/Predis/Cluster/RedisStrategyTest.php index 3a03a4ab..649fc9e0 100644 --- a/tests/Predis/Cluster/RedisStrategyTest.php +++ b/tests/Predis/Cluster/RedisStrategyTest.php @@ -387,6 +387,9 @@ class RedisStrategyTest extends PredisTestCase /* scripting */ 'EVAL' => 'keys-script', 'EVALSHA' => 'keys-script', + + /* commands performing geospatial operations */ + 'GEOADD' => 'keys-first', ); if (isset($type)) { diff --git a/tests/Predis/Command/GeospatialGeoAddTest.php b/tests/Predis/Command/GeospatialGeoAddTest.php new file mode 100644 index 00000000..d2be244a --- /dev/null +++ b/tests/Predis/Command/GeospatialGeoAddTest.php @@ -0,0 +1,106 @@ + + * + * 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 GeospatialGeoAddTest extends PredisCommandTestCase +{ + /** + * {@inheritdoc} + */ + protected function getExpectedCommand() + { + return 'Predis\Command\GeospatialGeoAdd'; + } + + /** + * {@inheritdoc} + */ + protected function getExpectedId() + { + return 'GEOADD'; + } + + /** + * @group disconnected + */ + public function testFilterArguments() + { + $arguments = array('Sicily', '13.361389', '38.115556', 'Palermo', '15.087269', '37.502669', 'Catania'); + $expected = array('Sicily', '13.361389', '38.115556', 'Palermo', '15.087269', '37.502669', 'Catania'); + + $command = $this->getCommand(); + $command->setArguments($arguments); + + $this->assertSame($expected, $command->getArguments()); + } + + /** + * @group disconnected + */ + public function testFilterArgumentsWithMembersAsSingleArray() + { + $arguments = array('Sicily', array( + array('13.361389', '38.115556', 'Palermo'), + array('15.087269', '37.502669', 'Catania'), + )); + + $expected = array('Sicily', '13.361389', '38.115556', 'Palermo', '15.087269', '37.502669', 'Catania'); + + $command = $this->getCommand(); + $command->setArguments($arguments); + + $this->assertSame($expected, $command->getArguments()); + } + + /** + * @group disconnected + */ + public function testParseResponse() + { + $raw = 1; + $expected = 1; + + $command = $this->getCommand(); + + $this->assertSame($expected, $command->parseResponse($raw)); + } + + /** + * @group connected + * @requiresRedisVersion >= 3.2.0 + */ + public function testCommandFillsSortedSet() + { + $redis = $this->getClient(); + + $redis->geoadd('Sicily', '13.361389', '38.115556', 'Palermo'); + $this->assertSame(array('Palermo' => '3479099956230698'), $redis->zrange('Sicily', 0, -1, 'WITHSCORES')); + } + + /** + * @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->geoadd('Sicily', '13.361389', '38.115556', 'Palermo'); + } +} diff --git a/tests/Predis/Command/Processor/KeyPrefixProcessorTest.php b/tests/Predis/Command/Processor/KeyPrefixProcessorTest.php index 8a754659..5b883a4a 100644 --- a/tests/Predis/Command/Processor/KeyPrefixProcessorTest.php +++ b/tests/Predis/Command/Processor/KeyPrefixProcessorTest.php @@ -873,6 +873,10 @@ class KeyPrefixProcessorTest extends PredisTestCase array('key', 'GET', 'u8', '0', 'SET', 'u8', '0', '1'), array('prefix:key', 'GET', 'u8', '0', 'SET', 'u8', '0', '1'), ), + array('GEOADD', + 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'), + ), ); } } diff --git a/tests/Predis/Profile/RedisUnstableTest.php b/tests/Predis/Profile/RedisUnstableTest.php index 2bf6eadc..5966f5ec 100644 --- a/tests/Predis/Profile/RedisUnstableTest.php +++ b/tests/Predis/Profile/RedisUnstableTest.php @@ -191,6 +191,7 @@ class RedisUnstableTest extends PredisProfileTestCase 150 => 'COMMAND', 151 => 'HSTRLEN', 152 => 'BITFIELD', + 153 => 'GEOADD', ); } } diff --git a/tests/Predis/Profile/RedisVersion320Test.php b/tests/Predis/Profile/RedisVersion320Test.php index 31bee7b8..51b48b91 100644 --- a/tests/Predis/Profile/RedisVersion320Test.php +++ b/tests/Predis/Profile/RedisVersion320Test.php @@ -191,6 +191,7 @@ class RedisVersion320Test extends PredisProfileTestCase 150 => 'COMMAND', 151 => 'HSTRLEN', 152 => 'BITFIELD', + 153 => 'GEOADD', ); } } diff --git a/tests/Predis/Replication/ReplicationStrategyTest.php b/tests/Predis/Replication/ReplicationStrategyTest.php index d07b3e53..1ad30755 100644 --- a/tests/Predis/Replication/ReplicationStrategyTest.php +++ b/tests/Predis/Replication/ReplicationStrategyTest.php @@ -438,6 +438,9 @@ class ReplicationStrategyTest extends PredisTestCase /* scripting */ 'EVAL' => 'write', 'EVALSHA' => 'write', + + /* commands performing geospatial operations */ + 'GEOADD' => 'write', ); if (isset($type)) {