Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Scripting abstraction can use negatives to calculate number of keys.

With a negative number Predis will count from the end of the arguments list
to calculate the actual number of keys that will be interpreted as elements
for `KEYS` by the underlying `EVAL` command.
  • Loading branch information...
commit 5af2b628f10b8be9eaa24d5bf64b83930c68e528 1 parent f4c58b9
@nrk authored
View
5 CHANGELOG.md
@@ -1,6 +1,11 @@
v0.7.3 (2012-xx-xx)
===============================================================================
+- When the number of keys `Predis\Commands\ScriptedCommand` is negative, Predis
+ will count from the end of the arguments list to calculate the actual number
+ of keys that will be interpreted as elements for `KEYS` by the underlying
+ `EVAL` command.
+
- __FIX__: `examples\CustomDistributionStrategy.php` had a mistyped constructor
call and produced a bad distribution due to an error as pointed in ISSUE #63.
This bug is limited to the above mentioned example and does not affect the
View
37 examples/ServerSideScripting.php
@@ -20,30 +20,47 @@
use Predis\Commands\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
<<<LUA
- local cmd = redis.call
- if cmd('exists', KEYS[1]) == 1 then
- return cmd('incr', KEYS[1])
- end
+local cmd, insert = redis.call, table.insert
+local increment, results = ARGV[1], { }
+
+for idx, key in ipairs(KEYS) do
+ if cmd('exists', key) == 1 then
+ insert(results, idx, cmd('incrby', key, increment))
+ else
+ insert(results, idx, false)
+ end
+end
+
+return results
LUA;
}
}
$client = new Predis\Client($single_server, '2.6');
-$client->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,
+)
+*/
View
9 lib/Predis/Commands/ScriptedCommand.php
@@ -60,8 +60,13 @@ public function getKeys()
*/
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);
}
}
View
60 tests/Predis/Commands/ScriptedCommandTest.php
@@ -42,6 +42,25 @@ public function testGetArguments()
/**
* @group disconnected
*/
+ public function testGetArgumentsWithNegativeKeysCount()
+ {
+ $arguments = array('key1', 'key2', 'value1', 'value2');
+
+ $command = $this->getMock('Predis\Commands\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
+ */
public function testGetKeys()
{
$arguments = array('key1', 'key2', 'value1', 'value2');
@@ -61,6 +80,25 @@ public function testGetKeys()
/**
* @group disconnected
*/
+ public function testGetKeysWithNegativeKeysCount()
+ {
+ $arguments = array('key1', 'key2', 'value1', 'value2');
+
+ $command = $this->getMock('Predis\Commands\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
+ */
public function testPrefixKeys()
{
$arguments = array('foo', 'hoge', 'bar', 'piyo');
@@ -83,6 +121,28 @@ public function testPrefixKeys()
/**
* @group disconnected
*/
+ public function testPrefixKeysWithNegativeKeysCount()
+ {
+ $arguments = array('foo', 'hoge', 'bar', 'piyo');
+ $expected = array('prefix:foo', 'prefix:hoge');
+
+ $command = $this->getMock('Predis\Commands\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
+ */
public function testGetScriptHash()
{
$arguments = array('key1', 'key2', 'value1', 'value2');
Please sign in to comment.
Something went wrong with that request. Please try again.