Compare commits

..

18 Commits

Author SHA1 Message Date
Till Krüss 33b70b971a Update CHANGELOG.md 2023-06-14 13:37:31 +03:00
Vladyslav Vildanov e46d56c45c Fixed subcommand test bug (#1313) 2023-06-08 11:33:25 -04:00
Vladyslav Vildanov c57a6744bb Added support for JSON.MSET command (#1307) 2023-06-08 17:35:04 +03:00
Vladyslav Vildanov df83c94bb3 Added support for JSON.MERGE command (#1304) 2023-06-08 12:16:14 +03:00
Vladyslav Vildanov a711ef96e2 Added GETDEL command to KeyPrefixProcessor (#1306)
* Added GETDEL command to KeyPrefixProcessor

* Added test coverage

* Codestyle fixes

* Added timeout after FT.CREATE call
2023-06-08 11:32:05 +03:00
Vladyslav Vildanov 3c322fc4e3 Codestyle changes related to php-cs-fixer update (#1311)
* Codestyle changes

* Added missing type-hints
2023-06-07 17:05:36 +03:00
Till Krüss 95c23fb94d tag 2.2.0-RC1 2023-05-09 10:45:20 -07:00
Till Krüss 946c4b7bd7 [v2.x] Relay support (#1263) 2023-05-09 10:39:00 -07:00
Vladyslav Vildanov 538c65946d Added timeout to prevent search before create (#1269) 2023-05-03 11:00:31 -07:00
Till Krüss e8ea05dafe spacing 2023-04-19 13:52:53 -07:00
Nicolas Grekas bf2075a176 Add missing @return annotations (#1265)
* Add missing `@return` annotations

* formatting

* formatting

* Update ProcessorChain.php

* Update Handler.php

---------

Co-authored-by: Till Krüss <tillkruss@users.noreply.github.com>
2023-04-19 13:51:42 -07:00
Till Krüss d2cd99492d don't export bin 2023-04-13 09:51:16 -07:00
Vladyslav Vildanov 971e47672d Added Redis stack support (JSON, Search, TimeSeries, Bloom) (#1253) 2023-04-11 08:09:14 -07:00
Till Krüss f9b755ece9 changes [skip ci] 2023-04-05 08:33:26 -07:00
Jess Archer 98d4f80263 Add missing stream key prefixes (#1230)
* Added missing stream key prefixes

* Tested stream command key prefixing
2023-03-29 07:03:45 -07:00
Vladyslav Vildanov 0e019cc08d Extended core support by implementing ACL SETUSER, GETUSER, DRYRUN (#1193)
* Added support for ACL GETUSER, SETUSER, DRYRUN commands

* Change test to support Redis > 6.0.0

* Removed selectors check
2023-03-15 14:57:12 +02:00
Till Krüss b898172009 typo 2023-03-12 09:22:07 -07:00
Vladyslav Vildanov f68543af37 Extended core support by implementing FCALL_RO command (#1191) 2023-03-12 08:52:20 -07:00
470 changed files with 27693 additions and 342 deletions
+1 -1
View File
@@ -3,4 +3,4 @@ skip=./.git
check-hidden=
check-filenames=
builtin=clear,rare,informal,usage,code,names
ignore-words-list=master,masters,slave,slaves,whitelist,cas,exat,smove
ignore-words-list=master,masters,slave,slaves,whitelist,cas,exat,smove,SUGGET,sugget
+5 -3
View File
@@ -1,8 +1,9 @@
* text=auto
/.github/ export-ignore
/examples/ export-ignore
/tests/ export-ignore
/.github export-ignore
/bin export-ignore
/examples export-ignore
/tests export-ignore
/.codespellrc export-ignore linguist-language=INI
/.editorconfig export-ignore
/.gitattributes export-ignore
@@ -12,6 +13,7 @@
/CONTRIBUTING.md export-ignore linguist-documentation
/FAQ.md export-ignore linguist-documentation
/VERSION export-ignore
/phpunit.relay.xml export-ignore
/phpunit.xml.dist export-ignore
/phpstan.dist.neon export-ignore
/phpstan-tests.dist.neon export-ignore
+66
View File
@@ -0,0 +1,66 @@
name: Stack
on:
push:
branches:
- main
- v2.**
pull_request:
jobs:
predis:
name: PHP ${{ matrix.php }} (Redis Stack ${{ matrix.redis }})
runs-on: ubuntu-latest
services:
redis:
image: redis/redis-stack-server:${{ matrix.redis }}
options: --health-cmd="redis-cli ping" --health-interval=10s --health-timeout=5s --health-retries=3
ports:
- 6379:6379
strategy:
fail-fast: false
matrix:
php:
- '7.2'
- '7.3'
- '7.4'
- '8.0'
- '8.1'
- '8.2'
redis:
- latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Setup PHP with Composer and extensions
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
extensions: relay
- name: Get Composer cache directory
id: composer-cache
run: echo "directory=$(composer config cache-dir)" >> $GITHUB_OUTPUT
- name: Cache Composer dependencies
uses: actions/cache@v3
with:
path: ${{ steps.composer-cache.outputs.directory }}
key: tests-php-${{ matrix.php }}-composer-${{ hashFiles('**/composer.lock') }}
restore-keys: tests-php-${{ matrix.php }}-composer
- name: Install Composer dependencies
env:
PHP_VERSION: ${{ matrix.php }}
run: composer install --ansi --no-progress --prefer-dist
- name: Run tests
run: vendor/bin/phpunit --group realm-stack
- name: Run tests using Relay
run: vendor/bin/phpunit --group realm-stack -c phpunit.relay.xml
+15 -10
View File
@@ -14,7 +14,7 @@ concurrency:
jobs:
predis:
name: PHP ${{ matrix.php }} Redis ${{ matrix.redis }}
name: PHP ${{ matrix.php }} (Redis ${{ matrix.redis }})
runs-on: ubuntu-latest
strategy:
@@ -28,11 +28,11 @@ jobs:
- '8.1'
- '8.2'
redis:
- '3'
- '4'
- '5'
- '6'
- '7'
- 3
- 4
- 5
- 6
- 7
services:
redis:
@@ -50,6 +50,7 @@ jobs:
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
extensions: relay
coverage: ${{ (matrix.php == '8.1' && matrix.redis == '7') && 'xdebug' || 'none' }}
- name: Install Composer dependencies
@@ -58,13 +59,17 @@ jobs:
dependency-versions: highest
composer-options: ${{ matrix.php == '8.0' && '--ignore-platform-reqs' || '' }}
- name: Run PHPUnit tests
- name: Run tests
if: ${{ matrix.php != '8.1' || matrix.redis != '7' }}
run: vendor/bin/phpunit --verbose
run: vendor/bin/phpunit
- name: Run PHPUnit tests with coverage
- name: Run tests with coverage
if: ${{ matrix.php == '8.1' && matrix.redis == '7' }}
run: vendor/bin/phpunit --verbose --coverage-clover build/logs/clover.xml --coverage-filter ./src
run: vendor/bin/phpunit --coverage-clover build/logs/clover.xml --coverage-filter ./src
- name: Run tests using Relay
if: ${{ matrix.redis >= '6' }}
run: vendor/bin/phpunit -c phpunit.relay.xml
- name: Send coverage to Coveralls
env:
+27 -9
View File
@@ -1,8 +1,26 @@
## Changelog
## v2.2.0 (2023-06-14)
### Added
- Added support for [Relay](https://github.com/predis/predis/wiki/Using-Relay) (#1263)
- Added support for `FCALL_RO` command (#1191)
- Added support for Redis `JSON`, `Bloom`, `Search` and `TimeSeries` module (#1253)
- Added support for `ACL SETUSER, GETUSER, DRYRUN` commands (#1193)
### Changed
- Minor code style and typehint changes (#1311)
### Fixed
- Fixed prefixes for `XTRIM` and `XREVRANGE` commands (#1230)
- Fixed `fclose()` being called on invalid stream resource (#1199)
- Fixed `BitByte` and `ExpireOptions` traits skip processing on null values (#1169)
- Fixed missing `@return` annotations (#1265)
- Fixed `GETDEL` prefixing (#1306)
## v2.1.2 (2023-03-02)
## Added
### Added
- Added stream commands to `KeyPrefixProcessor` (#1051)
- Added `ReplicationStrategy::$loadBalancing` option to disable replica reads (#1168)
- Added support for `FCALL` and `FUNCTIONS` commands (#1049)
@@ -16,28 +34,28 @@
- Added support for new arguments for `BITPOS` and `BITCOUNT` commands (#1045)
- Added support for new arguments for `EXPIRE` and `EXPIREAT` commands (#1046)
## Bug Fixes
### Bug Fixes
- Fixed deprecated function call syntax
## Deprecated
### Deprecated
- Further deprecated phpiredis and webdis integration (#1179)
## Maintenance
### Maintenance
- Applied coding standards
- Pass PHPStan level 2
## v2.1.1 (2023-01-17)
## Bug Fixes
### Bug Fixes
- Fix `@template` in `Predis\Client` (#1017)
- Fix support options array in `ZINTERSTORE` and `ZUNIONSTORE` (#1018)
## Deprecated
### Deprecated
- Deprecated phpiredis and webdis connections
## v2.1.0 (2023-01-16)
## New Features
### New Features
- Implemented `GETEX` command (#872)
- Implemented `GETDEL` command (#869)
- Implemented `COPY` command (#866)
@@ -63,10 +81,10 @@
- Implemented `GEOSEARCH` command (#867)
- Implemented `GEOSEARCHSTORE` command (#873)
## Bug Fixes
### Bug Fixes
- Added annotations to suppress PHP 8.1 return type deprecation warning (#810)
## Maintenance
### Maintenance
- Added mixin annotations for traits (#835)
## v2.0.3 (2022-10-11)
+32 -64
View File
@@ -1,7 +1,6 @@
# Some frequently asked questions about Predis #
________________________________________________
# Frequently asked questions about Predis #
### What is the point of Predis? ###
## What is the point of Predis? ##
The main point of Predis is about offering a highly customizable and extensible client for Redis,
that can be easily extended by developers while still being reasonably fast. With Predis you can
@@ -13,12 +12,12 @@ a great asset since it allows developers to add new and still missing features o
the standard behaviour of the library without the need to break dependencies in production code (at
least to some degree).
### Does Predis support UNIX domain sockets and persistent connections? ###
## Does Predis support UNIX domain sockets and persistent connections? ##
Yes. Obviously persistent connections actually work only when using PHP configured as a persistent
process reused by the web server (see [PHP-FPM](http://php-fpm.org)).
### Does Predis support SSL-encrypted connections? ###
## Does Predis support SSL-encrypted connections? ##
Yes. Encrypted connections are mostly useful when connecting to Redis instances exposed by various
cloud hosting providers without the need to configure an SSL proxy, but you should also take into
@@ -26,16 +25,21 @@ account the general performances degradation especially during the connect() ope
handshake must be performed to secure the connection. Persistent SSL-encrypted connections may help
in that respect, but they are supported only when running on PHP >= 7.0.0.
### Does Predis support transparent (de)serialization of values? ###
## Does Predis support transparent (de)serialization of values? ##
No and it will not ever do that by default. The reason behind this decision is that serialization is
usually something that developers prefer to customize depending on their needs and can not be easily
generalized when using Redis because of the many possible access patterns for your data. This does
not mean that it is impossible to have such a feature since you can leverage the extensibility of
this library to define your own serialization-aware commands. You can find more details about how to
do that [on this issue](http://github.com/predis/predis/issues/29#issuecomment-1202624).
When using [Relay](https://github.com/cachewerk/relay) as the underlying client, several
serialization and compression algorithms are supported. This slightly increases CPU usage,
but significantly reduces bytes sent over the network and Redis memory usage.
### How can I force Predis to connect to Redis before sending any command? ###
Without Relay, Predis will not serialize data and will never do that by default. The reason
behind this decision is that serialization is usually something that developers prefer to
customize depending on their needs and can not be easilygeneralized when using Redis because
of the many possible access patterns for your data. This does not mean that it is impossible
to have such a feature since you can leverage the extensibility of this library to define
your own serialization-aware commands. You can find more details about how to do that
[on this issue](http://github.com/predis/predis/issues/29#issuecomment-1202624).
## How can I force Predis to connect to Redis before sending any command? ##
Explicitly connecting to Redis is usually not needed since the client initializes connections lazily
only when they are needed. Admittedly, this behavior can be inconvenient in certain scenarios when
@@ -55,7 +59,7 @@ try {
$client->info();
```
### How Predis abstracts Redis commands? ###
## How Predis abstracts Redis commands? ##
The approach used to implement Redis commands is quite simple: by default each command follows the
same signature as defined on the [Redis documentation](http://redis.io/commands) which makes things
@@ -75,12 +79,20 @@ $client->hmset('my:hash', ['field1'=>'value1', 'field2'=>'value2']); // single n
An exception to this rule is [`SORT`](http://redis.io/commands/sort) for which modifiers are passed
[using a named array](tests/Predis/Command/KeySortTest.php#L54-L75).
## When should I use Relay? ##
# Speaking about performances... #
_________________________________________________
If you care about performance, __always__. [Relay](https://github.com/cachewerk/relay) is free to use.
## When should I use PhpRedis? ###
### Predis is a pure-PHP implementation: it can not be fast enough! ###
Predis is fast enough when Redis is located on the same machine as PHP, more on that later.
[PhpRedis](https://github.com/phpredis/phpredis) (and Relay) perform significantly better when
network I/O is involved, due to their ability to compress data by ~75%. Fewer bytes and received
sent over the network [means faster operations](https://akalongman.medium.com/phpredis-vs-predis-comparison-on-real-production-data-a819b48cbadb),
and potentially cost savings when network traffic isn't free (e.g. AWS Elasticache Inter-AZ transfer costs).
## Predis is a pure-PHP implementation: it can not be fast enough! ##
It really depends, but most of the times the answer is: _yes, it is fast enough_. I will give you a
couple of easy numbers with a simple test that uses a single client and is executed by PHP 5.5.6
@@ -92,7 +104,7 @@ against a local instance of Redis 2.8 that runs under Ubuntu 13.10 on a Intel Q6
0.130 seconds to fetch 30000 keys using _KEYS *_.
```
How does it compare with [__phpredis__](http://github.com/nicolasff/phpredis), a nice C extension
How does it compare with [__PhpRedis__](http://github.com/phpredis/phpredis), a nice C extension
providing an efficient client for Redis?
```
@@ -101,7 +113,7 @@ providing an efficient client for Redis?
0.035 seconds to fetch 30000 keys using "KEYS *"".
```
Wow __phpredis__ seems much faster! Well, we are comparing a C extension with a pure-PHP library so
Wow __PhpRedis__ seems much faster! Well, we are comparing a C extension with a pure-PHP library so
lower numbers are quite expected but there is a fundamental flaw in them: is this really how you are
going to use Redis in your application? Are you really going to send thousands of commands using a
for-loop on each page request using a single client instance? If so... well I guess you are probably
@@ -119,7 +131,7 @@ Using Predis:
3200 GET/sec while retrieving the very same values
0.132 seconds to fetch 30000 keys using "KEYS *".
Using phpredis:
Using PhpRedis:
3500 SET/sec using 12 bytes for both key and value
3500 GET/sec while retrieving the very same values
0.045 seconds to fetch 30000 keys using "KEYS *".
@@ -131,47 +143,3 @@ that we are measuring the overhead of client libraries implementations and the e
round-trip times, so we are not really measuring how fast Redis is. Redis shines best with thousands
of concurrent clients doing requests! Also, actual performances should be measured according to how
your application will use Redis.
### I am convinced, but performances for multi-bulk responses are still worse ###
Fair enough, but there is an option available if you need even more speed and consists on installing
__[phpiredis](http://github.com/nrk/phpiredis)__ (note the additional _i_ in the name) and let the
client use it. __phpiredis__ is another C extension that wraps __hiredis__ (the official C client
library for Redis) with a thin layer exposing its features to PHP. You can then choose between two
different connection classes:
- `Predis\Connection\PhpiredisStreamConnection` (using native PHP streams).
- `Predis\Connection\PhpiredisSocketConnection` (requires `ext-socket`).
You will now get the benefits of a faster protocol serializer and parser just by adding a couple of
lines of code:
```php
$client = new Predis\Client('tcp://127.0.0.1', array(
'connections' => array(
'tcp' => 'Predis\Connection\PhpiredisStreamConnection',
'unix' => 'Predis\Connection\PhpiredisSocketConnection',
),
));
```
Dead simple. Nothing changes in the way you use the library in your application. So how fast is it
our basic benchmark script now? There are not much improvements for inline or short bulk responses
like the ones returned by `SET` and `GET`, but the speed for parsing multi-bulk responses is now on
par with phpredis:
```
Fatching 30000 keys with _KEYS *_ using Predis paired with phpiredis::
0.035 seconds from a local Redis instance
0.047 seconds from a remote Redis instance
```
### If I need an extension to get better performances, why not using phpredis? ###
Good question. Generically speaking if you need absolute uber-speed using Redis on the localhost and
you do not care about abstractions built around some Redis features such as MULTI / EXEC, or if you
do not need any kind of extensibility or guaranteed backwards compatibility with different versions
of Redis (Predis currently supports from 1.2 up to 2.8 and the current development version), then
using __phpredis__ makes absolutely sense. Otherwise, Predis is perfect for the job and by adding
__phpiredis__ you can get a nice speed bump almost for free.
+10 -17
View File
@@ -396,6 +396,16 @@ $response = $client->lpushrand('random_values', $seed = mt_rand());
### Customizable connection backends ###
Predis can use different connection backends to connect to Redis. The builtin Relay integration
leverages the [Relay](https://github.com/cachewerk/relay) extension for PHP for major performance
gains, by caching a partial replica of the Redis dataset in PHP shared runtime memory.
```php
$client = new Predis\Client('tcp://127.0.0.1', [
'connections' => 'relay',
]);
```
Developers can create their own connection classes to support whole new network backends, extend
existing classes or provide completely different implementations. Connection classes must implement
`Predis\Connection\NodeConnectionInterface` or extend `Predis\Connection\AbstractConnection`:
@@ -439,23 +449,6 @@ be disabled. See [the tests README](tests/README.md) for more details about test
Predis uses GitHub Actions for continuous integration and the history for past and current builds can be
found [on its actions page](https://github.com/predis/predis/actions).
## Other ##
### Project related links ###
- [Source code](https://github.com/predis/predis)
- [Wiki](https://github.com/predis/predis/wiki)
- [Issue tracker](https://github.com/predis/predis/issues)
### Author ###
- [Till Krüss](https://till.im) ([Twitter](http://twitter.com/tillkruss))
- [Daniele Alessandri](mailto:suppakilla@gmail.com) ([twitter](http://twitter.com/JoL1hAHN))
### License ###
The code for Predis is distributed under the terms of the MIT license (see [LICENSE](LICENSE)).
+1 -1
View File
@@ -1 +1 @@
2.1.2
2.2.0-RC1
+3
View File
@@ -29,6 +29,9 @@
"phpstan/phpstan": "^1.9",
"phpunit/phpunit": "^8.0 || ~9.4.4"
},
"suggest": {
"ext-relay": "Faster connection with in-memory caching (>=0.6.2)"
},
"scripts": {
"phpstan": "phpstan analyse",
"style": "php-cs-fixer fix --diff --dry-run",
@@ -0,0 +1,28 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use Predis\Client;
require __DIR__ . '/../../shared.php';
// Example of JSON.DEBUG command usage:
// 1. Set JSON object
$client = new Client();
$client->jsonset('key', '$', '{"key1":"value1","key2":"value2"}');
// 2. Dump information about json memory usage in bytes
$response = $client->jsondebug->memory('key', '$');
echo 'Response:' . "\n";
print_r($response);
+52
View File
@@ -0,0 +1,52 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use Predis\Client;
use Predis\Command\Argument\Search\AggregateArguments;
use Predis\Command\Argument\Search\CreateArguments;
use Predis\Command\Argument\Search\SchemaFields\AbstractField;
use Predis\Command\Argument\Search\SchemaFields\NumericField;
use Predis\Command\Argument\Search\SchemaFields\TextField;
require __DIR__ . '/../../shared.php';
// Example of FT.AGGREGATE command usage:
// 1. Create index
$client = new Client();
$ftCreateArguments = (new CreateArguments())->prefix(['user:']);
$schema = [
new TextField('name'),
new TextField('country'),
new NumericField('dob', '', AbstractField::SORTABLE),
];
$client->ftcreate('idx', $schema, $ftCreateArguments);
// 2. Add documents
$client->hset('user:0', 'name', 'Vlad', 'country', 'Ukraine', 'dob', 813801600);
$client->hset('user:1', 'name', 'Vlad', 'country', 'Israel', 'dob', 782265600);
$client->hset('user:2', 'name', 'Vlad', 'country', 'Ukraine', 'dob', 813801600);
// 3. Execute aggregation query
$ftAggregateArguments = (new AggregateArguments())
->apply('year(@dob)', 'birth')
->groupBy('@country', '@birth')
->reduce('COUNT', true, 'country_birth_Vlad_count')
->sortBy(0, '@birth', 'DESC');
$response = $client->ftaggregate('idx', '@name: "Vlad"', $ftAggregateArguments);
// Response grouped by user country and birth year, with users count in each group, sorted by birth year from DESC.
echo 'Response:' . "\n";
print_r($response);
+41
View File
@@ -0,0 +1,41 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use Predis\Client;
use Predis\Command\Argument\Search\SchemaFields\TextField;
require __DIR__ . '/../../shared.php';
// Example of FT.ALTER command usage:
// 1. Create index
$client = new Client();
$schema = [
new TextField('text_field'),
];
$client->ftcreate('index_alter', $schema);
echo 'Default index attributes:' . "\n";
$defaultAttributes = $client->ftinfo('index_alter');
print_r($defaultAttributes[7]);
// 2. Add additional attribute to existing index
$schema = [
new TextField('new_field_name'),
];
$client->ftalter('index_alter', $schema);
echo 'Updated index attributes:' . "\n";
$updatedAttributes = $client->ftinfo('index_alter');
print_r($updatedAttributes[7]);
@@ -0,0 +1,25 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use Predis\Client;
require __DIR__ . '/../../shared.php';
// Example of FT.CONFIG HELP command usage:
// 1. Dump helpful information about FT.CONFIG MAXEXPANSIONS option
$client = new Client();
echo 'Response:' . "\n";
print_r(
$client->ftconfig->help('MAXEXPANSIONS')
);
@@ -0,0 +1,29 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use Predis\Client;
require __DIR__ . '/../../shared.php';
// Example of FT.CONFIG SET command usage:
// 1. Change default timeout setting
$client = new Client();
echo 'Response:' . "\n";
print_r(
$client->ftconfig->set('TIMEOUT', 42)
);
print_r(
$client->ftconfig->get('TIMEOUT')
);
@@ -0,0 +1,54 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use Predis\Client;
use Predis\Command\Argument\Search\AggregateArguments;
use Predis\Command\Argument\Search\CreateArguments;
use Predis\Command\Argument\Search\SchemaFields\AbstractField;
use Predis\Command\Argument\Search\SchemaFields\NumericField;
use Predis\Command\Argument\Search\SchemaFields\TextField;
require __DIR__ . '/../../shared.php';
// Example of FT.CURSOR DEL command usage
// 1. Create index
$client = new Client();
$ftCreateArguments = (new CreateArguments())->prefix(['user:']);
$schema = [
new TextField('name'),
new TextField('country'),
new NumericField('dob', '', AbstractField::SORTABLE),
];
$client->ftcreate('index_cursor_del', $schema, $ftCreateArguments);
// 2. Add documents
$client->hset('user:0', 'name', 'Vlad', 'country', 'Ukraine', 'dob', 813801600);
$client->hset('user:1', 'name', 'Vlad', 'country', 'Israel', 'dob', 782265600);
$client->hset('user:2', 'name', 'Vlad', 'country', 'Ukraine', 'dob', 813801600);
// 3. Execute aggregation query
$ftAggregateArguments = (new AggregateArguments())
->apply('year(@dob)', 'birth')
->groupBy('@country', '@birth')
->reduce('COUNT', true, 'country_birth_Vlad_count')
->sortBy(0, '@birth', 'DESC')
->withCursor(1);
[$_, $cursor] = $client->ftaggregate('index_cursor_del', '@name: "Vlad"', $ftAggregateArguments);
// 4. Explicitly remove returned cursor
$client->ftcursor->del('index_cursor_del', $cursor);
echo "Cursor with cursorId - {$cursor} was removed";
@@ -0,0 +1,62 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use Predis\Client;
use Predis\Command\Argument\Search\AggregateArguments;
use Predis\Command\Argument\Search\CreateArguments;
use Predis\Command\Argument\Search\SchemaFields\AbstractField;
use Predis\Command\Argument\Search\SchemaFields\NumericField;
use Predis\Command\Argument\Search\SchemaFields\TextField;
require __DIR__ . '/../../shared.php';
// Example of FT.CURSOR READ command usage
// 1. Create index
$client = new Client();
$ftCreateArguments = (new CreateArguments())->prefix(['user:']);
$schema = [
new TextField('name'),
new TextField('country'),
new NumericField('dob', '', AbstractField::SORTABLE),
];
$client->ftcreate('index_cursor_read', $schema, $ftCreateArguments);
// 2. Add documents
$client->hset('user:0', 'name', 'Vlad', 'country', 'Ukraine', 'dob', 813801600);
$client->hset('user:1', 'name', 'Vlad', 'country', 'Israel', 'dob', 782265600);
$client->hset('user:2', 'name', 'Vlad', 'country', 'Ukraine', 'dob', 813801600);
// 3. Execute aggregation query
$ftAggregateArguments = (new AggregateArguments())
->apply('year(@dob)', 'birth')
->groupBy('@country', '@birth')
->reduce('COUNT', true, 'country_birth_Vlad_count')
->sortBy(0, '@birth', 'DESC')
->withCursor(1);
[$response, $cursor] = $client->ftaggregate('index_cursor_read', '@name: "Vlad"', $ftAggregateArguments);
// 4. Processing response in loop until cursorId exists
$actualResponse = [];
$cursors = [];
while ($cursor) {
$actualResponse[] = $response[1];
$cursors[] = $cursor;
[$response, $cursor] = $client->ftcursor->read('index_cursor_read', $cursor);
}
echo "Response: \n";
print_r($actualResponse);
+32
View File
@@ -0,0 +1,32 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use Predis\Client;
use Predis\Command\Argument\Search\SchemaFields\TextField;
require __DIR__ . '/../../shared.php';
// Example of FT.EXPLAIN command usage:
// 1. Create index
$client = new Client();
$schema = [
new TextField('text_field'),
];
$client->ftcreate('index_explain', $schema);
// 2. Run query explanations
$response = $client->ftexplain('index_explain', '(foo bar)|(hello world) @date:[100 200]|@date:[500 +inf]');
echo 'Response:' . "\n";
print_r($response);
+38
View File
@@ -0,0 +1,38 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use Predis\Client;
use Predis\Command\Argument\Search\ProfileArguments;
use Predis\Command\Argument\Search\SchemaFields\TextField;
require __DIR__ . '/../../shared.php';
// Example of FT.PROFILE command usage:
// 1. Create index
$client = new Client();
$schema = [
new TextField('text_field'),
];
$client->ftcreate('index_profile', $schema);
// 2. Create FT.PROFILE command arguments
$arguments = (new ProfileArguments())
->search()
->query('query');
// 3. Run profile query
$response = $client->ftprofile('index_profile', $arguments);
echo 'Response:' . "\n";
print_r($response);
@@ -0,0 +1,40 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use Predis\Client;
use Predis\Command\Argument\Search\SchemaFields\TextField;
use Predis\Command\Argument\Search\SpellcheckArguments;
require __DIR__ . '/../../shared.php';
// Example of FT.SPELLCHECK command usage:
// 1. Create index
$client = new Client();
$schema = [
new TextField('text_field'),
];
$client->ftcreate('index_spellcheck', $schema);
// 2. Add dictionary with terms
$client->ftdictadd('dict', 'hello', 'help');
// 3. Perform spelling correction query
$response = $client->ftspellcheck(
'index_spellcheck',
'held',
(new SpellcheckArguments())->distance(2)->terms('dict')
);
echo 'Response:' . "\n";
print_r($response);
@@ -0,0 +1,39 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use Predis\Client;
use Predis\Command\Argument\Search\SugAddArguments;
use Predis\Command\Argument\Search\SugGetArguments;
require __DIR__ . '/../../shared.php';
// Example of FT.SUGADD, FT.SUGGET, FT.SUGDEL, FT.SUGLEN commands usage:
// 1. Add suggestion to key with payload
$client = new Client();
$client->ftsugadd('key', 'hello', 2, (new SugAddArguments())->payload('payload'));
echo 'Suggestions dictionary length: ' . $client->ftsuglen('key') . "\n";
// 2. Perform fuzzy search by prefix to get previous suggestion with payload
$response = $client->ftsugget('key', 'hellp', (new SugGetArguments())->fuzzy()->withPayloads());
echo 'Suggestion for "hellp" prefix:' . "\n";
print_r($response);
// 3. Removes previous suggestion from key
$client->ftsugdel('key', 'hello');
$response = $client->ftsugget('key', 'hello');
echo 'Suggestions, after removing "hello" suggestion:' . "\n";
print_r($response);
+35
View File
@@ -0,0 +1,35 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use Predis\Client;
use Predis\Command\Argument\Search\SchemaFields\TextField;
require __DIR__ . '/../../shared.php';
// Example of FT.SYNDUMP command usage:
// 1. Create index
$client = new Client();
$schema = [
new TextField('text_field'),
];
$client->ftcreate('index_syndump', $schema);
// 2. Add synonyms group with terms
$client->ftsynupdate('index_syndump', 'synonym1', null, 'term1', 'term2');
// 3. Dump terms with synonyms
$response = $client->ftsyndump('index_syndump');
echo 'Response:' . "\n";
print_r($response);
+32
View File
@@ -0,0 +1,32 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use Predis\Client;
use Predis\Command\Argument\Search\SchemaFields\TextField;
require __DIR__ . '/../../shared.php';
// Example of FT.SYNUPDATE command usage:
// 1. Create index
$client = new Client();
$schema = [
new TextField('text_field'),
];
$client->ftcreate('index_synupdate', $schema);
// 2. Add synonyms into synonym group
$response = $client->ftsynupdate('index_synupdate', 'synonym1', null, 'term1', 'term2');
echo 'Response:' . "\n";
print_r($response);
+37
View File
@@ -0,0 +1,37 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use Predis\Client;
use Predis\Command\Argument\Search\CreateArguments;
use Predis\Command\Argument\Search\SchemaFields\TagField;
require __DIR__ . '/../../shared.php';
// Example of FT.TAGVALS command usage:
// 1. Create index
$client = new Client();
$schema = [
new TagField('tag_field'),
];
$client->ftcreate('index_tagvals', $schema, (new CreateArguments())->prefix(['prefix:']));
// 2. Add indexed tags
$client->hset('prefix:1', 'tag_field', 'Hello, World');
$client->hset('prefix:2', 'tag_field', 'Hey, World');
// 3. Unique tags value query
$response = $client->fttagvals('index_tagvals', 'tag_field');
echo 'Response:' . "\n";
print_r($response);
+38
View File
@@ -0,0 +1,38 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use Predis\Client;
use Predis\Command\Argument\TimeSeries\AddArguments;
use Predis\Command\Argument\TimeSeries\CommonArguments;
use Predis\Command\Argument\TimeSeries\CreateArguments;
require __DIR__ . '/../../shared.php';
// Example of TS.ADD command usage:
// 1. Create time series
$client = new Client();
$arguments = (new CreateArguments())
->retentionMsecs(60000)
->duplicatePolicy(CommonArguments::POLICY_MAX)
->labels('sensor_id', 2, 'area_id', 32);
$client->tscreate('temperature:2:32', $arguments);
// 2. Add sample into newly created time series
$addArguments = (new AddArguments())
->retentionMsecs(31536000000);
$response = $client->tsadd('temperature:2:32', 123123123123, 27, $addArguments);
echo "Timeseries was added with timestamp: {$response}";
+41
View File
@@ -0,0 +1,41 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use Predis\Client;
use Predis\Command\Argument\TimeSeries\AlterArguments;
use Predis\Command\Argument\TimeSeries\CommonArguments;
use Predis\Command\Argument\TimeSeries\CreateArguments;
require __DIR__ . '/../../shared.php';
// Example of TS.ALTER command usage:
// 1. Create time series
$client = new Client();
$arguments = (new CreateArguments())
->retentionMsecs(60000)
->duplicatePolicy(CommonArguments::POLICY_MAX)
->labels('sensor_id', 2, 'area_id', 32);
$response = $client->tscreate('temperature:2:32', $arguments);
echo "Time series creation status: {$response}\n";
// 2. Update Duplicate policy for time series above
$arguments = (new AlterArguments())
->duplicatePolicy(CommonArguments::POLICY_FIRST);
$response = $client->tsalter('temperature:2:32', $arguments);
$output = ($response == 'OK') ? 'Duplicate policy was successfully updated' : $response;
echo $output;
@@ -0,0 +1,31 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use Predis\Client;
use Predis\Command\Argument\TimeSeries\CommonArguments;
use Predis\Command\Argument\TimeSeries\CreateArguments;
require __DIR__ . '/../../shared.php';
// Example of TS.CREATE command usage:
// Create time series
$client = new Client();
$arguments = (new CreateArguments())
->retentionMsecs(60000)
->duplicatePolicy(CommonArguments::POLICY_MAX)
->labels('sensor_id', 2, 'area_id', 32);
$response = $client->tscreate('temperature:2:32', $arguments);
echo "Time series creation status: {$response}";
@@ -0,0 +1,33 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use Predis\Client;
use Predis\Command\Argument\TimeSeries\CreateArguments;
require __DIR__ . '/../../shared.php';
// Example of TS.CREATERULE command usage:
// 1. Create time series
$client = new Client();
$arguments = (new CreateArguments())
->labels('type', 'temp', 'location', 'TLV');
$createResponse = $client->tscreate('temp:TLV', $arguments);
echo "Original time series creation status: {$createResponse}\n";
$createResponse = $client->tscreate('dailyAvgTemp:TLV', $arguments);
echo "Compacted time series creation status: {$createResponse}\n";
$createRuleResponse = $client->tscreaterule('temp:TLV', 'dailyAvgTemp:TLV', 'avg', 1000);
echo "Compacted rule for compacted time series creation status: {$createRuleResponse}\n";
@@ -0,0 +1,45 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use Predis\Client;
use Predis\Command\Argument\TimeSeries\AddArguments;
use Predis\Command\Argument\TimeSeries\CommonArguments;
use Predis\Command\Argument\TimeSeries\CreateArguments;
use Predis\Command\Argument\TimeSeries\DecrByArguments;
require __DIR__ . '/../../shared.php';
// Example of TS.DECRBY command usage:
// 1. Create time series
$client = new Client();
$arguments = (new CreateArguments())
->retentionMsecs(60000)
->duplicatePolicy(CommonArguments::POLICY_MAX)
->labels('sensor_id', 2, 'area_id', 32);
$client->tscreate('temperature:2:32', $arguments);
// 2. Add sample into newly created time series
$addArguments = (new AddArguments())
->retentionMsecs(31536000000);
$response = $client->tsadd('temperature:2:32', 123123123123, 27, $addArguments);
echo "Timeseries was added with timestamp: {$response}\n";
// 3. Increasing value and timestamp
$client->tsdecrby('temperature:2:32', 1, (new DecrByArguments())->timestamp(123123123124));
$response = $client->tsget('temperature:2:32');
echo "Decreased value to - {$response[1]} and timestamp to {$response[0]}";
+47
View File
@@ -0,0 +1,47 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use Predis\Client;
use Predis\Command\Argument\TimeSeries\CommonArguments;
use Predis\Command\Argument\TimeSeries\CreateArguments;
require __DIR__ . '/../../shared.php';
// Example of TS.GET command usage:
// 1. Create time series
$client = new Client();
$arguments = (new CreateArguments())
->retentionMsecs(60000)
->duplicatePolicy(CommonArguments::POLICY_MAX)
->labels('sensor_id', 2, 'area_id', 32);
$client->tscreate('temperature:2:32', $arguments);
// 2. Add samples into time series
$client->tsadd('temperature:2:32', 123123123123, 27);
$client->tsadd('temperature:2:32', 123123123124, 28);
$client->tsadd('temperature:2:32', 123123123125, 29);
$response = $client->tsget('temperature:2:32');
echo "Sample with highest timestamp - {$response[0]} and value {$response[1]}\n";
// 3. Removes 2 samples with the highest timestamps
$response = $client->tsdel('temperature:2:32', 123123123124, 123123123125);
echo "Removed {$response} samples from timeseries.\n";
// 3. Retrieve a timestamp with the highest timestamp
$response = $client->tsget('temperature:2:32');
echo "New sample with highest timestamp - {$response[0]} and value {$response[1]}";
@@ -0,0 +1,37 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use Predis\Client;
use Predis\Command\Argument\TimeSeries\CreateArguments;
require __DIR__ . '/../../shared.php';
// Example of TS.CREATERULE command usage:
// 1. Create time series
$client = new Client();
$arguments = (new CreateArguments())
->labels('type', 'temp', 'location', 'TLV');
$createResponse = $client->tscreate('temp:TLV', $arguments);
echo "Original time series creation status: {$createResponse}\n";
$createResponse = $client->tscreate('dailyAvgTemp:TLV', $arguments);
echo "Compacted time series creation status: {$createResponse}\n";
$createRuleResponse = $client->tscreaterule('temp:TLV', 'dailyAvgTemp:TLV', 'avg', 1000);
echo "Compacted rule for compacted time series creation status: {$createRuleResponse}\n";
// 2. Remove compaction rule
$deleteRuleResponse = $client->tsdeleterule('temp:TLV', 'dailyAvgTemp:TLV');
echo "Compacted rule for compacted time series deletion status: {$deleteRuleResponse}\n";
+38
View File
@@ -0,0 +1,38 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use Predis\Client;
use Predis\Command\Argument\TimeSeries\CommonArguments;
use Predis\Command\Argument\TimeSeries\CreateArguments;
require __DIR__ . '/../../shared.php';
// Example of TS.GET command usage:
// 1. Create time series
$client = new Client();
$arguments = (new CreateArguments())
->retentionMsecs(60000)
->duplicatePolicy(CommonArguments::POLICY_MAX)
->labels('sensor_id', 2, 'area_id', 32);
$client->tscreate('temperature:2:32', $arguments);
// 2. Add samples into time series
$client->tsadd('temperature:2:32', 123123123123, 27);
$client->tsadd('temperature:2:32', 123123123124, 28);
$client->tsadd('temperature:2:32', 123123123125, 29);
// 3. Retrieve a timestamp with highest timestamp
$response = $client->tsget('temperature:2:32');
echo "Sample with highest timestamp - {$response[0]} and value - {$response[1]}";
@@ -0,0 +1,45 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use Predis\Client;
use Predis\Command\Argument\TimeSeries\AddArguments;
use Predis\Command\Argument\TimeSeries\CommonArguments;
use Predis\Command\Argument\TimeSeries\CreateArguments;
use Predis\Command\Argument\TimeSeries\IncrByArguments;
require __DIR__ . '/../../shared.php';
// Example of TS.INCRBY command usage:
// 1. Create time series
$client = new Client();
$arguments = (new CreateArguments())
->retentionMsecs(60000)
->duplicatePolicy(CommonArguments::POLICY_MAX)
->labels('sensor_id', 2, 'area_id', 32);
$client->tscreate('temperature:2:32', $arguments);
// 2. Add sample into newly created time series
$addArguments = (new AddArguments())
->retentionMsecs(31536000000);
$response = $client->tsadd('temperature:2:32', 123123123123, 27, $addArguments);
echo "Timeseries was added with timestamp: {$response}\n";
// 3. Increasing value and timestamp
$client->tsincrby('temperature:2:32', 1, (new IncrByArguments())->timestamp(123123123124));
$response = $client->tsget('temperature:2:32');
echo "Increased value to - {$response[1]} and timestamp to {$response[0]}";
+32
View File
@@ -0,0 +1,32 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use Predis\Client;
use Predis\Command\Argument\TimeSeries\CommonArguments;
use Predis\Command\Argument\TimeSeries\CreateArguments;
require __DIR__ . '/../../shared.php';
// Example of TS.CREATE command usage:
// 1. Create time series
$client = new Client();
$arguments = (new CreateArguments())
->retentionMsecs(60000)
->duplicatePolicy(CommonArguments::POLICY_MAX)
->labels('sensor_id', 2, 'area_id', 32);
$client->tscreate('temperature:2:32', $arguments);
// 2. Show info about given time series
print_r($client->tsinfo('temperature:2:32'));
+36
View File
@@ -0,0 +1,36 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use Predis\Client;
use Predis\Command\Argument\TimeSeries\CommonArguments;
use Predis\Command\Argument\TimeSeries\CreateArguments;
require __DIR__ . '/../../shared.php';
// Example of TS.MADD command usage:
// 1. Create time series
$client = new Client();
$arguments = (new CreateArguments())
->retentionMsecs(60000)
->duplicatePolicy(CommonArguments::POLICY_MAX)
->labels('sensor_id', 2, 'area_id', 32);
$client->tscreate('temperature:2:32', $arguments);
$client->tscreate('temperature:2:33', $arguments);
// 2. Add samples into few time series
$response = $client->tsmadd('temperature:2:32', 123123123123, 27, 'temperature:2:33', 123123123124, 28);
$stringResponse = implode(', ', $response);
echo "Samples was added to time series - timestamps: {$stringResponse}";
+41
View File
@@ -0,0 +1,41 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use Predis\Client;
use Predis\Command\Argument\TimeSeries\CommonArguments;
use Predis\Command\Argument\TimeSeries\CreateArguments;
use Predis\Command\Argument\TimeSeries\MGetArguments;
require __DIR__ . '/../../shared.php';
// Example of TS.MGET command usage:
// 1. Create time series
$client = new Client();
$arguments = (new CreateArguments())
->retentionMsecs(60000)
->duplicatePolicy(CommonArguments::POLICY_MAX)
->labels('type', 'temp', 'sensor_id', 2, 'area_id', 32);
$client->tscreate('temperature:2:32', $arguments);
$client->tscreate('temperature:2:33', $arguments);
// 2. Add samples into time series
$client->tsadd('temperature:2:32', 123123123123, 27);
$client->tsadd('temperature:2:33', 123123123124, 27);
// 3. Get sample from multiple time series matching given filter expression, with selected labels only
$response = $client->tsmget((new MGetArguments())->selectedLabels('type'), 'type=temp');
echo "Sample from time series, with label = 'type':\n";
print_r($response);
@@ -0,0 +1,48 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use Predis\Client;
use Predis\Command\Argument\TimeSeries\CreateArguments;
use Predis\Command\Argument\TimeSeries\MRangeArguments;
require __DIR__ . '/../../shared.php';
// Example of TS.MRANGE command usage:
// 1. Create time series
$client = new Client();
$response = $client->tscreate('stock:A', (new CreateArguments())->labels('type', 'stock', 'name', 'A'));
echo "Time series A creation status: {$response}\n";
$response = $client->tscreate('stock:B', (new CreateArguments())->labels('type', 'stock', 'name', 'B'));
echo "Time series B creation status: {$response}\n";
// 2. Add samples into both time series
$response = $client->tsmadd('stock:A', 1000, 100, 'stock:A', 1010, 110, 'stock:A', 1020, 120);
$stringResponse = implode(', ', $response);
echo "Added samples into time series A with following timestamps: {$stringResponse}\n";
$response = $client->tsmadd('stock:B', 1000, 120, 'stock:B', 1010, 110, 'stock:B', 1020, 100);
$stringResponse = implode(', ', $response);
echo "Added samples into time series B with following timestamps: {$stringResponse}\n";
// 3. Query range across both time series filtered by "type" and grouped by max type
$mrangeArguments = (new MRangeArguments())
->withLabels()
->filter('type=stock')
->groupBy('type', 'max');
$response = $client->tsmrange('-', '+', $mrangeArguments);
echo "Response:\n";
print_r($response);
@@ -0,0 +1,48 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use Predis\Client;
use Predis\Command\Argument\TimeSeries\CreateArguments;
use Predis\Command\Argument\TimeSeries\MRangeArguments;
require __DIR__ . '/../../shared.php';
// Example of TS.MREVRANGE command usage:
// 1. Create time series
$client = new Client();
$response = $client->tscreate('stock:A', (new CreateArguments())->labels('type', 'stock', 'name', 'A'));
echo "Time series A creation status: {$response}\n";
$response = $client->tscreate('stock:B', (new CreateArguments())->labels('type', 'stock', 'name', 'B'));
echo "Time series B creation status: {$response}\n";
// 2. Add samples into both time series
$response = $client->tsmadd('stock:A', 1000, 100, 'stock:A', 1010, 110, 'stock:A', 1020, 120);
$stringResponse = implode(', ', $response);
echo "Added samples into time series A with following timestamps: {$stringResponse}\n";
$response = $client->tsmadd('stock:B', 1000, 120, 'stock:B', 1010, 110, 'stock:B', 1020, 100);
$stringResponse = implode(', ', $response);
echo "Added samples into time series B with following timestamps: {$stringResponse}\n";
// 3. Query range across both time series filtered by "type" and grouped by max type
$mrangeArguments = (new MRangeArguments())
->withLabels()
->filter('type=stock')
->groupBy('type', 'max');
$response = $client->tsmrevrange('-', '+', $mrangeArguments);
echo "Response:\n";
print_r($response);
@@ -0,0 +1,36 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use Predis\Client;
use Predis\Command\Argument\TimeSeries\CreateArguments;
require __DIR__ . '/../../shared.php';
// Example of TS.QUERYINDEX command usage:
// 1. Create time series
$client = new Client();
$arguments = (new CreateArguments())
->labels('type', 'temp', 'location', 'TLV');
$createResponse = $client->tscreate('temp:TLV', $arguments);
echo "Time series with location TLV creation status: {$createResponse}\n";
$anotherArguments = (new CreateArguments())
->labels('type', 'temp', 'location', 'JER');
$createResponse = $client->tscreate('temp:JER', $anotherArguments);
echo "Time series with location JER creation status: {$createResponse}\n";
echo "Returns all keys with location=TLV:\n";
print_r($client->tsqueryindex('location=TLV'));
+40
View File
@@ -0,0 +1,40 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use Predis\Client;
use Predis\Command\Argument\TimeSeries\CreateArguments;
use Predis\Command\Argument\TimeSeries\RangeArguments;
require __DIR__ . '/../../shared.php';
// Example of TS.RANGE command usage:
// 1. Create time series
$client = new Client();
$createArguments = (new CreateArguments())->labels('type', 'temp', 'location', 'TLV');
$createResponse = $client->tscreate('temp:TLV', $createArguments);
echo "Time series creation status: {$createResponse}\n";
// 2. Add samples into time series
$maddResponse = $client->tsmadd('temp:TLV', 1000, 30, 'temp:TLV', 1010, 35, 'temp:TLV', 1020, 9999, 'temp:TLV', 1030, 40);
$stringResponse = implode(', ', $maddResponse);
echo "Samples was added with following timestamps: {$stringResponse}\n";
// 3. Query samples by values in the given range
$rangeArguments = (new RangeArguments())->filterByValue(-100, 100);
$rangeResponse = $client->tsrange('temp:TLV', '-', '+', $rangeArguments);
echo "Samples with temperature in range -100 to 100 degrees:\n";
print_r($rangeResponse);
@@ -0,0 +1,40 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use Predis\Client;
use Predis\Command\Argument\TimeSeries\CreateArguments;
use Predis\Command\Argument\TimeSeries\RangeArguments;
require __DIR__ . '/../../shared.php';
// Example of TS.REVRANGE command usage:
// 1. Create time series
$client = new Client();
$createArguments = (new CreateArguments())->labels('type', 'temp', 'location', 'TLV');
$createResponse = $client->tscreate('temp:TLV', $createArguments);
echo "Time series creation status: {$createResponse}\n";
// 2. Add samples into time series
$maddResponse = $client->tsmadd('temp:TLV', 1000, 30, 'temp:TLV', 1010, 35, 'temp:TLV', 1020, 9999, 'temp:TLV', 1030, 40);
$stringResponse = implode(', ', $maddResponse);
echo "Samples was added with following timestamps: {$stringResponse}\n";
// 3. Query samples by values in the given range
$rangeArguments = (new RangeArguments())->filterByValue(-100, 100);
$rangeResponse = $client->tsrevrange('temp:TLV', '-', '+', $rangeArguments);
echo "Samples with temperature in range -100 to 100 degrees in reverse order:\n";
print_r($rangeResponse);
+36
View File
@@ -0,0 +1,36 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use Predis\Client;
require __DIR__ . '/../shared.php';
// Example of ACL DRYRUN command usage:
// 1. Set user with permissions to call only 'SET' command.
$client = new Client($single_server);
$response = $client->acl->setUser('Test_dry', '+SET', '~*');
$created = ($response == 'OK') ? 'Yes' : 'No';
echo "User with username 'Test' was created: {$created}. Permissions only to use SET command\n";
// 2. Dry run 'SET' command under 'Test_dry' user
$response = $client->acl->dryRun('Test_dry', 'SET', 'foo', 'bar');
echo 'Dry run "SET" command.' . "\n";
echo 'Response: ' . $response . "\n";
// 3. Dry run 'GET' command under 'Test_dry' user
$response = $client->acl->dryRun('Test_dry', 'GET', 'foo');
echo 'Dry run "GET" command.' . "\n";
echo 'Response: ' . $response;
+28
View File
@@ -0,0 +1,28 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use Predis\Client;
require __DIR__ . '/../shared.php';
// Example of ACL GETUSER command usage:
// 1. Set user
$client = new Client($single_server);
$response = $client->acl->setUser('Test');
// 2. Retrieve user rules:
echo 'Rules: ' . "\n";
print_r(
$client->acl->getUser('Test')
);
+24
View File
@@ -0,0 +1,24 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use Predis\Client;
require __DIR__ . '/../shared.php';
// Example of ACL SETUSER command usage:
// 1. Set user
$client = new Client($single_server);
$response = $client->acl->setUser('Test');
$created = ($response == 'OK') ? 'Yes' : 'No';
echo "User with username 'Test' was created: {$created}";
+43
View File
@@ -0,0 +1,43 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use Predis\Client;
require __DIR__ . '/../shared.php';
// Example of FCALL_RO command usage:
// 1. Set key-value pair
$client = new Client($single_server);
$client->set('foo', 'bar');
echo "Set key 'foo' with value 'bar'\n";
// 2. Load redis function with 'no-writes' flag
$client->function->load(
"#!lua name=mylib
redis.register_function{
function_name='myfunc',
callback=function(keys, args) return redis.call('GET', keys[1]) end,
flags={'no-writes'}
}"
);
echo 'Loaded custom function that perform GET command against provided key.' . "\n";
// 3. Call function above with given key
$response = $client->fcall_ro('myfunc', ['foo']);
echo "Function returned value against provided key 'foo' is '{$response}'";
// 4. Delete test library
$client->function->delete('mylib');
+3 -3
View File
@@ -24,10 +24,10 @@ $pubsub = $client->pubSubLoop();
// Subscribe to your channels
$pubsub->subscribe('control_channel', 'notifications');
// Start processing the pubsup messages. Open a terminal and use redis-cli
// Start processing the pubsub messages. Open a terminal and use redis-cli
// to push messages to the channels. Examples:
// ./redis-cli PUBLISH notifications "this is a test"
// ./redis-cli PUBLISH control_channel quit_loop
// redis-cli PUBLISH notifications "this is a test"
// redis-cli PUBLISH control_channel quit_loop
foreach ($pubsub as $message) {
switch ($message->kind) {
case 'subscribe':
+51
View File
@@ -0,0 +1,51 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
require __DIR__ . '/shared.php';
// Enable igbinary serializer as well as LZ4 compression
$options = [
'serializer' => 'igbinary',
'compression' => 'lz4',
];
$client = new Predis\Client($single_server + $options, [
'connections' => 'relay',
]);
$quote = (object) [
'author' => 'Jean-Luc Picard',
'text' => 'I look forward to your report Mr. Broccoli.',
];
// Serialize object and apply LZ4 compression, then write key to Redis
$client->set('quote', $client->pack($quote));
// NOTE: In Predis v3.x serialization and compression will happen
// automatically without the need to call `pack()` and `unpack()`
// Retrieve raw binary value from Redis
$raw = $client->get('quote');
// Decompress and unserialize binary value
$data = $client->unpack($raw);
var_dump($quote == $data); // true
var_dump($data);
/*
object(stdClass)#11 (2) {
["author"]=>string(15) "Jean-Luc Picard"
["text"]=>string(43) "I look forward to your report Mr. Broccoli."
}
*/
+55
View File
@@ -0,0 +1,55 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
require __DIR__ . '/shared.php';
$options = [
'timeout' => 1.0,
'read_write_timeout' => 1.0,
// Relay specific options
'cache' => true,
// 'compression' => 'lz4',
// 'serializer' => 'igbinary',
];
$client = new Predis\Client($single_server + $options, [
'connections' => 'relay',
]);
// Write key to Redis
$client->set('torpedo', mt_rand());
// Retrieve key from Redis
$client->get('torpedo');
// Retrieve key from Relay (without talking to Redis)
// This key is now available to all PHP workers in this FPM pool
$client->get('torpedo');
// For debugging only:
var_export(
$client->getConnection()->getClient()->_getKeys()
);
/*
array (
'torpedo' => array (
0 => array (
'type' => 'string',
'local-len' => 10,
'remote-len' => 10,
'size' => 10,
),
),
)
*/
+61
View File
@@ -0,0 +1,61 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
require __DIR__ . '/shared.php';
$key = null;
$client = new Predis\Client($single_server, [
'connections' => 'relay',
]);
/** @var Predis\Connection\RelayConnection $relay */
$relay = $client->getConnection();
// establish connection
$client->ping();
// register `FLUSH*` callback
$relay->onFlushed(
static function (Relay\Event $event) use (&$key) {
echo 'Redis was flushed, unsetting $key...' . PHP_EOL;
$key = null;
}
);
// register `INVALIDATE` callback
$relay->onInvalidated(
static function (Relay\Event $event) use (&$key) {
if ($event->key === 'library') {
echo "The `{$event->key}` key was invalidated, unsetting \$key..." . PHP_EOL;
$key = null;
}
}
);
// Write key to Redis
$client->set('library', mt_rand());
// Retrieve key once from Redis, then cached in Relay and $key
$key = $client->get('library');
while (true) {
echo '$key is: ' . var_export($key, true) . PHP_EOL;
// To trigger our event callbacks, we need to either interact with Relay:
$client->get(mt_rand());
// ... or alternatively dispatch events directly on Relay:
$relay->dispatchEvents();
sleep(1);
}
+59
View File
@@ -0,0 +1,59 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
require __DIR__ . '/shared.php';
// Create a Relay client and disable r/w timeout on the connection
$client = new Predis\Client(
$single_server + ['read_write_timeout' => 0],
['connections' => 'relay']
);
// Initialize a new pubsub consumer.
$pubsub = $client->pubSubLoop();
// When using Relay you cannot use foreach-loops to iterate
// over messages instead use a callback function
$poorMansKafka = function ($message, $client) {
switch ($message->kind) {
case 'subscribe':
echo "Subscribed to {$message->channel}", PHP_EOL;
break;
case 'message':
case 'pmessage':
if ($message->channel == 'control_channel') {
if ($message->payload == 'quit_loop') {
echo 'Aborting pubsub loop...', PHP_EOL;
$client->unsubscribe();
} else {
echo "Received an unrecognized command: {$message->payload}.", PHP_EOL;
}
} else {
echo "Received the message from `{$message->channel}` channel:",
PHP_EOL, " {$message->payload}", PHP_EOL, PHP_EOL;
}
}
};
// Subscribe to your channels and start processing the messages.
$pubsub->subscribe('control_channel', 'notifications', $poorMansKafka);
// Open a terminal and use redis-cli to push messages to the channels. Examples:
// redis-cli PUBLISH notifications "this is a test"
// redis-cli PUBLISH control_channel quit_loop
// When using Relay, there is no need to unset the pubsub consumer instance when you are done
// Say goodbye :-)
$version = redis_version($client->info());
echo "Goodbye from Redis $version!", PHP_EOL;
+42
View File
@@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit
bootstrap="tests/bootstrap.php"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnError="false"
stopOnFailure="false"
beStrictAboutTestsThatDoNotTestAnything="true"
>
<testsuites>
<testsuite name="Predis Test Suite">
<directory phpVersion="7.4">tests/Predis/</directory>
</testsuite>
</testsuites>
<groups>
<exclude>
<group>relay-incompatible</group>
<group>realm-webdis</group>
<group>realm-stack</group>
<group>ext-curl</group>
<group>ext-phpiredis</group>
</exclude>
</groups>
<filter>
<whitelist>
<directory suffix=".php">src/</directory>
</whitelist>
</filter>
<php>
<const name="REDIS_SERVER_HOST" value="127.0.0.1" />
<const name="REDIS_SERVER_PORT" value="6379" />
<const name="REDIS_SERVER_DBNUM" value="0" />
<env name="USE_RELAY" value="true" />
</php>
</phpunit>
+6 -8
View File
@@ -28,9 +28,11 @@
<groups>
<exclude>
<group>ext-phpiredis</group>
<group>ext-curl</group>
<group>realm-webdis</group>
<group>realm-stack</group>
<group>ext-relay</group>
<group>ext-curl</group>
<group>ext-phpiredis</group>
<!-- <group>connected</group> -->
<!-- <group>disconnected</group> -->
<!-- <group>commands</group> -->
@@ -45,13 +47,9 @@
</filter>
<php>
<!-- Redis -->
<const name="REDIS_SERVER_HOST" value="127.0.0.1" />
<const name="REDIS_SERVER_PORT" value="6379" />
<const name="REDIS_SERVER_DBNUM" value="15" />
<!-- Webdis -->
<const name="WEBDIS_SERVER_HOST" value="127.0.0.1" />
<const name="WEBDIS_SERVER_PORT" value="7379" />
<const name="REDIS_SERVER_DBNUM" value="0" />
<env name="USE_RELAY" value="false" />
</php>
</phpunit>
+60 -14
View File
@@ -25,9 +25,15 @@ use Predis\Configuration\OptionsInterface;
use Predis\Connection\ConnectionInterface;
use Predis\Connection\Parameters;
use Predis\Connection\ParametersInterface;
use Predis\Connection\RelayConnection;
use Predis\Monitor\Consumer as MonitorConsumer;
use Predis\Pipeline\Atomic;
use Predis\Pipeline\FireAndForget;
use Predis\Pipeline\Pipeline;
use Predis\Pipeline\RelayAtomic;
use Predis\Pipeline\RelayPipeline;
use Predis\PubSub\Consumer as PubSubConsumer;
use Predis\PubSub\RelayConsumer as RelayPubSubConsumer;
use Predis\Response\ErrorInterface as ErrorResponseInterface;
use Predis\Response\ResponseInterface;
use Predis\Response\ServerException;
@@ -47,7 +53,7 @@ use Traversable;
*/
class Client implements ClientInterface, IteratorAggregate
{
public const VERSION = '2.1.2';
public const VERSION = '2.2.0-RC1';
/** @var OptionsInterface */
private $options;
@@ -262,6 +268,32 @@ class Client implements ClientInterface, IteratorAggregate
return $this->connection;
}
/**
* Applies the configured serializer and compression to given value.
*
* @param mixed $value
* @return string
*/
public function pack($value)
{
return $this->connection instanceof RelayConnection
? $this->connection->pack($value)
: $value;
}
/**
* Deserializes and decompresses to given value.
*
* @param mixed $value
* @return string
*/
public function unpack($value)
{
return $this->connection instanceof RelayConnection
? $this->connection->unpack($value)
: $value;
}
/**
* Executes a command without filtering its arguments, parsing the response,
* applying any prefix to keys or throwing exceptions on Redis errors even
@@ -314,29 +346,29 @@ class Client implements ClientInterface, IteratorAggregate
}
/**
* @param $name
* @param string $name
* @return ContainerInterface
*/
public function __get($name)
public function __get(string $name)
{
return ContainerFactory::create($this, $name);
}
/**
* @param $name
* @param $value
* @param string $name
* @param mixed $value
* @return mixed
*/
public function __set($name, $value)
public function __set(string $name, $value)
{
throw new RuntimeException('Not allowed');
}
/**
* @param $name
* @param string $name
* @return mixed
*/
public function __isset($name)
public function __isset(string $name)
{
throw new RuntimeException('Not allowed');
}
@@ -435,19 +467,29 @@ class Client implements ClientInterface, IteratorAggregate
/**
* Actual pipeline context initializer method.
*
* @param array $options Options for the context.
* @param mixed $callable Optional callable used to execute the context.
* @param array|null $options Options for the context.
* @param mixed $callable Optional callable used to execute the context.
*
* @return Pipeline|array
*/
protected function createPipeline(array $options = null, $callable = null)
{
if (isset($options['atomic']) && $options['atomic']) {
$class = 'Predis\Pipeline\Atomic';
$class = Atomic::class;
} elseif (isset($options['fire-and-forget']) && $options['fire-and-forget']) {
$class = 'Predis\Pipeline\FireAndForget';
$class = FireAndForget::class;
} else {
$class = 'Predis\Pipeline\Pipeline';
$class = Pipeline::class;
}
if ($this->connection instanceof RelayConnection) {
if (isset($options['atomic']) && $options['atomic']) {
$class = RelayAtomic::class;
} elseif (isset($options['fire-and-forget']) && $options['fire-and-forget']) {
throw new NotSupportedException('The "relay" extension does not support fire-and-forget pipelines.');
} else {
$class = RelayPipeline::class;
}
}
/*
@@ -517,7 +559,11 @@ class Client implements ClientInterface, IteratorAggregate
*/
protected function createPubSub(array $options = null, $callable = null)
{
$pubsub = new PubSubConsumer($this, $options);
if ($this->connection instanceof RelayConnection) {
$pubsub = new RelayPubSubConsumer($this, $options);
} else {
$pubsub = new PubSubConsumer($this, $options);
}
if (!isset($callable)) {
return $pubsub;
+42
View File
@@ -0,0 +1,42 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Predis;
class ClientConfiguration
{
/**
* @var array{modules: array}|string[][]
*/
private static $config = [
'modules' => [
['name' => 'Json', 'commandPrefix' => 'JSON'],
['name' => 'BloomFilter', 'commandPrefix' => 'BF'],
['name' => 'CuckooFilter', 'commandPrefix' => 'CF'],
['name' => 'CountMinSketch', 'commandPrefix' => 'CMS'],
['name' => 'TDigest', 'commandPrefix' => 'TDIGEST'],
['name' => 'TopK', 'commandPrefix' => 'TOPK'],
['name' => 'Search', 'commandPrefix' => 'FT'],
['name' => 'TimeSeries', 'commandPrefix' => 'TS'],
],
];
/**
* Returns available modules with configuration.
*
* @return array|string[][]
*/
public static function getModules(): array
{
return self::$config['modules'];
}
}
+139 -1
View File
@@ -14,10 +14,35 @@ namespace Predis;
use Predis\Command\Argument\Geospatial\ByInterface;
use Predis\Command\Argument\Geospatial\FromInterface;
use Predis\Command\Argument\Search\AggregateArguments;
use Predis\Command\Argument\Search\AlterArguments;
use Predis\Command\Argument\Search\CreateArguments;
use Predis\Command\Argument\Search\DropArguments;
use Predis\Command\Argument\Search\ExplainArguments;
use Predis\Command\Argument\Search\ProfileArguments;
use Predis\Command\Argument\Search\SchemaFields\FieldInterface;
use Predis\Command\Argument\Search\SearchArguments;
use Predis\Command\Argument\Search\SugAddArguments;
use Predis\Command\Argument\Search\SugGetArguments;
use Predis\Command\Argument\Search\SynUpdateArguments;
use Predis\Command\Argument\Server\LimitOffsetCount;
use Predis\Command\Argument\Server\To;
use Predis\Command\Argument\TimeSeries\AddArguments;
use Predis\Command\Argument\TimeSeries\AlterArguments as TSAlterArguments;
use Predis\Command\Argument\TimeSeries\CreateArguments as TSCreateArguments;
use Predis\Command\Argument\TimeSeries\DecrByArguments;
use Predis\Command\Argument\TimeSeries\GetArguments;
use Predis\Command\Argument\TimeSeries\IncrByArguments;
use Predis\Command\Argument\TimeSeries\InfoArguments;
use Predis\Command\Argument\TimeSeries\MGetArguments;
use Predis\Command\Argument\TimeSeries\MRangeArguments;
use Predis\Command\Argument\TimeSeries\RangeArguments;
use Predis\Command\CommandInterface;
use Predis\Command\Redis\Container\ACL;
use Predis\Command\Redis\Container\FunctionContainer;
use Predis\Command\Redis\Container\Json\JSONDEBUG;
use Predis\Command\Redis\Container\Search\FTCONFIG;
use Predis\Command\Redis\Container\Search\FTCURSOR;
/**
* Interface defining a client-side context such as a pipeline or transaction.
@@ -45,7 +70,16 @@ use Predis\Command\Redis\Container\FunctionContainer;
* @method $this ttl($key)
* @method $this type($key)
* @method $this append($key, $value)
* @method $this bitcount($key, $start = null, $end = null, string $index = 'byte')
* @method $this bfadd(string $key, $item)
* @method $this bfexists(string $key, $item)
* @method $this bfinfo(string $key, string $modifier = '')
* @method $this bfinsert(string $key, int $capacity = -1, float $error = -1, int $expansion = -1, bool $noCreate = false, bool $nonScaling = false, string ...$item)
* @method $this bfloadchunk(string $key, int $iterator, $data)
* @method $this bfmadd(string $key, ...$item)
* @method $this bfmexists(string $key, ...$item)
* @method $this bfreserve(string $key, float $errorRate, int $capacity, int $expansion = -1, bool $nonScaling = false)
* @method $this bfscandump(string $key, int $iterator)
* @method $this bitcount(string $key, $start = null, $end = null, string $index = 'byte')
* @method $this bitop($operation, $destkey, $key)
* @method $this bitfield($key, $subcommand, ...$subcommandArg)
* @method $this bitpos($key, $bit, $start = null, $end = null, string $index = 'byte')
@@ -53,10 +87,51 @@ use Predis\Command\Redis\Container\FunctionContainer;
* @method $this bzpopmax(array $keys, int $timeout)
* @method $this bzpopmin(array $keys, int $timeout)
* @method $this bzmpop(int $timeout, array $keys, string $modifier = 'min', int $count = 1)
* @method $this cfadd(string $key, $item)
* @method $this cfaddnx(string $key, $item)
* @method $this cfcount(string $key, $item)
* @method $this cfdel(string $key, $item)
* @method $this cfexists(string $key, $item)
* @method $this cfloadchunk(string $key, int $iterator, $data)
* @method $this cfmexists(string $key, ...$item)
* @method $this cfinfo(string $key)
* @method $this cfinsert(string $key, int $capacity = -1, bool $noCreate = false, string ...$item)
* @method $this cfinsertnx(string $key, int $capacity = -1, bool $noCreate = false, string ...$item)
* @method $this cfreserve(string $key, int $capacity, int $bucketSize = -1, int $maxIterations = -1, int $expansion = -1)
* @method $this cfscandump(string $key, int $iterator)
* @method $this cmsincrby(string $key, string|int...$itemIncrementDictionary)
* @method $this cmsinfo(string $key)
* @method $this cmsinitbydim(string $key, int $width, int $depth)
* @method $this cmsinitbyprob(string $key, float $errorRate, float $probability)
* @method $this cmsmerge(string $destination, array $sources, array $weights = [])
* @method $this cmsquery(string $key, string ...$item)
* @method $this decr($key)
* @method $this decrby($key, $decrement)
* @method $this failover(?To $to = null, bool $abort = false, int $timeout = -1)
* @method $this fcall(string $function, array $keys, ...$args)
* @method $this fcall_ro(string $function, array $keys, ...$args)
* @method $this ftaggregate(string $index, string $query, ?AggregateArguments $arguments = null)
* @method $this ftaliasadd(string $alias, string $index)
* @method $this ftaliasdel(string $alias)
* @method $this ftaliasupdate(string $alias, string $index)
* @method $this ftalter(string $index, FieldInterface[] $schema, ?AlterArguments $arguments = null)
* @method $this ftcreate(string $index, FieldInterface[] $schema, ?CreateArguments $arguments = null)
* @method $this ftdictadd(string $dict, ...$term)
* @method $this ftdictdel(string $dict, ...$term)
* @method $this ftdictdump(string $dict)
* @method $this ftdropindex(string $index, ?DropArguments $arguments = null)
* @method $this ftexplain(string $index, string $query, ?ExplainArguments $arguments = null)
* @method $this ftinfo(string $index)
* @method $this ftprofile(string $index, ProfileArguments $arguments)
* @method $this ftsearch(string $index, string $query, ?SearchArguments $arguments = null)
* @method $this ftspellcheck(string $index, string $query, ?SearchArguments $arguments = null)
* @method $this ftsugadd(string $key, string $string, float $score, ?SugAddArguments $arguments = null)
* @method $this ftsugdel(string $key, string $string)
* @method $this ftsugget(string $key, string $prefix, ?SugGetArguments $arguments = null)
* @method $this ftsuglen(string $key)
* @method $this ftsyndump(string $index)
* @method $this ftsynupdate(string $index, string $synonymGroupId, ?SynUpdateArguments $arguments = null, string ...$terms)
* @method $this fttagvals(string $index, string $fieldName)
* @method $this get($key)
* @method $this getbit($key, $offset)
* @method $this getex(string $key, $modifier = '', $value = false)
@@ -92,6 +167,28 @@ use Predis\Command\Redis\Container\FunctionContainer;
* @method $this hsetnx($key, $field, $value)
* @method $this hvals($key)
* @method $this hstrlen($key, $field)
* @method $this jsonarrappend(string $key, string $path = '$', ...$value)
* @method $this jsonarrindex(string $key, string $path, string $value, int $start = 0, int $stop = 0)
* @method $this jsonarrinsert(string $key, string $path, int $index, string ...$value)
* @method $this jsonarrlen(string $key, string $path = '$')
* @method $this jsonarrpop(string $key, string $path = '$', int $index = -1)
* @method $this jsonarrtrim(string $key, string $path, int $start, int $stop)
* @method $this jsonclear(string $key, string $path = '$')
* @method $this jsondel(string $key, string $path = '$')
* @method $this jsonforget(string $key, string $path = '$')
* @method $this jsonget(string $key, string $indent = '', string $newline = '', string $space = '', string ...$paths)
* @method $this jsonnumincrby(string $key, string $path, int $value)
* @method $this jsonmerge(string $key, string $path, string $value)
* @method $this jsonmget(array $keys, string $path)
* @method $this jsonmset(string ...$keyPathValue)
* @method $this jsonobjkeys(string $key, string $path = '$')
* @method $this jsonobjlen(string $key, string $path = '$')
* @method $this jsonresp(string $key, string $path = '$')
* @method $this jsonset(string $key, string $path, string $value, ?string $subcommand = null)
* @method $this jsonstrappend(string $key, string $path, string $value)
* @method $this jsonstrlen(string $key, string $path = '$')
* @method $this jsontoggle(string $key, string $path)
* @method $this jsontype(string $key, string $path = '$')
* @method $this blmove(string $source, string $destination, string $where, string $to, int $timeout)
* @method $this blpop(array|string $keys, $timeout)
* @method $this brpop(array|string $keys, $timeout)
@@ -130,6 +227,43 @@ use Predis\Command\Redis\Container\FunctionContainer;
* @method $this sscan($key, $cursor, array $options = null)
* @method $this sunion(array|string $keys)
* @method $this sunionstore($destination, array|string $keys)
* @method $this tdigestadd(string $key, float ...$value)
* @method $this tdigestbyrank(string $key, int ...$rank)
* @method $this tdigestbyrevrank(string $key, int ...$reverseRank)
* @method $this tdigestcdf(string $key, int ...$value)
* @method $this tdigestcreate(string $key, int $compression = 0)
* @method $this tdigestinfo(string $key)
* @method $this tdigestmax(string $key)
* @method $this tdigestmerge(string $destinationKey, array $sourceKeys, int $compression = 0, bool $override = false)
* @method $this tdigestquantile(string $key, float ...$quantile)
* @method $this tdigestmin(string $key)
* @method $this tdigestrank(string $key, ...$value)
* @method $this tdigestreset(string $key)
* @method $this tdigestrevrank(string $key, float ...$value)
* @method $this tdigesttrimmed_mean(string $key, float $lowCutQuantile, float $highCutQuantile)
* @method $this topkadd(string $key, ...$items)
* @method $this topkincrby(string $key, ...$itemIncrement)
* @method $this topkinfo(string $key)
* @method $this topklist(string $key, bool $withCount = false)
* @method $this topkquery(string $key, ...$items)
* @method $this topkreserve(string $key, int $topK, int $width = 8, int $depth = 7, float $decay = 0.9)
* @method $this tsadd(string $key, int $timestamp, float $value, ?AddArguments $arguments = null)
* @method $this tsalter(string $key, ?TSAlterArguments $arguments = null)
* @method $this tscreate(string $key, ?TSCreateArguments $arguments = null)
* @method $this tscreaterule(string $sourceKey, string $destKey, string $aggregator, int $bucketDuration, int $alignTimestamp = 0)
* @method $this tsdecrby(string $key, float $value, ?DecrByArguments $arguments = null)
* @method $this tsdel(string $key, int $fromTimestamp, int $toTimestamp)
* @method $this tsdeleterule(string $sourceKey, string $destKey)
* @method $this tsget(string $key, GetArguments $arguments = null)
* @method $this tsincrby(string $key, float $value, ?IncrByArguments $arguments = null)
* @method $this tsinfo(string $key, ?InfoArguments $arguments = null)
* @method $this tsmadd(mixed ...$keyTimestampValue)
* @method $this tsmget(MGetArguments $arguments, string ...$filterExpression)
* @method $this tsmrange($fromTimestamp, $toTimestamp, MRangeArguments $arguments)
* @method $this tsmrevrange($fromTimestamp, $toTimestamp, MRangeArguments $arguments)
* @method $this tsqueryindex(string ...$filterExpression)
* @method $this tsrange(string $key, $fromTimestamp, $toTimestamp, ?RangeArguments $arguments = null)
* @method $this tsrevrange(string $key, $fromTimestamp, $toTimestamp, ?RangeArguments $arguments = null)
* @method $this zadd($key, array $membersAndScoresDictionary)
* @method $this zcard($key)
* @method $this zcount($key, $min, $max)
@@ -205,6 +339,10 @@ use Predis\Command\Redis\Container\FunctionContainer;
*
* Container commands
* @property FunctionContainer $function
* @property FTCONFIG $ftconfig
* @property FTCURSOR $ftcursor
* @property JSONDEBUG $jsondebug
* @property ACL $acl
*/
interface ClientContextInterface
{
+138
View File
@@ -14,11 +14,36 @@ namespace Predis;
use Predis\Command\Argument\Geospatial\ByInterface;
use Predis\Command\Argument\Geospatial\FromInterface;
use Predis\Command\Argument\Search\AggregateArguments;
use Predis\Command\Argument\Search\AlterArguments;
use Predis\Command\Argument\Search\CreateArguments;
use Predis\Command\Argument\Search\DropArguments;
use Predis\Command\Argument\Search\ExplainArguments;
use Predis\Command\Argument\Search\ProfileArguments;
use Predis\Command\Argument\Search\SchemaFields\FieldInterface;
use Predis\Command\Argument\Search\SearchArguments;
use Predis\Command\Argument\Search\SugAddArguments;
use Predis\Command\Argument\Search\SugGetArguments;
use Predis\Command\Argument\Search\SynUpdateArguments;
use Predis\Command\Argument\Server\LimitOffsetCount;
use Predis\Command\Argument\Server\To;
use Predis\Command\Argument\TimeSeries\AddArguments;
use Predis\Command\Argument\TimeSeries\AlterArguments as TSAlterArguments;
use Predis\Command\Argument\TimeSeries\CreateArguments as TSCreateArguments;
use Predis\Command\Argument\TimeSeries\DecrByArguments;
use Predis\Command\Argument\TimeSeries\GetArguments;
use Predis\Command\Argument\TimeSeries\IncrByArguments;
use Predis\Command\Argument\TimeSeries\InfoArguments;
use Predis\Command\Argument\TimeSeries\MGetArguments;
use Predis\Command\Argument\TimeSeries\MRangeArguments;
use Predis\Command\Argument\TimeSeries\RangeArguments;
use Predis\Command\CommandInterface;
use Predis\Command\FactoryInterface;
use Predis\Command\Redis\Container\ACL;
use Predis\Command\Redis\Container\FunctionContainer;
use Predis\Command\Redis\Container\Json\JSONDEBUG;
use Predis\Command\Redis\Container\Search\FTCONFIG;
use Predis\Command\Redis\Container\Search\FTCURSOR;
use Predis\Configuration\OptionsInterface;
use Predis\Connection\ConnectionInterface;
use Predis\Response\Status;
@@ -54,6 +79,15 @@ use Predis\Response\Status;
* @method int ttl(string $key)
* @method mixed type(string $key)
* @method int append(string $key, $value)
* @method int bfadd(string $key, $item)
* @method int bfexists(string $key, $item)
* @method array bfinfo(string $key, string $modifier = '')
* @method array bfinsert(string $key, int $capacity = -1, float $error = -1, int $expansion = -1, bool $noCreate = false, bool $nonScaling = false, string ...$item)
* @method Status bfloadchunk(string $key, int $iterator, $data)
* @method array bfmadd(string $key, ...$item)
* @method array bfmexists(string $key, ...$item)
* @method Status bfreserve(string $key, float $errorRate, int $capacity, int $expansion = -1, bool $nonScaling = false)
* @method array bfscandump(string $key, int $iterator)
* @method int bitcount(string $key, $start = null, $end = null, string $index = 'byte')
* @method int bitop($operation, $destkey, $key)
* @method array|null bitfield(string $key, $subcommand, ...$subcommandArg)
@@ -62,10 +96,51 @@ use Predis\Response\Status;
* @method array bzpopmax(array $keys, int $timeout)
* @method array bzpopmin(array $keys, int $timeout)
* @method array bzmpop(int $timeout, array $keys, string $modifier = 'min', int $count = 1)
* @method int cfadd(string $key, $item)
* @method int cfaddnx(string $key, $item)
* @method int cfcount(string $key, $item)
* @method int cfdel(string $key, $item)
* @method int cfexists(string $key, $item)
* @method Status cfloadchunk(string $key, int $iterator, $data)
* @method int cfmexists(string $key, ...$item)
* @method array cfinfo(string $key)
* @method array cfinsert(string $key, int $capacity = -1, bool $noCreate = false, string ...$item)
* @method array cfinsertnx(string $key, int $capacity = -1, bool $noCreate = false, string ...$item)
* @method Status cfreserve(string $key, int $capacity, int $bucketSize = -1, int $maxIterations = -1, int $expansion = -1)
* @method array cfscandump(string $key, int $iterator)
* @method array cmsincrby(string $key, string|int...$itemIncrementDictionary)
* @method array cmsinfo(string $key)
* @method Status cmsinitbydim(string $key, int $width, int $depth)
* @method Status cmsinitbyprob(string $key, float $errorRate, float $probability)
* @method Status cmsmerge(string $destination, array $sources, array $weights = [])
* @method array cmsquery(string $key, string ...$item)
* @method int decr(string $key)
* @method int decrby(string $key, int $decrement)
* @method Status failover(?To $to = null, bool $abort = false, int $timeout = -1)
* @method mixed fcall(string $function, array $keys, ...$args)
* @method mixed fcall_ro(string $function, array $keys, ...$args)
* @method array ftaggregate(string $index, string $query, ?AggregateArguments $arguments = null)
* @method Status ftaliasadd(string $alias, string $index)
* @method Status ftaliasdel(string $alias)
* @method Status ftaliasupdate(string $alias, string $index)
* @method Status ftalter(string $index, FieldInterface[] $schema, ?AlterArguments $arguments = null)
* @method Status ftcreate(string $index, FieldInterface[] $schema, ?CreateArguments $arguments = null)
* @method int ftdictadd(string $dict, ...$term)
* @method int ftdictdel(string $dict, ...$term)
* @method array ftdictdump(string $dict)
* @method Status ftdropindex(string $index, ?DropArguments $arguments = null)
* @method string ftexplain(string $index, string $query, ?ExplainArguments $arguments = null)
* @method array ftinfo(string $index)
* @method array ftprofile(string $index, ProfileArguments $arguments)
* @method array ftsearch(string $index, string $query, ?SearchArguments $arguments = null)
* @method array ftspellcheck(string $index, string $query, ?SearchArguments $arguments = null)
* @method int ftsugadd(string $key, string $string, float $score, ?SugAddArguments $arguments = null)
* @method int ftsugdel(string $key, string $string)
* @method array ftsugget(string $key, string $prefix, ?SugGetArguments $arguments = null)
* @method int ftsuglen(string $key)
* @method array ftsyndump(string $index)
* @method Status ftsynupdate(string $index, string $synonymGroupId, ?SynUpdateArguments $arguments = null, string ...$terms)
* @method array fttagvals(string $index, string $fieldName)
* @method string|null get(string $key)
* @method int getbit(string $key, $offset)
* @method int|null getex(string $key, $modifier = '', $value = false)
@@ -101,6 +176,28 @@ use Predis\Response\Status;
* @method int hsetnx(string $key, string $field, string $value)
* @method array hvals(string $key)
* @method int hstrlen(string $key, string $field)
* @method array jsonarrappend(string $key, string $path = '$', ...$value)
* @method array jsonarrindex(string $key, string $path, string $value, int $start = 0, int $stop = 0)
* @method array jsonarrinsert(string $key, string $path, int $index, string ...$value)
* @method array jsonarrlen(string $key, string $path = '$')
* @method array jsonarrpop(string $key, string $path = '$', int $index = -1)
* @method int jsonclear(string $key, string $path = '$')
* @method array jsonarrtrim(string $key, string $path, int $start, int $stop)
* @method int jsondel(string $key, string $path = '$')
* @method int jsonforget(string $key, string $path = '$')
* @method string jsonget(string $key, string $indent = '', string $newline = '', string $space = '', string ...$paths)
* @method string jsonnumincrby(string $key, string $path, int $value)
* @method Status jsonmerge(string $key, string $path, string $value)
* @method array jsonmget(array $keys, string $path)
* @method Status jsonmset(string ...$keyPathValue)
* @method array jsonobjkeys(string $key, string $path = '$')
* @method array jsonobjlen(string $key, string $path = '$')
* @method array jsonresp(string $key, string $path = '$')
* @method string jsonset(string $key, string $path, string $value, ?string $subcommand = null)
* @method array jsonstrappend(string $key, string $path, string $value)
* @method array jsonstrlen(string $key, string $path = '$')
* @method array jsontoggle(string $key, string $path)
* @method array jsontype(string $key, string $path = '$')
* @method string blmove(string $source, string $destination, string $where, string $to, int $timeout)
* @method array|null blpop(array|string $keys, int|float $timeout)
* @method array|null brpop(array|string $keys, int|float $timeout)
@@ -140,6 +237,43 @@ use Predis\Response\Status;
* @method string[] sunion(array|string $keys)
* @method int sunionstore(string $destination, array|string $keys)
* @method int touch(string[]|string $keyOrKeys, string ...$keys = null)
* @method Status tdigestadd(string $key, float ...$value)
* @method array tdigestbyrank(string $key, int ...$rank)
* @method array tdigestbyrevrank(string $key, int ...$reverseRank)
* @method array tdigestcdf(string $key, int ...$value)
* @method Status tdigestcreate(string $key, int $compression = 0)
* @method array tdigestinfo(string $key)
* @method string tdigestmax(string $key)
* @method Status tdigestmerge(string $destinationKey, array $sourceKeys, int $compression = 0, bool $override = false)
* @method string[] tdigestquantile(string $key, float ...$quantile)
* @method string tdigestmin(string $key)
* @method array tdigestrank(string $key, float ...$value)
* @method Status tdigestreset(string $key)
* @method array tdigestrevrank(string $key, float ...$value)
* @method string tdigesttrimmed_mean(string $key, float $lowCutQuantile, float $highCutQuantile)
* @method array topkadd(string $key, ...$items)
* @method array topkincrby(string $key, ...$itemIncrement)
* @method array topkinfo(string $key)
* @method array topklist(string $key, bool $withCount = false)
* @method array topkquery(string $key, ...$items)
* @method Status topkreserve(string $key, int $topK, int $width = 8, int $depth = 7, float $decay = 0.9)
* @method int tsadd(string $key, int $timestamp, float $value, ?AddArguments $arguments = null)
* @method Status tsalter(string $key, ?TSAlterArguments $arguments = null)
* @method Status tscreate(string $key, ?TSCreateArguments $arguments = null)
* @method Status tscreaterule(string $sourceKey, string $destKey, string $aggregator, int $bucketDuration, int $alignTimestamp = 0)
* @method int tsdecrby(string $key, float $value, ?DecrByArguments $arguments = null)
* @method int tsdel(string $key, int $fromTimestamp, int $toTimestamp)
* @method Status tsdeleterule(string $sourceKey, string $destKey)
* @method array tsget(string $key, GetArguments $arguments = null)
* @method int tsincrby(string $key, float $value, ?IncrByArguments $arguments = null)
* @method array tsinfo(string $key, ?InfoArguments $arguments = null)
* @method array tsmadd(mixed ...$keyTimestampValue)
* @method array tsmget(MGetArguments $arguments, string ...$filterExpression)
* @method array tsmrange($fromTimestamp, $toTimestamp, MRangeArguments $arguments)
* @method array tsmrevrange($fromTimestamp, $toTimestamp, MRangeArguments $arguments)
* @method array tsqueryindex(string ...$filterExpression)
* @method array tsrange(string $key, $fromTimestamp, $toTimestamp, ?RangeArguments $arguments = null)
* @method array tsrevrange(string $key, $fromTimestamp, $toTimestamp, ?RangeArguments $arguments = null)
* @method string xadd(string $key, array $dictionary, string $id = '*', array $options = null)
* @method int xdel(string $key, string ...$id)
* @method int xlen(string $key)
@@ -223,6 +357,10 @@ use Predis\Response\Status;
*
* Container commands
* @property FunctionContainer $function
* @property FTCONFIG $ftconfig
* @property FTCURSOR $ftcursor
* @property JSONDEBUG $jsondebug
* @property ACL $acl
*/
interface ClientInterface
{
+2 -1
View File
@@ -19,6 +19,7 @@ use IteratorAggregate;
use OutOfBoundsException;
use Predis\Connection\NodeConnectionInterface;
use ReturnTypeWillChange;
use Traversable;
/**
* Slot map for redis-cluster.
@@ -198,7 +199,7 @@ class SlotMap implements ArrayAccess, IteratorAggregate, Countable
/**
* Returns an iterator over the slot map.
*
* @return ArrayIterator
* @return Traversable<int, string>
*/
#[ReturnTypeWillChange]
public function getIterator()
@@ -138,7 +138,7 @@ abstract class CursorBasedIterator implements Iterator
}
/**
* {@inheritdoc}
* @return void
*/
#[ReturnTypeWillChange]
public function rewind()
@@ -148,7 +148,7 @@ abstract class CursorBasedIterator implements Iterator
}
/**
* {@inheritdoc}
* @return mixed
*/
#[ReturnTypeWillChange]
public function current()
@@ -157,7 +157,7 @@ abstract class CursorBasedIterator implements Iterator
}
/**
* {@inheritdoc}
* @return int|null
*/
#[ReturnTypeWillChange]
public function key()
@@ -166,7 +166,7 @@ abstract class CursorBasedIterator implements Iterator
}
/**
* {@inheritdoc}
* @return void
*/
#[ReturnTypeWillChange]
public function next()
@@ -186,7 +186,7 @@ abstract class CursorBasedIterator implements Iterator
}
/**
* {@inheritdoc}
* @return bool
*/
#[ReturnTypeWillChange]
public function valid()
+5 -5
View File
@@ -128,7 +128,7 @@ class ListKey implements Iterator
}
/**
* {@inheritdoc}
* @return void
*/
#[ReturnTypeWillChange]
public function rewind()
@@ -138,7 +138,7 @@ class ListKey implements Iterator
}
/**
* {@inheritdoc}
* @return mixed
*/
#[ReturnTypeWillChange]
public function current()
@@ -147,7 +147,7 @@ class ListKey implements Iterator
}
/**
* {@inheritdoc}
* @return int|null
*/
#[ReturnTypeWillChange]
public function key()
@@ -156,7 +156,7 @@ class ListKey implements Iterator
}
/**
* {@inheritdoc}
* @return void
*/
#[ReturnTypeWillChange]
public function next()
@@ -173,7 +173,7 @@ class ListKey implements Iterator
}
/**
* {@inheritdoc}
* @return bool
*/
#[ReturnTypeWillChange]
public function valid()
@@ -0,0 +1,161 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Predis\Command\Argument\Search;
class AggregateArguments extends CommonArguments
{
/**
* @var string[]
*/
private $sortingEnum = [
'asc' => 'ASC',
'desc' => 'DESC',
];
/**
* Loads document attributes from the source document.
*
* @param string ...$fields Could be just '*' to load all fields
* @return $this
*/
public function load(string ...$fields): self
{
$arguments = func_get_args();
$this->arguments[] = 'LOAD';
if ($arguments[0] === '*') {
$this->arguments[] = '*';
return $this;
}
$this->arguments[] = count($arguments);
$this->arguments = array_merge($this->arguments, $arguments);
return $this;
}
/**
* Loads document attributes from the source document.
*
* @param string ...$properties
* @return $this
*/
public function groupBy(string ...$properties): self
{
$arguments = func_get_args();
array_push($this->arguments, 'GROUPBY', count($arguments));
$this->arguments = array_merge($this->arguments, $arguments);
return $this;
}
/**
* Groups the results in the pipeline based on one or more properties.
*
* If you want to add alias property to your argument just add "true" value in arguments enumeration,
* next value will be considered as alias to previous one.
*
* Example: 'argument', true, 'name' => 'argument' AS 'name'
*
* @param string $function
* @param string|bool ...$argument
* @return $this
*/
public function reduce(string $function, ...$argument): self
{
$arguments = func_get_args();
$functionValue = array_shift($arguments);
$argumentsCounter = 0;
for ($i = 0, $iMax = count($arguments); $i < $iMax; $i++) {
if (true === $arguments[$i]) {
$arguments[$i] = 'AS';
$i++;
continue;
}
$argumentsCounter++;
}
array_push($this->arguments, 'REDUCE', $functionValue);
$this->arguments = array_merge($this->arguments, [$argumentsCounter], $arguments);
return $this;
}
/**
* Sorts the pipeline up until the point of SORTBY, using a list of properties.
*
* @param int $max
* @param string ...$properties Enumeration of properties, including sorting direction (ASC, DESC)
* @return $this
*/
public function sortBy(int $max = 0, ...$properties): self
{
$arguments = func_get_args();
$maxValue = array_shift($arguments);
$this->arguments[] = 'SORTBY';
$this->arguments = array_merge($this->arguments, [count($arguments)], $arguments);
if ($maxValue !== 0) {
array_push($this->arguments, 'MAX', $maxValue);
}
return $this;
}
/**
* Applies a 1-to-1 transformation on one or more properties and either stores the result
* as a new property down the pipeline or replaces any property using this transformation.
*
* @param string $expression
* @param string $as
* @return $this
*/
public function apply(string $expression, string $as = ''): self
{
array_push($this->arguments, 'APPLY', $expression);
if ($as !== '') {
array_push($this->arguments, 'AS', $as);
}
return $this;
}
/**
* Scan part of the results with a quicker alternative than LIMIT.
*
* @param int $readSize
* @param int $idleTime
* @return $this
*/
public function withCursor(int $readSize = 0, int $idleTime = 0): self
{
$this->arguments[] = 'WITHCURSOR';
if ($readSize !== 0) {
array_push($this->arguments, 'COUNT', $readSize);
}
if ($idleTime !== 0) {
array_push($this->arguments, 'MAXIDLE', $idleTime);
}
return $this;
}
}
@@ -0,0 +1,17 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Predis\Command\Argument\Search;
class AlterArguments extends CommonArguments
{
}
@@ -0,0 +1,182 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Predis\Command\Argument\Search;
use Predis\Command\Argument\ArrayableArgument;
class CommonArguments implements ArrayableArgument
{
/**
* @var array
*/
protected $arguments = [];
/**
* Adds default language for documents within an index.
*
* @param string $defaultLanguage
* @return $this
*/
public function language(string $defaultLanguage = 'english'): self
{
$this->arguments[] = 'LANGUAGE';
$this->arguments[] = $defaultLanguage;
return $this;
}
/**
* Selects the dialect version under which to execute the query.
* If not specified, the query will execute under the default dialect version
* set during module initial loading or via FT.CONFIG SET command.
*
* @param string $dialect
* @return $this
*/
public function dialect(string $dialect): self
{
$this->arguments[] = 'DIALECT';
$this->arguments[] = $dialect;
return $this;
}
/**
* If set, does not scan and index.
*
* @return $this
*/
public function skipInitialScan(): self
{
$this->arguments[] = 'SKIPINITIALSCAN';
return $this;
}
/**
* Adds an arbitrary, binary safe payload that is exposed to custom scoring functions.
*
* @param string $payload
* @return $this
*/
public function payload(string $payload): self
{
$this->arguments[] = 'PAYLOAD';
$this->arguments[] = $payload;
return $this;
}
/**
* Also returns the relative internal score of each document.
*
* @return $this
*/
public function withScores(): self
{
$this->arguments[] = 'WITHSCORES';
return $this;
}
/**
* Retrieves optional document payloads.
*
* @return $this
*/
public function withPayloads(): self
{
$this->arguments[] = 'WITHPAYLOADS';
return $this;
}
/**
* Does not try to use stemming for query expansion but searches the query terms verbatim.
*
* @return $this
*/
public function verbatim(): self
{
$this->arguments[] = 'VERBATIM';
return $this;
}
/**
* Overrides the timeout parameter of the module.
*
* @param int $timeout
* @return $this
*/
public function timeout(int $timeout): self
{
$this->arguments[] = 'TIMEOUT';
$this->arguments[] = $timeout;
return $this;
}
/**
* Adds an arbitrary, binary safe payload that is exposed to custom scoring functions.
*
* @param int $offset
* @param int $num
* @return $this
*/
public function limit(int $offset, int $num): self
{
array_push($this->arguments, 'LIMIT', $offset, $num);
return $this;
}
/**
* Adds filter expression into index.
*
* @param string $filter
* @return $this
*/
public function filter(string $filter): self
{
$this->arguments[] = 'FILTER';
$this->arguments[] = $filter;
return $this;
}
/**
* Defines one or more value parameters. Each parameter has a name and a value.
*
* Example: ['name1', 'value1', 'name2', 'value2'...]
*
* @param array $nameValuesDictionary
* @return $this
*/
public function params(array $nameValuesDictionary): self
{
$this->arguments[] = 'PARAMS';
$this->arguments[] = count($nameValuesDictionary);
$this->arguments = array_merge($this->arguments, $nameValuesDictionary);
return $this;
}
/**
* {@inheritDoc}
*/
public function toArray(): array
{
return $this->arguments;
}
}
@@ -0,0 +1,191 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Predis\Command\Argument\Search;
use InvalidArgumentException;
class CreateArguments extends CommonArguments
{
/**
* @var string[]
*/
private $supportedDataTypesEnum = [
'hash' => 'HASH',
'json' => 'JSON',
];
/**
* Specify data type for given index. To index JSON you must have the RedisJSON module to be installed.
*
* @param string $modifier
* @return $this
*/
public function on(string $modifier = 'HASH'): self
{
if (in_array(strtoupper($modifier), $this->supportedDataTypesEnum)) {
$this->arguments[] = 'ON';
$this->arguments[] = $this->supportedDataTypesEnum[strtolower($modifier)];
return $this;
}
$enumValues = implode(', ', array_values($this->supportedDataTypesEnum));
throw new InvalidArgumentException("Wrong modifier value given. Currently supports: {$enumValues}");
}
/**
* Adds one or more prefixes into index.
*
* @param array $prefixes
* @return $this
*/
public function prefix(array $prefixes): self
{
$this->arguments[] = 'PREFIX';
$this->arguments[] = count($prefixes);
$this->arguments = array_merge($this->arguments, $prefixes);
return $this;
}
/**
* Document attribute set as document language.
*
* @param string $languageAttribute
* @return $this
*/
public function languageField(string $languageAttribute): self
{
$this->arguments[] = 'LANGUAGE_FIELD';
$this->arguments[] = $languageAttribute;
return $this;
}
/**
* Default score for documents in the index.
*
* @param float $defaultScore
* @return $this
*/
public function score(float $defaultScore = 1.0): self
{
$this->arguments[] = 'SCORE';
$this->arguments[] = $defaultScore;
return $this;
}
/**
* Document attribute that used as the document rank based on the user ranking.
*
* @param string $scoreAttribute
* @return $this
*/
public function scoreField(string $scoreAttribute): self
{
$this->arguments[] = 'SCORE_FIELD';
$this->arguments[] = $scoreAttribute;
return $this;
}
/**
* Forces RediSearch to encode indexes as if there were more than 32 text attributes.
*
* @return $this
*/
public function maxTextFields(): self
{
$this->arguments[] = 'MAXTEXTFIELDS';
return $this;
}
/**
* Does not store term offsets for documents.
*
* @return $this
*/
public function noOffsets(): self
{
$this->arguments[] = 'NOOFFSETS';
return $this;
}
/**
* Creates a lightweight temporary index that expires after a specified period of inactivity, in seconds.
*
* @param int $seconds
* @return $this
*/
public function temporary(int $seconds): self
{
$this->arguments[] = 'TEMPORARY';
$this->arguments[] = $seconds;
return $this;
}
/**
* Conserves storage space and memory by disabling highlighting support.
*
* @return $this
*/
public function noHl(): self
{
$this->arguments[] = 'NOHL';
return $this;
}
/**
* Does not store attribute bits for each term.
*
* @return $this
*/
public function noFields(): self
{
$this->arguments[] = 'NOFIELDS';
return $this;
}
/**
* Avoids saving the term frequencies in the index.
*
* @return $this
*/
public function noFreqs(): self
{
$this->arguments[] = 'NOFREQS';
return $this;
}
/**
* Sets the index with a custom stopword list, to be ignored during indexing and search time.
*
* @param array $stopWords
* @return $this
*/
public function stopWords(array $stopWords): self
{
$this->arguments[] = 'STOPWORDS';
$this->arguments[] = count($stopWords);
$this->arguments = array_merge($this->arguments, $stopWords);
return $this;
}
}
@@ -0,0 +1,44 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Predis\Command\Argument\Search;
use Predis\Command\Argument\ArrayableArgument;
class CursorArguments implements ArrayableArgument
{
/**
* @var array
*/
protected $arguments = [];
/**
* Is number of results to read. This parameter overrides COUNT specified in FT.AGGREGATE.
*
* @param int $readSize
* @return $this
*/
public function count(int $readSize): self
{
array_push($this->arguments, 'COUNT', $readSize);
return $this;
}
/**
* {@inheritDoc}
*/
public function toArray(): array
{
return $this->arguments;
}
}
@@ -0,0 +1,43 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Predis\Command\Argument\Search;
use Predis\Command\Argument\ArrayableArgument;
class DropArguments implements ArrayableArgument
{
/**
* @var array
*/
protected $arguments = [];
/**
* Drop operation that, if set, deletes the actual document hashes.
*
* @return $this
*/
public function dd(): self
{
$this->arguments[] = 'DD';
return $this;
}
/**
* @return array
*/
public function toArray(): array
{
return $this->arguments;
}
}
@@ -0,0 +1,17 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Predis\Command\Argument\Search;
class ExplainArguments extends CommonArguments
{
}
@@ -0,0 +1,81 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Predis\Command\Argument\Search;
use Predis\Command\Argument\ArrayableArgument;
class ProfileArguments implements ArrayableArgument
{
/**
* @var array
*/
protected $arguments = [];
/**
* Adds search context.
*
* @return $this
*/
public function search(): self
{
$this->arguments[] = 'SEARCH';
return $this;
}
/**
* Adds aggregate context.
*
* @return $this
*/
public function aggregate(): self
{
$this->arguments[] = 'AGGREGATE';
return $this;
}
/**
* Removes details of reader iterator.
*
* @return $this
*/
public function limited(): self
{
$this->arguments[] = 'LIMITED';
return $this;
}
/**
* Is query string, as if sent to FT.SEARCH.
*
* @param string $query
* @return $this
*/
public function query(string $query): self
{
$this->arguments[] = 'QUERY';
$this->arguments[] = $query;
return $this;
}
/**
* {@inheritDoc}
*/
public function toArray(): array
{
return $this->arguments;
}
}
@@ -0,0 +1,69 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Predis\Command\Argument\Search\SchemaFields;
abstract class AbstractField implements FieldInterface
{
public const SORTABLE = true;
public const NOT_SORTABLE = false;
public const SORTABLE_UNF = 'UNF';
/**
* @var array
*/
protected $fieldArguments = [];
/**
* @param string $fieldType
* @param string $identifier
* @param string $alias
* @param bool|string $sortable
* @param bool $noIndex
* @return void
*/
protected function setCommonOptions(
string $fieldType,
string $identifier,
string $alias = '',
$sortable = self::NOT_SORTABLE,
bool $noIndex = false
): void {
$this->fieldArguments[] = $identifier;
if ($alias !== '') {
$this->fieldArguments[] = 'AS';
$this->fieldArguments[] = $alias;
}
$this->fieldArguments[] = $fieldType;
if ($sortable === self::SORTABLE) {
$this->fieldArguments[] = 'SORTABLE';
} elseif ($sortable === self::SORTABLE_UNF) {
$this->fieldArguments[] = 'SORTABLE';
$this->fieldArguments[] = 'UNF';
}
if ($noIndex) {
$this->fieldArguments[] = 'NOINDEX';
}
}
/**
* {@inheritDoc}
*/
public function toArray(): array
{
return $this->fieldArguments;
}
}
@@ -0,0 +1,22 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Predis\Command\Argument\Search\SchemaFields;
use Predis\Command\Argument\ArrayableArgument;
/**
* Represents field in search schema.
*/
interface FieldInterface extends ArrayableArgument
{
}
@@ -0,0 +1,31 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Predis\Command\Argument\Search\SchemaFields;
class GeoField extends AbstractField
{
/**
* @param string $identifier
* @param string $alias
* @param bool|string $sortable
* @param bool $noIndex
*/
public function __construct(
string $identifier,
string $alias = '',
$sortable = self::NOT_SORTABLE,
bool $noIndex = false
) {
$this->setCommonOptions('GEO', $identifier, $alias, $sortable, $noIndex);
}
}
@@ -0,0 +1,31 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Predis\Command\Argument\Search\SchemaFields;
class NumericField extends AbstractField
{
/**
* @param string $identifier
* @param string $alias
* @param bool|string $sortable
* @param bool $noIndex
*/
public function __construct(
string $identifier,
string $alias = '',
$sortable = self::NOT_SORTABLE,
bool $noIndex = false
) {
$this->setCommonOptions('NUMERIC', $identifier, $alias, $sortable, $noIndex);
}
}
@@ -0,0 +1,44 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Predis\Command\Argument\Search\SchemaFields;
class TagField extends AbstractField
{
/**
* @param string $identifier
* @param string $alias
* @param bool|string $sortable
* @param bool $noIndex
* @param string $separator
* @param bool $caseSensitive
*/
public function __construct(
string $identifier,
string $alias = '',
$sortable = self::NOT_SORTABLE,
bool $noIndex = false,
string $separator = ',',
bool $caseSensitive = false
) {
$this->setCommonOptions('TAG', $identifier, $alias, $sortable, $noIndex);
if ($separator !== ',') {
$this->fieldArguments[] = 'SEPARATOR';
$this->fieldArguments[] = $separator;
}
if ($caseSensitive) {
$this->fieldArguments[] = 'CASESENSITIVE';
}
}
}
@@ -0,0 +1,57 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Predis\Command\Argument\Search\SchemaFields;
class TextField extends AbstractField
{
/**
* @param string $identifier
* @param string $alias
* @param bool|string $sortable
* @param bool $noIndex
* @param bool $noStem
* @param string $phonetic
* @param int $weight
* @param bool $withSuffixTrie
*/
public function __construct(
string $identifier,
string $alias = '',
$sortable = self::NOT_SORTABLE,
bool $noIndex = false,
bool $noStem = false,
string $phonetic = '',
int $weight = 1,
bool $withSuffixTrie = false
) {
$this->setCommonOptions('TEXT', $identifier, $alias, $sortable, $noIndex);
if ($noStem) {
$this->fieldArguments[] = 'NOSTEM';
}
if ($phonetic !== '') {
$this->fieldArguments[] = 'PHONETIC';
$this->fieldArguments[] = $phonetic;
}
if ($weight !== 1) {
$this->fieldArguments[] = 'WEIGHT';
$this->fieldArguments[] = $weight;
}
if ($withSuffixTrie) {
$this->fieldArguments[] = 'WITHSUFFIXTRIE';
}
}
}
@@ -0,0 +1,47 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Predis\Command\Argument\Search\SchemaFields;
class VectorField extends AbstractField
{
/**
* @var array
*/
protected $fieldArguments = [];
/**
* @param string $fieldName
* @param string $algorithm
* @param array $attributeNameValueDictionary
* @param string $alias
*/
public function __construct(
string $fieldName,
string $algorithm,
array $attributeNameValueDictionary,
string $alias = ''
) {
$this->setCommonOptions('VECTOR', $fieldName, $alias);
array_push($this->fieldArguments, $algorithm, count($attributeNameValueDictionary));
$this->fieldArguments = array_merge($this->fieldArguments, $attributeNameValueDictionary);
}
/**
* {@inheritDoc}
*/
public function toArray(): array
{
return $this->fieldArguments;
}
}
@@ -0,0 +1,306 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Predis\Command\Argument\Search;
use InvalidArgumentException;
class SearchArguments extends CommonArguments
{
/**
* @var string[]
*/
private $sortingEnum = [
'asc' => 'ASC',
'desc' => 'DESC',
];
/**
* Returns the document ids and not the content.
*
* @return $this
*/
public function noContent(): self
{
$this->arguments[] = 'NOCONTENT';
return $this;
}
/**
* Returns the value of the sorting key, right after the id and score and/or payload, if requested.
*
* @return $this
*/
public function withSortKeys(): self
{
$this->arguments[] = 'WITHSORTKEYS';
return $this;
}
/**
* Limits results to those having numeric values ranging between min and max,
* if numeric_attribute is defined as a numeric attribute in FT.CREATE.
* Min and max follow ZRANGE syntax, and can be -inf, +inf, and use( for exclusive ranges.
* Multiple numeric filters for different attributes are supported in one query.
*
* @param array ...$filter Should contain: numeric_field, min and max. Example: ['numeric_field', 1, 10]
* @return $this
*/
public function searchFilter(array ...$filter): self
{
$arguments = func_get_args();
foreach ($arguments as $argument) {
array_push($this->arguments, 'FILTER', ...$argument);
}
return $this;
}
/**
* Filter the results to a given radius from lon and lat. Radius is given as a number and units.
*
* @param array ...$filter Should contain: geo_field, lon, lat, radius, unit. Example: ['geo_field', 34.1231, 35.1231, 300, km]
* @return $this
*/
public function geoFilter(array ...$filter): self
{
$arguments = func_get_args();
foreach ($arguments as $argument) {
array_push($this->arguments, 'GEOFILTER', ...$argument);
}
return $this;
}
/**
* Limits the result to a given set of keys specified in the list.
*
* @param array $keys
* @return $this
*/
public function inKeys(array $keys): self
{
$this->arguments[] = 'INKEYS';
$this->arguments[] = count($keys);
$this->arguments = array_merge($this->arguments, $keys);
return $this;
}
/**
* Filters the results to those appearing only in specific attributes of the document, like title or URL.
*
* @param array $fields
* @return $this
*/
public function inFields(array $fields): self
{
$this->arguments[] = 'INFIELDS';
$this->arguments[] = count($fields);
$this->arguments = array_merge($this->arguments, $fields);
return $this;
}
/**
* Limits the attributes returned from the document.
* Num is the number of attributes following the keyword.
* If num is 0, it acts like NOCONTENT.
* Identifier is either an attribute name (for hashes and JSON) or a JSON Path expression (for JSON).
* Property is an optional name used in the result. If not provided, the identifier is used in the result.
*
* If you want to add alias property to your identifier just add "true" value in identifier enumeration,
* next value will be considered as alias to previous one.
*
* Example: 'identifier', true, 'property' => 'identifier' AS 'property'
*
* @param int $count
* @param string|bool ...$identifier
* @return $this
*/
public function addReturn(int $count, ...$identifier): self
{
$arguments = func_get_args();
$this->arguments[] = 'RETURN';
for ($i = 1, $iMax = count($arguments); $i < $iMax; $i++) {
if (true === $arguments[$i]) {
$arguments[$i] = 'AS';
}
}
$this->arguments = array_merge($this->arguments, $arguments);
return $this;
}
/**
* Returns only the sections of the attribute that contain the matched text.
*
* @param array $fields
* @param int $frags
* @param int $len
* @param string $separator
* @return $this
*/
public function summarize(array $fields = [], int $frags = 0, int $len = 0, string $separator = ''): self
{
$this->arguments[] = 'SUMMARIZE';
if (!empty($fields)) {
$this->arguments[] = 'FIELDS';
$this->arguments[] = count($fields);
$this->arguments = array_merge($this->arguments, $fields);
}
if ($frags !== 0) {
$this->arguments[] = 'FRAGS';
$this->arguments[] = $frags;
}
if ($len !== 0) {
$this->arguments[] = 'LEN';
$this->arguments[] = $len;
}
if ($separator !== '') {
$this->arguments[] = 'SEPARATOR';
$this->arguments[] = $separator;
}
return $this;
}
/**
* Formats occurrences of matched text.
*
* @param array $fields
* @param string $openTag
* @param string $closeTag
* @return $this
*/
public function highlight(array $fields = [], string $openTag = '', string $closeTag = ''): self
{
$this->arguments[] = 'HIGHLIGHT';
if (!empty($fields)) {
$this->arguments[] = 'FIELDS';
$this->arguments[] = count($fields);
$this->arguments = array_merge($this->arguments, $fields);
}
if ($openTag !== '' && $closeTag !== '') {
array_push($this->arguments, 'TAGS', $openTag, $closeTag);
}
return $this;
}
/**
* Allows a maximum of N intervening number of unmatched offsets between phrase terms.
* In other words, the slop for exact phrases is 0.
*
* @param int $slop
* @return $this
*/
public function slop(int $slop): self
{
$this->arguments[] = 'SLOP';
$this->arguments[] = $slop;
return $this;
}
/**
* Puts the query terms in the same order in the document as in the query, regardless of the offsets between them.
* Typically used in conjunction with SLOP.
*
* @return $this
*/
public function inOrder(): self
{
$this->arguments[] = 'INORDER';
return $this;
}
/**
* Uses a custom query expander instead of the stemmer.
*
* @param string $expander
* @return $this
*/
public function expander(string $expander): self
{
$this->arguments[] = 'EXPANDER';
$this->arguments[] = $expander;
return $this;
}
/**
* Uses a custom scoring function you define.
*
* @param string $scorer
* @return $this
*/
public function scorer(string $scorer): self
{
$this->arguments[] = 'SCORER';
$this->arguments[] = $scorer;
return $this;
}
/**
* Returns a textual description of how the scores were calculated.
* Using this options requires the WITHSCORES option.
*
* @return $this
*/
public function explainScore(): self
{
$this->arguments[] = 'EXPLAINSCORE';
return $this;
}
/**
* Orders the results by the value of this attribute.
* This applies to both text and numeric attributes.
* Attributes needed for SORTBY should be declared as SORTABLE in the index, in order to be available with very low latency.
* Note that this adds memory overhead.
*
* @param string $sortAttribute
* @param string $orderBy
* @return $this
*/
public function sortBy(string $sortAttribute, string $orderBy = 'asc'): self
{
$this->arguments[] = 'SORTBY';
$this->arguments[] = $sortAttribute;
if (in_array(strtoupper($orderBy), $this->sortingEnum)) {
$this->arguments[] = $this->sortingEnum[strtolower($orderBy)];
} else {
$enumValues = implode(', ', array_values($this->sortingEnum));
throw new InvalidArgumentException("Wrong order direction value given. Currently supports: {$enumValues}");
}
return $this;
}
}
@@ -0,0 +1,59 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Predis\Command\Argument\Search;
use InvalidArgumentException;
class SpellcheckArguments extends CommonArguments
{
/**
* @var string[]
*/
private $termsEnum = [
'include' => 'INCLUDE',
'exclude' => 'EXCLUDE',
];
/**
* Is maximum Levenshtein distance for spelling suggestions (default: 1, max: 4).
*
* @return $this
*/
public function distance(int $distance): self
{
$this->arguments[] = 'DISTANCE';
$this->arguments[] = $distance;
return $this;
}
/**
* Specifies an inclusion (INCLUDE) or exclusion (EXCLUDE) of a custom dictionary named {dict}.
*
* @param string $dictionary
* @param string $modifier
* @param string ...$terms
* @return $this
*/
public function terms(string $dictionary, string $modifier = 'INCLUDE', string ...$terms): self
{
if (!in_array(strtoupper($modifier), $this->termsEnum)) {
$enumValues = implode(', ', array_values($this->termsEnum));
throw new InvalidArgumentException("Wrong modifier value given. Currently supports: {$enumValues}");
}
array_push($this->arguments, 'TERMS', $this->termsEnum[strtolower($modifier)], $dictionary, ...$terms);
return $this;
}
}
@@ -0,0 +1,28 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Predis\Command\Argument\Search;
class SugAddArguments extends CommonArguments
{
/**
* Adds INCR modifier.
*
* @return $this
*/
public function incr(): self
{
$this->arguments[] = 'INCR';
return $this;
}
}
@@ -0,0 +1,41 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Predis\Command\Argument\Search;
class SugGetArguments extends CommonArguments
{
/**
* Performs a fuzzy prefix search, including prefixes at Levenshtein distance of 1 from the prefix sent.
*
* @return $this
*/
public function fuzzy(): self
{
$this->arguments[] = 'FUZZY';
return $this;
}
/**
* Limits the results to a maximum of num (default: 5).
*
* @param int $num
* @return $this
*/
public function max(int $num): self
{
array_push($this->arguments, 'MAX', $num);
return $this;
}
}
@@ -0,0 +1,17 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Predis\Command\Argument\Search;
class SynUpdateArguments extends CommonArguments
{
}
@@ -0,0 +1,30 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Predis\Command\Argument\TimeSeries;
class AddArguments extends CommonArguments
{
/**
* Is overwrite key and database configuration for DUPLICATE_POLICY,
* the policy for handling samples with identical timestamps.
*
* @param string $policy
* @return $this
*/
public function onDuplicate(string $policy = self::POLICY_BLOCK): self
{
array_push($this->arguments, 'ON_DUPLICATE', $policy);
return $this;
}
}
@@ -0,0 +1,17 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Predis\Command\Argument\TimeSeries;
class AlterArguments extends CommonArguments
{
}
@@ -0,0 +1,143 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Predis\Command\Argument\TimeSeries;
use Predis\Command\Argument\ArrayableArgument;
class CommonArguments implements ArrayableArgument
{
public const POLICY_BLOCK = 'BLOCK';
public const POLICY_FIRST = 'FIRST';
public const POLICY_LAST = 'LAST';
public const POLICY_MIN = 'MIN';
public const POLICY_MAX = 'MAX';
public const POLICY_SUM = 'SUM';
public const ENCODING_UNCOMPRESSED = 'UNCOMPRESSED';
public const ENCODING_COMPRESSED = 'COMPRESSED';
/**
* @var array
*/
protected $arguments = [];
/**
* Is maximum age for samples compared to the highest reported timestamp, in milliseconds.
*
* @param int $retentionPeriod
* @return $this
*/
public function retentionMsecs(int $retentionPeriod): self
{
array_push($this->arguments, 'RETENTION', $retentionPeriod);
return $this;
}
/**
* Is initial allocation size, in bytes, for the data part of each new chunk.
*
* @param int $size
* @return $this
*/
public function chunkSize(int $size): self
{
array_push($this->arguments, 'CHUNK_SIZE', $size);
return $this;
}
/**
* Is policy for handling insertion of multiple samples with identical timestamps.
*
* @param string $policy
* @return $this
*/
public function duplicatePolicy(string $policy = self::POLICY_BLOCK): self
{
array_push($this->arguments, 'DUPLICATE_POLICY', $policy);
return $this;
}
/**
* Is set of label-value pairs that represent metadata labels of the key and serve as a secondary index.
*
* @param mixed ...$labelValuePair
* @return $this
*/
public function labels(...$labelValuePair): self
{
array_push($this->arguments, 'LABELS', ...$labelValuePair);
return $this;
}
/**
* Specifies the series samples encoding format.
*
* @param string $encoding
* @return $this
*/
public function encoding(string $encoding = self::ENCODING_COMPRESSED): self
{
array_push($this->arguments, 'ENCODING', $encoding);
return $this;
}
/**
* Is used when a time series is a compaction.
* With LATEST, TS.GET reports the compacted value of the latest, possibly partial, bucket.
*
* @return $this
*/
public function latest(): self
{
$this->arguments[] = 'LATEST';
return $this;
}
/**
* Includes in the reply all label-value pairs representing metadata labels of the time series.
*
* @return $this
*/
public function withLabels(): self
{
$this->arguments[] = 'WITHLABELS';
return $this;
}
/**
* Returns a subset of the label-value pairs that represent metadata labels of the time series.
*
* @return $this
*/
public function selectedLabels(string ...$labels): self
{
array_push($this->arguments, 'SELECTED_LABELS', ...$labels);
return $this;
}
/**
* {@inheritDoc}
*/
public function toArray(): array
{
return $this->arguments;
}
}
@@ -0,0 +1,17 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Predis\Command\Argument\TimeSeries;
class CreateArguments extends CommonArguments
{
}
@@ -0,0 +1,17 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Predis\Command\Argument\TimeSeries;
class DecrByArguments extends IncrByArguments
{
}
@@ -0,0 +1,17 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Predis\Command\Argument\TimeSeries;
class GetArguments extends CommonArguments
{
}
@@ -0,0 +1,41 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Predis\Command\Argument\TimeSeries;
class IncrByArguments extends CommonArguments
{
/**
* Is (integer) UNIX sample timestamp in milliseconds or * to set the timestamp according to the server clock.
*
* @param string|int $timeStamp
* @return $this
*/
public function timestamp($timeStamp): self
{
array_push($this->arguments, 'TIMESTAMP', $timeStamp);
return $this;
}
/**
* Changes data storage from compressed (default) to uncompressed.
*
* @return $this
*/
public function uncompressed(): self
{
$this->arguments[] = 'UNCOMPRESSED';
return $this;
}
}
@@ -0,0 +1,43 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Predis\Command\Argument\TimeSeries;
use Predis\Command\Argument\ArrayableArgument;
class InfoArguments implements ArrayableArgument
{
/**
* @var array
*/
private $arguments = [];
/**
* Is an optional flag to get a more detailed information about the chunks.
*
* @return $this
*/
public function debug(): self
{
$this->arguments[] = 'DEBUG';
return $this;
}
/**
* {@inheritDoc}
*/
public function toArray(): array
{
return $this->arguments;
}
}
@@ -0,0 +1,17 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Predis\Command\Argument\TimeSeries;
class MGetArguments extends CommonArguments
{
}
@@ -0,0 +1,44 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Predis\Command\Argument\TimeSeries;
class MRangeArguments extends RangeArguments
{
/**
* Filters time series based on their labels and label values.
*
* @param string ...$filterExpressions
* @return $this
*/
public function filter(string ...$filterExpressions): self
{
array_push($this->arguments, 'FILTER', ...$filterExpressions);
return $this;
}
/**
* Splits time series into groups, each group contains time series that share the same
* value for the provided label name, then aggregates results in each group.
*
* @param string $label
* @param string $reducer
* @return $this
*/
public function groupBy(string $label, string $reducer): self
{
array_push($this->arguments, 'GROUPBY', $label, 'REDUCE', $reducer);
return $this;
}
}
@@ -0,0 +1,85 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Predis\Command\Argument\TimeSeries;
class RangeArguments extends CommonArguments
{
/**
* Filters samples by a list of specific timestamps.
*
* @param int ...$ts
* @return $this
*/
public function filterByTs(int ...$ts): self
{
array_push($this->arguments, 'FILTER_BY_TS', ...$ts);
return $this;
}
/**
* Filters samples by minimum and maximum values.
*
* @param int $min
* @param int $max
* @return $this
*/
public function filterByValue(int $min, int $max): self
{
array_push($this->arguments, 'FILTER_BY_VALUE', $min, $max);
return $this;
}
/**
* Limits the number of returned samples.
*
* @param int $count
* @return $this
*/
public function count(int $count): self
{
array_push($this->arguments, 'COUNT', $count);
return $this;
}
/**
* Aggregates samples into time buckets.
*
* @param string $aggregator
* @param int $bucketDuration Is duration of each bucket, in milliseconds.
* @param int $align It controls the time bucket timestamps by changing the reference timestamp on which a bucket is defined.
* @param int $bucketTimestamp Controls how bucket timestamps are reported.
* @param bool $empty Is a flag, which, when specified, reports aggregations also for empty buckets.
* @return $this
*/
public function aggregation(string $aggregator, int $bucketDuration, int $align = 0, int $bucketTimestamp = 0, bool $empty = false): self
{
if ($align > 0) {
array_push($this->arguments, 'ALIGN', $align);
}
array_push($this->arguments, 'AGGREGATION', $aggregator, $bucketDuration);
if ($bucketTimestamp > 0) {
array_push($this->arguments, 'BUCKETTIMESTAMP', $bucketTimestamp);
}
if (true === $empty) {
$this->arguments[] = 'EMPTY';
}
return $this;
}
}
@@ -181,9 +181,14 @@ class KeyPrefixProcessor implements ProcessorInterface
/* ---------------- Redis 5.0 ---------------- */
'XADD' => $prefixFirst,
'XRANGE' => $prefixFirst,
'XREVRANGE' => $prefixFirst,
'XDEL' => $prefixFirst,
'XLEN' => $prefixFirst,
'XACK' => $prefixFirst,
'XTRIM' => $prefixFirst,
/* ---------------- Redis 6.2 ---------------- */
'GETDEL' => $prefixFirst,
];
}
+9 -4
View File
@@ -93,7 +93,8 @@ class ProcessorChain implements ArrayAccess, ProcessorInterface
}
/**
* {@inheritdoc}
* @param int $index
* @return bool
*/
#[ReturnTypeWillChange]
public function offsetExists($index)
@@ -102,7 +103,8 @@ class ProcessorChain implements ArrayAccess, ProcessorInterface
}
/**
* {@inheritdoc}
* @param int $index
* @return ProcessorInterface
*/
#[ReturnTypeWillChange]
public function offsetGet($index)
@@ -111,7 +113,9 @@ class ProcessorChain implements ArrayAccess, ProcessorInterface
}
/**
* {@inheritdoc}
* @param int $index
* @param ProcessorInterface $processor
* @return void
*/
#[ReturnTypeWillChange]
public function offsetSet($index, $processor)
@@ -126,7 +130,8 @@ class ProcessorChain implements ArrayAccess, ProcessorInterface
}
/**
* {@inheritdoc}
* @param int $index
* @return void
*/
#[ReturnTypeWillChange]
public function offsetUnset($index)
+53
View File
@@ -0,0 +1,53 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* 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;
/**
* @see https://redis.io/commands/?name=ACL
*
* Container command corresponds to any ACL *.
* Represents any ACL command with subcommand as first argument.
*/
class ACL extends RedisCommand
{
public function getId()
{
return 'ACL';
}
/**
* {@inheritdoc}
*/
public function parseResponse($data)
{
if (!is_array($data)) {
return $data;
}
if ($data === array_values($data)) {
return $data;
}
// flatten Relay (RESP3) maps
$return = [];
array_walk($data, function ($value, $key) use (&$return) {
$return[] = $key;
$return[] = $value;
});
return $return;
}
}
+29
View File
@@ -0,0 +1,29 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Predis\Command\Redis\BloomFilter;
use Predis\Command\Command as RedisCommand;
/**
* @see https://redis.io/commands/bf.add/
*
* Creates an empty Bloom Filter with a single sub-filter for the
* initial capacity requested and with an upper bound error_rate.
*/
class BFADD extends RedisCommand
{
public function getId()
{
return 'BF.ADD';
}
}
@@ -0,0 +1,28 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Predis\Command\Redis\BloomFilter;
use Predis\Command\Command as RedisCommand;
/**
* @see https://redis.io/commands/bf.exists/
*
* Determines whether an item may exist in the Bloom Filter or not.
*/
class BFEXISTS extends RedisCommand
{
public function getId()
{
return 'BF.EXISTS';
}
}
+79
View File
@@ -0,0 +1,79 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Predis\Command\Redis\BloomFilter;
use Predis\Command\Command as RedisCommand;
use UnexpectedValueException;
/**
* @see https://redis.io/commands/bf.info/
*
* Return information about key filter.
*/
class BFINFO extends RedisCommand
{
/**
* @var string[]
*/
private $modifierEnum = [
'capacity' => 'CAPACITY',
'size' => 'SIZE',
'filters' => 'FILTERS',
'items' => 'ITEMS',
'expansion' => 'EXPANSION',
];
public function getId()
{
return 'BF.INFO';
}
public function setArguments(array $arguments)
{
if (isset($arguments[1])) {
$modifier = array_pop($arguments);
if ($modifier === '') {
parent::setArguments($arguments);
return;
}
if (!in_array(strtoupper($modifier), $this->modifierEnum)) {
$enumValues = implode(', ', array_keys($this->modifierEnum));
throw new UnexpectedValueException("Argument accepts only: {$enumValues} values");
}
$arguments[] = $this->modifierEnum[strtolower($modifier)];
}
parent::setArguments($arguments);
}
public function parseResponse($data)
{
if (count($data) > 1) {
$result = [];
for ($i = 0, $iMax = count($data); $i < $iMax; ++$i) {
if (array_key_exists($i + 1, $data)) {
$result[(string) $data[$i]] = $data[++$i];
}
}
return $result;
}
return $data;
}
}
@@ -0,0 +1,72 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Predis\Command\Redis\BloomFilter;
use Predis\Command\Command as RedisCommand;
use Predis\Command\Traits\BloomFilters\Capacity;
use Predis\Command\Traits\BloomFilters\Error;
use Predis\Command\Traits\BloomFilters\Expansion;
use Predis\Command\Traits\BloomFilters\Items;
use Predis\Command\Traits\BloomFilters\NoCreate;
class BFINSERT extends RedisCommand
{
use Capacity {
Capacity::setArguments as setCapacity;
}
use Error {
Error::setArguments as setErrorRate;
}
use Expansion {
Expansion::setArguments as setExpansion;
}
use Items {
Items::setArguments as setItems;
}
use NoCreate {
NoCreate::setArguments as setNoCreate;
}
protected static $capacityArgumentPositionOffset = 1;
protected static $errorArgumentPositionOffset = 2;
protected static $expansionArgumentPositionOffset = 3;
protected static $noCreateArgumentPositionOffset = 4;
protected static $itemsArgumentPositionOffset = 6;
public function getId()
{
return 'BF.INSERT';
}
public function setArguments(array $arguments)
{
$this->setNoCreate($arguments);
$arguments = $this->getArguments();
if (array_key_exists(5, $arguments) && $arguments[5]) {
$arguments[5] = 'NONSCALING';
}
$this->setItems($arguments);
$arguments = $this->getArguments();
$this->setExpansion($arguments);
$arguments = $this->getArguments();
$this->setErrorRate($arguments);
$arguments = $this->getArguments();
$this->setCapacity($arguments);
$this->filterArguments();
}
}
@@ -0,0 +1,28 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Predis\Command\Redis\BloomFilter;
use Predis\Command\Command as RedisCommand;
/**
* @see https://redis.io/commands/bf.loadchunk/
*
* Restores a filter previously saved using SCANDUMP. See the SCANDUMP command for example usage.
*/
class BFLOADCHUNK extends RedisCommand
{
public function getId()
{
return 'BF.LOADCHUNK';
}
}
+29
View File
@@ -0,0 +1,29 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Predis\Command\Redis\BloomFilter;
use Predis\Command\Command as RedisCommand;
/**
* @see https://redis.io/commands/bf.madd/
*
* Adds one or more items to the Bloom Filter and creates the filter if it does not exist yet.
* This command operates identically to BF.ADD except that it allows multiple inputs and returns multiple values.
*/
class BFMADD extends RedisCommand
{
public function getId()
{
return 'BF.MADD';
}
}
@@ -0,0 +1,28 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Predis\Command\Redis\BloomFilter;
use Predis\Command\Command as RedisCommand;
/**
* @see https://redis.io/commands/bf.mexists/
*
* Determines if one or more items may exist in the filter or not.
*/
class BFMEXISTS extends RedisCommand
{
public function getId()
{
return 'BF.MEXISTS';
}
}
@@ -0,0 +1,49 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Predis\Command\Redis\BloomFilter;
use Predis\Command\Command as RedisCommand;
use Predis\Command\Traits\BloomFilters\Expansion;
/**
* @see https://redis.io/commands/bf.reserve/
*
* Creates an empty Bloom Filter with a single sub-filter for the initial capacity
* requested and with an upper bound error_rate.
*
* By default, the filter auto-scales by creating additional sub-filters when capacity is reached.
* The new sub-filter is created with size of the previous sub-filter multiplied by expansion.
*/
class BFRESERVE extends RedisCommand
{
use Expansion {
Expansion::setArguments as setExpansion;
}
protected static $expansionArgumentPositionOffset = 3;
public function getId()
{
return 'BF.RESERVE';
}
public function setArguments(array $arguments)
{
if (array_key_exists(4, $arguments) && $arguments[4]) {
$arguments[4] = 'NONSCALING';
}
$this->setExpansion($arguments);
$this->filterArguments();
}
}

Some files were not shown because too many files have changed in this diff Show More