mirror of
https://github.com/predis/predis.git
synced 2026-08-19 07:41:42 +00:00
Compare commits
14 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 07105e0506 | |||
| 07dc6ba6d2 | |||
| 5142011581 | |||
| c4b9c34d86 | |||
| f49e13ee3a | |||
| 6e3e2c0e78 | |||
| c35c422eda | |||
| 1b5ed7d516 | |||
| 5df852f227 | |||
| 9418df1924 | |||
| 0e4b3829a7 | |||
| 65f6127fab | |||
| 7ff24b19ae | |||
| 2babfc91d7 |
+1
-1
@@ -1,5 +1,5 @@
|
||||
[codespell]
|
||||
skip=./.git,./src/Command/Redis/Search/FTSUGGET.php,./examples/Commands/Search/ft_sug_add_get_del_len.php
|
||||
skip=./.git
|
||||
check-hidden=
|
||||
check-filenames=
|
||||
builtin=clear,rare,informal,usage,code,names
|
||||
|
||||
+14
-2
@@ -1,2 +1,14 @@
|
||||
* @predis/maintainers
|
||||
src/Relay* @tillkruss
|
||||
# Default
|
||||
* @tillkruss
|
||||
|
||||
# Redis commands
|
||||
src/Command/Redis/* @predis/team @tillkruss
|
||||
|
||||
# Redis Stack
|
||||
src/Command/Redis/Json/* @predis/team
|
||||
src/Command/Redis/Search/* @predis/team
|
||||
src/Command/Redis/TopK/* @predis/team
|
||||
src/Command/Redis/TDigest/* @predis/team
|
||||
src/Command/Redis/BloomFilter/* @predis/team
|
||||
src/Command/Redis/CuckooFilter/* @predis/team
|
||||
src/Command/Redis/CountMinSketch/* @predis/team
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
services:
|
||||
|
||||
redis-official:
|
||||
image: ${REDIS_IMAGE_NAME:-redis:8.0}
|
||||
container_name: redis-official
|
||||
image: ${REDIS_IMAGE_NAME:-redis:7.4}
|
||||
container_name: redis-standalone
|
||||
healthcheck:
|
||||
test: [ "CMD", "redis-cli", "PING" ]
|
||||
interval: 10s
|
||||
@@ -12,23 +12,20 @@ services:
|
||||
retries: 3
|
||||
ports:
|
||||
- "6379:6379"
|
||||
command:
|
||||
- --requirepass "foobar"
|
||||
profiles:
|
||||
- all
|
||||
- official
|
||||
- standalone
|
||||
|
||||
redis-clients:
|
||||
image: ${REDIS_IMAGE_NAME:-redislabs/client-libs-test:8.0.2}
|
||||
image: ${REDIS_IMAGE_NAME:-redislabs/client-libs-test:7.4.2}
|
||||
container_name: redis-standalone
|
||||
environment:
|
||||
- TLS_ENABLED=yes
|
||||
- REDIS_CLUSTER=no
|
||||
- REDIS_PASSWORD=foobar
|
||||
- PORT=6379
|
||||
- TLS_PORT=6666
|
||||
command: ${REDIS_EXTRA_ARGS:---enable-debug-command yes --enable-module-command yes --tls-auth-clients optional --save "" --requirepass "foobar"}
|
||||
command: ${REDIS_EXTRA_ARGS:---enable-debug-command yes --enable-module-command yes --tls-auth-clients optional --save ""}
|
||||
ports:
|
||||
- 6379:6379
|
||||
- 6666:6666 # TLS port
|
||||
@@ -39,38 +36,19 @@ services:
|
||||
- clients
|
||||
- standalone
|
||||
|
||||
redis-unprotected:
|
||||
image: ${REDIS_IMAGE_NAME:-redislabs/client-libs-test:8.0.2}
|
||||
container_name: redis-unprotected
|
||||
environment:
|
||||
- TLS_ENABLED=no
|
||||
- REDIS_CLUSTER=no
|
||||
- PORT=6379
|
||||
- TLS_PORT=6666
|
||||
command: ${REDIS_EXTRA_ARGS:---enable-debug-command yes --enable-module-command yes --tls-auth-clients optional --save ""}
|
||||
ports:
|
||||
- 6380:6379
|
||||
volumes:
|
||||
- "./dockers/unprotected:/redis/work"
|
||||
profiles:
|
||||
- all
|
||||
- clients
|
||||
- unprotected
|
||||
|
||||
redis-cluster:
|
||||
image: ${REDIS_IMAGE_NAME:-redislabs/client-libs-test:8.0.2}
|
||||
image: ${REDIS_IMAGE_NAME:-redislabs/client-libs-test:7.4.2}
|
||||
container_name: redis-cluster
|
||||
environment:
|
||||
- REDIS_CLUSTER=yes
|
||||
- REDIS_PASSWORD=foobar
|
||||
- NODES=6
|
||||
- REPLICAS=1
|
||||
- TLS_ENABLED=yes
|
||||
- PORT=6372
|
||||
- PORT=16379
|
||||
- TLS_PORT=27379
|
||||
command: ${REDIS_EXTRA_ARGS:---enable-debug-command yes --enable-module-command yes --tls-auth-clients optional --save "" --requirepass "foobar"}
|
||||
command: ${REDIS_EXTRA_ARGS:---enable-debug-command yes --enable-module-command yes --tls-auth-clients optional --save ""}
|
||||
ports:
|
||||
- "6372-6377:6372-6377"
|
||||
- "6372-6377:16379-16384"
|
||||
volumes:
|
||||
- "./dockers/cluster:/redis/work"
|
||||
profiles:
|
||||
@@ -85,9 +63,8 @@ services:
|
||||
- "6479:6379"
|
||||
environment:
|
||||
- REDIS_CLUSTER=no
|
||||
- REDIS_PASSWORD=foobar
|
||||
- PORT=6379
|
||||
command: ${REDIS_EXTRA_ARGS:---enable-debug-command yes --enable-module-command yes --save "" --requirepass "foobar"}
|
||||
command: ${REDIS_EXTRA_ARGS:---enable-debug-command yes --enable-module-command yes --save ""}
|
||||
volumes:
|
||||
- "./dockers/redis-stack:/redis/work"
|
||||
profiles:
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
name-template: 'v$NEXT_MINOR_VERSION'
|
||||
tag-template: 'v$NEXT_MINOR_VERSION'
|
||||
change-template: '- $TITLE (#$NUMBER)'
|
||||
filter-by-commitish: true
|
||||
commitish: v3.x
|
||||
|
||||
autolabeler:
|
||||
- label: 'maintenance'
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
matrix:
|
||||
- name: Markdown
|
||||
expect_match: false
|
||||
apsell:
|
||||
lang: en
|
||||
d: en_US
|
||||
ignore-case: true
|
||||
dictionary:
|
||||
wordlists:
|
||||
- .github/wordlist.txt
|
||||
output: wordlist.dic
|
||||
pipeline:
|
||||
- pyspelling.filters.markdown:
|
||||
markdown_extensions:
|
||||
- markdown.extensions.extra:
|
||||
- pyspelling.filters.html:
|
||||
comments: false
|
||||
attributes:
|
||||
- alt
|
||||
ignores:
|
||||
- ':matches(code, pre)'
|
||||
- code
|
||||
- pre
|
||||
- blockquote
|
||||
- img
|
||||
sources:
|
||||
- 'README.md'
|
||||
- 'FAQ.md'
|
||||
- 'docs/**'
|
||||
@@ -1,54 +0,0 @@
|
||||
ACLs
|
||||
Autoloading
|
||||
CAS
|
||||
Customizable
|
||||
ElastiCache
|
||||
FPM
|
||||
GC
|
||||
IANA
|
||||
Lua
|
||||
PSR
|
||||
Packagist
|
||||
PhpRedis
|
||||
Predis
|
||||
README
|
||||
Redis
|
||||
SHA
|
||||
SSL
|
||||
TCP
|
||||
OSS
|
||||
CLI
|
||||
TLS
|
||||
URI
|
||||
autoload
|
||||
autoloader
|
||||
autoloading
|
||||
backend
|
||||
backends
|
||||
behaviour
|
||||
customizable
|
||||
dataset
|
||||
de
|
||||
DevOPS
|
||||
extensibility
|
||||
keyspace
|
||||
keyspaces
|
||||
localhost
|
||||
namespace
|
||||
pipelining
|
||||
pluggable
|
||||
rebalanced
|
||||
rebalancing
|
||||
redis
|
||||
runtime
|
||||
sharding
|
||||
stunnel
|
||||
variadic
|
||||
commitish
|
||||
Kubernetes
|
||||
programmatically
|
||||
unhandled
|
||||
invalidations
|
||||
Sharded
|
||||
sharded
|
||||
Valkey
|
||||
@@ -7,7 +7,6 @@ on:
|
||||
branches:
|
||||
- main
|
||||
- v2.**
|
||||
- v3.**
|
||||
pull_request: null
|
||||
|
||||
permissions: {}
|
||||
@@ -144,6 +143,29 @@ jobs:
|
||||
echo "EXPECTED=${EXPECTED}"
|
||||
test "${CURRENT}" = "${EXPECTED}"
|
||||
|
||||
spelling:
|
||||
name: Spelling
|
||||
needs:
|
||||
- byte_level
|
||||
- syntax_errors
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Cache pip
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ~/.cache/pip
|
||||
key: ${{ runner.os }}-pip-codespell
|
||||
|
||||
- name: Install codespell
|
||||
run: pip install --user 'codespell>=2.2'
|
||||
|
||||
- name: Search for misspellings
|
||||
run: $(python -m site --user-base)/bin/codespell
|
||||
|
||||
changelog:
|
||||
|
||||
name: Changelog
|
||||
|
||||
@@ -4,24 +4,15 @@ on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- v2.**
|
||||
- v3.**
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
|
||||
update_release_draft:
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
|
||||
name: Update release draft
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
name: spellcheck
|
||||
on:
|
||||
pull_request:
|
||||
jobs:
|
||||
check-spelling:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
- name: Check Spelling
|
||||
uses: rojopolis/spellcheck-github-actions@0.33.1
|
||||
with:
|
||||
config_path: .github/spellcheck-settings.yml
|
||||
task_name: Markdown
|
||||
+23
-43
@@ -5,7 +5,6 @@ on:
|
||||
branches:
|
||||
- main
|
||||
- v2.**
|
||||
- v3.**
|
||||
pull_request:
|
||||
|
||||
concurrency:
|
||||
@@ -28,11 +27,10 @@ jobs:
|
||||
- '8.4'
|
||||
redis:
|
||||
- '4.0'
|
||||
- '6.2'
|
||||
- '7.2'
|
||||
- '7.4'
|
||||
- '8.0'
|
||||
- '8.2'
|
||||
- '8.4'
|
||||
|
||||
steps:
|
||||
|
||||
@@ -40,17 +38,17 @@ jobs:
|
||||
run: |
|
||||
# Mapping of original redis versions to client test containers
|
||||
declare -A redis_clients_version_mapping=(
|
||||
["8.4"]="8.4.0"
|
||||
["8.2"]="8.2.2-pre"
|
||||
["8.0"]="8.0.2"
|
||||
["8.0"]="8.0-RC2-pre"
|
||||
["7.4"]="7.4.2"
|
||||
["7.2"]="7.2.7"
|
||||
["6.2"]="6.2.17"
|
||||
)
|
||||
|
||||
# Mapping of redis version to stack version
|
||||
declare -A redis_stack_version_mapping=(
|
||||
["7.4"]="rs-7.4.0-v3"
|
||||
["7.2"]="rs-7.2.0-v15"
|
||||
["6.2"]="rs-6.2.6-v19"
|
||||
)
|
||||
|
||||
if [[ -v redis_clients_version_mapping[${{ matrix.redis }}] ]]; then
|
||||
@@ -82,17 +80,10 @@ jobs:
|
||||
compose-file: .github/docker-compose.yml
|
||||
services: ${{ env.DOCKER_SERVICE }}
|
||||
|
||||
- name: Start Redis unprotected image
|
||||
uses: hoverkraft-tech/compose-action@v2.0.1
|
||||
if: ${{ matrix.redis > '4.0' }}
|
||||
with:
|
||||
compose-file: .github/docker-compose.yml
|
||||
services: redis-unprotected
|
||||
|
||||
- name: Start Redis stack image
|
||||
id: stack_infra
|
||||
uses: hoverkraft-tech/compose-action@v2.0.1
|
||||
if: ${{ matrix.redis >= '7.2' && matrix.redis < '8.0' }}
|
||||
if: ${{ matrix.redis >= '6.2' && matrix.redis < '8.0' }}
|
||||
with:
|
||||
compose-file: .github/docker-compose.yml
|
||||
services: redis-stack
|
||||
@@ -110,7 +101,7 @@ jobs:
|
||||
with:
|
||||
php-version: ${{ matrix.php }}
|
||||
extensions: relay
|
||||
coverage: ${{ (matrix.php == '8.4' && matrix.redis == '8.0') && 'xdebug' || 'none' }}
|
||||
coverage: ${{ (matrix.php == '8.4' && matrix.redis == '7.4') && 'xdebug' || 'none' }}
|
||||
|
||||
- name: Install Composer dependencies
|
||||
uses: ramsey/composer-install@v2
|
||||
@@ -119,74 +110,63 @@ jobs:
|
||||
composer-options: ${{ matrix.php == '8.0' && '--ignore-platform-reqs' || '' }}
|
||||
|
||||
- name: Run tests
|
||||
if: ${{ matrix.php != '8.4' || matrix.redis != '8.0' }}
|
||||
if: ${{ matrix.php != '8.4' || matrix.redis != '7.4' }}
|
||||
run: vendor/bin/phpunit
|
||||
|
||||
- name: Run tests with coverage
|
||||
if: ${{ matrix.php == '8.4' && matrix.redis == '8.0' }}
|
||||
if: ${{ matrix.php == '8.4' && matrix.redis == '7.4' }}
|
||||
run: vendor/bin/phpunit --coverage-php build/cov/coverage-predis.cov --coverage-filter ./src
|
||||
|
||||
- name: Run tests using Relay
|
||||
if: ${{ matrix.php != '8.4' && matrix.redis >= '8.0' }}
|
||||
if: ${{ matrix.php != '8.4' && matrix.redis >= '6.2' }}
|
||||
run: vendor/bin/phpunit -c phpunit.relay.xml
|
||||
|
||||
- name: Run tests using Relay with coverage
|
||||
if: ${{ matrix.php == '8.4' && matrix.redis == '8.0' }}
|
||||
if: ${{ matrix.php == '8.4' && matrix.redis == '7.4' }}
|
||||
run: vendor/bin/phpunit -c phpunit.relay.xml --coverage-php build/cov/coverage-relay.cov --coverage-filter ./src
|
||||
|
||||
- name: Run tests against unprotected Redis
|
||||
if: ${{ (matrix.php != '8.4' || matrix.redis != '8.0') && matrix.redis > '4.0'}}
|
||||
run: vendor/bin/phpunit --group unprotected
|
||||
|
||||
- name: Run tests against unprotected Redis with coverage
|
||||
if: ${{ matrix.php == '8.4' && matrix.redis == '8.0' }}
|
||||
run: vendor/bin/phpunit --group unprotected --coverage-php build/cov/coverage-unprotected.cov --coverage-filter ./src
|
||||
|
||||
- name: Run stack tests
|
||||
if: ${{ (matrix.php != '8.4' || matrix.redis != '8.0') && matrix.redis >= '7.2' }}
|
||||
if: ${{ (matrix.php != '8.4' || matrix.redis != '7.4') && matrix.redis >= '6.2' }}
|
||||
run: vendor/bin/phpunit --group realm-stack
|
||||
|
||||
- name: Run stack tests with coverage
|
||||
if: ${{ matrix.php == '8.4' && matrix.redis == '8.0' }}
|
||||
if: ${{ matrix.php == '8.4' && matrix.redis == '7.4' && steps.stack_infra.conclusion == 'success' }}
|
||||
run: vendor/bin/phpunit --group realm-stack --coverage-php build/cov/coverage-stack.cov --coverage-filter ./src
|
||||
env:
|
||||
REDIS_STACK_SERVER_PORT: 6479
|
||||
|
||||
- name: Run stack tests using Relay
|
||||
if: ${{ (matrix.php != '8.4' || matrix.redis != '8.0') && matrix.redis >= '7.2' }}
|
||||
if: ${{ matrix.php != '8.4' && matrix.redis == '7.4' }}
|
||||
run: vendor/bin/phpunit --group realm-stack -c phpunit.relay.xml
|
||||
|
||||
- name: Run stack tests using Relay with coverage
|
||||
if: ${{ matrix.php == '8.4' && matrix.redis == '8.0' }}
|
||||
if: ${{ matrix.php == '8.4' && matrix.redis == '7.4' }}
|
||||
run: vendor/bin/phpunit --group realm-stack -c phpunit.relay.xml --coverage-php build/cov/coverage-stack-relay.cov --coverage-filter ./src
|
||||
env:
|
||||
REDIS_STACK_SERVER_PORT: 6479
|
||||
|
||||
- name: Run tests against cluster
|
||||
if: ${{ (matrix.php != '8.4' || matrix.redis != '8.0') && steps.cluster_infra.conclusion == 'success' }}
|
||||
if: ${{ (matrix.php != '8.4' || matrix.redis != '7.4') && steps.cluster_infra.conclusion == 'success' }}
|
||||
run: |
|
||||
vendor/bin/phpunit --group cluster
|
||||
|
||||
- name: Run tests against cluster with coverage
|
||||
if: ${{ matrix.php == '8.4' && matrix.redis == '8.0' && steps.cluster_infra.conclusion == 'success' }}
|
||||
if: ${{ matrix.php == '8.4' && matrix.redis == '7.4' && steps.cluster_infra.conclusion == 'success' }}
|
||||
run: |
|
||||
vendor/bin/phpunit --group cluster --coverage-php build/cov/coverage-cluster.cov --coverage-filter ./src
|
||||
|
||||
- name: Run tests against cluster using Relay
|
||||
if: ${{ matrix.php != '8.4' && matrix.redis == '8.0' }}
|
||||
if: ${{ matrix.php != '8.4' && matrix.redis == '7.4' }}
|
||||
run: |
|
||||
sleep 5
|
||||
vendor/bin/phpunit -c phpunit.relay.xml --group cluster
|
||||
|
||||
- name: Run tests against cluster using Relay with coverage
|
||||
if: ${{ matrix.php == '8.4' && matrix.redis == '8.0' }}
|
||||
run: |
|
||||
sleep 5
|
||||
vendor/bin/phpunit -c phpunit.relay.xml --group cluster --coverage-php build/cov/coverage-cluster-relay.cov --coverage-filter ./src
|
||||
|
||||
- name: Merge coverage reports
|
||||
if: ${{ matrix.php == '8.4' && matrix.redis == '8.0' }}
|
||||
if: ${{ matrix.php == '8.4' && matrix.redis == '7.4' }}
|
||||
run: php vendor/bin/phpcov merge --clover build/logs/clover.xml build/cov
|
||||
|
||||
- name: Send coverage to Coveralls
|
||||
uses: coverallsapp/github-action@v2
|
||||
if: ${{ matrix.php == '8.4' && matrix.redis == '8.0' }}
|
||||
if: ${{ matrix.php == '8.4' && matrix.redis == '7.4' }}
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
parallel: true
|
||||
|
||||
+33
-78
@@ -1,83 +1,9 @@
|
||||
## Changelog
|
||||
|
||||
## v3.3.0 (2025-11-24)
|
||||
### Added
|
||||
- Added cluster support for `XADD`, `XDEL` and `XRANGE` (#1587)
|
||||
- Added prefixable interface for `HEXPIRE` and `HEXPIRETIME` (#1592)
|
||||
- Added new experimental CAS/CAD functionality (#1609)
|
||||
- Added temporary `XREADGROUP_CLAIM` command (#1608)
|
||||
- Added support for `MSET` command (#1610)
|
||||
- Added experimental support for `FT.HYBRID` (#1607)
|
||||
|
||||
### Changed
|
||||
- Improved compatiblity with Relay (#1597)
|
||||
- Refactor pipeline data writing depends on connection type (#1586)
|
||||
|
||||
## v3.2.0 (2025-08-05)
|
||||
### Added
|
||||
- Added support for `XDELEX` and `XACKDEL` (#1580)
|
||||
- Added missing VSIM argument (#1582)
|
||||
|
||||
### Changed
|
||||
- Extended `XTRIM` and `XADD` commands with new parameters (#1580)
|
||||
|
||||
### Maintenance
|
||||
- Updated Redis 8.2 test image (#1583)
|
||||
- Added test coverage for updated Vamana (#1584)
|
||||
|
||||
## v3.1.0 (2025-07-22)
|
||||
### Added
|
||||
- Add experimental support for vector sets commands (#1550)
|
||||
- Added support for `XACK` command (#1555)
|
||||
- Added support for `XCLAIM` command (#1557)
|
||||
- Added support for `XPENDING` command (#1558)
|
||||
- Added support for `XSETID` command (#1559)
|
||||
- Added validation and support for the new `BITOP` command operations (#1566)
|
||||
|
||||
### Changed
|
||||
- Handle and retry `LOADING` errors from Sentinel replicas (#1536)
|
||||
- Retry all exceptions from Sentinel replicas (#1577)
|
||||
|
||||
## v2.4.1 (2025-11-12)
|
||||
### Fixed
|
||||
- Fixed PHP 8.4 deprecated call to `stream_context_set_option()` (#1545)
|
||||
- Fixed return type for `ZCOUNT` to be `int` (#1547)
|
||||
- Fixed throwing `CommunicationException` when stream is EOF (#1548)
|
||||
- Removed automatic `conn_uid` parameter assignment (#1552)
|
||||
- Fixed wrong command API call on prefix processing (#1554)
|
||||
- Fixed `XREAD` response parsing while read null (#1563)
|
||||
- Fixed `XINFO` command responses parsing (#1560)
|
||||
- Marked missing commands as Prefixable (#1576)
|
||||
|
||||
## v3.0.1 (2025-05-16)
|
||||
### Fixed
|
||||
- Send `default` user if only password is used for authentication (#1535)
|
||||
|
||||
## v3.0.0 (2025-05-02)
|
||||
### Added
|
||||
- ⚠️ Added support for transactions for clustered connections (#1497)
|
||||
- Added support for RESP3 communication protocol (#1047)
|
||||
- Added support for RESP3 push notifications (#1316)
|
||||
- Added support for Sharded Pub/Sub (#1303)
|
||||
- Added support for `XGROUP` commands (#1324)
|
||||
- Added support for `XREADGROUP` command (#1327)
|
||||
- Added support for `XAUTOCLAIM` command (#1328)
|
||||
- Added support for `XINFO` commands (#1331)
|
||||
- Added support for Redis 7.4 `XREAD` and `HSCAN` interface changes (#1452)
|
||||
|
||||
### Changed
|
||||
- ⚠️ Refactored Relay integration (#1423)
|
||||
- ⚠️ Changed interface of `CLIENT` command (#1337)
|
||||
- ⚠️ Changed interfaces for commands to support Redis 6.2 — 7.0 arguments (#1330)
|
||||
- ⚠️ Changed default search `DIALECT` to `2` (#1516)
|
||||
- ⚠️ Implemented PSR-7 compatible stream abstraction (#1450)
|
||||
- ⚠️ Improved pipeline abstractions (#1438)
|
||||
- ⚠️ Improved connection handshake (#1431)
|
||||
|
||||
### Fixed
|
||||
- Fixed single persistent connection using the same resource (#1512)
|
||||
|
||||
### Maintenance
|
||||
- Revisit incompatible tests against Relay (#1537)
|
||||
- Fixed return type for `ZCOUNT` to be `int` (#1546)
|
||||
- Removed automatic `conn_uid` parameter assignment (#1551)
|
||||
|
||||
## v2.4.0 (2025-04-30)
|
||||
### Added
|
||||
@@ -114,7 +40,36 @@
|
||||
- Filter out available replicas based on link status flag (#1440)
|
||||
- Respect `prefix` for `ZPOPMIN`, `ZPOPMAX`, `ZMSCORE`, `LMOVE`, `BLMOVE`, `SMISMEMBER` and `GEOSEARCH` (#1451, #1453, #1455, #1468)
|
||||
- Updated test infrastructure (#1510)
|
||||
-
|
||||
|
||||
### Fixed
|
||||
- Fixed Relay support when using Redis Cluster (#1397)
|
||||
- Fixed `cmsincrby()` type annotation (#1333)
|
||||
- Fixed `set()` type annotation (#1394)
|
||||
- Fixed operator precedence in connection factory (#1405)
|
||||
- Fixed a bug with `null` arguments in `set()` method (#1470, #1471)
|
||||
|
||||
## v2.2.2 (2023-09-13)
|
||||
|
||||
### Added
|
||||
- Added `client_info` client parameter
|
||||
- Added support for `CLUSTER` container command
|
||||
|
||||
### Fixed
|
||||
- Fixed `EXPIRETIME` not using `prefix`
|
||||
- Disabled `CLIENT SETINFO` calls by default
|
||||
|
||||
## v2.2.1 (2023-08-15)
|
||||
|
||||
### Added
|
||||
- Added support for `WAITAOF` command (#1357)
|
||||
- Added support for `SHUTDOWN` command (#1359)
|
||||
- Added support for `FUNCTION` command (#1332)
|
||||
- Added support for new optional `PEXPIRE`, `PEXPIREAT` and `COMMAND`
|
||||
- Added missing Redis Stack commands to `KeyPrefixProcessor` (#1358)
|
||||
|
||||
### Changed
|
||||
- Set client name and version when establishing a connection (#1347)
|
||||
|
||||
## v2.2.0 (2023-06-14)
|
||||
|
||||
Predis v2.2.0 introduces official support for [Redis Stack](https://redis.io/docs/stack/) as well as a [Relay](https://github.com/cachewerk/relay) integration for substantially [faster read performance](https://github.com/predis/predis/wiki/Using-Relay).
|
||||
|
||||
@@ -203,7 +203,6 @@ when needed. The client options supported by default in Predis are:
|
||||
- `aggregate`: configures the client with a custom aggregate connection (callable).
|
||||
- `parameters`: list of default connection parameters for aggregate connections.
|
||||
- `commands`: specifies a command factory instance to use through the library.
|
||||
- `readTimeout`: (cluster only) Timeout between read operations while loop over connections.
|
||||
|
||||
Users can also provide custom options with values or callable objects (for lazy initialization) that
|
||||
are stored in the options container for later use through the library.
|
||||
@@ -245,26 +244,6 @@ $options = ['cluster' => 'redis'];
|
||||
$client = new Predis\Client($parameters, $options);
|
||||
```
|
||||
|
||||
#### Redis Gears with cluster ####
|
||||
|
||||
Since Redis v7.2, Redis Gears module is a part of Redis Stack bundle. Client supports a variety of
|
||||
Redis Gears commands that can be used with OSS cluster API. Currently, before using any Redis
|
||||
Gears commands against OSS cluster Redis server needs to be aware of cluster topology.
|
||||
|
||||
`REDISGEARS_2.REFRESHCLUSTER` command should be called against **each master node** (read replicas
|
||||
should be ignored) **on cluster creation and each time cluster topology changes**.
|
||||
|
||||
In most cases this actions should be performed from the CLI interface by the administrator, DevOPS
|
||||
or even Kubernetes, depends on your infrastructure managing process. However, client provides an API
|
||||
to do this programmatically.
|
||||
|
||||
```php
|
||||
/** @var \Predis\Connection\Cluster\ClusterInterface $connection */
|
||||
$connection->executeCommandOnEachNode(
|
||||
new \Predis\Command\RawCommand('REDISGEARS_2.REFRESHCLUSTER')
|
||||
);
|
||||
```
|
||||
|
||||
#### Replication ####
|
||||
|
||||
The client can be configured to operate in a single master / multiple slaves setup to provide better
|
||||
@@ -380,25 +359,6 @@ This abstraction can perform check-and-set operations thanks to `WATCH` and `UNW
|
||||
automatic retries of transactions aborted by Redis when `WATCH`ed keys are touched. For an example
|
||||
of a transaction using CAS you can see [the following example](examples/transaction_using_cas.php).
|
||||
|
||||
#### Support for clustered connections ####
|
||||
|
||||
Since Predis v3.0 transactions could be used with clustered connections. However, it has some limitations due to the
|
||||
fact that Redis doesn't support distributed transactions. All keys in the transaction context should operate on the same
|
||||
hash slot, due to this limitation it's recommended to use `{}` syntax to make sure that all keys will be mapped to the same hash
|
||||
slot. Apart from it no additional configuration needed on a client side.
|
||||
|
||||
```php
|
||||
$redis = $this->getClient();
|
||||
|
||||
$response = $redis->transaction(function (MultiExec $tx) {
|
||||
$tx->set('{foo}foo', 'value');
|
||||
$tx->set('{foo}bar', 'value');
|
||||
$tx->set('{foo}baz', 'value');
|
||||
});
|
||||
|
||||
// ['OK', 'OK', 'OK']
|
||||
```
|
||||
|
||||
|
||||
### Adding new commands ###
|
||||
|
||||
@@ -509,149 +469,7 @@ $client = new Predis\Client('tcp://127.0.0.1', [
|
||||
For a more in-depth insight on how to create new connection backends you can refer to the actual
|
||||
implementation of the standard connection classes available in the `Predis\Connection` namespace.
|
||||
|
||||
## RESP3 ##
|
||||
|
||||
### Connection ###
|
||||
To establish the connection using the [RESP3](https://github.com/redis/redis-specifications/blob/master/protocol/RESP3.md) protocol, you need to set parameter `protocol => 3`. The default protocol is RESP2.
|
||||
|
||||
You can pass parameter as configuration option in array or as a query parameter in `redis_url`
|
||||
|
||||
```php
|
||||
// Configuration option
|
||||
$client = new \Predis\Client(['protocol' => 3]);
|
||||
|
||||
// Redis URL
|
||||
$client = new \Predis\Client('redis://localhost:6379?protocol=3');
|
||||
|
||||
// ["proto" => "3"]
|
||||
$client->executeRaw(['HELLO']);
|
||||
```
|
||||
|
||||
### Command responses ###
|
||||
RESP3 protocol introduce a variety of new [response types](https://github.com/redis/redis-specifications/blob/master/protocol/RESP3.md#resp3-types),
|
||||
so on the client-side we have more explicit understanding on data types we retrieve from server. Here's some examples to show the difference
|
||||
between RESP2 and RESP3 responses.
|
||||
|
||||
#### Float responses ####
|
||||
``` php
|
||||
// RESP2 connection
|
||||
$client = new \Predis\Client();
|
||||
|
||||
$client->geoadd('my_geo', 11.111, 22.222, 'member1');
|
||||
|
||||
// [[0 => string(20) "11.11099988222122192", 1 => string(20) "22.22200052541037252"]]
|
||||
// RESP2 returns float values as simple strings.
|
||||
var_dump($client->geopos('my_geo', ['member1']));
|
||||
|
||||
// RESP3 connection
|
||||
$client = new \Predis\Client(['protocol' => 3]);
|
||||
|
||||
// [[0 => float(11.110999882221222), 1 => float(22.222000525410373)]]
|
||||
// RESP3 introduces new double type, that corresponds to PHP float.
|
||||
var_dump($client->geopos('my_geo', ['member1']));
|
||||
```
|
||||
|
||||
#### Aggregate types ####
|
||||
In RESP3 new aggregate type [Map](https://github.com/redis/redis-specifications/blob/master/protocol/RESP3.md#map-type)
|
||||
was introduced, that represents the sequence of field-value pairs. So it simplifies parsing, since we don't need to specify
|
||||
parsing strategy per command (RESP2) and instead relies on the type defined by protocol (RESP3).
|
||||
|
||||
In most cases RESP2 responses shouldn't differ from RESP3, since we added additional parsing for those
|
||||
command that return field-value pairs. However, since RESP2 requires additional parsing, it could be that some commands
|
||||
had lack of it and return unhandled responses. In this case there would be difference like this:
|
||||
|
||||
```php
|
||||
$client = new \Predis\Client();
|
||||
|
||||
// RESP2: ['field', 'value]
|
||||
$client->commandThatReturnsFieldValuePair('key');
|
||||
|
||||
$client = new \Predis\Client(['protocol' => 3]);
|
||||
|
||||
// RESP3: ['field' => 'value]
|
||||
$client->commandThatReturnsFieldValuePair('key');
|
||||
```
|
||||
|
||||
Feel free to open PR or GitHub issue if you face those protocol mismatching.
|
||||
|
||||
### Push notifications ###
|
||||
RESP3 introduce a concept of [push connection](https://github.com/redis/redis-specifications/blob/master/protocol/RESP3.md#push-type),
|
||||
is the one where server could send asynchronous data to client which was not explicitly requested. Predis 3.0 provides
|
||||
an API to establish this kind of connection as separate blocking process (worker) and invoke callbacks depends on push
|
||||
notification message type.
|
||||
|
||||
#### Consumer ####
|
||||
First of all, you need to set up a consumer connection and provide an optional callback that will be executed before
|
||||
event loop will be started. It allows you to subscribe on channels, enable keys invalidations tracking or enable monitor
|
||||
connection, any Redis command to let server know that you want to receive push notification within this connection.
|
||||
|
||||
```php
|
||||
// Make sure that RESP3 protocol enabled and read_write_timeout set 0,
|
||||
// so connection won't be killed by timeout.
|
||||
$client = new Predis\Client(['read_write_timeout' => 0, 'protocol' => 3]);
|
||||
|
||||
// Create push notifications consumer.
|
||||
// Provides callback where current consumer subscribes to few channels before
|
||||
// enter the loop.
|
||||
$push = $client->push(static function (ClientInterface $client) {
|
||||
$response = $client->subscribe('channel', 'control');
|
||||
$status = ($response[2] === 1) ? 'OK' : 'FAILED';
|
||||
echo "Channel subscription status: {$status}\n";
|
||||
});
|
||||
```
|
||||
|
||||
#### Dispatcher loop ####
|
||||
Dispatcher object allows you to attach a callback to given push notification type and run the actual worker process that
|
||||
listen for incoming push notifications. To be able to stop blocking process in runtime you can specify a condition and
|
||||
call `$dispatcher->stop()` method from given callback. In this example we're waiting for specific message `terminate`
|
||||
within `control` channel that we subscribed to before entering the loop.
|
||||
|
||||
```php
|
||||
// Storage for incoming notifications.
|
||||
$messages = [];
|
||||
|
||||
// Create dispatcher for push notifications.
|
||||
$dispatcher = new Predis\Consumer\Push\DispatcherLoop($push);
|
||||
|
||||
$dispatcher->attachCallback(
|
||||
PushResponseInterface::MESSAGE_DATA_TYPE,
|
||||
static function (array $payload, DispatcherLoopInterface $dispatcher) {
|
||||
global $messages;
|
||||
[$channel, $message] = $payload;
|
||||
|
||||
if ($channel === 'control' && $message === 'terminate') {
|
||||
echo "Terminating notification consumer.\n";
|
||||
$dispatcher->stop();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$messages[] = $message;
|
||||
echo "Received message: {$message}\n";
|
||||
}
|
||||
);
|
||||
|
||||
// Run consumer loop with attached callbacks.
|
||||
$dispatcher->run();
|
||||
|
||||
// Count all messages that were received during consumer loop.
|
||||
$messagesCount = count($messages);
|
||||
echo "We received: {$messagesCount} messages\n";
|
||||
```
|
||||
|
||||
This example shows a simple script to count all incoming messages from push notifications that we receive from
|
||||
subscribed channels until stop condition will be met. Examples available in `examples/` folder.
|
||||
|
||||
### Sharded pub/sub ###
|
||||
From Redis 7.0, sharded Pub/Sub is introduced in which shard channels are assigned to slots by the same algorithm used
|
||||
to assign keys to slots.
|
||||
|
||||
Predis 3.0 provides an API that allows to use pub/sub for Cluster connections using sharded pub/sub from Redis.
|
||||
You don't need to specify any additional configuration to enable sharded pub/sub, it will be automatically enabled if
|
||||
Cluster connection is using.
|
||||
|
||||
Implementation looks pretty much the same as Push notification, so you need to set up consumer
|
||||
and run it over Dispatcher loop object. All examples available in `examples/` folder.
|
||||
## Development ##
|
||||
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
// For example, to generate a test case for SET (which is represented by the
|
||||
// Predis\Command\Redis\StringSet class):
|
||||
//
|
||||
// $ ./bin/create-command-test --class=StringSet
|
||||
// $ ./bin/generate-command-test --class=StringSet
|
||||
//
|
||||
// Here is a list of optional arguments:
|
||||
//
|
||||
|
||||
+2
-3
@@ -22,13 +22,12 @@
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": "^7.2 || ^8.0",
|
||||
"psr/http-message": "^1.0|^2.0"
|
||||
"php": "^7.2 || ^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"friendsofphp/php-cs-fixer": "^3.3",
|
||||
"phpstan/phpstan": "^1.9",
|
||||
"phpunit/phpunit": "^8.0 || ~9.4.4",
|
||||
"phpunit/phpunit": "^8.0 || ^9.4",
|
||||
"phpunit/phpcov": "^6.0 || ^8.0"
|
||||
},
|
||||
"suggest": {
|
||||
|
||||
@@ -34,11 +34,11 @@ class SimpleDebuggableConnection extends StreamConnection
|
||||
|
||||
private function storeDebug(CommandInterface $command, $direction)
|
||||
{
|
||||
$firstArg = $command->getArgument(0);
|
||||
$firtsArg = $command->getArgument(0);
|
||||
$timestamp = round(microtime(true) - $this->tstart, 4);
|
||||
|
||||
$debug = $command->getId();
|
||||
$debug .= isset($firstArg) ? " $firstArg " : ' ';
|
||||
$debug .= isset($firtsArg) ? " $firtsArg " : ' ';
|
||||
$debug .= "$direction $this";
|
||||
$debug .= " [{$timestamp}s]";
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ $client = new Predis\Client($single_server + ['read_write_timeout' => 0]);
|
||||
$pubsub = $client->pubSubLoop();
|
||||
|
||||
// Create a dispatcher loop instance and attach a bunch of callbacks.
|
||||
$dispatcher = new Predis\Consumer\PubSub\DispatcherLoop($pubsub);
|
||||
$dispatcher = new Predis\PubSub\DispatcherLoop($pubsub);
|
||||
|
||||
// Demonstrate how to use a callable class as a callback for the dispatcher loop.
|
||||
class EventsListener implements Countable
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2025 Till Krüss
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use Predis\ClientInterface;
|
||||
use Predis\Consumer\Push\PushResponseInterface;
|
||||
|
||||
require __DIR__ . '/shared.php';
|
||||
|
||||
// 1. Create client with RESP3 protocol specified. Push notifications allowed only in RESP3 mode.
|
||||
$client = new Predis\Client($single_server + ['read_write_timeout' => 0, 'protocol' => 3]);
|
||||
|
||||
// 2. Create push notifications consumer. Provides callback where current consumer subscribes to few channels before enter the loop.
|
||||
$push = $client->push(static function (ClientInterface $client) {
|
||||
$response = $client->subscribe('channel', 'control');
|
||||
$status = ($response[2] === 1) ? 'OK' : 'FAILED';
|
||||
echo "Channel subscription status: {$status}\n";
|
||||
});
|
||||
|
||||
// 3. Run consumer that will handle message data type push notifications. And stops if certain message will be sent to control channel.
|
||||
// Send following commands via redis-cli to test:
|
||||
//
|
||||
// PUBLISH channel message1
|
||||
// PUBLISH channel message2
|
||||
// PUBLISH channel message3
|
||||
// PUBLISH control terminate
|
||||
// Data types should be changed in near future. Instead of Message data type it should be one of kind data types.
|
||||
|
||||
foreach ($push as $notification) {
|
||||
if ((null !== $notification) && $notification->getDataType() === PushResponseInterface::MESSAGE_DATA_TYPE) {
|
||||
if ($notification[1] === 'control' && $notification[2] === 'terminate') {
|
||||
echo "Terminating notification consumer.\n";
|
||||
$push->stop();
|
||||
break;
|
||||
}
|
||||
|
||||
$message = $notification[2];
|
||||
|
||||
echo "Received message: {$message}\n";
|
||||
}
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2025 Till Krüss
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use Predis\ClientInterface;
|
||||
use Predis\Consumer\DispatcherLoopInterface;
|
||||
use Predis\Consumer\Push\DispatcherLoop;
|
||||
use Predis\Consumer\Push\PushResponseInterface;
|
||||
|
||||
require __DIR__ . '/shared.php';
|
||||
|
||||
// 1. Create client with RESP3 protocol specified. Push notifications allowed only in RESP3 mode.
|
||||
$client = new Predis\Client($single_server + ['read_write_timeout' => 0, 'protocol' => 3]);
|
||||
|
||||
// 2. Create push notifications consumer. Provides callback where current consumer subscribes to few channels before enter the loop.
|
||||
$push = $client->push(static function (ClientInterface $client) {
|
||||
$response = $client->subscribe('channel', 'control');
|
||||
$status = ($response[2] === 1) ? 'OK' : 'FAILED';
|
||||
echo "Channel subscription status: {$status}\n";
|
||||
});
|
||||
|
||||
// 3. Storage for upcoming notifications.
|
||||
$messages = [];
|
||||
|
||||
// 4. Create dispatcher for push notifications.
|
||||
$dispatcher = new DispatcherLoop($push);
|
||||
|
||||
// 5. Attach callback for message data type. Print every message and store them in storage.
|
||||
// Send following commands via redis-cli to test:
|
||||
//
|
||||
// PUBLISH channel message1
|
||||
// PUBLISH channel message2
|
||||
// PUBLISH channel message3
|
||||
// PUBLISH control terminate
|
||||
// Data types should be changed in near future. Instead of Message data type it should be one of kind data types.
|
||||
|
||||
$dispatcher->attachCallback(
|
||||
PushResponseInterface::MESSAGE_DATA_TYPE,
|
||||
static function (array $payload, DispatcherLoopInterface $dispatcher) {
|
||||
global $messages;
|
||||
[$channel, $message] = $payload;
|
||||
|
||||
if ($channel === 'control' && $message === 'terminate') {
|
||||
echo "Terminating notification consumer.\n";
|
||||
$dispatcher->stop();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$messages[] = $message;
|
||||
echo "Received message: {$message}\n";
|
||||
}
|
||||
);
|
||||
|
||||
// 6. Run consumer loop with attached callbacks.
|
||||
$dispatcher->run();
|
||||
|
||||
// 7. Count all messages that were received during consumer loop.
|
||||
$messagesCount = count($messages);
|
||||
echo "We received: {$messagesCount} messages\n";
|
||||
@@ -1,91 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2025 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';
|
||||
|
||||
// This is a basic example on how to use the Predis\DispatcherLoop class in sharded pub/sub mode.
|
||||
//
|
||||
// Both channels belong to different shards. So in sharded mode we can subscribe
|
||||
// and receive messages from different shard channels.
|
||||
//
|
||||
// To see this example in action you can just use redis-cli and publish some
|
||||
// messages to the '{channels}_events' and 'control' channel, e.g.:
|
||||
|
||||
// ./redis-cli
|
||||
// SPUBLISH {channels}_events first
|
||||
// SPUBLISH {channels}_events second
|
||||
// SPUBLISH {channels}_events third
|
||||
// SPUBLISH control terminate_dispatcher
|
||||
|
||||
// 1. Create client and setup RW timeout to 0.
|
||||
$client = new Client(
|
||||
[
|
||||
'tcp://127.0.0.1:6372?read_write_timeout=0',
|
||||
'tcp://127.0.0.1:6373?read_write_timeout=0',
|
||||
'tcp://127.0.0.1:6374?read_write_timeout=0',
|
||||
], [
|
||||
'cluster' => 'redis',
|
||||
]);
|
||||
|
||||
// 2. Run pub/sub loop.
|
||||
$pubSub = $client->pubSubLoop();
|
||||
|
||||
// 3. Create a dispatcher loop instance and attach a bunch of callbacks.
|
||||
$dispatcher = new Predis\Consumer\PubSub\DispatcherLoop($pubSub);
|
||||
|
||||
// 4. Demonstrate how to use a callable class as a callback for the dispatcher loop.
|
||||
class EventsListener implements Countable
|
||||
{
|
||||
private $events;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->events = [];
|
||||
}
|
||||
|
||||
public function count()
|
||||
{
|
||||
return count($this->events);
|
||||
}
|
||||
|
||||
public function getEvents()
|
||||
{
|
||||
return $this->events;
|
||||
}
|
||||
|
||||
public function __invoke($payload, $dispatcher)
|
||||
{
|
||||
$this->events[] = $payload;
|
||||
}
|
||||
}
|
||||
|
||||
// 5. Attach our callable class to the dispatcher.
|
||||
$dispatcher->attachCallback('{channels}_events', $events = new EventsListener());
|
||||
|
||||
// 6. Attach a function to control the dispatcher loop termination with a message.
|
||||
$dispatcher->attachCallback('control', function ($payload, $dispatcher) {
|
||||
if ($payload === 'terminate_dispatcher') {
|
||||
$dispatcher->stop();
|
||||
}
|
||||
});
|
||||
|
||||
// 7. Run the dispatcher loop until the callback attached to the 'control' channel
|
||||
// receives 'terminate_dispatcher' as a message.
|
||||
$dispatcher->run();
|
||||
|
||||
// Display our achievements!
|
||||
echo "We received {$events->count()} messages!", PHP_EOL;
|
||||
|
||||
// Say goodbye :-)
|
||||
echo 'Goodbye from Redis!', PHP_EOL;
|
||||
@@ -1,64 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2025 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';
|
||||
|
||||
// 1. Create client and setup RW timeout to 0.
|
||||
$client = new Client(
|
||||
[
|
||||
'tcp://127.0.0.1:6372?read_write_timeout=0',
|
||||
'tcp://127.0.0.1:6373?read_write_timeout=0',
|
||||
'tcp://127.0.0.1:6374?read_write_timeout=0',
|
||||
], [
|
||||
'cluster' => 'redis',
|
||||
]);
|
||||
|
||||
// 2. Run pub/sub loop. Sharded channels belongs to different shards.
|
||||
$pubSub = $client->pubSubLoop();
|
||||
$pubSub->ssubscribe('{channels}_notifications');
|
||||
$pubSub->ssubscribe('control_channel');
|
||||
|
||||
// Start processing the pubsup messages. Open a terminal and use redis-cli
|
||||
// to push messages to the channels. Examples:
|
||||
// ./redis-cli SPUBLISH {channels}_notifications "this is a test"
|
||||
// ./redis-cli SPUBLISH control_channel quit_loop
|
||||
foreach ($pubSub as $message) {
|
||||
switch ($message->kind) {
|
||||
case 'ssubscribe':
|
||||
echo "Subscribed to {$message->channel}", PHP_EOL;
|
||||
break;
|
||||
|
||||
case 'message':
|
||||
if ($message->channel == 'control_channel') {
|
||||
if ($message->payload == 'quit_loop') {
|
||||
echo 'Aborting pubsub loop...', PHP_EOL;
|
||||
$pubSub->sunsubscribe();
|
||||
} else {
|
||||
echo "Received an unrecognized command: {$message->payload}.", PHP_EOL;
|
||||
}
|
||||
} else {
|
||||
echo "Received the following message from {$message->channel}:",
|
||||
PHP_EOL, " {$message->payload}", PHP_EOL, PHP_EOL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Always unset the pubsub consumer instance when you are done! The
|
||||
// class destructor will take care of cleanups and prevent protocol
|
||||
// desynchronizations between the client and the server.
|
||||
unset($pubsub);
|
||||
|
||||
// Say goodbye :-)
|
||||
echo 'Goodbye from Redis!', PHP_EOL;
|
||||
@@ -12,6 +12,9 @@ parameters:
|
||||
- message: "#^Cannot cast Predis\\\\Connection\\\\ConnectionInterface to string\\.$#"
|
||||
count: 1
|
||||
path: src/Client.php
|
||||
# phpiredis extension is not installed
|
||||
- "#^Function phpiredis_\\w+ not found\\.$#"
|
||||
- "#^Constant PHPIREDIS_#"
|
||||
# "new static" in non-final classes
|
||||
- message: "#^Unsafe usage of new static\\(\\)\\.$#"
|
||||
count: 3
|
||||
@@ -26,6 +29,9 @@ parameters:
|
||||
- message: "#^Call to an undefined method Predis\\\\Command\\\\FactoryInterface\\:\\:undefine\\(\\)\\.$#"
|
||||
count: 1
|
||||
path: src/Configuration/Option/Commands.php
|
||||
- message: "#^Access to an undefined property Predis\\\\Configuration\\\\OptionsInterface\\:\\:\\$parameters\\.$#"
|
||||
count: 1
|
||||
path: src/Configuration/Option/Connections.php
|
||||
- message: "#^Access to an undefined property Predis\\\\Connection\\\\ParametersInterface\\:\\:\\$weight\\.$#"
|
||||
count: 1
|
||||
path: src/Connection/Cluster/PredisCluster.php
|
||||
|
||||
+3
-12
@@ -17,19 +17,15 @@
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
|
||||
<logging>
|
||||
<log type="coverage-php" target="build/cov/coverage.cov"/>
|
||||
</logging>
|
||||
|
||||
<groups>
|
||||
<exclude>
|
||||
<group>relay-incompatible</group>
|
||||
<group>relay-resp3</group>
|
||||
<group>realm-webdis</group>
|
||||
<group>realm-stack</group>
|
||||
<group>ext-curl</group>
|
||||
<group>ext-phpiredis</group>
|
||||
<group>cluster</group>
|
||||
<group>gears</group>
|
||||
<group>unprotected</group>
|
||||
</exclude>
|
||||
</groups>
|
||||
|
||||
@@ -42,17 +38,12 @@
|
||||
<php>
|
||||
<const name="REDIS_SERVER_HOST" value="127.0.0.1" />
|
||||
<const name="REDIS_SERVER_PORT" value="6379" />
|
||||
<const name="REDIS_UNPROTECTED_SERVER_PORT" value="6380" />
|
||||
<const name="REDIS_SERVER_DBNUM" value="0" />
|
||||
<const name="REDIS_PASSWORD" value="foobar" />
|
||||
<env name="USE_RELAY" value="true" />
|
||||
<env name="REDIS_STACK_SERVER_PORT" value="6479" />
|
||||
|
||||
<!-- Redis Cluster -->
|
||||
<!-- Only master nodes endpoints included -->
|
||||
<const
|
||||
name="REDIS_CLUSTER_ENDPOINTS"
|
||||
value="127.0.0.1:6372?password=foobar,127.0.0.1:6373?password=foobar,127.0.0.1:6374?password=foobar"
|
||||
/>
|
||||
<const name="REDIS_CLUSTER_ENDPOINTS" value="127.0.0.1:6372,127.0.0.1:6373,127.0.0.1:6374" />
|
||||
</php>
|
||||
</phpunit>
|
||||
|
||||
+11
-15
@@ -10,9 +10,6 @@
|
||||
stopOnFailure="false"
|
||||
beStrictAboutTestsThatDoNotTestAnything="true"
|
||||
>
|
||||
<php>
|
||||
<ini name="error_reporting" value="E_ALL & ~E_DEPRECATED"/>
|
||||
</php>
|
||||
|
||||
<testsuites>
|
||||
<testsuite name="Predis Test Suite">
|
||||
@@ -20,19 +17,23 @@
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
|
||||
<logging>
|
||||
<log type="coverage-php" target="build/cov/coverage.cov"/>
|
||||
</logging>
|
||||
<coverage processUncoveredFiles="true">
|
||||
<include>
|
||||
<directory suffix=".php">./src</directory>
|
||||
</include>
|
||||
<report>
|
||||
<clover outputFile="build/logs/clover.xml"/>
|
||||
</report>
|
||||
</coverage>
|
||||
|
||||
<groups>
|
||||
<exclude>
|
||||
<group>realm-webdis</group>
|
||||
<group>realm-stack</group>
|
||||
<group>ext-relay</group>
|
||||
<group>ext-curl</group>
|
||||
<group>ext-phpiredis</group>
|
||||
<group>cluster</group>
|
||||
<group>gears</group>
|
||||
<group>gears-cluster</group>
|
||||
<group>unprotected</group>
|
||||
<!-- <group>connected</group> -->
|
||||
<!-- <group>disconnected</group> -->
|
||||
<!-- <group>commands</group> -->
|
||||
@@ -49,17 +50,12 @@
|
||||
<php>
|
||||
<const name="REDIS_SERVER_HOST" value="127.0.0.1" />
|
||||
<const name="REDIS_SERVER_PORT" value="6379" />
|
||||
<const name="REDIS_UNPROTECTED_SERVER_PORT" value="6380" />
|
||||
<const name="REDIS_SERVER_DBNUM" value="0" />
|
||||
<const name="REDIS_PASSWORD" value="foobar" />
|
||||
<env name="USE_RELAY" value="false" />
|
||||
<env name="REDIS_STACK_SERVER_PORT" value="6479" />
|
||||
|
||||
<!-- Redis Cluster -->
|
||||
<!-- Only master nodes endpoints included -->
|
||||
<const
|
||||
name="REDIS_CLUSTER_ENDPOINTS"
|
||||
value="127.0.0.1:6372?password=foobar,127.0.0.1:6373?password=foobar,127.0.0.1:6374?password=foobar"
|
||||
/>
|
||||
<const name="REDIS_CLUSTER_ENDPOINTS" value="127.0.0.1:6372,127.0.0.1:6373,127.0.0.1:6374" />
|
||||
</php>
|
||||
</phpunit>
|
||||
|
||||
+6
-23
@@ -16,9 +16,9 @@ use ArrayIterator;
|
||||
use InvalidArgumentException;
|
||||
use IteratorAggregate;
|
||||
use Predis\Command\CommandInterface;
|
||||
use Predis\Command\Container\ContainerFactory;
|
||||
use Predis\Command\Container\ContainerInterface;
|
||||
use Predis\Command\RawCommand;
|
||||
use Predis\Command\Redis\Container\ContainerFactory;
|
||||
use Predis\Command\Redis\Container\ContainerInterface;
|
||||
use Predis\Command\ScriptCommand;
|
||||
use Predis\Configuration\Options;
|
||||
use Predis\Configuration\OptionsInterface;
|
||||
@@ -26,15 +26,14 @@ use Predis\Connection\ConnectionInterface;
|
||||
use Predis\Connection\Parameters;
|
||||
use Predis\Connection\ParametersInterface;
|
||||
use Predis\Connection\RelayConnection;
|
||||
use Predis\Consumer\PubSub\Consumer as PubSubConsumer;
|
||||
use Predis\Consumer\PubSub\RelayConsumer as RelayPubSubConsumer;
|
||||
use Predis\Consumer\Push\Consumer as PushConsumer;
|
||||
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;
|
||||
@@ -54,7 +53,7 @@ use Traversable;
|
||||
*/
|
||||
class Client implements ClientInterface, IteratorAggregate
|
||||
{
|
||||
public const VERSION = '3.3.0';
|
||||
public const VERSION = '2.4.1';
|
||||
|
||||
/** @var OptionsInterface */
|
||||
private $options;
|
||||
@@ -380,7 +379,6 @@ class Client implements ClientInterface, IteratorAggregate
|
||||
public function executeCommand(CommandInterface $command)
|
||||
{
|
||||
$response = $this->connection->executeCommand($command);
|
||||
$parameters = $this->connection->getParameters();
|
||||
|
||||
if ($response instanceof ResponseInterface) {
|
||||
if ($response instanceof ErrorResponseInterface) {
|
||||
@@ -390,11 +388,7 @@ class Client implements ClientInterface, IteratorAggregate
|
||||
return $response;
|
||||
}
|
||||
|
||||
if ($parameters->protocol === 2) {
|
||||
return $command->parseResponse($response);
|
||||
}
|
||||
|
||||
return $command->parseResp3Response($response);
|
||||
return $command->parseResponse($response);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -555,17 +549,6 @@ class Client implements ClientInterface, IteratorAggregate
|
||||
return $this->sharedContextFactory('createPubSub', func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new push notifications consumer.
|
||||
*
|
||||
* @param callable|null $preLoopCallback Callback that should be called on client before enter a loop.
|
||||
* @return PushConsumer
|
||||
*/
|
||||
public function push(?callable $preLoopCallback = null): PushConsumer
|
||||
{
|
||||
return new PushConsumer($this, $preLoopCallback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Actual publish/subscribe context initializer method.
|
||||
*
|
||||
|
||||
@@ -19,7 +19,6 @@ 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\HybridSearch\HybridSearchQuery;
|
||||
use Predis\Command\Argument\Search\ProfileArguments;
|
||||
use Predis\Command\Argument\Search\SchemaFields\FieldInterface;
|
||||
use Predis\Command\Argument\Search\SearchArguments;
|
||||
@@ -39,22 +38,20 @@ 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\Container\ACL;
|
||||
use Predis\Command\Container\CLIENT;
|
||||
use Predis\Command\Container\FUNCTIONS;
|
||||
use Predis\Command\Container\Json\JSONDEBUG;
|
||||
use Predis\Command\Container\Search\FTCONFIG;
|
||||
use Predis\Command\Container\Search\FTCURSOR;
|
||||
use Predis\Command\Container\XGROUP;
|
||||
use Predis\Command\Redis\VADD;
|
||||
use Predis\Command\Redis\Container\ACL;
|
||||
use Predis\Command\Redis\Container\CLUSTER;
|
||||
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\Command\Redis\HGETEX;
|
||||
use Predis\Command\Redis\HSETEX;
|
||||
|
||||
/**
|
||||
* Interface defining a client-side context such as a pipeline or transaction.
|
||||
*
|
||||
* @method $this copy(string $source, string $destination, int $db = -1, bool $replace = false)
|
||||
* @method $this del(array|string $keys)
|
||||
* @method $this delex(string $key, string $flag, $flagValue)
|
||||
* @method $this digest(string $key)
|
||||
* @method $this dump($key)
|
||||
* @method $this exists($key)
|
||||
* @method $this expire($key, $seconds, string $expireOption = '')
|
||||
@@ -64,8 +61,8 @@ use Predis\Command\Redis\VADD;
|
||||
* @method $this move($key, $db)
|
||||
* @method $this object($subcommand, $key)
|
||||
* @method $this persist($key)
|
||||
* @method $this pexpire($key, $milliseconds, string $option = null)
|
||||
* @method $this pexpireat($key, $timestamp, string $option = null)
|
||||
* @method $this pexpire($key, $milliseconds)
|
||||
* @method $this pexpireat($key, $timestamp)
|
||||
* @method $this pttl($key)
|
||||
* @method $this randomkey()
|
||||
* @method $this rename($key, $target)
|
||||
@@ -129,7 +126,6 @@ use Predis\Command\Redis\VADD;
|
||||
* @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 fthybrid(string $index, HybridSearchQuery $query)
|
||||
* @method $this ftinfo(string $index)
|
||||
* @method $this ftprofile(string $index, ProfileArguments $arguments)
|
||||
* @method $this ftsearch(string $index, string $query, ?SearchArguments $arguments = null)
|
||||
@@ -152,10 +148,9 @@ use Predis\Command\Redis\VADD;
|
||||
* @method $this incrbyfloat($key, $increment)
|
||||
* @method $this mget(array $keys)
|
||||
* @method $this mset(array $dictionary)
|
||||
* @method $this msetex(array $dictionary, ?string $existModifier = null, ?string $expireResolution = null, ?int $expireTTL = null)
|
||||
* @method $this msetnx(array $dictionary)
|
||||
* @method $this psetex($key, $milliseconds, $value)
|
||||
* @method $this set($key, $value, $expireResolution = null, $expireTTL = null, $flag = null, $flagValue = null)
|
||||
* @method $this set($key, $value, $expireResolution = null, $expireTTL = null, $flag = null)
|
||||
* @method $this setbit($key, $offset, $value)
|
||||
* @method $this setex($key, $seconds, $value)
|
||||
* @method $this setnx($key, $value)
|
||||
@@ -247,9 +242,6 @@ use Predis\Command\Redis\VADD;
|
||||
* @method $this srandmember($key, $count = null)
|
||||
* @method $this srem($key, $member)
|
||||
* @method $this sscan($key, $cursor, ?array $options = null)
|
||||
* @method $this ssubscribe(string ...$shardChannels)
|
||||
* @method $this subscribe(string ...$channels)
|
||||
* @method $this sunsubscribe(?string ...$shardChannels = null)
|
||||
* @method $this sunion(array|string $keys)
|
||||
* @method $this sunionstore($destination, array|string $keys)
|
||||
* @method $this tdigestadd(string $key, float ...$value)
|
||||
@@ -289,22 +281,6 @@ use Predis\Command\Redis\VADD;
|
||||
* @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 xack(string $key, string $group, string ...$id)
|
||||
* @method $this xackdel(string $key, string $group, string $mode, array $ids)
|
||||
* @method $this xadd(string $key, array $dictionary, string $id = '*', array $options = null)
|
||||
* @method $this xautoclaim(string $key, string $group, string $consumer, int $minIdleTime, string $start, ?int $count = null, bool $justId = false)
|
||||
* @method $this xclaim(string $key, string $group, string $consumer, int $minIdleTime, string|array $ids, ?int $idle = null, ?int $time = null, ?int $retryCount = null, bool $force = false, bool $justId = false, ?string $lastId = null)
|
||||
* @method $this xdel(string $key, string ...$id)
|
||||
* @method $this xdelex(string $key, string $mode, array $ids)
|
||||
* @method $this xlen(string $key)
|
||||
* @method $this xpending(string $key, string $group, ?int $minIdleTime = null, ?string $start = null, ?string $end = null, ?int $count = null, ?string $consumer = null)
|
||||
* @method $this xrevrange(string $key, string $end, string $start, ?int $count = null)
|
||||
* @method $this xrange(string $key, string $start, string $end, ?int $count = null)
|
||||
* @method $this xread(int $count = null, int $block = null, array $streams = null, string ...$id)
|
||||
* @method $this xreadgroup(string $group, string $consumer, ?int $count = null, ?int $blockMs = null, bool $noAck = false, string ...$keyOrId)
|
||||
* @method $this xreadgroup_claim(string $group, string $consumer, array $keyIdDict, ?int $count = null, ?int $blockMs = null, bool $noAck = false, ?int $claim = null)
|
||||
* @method $this xsetid(string $key, string $lastId, ?int $entriesAdded = null, ?string $maxDeleteId = null)
|
||||
* @method $this xtrim(string $key, array|string $strategy, string $threshold, array $options = null)
|
||||
* @method $this zadd($key, array $membersAndScoresDictionary)
|
||||
* @method $this zcard($key)
|
||||
* @method $this zcount($key, $min, $max)
|
||||
@@ -346,18 +322,6 @@ use Predis\Command\Redis\VADD;
|
||||
* @method $this multi()
|
||||
* @method $this unwatch()
|
||||
* @method $this waitaof(int $numLocal, int $numReplicas, int $timeout)
|
||||
* @method $this unsubscribe(string ...$channels)
|
||||
* @method $this vadd(string $key, string|array $vector, string $elem, int $dim = null, bool $cas = false, string $quant = VADD::QUANT_DEFAULT, ?int $BEF = null, string|array $attributes = null, int $numlinks = null)
|
||||
* @method $this vcard(string $key)
|
||||
* @method $this vdim(int $key)
|
||||
* @method $this vemb(string $key, string $elem, bool $raw = false)
|
||||
* @method $this vgetattr(string $key, string $elem, bool $asJson = false)
|
||||
* @method $this vinfo(string $key)
|
||||
* @method $this vlinks(string $key, string $elem, bool $withScores = false)
|
||||
* @method $this vrandmember(string $key, int $count = null)
|
||||
* @method $this vrem(string $key, string $elem)
|
||||
* @method $this vsetattr(string $key, string $elem, string|array $attributes)
|
||||
* @method $this vsim(string $key, string|array $vectorOrElem, bool $isElem = false, bool $withScores = false, int $count = null, float $epsilon = null, int $ef = null, string $filter = null, int $filterEf = null, bool $truth = false, bool $noThread = false)
|
||||
* @method $this watch($key)
|
||||
* @method $this eval($script, $numkeys, $keyOrArg1 = null, $keyOrArgN = null)
|
||||
* @method $this eval_ro(string $script, array $keys, ...$argument)
|
||||
@@ -371,18 +335,18 @@ use Predis\Command\Redis\VADD;
|
||||
* @method $this select($database)
|
||||
* @method $this bgrewriteaof()
|
||||
* @method $this bgsave()
|
||||
* @method $this client($subcommand, $argument = null)
|
||||
* @method $this config($subcommand, $argument = null)
|
||||
* @method $this dbsize()
|
||||
* @method $this flushall()
|
||||
* @method $this flushdb()
|
||||
* @method $this info(string ...$section = null)
|
||||
* @method $this info($section = null)
|
||||
* @method $this lastsave()
|
||||
* @method $this save()
|
||||
* @method $this slaveof($host, $port)
|
||||
* @method $this slowlog($subcommand, $argument = null)
|
||||
* @method $this spublish(string $shardChannel, string $message)
|
||||
* @method $this time()
|
||||
* @method $this command($subcommand, $argument = null)
|
||||
* @method $this command()
|
||||
* @method $this geoadd($key, $longitude, $latitude, $member)
|
||||
* @method $this geohash($key, array $members)
|
||||
* @method $this geopos($key, array $members)
|
||||
@@ -393,13 +357,12 @@ use Predis\Command\Redis\VADD;
|
||||
* @method $this geosearchstore(string $destination, string $source, FromInterface $from, ByInterface $by, ?string $sorting = null, int $count = -1, bool $any = false, bool $storeDist = false)
|
||||
*
|
||||
* Container commands
|
||||
* @property CLIENT $client
|
||||
* @property FUNCTIONS $function
|
||||
* @property FTCONFIG $ftconfig
|
||||
* @property FTCURSOR $ftcursor
|
||||
* @property JSONDEBUG $jsondebug
|
||||
* @property ACL $acl
|
||||
* @property XGROUP $xgroup
|
||||
* @property CLUSTER $cluster
|
||||
* @property FunctionContainer $function
|
||||
* @property FTCONFIG $ftconfig
|
||||
* @property FTCURSOR $ftcursor
|
||||
* @property JSONDEBUG $jsondebug
|
||||
* @property ACL $acl
|
||||
*/
|
||||
interface ClientContextInterface
|
||||
{
|
||||
|
||||
+35
-65
@@ -19,7 +19,6 @@ 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\HybridSearch\HybridSearchQuery;
|
||||
use Predis\Command\Argument\Search\ProfileArguments;
|
||||
use Predis\Command\Argument\Search\SchemaFields\FieldInterface;
|
||||
use Predis\Command\Argument\Search\SearchArguments;
|
||||
@@ -39,16 +38,15 @@ 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\Container\ACL;
|
||||
use Predis\Command\Container\CLIENT;
|
||||
use Predis\Command\Container\FUNCTIONS;
|
||||
use Predis\Command\Container\Json\JSONDEBUG;
|
||||
use Predis\Command\Container\Search\FTCONFIG;
|
||||
use Predis\Command\Container\Search\FTCURSOR;
|
||||
use Predis\Command\Container\XGROUP;
|
||||
use Predis\Command\Container\XINFO;
|
||||
use Predis\Command\FactoryInterface;
|
||||
use Predis\Command\Redis\VADD;
|
||||
use Predis\Command\Redis\Container\ACL;
|
||||
use Predis\Command\Redis\Container\CLUSTER;
|
||||
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\Command\Redis\HGETEX;
|
||||
use Predis\Command\Redis\HSETEX;
|
||||
use Predis\Configuration\OptionsInterface;
|
||||
use Predis\Connection\ConnectionInterface;
|
||||
use Predis\Response\Status;
|
||||
@@ -63,8 +61,6 @@ use Predis\Response\Status;
|
||||
*
|
||||
* @method int copy(string $source, string $destination, int $db = -1, bool $replace = false)
|
||||
* @method int del(string[]|string $keyOrKeys, string ...$keys = null)
|
||||
* @method int delex(string $key, string $flag, $flagValue)
|
||||
* @method string digest(string $key)
|
||||
* @method string|null dump(string $key)
|
||||
* @method int exists(string $key)
|
||||
* @method int expire(string $key, int $seconds, string $expireOption = '')
|
||||
@@ -74,8 +70,8 @@ use Predis\Response\Status;
|
||||
* @method int move(string $key, int $db)
|
||||
* @method mixed object($subcommand, string $key)
|
||||
* @method int persist(string $key)
|
||||
* @method int pexpire(string $key, int $milliseconds, string $option = null)
|
||||
* @method int pexpireat(string $key, int $timestamp, string $option = null)
|
||||
* @method int pexpire(string $key, int $milliseconds)
|
||||
* @method int pexpireat(string $key, int $timestamp)
|
||||
* @method int pttl(string $key)
|
||||
* @method string|null randomkey()
|
||||
* @method mixed rename(string $key, string $target)
|
||||
@@ -86,8 +82,8 @@ use Predis\Response\Status;
|
||||
* @method int ttl(string $key)
|
||||
* @method mixed type(string $key)
|
||||
* @method int append(string $key, $value)
|
||||
* @method mixed bfadd(string $key, $item)
|
||||
* @method mixed bfexists(string $key, $item)
|
||||
* @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)
|
||||
@@ -104,11 +100,11 @@ 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 mixed cfadd(string $key, $item)
|
||||
* @method mixed cfaddnx(string $key, $item)
|
||||
* @method int cfadd(string $key, $item)
|
||||
* @method int cfaddnx(string $key, $item)
|
||||
* @method int cfcount(string $key, $item)
|
||||
* @method mixed cfdel(string $key, $item)
|
||||
* @method mixed cfexists(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)
|
||||
@@ -139,7 +135,6 @@ use Predis\Response\Status;
|
||||
* @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 fthybrid(string $index, HybridSearchQuery $query)
|
||||
* @method array ftinfo(string $index)
|
||||
* @method array ftprofile(string $index, ProfileArguments $arguments)
|
||||
* @method array ftsearch(string $index, string $query, ?SearchArguments $arguments = null)
|
||||
@@ -162,10 +157,9 @@ use Predis\Response\Status;
|
||||
* @method string incrbyfloat(string $key, int|float $increment)
|
||||
* @method array mget(string[]|string $keyOrKeys, string ...$keys = null)
|
||||
* @method mixed mset(array $dictionary)
|
||||
* @method array msetex(array $dictionary, ?string $existModifier = null, ?string $expireResolution = null, ?int $expireTTL = null)
|
||||
* @method int msetnx(array $dictionary)
|
||||
* @method Status psetex(string $key, $milliseconds, $value)
|
||||
* @method Status|null set(string $key, $value, $expireResolution = null, $expireTTL = null, $flag = null, $flagValue = null)
|
||||
* @method Status|null set(string $key, $value, $expireResolution = null, $expireTTL = null, $flag = null)
|
||||
* @method int setbit(string $key, $offset, $value)
|
||||
* @method Status setex(string $key, $seconds, $value)
|
||||
* @method int setnx(string $key, $value)
|
||||
@@ -208,8 +202,8 @@ use Predis\Response\Status;
|
||||
* @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 mixed jsonget(string $key, string $indent = '', string $newline = '', string $space = '', string ...$paths)
|
||||
* @method mixed jsonnumincrby(string $key, string $path, int $value)
|
||||
* @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)
|
||||
@@ -256,12 +250,9 @@ use Predis\Response\Status;
|
||||
* @method string|array|null spop(string $key, ?int $count = null)
|
||||
* @method string|null srandmember(string $key, ?int $count = null)
|
||||
* @method int srem(string $key, array|string $member)
|
||||
* @method array sscan(string $key, int $cursor, array $options = null)
|
||||
* @method array ssubscribe(string ...$shardChannels)
|
||||
* @method array subscribe(string ...$channels)
|
||||
* @method array sscan(string $key, int $cursor, ?array $options = null)
|
||||
* @method string[] sunion(array|string $keys)
|
||||
* @method int sunionstore(string $destination, array|string $keys)
|
||||
* @method array sunsubscribe(?string ...$shardChannels = null)
|
||||
* @method int touch(string[]|string $keyOrKeys, string ...$keys = null)
|
||||
* @method Status tdigestadd(string $key, float ...$value)
|
||||
* @method array tdigestbyrank(string $key, int ...$rank)
|
||||
@@ -269,10 +260,10 @@ use Predis\Response\Status;
|
||||
* @method array tdigestcdf(string $key, int ...$value)
|
||||
* @method Status tdigestcreate(string $key, int $compression = 0)
|
||||
* @method array tdigestinfo(string $key)
|
||||
* @method mixed tdigestmax(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 mixed tdigestmin(string $key)
|
||||
* @method string tdigestmin(string $key)
|
||||
* @method array tdigestrank(string $key, float ...$value)
|
||||
* @method Status tdigestreset(string $key)
|
||||
* @method array tdigestrevrank(string $key, float ...$value)
|
||||
@@ -300,22 +291,13 @@ use Predis\Response\Status;
|
||||
* @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 int xack(string $key, string $group, string ...$id)
|
||||
* @method array xackdel(string $key, string $group, string $mode, array $ids)
|
||||
* @method string xadd(string $key, array $dictionary, string $id = '*', array $options = null)
|
||||
* @method array xautoclaim(string $key, string $group, string $consumer, int $minIdleTime, string $start, ?int $count = null, bool $justId = false)
|
||||
* @method array xclaim(string $key, string $group, string $consumer, int $minIdleTime, string|array $ids, ?int $idle = null, ?int $time = null, ?int $retryCount = null, bool $force = false, bool $justId = false, ?string $lastId = null)
|
||||
* @method string xadd(string $key, array $dictionary, string $id = '*', ?array $options = null)
|
||||
* @method int xdel(string $key, string ...$id)
|
||||
* @method array xdelex(string $key, string $mode, array $ids)
|
||||
* @method int xlen(string $key)
|
||||
* @method array xpending(string $key, string $group, ?int $minIdleTime = null, ?string $start = null, ?string $end = null, ?int $count = null, ?string $consumer = null)
|
||||
* @method array xrevrange(string $key, string $end, string $start, ?int $count = null)
|
||||
* @method array xrange(string $key, string $start, string $end, ?int $count = null)
|
||||
* @method string xtrim(string $key, array|string $strategy, string $threshold, ?array $options = null)
|
||||
* @method array|null xread(int $count = null, int $block = null, array $streams = null, string ...$id)
|
||||
* @method array xreadgroup(string $group, string $consumer, ?int $count = null, ?int $blockMs = null, bool $noAck = false, string ...$keyOrId)
|
||||
* @method array xreadgroup_claim(string $group, string $consumer, array $keyIdDict, ?int $count = null, ?int $blockMs = null, bool $noAck = false, ?int $claim = null)
|
||||
* @method Status xsetid(string $key, string $lastId, ?int $entriesAdded = null, ?string $maxDeleteId = null)
|
||||
* @method string xtrim(string $key, array|string $strategy, string $threshold, array $options = null)
|
||||
* @method int zadd(string $key, array $membersAndScoresDictionary)
|
||||
* @method int zcard(string $key)
|
||||
* @method int zcount(string $key, int|string $min, int|string $max)
|
||||
@@ -358,18 +340,6 @@ use Predis\Response\Status;
|
||||
* @method array|null exec()
|
||||
* @method mixed multi()
|
||||
* @method mixed unwatch()
|
||||
* @method array unsubscribe(string ...$channels)
|
||||
* @method bool vadd(string $key, string|array $vector, string $elem, int $dim = null, bool $cas = false, string $quant = VADD::QUANT_DEFAULT, int $bef = null, string|array $attributes = null, int $numlinks = null)
|
||||
* @method int vcard(string $key)
|
||||
* @method int vdim(string $key)
|
||||
* @method array vemb(string $key, string $elem, bool $raw = false)
|
||||
* @method string|array|null vgetattr(string $key, string $elem, bool $asJson = false)
|
||||
* @method array|null vinfo(string $key)
|
||||
* @method array|null vlinks(string $key, string $elem, bool $withScores = false)
|
||||
* @method string|array|null vrandmember(string $key, int $count = null)
|
||||
* @method bool vrem(string $key, string $elem)
|
||||
* @method array vsim(string $key, string|array $vectorOrElem, bool $isElem = false, bool $withScores = false, int $count = null, float $epsilon = null, int $ef = null, string $filter = null, int $filterEf = null, bool $truth = false, bool $noThread = false)
|
||||
* @method bool vsetattr(string $key, string $elem, string|array $attributes)
|
||||
* @method array waitaof(int $numLocal, int $numReplicas, int $timeout)
|
||||
* @method mixed watch(string[]|string $keyOrKeys)
|
||||
* @method mixed eval(string $script, int $numkeys, string ...$keyOrArg = null)
|
||||
@@ -384,18 +354,18 @@ use Predis\Response\Status;
|
||||
* @method mixed select(int $database)
|
||||
* @method mixed bgrewriteaof()
|
||||
* @method mixed bgsave()
|
||||
* @method mixed client($subcommand, $argument = null)
|
||||
* @method mixed config($subcommand, $argument = null)
|
||||
* @method int dbsize()
|
||||
* @method mixed flushall()
|
||||
* @method mixed flushdb()
|
||||
* @method array info(string ...$section = null)
|
||||
* @method array info($section = null)
|
||||
* @method int lastsave()
|
||||
* @method mixed save()
|
||||
* @method mixed slaveof(string $host, int $port)
|
||||
* @method mixed slowlog($subcommand, $argument = null)
|
||||
* @method int spublish(string $shardChannel, string $message)
|
||||
* @method array time()
|
||||
* @method array command($subcommand, $argument = null)
|
||||
* @method array command()
|
||||
* @method int geoadd(string $key, $longitude, $latitude, $member)
|
||||
* @method array geohash(string $key, array $members)
|
||||
* @method array geopos(string $key, array $members)
|
||||
@@ -406,14 +376,14 @@ use Predis\Response\Status;
|
||||
* @method int geosearchstore(string $destination, string $source, FromInterface $from, ByInterface $by, ?string $sorting = null, int $count = -1, bool $any = false, bool $storeDist = false)
|
||||
*
|
||||
* Container commands
|
||||
* @property CLIENT $client
|
||||
* @property FUNCTIONS $function
|
||||
* @property FTCONFIG $ftconfig
|
||||
* @property FTCURSOR $ftcursor
|
||||
* @property JSONDEBUG $jsondebug
|
||||
* @property ACL $acl
|
||||
* @property XGROUP $xgroup
|
||||
* @property XINFO $xinfo
|
||||
* @property CLUSTER $cluster
|
||||
* @property FunctionContainer $function
|
||||
* @property FTCONFIG $ftconfig
|
||||
* @property FTCURSOR $ftcursor
|
||||
* @property JSONDEBUG $jsondebug
|
||||
* @property ACL $acl
|
||||
*
|
||||
* @no-named-arguments
|
||||
*/
|
||||
interface ClientInterface
|
||||
{
|
||||
|
||||
@@ -155,11 +155,6 @@ abstract class ClusterStrategy implements StrategyInterface
|
||||
'HSCAN' => $getKeyFromFirstArgument,
|
||||
'HSTRLEN' => $getKeyFromFirstArgument,
|
||||
|
||||
/* commands operating on streams */
|
||||
'XADD' => $getKeyFromFirstArgument,
|
||||
'XDEL' => $getKeyFromFirstArgument,
|
||||
'XRANGE' => $getKeyFromFirstArgument,
|
||||
|
||||
/* commands operating on HyperLogLog */
|
||||
'PFADD' => $getKeyFromFirstArgument,
|
||||
'PFCOUNT' => $getKeyFromAllArguments,
|
||||
@@ -182,11 +177,6 @@ abstract class ClusterStrategy implements StrategyInterface
|
||||
'GEORADIUS' => [$this, 'getKeyFromGeoradiusCommands'],
|
||||
'GEORADIUSBYMEMBER' => [$this, 'getKeyFromGeoradiusCommands'],
|
||||
|
||||
/* sharded pubsub */
|
||||
'SSUBSCRIBE' => $getKeyFromAllArguments,
|
||||
'SUNSUBSCRIBE' => [$this, 'getKeyFromSUnsubscribeCommand'],
|
||||
'SPUBLISH' => $getKeyFromFirstArgument,
|
||||
|
||||
/* cluster */
|
||||
'CLUSTER' => [$this, 'getFakeKey'],
|
||||
];
|
||||
@@ -417,24 +407,6 @@ abstract class ClusterStrategy implements StrategyInterface
|
||||
return $arguments[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts key from SUNSUBSCRIBE command if it's given.
|
||||
*
|
||||
* @param CommandInterface $command
|
||||
* @return string
|
||||
*/
|
||||
protected function getKeyFromSUnsubscribeCommand(CommandInterface $command): ?string
|
||||
{
|
||||
$arguments = $command->getArguments();
|
||||
|
||||
// SUNSUBSCRIBE command could be called without arguments, so it doesn't matter on each node it will be called.
|
||||
if (empty($arguments)) {
|
||||
return 'fake';
|
||||
}
|
||||
|
||||
return $this->getKeyFromAllArguments($command);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the key from EVAL and EVALSHA commands.
|
||||
*
|
||||
@@ -475,9 +447,13 @@ abstract class ClusterStrategy implements StrategyInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* Checks if the specified array of keys will generate the same hash.
|
||||
*
|
||||
* @param array $keys Array of keys.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function checkSameSlotForKeys(array $keys): bool
|
||||
protected function checkSameSlotForKeys(array $keys)
|
||||
{
|
||||
if (!$count = count($keys)) {
|
||||
return false;
|
||||
@@ -491,6 +467,8 @@ abstract class ClusterStrategy implements StrategyInterface
|
||||
if ($currentSlot !== $nextSlot) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$currentSlot = $nextSlot;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2025 Till Krüss
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Predis\Cluster\Hash;
|
||||
|
||||
use Predis\NotSupportedException;
|
||||
|
||||
/**
|
||||
* Hash generator implementing the CRC-CCITT-16 algorithm used by redis-cluster.
|
||||
*
|
||||
* @deprecated 2.1.2
|
||||
*/
|
||||
class PhpiredisCRC16 implements HashGeneratorInterface
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
if (!function_exists('phpiredis_utils_crc16')) {
|
||||
// @codeCoverageIgnoreStart
|
||||
throw new NotSupportedException(
|
||||
'This hash generator requires a compatible version of ext-phpiredis'
|
||||
);
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function hash($value)
|
||||
{
|
||||
return phpiredis_utils_crc16($value);
|
||||
}
|
||||
}
|
||||
@@ -46,7 +46,7 @@ class PredisStrategy extends ClusterStrategy
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function checkSameSlotForKeys(array $keys): bool
|
||||
protected function checkSameSlotForKeys(array $keys)
|
||||
{
|
||||
if (!$count = count($keys)) {
|
||||
return false;
|
||||
@@ -60,6 +60,8 @@ class PredisStrategy extends ClusterStrategy
|
||||
if ($currentKey !== $nextKey) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$currentKey = $nextKey;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -66,7 +66,7 @@ class SlotRange implements Countable
|
||||
*/
|
||||
public static function isValidRange($first, $last)
|
||||
{
|
||||
return $first >= 0x0000 && $first <= self::MAX_SLOTS && $last >= 0x0000 && $last <= self::MAX_SLOTS && $first <= $last;
|
||||
return $first >= 0 && $first <= self::MAX_SLOTS && $last >= 0x0000 && $last <= self::MAX_SLOTS && $first <= $last;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -49,12 +49,4 @@ interface StrategyInterface
|
||||
* @return DistributorInterface
|
||||
*/
|
||||
public function getDistributor();
|
||||
|
||||
/**
|
||||
* Checks if the specified array of keys will generate the same hash.
|
||||
*
|
||||
* @param array $keys
|
||||
* @return bool
|
||||
*/
|
||||
public function checkSameSlotForKeys(array $keys): bool;
|
||||
}
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2025 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\HybridSearch\Combine;
|
||||
|
||||
use Predis\Command\Argument\ArrayableArgument;
|
||||
|
||||
abstract class BaseCombine implements ArrayableArgument
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $arguments = ['COMBINE'];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $as = [];
|
||||
|
||||
/**
|
||||
* @param string $alias
|
||||
* @return $this
|
||||
*/
|
||||
public function as(string $alias): self
|
||||
{
|
||||
array_push($this->as, 'YIELD_SCORE_AS', $alias);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
abstract public function toArray(): array;
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2025 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\HybridSearch\Combine;
|
||||
|
||||
class LinearCombineConfig extends BaseCombine
|
||||
{
|
||||
/**
|
||||
* @var float
|
||||
*/
|
||||
protected $alpha;
|
||||
|
||||
/**
|
||||
* @var float
|
||||
*/
|
||||
protected $beta;
|
||||
|
||||
/**
|
||||
* The weight for the text score (a value between 0 and 1).
|
||||
*
|
||||
* @param float $alpha
|
||||
* @return $this
|
||||
*/
|
||||
public function alpha(float $alpha): self
|
||||
{
|
||||
$this->alpha = $alpha;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* The weight for the vector score (a value between 0 and 1).
|
||||
*
|
||||
* @param float $beta
|
||||
* @return $this
|
||||
*/
|
||||
public function beta(float $beta): self
|
||||
{
|
||||
$this->beta = $beta;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
$this->arguments[] = 'LINEAR';
|
||||
$tokens = [];
|
||||
|
||||
if ($this->alpha !== null) {
|
||||
array_push($tokens, 'ALPHA', $this->alpha);
|
||||
}
|
||||
|
||||
if ($this->beta !== null) {
|
||||
array_push($tokens, 'BETA', $this->beta);
|
||||
}
|
||||
|
||||
if ($this->as) {
|
||||
array_push($tokens, ...$this->as);
|
||||
}
|
||||
|
||||
if (!empty($tokens)) {
|
||||
array_push($this->arguments, count($tokens), ...$tokens);
|
||||
}
|
||||
|
||||
return $this->arguments;
|
||||
}
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2025 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\HybridSearch\Combine;
|
||||
|
||||
class RRFCombineConfig extends BaseCombine
|
||||
{
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $window;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $rrfConstant;
|
||||
|
||||
/**
|
||||
* The number of top results from each search type to consider for fusion. Defaults to 50.
|
||||
*
|
||||
* @param int $window
|
||||
* @return $this
|
||||
*/
|
||||
public function window(int $window): self
|
||||
{
|
||||
$this->window = $window;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* The RRF ranking constant. A smaller value gives more weight to top-ranked items. Defaults to 60.
|
||||
*
|
||||
* @param int $constant
|
||||
* @return $this
|
||||
*/
|
||||
public function rrfConstant(int $constant): self
|
||||
{
|
||||
$this->rrfConstant = $constant;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
$this->arguments[] = 'RRF';
|
||||
$tokens = [];
|
||||
|
||||
if ($this->window !== null) {
|
||||
array_push($tokens, 'WINDOW', $this->window);
|
||||
}
|
||||
|
||||
if ($this->rrfConstant !== null) {
|
||||
array_push($tokens, 'CONSTANT', $this->rrfConstant);
|
||||
}
|
||||
|
||||
if ($this->as) {
|
||||
array_push($tokens, ...$this->as);
|
||||
}
|
||||
|
||||
if (!empty($tokens)) {
|
||||
array_push($this->arguments, count($tokens), ...$tokens);
|
||||
}
|
||||
|
||||
return $this->arguments;
|
||||
}
|
||||
}
|
||||
@@ -1,352 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2025 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\HybridSearch;
|
||||
|
||||
use Predis\Command\Argument\ArrayableArgument;
|
||||
use Predis\Command\Argument\Search\HybridSearch\Combine\LinearCombineConfig;
|
||||
use Predis\Command\Argument\Search\HybridSearch\Combine\RRFCombineConfig;
|
||||
use Predis\Command\Argument\Search\HybridSearch\VectorSearch\KNNVectorSearchConfig;
|
||||
use Predis\Command\Argument\Search\HybridSearch\VectorSearch\RangeVectorSearchConfig;
|
||||
use Predis\Command\Redis\Utils\CommandUtility;
|
||||
use ValueError;
|
||||
|
||||
class HybridSearchQuery implements ArrayableArgument
|
||||
{
|
||||
public const SORT_ASC = 'ASC';
|
||||
public const SORT_DESC = 'DESC';
|
||||
|
||||
/**
|
||||
* @var SearchConfig
|
||||
*/
|
||||
protected $searchConfig;
|
||||
|
||||
/**
|
||||
* The vector search portion of the query.
|
||||
*
|
||||
* @var KNNVectorSearchConfig|RangeVectorSearchConfig
|
||||
*/
|
||||
protected $vectorSearchConfig;
|
||||
|
||||
/**
|
||||
* Configuration for the score fusion method (optional).
|
||||
* If not provided, Reciprocal Rank Fusion (RRF) is used with server-side default parameters.
|
||||
*
|
||||
* @var RRFCombineConfig|LinearCombineConfig
|
||||
*/
|
||||
protected $combineConfig;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $load = [];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $groupBy = [];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $apply = [];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $sortBy = [];
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $filter;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $limit = [];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $params = [];
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $explainScore = false;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $timeout = false;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $withCursor = [];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $arguments = [];
|
||||
|
||||
/**
|
||||
* @param string $vectorSearchMethod Class type of desired vector search method
|
||||
* @param string $combineMethod Class type of desired combine method
|
||||
*/
|
||||
public function __construct(
|
||||
string $vectorSearchMethod = KNNVectorSearchConfig::class,
|
||||
string $combineMethod = RRFCombineConfig::class
|
||||
) {
|
||||
$this->searchConfig = new SearchConfig();
|
||||
$this->vectorSearchConfig = new $vectorSearchMethod();
|
||||
$this->combineConfig = new $combineMethod();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param callable(SearchConfig): void $callable
|
||||
* @return $this
|
||||
*/
|
||||
public function buildSearchConfig(callable $callable): self
|
||||
{
|
||||
$callable($this->searchConfig);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param callable(KNNVectorSearchConfig|RangeVectorSearchConfig): void $callable
|
||||
* @return $this
|
||||
*/
|
||||
public function buildVectorSearchConfig(callable $callable): self
|
||||
{
|
||||
$callable($this->vectorSearchConfig);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param callable(RRFCombineConfig|LinearCombineConfig): void $callable
|
||||
* @return $this
|
||||
*/
|
||||
public function buildCombineConfig(callable $callable): self
|
||||
{
|
||||
$callable($this->combineConfig);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* The list of fields to return in the results.
|
||||
*
|
||||
* @param array $fields
|
||||
* @return $this
|
||||
*/
|
||||
public function load(array $fields): self
|
||||
{
|
||||
array_push($this->load, 'LOAD', count($fields), ...$fields);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $fields
|
||||
* @param Reducer[] $reducers
|
||||
* @return $this
|
||||
*/
|
||||
public function groupBy(array $fields, array $reducers): self
|
||||
{
|
||||
array_push($this->groupBy, 'GROUPBY', count($fields), ...$fields);
|
||||
|
||||
foreach ($reducers as $reducer) {
|
||||
array_push($this->groupBy, 'REDUCE', ...$reducer->toArray());
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $expressionFieldDict field => function dictionary
|
||||
* @return $this
|
||||
*/
|
||||
public function apply(array $expressionFieldDict): self
|
||||
{
|
||||
foreach ($expressionFieldDict as $field => $function) {
|
||||
array_push($this->apply, 'APPLY', $function, 'AS', $field);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the final results by a specific field.
|
||||
*
|
||||
* @param array<string, string> $fields Dictionary with fields and sort direction. Check class constants.
|
||||
* @return $this
|
||||
*/
|
||||
public function sortBy(array $fields): self
|
||||
{
|
||||
$fieldsArray = [];
|
||||
foreach ($fields as $field => $direction) {
|
||||
if (!in_array(strtoupper($direction), [self::SORT_ASC, self::SORT_DESC])) {
|
||||
throw new ValueError('Sort direction must be one of "ASC" or "DESC".');
|
||||
}
|
||||
|
||||
array_push($fieldsArray, $field, $direction);
|
||||
}
|
||||
|
||||
array_push($this->sortBy, 'SORTBY', count($fieldsArray), ...$fieldsArray);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Final result filtering.
|
||||
*
|
||||
* @param string $expression
|
||||
* @return $this
|
||||
*/
|
||||
public function filter(string $expression): self
|
||||
{
|
||||
$this->filter = $expression;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $offset
|
||||
* @param int $num
|
||||
* @return $this
|
||||
*/
|
||||
public function limit(int $offset, int $num): self
|
||||
{
|
||||
array_push($this->limit, 'LIMIT', $offset, $num);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Binds values to named parameters in the query string.
|
||||
*
|
||||
* @param array $params
|
||||
* @return $this
|
||||
*/
|
||||
public function params(array $params): self
|
||||
{
|
||||
$arrayParams = CommandUtility::dictionaryToArray($params);
|
||||
array_push($this->params, 'PARAMS', count($arrayParams), ...$arrayParams);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function explainScore(): self
|
||||
{
|
||||
$this->explainScore = true;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function timeout(): self
|
||||
{
|
||||
$this->timeout = true;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int|null $readSize
|
||||
* @param int|null $idleTime
|
||||
* @return $this
|
||||
*/
|
||||
public function withCursor(?int $readSize = null, ?int $idleTime = null): self
|
||||
{
|
||||
$this->withCursor[] = 'WITHCURSOR';
|
||||
|
||||
if ($readSize) {
|
||||
array_push($this->withCursor, 'COUNT', $readSize);
|
||||
}
|
||||
|
||||
if ($idleTime) {
|
||||
array_push($this->withCursor, 'MAXIDLE', $idleTime);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
$this->arguments = array_merge(
|
||||
$this->arguments,
|
||||
$this->searchConfig->toArray(),
|
||||
$this->vectorSearchConfig->toArray()
|
||||
);
|
||||
|
||||
$combineConfig = $this->combineConfig->toArray();
|
||||
|
||||
// Only add if any configuration was applied
|
||||
if (count($combineConfig) > 2) {
|
||||
$this->arguments = array_merge($this->arguments, $combineConfig);
|
||||
}
|
||||
|
||||
if ($this->load) {
|
||||
$this->arguments = array_merge($this->arguments, $this->load);
|
||||
}
|
||||
|
||||
if ($this->groupBy) {
|
||||
$this->arguments = array_merge($this->arguments, $this->groupBy);
|
||||
}
|
||||
|
||||
if ($this->apply) {
|
||||
$this->arguments = array_merge($this->arguments, $this->apply);
|
||||
}
|
||||
|
||||
if ($this->sortBy) {
|
||||
$this->arguments = array_merge($this->arguments, $this->sortBy);
|
||||
}
|
||||
|
||||
if ($this->filter) {
|
||||
array_push($this->arguments, 'FILTER', $this->filter);
|
||||
}
|
||||
|
||||
if ($this->limit) {
|
||||
$this->arguments = array_merge($this->arguments, $this->limit);
|
||||
}
|
||||
|
||||
if ($this->params) {
|
||||
$this->arguments = array_merge($this->arguments, $this->params);
|
||||
}
|
||||
|
||||
if ($this->explainScore) {
|
||||
$this->arguments[] = 'EXPLAINSCORE';
|
||||
}
|
||||
|
||||
if ($this->timeout) {
|
||||
$this->arguments[] = 'TIMEOUT';
|
||||
}
|
||||
|
||||
if ($this->withCursor) {
|
||||
$this->arguments = array_merge($this->arguments, $this->withCursor);
|
||||
}
|
||||
|
||||
return $this->arguments;
|
||||
}
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2025 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\HybridSearch;
|
||||
|
||||
use Predis\Command\Argument\ArrayableArgument;
|
||||
|
||||
class Reducer implements ArrayableArgument
|
||||
{
|
||||
public const REDUCE_COUNT = 'COUNT';
|
||||
public const REDUCE_COUNT_DISTINCT = 'COUNT_DISTINCT';
|
||||
public const REDUCE_COUNT_DISTINCTISH = 'COUNT_DISTINCTISH';
|
||||
public const REDUCE_SUM = 'SUM';
|
||||
public const REDUCE_MIN = 'MIN';
|
||||
public const REDUCE_MAX = 'MAX';
|
||||
public const REDUCE_AVG = 'AVG';
|
||||
public const REDUCE_STDDEV = 'STDDEV';
|
||||
public const REDUCE_QUANTILE = 'QUANTILE';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $arguments = [];
|
||||
|
||||
/**
|
||||
* @param string $function One of the available functions. Check class constants.
|
||||
* @param array $arguments List of properties
|
||||
*/
|
||||
public function __construct(string $function = self::REDUCE_COUNT, array $arguments = [], ?string $alias = null)
|
||||
{
|
||||
array_push($this->arguments, $function, count($arguments), ...$arguments);
|
||||
|
||||
if ($alias) {
|
||||
array_push($this->arguments, 'AS', $alias);
|
||||
}
|
||||
}
|
||||
|
||||
public function toArray(): array
|
||||
{
|
||||
return $this->arguments;
|
||||
}
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2025 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\HybridSearch;
|
||||
|
||||
use Predis\Command\Argument\ArrayableArgument;
|
||||
|
||||
class ScorerConfig implements ArrayableArgument
|
||||
{
|
||||
public const TYPE_BM25 = 'BM25';
|
||||
public const TYPE_TFIDF = 'TFIDF';
|
||||
public const TYPE_DISMAX = 'DISMAX';
|
||||
public const TYPE_DOCSCORE = 'DOCSCORE';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $arguments = [];
|
||||
|
||||
/**
|
||||
* The text scoring algorithm. Defaults to BM25.
|
||||
*
|
||||
* @param string $type
|
||||
* @return $this
|
||||
*/
|
||||
public function type(string $type = self::TYPE_BM25): self
|
||||
{
|
||||
$this->arguments[] = $type;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* An alias for the text score field in the results.
|
||||
* The aliased field will be included in the `value` object of each returned document.
|
||||
*
|
||||
* @param string $alias
|
||||
* @return $this
|
||||
*/
|
||||
public function as(string $alias): self
|
||||
{
|
||||
array_push($this->arguments, 'YIELD_SCORE_AS', $alias);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function toArray(): array
|
||||
{
|
||||
return $this->arguments;
|
||||
}
|
||||
}
|
||||
@@ -1,80 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2025 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\HybridSearch;
|
||||
|
||||
use Predis\Command\Argument\ArrayableArgument;
|
||||
|
||||
class SearchConfig implements ArrayableArgument
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $arguments = ['SEARCH'];
|
||||
|
||||
/**
|
||||
* @var ScorerConfig
|
||||
*/
|
||||
protected $scorerConfig;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->scorerConfig = new ScorerConfig();
|
||||
}
|
||||
|
||||
/**
|
||||
* Search query.
|
||||
*
|
||||
* @param string $query
|
||||
* @return $this
|
||||
*/
|
||||
public function query(string $query): self
|
||||
{
|
||||
$this->arguments[] = $query;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $alias
|
||||
* @return $this
|
||||
*/
|
||||
public function as(string $alias): self
|
||||
{
|
||||
array_push($this->arguments, 'YIELD_SCORE_AS', $alias);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param callable(ScorerConfig): void $callable
|
||||
* @return $this
|
||||
*/
|
||||
public function buildScorerConfig(callable $callable): self
|
||||
{
|
||||
$callable($this->scorerConfig);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function toArray(): array
|
||||
{
|
||||
$scorerConfig = $this->scorerConfig->toArray();
|
||||
|
||||
if (!empty($scorerConfig)) {
|
||||
$this->arguments[] = 'SCORER';
|
||||
$this->arguments = array_merge($this->arguments, $scorerConfig);
|
||||
}
|
||||
|
||||
return $this->arguments;
|
||||
}
|
||||
}
|
||||
@@ -1,85 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2025 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\HybridSearch\VectorSearch;
|
||||
|
||||
use Predis\Command\Argument\ArrayableArgument;
|
||||
use Predis\Command\Redis\Utils\VectorUtility;
|
||||
|
||||
abstract class BaseVectorSearchConfig implements ArrayableArgument
|
||||
{
|
||||
public const POLICY_ADHOC = 'ADHOC';
|
||||
public const POLICY_BATCHES = 'BATCHES';
|
||||
public const POLICY_ACORN = 'ACORN';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $vector = [];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $filter = [];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $as = [];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $arguments = ['VSIM'];
|
||||
|
||||
/**
|
||||
* Vector to perform search against.
|
||||
*
|
||||
* @param string $field The vector field name to search against. Must start with "@".
|
||||
* @param string|float[] $value Binary vector representation or array of floats as vector.
|
||||
* @return self
|
||||
*/
|
||||
public function vector(string $field, $value): self
|
||||
{
|
||||
if (is_array($value)) {
|
||||
array_push($this->vector, $field, VectorUtility::toBlob($value));
|
||||
} else {
|
||||
array_push($this->vector, $field, $value);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $expression
|
||||
* @return $this
|
||||
*/
|
||||
public function filter(string $expression): self
|
||||
{
|
||||
array_push($this->filter, 'FILTER', $expression);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $alias
|
||||
* @return $this
|
||||
*/
|
||||
public function as(string $alias): self
|
||||
{
|
||||
array_push($this->as, 'YIELD_SCORE_AS', $alias);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
abstract public function toArray(): array;
|
||||
}
|
||||
@@ -1,91 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2025 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\HybridSearch\VectorSearch;
|
||||
|
||||
use ValueError;
|
||||
|
||||
class KNNVectorSearchConfig extends BaseVectorSearchConfig
|
||||
{
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $k;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $ef;
|
||||
|
||||
/**
|
||||
* The number of nearest neighbors to find. Defaults to 10 on server side.
|
||||
*
|
||||
* @param int $k
|
||||
* @return self
|
||||
*/
|
||||
public function k(int $k): self
|
||||
{
|
||||
$this->k = $k;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* The HNSW `ef_runtime` parameter for tuning the accuracy/speed trade-off.
|
||||
*
|
||||
* @param int $ef
|
||||
* @return $this
|
||||
*/
|
||||
public function ef(int $ef): self
|
||||
{
|
||||
$this->ef = $ef;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function toArray(): array
|
||||
{
|
||||
if (!$this->vector) {
|
||||
throw new ValueError('Vector configuration not specified.');
|
||||
}
|
||||
|
||||
$this->arguments = array_merge($this->arguments, $this->vector);
|
||||
|
||||
if ($this->k || $this->ef) {
|
||||
$this->arguments[] = 'KNN';
|
||||
}
|
||||
|
||||
$tokens = [];
|
||||
|
||||
if ($this->k !== null) {
|
||||
array_push($tokens, 'K', $this->k);
|
||||
}
|
||||
|
||||
if ($this->ef !== null) {
|
||||
array_push($tokens, 'EF_RUNTIME', $this->ef);
|
||||
}
|
||||
|
||||
if (!empty($tokens)) {
|
||||
array_push($this->arguments, count($tokens), ...$tokens);
|
||||
}
|
||||
|
||||
if ($this->filter) {
|
||||
$this->arguments = array_merge($this->arguments, $this->filter);
|
||||
}
|
||||
|
||||
if ($this->as) {
|
||||
array_push($this->arguments, ...$this->as);
|
||||
}
|
||||
|
||||
return $this->arguments;
|
||||
}
|
||||
}
|
||||
@@ -1,89 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2025 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\HybridSearch\VectorSearch;
|
||||
|
||||
use ValueError;
|
||||
|
||||
class RangeVectorSearchConfig extends BaseVectorSearchConfig
|
||||
{
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $radius;
|
||||
|
||||
/**
|
||||
* @var float
|
||||
*/
|
||||
protected $epsilon;
|
||||
|
||||
/**
|
||||
* The search radius/threshold. Finds all vectors within this distance.
|
||||
*
|
||||
* @param int $radius
|
||||
* @return $this
|
||||
*/
|
||||
public function radius(int $radius): self
|
||||
{
|
||||
$this->radius = $radius;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param float $epsilon
|
||||
* @return $this
|
||||
*/
|
||||
public function epsilon(float $epsilon): self
|
||||
{
|
||||
$this->epsilon = $epsilon;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function toArray(): array
|
||||
{
|
||||
if (!$this->vector) {
|
||||
throw new ValueError('Vector configuration not specified.');
|
||||
}
|
||||
|
||||
$this->arguments = array_merge($this->arguments, $this->vector);
|
||||
|
||||
if ($this->radius || $this->epsilon) {
|
||||
$this->arguments[] = 'RANGE';
|
||||
}
|
||||
|
||||
$tokens = [];
|
||||
|
||||
if ($this->radius !== null) {
|
||||
array_push($tokens, 'RADIUS', $this->radius);
|
||||
}
|
||||
|
||||
if ($this->epsilon !== null) {
|
||||
array_push($tokens, 'EPSILON', $this->epsilon);
|
||||
}
|
||||
|
||||
if (!empty($tokens)) {
|
||||
array_push($this->arguments, count($tokens), ...$tokens);
|
||||
}
|
||||
|
||||
if ($this->filter) {
|
||||
$this->arguments = array_merge($this->arguments, $this->filter);
|
||||
}
|
||||
|
||||
if ($this->as) {
|
||||
array_push($this->arguments, ...$this->as);
|
||||
}
|
||||
|
||||
return $this->arguments;
|
||||
}
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2025 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\Stream;
|
||||
|
||||
use Predis\Command\Argument\ArrayableArgument;
|
||||
|
||||
class XInfoStreamOptions implements ArrayableArgument
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $options = [];
|
||||
|
||||
/**
|
||||
* Modifier provides a more verbose reply.
|
||||
* The COUNT option can be used to limit the number of stream and PEL entries that are returned.
|
||||
*
|
||||
* @param int|null $count
|
||||
* @return self
|
||||
*/
|
||||
public function full(?int $count = null): self
|
||||
{
|
||||
$this->options[] = 'FULL';
|
||||
|
||||
if (null !== $count) {
|
||||
array_push($this->options, 'COUNT', $count);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
return $this->options;
|
||||
}
|
||||
}
|
||||
@@ -12,9 +12,6 @@
|
||||
|
||||
namespace Predis\Command;
|
||||
|
||||
use Predis\ClientConfiguration;
|
||||
use UnexpectedValueException;
|
||||
|
||||
/**
|
||||
* Base class for Redis commands.
|
||||
*/
|
||||
@@ -83,14 +80,6 @@ abstract class Command implements CommandInterface
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function parseResp3Response($data)
|
||||
{
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalizes the arguments array passed to a Redis command.
|
||||
*
|
||||
@@ -134,67 +123,4 @@ abstract class Command implements CommandInterface
|
||||
return $argument !== false && $argument !== null;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function serializeCommand(): string
|
||||
{
|
||||
$commandID = $this->getId();
|
||||
$arguments = $this->getArguments();
|
||||
|
||||
$cmdlen = strlen($commandID);
|
||||
$reqlen = count($arguments) + 1;
|
||||
|
||||
$buffer = "*{$reqlen}\r\n\${$cmdlen}\r\n{$commandID}\r\n";
|
||||
|
||||
foreach ($arguments as $argument) {
|
||||
$arglen = strlen(strval($argument));
|
||||
$buffer .= "\${$arglen}\r\n{$argument}\r\n";
|
||||
}
|
||||
|
||||
return $buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public static function deserializeCommand(string $serializedCommand): CommandInterface
|
||||
{
|
||||
if ($serializedCommand[0] !== '*') {
|
||||
throw new UnexpectedValueException('Invalid serializing format');
|
||||
}
|
||||
|
||||
$commandArray = explode("\r\n", $serializedCommand);
|
||||
$commandId = $commandArray[2];
|
||||
$classPath = __NAMESPACE__ . '\Redis\\';
|
||||
|
||||
// Check if given command is a module command.
|
||||
if (count($commandIdArray = explode('.', $commandId)) > 1) {
|
||||
// Fetch module configuration to resolve namespace.
|
||||
$moduleConfiguration = array_filter(
|
||||
ClientConfiguration::getModules(),
|
||||
static function ($module) use ($commandIdArray) {
|
||||
return $module['commandPrefix'] === $commandIdArray[0];
|
||||
}
|
||||
);
|
||||
|
||||
$commandClass = strtoupper($commandIdArray[0] . $commandIdArray[1]);
|
||||
$classPath .= array_shift($moduleConfiguration)['name'] . '\\' . $commandClass;
|
||||
} else {
|
||||
$classPath .= $commandIdArray[0];
|
||||
}
|
||||
|
||||
$command = new $classPath();
|
||||
$arguments = [];
|
||||
|
||||
for ($i = 4, $iMax = count($commandArray); $i < $iMax; $i++) {
|
||||
$arguments[] = $commandArray[$i];
|
||||
++$i;
|
||||
}
|
||||
|
||||
$command->setArguments($arguments);
|
||||
|
||||
return $command;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,27 +77,4 @@ interface CommandInterface
|
||||
* @return mixed
|
||||
*/
|
||||
public function parseResponse($data);
|
||||
|
||||
/**
|
||||
* Parses RESP3 protocol response and returns a PHP object.
|
||||
*
|
||||
* @param mixed $data
|
||||
* @return mixed
|
||||
*/
|
||||
public function parseResp3Response($data);
|
||||
|
||||
/**
|
||||
* Returns RESP-formatted representation of command.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function serializeCommand(): string;
|
||||
|
||||
/**
|
||||
* Creates command object from given serialized representation.
|
||||
*
|
||||
* @param string $serializedCommand
|
||||
* @return static
|
||||
*/
|
||||
public static function deserializeCommand(string $serializedCommand): CommandInterface;
|
||||
}
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2025 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\Container;
|
||||
|
||||
use Predis\Response\Status;
|
||||
|
||||
/**
|
||||
* @method string getName()
|
||||
* @method Status kill(...$arguments)
|
||||
* @method string list(string $type = null, int ...$clientId)
|
||||
* @method Status noEvict(bool $enable = null)
|
||||
* @method Status noTouch(bool $enable = null)
|
||||
* @method Status setInfo(string $modifier = null, string $value = null)
|
||||
* @method Status setName(string $connectionName)
|
||||
*/
|
||||
class CLIENT extends AbstractContainer
|
||||
{
|
||||
public function getContainerCommandId(): string
|
||||
{
|
||||
return 'CLIENT';
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2025 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\Container;
|
||||
|
||||
use Predis\Response\Status;
|
||||
|
||||
/**
|
||||
* @method Status create(string $key, string $group, string $id, bool $mkStream = false, ?string $entriesRead = null)
|
||||
* @method int createConsumer(string $key, string $group, string $consumer)
|
||||
* @method int delConsumer(string $key, string $group, string $consumer)
|
||||
* @method int destroy(string $key, string $group)
|
||||
* @method Status setId(string $key, string $group, string $id, ?string $entriesRead = null)
|
||||
*/
|
||||
class XGROUP extends AbstractContainer
|
||||
{
|
||||
public function getContainerCommandId(): string
|
||||
{
|
||||
return 'xgroup';
|
||||
}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2025 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\Container;
|
||||
|
||||
use Predis\Command\Argument\Stream\XInfoStreamOptions;
|
||||
|
||||
/**
|
||||
* @method array consumers(string $key, string $group)
|
||||
* @method array groups(string $key)
|
||||
* @method array stream(string $key, XInfoStreamOptions $options = null)
|
||||
*/
|
||||
class XINFO extends AbstractContainer
|
||||
{
|
||||
public function getContainerCommandId(): string
|
||||
{
|
||||
return 'XINFO';
|
||||
}
|
||||
}
|
||||
@@ -1,111 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2025 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;
|
||||
|
||||
abstract class PrefixableCommand extends Command implements PrefixableCommandInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
abstract public function getId();
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
abstract public function prefixKeys($prefix);
|
||||
|
||||
/**
|
||||
* Applies prefix for all arguments.
|
||||
*
|
||||
* @param string $prefix
|
||||
* @return void
|
||||
*/
|
||||
public function applyPrefixForAllArguments(string $prefix): void
|
||||
{
|
||||
$this->setRawArguments(
|
||||
array_map(static function ($key) use ($prefix) {
|
||||
return $prefix . $key;
|
||||
}, $this->getArguments())
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies prefix for first argument.
|
||||
*
|
||||
* @param string $prefix
|
||||
* @return void
|
||||
*/
|
||||
public function applyPrefixForFirstArgument(string $prefix): void
|
||||
{
|
||||
$arguments = $this->getArguments();
|
||||
$arguments[0] = $prefix . $arguments[0];
|
||||
$this->setRawArguments($arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies prefix for interleaved arguments.
|
||||
*
|
||||
* @param string $prefix
|
||||
* @return void
|
||||
*/
|
||||
public function applyPrefixForInterleavedArgument(string $prefix): void
|
||||
{
|
||||
if ($arguments = $this->getArguments()) {
|
||||
$length = count($arguments);
|
||||
|
||||
for ($i = 0; $i < $length; $i += 2) {
|
||||
$arguments[$i] = "$prefix{$arguments[$i]}";
|
||||
}
|
||||
|
||||
$this->setRawArguments($arguments);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies prefix for all keys except last one.
|
||||
*
|
||||
* @param string $prefix
|
||||
* @return void
|
||||
*/
|
||||
public function applyPrefixSkippingLastArgument(string $prefix): void
|
||||
{
|
||||
if ($arguments = $this->getArguments()) {
|
||||
$length = count($arguments);
|
||||
|
||||
for ($i = 0; $i < $length - 1; ++$i) {
|
||||
$arguments[$i] = "$prefix{$arguments[$i]}";
|
||||
}
|
||||
|
||||
$this->setRawArguments($arguments);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies prefix for all keys except first one.
|
||||
*
|
||||
* @param string $prefix
|
||||
* @return void
|
||||
*/
|
||||
public function applyPrefixSkippingFirstArgument(string $prefix): void
|
||||
{
|
||||
if ($arguments = $this->getArguments()) {
|
||||
$length = count($arguments);
|
||||
|
||||
for ($i = 1; $i < $length; ++$i) {
|
||||
$arguments[$i] = "$prefix{$arguments[$i]}";
|
||||
}
|
||||
|
||||
$this->setRawArguments($arguments);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -31,6 +31,284 @@ class KeyPrefixProcessor implements ProcessorInterface
|
||||
public function __construct($prefix)
|
||||
{
|
||||
$this->prefix = $prefix;
|
||||
|
||||
$prefixFirst = static::class . '::first';
|
||||
$prefixFirstTwo = static::class . '::firstTwo';
|
||||
$prefixAll = static::class . '::all';
|
||||
$prefixInterleaved = static::class . '::interleaved';
|
||||
$prefixSkipFirst = static::class . '::skipFirst';
|
||||
$prefixSkipLast = static::class . '::skipLast';
|
||||
$prefixSort = static::class . '::sort';
|
||||
$prefixEvalKeys = static::class . '::evalKeys';
|
||||
$prefixZsetStore = static::class . '::zsetStore';
|
||||
$prefixMigrate = static::class . '::migrate';
|
||||
$prefixGeoradius = static::class . '::georadius';
|
||||
|
||||
$this->commands = [
|
||||
/* ---------------- Redis 1.2 ---------------- */
|
||||
'EXISTS' => $prefixAll,
|
||||
'DEL' => $prefixAll,
|
||||
'TYPE' => $prefixFirst,
|
||||
'KEYS' => $prefixFirst,
|
||||
'RENAME' => $prefixAll,
|
||||
'RENAMENX' => $prefixAll,
|
||||
'EXPIRE' => $prefixFirst,
|
||||
'EXPIREAT' => $prefixFirst,
|
||||
'TTL' => $prefixFirst,
|
||||
'MOVE' => $prefixFirst,
|
||||
'SORT' => $prefixSort,
|
||||
'DUMP' => $prefixFirst,
|
||||
'RESTORE' => $prefixFirst,
|
||||
'SET' => $prefixFirst,
|
||||
'SETNX' => $prefixFirst,
|
||||
'MSET' => $prefixInterleaved,
|
||||
'MSETNX' => $prefixInterleaved,
|
||||
'GET' => $prefixFirst,
|
||||
'MGET' => $prefixAll,
|
||||
'GETSET' => $prefixFirst,
|
||||
'INCR' => $prefixFirst,
|
||||
'INCRBY' => $prefixFirst,
|
||||
'DECR' => $prefixFirst,
|
||||
'DECRBY' => $prefixFirst,
|
||||
'RPUSH' => $prefixFirst,
|
||||
'LPUSH' => $prefixFirst,
|
||||
'LLEN' => $prefixFirst,
|
||||
'LRANGE' => $prefixFirst,
|
||||
'LTRIM' => $prefixFirst,
|
||||
'LINDEX' => $prefixFirst,
|
||||
'LSET' => $prefixFirst,
|
||||
'LREM' => $prefixFirst,
|
||||
'LPOP' => $prefixFirst,
|
||||
'RPOP' => $prefixFirst,
|
||||
'RPOPLPUSH' => $prefixAll,
|
||||
'SADD' => $prefixFirst,
|
||||
'SREM' => $prefixFirst,
|
||||
'SPOP' => $prefixFirst,
|
||||
'SMOVE' => $prefixSkipLast,
|
||||
'SCARD' => $prefixFirst,
|
||||
'SISMEMBER' => $prefixFirst,
|
||||
'SINTER' => $prefixAll,
|
||||
'SINTERSTORE' => $prefixAll,
|
||||
'SUNION' => $prefixAll,
|
||||
'SUNIONSTORE' => $prefixAll,
|
||||
'SDIFF' => $prefixAll,
|
||||
'SDIFFSTORE' => $prefixAll,
|
||||
'SMEMBERS' => $prefixFirst,
|
||||
'SMISMEMBER' => $prefixFirst,
|
||||
'SRANDMEMBER' => $prefixFirst,
|
||||
'ZADD' => $prefixFirst,
|
||||
'ZINCRBY' => $prefixFirst,
|
||||
'ZREM' => $prefixFirst,
|
||||
'ZRANGE' => $prefixFirst,
|
||||
'ZREVRANGE' => $prefixFirst,
|
||||
'ZRANGEBYSCORE' => $prefixFirst,
|
||||
'ZCARD' => $prefixFirst,
|
||||
'ZSCORE' => $prefixFirst,
|
||||
'ZREMRANGEBYSCORE' => $prefixFirst,
|
||||
|
||||
/* ---------------- Redis 2.0 ---------------- */
|
||||
'SETEX' => $prefixFirst,
|
||||
'APPEND' => $prefixFirst,
|
||||
'SUBSTR' => $prefixFirst,
|
||||
'BLPOP' => $prefixSkipLast,
|
||||
'BRPOP' => $prefixSkipLast,
|
||||
'ZUNIONSTORE' => $prefixZsetStore,
|
||||
'ZINTERSTORE' => $prefixZsetStore,
|
||||
'ZCOUNT' => $prefixFirst,
|
||||
'ZRANK' => $prefixFirst,
|
||||
'ZREVRANK' => $prefixFirst,
|
||||
'ZREMRANGEBYRANK' => $prefixFirst,
|
||||
'HSET' => $prefixFirst,
|
||||
'HSETNX' => $prefixFirst,
|
||||
'HMSET' => $prefixFirst,
|
||||
'HINCRBY' => $prefixFirst,
|
||||
'HGET' => $prefixFirst,
|
||||
'HMGET' => $prefixFirst,
|
||||
'HDEL' => $prefixFirst,
|
||||
'HEXISTS' => $prefixFirst,
|
||||
'HLEN' => $prefixFirst,
|
||||
'HKEYS' => $prefixFirst,
|
||||
'HVALS' => $prefixFirst,
|
||||
'HGETALL' => $prefixFirst,
|
||||
'SUBSCRIBE' => $prefixAll,
|
||||
'UNSUBSCRIBE' => $prefixAll,
|
||||
'PSUBSCRIBE' => $prefixAll,
|
||||
'PUNSUBSCRIBE' => $prefixAll,
|
||||
'PUBLISH' => $prefixFirst,
|
||||
|
||||
/* ---------------- Redis 2.2 ---------------- */
|
||||
'PERSIST' => $prefixFirst,
|
||||
'STRLEN' => $prefixFirst,
|
||||
'SETRANGE' => $prefixFirst,
|
||||
'GETRANGE' => $prefixFirst,
|
||||
'SETBIT' => $prefixFirst,
|
||||
'GETBIT' => $prefixFirst,
|
||||
'RPUSHX' => $prefixFirst,
|
||||
'LPUSHX' => $prefixFirst,
|
||||
'LINSERT' => $prefixFirst,
|
||||
'BRPOPLPUSH' => $prefixSkipLast,
|
||||
'ZREVRANGEBYSCORE' => $prefixFirst,
|
||||
'WATCH' => $prefixAll,
|
||||
|
||||
/* ---------------- Redis 2.6 ---------------- */
|
||||
'PTTL' => $prefixFirst,
|
||||
'PEXPIRE' => $prefixFirst,
|
||||
'PEXPIREAT' => $prefixFirst,
|
||||
'PSETEX' => $prefixFirst,
|
||||
'INCRBYFLOAT' => $prefixFirst,
|
||||
'BITOP' => $prefixSkipFirst,
|
||||
'BITCOUNT' => $prefixFirst,
|
||||
'HINCRBYFLOAT' => $prefixFirst,
|
||||
'EVAL' => $prefixEvalKeys,
|
||||
'EVALSHA' => $prefixEvalKeys,
|
||||
'MIGRATE' => $prefixMigrate,
|
||||
|
||||
/* ---------------- Redis 2.8 ---------------- */
|
||||
'SSCAN' => $prefixFirst,
|
||||
'ZSCAN' => $prefixFirst,
|
||||
'HSCAN' => $prefixFirst,
|
||||
'PFADD' => $prefixFirst,
|
||||
'PFCOUNT' => $prefixAll,
|
||||
'PFMERGE' => $prefixAll,
|
||||
'ZLEXCOUNT' => $prefixFirst,
|
||||
'ZRANGEBYLEX' => $prefixFirst,
|
||||
'ZREMRANGEBYLEX' => $prefixFirst,
|
||||
'ZREVRANGEBYLEX' => $prefixFirst,
|
||||
'BITPOS' => $prefixFirst,
|
||||
|
||||
/* ---------------- Redis 3.2 ---------------- */
|
||||
'HSTRLEN' => $prefixFirst,
|
||||
'BITFIELD' => $prefixFirst,
|
||||
'GEOADD' => $prefixFirst,
|
||||
'GEOHASH' => $prefixFirst,
|
||||
'GEOPOS' => $prefixFirst,
|
||||
'GEODIST' => $prefixFirst,
|
||||
'GEORADIUS' => $prefixGeoradius,
|
||||
'GEORADIUSBYMEMBER' => $prefixGeoradius,
|
||||
|
||||
/* ---------------- Redis 5.0 ---------------- */
|
||||
'XADD' => $prefixFirst,
|
||||
'XRANGE' => $prefixFirst,
|
||||
'XREVRANGE' => $prefixFirst,
|
||||
'XDEL' => $prefixFirst,
|
||||
'XLEN' => $prefixFirst,
|
||||
'XACK' => $prefixFirst,
|
||||
'XTRIM' => $prefixFirst,
|
||||
'ZPOPMIN' => $prefixFirst,
|
||||
'ZPOPMAX' => $prefixFirst,
|
||||
|
||||
/* ---------------- Redis 6.2 ---------------- */
|
||||
'GETDEL' => $prefixFirst,
|
||||
'ZMSCORE' => $prefixFirst,
|
||||
'LMOVE' => $prefixFirstTwo,
|
||||
'BLMOVE' => $prefixFirstTwo,
|
||||
'GEOSEARCH' => $prefixFirst,
|
||||
|
||||
/* ---------------- Redis 7.0 ---------------- */
|
||||
'EXPIRETIME' => $prefixFirst,
|
||||
|
||||
/* RedisJSON */
|
||||
'JSON.ARRAPPEND' => $prefixFirst,
|
||||
'JSON.ARRINDEX' => $prefixFirst,
|
||||
'JSON.ARRINSERT' => $prefixFirst,
|
||||
'JSON.ARRLEN' => $prefixFirst,
|
||||
'JSON.ARRPOP' => $prefixFirst,
|
||||
'JSON.ARRTRIM' => $prefixFirst,
|
||||
'JSON.CLEAR' => $prefixFirst,
|
||||
'JSON.DEBUG MEMORY' => $prefixFirst,
|
||||
'JSON.DEL' => $prefixFirst,
|
||||
'JSON.FORGET' => $prefixFirst,
|
||||
'JSON.GET' => $prefixFirst,
|
||||
'JSON.MGET' => $prefixAll,
|
||||
'JSON.NUMINCRBY' => $prefixFirst,
|
||||
'JSON.OBJKEYS' => $prefixFirst,
|
||||
'JSON.OBJLEN' => $prefixFirst,
|
||||
'JSON.RESP' => $prefixFirst,
|
||||
'JSON.SET' => $prefixFirst,
|
||||
'JSON.STRAPPEND' => $prefixFirst,
|
||||
'JSON.STRLEN' => $prefixFirst,
|
||||
'JSON.TOGGLE' => $prefixFirst,
|
||||
'JSON.TYPE' => $prefixFirst,
|
||||
|
||||
/* RedisBloom */
|
||||
'BF.ADD' => $prefixFirst,
|
||||
'BF.EXISTS' => $prefixFirst,
|
||||
'BF.INFO' => $prefixFirst,
|
||||
'BF.INSERT' => $prefixFirst,
|
||||
'BF.LOADCHUNK' => $prefixFirst,
|
||||
'BF.MADD' => $prefixFirst,
|
||||
'BF.MEXISTS' => $prefixFirst,
|
||||
'BF.RESERVE' => $prefixFirst,
|
||||
'BF.SCANDUMP' => $prefixFirst,
|
||||
'CF.ADD' => $prefixFirst,
|
||||
'CF.ADDNX' => $prefixFirst,
|
||||
'CF.COUNT' => $prefixFirst,
|
||||
'CF.DEL' => $prefixFirst,
|
||||
'CF.EXISTS' => $prefixFirst,
|
||||
'CF.INFO' => $prefixFirst,
|
||||
'CF.INSERT' => $prefixFirst,
|
||||
'CF.INSERTNX' => $prefixFirst,
|
||||
'CF.LOADCHUNK' => $prefixFirst,
|
||||
'CF.MEXISTS' => $prefixFirst,
|
||||
'CF.RESERVE' => $prefixFirst,
|
||||
'CF.SCANDUMP' => $prefixFirst,
|
||||
'CMS.INCRBY' => $prefixFirst,
|
||||
'CMS.INFO' => $prefixFirst,
|
||||
'CMS.INITBYDIM' => $prefixFirst,
|
||||
'CMS.INITBYPROB' => $prefixFirst,
|
||||
'CMS.QUERY' => $prefixFirst,
|
||||
'TDIGEST.ADD' => $prefixFirst,
|
||||
'TDIGEST.BYRANK' => $prefixFirst,
|
||||
'TDIGEST.BYREVRANK' => $prefixFirst,
|
||||
'TDIGEST.CDF' => $prefixFirst,
|
||||
'TDIGEST.CREATE' => $prefixFirst,
|
||||
'TDIGEST.INFO' => $prefixFirst,
|
||||
'TDIGEST.MAX' => $prefixFirst,
|
||||
'TDIGEST.MIN' => $prefixFirst,
|
||||
'TDIGEST.QUANTILE' => $prefixFirst,
|
||||
'TDIGEST.RANK' => $prefixFirst,
|
||||
'TDIGEST.RESET' => $prefixFirst,
|
||||
'TDIGEST.REVRANK' => $prefixFirst,
|
||||
'TDIGEST.TRIMMED_MEAN' => $prefixFirst,
|
||||
'TOPK.ADD' => $prefixFirst,
|
||||
'TOPK.INCRBY' => $prefixFirst,
|
||||
'TOPK.INFO' => $prefixFirst,
|
||||
'TOPK.LIST' => $prefixFirst,
|
||||
'TOPK.QUERY' => $prefixFirst,
|
||||
'TOPK.RESERVE' => $prefixFirst,
|
||||
|
||||
/* RediSearch */
|
||||
'FT.AGGREGATE' => $prefixFirst,
|
||||
'FT.ALTER' => $prefixFirst,
|
||||
'FT.CREATE' => $prefixFirst,
|
||||
'FT.CURSOR DEL' => $prefixFirst,
|
||||
'FT.CURSOR READ' => $prefixFirst,
|
||||
'FT.DROPINDEX' => $prefixFirst,
|
||||
'FT.EXPLAIN' => $prefixFirst,
|
||||
'FT.INFO' => $prefixFirst,
|
||||
'FT.PROFILE' => $prefixFirst,
|
||||
'FT.SEARCH' => $prefixFirst,
|
||||
'FT.SPELLCHECK' => $prefixFirst,
|
||||
'FT.SYNDUMP' => $prefixFirst,
|
||||
'FT.SYNUPDATE' => $prefixFirst,
|
||||
'FT.TAGVALS' => $prefixFirst,
|
||||
|
||||
/* Redis TimeSeries */
|
||||
'TS.ADD' => $prefixFirst,
|
||||
'TS.ALTER' => $prefixFirst,
|
||||
'TS.CREATE' => $prefixFirst,
|
||||
'TS.DECRBY' => $prefixFirst,
|
||||
'TS.DEL' => $prefixFirst,
|
||||
'TS.GET' => $prefixFirst,
|
||||
'TS.INCRBY' => $prefixFirst,
|
||||
'TS.INFO' => $prefixFirst,
|
||||
'TS.MGET' => $prefixFirst,
|
||||
'TS.MRANGE' => $prefixFirst,
|
||||
'TS.MREVRANGE' => $prefixFirst,
|
||||
'TS.QUERYINDEX' => $prefixFirst,
|
||||
'TS.RANGE' => $prefixFirst,
|
||||
'TS.REVRANGE' => $prefixFirst,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -107,4 +385,225 @@ class KeyPrefixProcessor implements ProcessorInterface
|
||||
{
|
||||
return $this->getPrefix();
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the specified prefix only the first argument.
|
||||
*
|
||||
* @param CommandInterface $command Command instance.
|
||||
* @param string $prefix Prefix string.
|
||||
*/
|
||||
public static function first(CommandInterface $command, $prefix)
|
||||
{
|
||||
if ($arguments = $command->getArguments()) {
|
||||
$arguments[0] = "$prefix{$arguments[0]}";
|
||||
$command->setRawArguments($arguments);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the specified prefix only to the first two arguments.
|
||||
*
|
||||
* @param CommandInterface $command Command instance.
|
||||
* @param string $prefix Prefix string.
|
||||
*/
|
||||
public static function firstTwo(CommandInterface $command, $prefix)
|
||||
{
|
||||
$arguments = $command->getArguments();
|
||||
$length = min(count($arguments), 2);
|
||||
|
||||
for ($i = 0; $i < $length; $i++) {
|
||||
$arguments[$i] = "$prefix{$arguments[$i]}";
|
||||
}
|
||||
|
||||
$command->setRawArguments($arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the specified prefix to all the arguments.
|
||||
*
|
||||
* @param CommandInterface $command Command instance.
|
||||
* @param string $prefix Prefix string.
|
||||
*/
|
||||
public static function all(CommandInterface $command, $prefix)
|
||||
{
|
||||
if ($arguments = $command->getArguments()) {
|
||||
foreach ($arguments as &$key) {
|
||||
$key = "$prefix$key";
|
||||
}
|
||||
|
||||
$command->setRawArguments($arguments);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the specified prefix only to even arguments in the list.
|
||||
*
|
||||
* @param CommandInterface $command Command instance.
|
||||
* @param string $prefix Prefix string.
|
||||
*/
|
||||
public static function interleaved(CommandInterface $command, $prefix)
|
||||
{
|
||||
if ($arguments = $command->getArguments()) {
|
||||
$length = count($arguments);
|
||||
|
||||
for ($i = 0; $i < $length; $i += 2) {
|
||||
$arguments[$i] = "$prefix{$arguments[$i]}";
|
||||
}
|
||||
|
||||
$command->setRawArguments($arguments);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the specified prefix to all the arguments but the first one.
|
||||
*
|
||||
* @param CommandInterface $command Command instance.
|
||||
* @param string $prefix Prefix string.
|
||||
*/
|
||||
public static function skipFirst(CommandInterface $command, $prefix)
|
||||
{
|
||||
if ($arguments = $command->getArguments()) {
|
||||
$length = count($arguments);
|
||||
|
||||
for ($i = 1; $i < $length; ++$i) {
|
||||
$arguments[$i] = "$prefix{$arguments[$i]}";
|
||||
}
|
||||
|
||||
$command->setRawArguments($arguments);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the specified prefix to all the arguments but the last one.
|
||||
*
|
||||
* @param CommandInterface $command Command instance.
|
||||
* @param string $prefix Prefix string.
|
||||
*/
|
||||
public static function skipLast(CommandInterface $command, $prefix)
|
||||
{
|
||||
if ($arguments = $command->getArguments()) {
|
||||
$length = count($arguments);
|
||||
|
||||
for ($i = 0; $i < $length - 1; ++$i) {
|
||||
$arguments[$i] = "$prefix{$arguments[$i]}";
|
||||
}
|
||||
|
||||
$command->setRawArguments($arguments);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the specified prefix to the keys of a SORT command.
|
||||
*
|
||||
* @param CommandInterface $command Command instance.
|
||||
* @param string $prefix Prefix string.
|
||||
*/
|
||||
public static function sort(CommandInterface $command, $prefix)
|
||||
{
|
||||
if ($arguments = $command->getArguments()) {
|
||||
$arguments[0] = "$prefix{$arguments[0]}";
|
||||
|
||||
if (($count = count($arguments)) > 1) {
|
||||
for ($i = 1; $i < $count; ++$i) {
|
||||
switch (strtoupper($arguments[$i])) {
|
||||
case 'BY':
|
||||
case 'STORE':
|
||||
$arguments[$i] = "$prefix{$arguments[++$i]}";
|
||||
break;
|
||||
|
||||
case 'GET':
|
||||
$value = $arguments[++$i];
|
||||
if ($value !== '#') {
|
||||
$arguments[$i] = "$prefix$value";
|
||||
}
|
||||
break;
|
||||
|
||||
case 'LIMIT':
|
||||
$i += 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$command->setRawArguments($arguments);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the specified prefix to the keys of an EVAL-based command.
|
||||
*
|
||||
* @param CommandInterface $command Command instance.
|
||||
* @param string $prefix Prefix string.
|
||||
*/
|
||||
public static function evalKeys(CommandInterface $command, $prefix)
|
||||
{
|
||||
if ($arguments = $command->getArguments()) {
|
||||
for ($i = 2; $i < $arguments[1] + 2; ++$i) {
|
||||
$arguments[$i] = "$prefix{$arguments[$i]}";
|
||||
}
|
||||
|
||||
$command->setRawArguments($arguments);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the specified prefix to the keys of Z[INTERSECTION|UNION]STORE.
|
||||
*
|
||||
* @param CommandInterface $command Command instance.
|
||||
* @param string $prefix Prefix string.
|
||||
*/
|
||||
public static function zsetStore(CommandInterface $command, $prefix)
|
||||
{
|
||||
if ($arguments = $command->getArguments()) {
|
||||
$arguments[0] = "$prefix{$arguments[0]}";
|
||||
$length = ((int) $arguments[1]) + 2;
|
||||
|
||||
for ($i = 2; $i < $length; ++$i) {
|
||||
$arguments[$i] = "$prefix{$arguments[$i]}";
|
||||
}
|
||||
|
||||
$command->setRawArguments($arguments);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the specified prefix to the key of a MIGRATE command.
|
||||
*
|
||||
* @param CommandInterface $command Command instance.
|
||||
* @param string $prefix Prefix string.
|
||||
*/
|
||||
public static function migrate(CommandInterface $command, $prefix)
|
||||
{
|
||||
if ($arguments = $command->getArguments()) {
|
||||
$arguments[2] = "$prefix{$arguments[2]}";
|
||||
$command->setRawArguments($arguments);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the specified prefix to the key of a GEORADIUS command.
|
||||
*
|
||||
* @param CommandInterface $command Command instance.
|
||||
* @param string $prefix Prefix string.
|
||||
*/
|
||||
public static function georadius(CommandInterface $command, $prefix)
|
||||
{
|
||||
if ($arguments = $command->getArguments()) {
|
||||
$arguments[0] = "$prefix{$arguments[0]}";
|
||||
$startIndex = $command->getId() === 'GEORADIUS' ? 5 : 4;
|
||||
|
||||
if (($count = count($arguments)) > $startIndex) {
|
||||
for ($i = $startIndex; $i < $count; ++$i) {
|
||||
switch (strtoupper($arguments[$i])) {
|
||||
case 'STORE':
|
||||
case 'STOREDIST':
|
||||
$arguments[$i] = "$prefix{$arguments[++$i]}";
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$command->setRawArguments($arguments);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,9 +12,6 @@
|
||||
|
||||
namespace Predis\Command;
|
||||
|
||||
use Predis\ClientConfiguration;
|
||||
use UnexpectedValueException;
|
||||
|
||||
/**
|
||||
* Class representing a generic Redis command.
|
||||
*
|
||||
@@ -123,72 +120,4 @@ final class RawCommand implements CommandInterface
|
||||
{
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function parseResp3Response($data)
|
||||
{
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function serializeCommand(): string
|
||||
{
|
||||
$commandID = $this->getId();
|
||||
$arguments = $this->getArguments();
|
||||
|
||||
$cmdlen = strlen($commandID);
|
||||
$reqlen = count($arguments) + 1;
|
||||
|
||||
$buffer = "*{$reqlen}\r\n\${$cmdlen}\r\n{$commandID}\r\n";
|
||||
|
||||
foreach ($arguments as $argument) {
|
||||
$arglen = strlen(strval($argument));
|
||||
$buffer .= "\${$arglen}\r\n{$argument}\r\n";
|
||||
}
|
||||
|
||||
return $buffer;
|
||||
}
|
||||
|
||||
public static function deserializeCommand(string $serializedCommand): CommandInterface
|
||||
{
|
||||
if ($serializedCommand[0] !== '*') {
|
||||
throw new UnexpectedValueException('Invalid serializing format');
|
||||
}
|
||||
|
||||
$commandArray = explode("\r\n", $serializedCommand);
|
||||
$commandId = $commandArray[2];
|
||||
$classPath = __NAMESPACE__ . '\Redis\\';
|
||||
|
||||
// Check if given command is a module command.
|
||||
if (count($commandIdArray = explode('.', $commandId)) > 1) {
|
||||
// Fetch module configuration to resolve namespace.
|
||||
$moduleConfiguration = array_filter(
|
||||
ClientConfiguration::getModules(),
|
||||
static function ($module) use ($commandIdArray) {
|
||||
return $module['commandPrefix'] === $commandIdArray[0];
|
||||
}
|
||||
);
|
||||
|
||||
$commandClass = strtoupper($commandIdArray[0] . $commandIdArray[1]);
|
||||
$classPath .= array_shift($moduleConfiguration)['name'] . '\\' . $commandClass;
|
||||
} else {
|
||||
$classPath .= $commandIdArray[0];
|
||||
}
|
||||
|
||||
$command = new $classPath();
|
||||
$arguments = [];
|
||||
|
||||
for ($i = 4, $iMax = count($commandArray); $i < $iMax; $i++) {
|
||||
$arguments[] = $commandArray[$i];
|
||||
++$i;
|
||||
}
|
||||
|
||||
$command->setArguments($arguments);
|
||||
|
||||
return $command;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
namespace Predis\Command\Redis;
|
||||
|
||||
use Predis\Command\PrefixableCommand as RedisCommand;
|
||||
use Predis\Command\Command as RedisCommand;
|
||||
|
||||
/**
|
||||
* @see http://redis.io/commands/append
|
||||
@@ -26,9 +26,4 @@ class APPEND extends RedisCommand
|
||||
{
|
||||
return 'APPEND';
|
||||
}
|
||||
|
||||
public function prefixKeys($prefix)
|
||||
{
|
||||
$this->applyPrefixForFirstArgument($prefix);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,13 +40,4 @@ abstract class BZPOPBase extends RedisCommand
|
||||
|
||||
return array_combine([$key], [[$data[0] => $data[1]]]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $data
|
||||
* @return array|false|mixed|null[]|string|null
|
||||
*/
|
||||
public function parseResp3Response($data)
|
||||
{
|
||||
return $this->parseResponse($data);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
namespace Predis\Command\Redis;
|
||||
|
||||
use Predis\Command\PrefixableCommand as RedisCommand;
|
||||
use Predis\Command\Command as RedisCommand;
|
||||
use Predis\Command\Traits\BitByte;
|
||||
|
||||
/**
|
||||
@@ -31,9 +31,4 @@ class BITCOUNT extends RedisCommand
|
||||
{
|
||||
return 'BITCOUNT';
|
||||
}
|
||||
|
||||
public function prefixKeys($prefix)
|
||||
{
|
||||
$this->applyPrefixForFirstArgument($prefix);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
namespace Predis\Command\Redis;
|
||||
|
||||
use Predis\Command\PrefixableCommand as RedisCommand;
|
||||
use Predis\Command\Command as RedisCommand;
|
||||
|
||||
/**
|
||||
* @see http://redis.io/commands/bitfield
|
||||
@@ -26,9 +26,4 @@ class BITFIELD extends RedisCommand
|
||||
{
|
||||
return 'BITFIELD';
|
||||
}
|
||||
|
||||
public function prefixKeys($prefix)
|
||||
{
|
||||
$this->applyPrefixForFirstArgument($prefix);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,16 +12,13 @@
|
||||
|
||||
namespace Predis\Command\Redis;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use Predis\Command\PrefixableCommand as RedisCommand;
|
||||
use Predis\Command\Command as RedisCommand;
|
||||
|
||||
/**
|
||||
* @see http://redis.io/commands/bitop
|
||||
*/
|
||||
class BITOP extends RedisCommand
|
||||
{
|
||||
private const VALID_OPERATIONS = ['AND', 'OR', 'XOR', 'NOT', 'DIFF', 'DIFF1', 'ANDOR', 'ONE'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
@@ -41,18 +38,6 @@ class BITOP extends RedisCommand
|
||||
array_unshift($arguments, $operation, $destination);
|
||||
}
|
||||
|
||||
if (!empty($arguments)) {
|
||||
$operation = strtoupper($arguments[0]);
|
||||
if (!in_array($operation, self::VALID_OPERATIONS, false)) {
|
||||
throw new InvalidArgumentException('BITOP operation must be one of: AND, OR, XOR, NOT, DIFF, DIFF1, ANDOR, ONE');
|
||||
}
|
||||
}
|
||||
|
||||
parent::setArguments($arguments);
|
||||
}
|
||||
|
||||
public function prefixKeys($prefix)
|
||||
{
|
||||
$this->applyPrefixSkippingFirstArgument($prefix);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
namespace Predis\Command\Redis;
|
||||
|
||||
use Predis\Command\PrefixableCommand as RedisCommand;
|
||||
use Predis\Command\Command as RedisCommand;
|
||||
use Predis\Command\Traits\BitByte;
|
||||
|
||||
/**
|
||||
@@ -31,9 +31,4 @@ class BITPOS extends RedisCommand
|
||||
{
|
||||
return 'BITPOS';
|
||||
}
|
||||
|
||||
public function prefixKeys($prefix)
|
||||
{
|
||||
$this->applyPrefixForFirstArgument($prefix);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
namespace Predis\Command\Redis;
|
||||
|
||||
use Predis\Command\PrefixableCommand as RedisCommand;
|
||||
use Predis\Command\Command as RedisCommand;
|
||||
|
||||
/**
|
||||
* @see http://redis.io/commands/blpop
|
||||
@@ -39,9 +39,4 @@ class BLPOP extends RedisCommand
|
||||
|
||||
parent::setArguments($arguments);
|
||||
}
|
||||
|
||||
public function prefixKeys($prefix)
|
||||
{
|
||||
$this->applyPrefixSkippingLastArgument($prefix);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
namespace Predis\Command\Redis;
|
||||
|
||||
use Predis\Command\PrefixableCommand as RedisCommand;
|
||||
use Predis\Command\Command as RedisCommand;
|
||||
|
||||
/**
|
||||
* @see http://redis.io/commands/brpop
|
||||
@@ -39,9 +39,4 @@ class BRPOP extends RedisCommand
|
||||
|
||||
parent::setArguments($arguments);
|
||||
}
|
||||
|
||||
public function prefixKeys($prefix)
|
||||
{
|
||||
$this->applyPrefixSkippingLastArgument($prefix);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
namespace Predis\Command\Redis;
|
||||
|
||||
use Predis\Command\PrefixableCommand as RedisCommand;
|
||||
use Predis\Command\Command as RedisCommand;
|
||||
|
||||
/**
|
||||
* @see http://redis.io/commands/brpoplpush
|
||||
@@ -26,9 +26,4 @@ class BRPOPLPUSH extends RedisCommand
|
||||
{
|
||||
return 'BRPOPLPUSH';
|
||||
}
|
||||
|
||||
public function prefixKeys($prefix)
|
||||
{
|
||||
$this->applyPrefixSkippingLastArgument($prefix);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
namespace Predis\Command\Redis\BloomFilter;
|
||||
|
||||
use Predis\Command\PrefixableCommand as RedisCommand;
|
||||
use Predis\Command\Command as RedisCommand;
|
||||
|
||||
/**
|
||||
* @see https://redis.io/commands/bf.add/
|
||||
@@ -26,9 +26,4 @@ class BFADD extends RedisCommand
|
||||
{
|
||||
return 'BF.ADD';
|
||||
}
|
||||
|
||||
public function prefixKeys($prefix)
|
||||
{
|
||||
$this->applyPrefixForFirstArgument($prefix);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
namespace Predis\Command\Redis\BloomFilter;
|
||||
|
||||
use Predis\Command\PrefixableCommand as RedisCommand;
|
||||
use Predis\Command\Command as RedisCommand;
|
||||
|
||||
/**
|
||||
* @see https://redis.io/commands/bf.exists/
|
||||
@@ -25,9 +25,4 @@ class BFEXISTS extends RedisCommand
|
||||
{
|
||||
return 'BF.EXISTS';
|
||||
}
|
||||
|
||||
public function prefixKeys($prefix)
|
||||
{
|
||||
$this->applyPrefixForFirstArgument($prefix);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
namespace Predis\Command\Redis\BloomFilter;
|
||||
|
||||
use Predis\Command\PrefixableCommand as RedisCommand;
|
||||
use Predis\Command\Command as RedisCommand;
|
||||
use UnexpectedValueException;
|
||||
|
||||
/**
|
||||
@@ -76,9 +76,4 @@ class BFINFO extends RedisCommand
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function prefixKeys($prefix)
|
||||
{
|
||||
$this->applyPrefixForFirstArgument($prefix);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
namespace Predis\Command\Redis\BloomFilter;
|
||||
|
||||
use Predis\Command\PrefixableCommand as RedisCommand;
|
||||
use Predis\Command\Command as RedisCommand;
|
||||
use Predis\Command\Traits\BloomFilters\Capacity;
|
||||
use Predis\Command\Traits\BloomFilters\Error;
|
||||
use Predis\Command\Traits\BloomFilters\Expansion;
|
||||
@@ -48,11 +48,6 @@ class BFINSERT extends RedisCommand
|
||||
return 'BF.INSERT';
|
||||
}
|
||||
|
||||
public function prefixKeys($prefix)
|
||||
{
|
||||
$this->applyPrefixForFirstArgument($prefix);
|
||||
}
|
||||
|
||||
public function setArguments(array $arguments)
|
||||
{
|
||||
$this->setNoCreate($arguments);
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
namespace Predis\Command\Redis\BloomFilter;
|
||||
|
||||
use Predis\Command\PrefixableCommand as RedisCommand;
|
||||
use Predis\Command\Command as RedisCommand;
|
||||
|
||||
/**
|
||||
* @see https://redis.io/commands/bf.loadchunk/
|
||||
@@ -25,9 +25,4 @@ class BFLOADCHUNK extends RedisCommand
|
||||
{
|
||||
return 'BF.LOADCHUNK';
|
||||
}
|
||||
|
||||
public function prefixKeys($prefix)
|
||||
{
|
||||
$this->applyPrefixForFirstArgument($prefix);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
namespace Predis\Command\Redis\BloomFilter;
|
||||
|
||||
use Predis\Command\PrefixableCommand as RedisCommand;
|
||||
use Predis\Command\Command as RedisCommand;
|
||||
|
||||
/**
|
||||
* @see https://redis.io/commands/bf.madd/
|
||||
@@ -26,9 +26,4 @@ class BFMADD extends RedisCommand
|
||||
{
|
||||
return 'BF.MADD';
|
||||
}
|
||||
|
||||
public function prefixKeys($prefix)
|
||||
{
|
||||
$this->applyPrefixForFirstArgument($prefix);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
namespace Predis\Command\Redis\BloomFilter;
|
||||
|
||||
use Predis\Command\PrefixableCommand as RedisCommand;
|
||||
use Predis\Command\Command as RedisCommand;
|
||||
|
||||
/**
|
||||
* @see https://redis.io/commands/bf.mexists/
|
||||
@@ -25,9 +25,4 @@ class BFMEXISTS extends RedisCommand
|
||||
{
|
||||
return 'BF.MEXISTS';
|
||||
}
|
||||
|
||||
public function prefixKeys($prefix)
|
||||
{
|
||||
$this->applyPrefixForFirstArgument($prefix);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
namespace Predis\Command\Redis\BloomFilter;
|
||||
|
||||
use Predis\Command\PrefixableCommand as RedisCommand;
|
||||
use Predis\Command\Command as RedisCommand;
|
||||
use Predis\Command\Traits\BloomFilters\Expansion;
|
||||
|
||||
/**
|
||||
@@ -46,9 +46,4 @@ class BFRESERVE extends RedisCommand
|
||||
$this->setExpansion($arguments);
|
||||
$this->filterArguments();
|
||||
}
|
||||
|
||||
public function prefixKeys($prefix)
|
||||
{
|
||||
$this->applyPrefixForFirstArgument($prefix);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
namespace Predis\Command\Redis\BloomFilter;
|
||||
|
||||
use Predis\Command\PrefixableCommand as RedisCommand;
|
||||
use Predis\Command\Command as RedisCommand;
|
||||
|
||||
/**
|
||||
* @see https://redis.io/commands/bf.scandump/
|
||||
@@ -26,9 +26,4 @@ class BFSCANDUMP extends RedisCommand
|
||||
{
|
||||
return 'BF.SCANDUMP';
|
||||
}
|
||||
|
||||
public function prefixKeys($prefix)
|
||||
{
|
||||
$this->applyPrefixForFirstArgument($prefix);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,77 +30,6 @@ class CLIENT extends RedisCommand
|
||||
return 'CLIENT';
|
||||
}
|
||||
|
||||
public function setArguments(array $arguments)
|
||||
{
|
||||
switch ($arguments[0]) {
|
||||
case 'LIST':
|
||||
$this->setListArguments($arguments);
|
||||
break;
|
||||
case 'NOEVICT':
|
||||
$arguments[0] = 'NO-EVICT';
|
||||
$this->setNoTouchArguments($arguments);
|
||||
break;
|
||||
case 'NOTOUCH':
|
||||
$arguments[0] = 'NO-TOUCH';
|
||||
$this->setNoTouchArguments($arguments);
|
||||
break;
|
||||
case 'SETINFO':
|
||||
$this->setSetInfoArguments($arguments);
|
||||
break;
|
||||
default:
|
||||
parent::setArguments($arguments);
|
||||
}
|
||||
}
|
||||
|
||||
private function setListArguments(array $arguments): void
|
||||
{
|
||||
$processedArguments = [$arguments[0]];
|
||||
|
||||
if (array_key_exists(1, $arguments) && null !== $arguments[1]) {
|
||||
array_push($processedArguments, 'TYPE', strtoupper($arguments[1]));
|
||||
}
|
||||
|
||||
if (array_key_exists(2, $arguments)) {
|
||||
array_push($processedArguments, 'ID', $arguments[2]);
|
||||
}
|
||||
|
||||
if (count($arguments) > 3) {
|
||||
for ($i = 3, $iMax = count($arguments); $i < $iMax; $i++) {
|
||||
$processedArguments[] = $arguments[$i];
|
||||
}
|
||||
}
|
||||
|
||||
parent::setArguments($processedArguments);
|
||||
}
|
||||
|
||||
private function setNoTouchArguments(array $arguments): void
|
||||
{
|
||||
$processedArguments = [$arguments[0]];
|
||||
|
||||
if (array_key_exists(1, $arguments) && null !== $arguments[1]) {
|
||||
$modifier = ($arguments[1]) ? 'ON' : 'OFF';
|
||||
$processedArguments[] = $modifier;
|
||||
}
|
||||
|
||||
parent::setArguments($processedArguments);
|
||||
}
|
||||
|
||||
private function setSetInfoArguments(array $arguments): void
|
||||
{
|
||||
$processedArguments = [$arguments[0]];
|
||||
|
||||
if (
|
||||
array_key_exists(1, $arguments)
|
||||
&& null !== $arguments[1]
|
||||
&& array_key_exists(2, $arguments)
|
||||
&& null !== $arguments[2]
|
||||
) {
|
||||
array_push($processedArguments, strtoupper($arguments[1]), $arguments[2]);
|
||||
}
|
||||
|
||||
parent::setArguments($processedArguments);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
@@ -143,13 +72,4 @@ class CLIENT extends RedisCommand
|
||||
|
||||
return $clients;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $data
|
||||
* @return array|mixed|string|null
|
||||
*/
|
||||
public function parseResp3Response($data)
|
||||
{
|
||||
return $this->parseResponse($data);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,23 +32,9 @@ class COMMAND extends BaseCommand
|
||||
*/
|
||||
public function parseResponse($data)
|
||||
{
|
||||
if (!is_array($data)) {
|
||||
return $data;
|
||||
}
|
||||
// Relay (RESP3) uses maps and it might be good
|
||||
// to make the return value a breaking change
|
||||
|
||||
if ($data === array_values($data)) {
|
||||
return array_map(function ($item) {
|
||||
return $this->parseResponse($item);
|
||||
}, $data);
|
||||
}
|
||||
|
||||
// Relay
|
||||
$result = [];
|
||||
foreach ($data as $key => $value) {
|
||||
$result[] = $key;
|
||||
$result[] = $this->parseResponse($value);
|
||||
}
|
||||
|
||||
return $result;
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,17 +10,15 @@
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Predis\Command\Container;
|
||||
namespace Predis\Command\Redis\Container;
|
||||
|
||||
use Predis\Response\Status;
|
||||
|
||||
/**
|
||||
* @method array cat(string $category = null)
|
||||
* @method Status dryRun(string $username, string $command, ...$arguments)
|
||||
* @method int delUser(string ...$username)
|
||||
* @method array getUser(string $username)
|
||||
* @method Status setUser(string $username, string ...$rules)
|
||||
* @method string whoami()
|
||||
*/
|
||||
class ACL extends AbstractContainer
|
||||
{
|
||||
+1
-1
@@ -10,7 +10,7 @@
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Predis\Command\Container;
|
||||
namespace Predis\Command\Redis\Container;
|
||||
|
||||
use Predis\ClientInterface;
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Predis\Command\Container;
|
||||
namespace Predis\Command\Redis\Container;
|
||||
|
||||
use Predis\Response\Status;
|
||||
|
||||
+3
-3
@@ -10,7 +10,7 @@
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Predis\Command\Container;
|
||||
namespace Predis\Command\Redis\Container;
|
||||
|
||||
use Predis\ClientConfiguration;
|
||||
use Predis\ClientInterface;
|
||||
@@ -18,7 +18,7 @@ use UnexpectedValueException;
|
||||
|
||||
class ContainerFactory
|
||||
{
|
||||
private const CONTAINER_NAMESPACE = "Predis\Command\Container";
|
||||
private const CONTAINER_NAMESPACE = "Predis\Command\Redis\Container";
|
||||
|
||||
/**
|
||||
* Mappings for class names that corresponds to PHP reserved words.
|
||||
@@ -26,7 +26,7 @@ class ContainerFactory
|
||||
* @var array
|
||||
*/
|
||||
private static $specialMappings = [
|
||||
'FUNCTION' => FUNCTIONS::class,
|
||||
'FUNCTION' => FunctionContainer::class,
|
||||
];
|
||||
|
||||
/**
|
||||
+1
-1
@@ -10,7 +10,7 @@
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Predis\Command\Container;
|
||||
namespace Predis\Command\Redis\Container;
|
||||
|
||||
interface ContainerInterface
|
||||
{
|
||||
+4
-4
@@ -10,7 +10,7 @@
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Predis\Command\Container;
|
||||
namespace Predis\Command\Redis\Container;
|
||||
|
||||
use Predis\Response\Status;
|
||||
|
||||
@@ -19,12 +19,12 @@ use Predis\Response\Status;
|
||||
* @method string dump()
|
||||
* @method Status flush(?string $mode = null)
|
||||
* @method Status kill()
|
||||
* @method array list(string $libraryNamePattern = null, bool $withCode = false)
|
||||
* @method array list(?string $libraryNamePattern = null, bool $withCode = false)
|
||||
* @method string load(string $functionCode, bool $replace = 'false')
|
||||
* @method Status restore(string $value, string $policy = null)
|
||||
* @method Status restore(string $value, ?string $policy = null)
|
||||
* @method array stats()
|
||||
*/
|
||||
class FUNCTIONS extends AbstractContainer
|
||||
class FunctionContainer extends AbstractContainer
|
||||
{
|
||||
public function getContainerCommandId(): string
|
||||
{
|
||||
+2
-2
@@ -10,9 +10,9 @@
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Predis\Command\Container\Json;
|
||||
namespace Predis\Command\Redis\Container\Json;
|
||||
|
||||
use Predis\Command\Container\AbstractContainer;
|
||||
use Predis\Command\Redis\Container\AbstractContainer;
|
||||
|
||||
/**
|
||||
* @method array memory(string $key, string $path)
|
||||
+2
-2
@@ -10,9 +10,9 @@
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Predis\Command\Container\Search;
|
||||
namespace Predis\Command\Redis\Container\Search;
|
||||
|
||||
use Predis\Command\Container\AbstractContainer;
|
||||
use Predis\Command\Redis\Container\AbstractContainer;
|
||||
use Predis\Response\Status;
|
||||
|
||||
/**
|
||||
+2
-2
@@ -10,10 +10,10 @@
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Predis\Command\Container\Search;
|
||||
namespace Predis\Command\Redis\Container\Search;
|
||||
|
||||
use Predis\Command\Argument\Search\CursorArguments;
|
||||
use Predis\Command\Container\AbstractContainer;
|
||||
use Predis\Command\Redis\Container\AbstractContainer;
|
||||
use Predis\Response\Status;
|
||||
|
||||
/**
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
namespace Predis\Command\Redis\CountMinSketch;
|
||||
|
||||
use Predis\Command\PrefixableCommand as RedisCommand;
|
||||
use Predis\Command\Command as RedisCommand;
|
||||
|
||||
/**
|
||||
* @see https://redis.io/commands/cms.incrby/
|
||||
@@ -26,9 +26,4 @@ class CMSINCRBY extends RedisCommand
|
||||
{
|
||||
return 'CMS.INCRBY';
|
||||
}
|
||||
|
||||
public function prefixKeys($prefix)
|
||||
{
|
||||
$this->applyPrefixForFirstArgument($prefix);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
namespace Predis\Command\Redis\CountMinSketch;
|
||||
|
||||
use Predis\Command\PrefixableCommand as RedisCommand;
|
||||
use Predis\Command\Command as RedisCommand;
|
||||
|
||||
/**
|
||||
* @see https://redis.io/commands/cms.info/
|
||||
@@ -42,9 +42,4 @@ class CMSINFO extends RedisCommand
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function prefixKeys($prefix)
|
||||
{
|
||||
$this->applyPrefixForFirstArgument($prefix);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
namespace Predis\Command\Redis\CountMinSketch;
|
||||
|
||||
use Predis\Command\PrefixableCommand as RedisCommand;
|
||||
use Predis\Command\Command as RedisCommand;
|
||||
|
||||
/**
|
||||
* @see https://redis.io/commands/cms.initbydim/
|
||||
@@ -25,9 +25,4 @@ class CMSINITBYDIM extends RedisCommand
|
||||
{
|
||||
return 'CMS.INITBYDIM';
|
||||
}
|
||||
|
||||
public function prefixKeys($prefix)
|
||||
{
|
||||
$this->applyPrefixForFirstArgument($prefix);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
namespace Predis\Command\Redis\CountMinSketch;
|
||||
|
||||
use Predis\Command\PrefixableCommand as RedisCommand;
|
||||
use Predis\Command\Command as RedisCommand;
|
||||
|
||||
/**
|
||||
* @see https://redis.io/commands/cms.initbyprob/
|
||||
@@ -25,9 +25,4 @@ class CMSINITBYPROB extends RedisCommand
|
||||
{
|
||||
return 'CMS.INITBYPROB';
|
||||
}
|
||||
|
||||
public function prefixKeys($prefix)
|
||||
{
|
||||
$this->applyPrefixForFirstArgument($prefix);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
namespace Predis\Command\Redis\CountMinSketch;
|
||||
|
||||
use Predis\Command\PrefixableCommand as RedisCommand;
|
||||
use Predis\Command\Command as RedisCommand;
|
||||
|
||||
/**
|
||||
* @see https://redis.io/commands/cms.merge/
|
||||
@@ -39,17 +39,4 @@ class CMSMERGE extends RedisCommand
|
||||
|
||||
parent::setArguments($processedArguments);
|
||||
}
|
||||
|
||||
public function prefixKeys($prefix)
|
||||
{
|
||||
if ($arguments = $this->getArguments()) {
|
||||
$arguments[0] = $prefix . $arguments[0];
|
||||
|
||||
for ($i = 2, $iMax = (int) $arguments[1] + 2; $i < $iMax; $i++) {
|
||||
$arguments[$i] = $prefix . $arguments[$i];
|
||||
}
|
||||
|
||||
$this->setRawArguments($arguments);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
namespace Predis\Command\Redis\CountMinSketch;
|
||||
|
||||
use Predis\Command\PrefixableCommand as RedisCommand;
|
||||
use Predis\Command\Command as RedisCommand;
|
||||
|
||||
/**
|
||||
* @see https://redis.io/commands/cms.query/
|
||||
@@ -25,9 +25,4 @@ class CMSQUERY extends RedisCommand
|
||||
{
|
||||
return 'CMS.QUERY';
|
||||
}
|
||||
|
||||
public function prefixKeys($prefix)
|
||||
{
|
||||
$this->applyPrefixForFirstArgument($prefix);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
namespace Predis\Command\Redis\CuckooFilter;
|
||||
|
||||
use Predis\Command\PrefixableCommand as RedisCommand;
|
||||
use Predis\Command\Command as RedisCommand;
|
||||
|
||||
/**
|
||||
* @see https://redis.io/commands/cf.add/
|
||||
@@ -25,9 +25,4 @@ class CFADD extends RedisCommand
|
||||
{
|
||||
return 'CF.ADD';
|
||||
}
|
||||
|
||||
public function prefixKeys($prefix)
|
||||
{
|
||||
$this->applyPrefixForFirstArgument($prefix);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
namespace Predis\Command\Redis\CuckooFilter;
|
||||
|
||||
use Predis\Command\PrefixableCommand as RedisCommand;
|
||||
use Predis\Command\Command as RedisCommand;
|
||||
|
||||
/**
|
||||
* @see https://redis.io/commands/cf.addnx/
|
||||
@@ -25,9 +25,4 @@ class CFADDNX extends RedisCommand
|
||||
{
|
||||
return 'CF.ADDNX';
|
||||
}
|
||||
|
||||
public function prefixKeys($prefix)
|
||||
{
|
||||
$this->applyPrefixForFirstArgument($prefix);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
namespace Predis\Command\Redis\CuckooFilter;
|
||||
|
||||
use Predis\Command\PrefixableCommand as RedisCommand;
|
||||
use Predis\Command\Command as RedisCommand;
|
||||
|
||||
/**
|
||||
* @see https://redis.io/commands/cf.count/
|
||||
@@ -26,9 +26,4 @@ class CFCOUNT extends RedisCommand
|
||||
{
|
||||
return 'CF.COUNT';
|
||||
}
|
||||
|
||||
public function prefixKeys($prefix)
|
||||
{
|
||||
$this->applyPrefixForFirstArgument($prefix);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
namespace Predis\Command\Redis\CuckooFilter;
|
||||
|
||||
use Predis\Command\PrefixableCommand as RedisCommand;
|
||||
use Predis\Command\Command as RedisCommand;
|
||||
|
||||
/**
|
||||
* @see https://redis.io/commands/cf.del/
|
||||
@@ -27,9 +27,4 @@ class CFDEL extends RedisCommand
|
||||
{
|
||||
return 'CF.DEL';
|
||||
}
|
||||
|
||||
public function prefixKeys($prefix)
|
||||
{
|
||||
$this->applyPrefixForFirstArgument($prefix);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
namespace Predis\Command\Redis\CuckooFilter;
|
||||
|
||||
use Predis\Command\PrefixableCommand as RedisCommand;
|
||||
use Predis\Command\Command as RedisCommand;
|
||||
|
||||
/**
|
||||
* @see https://redis.io/commands/cf.exists/
|
||||
@@ -25,9 +25,4 @@ class CFEXISTS extends RedisCommand
|
||||
{
|
||||
return 'CF.EXISTS';
|
||||
}
|
||||
|
||||
public function prefixKeys($prefix)
|
||||
{
|
||||
$this->applyPrefixForFirstArgument($prefix);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
namespace Predis\Command\Redis\CuckooFilter;
|
||||
|
||||
use Predis\Command\PrefixableCommand as RedisCommand;
|
||||
use Predis\Command\Command as RedisCommand;
|
||||
|
||||
/**
|
||||
* @see https://redis.io/commands/cf.info/
|
||||
@@ -42,9 +42,4 @@ class CFINFO extends RedisCommand
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function prefixKeys($prefix)
|
||||
{
|
||||
$this->applyPrefixForFirstArgument($prefix);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
namespace Predis\Command\Redis\CuckooFilter;
|
||||
|
||||
use Predis\Command\PrefixableCommand as RedisCommand;
|
||||
use Predis\Command\Command as RedisCommand;
|
||||
use Predis\Command\Traits\BloomFilters\Capacity;
|
||||
use Predis\Command\Traits\BloomFilters\Items;
|
||||
use Predis\Command\Traits\BloomFilters\NoCreate;
|
||||
@@ -49,9 +49,4 @@ class CFINSERT extends RedisCommand
|
||||
$this->setCapacity($arguments);
|
||||
$this->filterArguments();
|
||||
}
|
||||
|
||||
public function prefixKeys($prefix)
|
||||
{
|
||||
$this->applyPrefixForFirstArgument($prefix);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
namespace Predis\Command\Redis\CuckooFilter;
|
||||
|
||||
use Predis\Command\PrefixableCommand as RedisCommand;
|
||||
use Predis\Command\Command as RedisCommand;
|
||||
|
||||
/**
|
||||
* @see https://redis.io/commands/cf.loadchunk/
|
||||
@@ -26,9 +26,4 @@ class CFLOADCHUNK extends RedisCommand
|
||||
{
|
||||
return 'CF.LOADCHUNK';
|
||||
}
|
||||
|
||||
public function prefixKeys($prefix)
|
||||
{
|
||||
$this->applyPrefixForFirstArgument($prefix);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
namespace Predis\Command\Redis\CuckooFilter;
|
||||
|
||||
use Predis\Command\PrefixableCommand as RedisCommand;
|
||||
use Predis\Command\Command as RedisCommand;
|
||||
|
||||
/**
|
||||
* @see https://redis.io/commands/cf.mexists/
|
||||
@@ -25,9 +25,4 @@ class CFMEXISTS extends RedisCommand
|
||||
{
|
||||
return 'CF.MEXISTS';
|
||||
}
|
||||
|
||||
public function prefixKeys($prefix)
|
||||
{
|
||||
$this->applyPrefixForFirstArgument($prefix);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
namespace Predis\Command\Redis\CuckooFilter;
|
||||
|
||||
use Predis\Command\PrefixableCommand as RedisCommand;
|
||||
use Predis\Command\Command as RedisCommand;
|
||||
use Predis\Command\Traits\BloomFilters\BucketSize;
|
||||
use Predis\Command\Traits\BloomFilters\Expansion;
|
||||
use Predis\Command\Traits\BloomFilters\MaxIterations;
|
||||
@@ -49,9 +49,4 @@ class CFRESERVE extends RedisCommand
|
||||
$this->setBucketSize($arguments);
|
||||
$this->filterArguments();
|
||||
}
|
||||
|
||||
public function prefixKeys($prefix)
|
||||
{
|
||||
$this->applyPrefixForFirstArgument($prefix);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
namespace Predis\Command\Redis\CuckooFilter;
|
||||
|
||||
use Predis\Command\PrefixableCommand as RedisCommand;
|
||||
use Predis\Command\Command as RedisCommand;
|
||||
|
||||
/**
|
||||
* @see https://redis.io/commands/cf.scandump/
|
||||
@@ -26,9 +26,4 @@ class CFSCANDUMP extends RedisCommand
|
||||
{
|
||||
return 'CF.SCANDUMP';
|
||||
}
|
||||
|
||||
public function prefixKeys($prefix)
|
||||
{
|
||||
$this->applyPrefixForFirstArgument($prefix);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
namespace Predis\Command\Redis;
|
||||
|
||||
use Predis\Command\PrefixableCommand as RedisCommand;
|
||||
use Predis\Command\Command as RedisCommand;
|
||||
|
||||
/**
|
||||
* @see http://redis.io/commands/decr
|
||||
@@ -26,9 +26,4 @@ class DECR extends RedisCommand
|
||||
{
|
||||
return 'DECR';
|
||||
}
|
||||
|
||||
public function prefixKeys($prefix)
|
||||
{
|
||||
$this->applyPrefixForFirstArgument($prefix);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
namespace Predis\Command\Redis;
|
||||
|
||||
use Predis\Command\PrefixableCommand as RedisCommand;
|
||||
use Predis\Command\Command as RedisCommand;
|
||||
|
||||
/**
|
||||
* @see http://redis.io/commands/decrby
|
||||
@@ -26,9 +26,4 @@ class DECRBY extends RedisCommand
|
||||
{
|
||||
return 'DECRBY';
|
||||
}
|
||||
|
||||
public function prefixKeys($prefix)
|
||||
{
|
||||
$this->applyPrefixForFirstArgument($prefix);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
namespace Predis\Command\Redis;
|
||||
|
||||
use Predis\Command\PrefixableCommand as RedisCommand;
|
||||
use Predis\Command\Command as RedisCommand;
|
||||
|
||||
/**
|
||||
* @see http://redis.io/commands/del
|
||||
@@ -36,9 +36,4 @@ class DEL extends RedisCommand
|
||||
|
||||
parent::setArguments($arguments);
|
||||
}
|
||||
|
||||
public function prefixKeys($prefix)
|
||||
{
|
||||
$this->applyPrefixForAllArguments($prefix);
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user