diff --git a/examples/ServerSideScripting.php b/examples/ServerSideScripting.php index e863cbec..ac236e60 100644 --- a/examples/ServerSideScripting.php +++ b/examples/ServerSideScripting.php @@ -20,30 +20,47 @@ require 'SharedConfigurations.php'; use Predis\Command\ScriptedCommand; -class IncrementExistingKey extends ScriptedCommand +class IncrementExistingKeysBy extends ScriptedCommand { public function getKeysCount() { - return 1; + // Tell Predis to use all the arguments but the last one as arguments + // for KEYS. The last one will be used to populate ARGV. + return -1; } public function getScript() { return <<getProfile()->defineCommand('increx', 'IncrementExistingKey'); +$client->getProfile()->defineCommand('increxby', 'IncrementExistingKeysBy'); -$client->set('foo', 10); +$client->mset('foo', 10, 'foobar', 100); -var_dump($client->increx('foo')); // int(11) -var_dump($client->increx('bar')); // NULL +var_export($client->increxby('foo', 'foofoo', 'foobar', 50)); + +/* +array ( + 0 => 60, + 1 => NULL, + 2 => 150, +) +*/ diff --git a/lib/Predis/Command/ScriptedCommand.php b/lib/Predis/Command/ScriptedCommand.php index d98b2d6d..bd5500a1 100644 --- a/lib/Predis/Command/ScriptedCommand.php +++ b/lib/Predis/Command/ScriptedCommand.php @@ -60,8 +60,13 @@ abstract class ScriptedCommand extends ServerEval */ protected function filterArguments(Array $arguments) { - $header = array($this->getScript(), ($keys = $this->getKeysCount()) !== false ? $keys : count($arguments)); + if (false !== $numkeys = $this->getKeysCount()) { + $numkeys = $numkeys >= 0 ? $numkeys : count($arguments) + $numkeys; + } + else { + $numkeys = count($arguments); + } - return array_merge($header, $arguments); + return array_merge(array($this->getScript(), $numkeys), $arguments); } } diff --git a/tests/Predis/Command/ScriptedCommandTest.php b/tests/Predis/Command/ScriptedCommandTest.php index f941b2fe..ecd32c30 100644 --- a/tests/Predis/Command/ScriptedCommandTest.php +++ b/tests/Predis/Command/ScriptedCommandTest.php @@ -39,6 +39,25 @@ class ScriptedCommandTest extends StandardTestCase $this->assertSame(array_merge(array(self::LUA_SCRIPT, 2), $arguments), $command->getArguments()); } + /** + * @group disconnected + */ + public function testGetArgumentsWithNegativeKeysCount() + { + $arguments = array('key1', 'key2', 'value1', 'value2'); + + $command = $this->getMock('Predis\Command\ScriptedCommand', array('getScript', 'getKeysCount')); + $command->expects($this->once()) + ->method('getScript') + ->will($this->returnValue(self::LUA_SCRIPT)); + $command->expects($this->once()) + ->method('getKeysCount') + ->will($this->returnValue(-2)); + $command->setArguments($arguments); + + $this->assertSame(array_merge(array(self::LUA_SCRIPT, 2), $arguments), $command->getArguments()); + } + /** * @group disconnected */ @@ -58,6 +77,25 @@ class ScriptedCommandTest extends StandardTestCase $this->assertSame(array('key1', 'key2'), $command->getKeys()); } + /** + * @group disconnected + */ + public function testGetKeysWithNegativeKeysCount() + { + $arguments = array('key1', 'key2', 'value1', 'value2'); + + $command = $this->getMock('Predis\Command\ScriptedCommand', array('getScript', 'getKeysCount')); + $command->expects($this->once()) + ->method('getScript') + ->will($this->returnValue(self::LUA_SCRIPT)); + $command->expects($this->exactly(2)) + ->method('getKeysCount') + ->will($this->returnValue(-2)); + $command->setArguments($arguments); + + $this->assertSame(array('key1', 'key2'), $command->getKeys()); + } + /** * @group disconnected */ @@ -80,6 +118,28 @@ class ScriptedCommandTest extends StandardTestCase $this->assertSame($expected, $command->getKeys()); } + /** + * @group disconnected + */ + public function testPrefixKeysWithNegativeKeysCount() + { + $arguments = array('foo', 'hoge', 'bar', 'piyo'); + $expected = array('prefix:foo', 'prefix:hoge'); + + $command = $this->getMock('Predis\Command\ScriptedCommand', array('getScript', 'getKeysCount')); + $command->expects($this->once()) + ->method('getScript') + ->will($this->returnValue(self::LUA_SCRIPT)); + $command->expects($this->exactly(2)) + ->method('getKeysCount') + ->will($this->returnValue(-2)); + $command->setArguments($arguments); + + $command->prefixKeys('prefix:'); + + $this->assertSame($expected, $command->getKeys()); + } + /** * @group disconnected */