Skip to content

Commit

Permalink
[6.x] Fix *scan methods for phpredis (laravel#24222)
Browse files Browse the repository at this point in the history
  • Loading branch information
shufo committed Apr 11, 2020
1 parent 0fd4c5c commit 8309969
Show file tree
Hide file tree
Showing 2 changed files with 170 additions and 0 deletions.
54 changes: 54 additions & 0 deletions src/Illuminate/Redis/Connections/PhpRedisConnection.php
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,60 @@ public function zunionstore($output, $keys, $options = [])
]);
}

/**
* Scans the given set for all values based on options.
*
* @param string $key
* @param mixed $cursor
* @param array $options
* @return mixed
*/
public function zscan($key, $cursor, $options = [])
{
$result = $this->client->zscan($key, $cursor,
$options['match'] ?? '*',
$options['count'] ?? 10
);

return $result === false ? [0, []] : [$cursor, $result];
}

/**
* Scans the given set for all values based on options.
*
* @param string $key
* @param mixed $cursor
* @param array $options
* @return mixed
*/
public function hscan($key, $cursor, $options = [])
{
$result = $this->client->hscan($key, $cursor,
$options['match'] ?? '*',
$options['count'] ?? 10
);

return $result === false ? [0, []] : [$cursor, $result];
}

/**
* Scans the given set for all values based on options.
*
* @param string $key
* @param mixed $cursor
* @param array $options
* @return mixed
*/
public function sscan($key, $cursor, $options = [])
{
$result = $this->client->sscan($key, $cursor,
$options['match'] ?? '*',
$options['count'] ?? 10
);

return $result === false ? [0, []] : [$cursor, $result];
}

/**
* Execute commands in a pipeline.
*
Expand Down
116 changes: 116 additions & 0 deletions tests/Redis/RedisConnectionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -577,6 +577,122 @@ public function testItScansForKeys()
}
}

public function testItZscansForKeys()
{
foreach ($this->connections() as $redis) {
$members = range(1, 200);

foreach ($members as $score => $member) {
$redis->zadd('set', $score, $member);
}

$iterator = null;
$result = [];

do {
[$iterator, $returnedMembers] = $redis->zscan('set', $iterator);

if (!is_array($returnedMembers)) {
$returnedMembers = [$returnedMembers];
}

foreach ($returnedMembers as $member => $score) {
$this->assertArrayHasKey((int) $score, $members);
$this->assertContains($member, $members);
}

$result += $returnedMembers;
} while ($iterator > 0);

$this->assertCount(200, $result);

$iterator = null;
[$iterator, $unmatched] = $redis->zscan('set', $iterator, ['match' => 'test:unmatch']);
$this->assertEmpty($unmatched);

$iterator = null;
[$iterator, $returned] = $redis->zscan('set', $iterator, ['count' => 50]);
$this->assertGreaterThan(10, count($returned));
$this->assertLessThan(200, count($returned));

$redis->flushAll();
}
}

public function testItHscansForKeys()
{
foreach ($this->connections() as $redis) {
$fields = array_combine(range(1, 1000), range(1, 1000));

foreach ($fields as $field => $value) {
$redis->hset('hash', $field, $value);
}

$iterator = null;
$result = [];

do {
[$iterator, $returnedFields] = $redis->hscan('hash', $iterator);

foreach ($returnedFields as $field => $value) {
$this->assertArrayHasKey($field, $fields);
$this->assertContains((int) $value, $fields);
}

$result += $returnedFields;
} while ($iterator > 0);

$this->assertCount(1000, $result);

$iterator = null;
[$iterator, $unmatched] = $redis->hscan('hash', $iterator, ['match' => 'test:unmatch']);
$this->assertEmpty($unmatched);

$iterator = null;
[$iterator, $returned] = $redis->hscan('hash', $iterator, ['count' => 100]);
$this->assertGreaterThan(50, count($returned));
$this->assertLessThan(1000, count($returned));

$redis->flushAll();
}
}

public function testItSscansForKeys()
{
foreach ($this->connections() as $redis) {
$members = range(1, 1000);

foreach ($members as $member) {
$redis->sadd('set', $member);
}

$iterator = null;
$result = [];

do {
[$iterator, $returnedMembers] = $redis->sscan('set', $iterator);

foreach ($returnedMembers as $member) {
$this->assertContains((int) $member, $members);
array_push($result, $member);
}
} while ($iterator > 0);

$this->assertCount(1000, $result);

$iterator = null;
[$iterator, $unmatched] = $redis->sscan('set', $iterator, ['match' => 'test:unmatch']);
$this->assertEmpty($unmatched);

$iterator = null;
[$iterator, $returned] = $redis->sscan('set', $iterator, ['count' => 100]);
$this->assertGreaterThan(50, count($returned));
$this->assertLessThan(1000, count($returned));

$redis->flushAll();
}
}

public function testPhpRedisScanOption()
{
foreach ($this->connections() as $redis) {
Expand Down

0 comments on commit 8309969

Please sign in to comment.