Compare commits

...

30 Commits

Author SHA1 Message Date
Till Krüss 4cc119a03c tag 2.0.0-beta.1 2022-05-26 11:48:12 -07:00
Till Krüss 619890f715 fix test 2022-05-26 11:45:35 -07:00
Till Krüss b060d43157 port changes from v1.1 branch 2022-05-26 11:29:45 -07:00
Till Krüss a5ab2bce6b truncate changelog 2022-05-26 11:12:41 -07:00
Hubert Lenoir 89f20dc968 add TOUCH command (#767) 2022-05-23 08:46:48 -07:00
Michal Lulco 6af5394a89 Added ZPOPMIN and ZPOPMAX (#758)
* Added ZPOPMIN and ZPOPMAX

* Added ZPOPMIN and ZPOPMAX

* Applied patch
2022-05-16 08:00:06 -07:00
Zaher Ghaibeh c508086b0e remove redundant variables (#765) 2022-05-15 09:51:28 -07:00
Zaher Ghaibeh 3c01ccc94c Testing code against Redis 7 (#764)
* redis 7 init

fix typo

add the new returns

* having a full sentence for the exception message
2022-05-12 12:23:51 -07:00
Jordi Boggiano e382bedb27 Update method tags (#762) 2022-05-12 09:13:06 -07:00
Zaher Ghaibeh a2449da7c8 PHP 8.1 tests (#760)
* - init 8.1 tests
- adding `#[\ReturnTypeWillChange]`
- Fix deprecation message: strlen(): Passing null to parameter #1 ($string) of type string is deprecated
- null is not allowed
- cleanup
- default values should be same type

* Mirror `v1.1` fixes for these files

* add null as type too since we also accept null as default value

Signed-off-by: Zaher Ghaibeh <zaher@zaher.dev>

* revert back to assertNull

* Update CHANGELOG

* Update CHANGELOG.md

Co-authored-by: Till Krüss <tillkruss@users.noreply.github.com>
2022-05-07 08:03:53 -07:00
♚ PH⑦ de Soria™♛ b3a5bdf940 Remove invalid input for actions/cache (#737)
https://github.com/actions/cache/blob/main/examples.md#php---composer
2022-01-14 08:22:59 -08:00
Georges.L 4c1aada5ae Updated set, setex, setexp type hint (#710) 2021-09-08 09:05:55 -07:00
Mehdi Baaboura 54775a0295 Update LICENSE (#704) 2021-07-19 09:27:37 -07:00
Ruslan Bekenev 367bd72a0b Test optional count argument for LPOP (#700)
First added in Redis 6.2
2021-06-09 09:46:24 -07:00
Till Krüss 1d7ccb64ab Merge pull request #670 from charescape/patch-1
Update README.md
2021-04-04 10:33:08 -07:00
Till Krüss e29ae9065f some spacing 2021-04-04 10:31:53 -07:00
Till Krüss 64fc7774c6 stick to PHPUnit 9.4.* for now
`getAnnotations()` was removed in 9.5:

https://github.com/sebastianbergmann/phpunit/commit/68582043e149039cfa3596b42ed35753dcf54fb2
2021-04-04 10:31:45 -07:00
Till Krüss 554c36b329 Merge pull request #688 from open-source-contributions/improve_assertions
Improve PHPUnit assertions
2021-04-04 10:20:39 -07:00
Till Krüss be9d477564 fix for Redis 6 error message 2021-04-04 10:16:44 -07:00
Till Krüss 0e4e8f41cc fix 2021-04-04 10:14:13 -07:00
Till Krüss aa0c30809b fix test when using Redis 6 2021-04-04 10:11:29 -07:00
Peter 20f8faee6f Improve PHPUnit assertions 2021-04-04 23:30:14 +08:00
Till Krüss aa436263f8 Merge pull request #684 from andrew-demb/patch-2
CommandInterface::parseResponse() can accept array and null argument
2021-03-09 08:43:59 -08:00
Till Krüss 3c8856b05a Merge pull request #683 from andrew-demb/patch-1
Status::get() always return self
2021-03-09 08:43:39 -08:00
Andrii Dembitskyi d935f6e5c2 CommandInterface::parseResponse() can accept array and null argument 2021-03-09 07:15:08 -05:00
Andrii Dembitskyi 87fcc69e7a Status::get() always return self 2021-03-09 07:09:15 -05:00
charescape 407ddeca92 Update README.md 2020-11-12 11:39:48 +08:00
Till Krüss 338ba6d73d Merge pull request #665 from danwall/patch-1
Fix typo
2020-09-26 19:08:13 -07:00
Dan Wall 25db9bfec5 Fix typo 2020-09-26 11:52:44 +10:00
Daniele Alessandri 0e9aeee90f Fix PhpiredisSocketConnection for PHP 8.
Removed is_resource() check as socket_create() now returns an object.
2020-09-20 15:29:16 +02:00
55 changed files with 785 additions and 1293 deletions
+16 -4
View File
@@ -1,40 +1,52 @@
name: Tests
on: [push, pull_request]
on:
- push
- pull_request
jobs:
predis:
name: PHP ${{ matrix.php-versions }} (Redis ${{ matrix.redis-versions }})
runs-on: ubuntu-latest
services:
redis:
image: redis:${{ matrix.redis-versions }}
ports:
- 6379:6379
options: --health-cmd="redis-cli ping" --health-interval=10s --health-timeout=5s --health-retries=3
strategy:
fail-fast: false
matrix:
php-versions: ['7.2', '7.3', '7.4', '8.0']
redis-versions: ['3', '4', '5', '6']
php-versions: ['7.2', '7.3', '7.4', '8.0', '8.1']
redis-versions: ['3', '4', '5', '6', '7']
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Setup PHP with Composer and extensions
with:
php-version: ${{ matrix.php-versions }}
uses: shivammathur/setup-php@v2
- name: Get Composer cache directory
id: composercache
run: echo "::set-output name=dir::$(composer config cache-files-dir)"
- name: Cache Composer dependencies
uses: actions/cache@v2
with:
php-version: ${{ matrix.php-versions }}
path: ${{ steps.composercache.outputs.dir }}
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
restore-keys: ${{ runner.os }}-composer-
- name: Install Composer dependencies
env:
PHP_VERSION: ${{ matrix.php-versions }}
run: composer install --no-progress --prefer-dist --optimize-autoloader $(if [ "$PHP_VERSION" == "8.0" ]; then echo "--ignore-platform-reqs"; fi;)
- name: Test with PHPUnit
run: vendor/bin/phpunit
+19 -1066
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -1,4 +1,4 @@
Copyright (c) 2009-2020 Daniele Alessandri
Copyright (c) 2009-2021 Daniele Alessandri
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
+1 -1
View File
@@ -22,7 +22,7 @@ More details about this project can be found on the [frequently asked questions]
## Main features ##
- Support for Redis from __2.0__ to __3.2__.
- Support for Redis from __2.0__ to __6.0__.
- Support for clustering using client-side sharding and pluggable keyspace distributors.
- Support for [redis-cluster](http://redis.io/topics/cluster-tutorial) (Redis >= 3.0).
- Support for master-slave replication setups and [redis-sentinel](http://redis.io/topics/sentinel).
+1 -1
View File
@@ -1 +1 @@
2.0.0-dev
2.0.0-beta.1
+1 -1
View File
@@ -31,7 +31,7 @@
"php": "^7.2 || ^8.0"
},
"require-dev": {
"phpunit/phpunit": "^8.0 || ^9.0"
"phpunit/phpunit": "^8.0 || ~9.4.4"
},
"suggest": {
"ext-phpiredis": "Allows faster serialization and deserialization of the Redis protocol",
+3 -4
View File
@@ -40,7 +40,7 @@ use Predis\Transaction\MultiExec as MultiExecTransaction;
*/
class Client implements ClientInterface, \IteratorAggregate
{
const VERSION = '2.0.0-dev';
const VERSION = '2.0.0-beta.1';
/** @var OptionsInterface */
private $options;
@@ -209,9 +209,7 @@ class Client implements ClientInterface, \IteratorAggregate
throw new \InvalidArgumentException("Cannot find a connection by $selector matching `$value`");
}
$client = new static($connection, $this->getOptions());
return $client;
return new static($connection, $this->getOptions());
}
/**
@@ -515,6 +513,7 @@ class Client implements ClientInterface, \IteratorAggregate
/**
* {@inheritdoc}
*/
#[\ReturnTypeWillChange]
public function getIterator()
{
$clients = array();
+127 -123
View File
@@ -15,6 +15,7 @@ use Predis\Command\CommandInterface;
use Predis\Command\FactoryInterface;
use Predis\Configuration\OptionsInterface;
use Predis\Connection\ConnectionInterface;
use Predis\Response\Status;
/**
* Interface defining a client able to execute commands against Redis.
@@ -24,134 +25,137 @@ use Predis\Connection\ConnectionInterface;
* and more friendly interface to ease programming which is described in the
* following list of methods:
*
* @method int del(array|string $keys)
* @method string|null dump($key)
* @method int exists($key)
* @method int expire($key, $seconds)
* @method int expireat($key, $timestamp)
* @method array keys($pattern)
* @method int move($key, $db)
* @method mixed object($subcommand, $key)
* @method int persist($key)
* @method int pexpire($key, $milliseconds)
* @method int pexpireat($key, $timestamp)
* @method int pttl($key)
* @method int del(string[]|string $keyOrKeys, string ...$keys = null)
* @method string|null dump(string $key)
* @method int exists(string $key)
* @method int expire(string $key, int $seconds)
* @method int expireat(string $key, int $timestamp)
* @method array keys(string $pattern)
* @method int move(string $key, int $db)
* @method mixed object($subcommand, string $key)
* @method int persist(string $key)
* @method int pexpire(string $key, int $milliseconds)
* @method int pexpireat(string $key, int $timestamp)
* @method int pttl(string $key)
* @method string|null randomkey()
* @method mixed rename($key, $target)
* @method int renamenx($key, $target)
* @method mixed rename(string $key, string $target)
* @method int renamenx(string $key, string $target)
* @method array scan($cursor, array $options = null)
* @method array sort($key, array $options = null)
* @method int ttl($key)
* @method mixed type($key)
* @method int append($key, $value)
* @method int bitcount($key, $start = null, $end = null)
* @method array sort(string $key, array $options = null)
* @method int ttl(string $key)
* @method mixed type(string $key)
* @method int append(string $key, $value)
* @method int bitcount(string $key, $start = null, $end = null)
* @method int bitop($operation, $destkey, $key)
* @method array|null bitfield($key, $subcommand, ...$subcommandArg)
* @method int bitpos($key, $bit, $start = null, $end = null)
* @method int decr($key)
* @method int decrby($key, $decrement)
* @method string|null get($key)
* @method int getbit($key, $offset)
* @method string getrange($key, $start, $end)
* @method string|null getset($key, $value)
* @method int incr($key)
* @method int incrby($key, $increment)
* @method string incrbyfloat($key, $increment)
* @method array mget(array $keys)
* @method array|null bitfield(string $key, $subcommand, ...$subcommandArg)
* @method int bitpos(string $key, $bit, $start = null, $end = null)
* @method int decr(string $key)
* @method int decrby(string $key, int $decrement)
* @method string|null get(string $key)
* @method int getbit(string $key, $offset)
* @method string getrange(string $key, $start, $end)
* @method string|null getset(string $key, $value)
* @method int incr(string $key)
* @method int incrby(string $key, int $increment)
* @method string incrbyfloat(string $key, int|float $increment)
* @method array mget(string[]|string $keyOrKeys, string ...$keys = null)
* @method mixed mset(array $dictionary)
* @method int msetnx(array $dictionary)
* @method mixed psetex($key, $milliseconds, $value)
* @method mixed set($key, $value, $expireResolution = null, $expireTTL = null, $flag = null)
* @method int setbit($key, $offset, $value)
* @method int setex($key, $seconds, $value)
* @method int setnx($key, $value)
* @method int setrange($key, $offset, $value)
* @method int strlen($key)
* @method int hdel($key, array $fields)
* @method int hexists($key, $field)
* @method string|null hget($key, $field)
* @method array hgetall($key)
* @method int hincrby($key, $field, $increment)
* @method string hincrbyfloat($key, $field, $increment)
* @method array hkeys($key)
* @method int hlen($key)
* @method array hmget($key, array $fields)
* @method mixed hmset($key, array $dictionary)
* @method array hscan($key, $cursor, array $options = null)
* @method int hset($key, $field, $value)
* @method int hsetnx($key, $field, $value)
* @method array hvals($key)
* @method int hstrlen($key, $field)
* @method array|null blpop(array|string $keys, $timeout)
* @method array|null brpop(array|string $keys, $timeout)
* @method string|null brpoplpush($source, $destination, $timeout)
* @method string|null lindex($key, $index)
* @method int linsert($key, $whence, $pivot, $value)
* @method int llen($key)
* @method string|null lpop($key)
* @method int lpush($key, array $values)
* @method int lpushx($key, array $values)
* @method array lrange($key, $start, $stop)
* @method int lrem($key, $count, $value)
* @method mixed lset($key, $index, $value)
* @method mixed ltrim($key, $start, $stop)
* @method string|null rpop($key)
* @method string|null rpoplpush($source, $destination)
* @method int rpush($key, array $values)
* @method int rpushx($key, array $values)
* @method int sadd($key, array $members)
* @method int scard($key)
* @method array sdiff(array|string $keys)
* @method int sdiffstore($destination, array|string $keys)
* @method array sinter(array|string $keys)
* @method int sinterstore($destination, array|string $keys)
* @method int sismember($key, $member)
* @method array smembers($key)
* @method int smove($source, $destination, $member)
* @method string|null spop($key, $count = null)
* @method string|null srandmember($key, $count = null)
* @method int srem($key, $member)
* @method array sscan($key, $cursor, array $options = null)
* @method array sunion(array|string $keys)
* @method int sunionstore($destination, array|string $keys)
* @method int zadd($key, array $membersAndScoresDictionary)
* @method int zcard($key)
* @method string zcount($key, $min, $max)
* @method string zincrby($key, $increment, $member)
* @method int zinterstore($destination, array|string $keys, array $options = null)
* @method array zrange($key, $start, $stop, array $options = null)
* @method array zrangebyscore($key, $min, $max, array $options = null)
* @method int|null zrank($key, $member)
* @method int zrem($key, $member)
* @method int zremrangebyrank($key, $start, $stop)
* @method int zremrangebyscore($key, $min, $max)
* @method array zrevrange($key, $start, $stop, array $options = null)
* @method array zrevrangebyscore($key, $max, $min, array $options = null)
* @method int|null zrevrank($key, $member)
* @method int zunionstore($destination, array|string $keys, array $options = null)
* @method string|null zscore($key, $member)
* @method array zscan($key, $cursor, array $options = null)
* @method array zrangebylex($key, $start, $stop, array $options = null)
* @method array zrevrangebylex($key, $start, $stop, array $options = null)
* @method int zremrangebylex($key, $min, $max)
* @method int zlexcount($key, $min, $max)
* @method int pfadd($key, array $elements)
* @method mixed pfmerge($destinationKey, array|string $sourceKeys)
* @method int pfcount(array|string $keys)
* @method Status psetex(string $key, $milliseconds, $value)
* @method Status set(string $key, $value, $expireResolution = null, $expireTTL = null, $flag = null)
* @method int setbit(string $key, $offset, $value)
* @method Status setex(string $key, $seconds, $value)
* @method int setnx(string $key, $value)
* @method int setrange(string $key, $offset, $value)
* @method int strlen(string $key)
* @method int hdel(string $key, array $fields)
* @method int hexists(string $key, string $field)
* @method string|null hget(string $key, string $field)
* @method array hgetall(string $key)
* @method int hincrby(string $key, string $field, int $increment)
* @method string hincrbyfloat(string $key, string $field, int|float $increment)
* @method array hkeys(string $key)
* @method int hlen(string $key)
* @method array hmget(string $key, array $fields)
* @method mixed hmset(string $key, array $dictionary)
* @method array hscan(string $key, $cursor, array $options = null)
* @method int hset(string $key, string $field, string $value)
* @method int hsetnx(string $key, string $field, string $value)
* @method array hvals(string $key)
* @method int hstrlen(string $key, string $field)
* @method array|null blpop(array|string $keys, int|float $timeout)
* @method array|null brpop(array|string $keys, int|float $timeout)
* @method string|null brpoplpush(string $source, string $destination, int|float $timeout)
* @method string|null lindex(string $key, int $index)
* @method int linsert(string $key, $whence, $pivot, $value)
* @method int llen(string $key)
* @method string|null lpop(string $key)
* @method int lpush(string $key, array $values)
* @method int lpushx(string $key, array $values)
* @method string[] lrange(string $key, int $start, int $stop)
* @method int lrem(string $key, int $count, string $value)
* @method mixed lset(string $key, int $index, string $value)
* @method mixed ltrim(string $key, int $start, int $stop)
* @method string|null rpop(string $key)
* @method string|null rpoplpush(string $source, string $destination)
* @method int rpush(string $key, array $values)
* @method int rpushx(string $key, array $values)
* @method int sadd(string $key, array $members)
* @method int scard(string $key)
* @method string[] sdiff(array|string $keys)
* @method int sdiffstore(string $destination, array|string $keys)
* @method string[] sinter(array|string $keys)
* @method int sinterstore(string $destination, array|string $keys)
* @method int sismember(string $key, string $member)
* @method string[] smembers(string $key)
* @method int smove(string $source, string $destination, string $member)
* @method string|null spop(string $key, int $count = null)
* @method string|null srandmember(string $key, int $count = null)
* @method int srem(string $key, string $member)
* @method array sscan(string $key, int $cursor, array $options = null)
* @method string[] sunion(array|string $keys)
* @method int sunionstore(string $destination, array|string $keys)
* @method int touch(string[]|string $keyOrKeys, string ...$keys = null)
* @method int zadd(string $key, array $membersAndScoresDictionary)
* @method int zcard(string $key)
* @method string zcount(string $key, int|string $min, int|string $max)
* @method string zincrby(string $key, int $increment, string $member)
* @method int zinterstore(string $destination, array|string $keys, array $options = null)
* @method array zpopmin(string $key, int $count = 1)
* @method array zpopmax(string $key, int $count = 1)
* @method array zrange(string $key, int|string $start, int|string $stop, array $options = null)
* @method array zrangebyscore(string $key, int|string $min, int|string $max, array $options = null)
* @method int|null zrank(string $key, string $member)
* @method int zrem(string $key, string ...$member)
* @method int zremrangebyrank(string $key, int|string $start, int|string $stop)
* @method int zremrangebyscore(string $key, int|string $min, int|string $max)
* @method array zrevrange(string $key, int|string $start, int|string $stop, array $options = null)
* @method array zrevrangebyscore(string $key, int|string $max, int|string $min, array $options = null)
* @method int|null zrevrank(string $key, string $member)
* @method int zunionstore(string $destination, array|string $keys, array $options = null)
* @method string|null zscore(string $key, string $member)
* @method array zscan(string $key, int $cursor, array $options = null)
* @method array zrangebylex(string $key, string $start, string $stop, array $options = null)
* @method array zrevrangebylex(string $key, string $start, string $stop, array $options = null)
* @method int zremrangebylex(string $key, string $min, string $max)
* @method int zlexcount(string $key, string $min, string $max)
* @method int pfadd(string $key, array $elements)
* @method mixed pfmerge(string $destinationKey, array|string $sourceKeys)
* @method int pfcount(string[]|string $keyOrKeys, string ...$keys = null)
* @method mixed pubsub($subcommand, $argument)
* @method int publish($channel, $message)
* @method mixed discard()
* @method array|null exec()
* @method mixed multi()
* @method mixed unwatch()
* @method mixed watch($key)
* @method mixed eval($script, $numkeys, $keyOrArg1 = null, $keyOrArgN = null)
* @method mixed evalsha($script, $numkeys, $keyOrArg1 = null, $keyOrArgN = null)
* @method mixed watch(string $key)
* @method mixed eval(string $script, int $numkeys, string ...$keyOrArg = null)
* @method mixed evalsha(string $script, int $numkeys, string ...$keyOrArg = null)
* @method mixed script($subcommand, $argument = null)
* @method mixed auth($password)
* @method string echo($message)
* @method mixed ping($message = null)
* @method mixed select($database)
* @method mixed auth(string $password)
* @method string echo(string $message)
* @method mixed ping(string $message = null)
* @method mixed select(int $database)
* @method mixed bgrewriteaof()
* @method mixed bgsave()
* @method mixed client($subcommand, $argument = null)
@@ -162,16 +166,16 @@ use Predis\Connection\ConnectionInterface;
* @method array info($section = null)
* @method int lastsave()
* @method mixed save()
* @method mixed slaveof($host, $port)
* @method mixed slaveof(string $host, int $port)
* @method mixed slowlog($subcommand, $argument = null)
* @method array time()
* @method array command()
* @method int geoadd($key, $longitude, $latitude, $member)
* @method array geohash($key, array $members)
* @method array geopos($key, array $members)
* @method string|null geodist($key, $member1, $member2, $unit = null)
* @method array georadius($key, $longitude, $latitude, $radius, $unit, array $options = null)
* @method array georadiusbymember($key, $member, $radius, $unit, array $options = null)
* @method int geoadd(string $key, $longitude, $latitude, $member)
* @method array geohash(string $key, array $members)
* @method array geopos(string $key, array $members)
* @method string|null geodist(string $key, $member1, $member2, $unit = null)
* @method array georadius(string $key, $longitude, $latitude, $radius, $unit, array $options = null)
* @method array georadiusbymember(string $key, $member, $radius, $unit, array $options = null)
*
* @author Daniele Alessandri <suppakilla@gmail.com>
*/
+1 -2
View File
@@ -239,9 +239,8 @@ class HashRing implements DistributorInterface, HashGeneratorInterface
public function get($value)
{
$hash = $this->hash($value);
$node = $this->getByHash($hash);
return $node;
return $this->getByHash($hash);
}
/**
+1 -2
View File
@@ -40,9 +40,8 @@ class PredisStrategy extends ClusterStrategy
{
$key = $this->extractKeyTag($key);
$hash = $this->distributor->hash($key);
$slot = $this->distributor->getSlot($hash);
return $slot;
return $this->distributor->getSlot($hash);
}
/**
+1 -2
View File
@@ -41,9 +41,8 @@ class RedisStrategy extends ClusterStrategy
public function getSlotByKey($key)
{
$key = $this->extractKeyTag($key);
$slot = $this->hashGenerator->hash($key) & 0x3FFF;
return $slot;
return $this->hashGenerator->hash($key) & 0x3FFF;
}
/**
+6
View File
@@ -125,6 +125,7 @@ class SlotMap implements \ArrayAccess, \IteratorAggregate, \Countable
*
* @return bool
*/
#[\ReturnTypeWillChange]
public function offsetExists($slot)
{
return isset($this->slots[$slot]);
@@ -137,6 +138,7 @@ class SlotMap implements \ArrayAccess, \IteratorAggregate, \Countable
*
* @return string
*/
#[\ReturnTypeWillChange]
public function offsetGet($slot)
{
if (isset($this->slots[$slot])) {
@@ -152,6 +154,7 @@ class SlotMap implements \ArrayAccess, \IteratorAggregate, \Countable
*
* @return string
*/
#[\ReturnTypeWillChange]
public function offsetSet($slot, $connection)
{
if (!static::isValid($slot)) {
@@ -168,6 +171,7 @@ class SlotMap implements \ArrayAccess, \IteratorAggregate, \Countable
*
* @return string
*/
#[\ReturnTypeWillChange]
public function offsetUnset($slot)
{
unset($this->slots[$slot]);
@@ -178,6 +182,7 @@ class SlotMap implements \ArrayAccess, \IteratorAggregate, \Countable
*
* @return int
*/
#[\ReturnTypeWillChange]
public function count()
{
return count($this->slots);
@@ -188,6 +193,7 @@ class SlotMap implements \ArrayAccess, \IteratorAggregate, \Countable
*
* @return \ArrayIterator
*/
#[\ReturnTypeWillChange]
public function getIterator()
{
return new \ArrayIterator($this->slots);
@@ -92,7 +92,7 @@ abstract class CursorBasedIterator implements \Iterator
{
$options = array();
if (strlen($this->match) > 0) {
if (strlen(strval($this->match)) > 0) {
$options['MATCH'] = $this->match;
}
@@ -139,6 +139,7 @@ abstract class CursorBasedIterator implements \Iterator
/**
* {@inheritdoc}
*/
#[\ReturnTypeWillChange]
public function rewind()
{
$this->reset();
@@ -148,6 +149,7 @@ abstract class CursorBasedIterator implements \Iterator
/**
* {@inheritdoc}
*/
#[\ReturnTypeWillChange]
public function current()
{
return $this->current;
@@ -156,6 +158,7 @@ abstract class CursorBasedIterator implements \Iterator
/**
* {@inheritdoc}
*/
#[\ReturnTypeWillChange]
public function key()
{
return $this->position;
@@ -164,6 +167,7 @@ abstract class CursorBasedIterator implements \Iterator
/**
* {@inheritdoc}
*/
#[\ReturnTypeWillChange]
public function next()
{
tryFetch: {
@@ -184,6 +188,7 @@ abstract class CursorBasedIterator implements \Iterator
/**
* {@inheritdoc}
*/
#[\ReturnTypeWillChange]
public function valid()
{
return $this->valid;
+5
View File
@@ -128,6 +128,7 @@ class ListKey implements \Iterator
/**
* {@inheritdoc}
*/
#[\ReturnTypeWillChange]
public function rewind()
{
$this->reset();
@@ -137,6 +138,7 @@ class ListKey implements \Iterator
/**
* {@inheritdoc}
*/
#[\ReturnTypeWillChange]
public function current()
{
return $this->current;
@@ -145,6 +147,7 @@ class ListKey implements \Iterator
/**
* {@inheritdoc}
*/
#[\ReturnTypeWillChange]
public function key()
{
return $this->position;
@@ -153,6 +156,7 @@ class ListKey implements \Iterator
/**
* {@inheritdoc}
*/
#[\ReturnTypeWillChange]
public function next()
{
if (!$this->elements && $this->fetchmore) {
@@ -169,6 +173,7 @@ class ListKey implements \Iterator
/**
* {@inheritdoc}
*/
#[\ReturnTypeWillChange]
public function valid()
{
return $this->valid;
+1 -1
View File
@@ -92,7 +92,7 @@ abstract class Command implements CommandInterface
*/
public static function normalizeArguments(array $arguments)
{
if (count($arguments) === 1 && is_array($arguments[0])) {
if (count($arguments) === 1 && isset($arguments[0]) && is_array($arguments[0])) {
return $arguments[0];
}
+1 -1
View File
@@ -73,7 +73,7 @@ interface CommandInterface
/**
* Parses a raw response and returns a PHP object.
*
* @param string $data Binary string containing the whole response.
* @param string|array|null $data Binary string containing the whole response.
*
* @return mixed
*/
+5 -1
View File
@@ -71,7 +71,7 @@ class ProcessorChain implements \ArrayAccess, ProcessorInterface
/**
* Returns an iterator over the list of command processor in the chain.
*
* @return \ArrayIterator
* @return \Traversable<int, ProcessorInterface>
*/
public function getIterator()
{
@@ -91,6 +91,7 @@ class ProcessorChain implements \ArrayAccess, ProcessorInterface
/**
* {@inheritdoc}
*/
#[\ReturnTypeWillChange]
public function offsetExists($index)
{
return isset($this->processors[$index]);
@@ -99,6 +100,7 @@ class ProcessorChain implements \ArrayAccess, ProcessorInterface
/**
* {@inheritdoc}
*/
#[\ReturnTypeWillChange]
public function offsetGet($index)
{
return $this->processors[$index];
@@ -107,6 +109,7 @@ class ProcessorChain implements \ArrayAccess, ProcessorInterface
/**
* {@inheritdoc}
*/
#[\ReturnTypeWillChange]
public function offsetSet($index, $processor)
{
if (!$processor instanceof ProcessorInterface) {
@@ -121,6 +124,7 @@ class ProcessorChain implements \ArrayAccess, ProcessorInterface
/**
* {@inheritdoc}
*/
#[\ReturnTypeWillChange]
public function offsetUnset($index)
{
unset($this->processors[$index]);
+1 -2
View File
@@ -51,9 +51,8 @@ final class RawCommand implements CommandInterface
public static function create($commandID /* [ $arg, ... */)
{
$arguments = func_get_args();
$command = new static(array_shift($arguments), $arguments);
return $command;
return new static(array_shift($arguments), $arguments);
}
/**
+4 -1
View File
@@ -33,7 +33,10 @@ class SENTINEL extends RedisCommand
*/
public function parseResponse($data)
{
switch (strtolower($this->getArgument(0))) {
$argument = $this->getArgument(0);
$argument = is_null($argument) ? null : strtolower($argument);
switch ($argument) {
case 'masters':
case 'slaves':
return self::processMastersOrSlaves($data);
+40
View File
@@ -0,0 +1,40 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) Daniele Alessandri <suppakilla@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Predis\Command\Redis;
use Predis\Command\Command as RedisCommand;
/**
* @link http://redis.io/commands/touch
*
* @author Daniele Alessandri <suppakilla@gmail.com>
*/
class TOUCH extends RedisCommand
{
/**
* {@inheritdoc}
*/
public function getId()
{
return 'TOUCH';
}
/**
* {@inheritdoc}
*/
public function setArguments(array $arguments)
{
$arguments = self::normalizeArguments($arguments);
parent::setArguments($arguments);
}
}
+44
View File
@@ -0,0 +1,44 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) Daniele Alessandri <suppakilla@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Predis\Command\Redis;
use Predis\Command\Command as RedisCommand;
/**
* @link http://redis.io/commands/zpopmax
*
* @author Daniele Alessandri <suppakilla@gmail.com>
*/
class ZPOPMAX extends RedisCommand
{
/**
* {@inheritdoc}
*/
public function getId()
{
return 'ZPOPMAX';
}
/**
* {@inheritdoc}
*/
public function parseResponse($data)
{
$result = array();
for ($i = 0; $i < count($data); ++$i) {
$result[$data[$i]] = $data[++$i];
}
return $result;
}
}
+44
View File
@@ -0,0 +1,44 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) Daniele Alessandri <suppakilla@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Predis\Command\Redis;
use Predis\Command\Command as RedisCommand;
/**
* @link http://redis.io/commands/zpopmin
*
* @author Daniele Alessandri <suppakilla@gmail.com>
*/
class ZPOPMIN extends RedisCommand
{
/**
* {@inheritdoc}
*/
public function getId()
{
return 'ZPOPMIN';
}
/**
* {@inheritdoc}
*/
public function parseResponse($data)
{
$result = array();
for ($i = 0; $i < count($data); ++$i) {
$result[$data[$i]] = $data[++$i];
}
return $result;
}
}
+9 -5
View File
@@ -26,17 +26,21 @@ abstract class CommunicationException extends PredisException
* @param NodeConnectionInterface $connection Connection that generated the exception.
* @param string $message Error message.
* @param int $code Error code.
* @param \Exception $innerException Inner exception for wrapping the original error.
* @param \Exception|null $innerException Inner exception for wrapping the original error.
*/
public function __construct(
NodeConnectionInterface $connection,
$message = null,
$code = null,
$message = "",
$code = 0,
\Exception $innerException = null
) {
$this->connection = $connection;
parent::__construct(
is_null($message) ? '' : $message,
is_null($code) ? 0 : $code,
$innerException
);
parent::__construct($message, $code, $innerException);
$this->connection = $connection;
}
/**
+1 -1
View File
@@ -126,7 +126,7 @@ abstract class AbstractConnection implements NodeConnectionInterface
* @param string $message Error message.
* @param int $code Error code.
*/
protected function onConnectionError($message, $code = null)
protected function onConnectionError($message, $code = 0)
{
CommunicationException::handle(
new ConnectionException($this, "$message [{$this->getParameters()}]", $code)
+4 -6
View File
@@ -138,9 +138,7 @@ class PredisCluster implements ClusterInterface, \IteratorAggregate, \Countable
);
}
$node = $this->distributor->getBySlot($slot);
return $node;
return $this->distributor->getBySlot($slot);
}
/**
@@ -189,9 +187,7 @@ class PredisCluster implements ClusterInterface, \IteratorAggregate, \Countable
public function getConnectionByKey($key)
{
$hash = $this->strategy->getSlotByKey($key);
$node = $this->distributor->getBySlot($hash);
return $node;
return $this->distributor->getBySlot($hash);
}
/**
@@ -208,6 +204,7 @@ class PredisCluster implements ClusterInterface, \IteratorAggregate, \Countable
/**
* {@inheritdoc}
*/
#[\ReturnTypeWillChange]
public function count()
{
return count($this->pool);
@@ -216,6 +213,7 @@ class PredisCluster implements ClusterInterface, \IteratorAggregate, \Countable
/**
* {@inheritdoc}
*/
#[\ReturnTypeWillChange]
public function getIterator()
{
return new \ArrayIterator($this->pool);
+4 -6
View File
@@ -442,9 +442,7 @@ class RedisCluster implements ClusterInterface, \IteratorAggregate, \Countable
}
$this->move($connection, $slot);
$response = $this->executeCommand($command);
return $response;
return $this->executeCommand($command);
}
/**
@@ -465,9 +463,7 @@ class RedisCluster implements ClusterInterface, \IteratorAggregate, \Countable
}
$connection->executeCommand(RawCommand::create('ASKING'));
$response = $connection->executeCommand($command);
return $response;
return $connection->executeCommand($command);
}
/**
@@ -545,6 +541,7 @@ class RedisCluster implements ClusterInterface, \IteratorAggregate, \Countable
/**
* {@inheritdoc}
*/
#[\ReturnTypeWillChange]
public function count()
{
return count($this->pool);
@@ -553,6 +550,7 @@ class RedisCluster implements ClusterInterface, \IteratorAggregate, \Countable
/**
* {@inheritdoc}
*/
#[\ReturnTypeWillChange]
public function getIterator()
{
if ($this->slotmap->isEmpty()) {
+5 -5
View File
@@ -66,9 +66,9 @@ class PhpiredisSocketConnection extends AbstractConnection
*/
public function __destruct()
{
phpiredis_reader_destroy($this->reader);
parent::__destruct();
phpiredis_reader_destroy($this->reader);
}
/**
@@ -227,9 +227,7 @@ class PhpiredisSocketConnection extends AbstractConnection
$protocol = SOL_TCP;
}
$socket = @socket_create($domain, SOCK_STREAM, $protocol);
if (!is_resource($socket)) {
if (false === $socket = @socket_create($domain, SOCK_STREAM, $protocol)) {
$this->emitSocketError();
}
@@ -344,7 +342,9 @@ class PhpiredisSocketConnection extends AbstractConnection
public function disconnect()
{
if ($this->isConnected()) {
phpiredis_reader_reset($this->reader);
socket_close($this->getResource());
parent::disconnect();
}
}
+12 -2
View File
@@ -67,9 +67,19 @@ class PhpiredisStreamConnection extends StreamConnection
*/
public function __destruct()
{
phpiredis_reader_destroy($this->reader);
parent::__destruct();
phpiredis_reader_destroy($this->reader);
}
/**
* {@inheritdoc}
*/
public function disconnect()
{
phpiredis_reader_reset($this->reader);
parent::disconnect();
}
/**
@@ -20,6 +20,7 @@ use Predis\Connection\NodeConnectionInterface;
use Predis\Connection\Parameters;
use Predis\Replication\ReplicationStrategy;
use Predis\Replication\RoleException;
use Predis\Response\Error;
use Predis\Response\ErrorInterface as ErrorResponseInterface;
use Predis\Response\ServerException;
@@ -151,14 +152,14 @@ class SentinelReplication implements ReplicationInterface
}
/**
* Sets the time to wait (in seconds) before fetching a new configuration
* Sets the time to wait (in milliseconds) before fetching a new configuration
* from one of the sentinels.
*
* @param float $seconds Time to wait before the next attempt.
* @param float $milliseconds Time to wait before the next attempt.
*/
public function setRetryWait($seconds)
public function setRetryWait($milliseconds)
{
$this->retryWait = (float) $seconds;
$this->retryWait = (float) $milliseconds;
}
/**
@@ -254,10 +255,12 @@ class SentinelReplication implements ReplicationInterface
}
if (is_array($parameters)) {
// Password authentication is fine now that Redis Sentinel supports
// password-protected sentinel instances, but we must explicitly set
// "database" and "username" to NULL so that no augmented AUTH (ACL)
// and SELECT command are sent by accident to the sentinels.
// NOTE: sentinels do not accept AUTH and SELECT commands so we must
// explicitly set them to NULL to avoid problems when using default
// parameters set via client options. Actually AUTH is supported for
// sentinels starting with Redis 5 but we have to differentiate from
// sentinels passwords and nodes passwords, this will be implemented
// in a later release.
$parameters['database'] = null;
$parameters['username'] = null;
@@ -266,9 +269,7 @@ class SentinelReplication implements ReplicationInterface
}
}
$connection = $this->connectionFactory->create($parameters);
return $connection;
return $this->connectionFactory->create($parameters);
}
/**
@@ -536,13 +537,17 @@ class SentinelReplication implements ReplicationInterface
* @param NodeConnectionInterface $connection Connection to a redis server.
* @param string $role Expected role of the server ("master", "slave" or "sentinel").
*
* @throws RoleException
* @throws RoleException|ConnectionException
*/
protected function assertConnectionRole(NodeConnectionInterface $connection, $role)
{
$role = strtolower($role);
$actualRole = $connection->executeCommand(RawCommand::create('ROLE'));
if ($actualRole instanceof Error) {
throw new ConnectionException($connection, $actualRole->getMessage());
}
if ($role !== $actualRole[0]) {
throw new RoleException($connection, "Expected $role but got $actualRole[0] [$connection]");
}
+3 -7
View File
@@ -151,9 +151,7 @@ class StreamConnection extends AbstractConnection
}
}
$resource = $this->createStreamSocket($parameters, $address, $flags);
return $resource;
return $this->createStreamSocket($parameters, $address, $flags);
}
/**
@@ -183,9 +181,7 @@ class StreamConnection extends AbstractConnection
}
}
$resource = $this->createStreamSocket($parameters, "unix://{$parameters->path}", $flags);
return $resource;
return $this->createStreamSocket($parameters, "unix://{$parameters->path}", $flags);
}
/**
@@ -364,7 +360,7 @@ class StreamConnection extends AbstractConnection
$buffer = "*{$reqlen}\r\n\${$cmdlen}\r\n{$commandID}\r\n";
foreach ($arguments as $argument) {
$arglen = strlen($argument);
$arglen = strlen(strval($argument));
$buffer .= "\${$arglen}\r\n{$argument}\r\n";
}
+5
View File
@@ -91,6 +91,7 @@ class Consumer implements \Iterator
/**
* {@inheritdoc}
*/
#[\ReturnTypeWillChange]
public function rewind()
{
// NOOP
@@ -101,6 +102,7 @@ class Consumer implements \Iterator
*
* @return object
*/
#[\ReturnTypeWillChange]
public function current()
{
return $this->getValue();
@@ -109,6 +111,7 @@ class Consumer implements \Iterator
/**
* {@inheritdoc}
*/
#[\ReturnTypeWillChange]
public function key()
{
return $this->position;
@@ -117,6 +120,7 @@ class Consumer implements \Iterator
/**
* {@inheritdoc}
*/
#[\ReturnTypeWillChange]
public function next()
{
++$this->position;
@@ -127,6 +131,7 @@ class Consumer implements \Iterator
*
* @return bool
*/
#[\ReturnTypeWillChange]
public function valid()
{
return $this->valid;
+1 -1
View File
@@ -14,7 +14,7 @@ namespace Predis\Protocol;
use Predis\CommunicationException;
/**
* Exception used to indentify errors encountered while parsing the Redis wire
* Exception used to identify errors encountered while parsing the Redis wire
* protocol.
*
* @author Daniele Alessandri <suppakilla@gmail.com>
+1 -3
View File
@@ -95,9 +95,7 @@ class ResponseReader implements ResponseReaderInterface
$this->onProtocolError($connection, "Unknown response prefix: '$prefix'");
}
$payload = $this->handlers[$prefix]->handle($connection, substr($header, 1));
return $payload;
return $this->handlers[$prefix]->handle($connection, substr($header, 1));
}
/**
+5
View File
@@ -151,6 +151,7 @@ abstract class AbstractConsumer implements \Iterator
/**
* {@inheritdoc}
*/
#[\ReturnTypeWillChange]
public function rewind()
{
// NOOP
@@ -162,6 +163,7 @@ abstract class AbstractConsumer implements \Iterator
*
* @return array
*/
#[\ReturnTypeWillChange]
public function current()
{
return $this->getValue();
@@ -170,6 +172,7 @@ abstract class AbstractConsumer implements \Iterator
/**
* {@inheritdoc}
*/
#[\ReturnTypeWillChange]
public function key()
{
return $this->position;
@@ -178,6 +181,7 @@ abstract class AbstractConsumer implements \Iterator
/**
* {@inheritdoc}
*/
#[\ReturnTypeWillChange]
public function next()
{
if ($this->valid()) {
@@ -192,6 +196,7 @@ abstract class AbstractConsumer implements \Iterator
*
* @return bool
*/
#[\ReturnTypeWillChange]
public function valid()
{
$isValid = $this->isFlagSet(self::STATUS_VALID);
+2 -1
View File
@@ -62,7 +62,8 @@ class ReplicationStrategy
}
if (($eval = $id === 'EVAL') || $id === 'EVALSHA') {
$sha1 = $eval ? sha1($command->getArgument(0)) : $command->getArgument(0);
$argument = $command->getArgument(0);
$sha1 = $eval ? sha1(strval($argument)) : $argument;
if (isset($this->readonlySHA1[$sha1])) {
if (true === $readonly = $this->readonlySHA1[$sha1]) {
@@ -34,6 +34,7 @@ abstract class MultiBulkIterator implements \Iterator, \Countable, ResponseInter
/**
* {@inheritdoc}
*/
#[\ReturnTypeWillChange]
public function rewind()
{
// NOOP
@@ -42,6 +43,7 @@ abstract class MultiBulkIterator implements \Iterator, \Countable, ResponseInter
/**
* {@inheritdoc}
*/
#[\ReturnTypeWillChange]
public function current()
{
return $this->current;
@@ -50,6 +52,7 @@ abstract class MultiBulkIterator implements \Iterator, \Countable, ResponseInter
/**
* {@inheritdoc}
*/
#[\ReturnTypeWillChange]
public function key()
{
return $this->position;
@@ -58,6 +61,7 @@ abstract class MultiBulkIterator implements \Iterator, \Countable, ResponseInter
/**
* {@inheritdoc}
*/
#[\ReturnTypeWillChange]
public function next()
{
if (++$this->position < $this->size) {
@@ -68,6 +72,7 @@ abstract class MultiBulkIterator implements \Iterator, \Countable, ResponseInter
/**
* {@inheritdoc}
*/
#[\ReturnTypeWillChange]
public function valid()
{
return $this->position < $this->size;
@@ -82,6 +87,7 @@ abstract class MultiBulkIterator implements \Iterator, \Countable, ResponseInter
*
* @return int
*/
#[\ReturnTypeWillChange]
public function count()
{
return $this->size;
+1
View File
@@ -61,6 +61,7 @@ class MultiBulkTuple extends MultiBulk implements \OuterIterator
/**
* {@inheritdoc}
*/
#[\ReturnTypeWillChange]
public function getInnerIterator()
{
return $this->iterator;
+1 -1
View File
@@ -59,7 +59,7 @@ class Status implements ResponseInterface
*
* @param string $payload Status response payload.
*
* @return string
* @return self
*/
public static function get($payload)
{
+6
View File
@@ -54,6 +54,7 @@ class Handler implements \SessionHandlerInterface
/**
* {@inheritdoc}
*/
#[\ReturnTypeWillChange]
public function open($save_path, $session_id)
{
// NOOP
@@ -63,6 +64,7 @@ class Handler implements \SessionHandlerInterface
/**
* {@inheritdoc}
*/
#[\ReturnTypeWillChange]
public function close()
{
// NOOP
@@ -72,6 +74,7 @@ class Handler implements \SessionHandlerInterface
/**
* {@inheritdoc}
*/
#[\ReturnTypeWillChange]
public function gc($maxlifetime)
{
// NOOP
@@ -81,6 +84,7 @@ class Handler implements \SessionHandlerInterface
/**
* {@inheritdoc}
*/
#[\ReturnTypeWillChange]
public function read($session_id)
{
if ($data = $this->client->get($session_id)) {
@@ -92,6 +96,7 @@ class Handler implements \SessionHandlerInterface
/**
* {@inheritdoc}
*/
#[\ReturnTypeWillChange]
public function write($session_id, $session_data)
{
$this->client->setex($session_id, $this->ttl, $session_data);
@@ -102,6 +107,7 @@ class Handler implements \SessionHandlerInterface
/**
* {@inheritdoc}
*/
#[\ReturnTypeWillChange]
public function destroy($session_id)
{
$this->client->del($session_id);
@@ -27,9 +27,10 @@ class AbortedMultiExecException extends PredisException
* @param string $message Error message.
* @param int $code Error code.
*/
public function __construct(MultiExec $transaction, $message, $code = null)
public function __construct(MultiExec $transaction, $message, $code = 0)
{
parent::__construct($message, $code);
parent::__construct($message, is_null($code) ? 0 : $code);
$this->transaction = $transaction;
}
+4 -4
View File
@@ -236,7 +236,7 @@ class SlotMapTest extends PredisTestCase
{
$slotmap = new SlotMap();
$this->assertSame(0, count($slotmap));
$this->assertCount(0, $slotmap);
}
/**
@@ -247,13 +247,13 @@ class SlotMapTest extends PredisTestCase
$slotmap = new SlotMap();
$slotmap->setSlots(0, 5460, '127.0.0.1:6379');
$this->assertSame(5461, count($slotmap));
$this->assertCount(5461, $slotmap);
$slotmap->setSlots(5461, 10922, '127.0.0.1:6380');
$this->assertSame(10923, count($slotmap));
$this->assertCount(10923, $slotmap);
$slotmap->setSlots(10923, 16383, '127.0.0.1:6381');
$this->assertSame(16384, count($slotmap));
$this->assertCount(16384, $slotmap);
}
/**
+22 -1
View File
@@ -106,13 +106,34 @@ class COMMAND_Test extends PredisCommandTestCase
// NOTE: starting with Redis 6.0 and the introduction of Access Control
// Lists, COMMAND INFO returns an additional array for each specified
// command in yhe request with a list of the ACL categories associated
// command in the request with a list of the ACL categories associated
// to a command. We simply append this additional array in the expected
// response if the test suite is executed against Redis >= 6.0.
if ($this->isRedisServerVersion('>=', '6.0')) {
$expected[0][] = array('@read', '@string', '@fast');
}
// NOTE: starting with Redis 7.0 COMMAND INFO returns an additional arrays:
// - Command tips: https://redis.io/topics/command-tips.
// - Key specifications: https://redis.io/topics/key-specs.
// - Subcommands: https://redis.io/commands/command/#subcommands.
// We simply append this additional array in the expected response if the
// test suite is executed against Redis >= 7.0.
if ($this->isRedisServerVersion('>=', '7.0')) {
$expected[0][] = array();
$expected[0][] = array(
array(
'flags',
array('RO','access'),
'begin_search',
array('type','index','spec', array('index',1)),
'find_keys',
array('type','range','spec', array('lastkey',0,'keystep',1,'limit',0))
)
);
$expected[0][] = array();
}
$this->assertCount(1, $response = $redis->command('INFO', 'GET'));
// NOTE: we use assertEquals instead of assertSame because Redis returns
+8 -2
View File
@@ -104,7 +104,7 @@ class CONFIG_Test extends PredisCommandTestCase
$redis = $this->getClient();
$this->assertIsArray($configs = $redis->config('GET', 'dbfilename'));
$this->assertEquals(1, count($configs));
$this->assertCount(1, $configs);
$this->assertArrayHasKey('dbfilename', $configs);
}
@@ -143,7 +143,13 @@ class CONFIG_Test extends PredisCommandTestCase
public function testThrowsExceptionWhenSettingUnknownConfiguration(): void
{
$this->expectException('Predis\Response\ServerException');
$this->expectExceptionMessage('ERR Unsupported CONFIG parameter: foo');
if ($this->isRedisServerVersion('<=', '6.0')) {
$this->expectExceptionMessage('ERR Unsupported CONFIG parameter: foo');
}
if ($this->isRedisServerVersion('>=', '7.0')) {
$this->expectExceptionMessage("ERR Unknown option or number of arguments for CONFIG SET - 'foo'");
}
$redis = $this->getClient();
+1 -1
View File
@@ -320,7 +320,7 @@ BUFFER;
$redis = $this->getClient();
$command = $this->getCommand();
$this->assertInternalType('array', $info = $redis->executeCommand($command));
$this->assertIsArray($info = $redis->executeCommand($command));
$this->assertArrayHasKey('redis_version', $info);
}
}
+15
View File
@@ -92,4 +92,19 @@ class LPOP_Test extends PredisCommandTestCase
$redis->set('foo', 'bar');
$redis->lpop('foo');
}
/**
* @group connected
* @requiresRedisVersion >= 6.2
*/
public function testPopsSpecifiedNumberOfElements(): void
{
$redis = $this->getClient();
$redis->rpush('letters', 'a', 'b', 'c', 'd', 'e', 'f');
$this->assertSame(array('a', 'b'), $redis->lpop('letters', 2));
$this->assertSame(array('c', 'd'), $redis->lpop('letters', 2));
$this->assertSame(array('e', 'f'), $redis->lrange('letters', 0, -1));
}
}
+1 -1
View File
@@ -85,7 +85,7 @@ class MOVE_Test extends PredisCommandTestCase
public function testThrowsExceptionOnInvalidDatabases(): void
{
$this->expectException('Predis\Response\ServerException');
$this->expectExceptionMessage('ERR index out of range');
$this->expectExceptionMessageMatches('/ERR.*out of range/');
$redis = $this->getClient();
+1 -1
View File
@@ -87,7 +87,7 @@ class SELECT_Test extends PredisCommandTestCase
public function testThrowsExceptionOnUnexpectedDatabaseName(): void
{
$this->expectException('Predis\Response\ServerException');
$this->expectExceptionMessage('ERR invalid DB index');
$this->expectExceptionMessageMatches('/ERR.*(invalid DB index|value is not an integer or out of range)/');
$redis = $this->getClient();
+3 -3
View File
@@ -185,11 +185,11 @@ class SORT_Test extends PredisCommandTestCase
$redis = $this->getClient();
$redis->lpush('list:unordered', $unordered = array(2, 100, 3, 1, 30, 10));
$this->assertEquals(
count($unordered),
$this->assertCount(
$redis->sort('list:unordered', array(
'store' => 'list:ordered',
))
)),
$unordered
);
$this->assertEquals(array(1, 2, 3, 10, 30, 100), $redis->lrange('list:ordered', 0, -1));
+98
View File
@@ -0,0 +1,98 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) Daniele Alessandri <suppakilla@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Predis\Command\Redis;
/**
* @group commands
* @group realm-server
*/
class TOUCH_Test extends PredisCommandTestCase
{
/**
* {@inheritdoc}
*/
protected function getExpectedCommand(): string
{
return 'Predis\Command\Redis\TOUCH';
}
/**
* {@inheritdoc}
*/
protected function getExpectedId(): string
{
return 'TOUCH';
}
/**
* @requiresRedisVersion >= 3.2.1
*
* @group disconnected
*/
public function testFilterArguments(): void
{
$arguments = ['key1', 'key2', 'key3'];
$expected = ['key1', 'key2', 'key3'];
$command = $this->getCommand();
$command->setArguments($arguments);
$this->assertSame($expected, $command->getArguments());
}
/**
* @requiresRedisVersion >= 3.2.1
*
* @group disconnected
*/
public function testFilterArgumentsAsSingleArray(): void
{
$arguments = [['key1', 'key2', 'key3']];
$expected = ['key1', 'key2', 'key3'];
$command = $this->getCommand();
$command->setArguments($arguments);
$this->assertSame($expected, $command->getArguments());
}
/**
* @requiresRedisVersion >= 3.2.1
*
* @group disconnected
*/
public function testParseResponse(): void
{
$command = $this->getCommand();
$this->assertSame(10, $command->parseResponse(10));
}
/**
* @requiresRedisVersion >= 3.2.1
*
* @group connected
*/
public function testReturnsNumberOfDeletedKeys(): void
{
$redis = $this->getClient();
$this->assertSame(0, $redis->touch('foo'));
$redis->set('foo', 'bar');
$this->assertSame(1, $redis->touch('foo'));
$this->assertSame(1, $redis->touch('foo', 'hoge'));
$redis->set('hoge', 'piyo');
$this->assertSame(1, $redis->touch('foo'));
$this->assertSame(2, $redis->touch('foo', 'hoge'));
}
}
+102
View File
@@ -0,0 +1,102 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) Daniele Alessandri <suppakilla@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Predis\Command\Redis;
/**
* @group commands
* @group realm-zset
*/
class ZPOPMAX_Test extends PredisCommandTestCase
{
/**
* {@inheritdoc}
*/
protected function getExpectedCommand(): string
{
return 'Predis\Command\Redis\ZPOPMAX';
}
/**
* {@inheritdoc}
*/
protected function getExpectedId(): string
{
return 'ZPOPMAX';
}
/**
* @requiresRedisVersion >= 5.0.0
*
* @group disconnected
*/
public function testFilterArguments(): void
{
$arguments = array('zset', 2);
$expected = array('zset', 2);
$command = $this->getCommand();
$command->setArguments($arguments);
$this->assertSame($expected, $command->getArguments());
}
/**
* @requiresRedisVersion >= 5.0.0
*
* @group disconnected
*/
public function testParseResponse(): void
{
$raw = array('element1', '1', 'element2', '2', 'element3', '3');
$expected = array('element1' => '1', 'element2' => '2', 'element3' => '3');
$command = $this->getCommand();
$this->assertSame($expected, $command->parseResponse($raw));
}
/**
* @requiresRedisVersion >= 5.0.0
*
* @group connected
*/
public function testReturnsElements(): void
{
$redis = $this->getClient();
$this->assertSame(array(), $redis->zpopmax('letters'));
$this->assertSame(array(), $redis->zpopmax('letters', 3));
$redis->zadd('letters', -10, 'a', 0, 'b', 10, 'c', 20, 'd', 20, 'e', 30, 'f');
$this->assertSame(array('f' => '30'), $redis->zpopmax('letters'));
$this->assertSame(array('e' => '20', 'd' => '20', 'c' => '10'), $redis->zpopmax('letters', 3));
$this->assertSame(array('b' => '0', 'a' => '-10'), $redis->zpopmax('letters', 3));
}
/**
* @requiresRedisVersion >= 5.0.0
*
* @group connected
*/
public function testThrowsExceptionOnWrongType(): void
{
$this->expectException('Predis\Response\ServerException');
$this->expectExceptionMessage('Operation against a key holding the wrong kind of value');
$redis = $this->getClient();
$redis->set('foo', 'bar');
$redis->zpopmax('foo');
}
}
+101
View File
@@ -0,0 +1,101 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) Daniele Alessandri <suppakilla@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Predis\Command\Redis;
/**
* @group commands
* @group realm-zset
*/
class ZPOPMIN_Test extends PredisCommandTestCase
{
/**
* {@inheritdoc}
*/
protected function getExpectedCommand(): string
{
return 'Predis\Command\Redis\ZPOPMIN';
}
/**
* {@inheritdoc}
*/
protected function getExpectedId(): string
{
return 'ZPOPMIN';
}
/**
* @requiresRedisVersion >= 5.0.0
*
* @group disconnected
*/
public function testFilterArguments(): void
{
$arguments = array('zset', 2);
$expected = array('zset', 2);
$command = $this->getCommand();
$command->setArguments($arguments);
$this->assertSame($expected, $command->getArguments());
}
/**
* @requiresRedisVersion >= 5.0.0
*
* @group disconnected
*/
public function testParseResponse(): void
{
$raw = array('element1', '1', 'element2', '2', 'element3', '3');
$expected = array('element1' => '1', 'element2' => '2', 'element3' => '3');
$command = $this->getCommand();
$this->assertSame($expected, $command->parseResponse($raw));
}
/**
* @requiresRedisVersion >= 5.0.0
*
* @group connected
*/
public function testReturnsElements(): void
{
$redis = $this->getClient();
$this->assertSame(array(), $redis->zpopmin('letters'));
$this->assertSame(array(), $redis->zpopmin('letters', 3));
$redis->zadd('letters', -10, 'a', 0, 'b', 10, 'c', 20, 'd', 20, 'e', 30, 'f');
$this->assertSame(array('a' => '-10'), $redis->zpopmin('letters'));
$this->assertSame(array('b' => '0', 'c' => '10', 'd' => '20'), $redis->zpopmin('letters', 3));
$this->assertSame(array('e' => '20', 'f' => '30'), $redis->zpopmin('letters', 3));
}
/**
* @requiresRedisVersion >= 5.0.0
*
* @group connected
*/
public function testThrowsExceptionOnWrongType(): void
{
$this->expectException('Predis\Response\ServerException');
$this->expectExceptionMessage('Operation against a key holding the wrong kind of value');
$redis = $this->getClient();
$redis->set('foo', 'bar');
$redis->zpopmin('foo');
}
}
+1 -1
View File
@@ -90,7 +90,7 @@ class RedisFactoryTest extends PredisTestCase
$this->assertTrue($factory->supports('mock'));
$this->assertTrue($factory->supports('MOCK'));
$this->assertSame(get_class($command), $factory->getCommandClass('mock'));
$this->assertInstanceOf($factory->getCommandClass('mock'), $command);
}
/**
@@ -40,7 +40,7 @@ class PredisClusterTest extends PredisTestCase
$cluster->add($connection1);
$cluster->add($connection2);
$this->assertSame(2, count($cluster));
$this->assertCount(2, $cluster);
$this->assertSame($connection1, $cluster->getConnectionById('127.0.0.1:7001'));
$this->assertSame($connection2, $cluster->getConnectionById('127.0.0.1:7002'));
}
@@ -58,7 +58,7 @@ class PredisClusterTest extends PredisTestCase
$cluster->add($connection1);
$cluster->add($connection2);
$this->assertSame(2, count($cluster));
$this->assertCount(2, $cluster);
$this->assertSame($connection1, $cluster->getConnectionByAlias('node01'));
$this->assertSame($connection2, $cluster->getConnectionByAlias('node02'));
}
@@ -71,7 +71,7 @@ class RedisClusterTest extends PredisTestCase
$cluster->add($connection1);
$cluster->add($connection2);
$this->assertSame(2, count($cluster));
$this->assertCount(2, $cluster);
$this->assertSame($connection1, $cluster->getConnectionById('127.0.0.1:6379'));
$this->assertSame($connection2, $cluster->getConnectionById('127.0.0.1:6380'));
}
@@ -92,7 +92,7 @@ class RedisClusterTest extends PredisTestCase
$this->assertTrue($cluster->remove($connection1));
$this->assertFalse($cluster->remove($connection3));
$this->assertSame(1, count($cluster));
$this->assertCount(1, $cluster);
}
/**
@@ -110,7 +110,7 @@ class RedisClusterTest extends PredisTestCase
$this->assertTrue($cluster->removeById('127.0.0.1:6380'));
$this->assertFalse($cluster->removeById('127.0.0.1:6390'));
$this->assertSame(1, count($cluster));
$this->assertCount(1, $cluster);
}
/**
@@ -128,11 +128,11 @@ class RedisClusterTest extends PredisTestCase
$cluster->add($connection2);
$cluster->add($connection3);
$this->assertSame(3, count($cluster));
$this->assertCount(3, $cluster);
$cluster->remove($connection3);
$this->assertSame(2, count($cluster));
$this->assertCount(2, $cluster);
}
/**
@@ -977,7 +977,7 @@ class RedisClusterTest extends PredisTestCase
$this->assertSame('foobar', $cluster->executeCommand($command));
$this->assertSame('foobar', $cluster->executeCommand($command));
$this->assertSame(2, count($cluster));
$this->assertCount(2, $cluster);
}
/**
@@ -1033,7 +1033,7 @@ class RedisClusterTest extends PredisTestCase
$this->assertSame('foobar', $cluster->executeCommand($command));
$this->assertSame('foobar', $cluster->executeCommand($command));
$this->assertSame(2, count($cluster));
$this->assertCount(2, $cluster);
}
/**
@@ -1071,7 +1071,7 @@ class RedisClusterTest extends PredisTestCase
$this->assertSame('foobar', $cluster->executeCommand($command));
$this->assertSame('foobar', $cluster->executeCommand($command));
$this->assertSame(2, count($cluster));
$this->assertCount(2, $cluster);
}
/**
@@ -1121,7 +1121,7 @@ class RedisClusterTest extends PredisTestCase
$this->assertSame('foobar', $cluster->executeCommand($command));
$this->assertSame('foobar', $cluster->executeCommand($command));
$this->assertSame(3, count($cluster));
$this->assertCount(3, $cluster);
}
/**
@@ -1259,7 +1259,7 @@ class RedisClusterTest extends PredisTestCase
$cluster->add($connection1);
$this->assertSame('foobar', $cluster->executeCommand($cmdGET));
$this->assertSame(2, count($cluster));
$this->assertCount(2, $cluster);
}
/**
+1 -1
View File
@@ -749,7 +749,7 @@ class MultiExecTest extends PredisTestCase
$tx->set('hoge', 'piyo');
});
$this->assertSame(1, count($responses));
$this->assertCount(1, $responses);
$this->assertSame(0, $client->exists('foo'));
$this->assertSame(1, $client->exists('hoge'));
}