mirror of
https://github.com/predis/predis.git
synced 2026-08-20 20:42:13 +00:00
Compare commits
100 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a77a43913a | |||
| fea402743f | |||
| 84844acb93 | |||
| 26c625230f | |||
| 8ef75ba6b2 | |||
| 8a5ced5251 | |||
| 29350952d0 | |||
| 98222f47b0 | |||
| 38e955bc26 | |||
| db65e5ebd3 | |||
| 50e005bfe3 | |||
| c541617333 | |||
| 0a8e0c2f96 | |||
| 793de36822 | |||
| fa13640ddd | |||
| 5331d943fe | |||
| 74d5ad22dd | |||
| a04bcb94fc | |||
| 9f77e5178f | |||
| ac259bdb6f | |||
| 6e45ca5154 | |||
| c201af5ad3 | |||
| 1c6c5feb3a | |||
| a8c5794b8a | |||
| ccc2860ad2 | |||
| 1cd78095e6 | |||
| f6f4830b3c | |||
| e3ad353125 | |||
| e00d1a0bd3 | |||
| 64604de751 | |||
| 20dcb4bb73 | |||
| 3daf75508d | |||
| 7a4b3d1d0f | |||
| 3cf958580a | |||
| d6dc6e51e1 | |||
| 113145f306 | |||
| 47a7cbc862 | |||
| 3c8a811ca3 | |||
| f4bd6d44b1 | |||
| 6b6179ee44 | |||
| 82791e55e1 | |||
| ea7698e12f | |||
| af2e5cc553 | |||
| b1009f46ac | |||
| a09da4f3b0 | |||
| 06c00ac43f | |||
| f3deda22cd | |||
| c412594217 | |||
| cc40219268 | |||
| 31b65f614b | |||
| c9babb1984 | |||
| c2af9427c5 | |||
| c5b60884e8 | |||
| 836ab07d40 | |||
| 2bfc8a9316 | |||
| d21576669d | |||
| 65fe24e346 | |||
| fbf270156f | |||
| 24630fbd5b | |||
| bded73f516 | |||
| 6a3f4a4c08 | |||
| 47896f1be7 | |||
| 586b039289 | |||
| d1acca607e | |||
| 721c829042 | |||
| b8cc7c643a | |||
| b47aa7ad3a | |||
| bb65b31580 | |||
| e540ca062b | |||
| 9c543ef5b1 | |||
| 83fb0020a1 | |||
| 4a77aea9ef | |||
| 72bc11eb63 | |||
| f26fd899f9 | |||
| 65447807ed | |||
| 5418cd5813 | |||
| bc5892e260 | |||
| 7c0cc7bdbe | |||
| 87ecd7bde2 | |||
| f9e77a0562 | |||
| d2b05ff58a | |||
| e24ecbbf90 | |||
| 9f3bdd5616 | |||
| 57a24413c2 | |||
| 0e6126ba9d | |||
| 7904fed6da | |||
| cfd6f030bc | |||
| 35d18d739a | |||
| 573c54ac4c | |||
| 169604bf74 | |||
| 94bd54b2af | |||
| bdebad7d62 | |||
| 1a411d2ad7 | |||
| 1400689df8 | |||
| ff59f74581 | |||
| 1a0eb7ee85 | |||
| bb6c1a7b6d | |||
| 42c33a406f | |||
| 7ad74217c2 | |||
| 72d7675563 |
@@ -0,0 +1,6 @@
|
||||
[codespell]
|
||||
skip=./.git
|
||||
check-hidden=
|
||||
check-filenames=
|
||||
builtin=clear,rare,informal,usage,code,names
|
||||
ignore-words-list=master,masters,slave,slaves,whitelist,cas,exat,smove
|
||||
+12
-5
@@ -1,5 +1,3 @@
|
||||
# http://editorconfig.org
|
||||
|
||||
root = true
|
||||
|
||||
[*]
|
||||
@@ -8,10 +6,19 @@ indent_style = space
|
||||
indent_size = 4
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
block_comment_start = /*
|
||||
block_comment = *
|
||||
block_comment_end = */
|
||||
|
||||
[*.php]
|
||||
trim_trailing_whitespace = true
|
||||
max_line_length = 120
|
||||
max_line_length = 150
|
||||
|
||||
[*.{md,yml}]
|
||||
[*.{md,yml,yaml,neon}]
|
||||
indent_size = 2
|
||||
|
||||
[tests/**.php]
|
||||
max_line_length = unset
|
||||
|
||||
[{src/ClientInterface.php,src/ClientContextInterface.php}]
|
||||
max_line_length = unset
|
||||
|
||||
+11
-3
@@ -1,9 +1,17 @@
|
||||
* text=auto
|
||||
|
||||
/tests export-ignore
|
||||
/.github export-ignore
|
||||
/.github/ export-ignore
|
||||
/examples/ export-ignore
|
||||
/tests/ export-ignore
|
||||
/.codespellrc export-ignore linguist-language=INI
|
||||
/.editorconfig export-ignore
|
||||
/.gitattributes export-ignore
|
||||
/.gitignore export-ignore
|
||||
/.php_cs.dist export-ignore
|
||||
/.php-cs-fixer.dist.php export-ignore
|
||||
/CHANGELOG.md export-ignore linguist-documentation
|
||||
/CONTRIBUTING.md export-ignore linguist-documentation
|
||||
/FAQ.md export-ignore linguist-documentation
|
||||
/VERSION export-ignore
|
||||
/phpunit.xml.dist export-ignore
|
||||
/phpstan.dist.neon export-ignore
|
||||
/phpstan-tests.dist.neon export-ignore
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
# 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
|
||||
@@ -19,10 +19,10 @@ Steps to reproduce the behavior:
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Versions (please complete the following information):**
|
||||
- Predis: [e.g. 1.1.2]
|
||||
- PHP [e.g. 8.0.0]
|
||||
- Redis Server [e.g. 6.0.0]
|
||||
- OS [e.g. Ubuntu 20.10]
|
||||
- Predis: [e.g. 1.1.2]
|
||||
- PHP [e.g. 8.0.0]
|
||||
- Redis Server [e.g. 6.0.0]
|
||||
- OS [e.g. Ubuntu 20.10]
|
||||
|
||||
**Code sample**
|
||||
If applicable, a small snippet of code that reproduces the issue.
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
name-template: 'v$NEXT_MINOR_VERSION'
|
||||
tag-template: 'v$NEXT_MINOR_VERSION'
|
||||
change-template: '- $TITLE (#$NUMBER)'
|
||||
|
||||
autolabeler:
|
||||
- label: 'maintenance'
|
||||
files:
|
||||
- '*.md'
|
||||
- '.github/*'
|
||||
- label: 'bug'
|
||||
branch:
|
||||
- '/bug-.+'
|
||||
- label: 'maintenance'
|
||||
branch:
|
||||
- '/maintenance-.+'
|
||||
- label: 'feature'
|
||||
branch:
|
||||
- '/feature-.+'
|
||||
|
||||
categories:
|
||||
- title: 'Breaking Changes'
|
||||
labels:
|
||||
- 'breakingchange'
|
||||
- title: 'Experimental Features'
|
||||
labels:
|
||||
- 'experimental'
|
||||
- title: 'New Features'
|
||||
labels:
|
||||
- 'feature'
|
||||
- 'enhancement'
|
||||
- title: 'Bug Fixes'
|
||||
labels:
|
||||
- 'fix'
|
||||
- 'bugfix'
|
||||
- 'bug'
|
||||
- 'BUG'
|
||||
- title: 'Maintenance'
|
||||
label: 'maintenance'
|
||||
|
||||
exclude-labels:
|
||||
- 'skip-changelog'
|
||||
|
||||
template: |
|
||||
$CHANGES
|
||||
|
||||
## Contributors
|
||||
We'd like to thank all the contributors who worked on this release!
|
||||
|
||||
$CONTRIBUTORS
|
||||
@@ -0,0 +1,9 @@
|
||||
# Workflows
|
||||
|
||||
## Delete runs by workflow name
|
||||
|
||||
```bash
|
||||
gh run list --workflow 'redis-server-tests.yml' --limit 1000 --json databaseId \
|
||||
| jq '.[].databaseId' \
|
||||
| xargs -I % gh api --silent -X DELETE /repos/predis/predis/actions/runs/%
|
||||
```
|
||||
@@ -0,0 +1,167 @@
|
||||
# yaml-language-server: $schema=https://json.schemastore.org/github-workflow
|
||||
|
||||
name: Linters
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- v2.**
|
||||
pull_request: null
|
||||
|
||||
permissions: {}
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
|
||||
byte_level:
|
||||
name: Byte-level
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Check file permissions
|
||||
run: test "$(find . -type f -not -path './.git/*' -executable)" = "./bin/create-command-test"
|
||||
|
||||
- name: "Find non-printable ASCII characters"
|
||||
run: |
|
||||
! LC_ALL=C.UTF-8 find . -type f -name '*.php' -print0 \
|
||||
| xargs --null -- grep --perl-regexp --with-filename --line-number '[^ -~ü]'
|
||||
|
||||
syntax_errors:
|
||||
name: Syntax errors
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Set up PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: "8.1"
|
||||
coverage: none
|
||||
tools: parallel-lint
|
||||
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Check source code for syntax errors
|
||||
run: composer exec -- parallel-lint bin/ examples/ src/ tests/
|
||||
|
||||
static_analysis:
|
||||
name: Static Analysis
|
||||
needs:
|
||||
- byte_level
|
||||
- syntax_errors
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Set up PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: "8.2"
|
||||
coverage: none
|
||||
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Validate Composer configuration
|
||||
run: composer validate --no-interaction --strict
|
||||
|
||||
- name: Install dependencies
|
||||
uses: ramsey/composer-install@v2
|
||||
with:
|
||||
dependency-versions: highest
|
||||
|
||||
- name: Check PSR-4 mapping
|
||||
run: composer dump-autoload --no-interaction --optimize --strict-psr
|
||||
|
||||
- name: Perform static analysis
|
||||
run: composer run phpstan
|
||||
|
||||
- name: Perform static analysis on tests
|
||||
run: composer run phpstan -- --configuration=phpstan-tests.dist.neon
|
||||
|
||||
coding_standards:
|
||||
name: Coding Standards
|
||||
needs:
|
||||
- byte_level
|
||||
- syntax_errors
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Set up PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: "8.1"
|
||||
coverage: none
|
||||
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Check EditorConfig configuration
|
||||
run: test -f .editorconfig
|
||||
|
||||
- name: Check adherence to EditorConfig
|
||||
uses: greut/eclint-action@v0
|
||||
|
||||
- name: Install dependencies
|
||||
uses: ramsey/composer-install@v2
|
||||
with:
|
||||
dependency-versions: highest
|
||||
|
||||
- name: Check coding style
|
||||
run: composer exec -- php-cs-fixer fix --diff --dry-run --allow-risky=yes --using-cache=no
|
||||
|
||||
- name: Search for TODO-s and FIXME-s
|
||||
run: |
|
||||
! git grep --extended-regexp --ignore-case '\b(TODO|FIXME)\b' -- ':/' ':!tests/*' ':!*/linters\.yml'
|
||||
|
||||
exported_files:
|
||||
name: Exported files
|
||||
needs:
|
||||
- byte_level
|
||||
- syntax_errors
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Check exported files
|
||||
run: |
|
||||
EXPECTED="LICENSE,README.md,autoload.php,composer.json"
|
||||
CURRENT="$(
|
||||
git archive HEAD \
|
||||
| tar --list --exclude="src" --exclude="src/*" --exclude="bin" --exclude="bin/*" \
|
||||
| paste --serial --delimiters=","
|
||||
)"
|
||||
echo "CURRENT =${CURRENT}"
|
||||
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
|
||||
@@ -0,0 +1,25 @@
|
||||
name: Release Drafter
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
|
||||
update_release_draft:
|
||||
|
||||
name: Update release draft
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
|
||||
- uses: release-drafter/release-drafter@v5
|
||||
with:
|
||||
config-name: release-drafter-config.yml
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
+56
-33
@@ -1,52 +1,75 @@
|
||||
name: Tests
|
||||
|
||||
on:
|
||||
- push
|
||||
- pull_request
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- v2.**
|
||||
pull_request:
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
|
||||
predis:
|
||||
name: PHP ${{ matrix.php-versions }} (Redis ${{ matrix.redis-versions }})
|
||||
name: PHP ${{ matrix.php }} Redis ${{ matrix.redis }}
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
services:
|
||||
redis:
|
||||
image: redis:${{ matrix.redis-versions }}
|
||||
ports:
|
||||
- 6379:6379
|
||||
options: --health-cmd="redis-cli ping" --health-interval=10s --health-timeout=5s --health-retries=3
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
php-versions: ['7.2', '7.3', '7.4', '8.0', '8.1', '8.2']
|
||||
redis-versions: ['3', '4', '5', '6', '7']
|
||||
php:
|
||||
- '7.2'
|
||||
- '7.3'
|
||||
- '7.4'
|
||||
- '8.0'
|
||||
- '8.1'
|
||||
- '8.2'
|
||||
redis:
|
||||
- '3'
|
||||
- '4'
|
||||
- '5'
|
||||
- '6'
|
||||
- '7'
|
||||
|
||||
services:
|
||||
redis:
|
||||
image: redis:${{ matrix.redis }}
|
||||
options: --health-cmd="redis-cli ping" --health-interval=10s --health-timeout=5s --health-retries=3
|
||||
ports:
|
||||
- 6379:6379
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Setup PHP with Composer and extensions
|
||||
with:
|
||||
php-version: ${{ matrix.php-versions }}
|
||||
uses: shivammathur/setup-php@v2
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Get Composer cache directory
|
||||
id: composercache
|
||||
run: echo "::set-output name=dir::$(composer config cache-files-dir)"
|
||||
- name: Setup PHP with Composer and extensions
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: ${{ matrix.php }}
|
||||
coverage: ${{ (matrix.php == '8.1' && matrix.redis == '7') && 'xdebug' || 'none' }}
|
||||
|
||||
- name: Cache Composer dependencies
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ${{ steps.composercache.outputs.dir }}
|
||||
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
|
||||
restore-keys: ${{ runner.os }}-composer-
|
||||
- name: Install Composer dependencies
|
||||
uses: ramsey/composer-install@v2
|
||||
with:
|
||||
dependency-versions: highest
|
||||
composer-options: ${{ matrix.php == '8.0' && '--ignore-platform-reqs' || '' }}
|
||||
|
||||
- name: Install Composer dependencies
|
||||
env:
|
||||
PHP_VERSION: ${{ matrix.php-versions }}
|
||||
run: composer install --no-progress --prefer-dist --optimize-autoloader $(if [ "$PHP_VERSION" == "8.0" ]; then echo "--ignore-platform-reqs"; fi;)
|
||||
- name: Run PHPUnit tests
|
||||
if: ${{ matrix.php != '8.1' || matrix.redis != '7' }}
|
||||
run: vendor/bin/phpunit --verbose
|
||||
|
||||
- name: Test with PHPUnit
|
||||
run: vendor/bin/phpunit
|
||||
- name: Run PHPUnit tests with coverage
|
||||
if: ${{ matrix.php == '8.1' && matrix.redis == '7' }}
|
||||
run: vendor/bin/phpunit --verbose --coverage-clover build/logs/clover.xml --coverage-filter ./src
|
||||
|
||||
- name: Send coverage to Coveralls
|
||||
env:
|
||||
COVERALLS_REPO_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
if: ${{ env.COVERALLS_REPO_TOKEN && matrix.php == '8.1' && matrix.redis == '7' }}
|
||||
run: |
|
||||
wget "https://github.com/php-coveralls/php-coveralls/releases/download/v2.5.3/php-coveralls.phar"
|
||||
php ./php-coveralls.phar -v
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
/build
|
||||
/vendor
|
||||
.php-version
|
||||
.php_cs.cache
|
||||
.phpunit.result.cache
|
||||
.php-cs-fixer.cache
|
||||
composer.lock
|
||||
phpunit.xml
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
$PREDIS_HEADER = <<<EOS
|
||||
This file is part of the Predis package.
|
||||
|
||||
(c) 2009-2020 Daniele Alessandri
|
||||
(c) 2021-2023 Till Krüss
|
||||
|
||||
For the full copyright and license information, please view the LICENSE
|
||||
file that was distributed with this source code.
|
||||
EOS;
|
||||
|
||||
return (new PhpCsFixer\Config)
|
||||
->setRules([
|
||||
'@PHP71Migration' => true,
|
||||
'header_comment' => ['header' => $PREDIS_HEADER],
|
||||
'@Symfony' => true,
|
||||
'phpdoc_separation' => false,
|
||||
'phpdoc_annotation_without_dot' => false,
|
||||
'no_superfluous_phpdoc_tags' => false,
|
||||
'no_unneeded_curly_braces' => false,
|
||||
'global_namespace_import' => true,
|
||||
'yoda_style' => false,
|
||||
'single_line_throw' => false,
|
||||
'concat_space' => ['spacing' => 'one'],
|
||||
'increment_style' => false,
|
||||
])
|
||||
->setFinder(
|
||||
PhpCsFixer\Finder::create()
|
||||
->in(__DIR__ . '/bin')
|
||||
->in(__DIR__ . '/examples')
|
||||
->in(__DIR__ . '/src')
|
||||
->in(__DIR__ . '/tests')
|
||||
);
|
||||
@@ -1,33 +0,0 @@
|
||||
<?php
|
||||
|
||||
$PREDIS_HEADER = <<<EOS
|
||||
This file is part of the Predis package.
|
||||
|
||||
(c) Daniele Alessandri <suppakilla@gmail.com>
|
||||
|
||||
For the full copyright and license information, please view the LICENSE
|
||||
file that was distributed with this source code.
|
||||
EOS;
|
||||
|
||||
return PhpCsFixer\Config::create()
|
||||
->setUsingCache(true)
|
||||
->setRules(array(
|
||||
'@Symfony' => true,
|
||||
'header_comment' => array(
|
||||
'header' => $PREDIS_HEADER,
|
||||
),
|
||||
'ordered_imports' => true,
|
||||
'phpdoc_order' => true,
|
||||
'binary_operator_spaces' => array(
|
||||
'align_double_arrow' => false,
|
||||
'align_equals' => false,
|
||||
),
|
||||
'array_syntax' => array('syntax' => 'long'),
|
||||
))
|
||||
->setFinder(
|
||||
PhpCsFixer\Finder::create()
|
||||
->in(__DIR__.'/bin')
|
||||
->in(__DIR__.'/src')
|
||||
->in(__DIR__.'/tests')
|
||||
->in(__DIR__.'/examples')
|
||||
);
|
||||
+81
-5
@@ -1,5 +1,81 @@
|
||||
## Changelog
|
||||
|
||||
## v2.1.2 (2023-03-02)
|
||||
|
||||
## Added
|
||||
- Added stream commands to `KeyPrefixProcessor` (#1051)
|
||||
- Added `ReplicationStrategy::$loadBalancing` option to disable replica reads (#1168)
|
||||
- Added support for `FCALL` and `FUNCTIONS` commands (#1049)
|
||||
- Added support for `PEXPIRETIME` command (#1031)
|
||||
- Added support for `EXPIRETIME` command (#1029)
|
||||
- Added support for `EVAL_RO` command (#1032)
|
||||
- Added support for `LCS` command (#1035)
|
||||
- Added support for `SORT_RO` command (#1044)
|
||||
- Added support for `SINTERCARD` command (#1027)
|
||||
- Added support for `EVALSHA_RO` command (#1034)
|
||||
- Added support for new arguments for `BITPOS` and `BITCOUNT` commands (#1045)
|
||||
- Added support for new arguments for `EXPIRE` and `EXPIREAT` commands (#1046)
|
||||
|
||||
## Bug Fixes
|
||||
- Fixed deprecated function call syntax
|
||||
|
||||
## Deprecated
|
||||
- Further deprecated phpiredis and webdis integration (#1179)
|
||||
|
||||
## Maintenance
|
||||
- Applied coding standards
|
||||
- Pass PHPStan level 2
|
||||
|
||||
## v2.1.1 (2023-01-17)
|
||||
|
||||
## Bug Fixes
|
||||
- Fix `@template` in `Predis\Client` (#1017)
|
||||
- Fix support options array in `ZINTERSTORE` and `ZUNIONSTORE` (#1018)
|
||||
|
||||
## Deprecated
|
||||
- Deprecated phpiredis and webdis connections
|
||||
|
||||
## v2.1.0 (2023-01-16)
|
||||
|
||||
## New Features
|
||||
- Implemented `GETEX` command (#872)
|
||||
- Implemented `GETDEL` command (#869)
|
||||
- Implemented `COPY` command (#866)
|
||||
- Implemented `FAILOVER` command (#875)
|
||||
- Implemented `LMOVE` command (#863)
|
||||
- Implemented `LMPOP` command (#1013)
|
||||
- Implemented `HRANDFIELD` command (#870)
|
||||
- Implemented `SMISMEMBER` command (#871)
|
||||
- Implemented `ZMPOP` command (#831)
|
||||
- Implemented `BLMOVE` command (#865)
|
||||
- Implemented `BLMPOP` command (#1015)
|
||||
- Implemented `BZMPOP` command (#833)
|
||||
- Implemented `BZPOPMIN` command (#862)
|
||||
- Implemented `BZPOPMAX` command (#864)
|
||||
- Implemented `ZUNION` command (#860)
|
||||
- Implemented `ZINTER` command (#859)
|
||||
- Implemented `ZINTERCARD` command (#861)
|
||||
- Implemented `ZRANGESTORE` command (#829)
|
||||
- Implemented `ZDIFFSTORE` command (#828)
|
||||
- Implemented `ZDIFF` command (#826)
|
||||
- Implemented `ZRANDMEMBER` command (#825)
|
||||
- Implemented `ZMSCORE` (#823)
|
||||
- Implemented `GEOSEARCH` command (#867)
|
||||
- Implemented `GEOSEARCHSTORE` command (#873)
|
||||
|
||||
## Bug Fixes
|
||||
- Added annotations to suppress PHP 8.1 return type deprecation warning (#810)
|
||||
|
||||
## Maintenance
|
||||
- Added mixin annotations for traits (#835)
|
||||
|
||||
## v2.0.3 (2022-10-11)
|
||||
|
||||
- Improved PHP 8.2 support
|
||||
- Call `is_resource()` before reading/writing
|
||||
- Added partial support for Redis Stream commands
|
||||
- Fixed Sentinel authentication issue
|
||||
|
||||
## v2.0.2 (2022-09-06)
|
||||
|
||||
- Fixed PHP 8.2 deprecation notice: Use of "static" in callables
|
||||
@@ -21,7 +97,7 @@
|
||||
- `cluster`: string value (`predis`, `redis`), callable returning an aggregate
|
||||
connection.
|
||||
- `replication`: string value (`predis`, `sentinel`), callable returning an
|
||||
aggregate connection.
|
||||
aggregate connection.
|
||||
- `commands`: command factory, named array mapping command IDs to PHP classes,
|
||||
callable returning a command factory or a named array.
|
||||
- `connections`: connection factory, callable object returning a connection
|
||||
@@ -34,7 +110,7 @@
|
||||
acting as initializer instead of an aggregate connection instance.
|
||||
|
||||
- The `connections` client option now accepts certain string values identifying
|
||||
certain combinations of configurations for the connection factory. Currenlty
|
||||
certain combinations of configurations for the connection factory. Currently
|
||||
this is used to provide a short way to configure Predis to load our phpiredis
|
||||
based connection backends simply, accepted values are:
|
||||
|
||||
@@ -59,7 +135,7 @@
|
||||
supported by the redis-sentinel backend due to its dynamic nature (connections
|
||||
are retrieved and initialized at runtime from sentinels) but it is possible to
|
||||
get a single connection from the pool by using its ID. It is also possible to
|
||||
retrive a connection by role using the method getConnectionByRole().
|
||||
retrieve a connection by role using the method getConnectionByRole().
|
||||
|
||||
- The concept of connection ID (ip:port pair) and connection alias (the `alias`
|
||||
parameter) in `Predis\Connection\Cluster\PredisCluster` has been separated.
|
||||
@@ -119,7 +195,7 @@
|
||||
|
||||
- Support Pub/Sub and Pipelines when using replication
|
||||
|
||||
- The class `Predis\Transaction\AbortedMultiExecException` now uses the correct
|
||||
- The class `Predis\Transaction\AbortedMultiExecException` now uses the correct
|
||||
default types for the `$code` (integer) parameter.
|
||||
|
||||
- __FIX__: using `strval` in `getScanOptions()` method, part of
|
||||
@@ -127,7 +203,7 @@
|
||||
string value of `$this->match` and not passing `null` to `strlen()` function.
|
||||
|
||||
- __FIX__: the value returned from `getArgument()` in `isReadOperation()` method,
|
||||
part of `Predis\Replication\ReplicationStrategy` class, is checked to not pass
|
||||
part of `Predis\Replication\ReplicationStrategy` class, is checked to not pass
|
||||
`null` to `sha1` function.
|
||||
|
||||
- __FIX__: the value returned from `getArgument()` in `parseResponse()`method,
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
## Filing bug reports ##
|
||||
|
||||
Bugs or feature requests can be posted on the [GitHub issues](http://github.com/predis/predis/issues)
|
||||
section of the project.
|
||||
|
||||
When reporting bugs, in addition to the obvious description of your issue you __must__ always provide
|
||||
some essential information about your environment such as:
|
||||
|
||||
1. version of Predis (check the `VERSION` file or the `Predis\Client::VERSION` constant).
|
||||
2. version of Redis (check `redis_version` returned by [`INFO`](http://redis.io/commands/info)).
|
||||
3. version of PHP.
|
||||
4. name and version of the operating system.
|
||||
5. when possible, a small snippet of code that reproduces the issue.
|
||||
|
||||
__Think about it__: we do not have a crystal ball and cannot predict things or peer into the unknown
|
||||
so please provide as much details as possible to help us isolating issues and fix them.
|
||||
|
||||
__Never__ use GitHub issues to post generic questions about Predis! When you have questions about
|
||||
how Predis works or how it can be used, please just hop me an email and I will get back to you as
|
||||
soon as possible.
|
||||
|
||||
|
||||
## Contributing code ##
|
||||
|
||||
If you want to work on Predis, it is highly recommended that you first run the test suite in order
|
||||
to check that everything is OK and report strange behaviours or bugs. When modifying Predis please
|
||||
make sure that no warnings or notices are emitted by PHP running the interpreter in your development
|
||||
environment with the `error_reporting` variable set to `E_ALL | E_STRICT`.
|
||||
|
||||
The recommended way to contribute to Predis is to fork the project on GitHub, create topic branches
|
||||
on your newly created repository to fix bugs or add new features (possibly with tests covering your
|
||||
modifications) and then open a pull request with a description of the applied changes. Obviously you
|
||||
can use any other Git hosting provider of your preference.
|
||||
|
||||
We always aim for consistency in our code base so you should follow basic coding rules as defined by
|
||||
[PSR-1](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-1-basic-coding-standard.md)
|
||||
and [PSR-2](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md)
|
||||
and stick with the conventions used in Predis to name classes and interfaces. Indentation should be
|
||||
done with 4 spaces and code should be wrapped at 100 columns (please try to stay within this limit
|
||||
even if the above mentioned official coding guidelines set the soft limit to 120 columns).
|
||||
|
||||
Please follow these [commit guidelines](http://git-scm.com/book/ch5-2.html#Commit-Guidelines) when
|
||||
committing your code to Git and always write a meaningful (not necessarily extended) description of
|
||||
your changes before opening pull requests.
|
||||
@@ -4,7 +4,7 @@ ________________________________________________
|
||||
### What is the point of Predis? ###
|
||||
|
||||
The main point of Predis is about offering a highly customizable and extensible client for Redis,
|
||||
that can be easily extended by developers while still being reasonabily fast. With Predis you can
|
||||
that can be easily extended by developers while still being reasonably fast. With Predis you can
|
||||
swap almost any class with your own custom implementation: you can have custom connection classes,
|
||||
new distribution strategies for client-side sharding, or handlers to replace or add Redis commands.
|
||||
All of this can be achieved without messing with the source code of the library and directly in your
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
Copyright (c) 2009-2021 Daniele Alessandri
|
||||
MIT License
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without
|
||||
restriction, including without limitation the rights to use,
|
||||
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following
|
||||
conditions:
|
||||
Copyright (c) 2009-2020 Daniele Alessandri (original work)
|
||||
Copyright (c) 2021-2023 Till Krüss (modified work)
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
# Predis #
|
||||
|
||||
[![Software license][ico-license]](LICENSE)
|
||||
[![Latest stable][ico-version-stable]][link-packagist]
|
||||
[![Latest development][ico-version-dev]][link-packagist]
|
||||
[![Latest stable][ico-version-stable]][link-releases]
|
||||
[![Latest development][ico-version-dev]][link-releases]
|
||||
[![Monthly installs][ico-downloads-monthly]][link-downloads]
|
||||
[![Build status][ico-build]][link-actions]
|
||||
[![Coverage Status][ico-coverage]][link-coverage]
|
||||
|
||||
A flexible and feature-complete [Redis](http://redis.io) client for PHP 7.2 and newer.
|
||||
|
||||
@@ -24,7 +25,6 @@ More details about this project can be found on the [frequently asked questions]
|
||||
- Abstraction for `SCAN`, `SSCAN`, `ZSCAN` and `HSCAN` (Redis >= 2.8) based on PHP iterators.
|
||||
- Connections are established lazily by the client upon the first command and can be persisted.
|
||||
- Connections can be established via TCP/IP (also TLS/SSL-encrypted) or UNIX domain sockets.
|
||||
- Support for [Webdis](http://webd.is) (requires both `ext-curl` and `ext-phpiredis`).
|
||||
- Support for custom connection classes for providing different network or protocol backends.
|
||||
- Flexible system for defining custom commands and override the default ones.
|
||||
|
||||
@@ -396,31 +396,6 @@ $response = $client->lpushrand('random_values', $seed = mt_rand());
|
||||
|
||||
### Customizable connection backends ###
|
||||
|
||||
Predis can use different connection backends to connect to Redis. Two of them leverage a third party
|
||||
extension such as [phpiredis](https://github.com/nrk/phpiredis) resulting in major performance gains
|
||||
especially when dealing with big multibulk responses. While one is based on PHP streams, the other
|
||||
is based on socket resources provided by `ext-socket`. Both support TCP/IP and UNIX domain sockets:
|
||||
|
||||
```php
|
||||
$client = new Predis\Client('tcp://127.0.0.1', [
|
||||
'connections' => [
|
||||
'tcp' => 'Predis\Connection\PhpiredisStreamConnection', // PHP stream resources
|
||||
'unix' => 'Predis\Connection\PhpiredisSocketConnection', // ext-socket resources
|
||||
],
|
||||
]);
|
||||
```
|
||||
|
||||
The client can also be configured to rely on a [phpiredis](https://github.com/nrk/phpiredis)-backend
|
||||
by specifying a descriptive string for the `connections` client option. Supported string values are:
|
||||
|
||||
- `phpiredis-stream` maps `tcp`, `redis` and `unix` to `Predis\Connection\PhpiredisStreamConnection`
|
||||
- `phpiredis-socket` maps `tcp`, `redis` and `unix` to `Predis\Connection\PhpiredisSocketConnection`
|
||||
- `phpiredis` is simply an alias of `phpiredis-stream`
|
||||
|
||||
```php
|
||||
$client = new Predis\Client('tcp://127.0.0.1', ['connections' => 'phpiredis']);
|
||||
```
|
||||
|
||||
Developers can create their own connection classes to support whole new network backends, extend
|
||||
existing classes or provide completely different implementations. Connection classes must implement
|
||||
`Predis\Connection\NodeConnectionInterface` or extend `Predis\Connection\AbstractConnection`:
|
||||
@@ -447,9 +422,7 @@ implementation of the standard connection classes available in the `Predis\Conne
|
||||
### Reporting bugs and contributing code ###
|
||||
|
||||
Contributions to Predis are highly appreciated either in the form of pull requests for new features,
|
||||
bug fixes, or just bug reports. We only ask you to adhere to a [basic set of rules](CONTRIBUTING.md)
|
||||
before submitting your changes or filing bugs on the issue tracker to make it easier for everyone to
|
||||
stay consistent while working on the project.
|
||||
bug fixes, or just bug reports. We only ask you to adhere to issue and pull request templates.
|
||||
|
||||
|
||||
### Test suite ###
|
||||
@@ -479,8 +452,8 @@ found [on its actions page](https://github.com/predis/predis/actions).
|
||||
|
||||
### Author ###
|
||||
|
||||
- [Daniele Alessandri](mailto:suppakilla@gmail.com) ([twitter](http://twitter.com/JoL1hAHN))
|
||||
- [Till Krüss](https://till.im) ([Twitter](http://twitter.com/tillkruss))
|
||||
- [Daniele Alessandri](mailto:suppakilla@gmail.com) ([twitter](http://twitter.com/JoL1hAHN))
|
||||
|
||||
|
||||
### License ###
|
||||
@@ -488,11 +461,13 @@ found [on its actions page](https://github.com/predis/predis/actions).
|
||||
The code for Predis is distributed under the terms of the MIT license (see [LICENSE](LICENSE)).
|
||||
|
||||
[ico-license]: https://img.shields.io/github/license/predis/predis.svg?style=flat-square
|
||||
[ico-version-stable]: https://img.shields.io/packagist/v/predis/predis.svg?style=flat-square
|
||||
[ico-version-dev]: https://img.shields.io/packagist/vpre/predis/predis.svg?style=flat-square
|
||||
[ico-version-stable]: https://img.shields.io/github/v/tag/predis/predis?label=stable&style=flat-square
|
||||
[ico-version-dev]: https://img.shields.io/github/v/tag/predis/predis?include_prereleases&label=pre-release&style=flat-square
|
||||
[ico-downloads-monthly]: https://img.shields.io/packagist/dm/predis/predis.svg?style=flat-square
|
||||
[ico-build]: https://img.shields.io/github/workflow/status/predis/predis/Tests/main?style=flat-square
|
||||
[ico-build]: https://img.shields.io/github/actions/workflow/status/predis/predis/tests.yml?branch=main&style=flat-square
|
||||
[ico-coverage]: https://img.shields.io/coverallsCoverage/github/predis/predis?style=flat-square
|
||||
|
||||
[link-packagist]: https://packagist.org/packages/predis/predis
|
||||
[link-releases]: https://github.com/predis/predis/releases
|
||||
[link-actions]: https://github.com/predis/predis/actions
|
||||
[link-downloads]: https://packagist.org/packages/predis/predis/stats
|
||||
[link-coverage]: https://coveralls.io/github/predis/predis
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
@@ -4,8 +4,6 @@
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
@@ -119,7 +117,7 @@ class CommandTestCaseGenerator
|
||||
protected function getTestRealm()
|
||||
{
|
||||
if (empty($this->options['realm'])) {
|
||||
throw new RuntimeException('Invalid value for realm has been sepcified (empty).');
|
||||
throw new RuntimeException('Invalid value for realm has been specified (empty).');
|
||||
}
|
||||
|
||||
return $this->options['realm'];
|
||||
@@ -170,8 +168,6 @@ class CommandTestCaseGenerator
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
+12
-14
@@ -9,12 +9,6 @@
|
||||
"issues": "https://github.com/predis/predis/issues"
|
||||
},
|
||||
"authors": [
|
||||
{
|
||||
"name": "Daniele Alessandri",
|
||||
"email": "suppakilla@gmail.com",
|
||||
"homepage": "http://clorophilla.net",
|
||||
"role": "Creator & Maintainer"
|
||||
},
|
||||
{
|
||||
"name": "Till Krüss",
|
||||
"homepage": "https://till.im",
|
||||
@@ -31,20 +25,24 @@
|
||||
"php": "^7.2 || ^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"friendsofphp/php-cs-fixer": "^3.3",
|
||||
"phpstan/phpstan": "^1.9",
|
||||
"phpunit/phpunit": "^8.0 || ~9.4.4"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-phpiredis": "Allows faster serialization and deserialization of the Redis protocol",
|
||||
"ext-curl": "Allows access to Webdis when paired with phpiredis"
|
||||
"scripts": {
|
||||
"phpstan": "phpstan analyse",
|
||||
"style": "php-cs-fixer fix --diff --dry-run",
|
||||
"style:fix": "php-cs-fixer fix"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Predis\\": "src/"
|
||||
}
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "2.0-dev"
|
||||
}
|
||||
}
|
||||
"config": {
|
||||
"sort-packages": true,
|
||||
"preferred-install": "dist"
|
||||
},
|
||||
"minimum-stability": "dev",
|
||||
"prefer-stable": true
|
||||
}
|
||||
|
||||
@@ -3,13 +3,14 @@
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2023 Till Krüss
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
require __DIR__.'/shared.php';
|
||||
require __DIR__ . '/shared.php';
|
||||
|
||||
// Developers can implement Predis\Distribution\DistributorInterface to create
|
||||
// their own distributors used by the client to distribute keys among a cluster
|
||||
@@ -27,7 +28,7 @@ class NaiveDistributor implements DistributorInterface, HashGeneratorInterface
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->nodes = array();
|
||||
$this->nodes = [];
|
||||
$this->nodesCount = 0;
|
||||
}
|
||||
|
||||
@@ -53,7 +54,7 @@ class NaiveDistributor implements DistributorInterface, HashGeneratorInterface
|
||||
|
||||
public function getBySlot($slot)
|
||||
{
|
||||
return isset($this->nodes[$slot]) ? $this->nodes[$slot] : null;
|
||||
return $this->nodes[$slot] ?? null;
|
||||
}
|
||||
|
||||
public function getByHash($hash)
|
||||
@@ -87,7 +88,7 @@ class NaiveDistributor implements DistributorInterface, HashGeneratorInterface
|
||||
}
|
||||
}
|
||||
|
||||
$options = array(
|
||||
$options = [
|
||||
'cluster' => function () {
|
||||
$distributor = new NaiveDistributor();
|
||||
$strategy = new PredisStrategy($distributor);
|
||||
@@ -95,7 +96,7 @@ $options = array(
|
||||
|
||||
return $cluster;
|
||||
},
|
||||
);
|
||||
];
|
||||
|
||||
$client = new Predis\Client($multiple_servers, $options);
|
||||
|
||||
|
||||
@@ -3,17 +3,18 @@
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2023 Till Krüss
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
require __DIR__.'/shared.php';
|
||||
require __DIR__ . '/shared.php';
|
||||
|
||||
// This is an example of how you can easily extend an existing connection class
|
||||
// and trace the execution of commands for debugging purposes. This can be quite
|
||||
// useful as a starting poing to understand how your application interacts with
|
||||
// useful as a starting point to understand how your application interacts with
|
||||
// Redis.
|
||||
|
||||
use Predis\Command\CommandInterface;
|
||||
@@ -22,7 +23,7 @@ use Predis\Connection\StreamConnection;
|
||||
class SimpleDebuggableConnection extends StreamConnection
|
||||
{
|
||||
private $tstart = 0;
|
||||
private $debugBuffer = array();
|
||||
private $debugBuffer = [];
|
||||
|
||||
public function connect()
|
||||
{
|
||||
@@ -65,11 +66,11 @@ class SimpleDebuggableConnection extends StreamConnection
|
||||
}
|
||||
}
|
||||
|
||||
$options = array(
|
||||
'connections' => array(
|
||||
$options = [
|
||||
'connections' => [
|
||||
'tcp' => 'SimpleDebuggableConnection',
|
||||
),
|
||||
);
|
||||
],
|
||||
];
|
||||
|
||||
$client = new Predis\Client($single_server, $options);
|
||||
$client->set('foo', 'bar');
|
||||
@@ -80,13 +81,13 @@ var_export($client->getConnection()->getDebugBuffer());
|
||||
|
||||
/* OUTPUT:
|
||||
array (
|
||||
0 => 'SELECT 15 -> 127.0.0.1:6379 [0.0008s]',
|
||||
1 => 'SELECT 15 <- 127.0.0.1:6379 [0.001s]',
|
||||
2 => 'SET foo -> 127.0.0.1:6379 [0.001s]',
|
||||
3 => 'SET foo <- 127.0.0.1:6379 [0.0011s]',
|
||||
4 => 'GET foo -> 127.0.0.1:6379 [0.0013s]',
|
||||
5 => 'GET foo <- 127.0.0.1:6379 [0.0015s]',
|
||||
6 => 'INFO -> 127.0.0.1:6379 [0.0019s]',
|
||||
7 => 'INFO <- 127.0.0.1:6379 [0.0022s]',
|
||||
0 => 'SELECT 15 -> 127.0.0.1:6379 [0.0008s]',
|
||||
1 => 'SELECT 15 <- 127.0.0.1:6379 [0.001s]',
|
||||
2 => 'SET foo -> 127.0.0.1:6379 [0.001s]',
|
||||
3 => 'SET foo <- 127.0.0.1:6379 [0.0011s]',
|
||||
4 => 'GET foo -> 127.0.0.1:6379 [0.0013s]',
|
||||
5 => 'GET foo <- 127.0.0.1:6379 [0.0015s]',
|
||||
6 => 'INFO -> 127.0.0.1:6379 [0.0019s]',
|
||||
7 => 'INFO <- 127.0.0.1:6379 [0.0022s]',
|
||||
)
|
||||
*/
|
||||
|
||||
@@ -3,13 +3,14 @@
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2023 Till Krüss
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
require __DIR__.'/shared.php';
|
||||
require __DIR__ . '/shared.php';
|
||||
|
||||
// This is a basic example on how to use the Predis\DispatcherLoop class.
|
||||
//
|
||||
@@ -23,7 +24,7 @@ require __DIR__.'/shared.php';
|
||||
// PUBLISH control terminate_dispatcher
|
||||
|
||||
// Create a client and disable r/w timeout on the socket
|
||||
$client = new Predis\Client($single_server + array('read_write_timeout' => 0));
|
||||
$client = new Predis\Client($single_server + ['read_write_timeout' => 0]);
|
||||
|
||||
// Return an initialized PubSub consumer instance from the client.
|
||||
$pubsub = $client->pubSubLoop();
|
||||
@@ -38,7 +39,7 @@ class EventsListener implements Countable
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->events = array();
|
||||
$this->events = [];
|
||||
}
|
||||
|
||||
public function count()
|
||||
@@ -58,7 +59,7 @@ class EventsListener implements Countable
|
||||
}
|
||||
|
||||
// Attach our callable class to the dispatcher.
|
||||
$dispatcher->attachCallback('events', ($events = new EventsListener()));
|
||||
$dispatcher->attachCallback('events', $events = new EventsListener());
|
||||
|
||||
// Attach a function to control the dispatcher loop termination with a message.
|
||||
$dispatcher->attachCallback('control', function ($payload, $dispatcher) {
|
||||
|
||||
@@ -3,13 +3,14 @@
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2023 Till Krüss
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
require __DIR__.'/shared.php';
|
||||
require __DIR__ . '/shared.php';
|
||||
|
||||
$client = new Predis\Client($single_server);
|
||||
|
||||
@@ -17,41 +18,46 @@ $client = new Predis\Client($single_server);
|
||||
$client->set('library', 'predis');
|
||||
$response = $client->get('library');
|
||||
|
||||
var_export($response); echo PHP_EOL;
|
||||
var_export($response);
|
||||
echo PHP_EOL;
|
||||
/* OUTPUT: 'predis' */
|
||||
|
||||
// Redis has the MSET and MGET commands to set or get multiple keys in one go,
|
||||
// cases like this Predis accepts arguments for variadic commands both as a list
|
||||
// of arguments or an array containing all of the keys and/or values.
|
||||
$mkv = array(
|
||||
$mkv = [
|
||||
'uid:0001' => '1st user',
|
||||
'uid:0002' => '2nd user',
|
||||
'uid:0003' => '3rd user',
|
||||
);
|
||||
];
|
||||
|
||||
$client->mset($mkv);
|
||||
$response = $client->mget(array_keys($mkv));
|
||||
|
||||
var_export($response); echo PHP_EOL;
|
||||
var_export($response);
|
||||
echo PHP_EOL;
|
||||
/* OUTPUT:
|
||||
array (
|
||||
0 => '1st user',
|
||||
1 => '2nd user',
|
||||
2 => '3rd user',
|
||||
) */
|
||||
0 => '1st user',
|
||||
1 => '2nd user',
|
||||
2 => '3rd user',
|
||||
)
|
||||
*/
|
||||
|
||||
// Predis can also send "raw" commands to Redis. The difference between sending
|
||||
// commands to Redis the usual way and the "raw" way is that in the latter case
|
||||
// their arguments are not filtered nor responses coming from Redis are parsed.
|
||||
|
||||
$response = $client->executeRaw(array(
|
||||
$response = $client->executeRaw([
|
||||
'MGET', 'uid:0001', 'uid:0002', 'uid:0003',
|
||||
));
|
||||
]);
|
||||
|
||||
var_export($response); echo PHP_EOL;
|
||||
var_export($response);
|
||||
echo PHP_EOL;
|
||||
/* OUTPUT:
|
||||
array (
|
||||
0 => '1st user',
|
||||
1 => '2nd user',
|
||||
2 => '3rd user',
|
||||
) */
|
||||
0 => '1st user',
|
||||
1 => '2nd user',
|
||||
2 => '3rd user',
|
||||
)
|
||||
*/
|
||||
|
||||
@@ -3,34 +3,35 @@
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2023 Till Krüss
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
require __DIR__.'/shared.php';
|
||||
require __DIR__ . '/shared.php';
|
||||
|
||||
// Predis can prefix keys found in commands arguments before sending commands to
|
||||
// Redis, even for complex commands such as SORT, ZUNIONSTORE and ZINTERSTORE.
|
||||
// Prefixing keys can be useful to create user-level namespaces for you keyspace
|
||||
// thus reducing the need for separate logical databases in certain scenarios.
|
||||
|
||||
$client = new Predis\Client($single_server, array('prefix' => 'nrk:'));
|
||||
$client = new Predis\Client($single_server, ['prefix' => 'nrk:']);
|
||||
|
||||
$client->mset(array('foo' => 'bar', 'lol' => 'wut'));
|
||||
$client->mset(['foo' => 'bar', 'lol' => 'wut']);
|
||||
var_export($client->mget('foo', 'lol'));
|
||||
/*
|
||||
array (
|
||||
0 => 'bar',
|
||||
1 => 'wut',
|
||||
0 => 'bar',
|
||||
1 => 'wut',
|
||||
)
|
||||
*/
|
||||
|
||||
var_export($client->keys('*'));
|
||||
/*
|
||||
array (
|
||||
0 => 'nrk:foo',
|
||||
1 => 'nrk:lol',
|
||||
0 => 'nrk:foo',
|
||||
1 => 'nrk:lol',
|
||||
)
|
||||
*/
|
||||
|
||||
@@ -3,13 +3,14 @@
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2023 Till Krüss
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
require __DIR__.'/shared.php';
|
||||
require __DIR__ . '/shared.php';
|
||||
|
||||
// This example will not work with versions of Redis < 2.6.
|
||||
//
|
||||
@@ -36,11 +37,11 @@ local cmd, insert = redis.call, table.insert
|
||||
local increment, results = ARGV[1], { }
|
||||
|
||||
for idx, key in ipairs(KEYS) do
|
||||
if cmd('exists', key) == 1 then
|
||||
insert(results, idx, cmd('incrby', key, increment))
|
||||
else
|
||||
insert(results, idx, false)
|
||||
end
|
||||
if cmd('exists', key) == 1 then
|
||||
insert(results, idx, cmd('incrby', key, increment))
|
||||
else
|
||||
insert(results, idx, false)
|
||||
end
|
||||
end
|
||||
|
||||
return results
|
||||
@@ -48,11 +49,11 @@ LUA;
|
||||
}
|
||||
}
|
||||
|
||||
$client = new Predis\Client($single_server, array(
|
||||
'commands' => array(
|
||||
$client = new Predis\Client($single_server, [
|
||||
'commands' => [
|
||||
'increxby' => 'IncrementExistingKeysBy',
|
||||
),
|
||||
));
|
||||
],
|
||||
]);
|
||||
|
||||
$client->mset('foo', 10, 'foobar', 100);
|
||||
|
||||
@@ -60,8 +61,8 @@ var_export($client->increxby('foo', 'foofoo', 'foobar', 50));
|
||||
|
||||
/*
|
||||
array (
|
||||
0 => 60,
|
||||
1 => NULL,
|
||||
2 => 150,
|
||||
0 => 60,
|
||||
1 => NULL,
|
||||
2 => 150,
|
||||
)
|
||||
*/
|
||||
|
||||
@@ -3,13 +3,14 @@
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2023 Till Krüss
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
require __DIR__.'/shared.php';
|
||||
require __DIR__ . '/shared.php';
|
||||
|
||||
// This is a basic example on how to use the Predis\Monitor\Consumer class. You
|
||||
// can use redis-cli to send commands to the same Redis instance your client is
|
||||
@@ -17,7 +18,7 @@ require __DIR__.'/shared.php';
|
||||
// exit the monitor loop and terminate this script in a graceful way.
|
||||
|
||||
// Create a client and disable r/w timeout on the socket.
|
||||
$client = new Predis\Client($single_server + array('read_write_timeout' => 0));
|
||||
$client = new Predis\Client($single_server + ['read_write_timeout' => 0]);
|
||||
|
||||
// Use only one instance of DateTime, we will update the timestamp later.
|
||||
$timestamp = new DateTime();
|
||||
|
||||
@@ -3,13 +3,14 @@
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2023 Till Krüss
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
require __DIR__.'/shared.php';
|
||||
require __DIR__ . '/shared.php';
|
||||
|
||||
// When you have a whole set of consecutive commands to send to a redis server,
|
||||
// you can use a pipeline to dramatically improve performances. Pipelines can
|
||||
@@ -30,16 +31,16 @@ var_export($responses);
|
||||
|
||||
/* OUTPUT:
|
||||
array (
|
||||
0 => Predis\Response\Status::__set_state(array(
|
||||
'payload' => 'OK',
|
||||
)),
|
||||
1 => 10,
|
||||
2 => 40,
|
||||
3 => true,
|
||||
4 => '40',
|
||||
5 => array (
|
||||
0 => NULL,
|
||||
1 => '40',
|
||||
),
|
||||
0 => Predis\Response\Status::__set_state(array(
|
||||
'payload' => 'OK',
|
||||
)),
|
||||
1 => 10,
|
||||
2 => 40,
|
||||
3 => true,
|
||||
4 => '40',
|
||||
5 => array (
|
||||
0 => NULL,
|
||||
1 => '40',
|
||||
),
|
||||
)
|
||||
*/
|
||||
|
||||
@@ -3,19 +3,20 @@
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2023 Till Krüss
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
require __DIR__.'/shared.php';
|
||||
require __DIR__ . '/shared.php';
|
||||
|
||||
// Starting from Redis 2.0 clients can subscribe and listen for events published
|
||||
// on certain channels using a Publish/Subscribe (PUB/SUB) approach.
|
||||
|
||||
// Create a client and disable r/w timeout on the socket
|
||||
$client = new Predis\Client($single_server + array('read_write_timeout' => 0));
|
||||
$client = new Predis\Client($single_server + ['read_write_timeout' => 0]);
|
||||
|
||||
// Initialize a new pubsub consumer.
|
||||
$pubsub = $client->pubSubLoop();
|
||||
@@ -43,7 +44,7 @@ foreach ($pubsub as $message) {
|
||||
}
|
||||
} else {
|
||||
echo "Received the following message from {$message->channel}:",
|
||||
PHP_EOL, " {$message->payload}", PHP_EOL, PHP_EOL;
|
||||
PHP_EOL, " {$message->payload}", PHP_EOL, PHP_EOL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -3,13 +3,14 @@
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2023 Till Krüss
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
require __DIR__.'/shared.php';
|
||||
require __DIR__ . '/shared.php';
|
||||
|
||||
use Predis\Collection\Iterator;
|
||||
|
||||
@@ -47,9 +48,9 @@ foreach (new Iterator\Keyspace($client, 'predis:*') as $key) {
|
||||
|
||||
/* OUTPUT
|
||||
Scan the keyspace matching only our prefixed keys:
|
||||
- predis:zset
|
||||
- predis:set
|
||||
- predis:hash
|
||||
- predis:zset
|
||||
- predis:set
|
||||
- predis:hash
|
||||
*/
|
||||
|
||||
// === Set iterator based on SSCAN ===
|
||||
@@ -60,11 +61,11 @@ foreach (new Iterator\SetKey($client, 'predis:set') as $member) {
|
||||
|
||||
/* OUTPUT
|
||||
Scan members of `predis:set`:
|
||||
- member:1
|
||||
- member:4
|
||||
- member:0
|
||||
- member:3
|
||||
- member:2
|
||||
- member:1
|
||||
- member:4
|
||||
- member:0
|
||||
- member:3
|
||||
- member:2
|
||||
*/
|
||||
|
||||
// === Sorted set iterator based on ZSCAN ===
|
||||
@@ -75,11 +76,11 @@ foreach (new Iterator\SortedSetKey($client, 'predis:zset') as $member => $rank)
|
||||
|
||||
/* OUTPUT
|
||||
Scan members and ranks of `predis:zset`:
|
||||
- member:4 [rank: -4]
|
||||
- member:3 [rank: -3]
|
||||
- member:2 [rank: -2]
|
||||
- member:1 [rank: -1]
|
||||
- member:0 [rank: 0]
|
||||
- member:4 [rank: -4]
|
||||
- member:3 [rank: -3]
|
||||
- member:2 [rank: -2]
|
||||
- member:1 [rank: -1]
|
||||
- member:0 [rank: 0]
|
||||
*/
|
||||
|
||||
// === Hash iterator based on HSCAN ===
|
||||
@@ -90,9 +91,9 @@ foreach (new Iterator\HashKey($client, 'predis:hash') as $field => $value) {
|
||||
|
||||
/* OUTPUT
|
||||
Scan fields and values of `predis:hash`:
|
||||
- field:0 => value:0
|
||||
- field:1 => value:1
|
||||
- field:2 => value:2
|
||||
- field:3 => value:3
|
||||
- field:4 => value:4
|
||||
- field:0 => value:0
|
||||
- field:1 => value:1
|
||||
- field:2 => value:2
|
||||
- field:3 => value:3
|
||||
- field:4 => value:4
|
||||
*/
|
||||
|
||||
@@ -3,13 +3,14 @@
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2023 Till Krüss
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
require __DIR__.'/shared.php';
|
||||
require __DIR__ . '/shared.php';
|
||||
|
||||
// Predis allows to set Lua scripts as read-only operations for replication.
|
||||
// This works for both EVAL and EVALSHA and also for the client-side abstraction
|
||||
@@ -29,7 +30,7 @@ use Predis\Replication\ReplicationStrategy;
|
||||
|
||||
class HashMultipleGetAll extends ScriptCommand
|
||||
{
|
||||
const BODY = <<<LUA
|
||||
public const BODY = <<<LUA
|
||||
local hashes = {}
|
||||
for _, key in pairs(KEYS) do
|
||||
table.insert(hashes, key)
|
||||
@@ -46,15 +47,15 @@ LUA;
|
||||
|
||||
// ------------------------------------------------------------------------- //
|
||||
|
||||
$parameters = array(
|
||||
$parameters = [
|
||||
'tcp://127.0.0.1:6381?role=master&database=15',
|
||||
'tcp://127.0.0.1:6382?role=slave&alias=slave-01&database=15',
|
||||
);
|
||||
];
|
||||
|
||||
$options = array(
|
||||
'commands' => array(
|
||||
$options = [
|
||||
'commands' => [
|
||||
'hmgetall' => 'HashMultipleGetAll',
|
||||
),
|
||||
],
|
||||
'replication' => function () {
|
||||
$strategy = new ReplicationStrategy();
|
||||
$strategy->setScriptReadOnly(HashMultipleGetAll::BODY);
|
||||
@@ -63,7 +64,7 @@ $options = array(
|
||||
|
||||
return $replication;
|
||||
},
|
||||
);
|
||||
];
|
||||
|
||||
// ------------------------------------------------------------------------- //
|
||||
|
||||
|
||||
@@ -3,13 +3,14 @@
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2023 Till Krüss
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
require __DIR__.'/shared.php';
|
||||
require __DIR__ . '/shared.php';
|
||||
|
||||
// Predis supports redis-sentinel to provide high availability in master / slave
|
||||
// scenarios. The only but relevant difference with a basic replication scenario
|
||||
@@ -25,16 +26,16 @@ require __DIR__.'/shared.php';
|
||||
// without an explicit timeout value.
|
||||
//
|
||||
// NOTE: in real-world scenarios sentinels should be running on different hosts!
|
||||
$sentinels = array(
|
||||
$sentinels = [
|
||||
'tcp://127.0.0.1:5380?timeout=0.100',
|
||||
'tcp://127.0.0.1:5381?timeout=0.100',
|
||||
'tcp://127.0.0.1:5382?timeout=0.100',
|
||||
);
|
||||
];
|
||||
|
||||
$client = new Predis\Client($sentinels, array(
|
||||
$client = new Predis\Client($sentinels, [
|
||||
'replication' => 'sentinel',
|
||||
'service' => 'mymaster',
|
||||
));
|
||||
]);
|
||||
|
||||
// Read operation.
|
||||
$exists = $client->exists('foo') ? 'yes' : 'no';
|
||||
|
||||
@@ -3,13 +3,14 @@
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2023 Till Krüss
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
require __DIR__.'/shared.php';
|
||||
require __DIR__ . '/shared.php';
|
||||
|
||||
// Predis supports master / slave replication scenarios where write operations
|
||||
// are performed on the master server and read operations are executed against
|
||||
@@ -21,12 +22,12 @@ require __DIR__.'/shared.php';
|
||||
// slave of the first one (see the "SLAVEOF" command).
|
||||
//
|
||||
|
||||
$parameters = array(
|
||||
$parameters = [
|
||||
'tcp://127.0.0.1:6381?role=master&database=15',
|
||||
'tcp://127.0.0.1:6382?role=slave&database=15',
|
||||
);
|
||||
];
|
||||
|
||||
$options = array('replication' => 'predis');
|
||||
$options = ['replication' => 'predis'];
|
||||
|
||||
$client = new Predis\Client($parameters, $options);
|
||||
|
||||
|
||||
@@ -3,13 +3,14 @@
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2023 Till Krüss
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
require __DIR__.'/shared.php';
|
||||
require __DIR__ . '/shared.php';
|
||||
|
||||
// This example demonstrates how to use Predis to save PHP sessions on Redis.
|
||||
//
|
||||
@@ -25,16 +26,16 @@ require __DIR__.'/shared.php';
|
||||
//
|
||||
|
||||
if (!interface_exists('SessionHandlerInterface')) {
|
||||
die('ATTENTION: the session handler implemented by Predis requires PHP >= 5.4.0 '.
|
||||
exit('ATTENTION: the session handler implemented by Predis requires PHP >= 5.4.0 ' .
|
||||
"or a polyfill for SessionHandlerInterface provided by an external package.\n");
|
||||
}
|
||||
|
||||
// Instantiate a new client just like you would normally do. Using a prefix for
|
||||
// keys will effectively prefix all session keys with the specified string.
|
||||
$client = new Predis\Client($single_server, array('prefix' => 'sessions:'));
|
||||
$client = new Predis\Client($single_server, ['prefix' => 'sessions:']);
|
||||
|
||||
// Set `gc_maxlifetime` to specify a time-to-live of 5 seconds for session keys.
|
||||
$handler = new Predis\Session\Handler($client, array('gc_maxlifetime' => 5));
|
||||
$handler = new Predis\Session\Handler($client, ['gc_maxlifetime' => 5]);
|
||||
|
||||
// Register the session handler.
|
||||
$handler->register();
|
||||
|
||||
+20
-19
@@ -3,17 +3,18 @@
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2023 Till Krüss
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
if (PHP_SAPI !== 'cli') {
|
||||
die("Example scripts are meant to be executed locally via CLI.");
|
||||
exit('Example scripts are meant to be executed locally via CLI.');
|
||||
}
|
||||
|
||||
require __DIR__.'/../autoload.php';
|
||||
require __DIR__ . '/../autoload.php';
|
||||
|
||||
function redis_version($info)
|
||||
{
|
||||
@@ -26,23 +27,23 @@ function redis_version($info)
|
||||
}
|
||||
}
|
||||
|
||||
$single_server = array(
|
||||
$single_server = [
|
||||
'host' => '127.0.0.1',
|
||||
'port' => 6379,
|
||||
'database' => 15,
|
||||
);
|
||||
];
|
||||
|
||||
$multiple_servers = array(
|
||||
array(
|
||||
'host' => '127.0.0.1',
|
||||
'port' => 6379,
|
||||
'database' => 15,
|
||||
'alias' => 'first',
|
||||
),
|
||||
array(
|
||||
'host' => '127.0.0.1',
|
||||
'port' => 6380,
|
||||
'database' => 15,
|
||||
'alias' => 'second',
|
||||
),
|
||||
);
|
||||
$multiple_servers = [
|
||||
[
|
||||
'host' => '127.0.0.1',
|
||||
'port' => 6379,
|
||||
'database' => 15,
|
||||
'alias' => 'first',
|
||||
],
|
||||
[
|
||||
'host' => '127.0.0.1',
|
||||
'port' => 6380,
|
||||
'database' => 15,
|
||||
'alias' => 'second',
|
||||
],
|
||||
];
|
||||
|
||||
@@ -3,13 +3,14 @@
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2023 Till Krüss
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
require __DIR__.'/shared.php';
|
||||
require __DIR__ . '/shared.php';
|
||||
|
||||
// This is an implementation of an atomic client-side ZPOP using the support for
|
||||
// check-and-set (CAS) operations with MULTI/EXEC transactions, as described in
|
||||
@@ -27,15 +28,15 @@ require __DIR__.'/shared.php';
|
||||
function zpop($client, $key)
|
||||
{
|
||||
$element = null;
|
||||
$options = array(
|
||||
$options = [
|
||||
'cas' => true, // Initialize with support for CAS operations
|
||||
'watch' => $key, // Key that needs to be WATCHed to detect changes
|
||||
'retry' => 3, // Number of retries on aborted transactions, after
|
||||
// which the client bails out with an exception.
|
||||
);
|
||||
];
|
||||
|
||||
$client->transaction($options, function ($tx) use ($key, &$element) {
|
||||
@list($element) = $tx->zrange($key, 0, 0);
|
||||
@[$element] = $tx->zrange($key, 0, 0);
|
||||
|
||||
if (isset($element)) {
|
||||
$tx->multi(); // With CAS, MULTI *must* be explicitly invoked.
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
parameters:
|
||||
level: 0
|
||||
|
||||
paths:
|
||||
- tests/
|
||||
|
||||
ignoreErrors:
|
||||
# Uses func_get_args()
|
||||
- message: "#^Static method Predis\\\\Command\\\\RawCommand\\:\\:create\\(\\) invoked with 0 parameters, at least 1 required\\.$#"
|
||||
count: 1
|
||||
path: tests/Predis/Command/RawCommandTest.php
|
||||
# Mockery
|
||||
- message: "#^Call to an undefined method Predis\\\\Configuration\\\\Option\\\\AggregateTest\\:\\:getMockConnectionClass\\(\\)\\.$#"
|
||||
count: 2
|
||||
path: tests/Predis/Configuration/Option/AggregateTest.php
|
||||
@@ -0,0 +1,56 @@
|
||||
parameters:
|
||||
level: 2
|
||||
|
||||
paths:
|
||||
- src/
|
||||
|
||||
ignoreErrors:
|
||||
# Tricky ones
|
||||
- message: "#^Cannot cast Predis\\\\Response\\\\ResponseInterface to string\\.$#"
|
||||
count: 1
|
||||
path: src/Client.php
|
||||
- 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
|
||||
path: src/Client.php
|
||||
- message: "#^Unsafe usage of new static\\(\\)\\.$#"
|
||||
count: 1
|
||||
path: src/Connection/Parameters.php
|
||||
# Using an interface as concrete type
|
||||
- message: "#^Call to an undefined method Predis\\\\Command\\\\FactoryInterface\\:\\:define\\(\\)\\.$#"
|
||||
count: 1
|
||||
path: src/Configuration/Option/Commands.php
|
||||
- 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
|
||||
- message: "#^Variable \\$response might not be defined\\.$#"
|
||||
count: 2
|
||||
path: src/Connection/Cluster/RedisCluster.php
|
||||
- message: "#^Access to an undefined property Predis\\\\Connection\\\\ParametersInterface\\:\\:\\$role\\.$#"
|
||||
count: 1
|
||||
path: src/Connection/Replication/MasterSlaveReplication.php
|
||||
- message: "#^Access to an undefined property Predis\\\\Connection\\\\ParametersInterface\\:\\:\\$role\\.$#"
|
||||
count: 1
|
||||
path: src/Connection/Replication/SentinelReplication.php
|
||||
# try/catch problems
|
||||
- message: "#^Variable \\$connection might not be defined\\.$#"
|
||||
count: 1
|
||||
path: src/Connection/Replication/MasterSlaveReplication.php
|
||||
- message: "#^Variable \\$response might not be defined\\.$#"
|
||||
count: 1
|
||||
path: src/Connection/Replication/MasterSlaveReplication.php
|
||||
- message: "#^Variable \\$response might not be defined\\.$#"
|
||||
count: 1
|
||||
path: src/Connection/Replication/SentinelReplication.php
|
||||
+20
-10
@@ -1,14 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<phpunit bootstrap="tests/bootstrap.php"
|
||||
colors="true"
|
||||
convertErrorsToExceptions="true"
|
||||
convertNoticesToExceptions="true"
|
||||
convertWarningsToExceptions="true"
|
||||
processIsolation="false"
|
||||
stopOnError="false"
|
||||
stopOnFailure="false"
|
||||
beStrictAboutTestsThatDoNotTestAnything="true">
|
||||
<phpunit
|
||||
bootstrap="tests/bootstrap.php"
|
||||
colors="true"
|
||||
convertErrorsToExceptions="true"
|
||||
convertNoticesToExceptions="true"
|
||||
convertWarningsToExceptions="true"
|
||||
processIsolation="false"
|
||||
stopOnError="false"
|
||||
stopOnFailure="false"
|
||||
beStrictAboutTestsThatDoNotTestAnything="true"
|
||||
>
|
||||
|
||||
<testsuites>
|
||||
<testsuite name="Predis Test Suite">
|
||||
@@ -16,6 +17,15 @@
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
|
||||
<coverage processUncoveredFiles="true">
|
||||
<include>
|
||||
<directory suffix=".php">./src</directory>
|
||||
</include>
|
||||
<report>
|
||||
<clover outputFile="build/logs/clover.xml"/>
|
||||
</report>
|
||||
</coverage>
|
||||
|
||||
<groups>
|
||||
<exclude>
|
||||
<group>ext-phpiredis</group>
|
||||
|
||||
+5
-4
@@ -3,7 +3,8 @@
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2023 Till Krüss
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
@@ -30,7 +31,7 @@ class Autoloader
|
||||
public function __construct($baseDirectory = __DIR__)
|
||||
{
|
||||
$this->directory = $baseDirectory;
|
||||
$this->prefix = __NAMESPACE__.'\\';
|
||||
$this->prefix = __NAMESPACE__ . '\\';
|
||||
$this->prefixLength = strlen($this->prefix);
|
||||
}
|
||||
|
||||
@@ -41,7 +42,7 @@ class Autoloader
|
||||
*/
|
||||
public static function register($prepend = false)
|
||||
{
|
||||
spl_autoload_register(array(new self(), 'autoload'), true, $prepend);
|
||||
spl_autoload_register([new self(), 'autoload'], true, $prepend);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -53,7 +54,7 @@ class Autoloader
|
||||
{
|
||||
if (0 === strpos($className, $this->prefix)) {
|
||||
$parts = explode('\\', substr($className, $this->prefixLength));
|
||||
$filepath = $this->directory.DIRECTORY_SEPARATOR.implode(DIRECTORY_SEPARATOR, $parts).'.php';
|
||||
$filepath = $this->directory . DIRECTORY_SEPARATOR . implode(DIRECTORY_SEPARATOR, $parts) . '.php';
|
||||
|
||||
if (is_file($filepath)) {
|
||||
require $filepath;
|
||||
|
||||
+73
-41
@@ -3,7 +3,8 @@
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2023 Till Krüss
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
@@ -11,8 +12,13 @@
|
||||
|
||||
namespace Predis;
|
||||
|
||||
use ArrayIterator;
|
||||
use InvalidArgumentException;
|
||||
use IteratorAggregate;
|
||||
use Predis\Command\CommandInterface;
|
||||
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,6 +32,9 @@ use Predis\Response\ErrorInterface as ErrorResponseInterface;
|
||||
use Predis\Response\ResponseInterface;
|
||||
use Predis\Response\ServerException;
|
||||
use Predis\Transaction\MultiExec as MultiExecTransaction;
|
||||
use ReturnTypeWillChange;
|
||||
use RuntimeException;
|
||||
use Traversable;
|
||||
|
||||
/**
|
||||
* Client class used for connecting and executing commands on Redis.
|
||||
@@ -34,13 +43,11 @@ use Predis\Transaction\MultiExec as MultiExecTransaction;
|
||||
* abstractions are built. Internally it aggregates various other classes each
|
||||
* one with its own responsibility and scope.
|
||||
*
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||
* @template-implements \IteratorAggregate<string, static>
|
||||
*/
|
||||
class Client implements ClientInterface, \IteratorAggregate
|
||||
class Client implements ClientInterface, IteratorAggregate
|
||||
{
|
||||
const VERSION = '2.0.2';
|
||||
public const VERSION = '2.1.2';
|
||||
|
||||
/** @var OptionsInterface */
|
||||
private $options;
|
||||
@@ -57,8 +64,8 @@ class Client implements ClientInterface, \IteratorAggregate
|
||||
*/
|
||||
public function __construct($parameters = null, $options = null)
|
||||
{
|
||||
$this->options = static::createOptions($options ?? new Options);
|
||||
$this->connection = static::createConnection($this->options, $parameters ?? new Parameters);
|
||||
$this->options = static::createOptions($options ?? new Options());
|
||||
$this->connection = static::createConnection($this->options, $parameters ?? new Parameters());
|
||||
$this->commands = $this->options->commands;
|
||||
}
|
||||
|
||||
@@ -67,9 +74,8 @@ class Client implements ClientInterface, \IteratorAggregate
|
||||
*
|
||||
* @param array|OptionsInterface $options Set of client options
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*
|
||||
* @return OptionsInterface
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
protected static function createOptions($options)
|
||||
{
|
||||
@@ -78,7 +84,7 @@ class Client implements ClientInterface, \IteratorAggregate
|
||||
} elseif ($options instanceof OptionsInterface) {
|
||||
return $options;
|
||||
} else {
|
||||
throw new \InvalidArgumentException('Invalid type for client options');
|
||||
throw new InvalidArgumentException('Invalid type for client options');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,9 +109,8 @@ class Client implements ClientInterface, \IteratorAggregate
|
||||
* @param OptionsInterface $options Client options container
|
||||
* @param mixed $parameters Connection parameters
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*
|
||||
* @return ConnectionInterface
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
protected static function createConnection(OptionsInterface $options, $parameters)
|
||||
{
|
||||
@@ -127,7 +132,7 @@ class Client implements ClientInterface, \IteratorAggregate
|
||||
} elseif ($options->defined('aggregate') && $initializer = $options->aggregate) {
|
||||
return $initializer($parameters, false);
|
||||
} else {
|
||||
throw new \InvalidArgumentException(
|
||||
throw new InvalidArgumentException(
|
||||
'Array of connection parameters requires `cluster`, `replication` or `aggregate` client option'
|
||||
);
|
||||
}
|
||||
@@ -137,13 +142,13 @@ class Client implements ClientInterface, \IteratorAggregate
|
||||
$connection = call_user_func($parameters, $options);
|
||||
|
||||
if (!$connection instanceof ConnectionInterface) {
|
||||
throw new \InvalidArgumentException('Callable parameters must return a valid connection');
|
||||
throw new InvalidArgumentException('Callable parameters must return a valid connection');
|
||||
}
|
||||
|
||||
return $connection;
|
||||
}
|
||||
|
||||
throw new \InvalidArgumentException('Invalid type for connection parameters');
|
||||
throw new InvalidArgumentException('Invalid type for connection parameters');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -196,17 +201,17 @@ class Client implements ClientInterface, \IteratorAggregate
|
||||
{
|
||||
$selector = strtolower($selector);
|
||||
|
||||
if (!in_array($selector, array('id', 'key', 'slot', 'role', 'alias', 'command'))) {
|
||||
throw new \InvalidArgumentException("Invalid selector type: `$selector`");
|
||||
if (!in_array($selector, ['id', 'key', 'slot', 'role', 'alias', 'command'])) {
|
||||
throw new InvalidArgumentException("Invalid selector type: `$selector`");
|
||||
}
|
||||
|
||||
if (!method_exists($this->connection, $method = "getConnectionBy$selector")) {
|
||||
$class = get_class($this->connection);
|
||||
throw new \InvalidArgumentException("Selecting connection by $selector is not supported by $class");
|
||||
throw new InvalidArgumentException("Selecting connection by $selector is not supported by $class");
|
||||
}
|
||||
|
||||
if (!$connection = $this->connection->$method($value)) {
|
||||
throw new \InvalidArgumentException("Cannot find a connection by $selector matching `$value`");
|
||||
throw new InvalidArgumentException("Cannot find a connection by $selector matching `$value`");
|
||||
}
|
||||
|
||||
return new static($connection, $this->getOptions());
|
||||
@@ -303,11 +308,39 @@ class Client implements ClientInterface, \IteratorAggregate
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function createCommand($commandID, $arguments = array())
|
||||
public function createCommand($commandID, $arguments = [])
|
||||
{
|
||||
return $this->commands->create($commandID, $arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @return ContainerInterface
|
||||
*/
|
||||
public function __get($name)
|
||||
{
|
||||
return ContainerFactory::create($this, $name);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @param $value
|
||||
* @return mixed
|
||||
*/
|
||||
public function __set($name, $value)
|
||||
{
|
||||
throw new RuntimeException('Not allowed');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @return mixed
|
||||
*/
|
||||
public function __isset($name)
|
||||
{
|
||||
throw new RuntimeException('Not allowed');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
@@ -332,9 +365,8 @@ class Client implements ClientInterface, \IteratorAggregate
|
||||
* @param CommandInterface $command Redis command that generated the error.
|
||||
* @param ErrorResponseInterface $response Instance of the error response.
|
||||
*
|
||||
* @throws ServerException
|
||||
*
|
||||
* @return mixed
|
||||
* @throws ServerException
|
||||
*/
|
||||
protected function onErrorResponse(CommandInterface $command, ErrorResponseInterface $response)
|
||||
{
|
||||
@@ -357,7 +389,7 @@ class Client implements ClientInterface, \IteratorAggregate
|
||||
|
||||
/**
|
||||
* Executes the specified initializer method on `$this` by adjusting the
|
||||
* actual invokation depending on the arity (0, 1 or 2 arguments). This is
|
||||
* actual invocation depending on the arity (0, 1 or 2 arguments). This is
|
||||
* simply an utility method to create Redis contexts instances since they
|
||||
* follow a common initialization path.
|
||||
*
|
||||
@@ -378,26 +410,24 @@ class Client implements ClientInterface, \IteratorAggregate
|
||||
: $this->$initializer(null, $argv[0]);
|
||||
|
||||
case 2:
|
||||
list($arg0, $arg1) = $argv;
|
||||
[$arg0, $arg1] = $argv;
|
||||
|
||||
return $this->$initializer($arg0, $arg1);
|
||||
|
||||
// @codeCoverageIgnoreStart
|
||||
default:
|
||||
return $this->$initializer($this, $argv);
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new pipeline context and returns it, or returns the results of
|
||||
* a pipeline executed inside the optionally provided callable object.
|
||||
*
|
||||
* @param mixed ... Array of options, a callable for execution, or both.
|
||||
* @param mixed ...$arguments Array of options, a callable for execution, or both.
|
||||
*
|
||||
* @return Pipeline|array
|
||||
*/
|
||||
public function pipeline(/* arguments */)
|
||||
public function pipeline(...$arguments)
|
||||
{
|
||||
return $this->sharedContextFactory('createPipeline', func_get_args());
|
||||
}
|
||||
@@ -436,11 +466,11 @@ class Client implements ClientInterface, \IteratorAggregate
|
||||
* Creates a new transaction context and returns it, or returns the results
|
||||
* of a transaction executed inside the optionally provided callable object.
|
||||
*
|
||||
* @param mixed ... Array of options, a callable for execution, or both.
|
||||
* @param mixed ...$arguments Array of options, a callable for execution, or both.
|
||||
*
|
||||
* @return MultiExecTransaction|array
|
||||
*/
|
||||
public function transaction(/* arguments */)
|
||||
public function transaction(...$arguments)
|
||||
{
|
||||
return $this->sharedContextFactory('createTransaction', func_get_args());
|
||||
}
|
||||
@@ -468,11 +498,11 @@ class Client implements ClientInterface, \IteratorAggregate
|
||||
* Creates a new publish/subscribe context and returns it, or starts its loop
|
||||
* inside the optionally provided callable object.
|
||||
*
|
||||
* @param mixed ... Array of options, a callable for execution, or both.
|
||||
* @param mixed ...$arguments Array of options, a callable for execution, or both.
|
||||
*
|
||||
* @return PubSubConsumer|null
|
||||
*/
|
||||
public function pubSubLoop(/* arguments */)
|
||||
public function pubSubLoop(...$arguments)
|
||||
{
|
||||
return $this->sharedContextFactory('createPubSub', func_get_args());
|
||||
}
|
||||
@@ -498,6 +528,8 @@ class Client implements ClientInterface, \IteratorAggregate
|
||||
$pubsub->stop();
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -511,24 +543,24 @@ class Client implements ClientInterface, \IteratorAggregate
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @return Traversable<string, static>
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
#[ReturnTypeWillChange]
|
||||
public function getIterator()
|
||||
{
|
||||
$clients = array();
|
||||
$clients = [];
|
||||
$connection = $this->getConnection();
|
||||
|
||||
if (!$connection instanceof \Traversable) {
|
||||
return new \ArrayIterator(array(
|
||||
(string) $connection => new static($connection, $this->getOptions())
|
||||
));
|
||||
if (!$connection instanceof Traversable) {
|
||||
return new ArrayIterator([
|
||||
(string) $connection => new static($connection, $this->getOptions()),
|
||||
]);
|
||||
}
|
||||
|
||||
foreach ($connection as $node) {
|
||||
$clients[(string) $node] = new static($node, $this->getOptions());
|
||||
}
|
||||
|
||||
return new \ArrayIterator($clients);
|
||||
return new ArrayIterator($clients);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2023 Till Krüss
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
@@ -11,16 +12,23 @@
|
||||
|
||||
namespace Predis;
|
||||
|
||||
use Predis\Command\Argument\Geospatial\ByInterface;
|
||||
use Predis\Command\Argument\Geospatial\FromInterface;
|
||||
use Predis\Command\Argument\Server\LimitOffsetCount;
|
||||
use Predis\Command\Argument\Server\To;
|
||||
use Predis\Command\CommandInterface;
|
||||
use Predis\Command\Redis\Container\FunctionContainer;
|
||||
|
||||
/**
|
||||
* 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 dump($key)
|
||||
* @method $this exists($key)
|
||||
* @method $this expire($key, $seconds)
|
||||
* @method $this expireat($key, $timestamp)
|
||||
* @method $this expire($key, $seconds, string $expireOption = '')
|
||||
* @method $this expireat($key, $timestamp, string $expireOption = '')
|
||||
* @method $this expiretime(string $key)
|
||||
* @method $this keys($pattern)
|
||||
* @method $this move($key, $db)
|
||||
* @method $this object($subcommand, $key)
|
||||
@@ -33,18 +41,27 @@ use Predis\Command\CommandInterface;
|
||||
* @method $this renamenx($key, $target)
|
||||
* @method $this scan($cursor, array $options = null)
|
||||
* @method $this sort($key, array $options = null)
|
||||
* @method $this sort_ro(string $key, ?string $byPattern = null, ?LimitOffsetCount $limit = null, array $getPatterns = [], ?string $sorting = null, bool $alpha = false)
|
||||
* @method $this ttl($key)
|
||||
* @method $this type($key)
|
||||
* @method $this append($key, $value)
|
||||
* @method $this bitcount($key, $start = null, $end = null)
|
||||
* @method $this bitcount($key, $start = null, $end = null, string $index = 'byte')
|
||||
* @method $this bitop($operation, $destkey, $key)
|
||||
* @method $this bitfield($key, $subcommand, ...$subcommandArg)
|
||||
* @method $this bitpos($key, $bit, $start = null, $end = null)
|
||||
* @method $this bitpos($key, $bit, $start = null, $end = null, string $index = 'byte')
|
||||
* @method $this blmpop(int $timeout, array $keys, string $modifier = 'left', int $count = 1)
|
||||
* @method $this bzpopmax(array $keys, int $timeout)
|
||||
* @method $this bzpopmin(array $keys, int $timeout)
|
||||
* @method $this bzmpop(int $timeout, array $keys, string $modifier = 'min', int $count = 1)
|
||||
* @method $this decr($key)
|
||||
* @method $this decrby($key, $decrement)
|
||||
* @method $this failover(?To $to = null, bool $abort = false, int $timeout = -1)
|
||||
* @method $this fcall(string $function, array $keys, ...$args)
|
||||
* @method $this get($key)
|
||||
* @method $this getbit($key, $offset)
|
||||
* @method $this getex(string $key, $modifier = '', $value = false)
|
||||
* @method $this getrange($key, $start, $end)
|
||||
* @method $this getdel(string $key)
|
||||
* @method $this getset($key, $value)
|
||||
* @method $this incr($key)
|
||||
* @method $this incrby($key, $increment)
|
||||
@@ -69,17 +86,22 @@ use Predis\Command\CommandInterface;
|
||||
* @method $this hlen($key)
|
||||
* @method $this hmget($key, array $fields)
|
||||
* @method $this hmset($key, array $dictionary)
|
||||
* @method $this hrandfield(string $key, int $count = 1, bool $withValues = false)
|
||||
* @method $this hscan($key, $cursor, array $options = null)
|
||||
* @method $this hset($key, $field, $value)
|
||||
* @method $this hsetnx($key, $field, $value)
|
||||
* @method $this hvals($key)
|
||||
* @method $this hstrlen($key, $field)
|
||||
* @method $this blmove(string $source, string $destination, string $where, string $to, int $timeout)
|
||||
* @method $this blpop(array|string $keys, $timeout)
|
||||
* @method $this brpop(array|string $keys, $timeout)
|
||||
* @method $this brpoplpush($source, $destination, $timeout)
|
||||
* @method $this lcs(string $key1, string $key2, bool $len = false, bool $idx = false, int $minMatchLen = 0, bool $withMatchLen = false)
|
||||
* @method $this lindex($key, $index)
|
||||
* @method $this linsert($key, $whence, $pivot, $value)
|
||||
* @method $this llen($key)
|
||||
* @method $this lmove(string $source, string $destination, string $where, string $to)
|
||||
* @method $this lmpop(array $keys, string $modifier = 'left', int $count = 1)
|
||||
* @method $this lpop($key)
|
||||
* @method $this lpush($key, array $values)
|
||||
* @method $this lpushx($key, array $values)
|
||||
@@ -96,9 +118,11 @@ use Predis\Command\CommandInterface;
|
||||
* @method $this sdiff(array|string $keys)
|
||||
* @method $this sdiffstore($destination, array|string $keys)
|
||||
* @method $this sinter(array|string $keys)
|
||||
* @method $this sintercard(array $keys, int $limit = 0)
|
||||
* @method $this sinterstore($destination, array|string $keys)
|
||||
* @method $this sismember($key, $member)
|
||||
* @method $this smembers($key)
|
||||
* @method $this smismember(string $key, string ...$members)
|
||||
* @method $this smove($source, $destination, $member)
|
||||
* @method $this spop($key, $count = null)
|
||||
* @method $this srandmember($key, $count = null)
|
||||
@@ -109,10 +133,18 @@ use Predis\Command\CommandInterface;
|
||||
* @method $this zadd($key, array $membersAndScoresDictionary)
|
||||
* @method $this zcard($key)
|
||||
* @method $this zcount($key, $min, $max)
|
||||
* @method $this zdiff(array $keys, bool $withScores = false)
|
||||
* @method $this zdiffstore(string $destination, array $keys)
|
||||
* @method $this zincrby($key, $increment, $member)
|
||||
* @method $this zinterstore($destination, array|string $keys, array $options = null)
|
||||
* @method $this zintercard(array $keys, int $limit = 0)
|
||||
* @method $this zinterstore(string $destination, array $keys, int[] $weights = [], string $aggregate = 'sum')
|
||||
* @method $this zinter(array $keys, int[] $weights = [], string $aggregate = 'sum', bool $withScores = false)
|
||||
* @method $this zmpop(array $keys, string $modifier = 'min', int $count = 1)
|
||||
* @method $this zmscore(string $key, string ...$member)
|
||||
* @method $this zrandmember(string $key, int $count = 1, bool $withScores = false)
|
||||
* @method $this zrange($key, $start, $stop, array $options = null)
|
||||
* @method $this zrangebyscore($key, $min, $max, array $options = null)
|
||||
* @method $this zrangestore(string $destination, string $source, int|string $min, string|int $max, string|bool $by = false, bool $reversed = false, bool $limit = false, int $offset = 0, int $count = 0)
|
||||
* @method $this zrank($key, $member)
|
||||
* @method $this zrem($key, $member)
|
||||
* @method $this zremrangebyrank($key, $start, $stop)
|
||||
@@ -120,13 +152,15 @@ use Predis\Command\CommandInterface;
|
||||
* @method $this zrevrange($key, $start, $stop, array $options = null)
|
||||
* @method $this zrevrangebyscore($key, $max, $min, array $options = null)
|
||||
* @method $this zrevrank($key, $member)
|
||||
* @method $this zunionstore($destination, array|string $keys, array $options = null)
|
||||
* @method $this zunion(array $keys, int[] $weights = [], string $aggregate = 'sum', bool $withScores = false)
|
||||
* @method $this zunionstore(string $destination, array $keys, int[] $weights = [], string $aggregate = 'sum')
|
||||
* @method $this zscore($key, $member)
|
||||
* @method $this zscan($key, $cursor, array $options = null)
|
||||
* @method $this zrangebylex($key, $start, $stop, array $options = null)
|
||||
* @method $this zrevrangebylex($key, $start, $stop, array $options = null)
|
||||
* @method $this zremrangebylex($key, $min, $max)
|
||||
* @method $this zlexcount($key, $min, $max)
|
||||
* @method $this pexpiretime(string $key)
|
||||
* @method $this pfadd($key, array $elements)
|
||||
* @method $this pfmerge($destinationKey, array|string $sourceKeys)
|
||||
* @method $this pfcount(array|string $keys)
|
||||
@@ -138,7 +172,9 @@ use Predis\Command\CommandInterface;
|
||||
* @method $this unwatch()
|
||||
* @method $this watch($key)
|
||||
* @method $this eval($script, $numkeys, $keyOrArg1 = null, $keyOrArgN = null)
|
||||
* @method $this eval_ro(string $script, array $keys, ...$argument)
|
||||
* @method $this evalsha($script, $numkeys, $keyOrArg1 = null, $keyOrArgN = null)
|
||||
* @method $this evalsha_ro(string $sha1, array $keys, ...$argument)
|
||||
* @method $this script($subcommand, $argument = null)
|
||||
* @method $this auth($password)
|
||||
* @method $this echo($message)
|
||||
@@ -164,8 +200,11 @@ use Predis\Command\CommandInterface;
|
||||
* @method $this geodist($key, $member1, $member2, $unit = null)
|
||||
* @method $this georadius($key, $longitude, $latitude, $radius, $unit, array $options = null)
|
||||
* @method $this georadiusbymember($key, $member, $radius, $unit, array $options = null)
|
||||
* @method $this geosearch(string $key, FromInterface $from, ByInterface $by, ?string $sorting = null, int $count = -1, bool $any = false, bool $withCoord = false, bool $withDist = false, bool $withHash = false)
|
||||
* @method $this geosearchstore(string $destination, string $source, FromInterface $from, ByInterface $by, ?string $sorting = null, int $count = -1, bool $any = false, bool $storeDist = false)
|
||||
*
|
||||
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||
* Container commands
|
||||
* @property FunctionContainer $function
|
||||
*/
|
||||
interface ClientContextInterface
|
||||
{
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2023 Till Krüss
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
@@ -13,8 +14,6 @@ namespace Predis;
|
||||
|
||||
/**
|
||||
* Exception class that identifies client-side errors.
|
||||
*
|
||||
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||
*/
|
||||
class ClientException extends PredisException
|
||||
{
|
||||
|
||||
+54
-9
@@ -3,7 +3,8 @@
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2023 Till Krüss
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
@@ -11,8 +12,13 @@
|
||||
|
||||
namespace Predis;
|
||||
|
||||
use Predis\Command\Argument\Geospatial\ByInterface;
|
||||
use Predis\Command\Argument\Geospatial\FromInterface;
|
||||
use Predis\Command\Argument\Server\LimitOffsetCount;
|
||||
use Predis\Command\Argument\Server\To;
|
||||
use Predis\Command\CommandInterface;
|
||||
use Predis\Command\FactoryInterface;
|
||||
use Predis\Command\Redis\Container\FunctionContainer;
|
||||
use Predis\Configuration\OptionsInterface;
|
||||
use Predis\Connection\ConnectionInterface;
|
||||
use Predis\Response\Status;
|
||||
@@ -25,11 +31,13 @@ use Predis\Response\Status;
|
||||
* and more friendly interface to ease programming which is described in the
|
||||
* following list of methods:
|
||||
*
|
||||
* @method int copy(string $source, string $destination, int $db = -1, bool $replace = false)
|
||||
* @method int del(string[]|string $keyOrKeys, string ...$keys = null)
|
||||
* @method string|null dump(string $key)
|
||||
* @method int exists(string $key)
|
||||
* @method int expire(string $key, int $seconds)
|
||||
* @method int expireat(string $key, int $timestamp)
|
||||
* @method int expire(string $key, int $seconds, string $expireOption = '')
|
||||
* @method int expireat(string $key, int $timestamp, string $expireOption = '')
|
||||
* @method int expiretime(string $key)
|
||||
* @method array keys(string $pattern)
|
||||
* @method int move(string $key, int $db)
|
||||
* @method mixed object($subcommand, string $key)
|
||||
@@ -42,18 +50,27 @@ use Predis\Response\Status;
|
||||
* @method int renamenx(string $key, string $target)
|
||||
* @method array scan($cursor, array $options = null)
|
||||
* @method array sort(string $key, array $options = null)
|
||||
* @method array sort_ro(string $key, ?string $byPattern = null, ?LimitOffsetCount $limit = null, array $getPatterns = [], ?string $sorting = null, bool $alpha = false)
|
||||
* @method int ttl(string $key)
|
||||
* @method mixed type(string $key)
|
||||
* @method int append(string $key, $value)
|
||||
* @method int bitcount(string $key, $start = null, $end = null)
|
||||
* @method int bitcount(string $key, $start = null, $end = null, string $index = 'byte')
|
||||
* @method int bitop($operation, $destkey, $key)
|
||||
* @method array|null bitfield(string $key, $subcommand, ...$subcommandArg)
|
||||
* @method int bitpos(string $key, $bit, $start = null, $end = null)
|
||||
* @method int bitpos(string $key, $bit, $start = null, $end = null, string $index = 'byte')
|
||||
* @method array blmpop(int $timeout, array $keys, string $modifier = 'left', int $count = 1)
|
||||
* @method array bzpopmax(array $keys, int $timeout)
|
||||
* @method array bzpopmin(array $keys, int $timeout)
|
||||
* @method array bzmpop(int $timeout, array $keys, string $modifier = 'min', int $count = 1)
|
||||
* @method int decr(string $key)
|
||||
* @method int decrby(string $key, int $decrement)
|
||||
* @method Status failover(?To $to = null, bool $abort = false, int $timeout = -1)
|
||||
* @method mixed fcall(string $function, array $keys, ...$args)
|
||||
* @method string|null get(string $key)
|
||||
* @method int getbit(string $key, $offset)
|
||||
* @method int|null getex(string $key, $modifier = '', $value = false)
|
||||
* @method string getrange(string $key, $start, $end)
|
||||
* @method string getdel(string $key)
|
||||
* @method string|null getset(string $key, $value)
|
||||
* @method int incr(string $key)
|
||||
* @method int incrby(string $key, int $increment)
|
||||
@@ -78,17 +95,22 @@ use Predis\Response\Status;
|
||||
* @method int hlen(string $key)
|
||||
* @method array hmget(string $key, array $fields)
|
||||
* @method mixed hmset(string $key, array $dictionary)
|
||||
* @method array hrandfield(string $key, int $count = 1, bool $withValues = false)
|
||||
* @method array hscan(string $key, $cursor, array $options = null)
|
||||
* @method int hset(string $key, string $field, string $value)
|
||||
* @method int hsetnx(string $key, string $field, string $value)
|
||||
* @method array hvals(string $key)
|
||||
* @method int hstrlen(string $key, string $field)
|
||||
* @method string blmove(string $source, string $destination, string $where, string $to, int $timeout)
|
||||
* @method array|null blpop(array|string $keys, int|float $timeout)
|
||||
* @method array|null brpop(array|string $keys, int|float $timeout)
|
||||
* @method string|null brpoplpush(string $source, string $destination, int|float $timeout)
|
||||
* @method mixed lcs(string $key1, string $key2, bool $len = false, bool $idx = false, int $minMatchLen = 0, bool $withMatchLen = false)
|
||||
* @method string|null lindex(string $key, int $index)
|
||||
* @method int linsert(string $key, $whence, $pivot, $value)
|
||||
* @method int llen(string $key)
|
||||
* @method string lmove(string $source, string $destination, string $where, string $to)
|
||||
* @method array|null lmpop(array $keys, string $modifier = 'left', int $count = 1)
|
||||
* @method string|null lpop(string $key)
|
||||
* @method int lpush(string $key, array $values)
|
||||
* @method int lpushx(string $key, array $values)
|
||||
@@ -105,9 +127,11 @@ use Predis\Response\Status;
|
||||
* @method string[] sdiff(array|string $keys)
|
||||
* @method int sdiffstore(string $destination, array|string $keys)
|
||||
* @method string[] sinter(array|string $keys)
|
||||
* @method int sintercard(array $keys, int $limit = 0)
|
||||
* @method int sinterstore(string $destination, array|string $keys)
|
||||
* @method int sismember(string $key, string $member)
|
||||
* @method string[] smembers(string $key)
|
||||
* @method array smismember(string $key, string ...$members)
|
||||
* @method int smove(string $source, string $destination, string $member)
|
||||
* @method string|array|null spop(string $key, int $count = null)
|
||||
* @method string|null srandmember(string $key, int $count = null)
|
||||
@@ -116,15 +140,29 @@ use Predis\Response\Status;
|
||||
* @method string[] sunion(array|string $keys)
|
||||
* @method int sunionstore(string $destination, array|string $keys)
|
||||
* @method int touch(string[]|string $keyOrKeys, string ...$keys = null)
|
||||
* @method string xadd(string $key, array $dictionary, string $id = '*', array $options = null)
|
||||
* @method int xdel(string $key, string ...$id)
|
||||
* @method int xlen(string $key)
|
||||
* @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 int zadd(string $key, array $membersAndScoresDictionary)
|
||||
* @method int zcard(string $key)
|
||||
* @method string zcount(string $key, int|string $min, int|string $max)
|
||||
* @method array zdiff(array $keys, bool $withScores = false)
|
||||
* @method int zdiffstore(string $destination, array $keys)
|
||||
* @method string zincrby(string $key, int $increment, string $member)
|
||||
* @method int zinterstore(string $destination, array|string $keys, array $options = null)
|
||||
* @method int zintercard(array $keys, int $limit = 0)
|
||||
* @method int zinterstore(string $destination, array $keys, int[] $weights = [], string $aggregate = 'sum')
|
||||
* @method array zinter(array $keys, int[] $weights = [], string $aggregate = 'sum', bool $withScores = false)
|
||||
* @method array zmpop(array $keys, string $modifier = 'min', int $count = 1)
|
||||
* @method array zmscore(string $key, string ...$member)
|
||||
* @method array zpopmin(string $key, int $count = 1)
|
||||
* @method array zpopmax(string $key, int $count = 1)
|
||||
* @method mixed zrandmember(string $key, int $count = 1, bool $withScores = false)
|
||||
* @method array zrange(string $key, int|string $start, int|string $stop, array $options = null)
|
||||
* @method array zrangebyscore(string $key, int|string $min, int|string $max, array $options = null)
|
||||
* @method int zrangestore(string $destination, string $source, int|string $min, int|string $max, string|bool $by = false, bool $reversed = false, bool $limit = false, int $offset = 0, int $count = 0)
|
||||
* @method int|null zrank(string $key, string $member)
|
||||
* @method int zrem(string $key, string ...$member)
|
||||
* @method int zremrangebyrank(string $key, int|string $start, int|string $stop)
|
||||
@@ -132,13 +170,15 @@ use Predis\Response\Status;
|
||||
* @method array zrevrange(string $key, int|string $start, int|string $stop, array $options = null)
|
||||
* @method array zrevrangebyscore(string $key, int|string $max, int|string $min, array $options = null)
|
||||
* @method int|null zrevrank(string $key, string $member)
|
||||
* @method int zunionstore(string $destination, array|string $keys, array $options = null)
|
||||
* @method array zunion(array $keys, int[] $weights = [], string $aggregate = 'sum', bool $withScores = false)
|
||||
* @method int zunionstore(string $destination, array $keys, int[] $weights = [], string $aggregate = 'sum')
|
||||
* @method string|null zscore(string $key, string $member)
|
||||
* @method array zscan(string $key, int $cursor, array $options = null)
|
||||
* @method array zrangebylex(string $key, string $start, string $stop, array $options = null)
|
||||
* @method array zrevrangebylex(string $key, string $start, string $stop, array $options = null)
|
||||
* @method int zremrangebylex(string $key, string $min, string $max)
|
||||
* @method int zlexcount(string $key, string $min, string $max)
|
||||
* @method int pexpiretime(string $key)
|
||||
* @method int pfadd(string $key, array $elements)
|
||||
* @method mixed pfmerge(string $destinationKey, array|string $sourceKeys)
|
||||
* @method int pfcount(string[]|string $keyOrKeys, string ...$keys = null)
|
||||
@@ -150,7 +190,9 @@ use Predis\Response\Status;
|
||||
* @method mixed unwatch()
|
||||
* @method mixed watch(string $key)
|
||||
* @method mixed eval(string $script, int $numkeys, string ...$keyOrArg = null)
|
||||
* @method mixed eval_ro(string $script, array $keys, ...$argument)
|
||||
* @method mixed evalsha(string $script, int $numkeys, string ...$keyOrArg = null)
|
||||
* @method mixed evalsha_ro(string $sha1, array $keys, ...$argument)
|
||||
* @method mixed script($subcommand, $argument = null)
|
||||
* @method mixed auth(string $password)
|
||||
* @method string echo(string $message)
|
||||
@@ -176,8 +218,11 @@ use Predis\Response\Status;
|
||||
* @method string|null geodist(string $key, $member1, $member2, $unit = null)
|
||||
* @method array georadius(string $key, $longitude, $latitude, $radius, $unit, array $options = null)
|
||||
* @method array georadiusbymember(string $key, $member, $radius, $unit, array $options = null)
|
||||
* @method array geosearch(string $key, FromInterface $from, ByInterface $by, ?string $sorting = null, int $count = -1, bool $any = false, bool $withCoord = false, bool $withDist = false, bool $withHash = false)
|
||||
* @method int geosearchstore(string $destination, string $source, FromInterface $from, ByInterface $by, ?string $sorting = null, int $count = -1, bool $any = false, bool $storeDist = false)
|
||||
*
|
||||
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||
* Container commands
|
||||
* @property FunctionContainer $function
|
||||
*/
|
||||
interface ClientInterface
|
||||
{
|
||||
@@ -220,7 +265,7 @@ interface ClientInterface
|
||||
*
|
||||
* @return CommandInterface
|
||||
*/
|
||||
public function createCommand($method, $arguments = array());
|
||||
public function createCommand($method, $arguments = []);
|
||||
|
||||
/**
|
||||
* Executes the specified Redis command.
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2023 Till Krüss
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
@@ -11,21 +12,17 @@
|
||||
|
||||
namespace Predis\Cluster;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use Predis\Command\CommandInterface;
|
||||
use Predis\Command\ScriptCommand;
|
||||
|
||||
/**
|
||||
* Common class implementing the logic needed to support clustering strategies.
|
||||
*
|
||||
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||
*/
|
||||
abstract class ClusterStrategy implements StrategyInterface
|
||||
{
|
||||
protected $commands;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->commands = $this->getDefaultCommands();
|
||||
@@ -38,10 +35,10 @@ abstract class ClusterStrategy implements StrategyInterface
|
||||
*/
|
||||
protected function getDefaultCommands()
|
||||
{
|
||||
$getKeyFromFirstArgument = array($this, 'getKeyFromFirstArgument');
|
||||
$getKeyFromAllArguments = array($this, 'getKeyFromAllArguments');
|
||||
$getKeyFromFirstArgument = [$this, 'getKeyFromFirstArgument'];
|
||||
$getKeyFromAllArguments = [$this, 'getKeyFromAllArguments'];
|
||||
|
||||
return array(
|
||||
return [
|
||||
/* commands operating on the key space */
|
||||
'EXISTS' => $getKeyFromAllArguments,
|
||||
'DEL' => $getKeyFromAllArguments,
|
||||
@@ -53,7 +50,7 @@ abstract class ClusterStrategy implements StrategyInterface
|
||||
'PEXPIREAT' => $getKeyFromFirstArgument,
|
||||
'TTL' => $getKeyFromFirstArgument,
|
||||
'PTTL' => $getKeyFromFirstArgument,
|
||||
'SORT' => array($this, 'getKeyFromSortCommand'),
|
||||
'SORT' => [$this, 'getKeyFromSortCommand'],
|
||||
'DUMP' => $getKeyFromFirstArgument,
|
||||
'RESTORE' => $getKeyFromFirstArgument,
|
||||
|
||||
@@ -72,13 +69,13 @@ abstract class ClusterStrategy implements StrategyInterface
|
||||
'INCRBYFLOAT' => $getKeyFromFirstArgument,
|
||||
'SETBIT' => $getKeyFromFirstArgument,
|
||||
'SETEX' => $getKeyFromFirstArgument,
|
||||
'MSET' => array($this, 'getKeyFromInterleavedArguments'),
|
||||
'MSETNX' => array($this, 'getKeyFromInterleavedArguments'),
|
||||
'MSET' => [$this, 'getKeyFromInterleavedArguments'],
|
||||
'MSETNX' => [$this, 'getKeyFromInterleavedArguments'],
|
||||
'SETNX' => $getKeyFromFirstArgument,
|
||||
'SETRANGE' => $getKeyFromFirstArgument,
|
||||
'STRLEN' => $getKeyFromFirstArgument,
|
||||
'SUBSTR' => $getKeyFromFirstArgument,
|
||||
'BITOP' => array($this, 'getKeyFromBitOp'),
|
||||
'BITOP' => [$this, 'getKeyFromBitOp'],
|
||||
'BITCOUNT' => $getKeyFromFirstArgument,
|
||||
'BITFIELD' => $getKeyFromFirstArgument,
|
||||
|
||||
@@ -89,9 +86,9 @@ abstract class ClusterStrategy implements StrategyInterface
|
||||
'LPOP' => $getKeyFromFirstArgument,
|
||||
'RPOP' => $getKeyFromFirstArgument,
|
||||
'RPOPLPUSH' => $getKeyFromAllArguments,
|
||||
'BLPOP' => array($this, 'getKeyFromBlockingListCommands'),
|
||||
'BRPOP' => array($this, 'getKeyFromBlockingListCommands'),
|
||||
'BRPOPLPUSH' => array($this, 'getKeyFromBlockingListCommands'),
|
||||
'BLPOP' => [$this, 'getKeyFromBlockingListCommands'],
|
||||
'BRPOP' => [$this, 'getKeyFromBlockingListCommands'],
|
||||
'BRPOPLPUSH' => [$this, 'getKeyFromBlockingListCommands'],
|
||||
'LPUSH' => $getKeyFromFirstArgument,
|
||||
'LPUSHX' => $getKeyFromFirstArgument,
|
||||
'RPUSH' => $getKeyFromFirstArgument,
|
||||
@@ -122,7 +119,7 @@ abstract class ClusterStrategy implements StrategyInterface
|
||||
'ZCARD' => $getKeyFromFirstArgument,
|
||||
'ZCOUNT' => $getKeyFromFirstArgument,
|
||||
'ZINCRBY' => $getKeyFromFirstArgument,
|
||||
'ZINTERSTORE' => array($this, 'getKeyFromZsetAggregationCommands'),
|
||||
'ZINTERSTORE' => [$this, 'getKeyFromZsetAggregationCommands'],
|
||||
'ZRANGE' => $getKeyFromFirstArgument,
|
||||
'ZRANGEBYSCORE' => $getKeyFromFirstArgument,
|
||||
'ZRANK' => $getKeyFromFirstArgument,
|
||||
@@ -133,7 +130,7 @@ abstract class ClusterStrategy implements StrategyInterface
|
||||
'ZREVRANGEBYSCORE' => $getKeyFromFirstArgument,
|
||||
'ZREVRANK' => $getKeyFromFirstArgument,
|
||||
'ZSCORE' => $getKeyFromFirstArgument,
|
||||
'ZUNIONSTORE' => array($this, 'getKeyFromZsetAggregationCommands'),
|
||||
'ZUNIONSTORE' => [$this, 'getKeyFromZsetAggregationCommands'],
|
||||
'ZSCAN' => $getKeyFromFirstArgument,
|
||||
'ZLEXCOUNT' => $getKeyFromFirstArgument,
|
||||
'ZRANGEBYLEX' => $getKeyFromFirstArgument,
|
||||
@@ -163,17 +160,17 @@ abstract class ClusterStrategy implements StrategyInterface
|
||||
'PFMERGE' => $getKeyFromAllArguments,
|
||||
|
||||
/* scripting */
|
||||
'EVAL' => array($this, 'getKeyFromScriptingCommands'),
|
||||
'EVALSHA' => array($this, 'getKeyFromScriptingCommands'),
|
||||
'EVAL' => [$this, 'getKeyFromScriptingCommands'],
|
||||
'EVALSHA' => [$this, 'getKeyFromScriptingCommands'],
|
||||
|
||||
/* commands performing geospatial operations */
|
||||
'GEOADD' => $getKeyFromFirstArgument,
|
||||
'GEOHASH' => $getKeyFromFirstArgument,
|
||||
'GEOPOS' => $getKeyFromFirstArgument,
|
||||
'GEODIST' => $getKeyFromFirstArgument,
|
||||
'GEORADIUS' => array($this, 'getKeyFromGeoradiusCommands'),
|
||||
'GEORADIUSBYMEMBER' => array($this, 'getKeyFromGeoradiusCommands'),
|
||||
);
|
||||
'GEORADIUS' => [$this, 'getKeyFromGeoradiusCommands'],
|
||||
'GEORADIUSBYMEMBER' => [$this, 'getKeyFromGeoradiusCommands'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -198,7 +195,7 @@ abstract class ClusterStrategy implements StrategyInterface
|
||||
* @param string $commandID Command ID.
|
||||
* @param mixed $callback A valid callable object, or NULL to unset the handler.
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function setCommandHandler($commandID, $callback = null)
|
||||
{
|
||||
@@ -211,7 +208,7 @@ abstract class ClusterStrategy implements StrategyInterface
|
||||
}
|
||||
|
||||
if (!is_callable($callback)) {
|
||||
throw new \InvalidArgumentException(
|
||||
throw new InvalidArgumentException(
|
||||
'The argument must be a callable object or NULL.'
|
||||
);
|
||||
}
|
||||
@@ -243,9 +240,11 @@ abstract class ClusterStrategy implements StrategyInterface
|
||||
{
|
||||
$arguments = $command->getArguments();
|
||||
|
||||
if ($this->checkSameSlotForKeys($arguments)) {
|
||||
return $arguments[0];
|
||||
if (!$this->checkSameSlotForKeys($arguments)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $arguments[0];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -259,15 +258,17 @@ abstract class ClusterStrategy implements StrategyInterface
|
||||
protected function getKeyFromInterleavedArguments(CommandInterface $command)
|
||||
{
|
||||
$arguments = $command->getArguments();
|
||||
$keys = array();
|
||||
$keys = [];
|
||||
|
||||
for ($i = 0; $i < count($arguments); $i += 2) {
|
||||
$keys[] = $arguments[$i];
|
||||
}
|
||||
|
||||
if ($this->checkSameSlotForKeys($keys)) {
|
||||
return $arguments[0];
|
||||
if (!$this->checkSameSlotForKeys($keys)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $arguments[0];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -286,7 +287,7 @@ abstract class ClusterStrategy implements StrategyInterface
|
||||
return $firstKey;
|
||||
}
|
||||
|
||||
$keys = array($firstKey);
|
||||
$keys = [$firstKey];
|
||||
|
||||
for ($i = 1; $i < $argc; ++$i) {
|
||||
if (strtoupper($arguments[$i]) === 'STORE') {
|
||||
@@ -294,9 +295,11 @@ abstract class ClusterStrategy implements StrategyInterface
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->checkSameSlotForKeys($keys)) {
|
||||
return $firstKey;
|
||||
if (!$this->checkSameSlotForKeys($keys)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $firstKey;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -310,9 +313,11 @@ abstract class ClusterStrategy implements StrategyInterface
|
||||
{
|
||||
$arguments = $command->getArguments();
|
||||
|
||||
if ($this->checkSameSlotForKeys(array_slice($arguments, 0, count($arguments) - 1))) {
|
||||
return $arguments[0];
|
||||
if (!$this->checkSameSlotForKeys(array_slice($arguments, 0, count($arguments) - 1))) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $arguments[0];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -326,9 +331,11 @@ abstract class ClusterStrategy implements StrategyInterface
|
||||
{
|
||||
$arguments = $command->getArguments();
|
||||
|
||||
if ($this->checkSameSlotForKeys(array_slice($arguments, 1, count($arguments)))) {
|
||||
return $arguments[1];
|
||||
if (!$this->checkSameSlotForKeys(array_slice($arguments, 1, count($arguments)))) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $arguments[1];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -345,7 +352,7 @@ abstract class ClusterStrategy implements StrategyInterface
|
||||
$startIndex = $command->getId() === 'GEORADIUS' ? 5 : 4;
|
||||
|
||||
if ($argc > $startIndex) {
|
||||
$keys = array($arguments[0]);
|
||||
$keys = [$arguments[0]];
|
||||
|
||||
for ($i = $startIndex; $i < $argc; ++$i) {
|
||||
$argument = strtoupper($arguments[$i]);
|
||||
@@ -354,10 +361,8 @@ abstract class ClusterStrategy implements StrategyInterface
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->checkSameSlotForKeys($keys)) {
|
||||
return $arguments[0];
|
||||
} else {
|
||||
return;
|
||||
if (!$this->checkSameSlotForKeys($keys)) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -374,11 +379,13 @@ abstract class ClusterStrategy implements StrategyInterface
|
||||
protected function getKeyFromZsetAggregationCommands(CommandInterface $command)
|
||||
{
|
||||
$arguments = $command->getArguments();
|
||||
$keys = array_merge(array($arguments[0]), array_slice($arguments, 2, $arguments[1]));
|
||||
$keys = array_merge([$arguments[0]], array_slice($arguments, 2, $arguments[1]));
|
||||
|
||||
if ($this->checkSameSlotForKeys($keys)) {
|
||||
return $arguments[0];
|
||||
if (!$this->checkSameSlotForKeys($keys)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $arguments[0];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -390,15 +397,15 @@ abstract class ClusterStrategy implements StrategyInterface
|
||||
*/
|
||||
protected function getKeyFromScriptingCommands(CommandInterface $command)
|
||||
{
|
||||
if ($command instanceof ScriptCommand) {
|
||||
$keys = $command->getKeys();
|
||||
} else {
|
||||
$keys = array_slice($args = $command->getArguments(), 2, $args[1]);
|
||||
$keys = $command instanceof ScriptCommand
|
||||
? $command->getKeys()
|
||||
: array_slice($args = $command->getArguments(), 2, $args[1]);
|
||||
|
||||
if (!$keys || !$this->checkSameSlotForKeys($keys)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($keys && $this->checkSameSlotForKeys($keys)) {
|
||||
return $keys[0];
|
||||
}
|
||||
return $keys[0];
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2023 Till Krüss
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
@@ -16,8 +17,6 @@ use Predis\Cluster\Hash\HashGeneratorInterface;
|
||||
/**
|
||||
* A distributor implements the logic to automatically distribute keys among
|
||||
* several nodes for client-side sharding.
|
||||
*
|
||||
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||
*/
|
||||
interface DistributorInterface
|
||||
{
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2023 Till Krüss
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
@@ -11,11 +12,11 @@
|
||||
|
||||
namespace Predis\Cluster\Distributor;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* Exception class that identifies empty rings.
|
||||
*
|
||||
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||
*/
|
||||
class EmptyRingException extends \Exception
|
||||
class EmptyRingException extends Exception
|
||||
{
|
||||
}
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2023 Till Krüss
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
@@ -17,21 +18,19 @@ use Predis\Cluster\Hash\HashGeneratorInterface;
|
||||
* This class implements an hashring-based distributor that uses the same
|
||||
* algorithm of memcache to distribute keys in a cluster using client-side
|
||||
* sharding.
|
||||
*
|
||||
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||
* @author Lorenzo Castelli <lcastelli@gmail.com>
|
||||
*/
|
||||
class HashRing implements DistributorInterface, HashGeneratorInterface
|
||||
{
|
||||
const DEFAULT_REPLICAS = 128;
|
||||
const DEFAULT_WEIGHT = 100;
|
||||
public const DEFAULT_REPLICAS = 128;
|
||||
public const DEFAULT_WEIGHT = 100;
|
||||
|
||||
private $ring;
|
||||
private $ringKeys;
|
||||
private $ringKeysCount;
|
||||
private $replicas;
|
||||
private $nodeHashCallback;
|
||||
private $nodes = array();
|
||||
private $nodes = [];
|
||||
|
||||
/**
|
||||
* @param int $replicas Number of replicas in the ring.
|
||||
@@ -53,10 +52,10 @@ class HashRing implements DistributorInterface, HashGeneratorInterface
|
||||
{
|
||||
// In case of collisions in the hashes of the nodes, the node added
|
||||
// last wins, thus the order in which nodes are added is significant.
|
||||
$this->nodes[] = array(
|
||||
$this->nodes[] = [
|
||||
'object' => $node,
|
||||
'weight' => (int) $weight ?: $this::DEFAULT_WEIGHT,
|
||||
);
|
||||
];
|
||||
|
||||
$this->reset();
|
||||
}
|
||||
@@ -131,7 +130,7 @@ class HashRing implements DistributorInterface, HashGeneratorInterface
|
||||
throw new EmptyRingException('Cannot initialize an empty hashring.');
|
||||
}
|
||||
|
||||
$this->ring = array();
|
||||
$this->ring = [];
|
||||
$totalWeight = $this->computeTotalWeight();
|
||||
$nodesCount = count($this->nodes);
|
||||
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2023 Till Krüss
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
@@ -15,13 +16,11 @@ namespace Predis\Cluster\Distributor;
|
||||
* This class implements an hashring-based distributor that uses the same
|
||||
* algorithm of libketama to distribute keys in a cluster using client-side
|
||||
* sharding.
|
||||
*
|
||||
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||
* @author Lorenzo Castelli <lcastelli@gmail.com>
|
||||
*/
|
||||
class KetamaRing extends HashRing
|
||||
{
|
||||
const DEFAULT_REPLICAS = 160;
|
||||
public const DEFAULT_REPLICAS = 160;
|
||||
|
||||
/**
|
||||
* @param mixed $nodeHashCallback Callback returning a string used to calculate the hash of nodes.
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2023 Till Krüss
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
@@ -13,12 +14,10 @@ namespace Predis\Cluster\Hash;
|
||||
|
||||
/**
|
||||
* Hash generator implementing the CRC-CCITT-16 algorithm used by redis-cluster.
|
||||
*
|
||||
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||
*/
|
||||
class CRC16 implements HashGeneratorInterface
|
||||
{
|
||||
private static $CCITT_16 = array(
|
||||
private static $CCITT_16 = [
|
||||
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
|
||||
0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
|
||||
0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
|
||||
@@ -51,7 +50,7 @@ class CRC16 implements HashGeneratorInterface
|
||||
0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
|
||||
0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
|
||||
0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0,
|
||||
);
|
||||
];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2023 Till Krüss
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
@@ -14,8 +15,6 @@ namespace Predis\Cluster\Hash;
|
||||
/**
|
||||
* An hash generator implements the logic used to calculate the hash of a key to
|
||||
* distribute operations among Redis nodes.
|
||||
*
|
||||
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||
*/
|
||||
interface HashGeneratorInterface
|
||||
{
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2023 Till Krüss
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
@@ -16,13 +17,10 @@ use Predis\NotSupportedException;
|
||||
/**
|
||||
* Hash generator implementing the CRC-CCITT-16 algorithm used by redis-cluster.
|
||||
*
|
||||
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||
* @deprecated 2.1.2
|
||||
*/
|
||||
class PhpiredisCRC16 implements HashGeneratorInterface
|
||||
{
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
if (!function_exists('phpiredis_utils_crc16')) {
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2023 Till Krüss
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
@@ -16,8 +17,6 @@ use Predis\Cluster\Distributor\HashRing;
|
||||
|
||||
/**
|
||||
* Default cluster strategy used by Predis to handle client-side sharding.
|
||||
*
|
||||
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||
*/
|
||||
class PredisStrategy extends ClusterStrategy
|
||||
{
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2023 Till Krüss
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
@@ -18,8 +19,6 @@ use Predis\NotSupportedException;
|
||||
/**
|
||||
* Default class used by Predis to calculate hashes out of keys of
|
||||
* commands supported by redis-cluster.
|
||||
*
|
||||
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||
*/
|
||||
class RedisStrategy extends ClusterStrategy
|
||||
{
|
||||
|
||||
+30
-23
@@ -3,7 +3,8 @@
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2023 Till Krüss
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
@@ -11,17 +12,25 @@
|
||||
|
||||
namespace Predis\Cluster;
|
||||
|
||||
use ArrayAccess;
|
||||
use ArrayIterator;
|
||||
use Countable;
|
||||
use IteratorAggregate;
|
||||
use OutOfBoundsException;
|
||||
use Predis\Connection\NodeConnectionInterface;
|
||||
use ReturnTypeWillChange;
|
||||
|
||||
/**
|
||||
* Slot map for redis-cluster.
|
||||
*/
|
||||
class SlotMap implements \ArrayAccess, \IteratorAggregate, \Countable
|
||||
class SlotMap implements ArrayAccess, IteratorAggregate, Countable
|
||||
{
|
||||
private $slots = array();
|
||||
private $slots = [];
|
||||
|
||||
/**
|
||||
* Checks if the given slot is valid.
|
||||
*
|
||||
* @param int $first Slot index.
|
||||
* @param int $slot Slot index.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
@@ -48,7 +57,7 @@ class SlotMap implements \ArrayAccess, \IteratorAggregate, \Countable
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
$this->slots = array();
|
||||
$this->slots = [];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -90,12 +99,12 @@ class SlotMap implements \ArrayAccess, \IteratorAggregate, \Countable
|
||||
* @param int $last Last slot of the range.
|
||||
* @param NodeConnectionInterface|string $connection ID or connection instance.
|
||||
*
|
||||
* @throws \OutOfBoundsException
|
||||
* @throws OutOfBoundsException
|
||||
*/
|
||||
public function setSlots($first, $last, $connection)
|
||||
{
|
||||
if (!static::isValidRange($first, $last)) {
|
||||
throw new \OutOfBoundsException("Invalid slot range $first-$last for `$connection`");
|
||||
throw new OutOfBoundsException("Invalid slot range $first-$last for `$connection`");
|
||||
}
|
||||
|
||||
$this->slots += array_fill($first, $last - $first + 1, (string) $connection);
|
||||
@@ -112,7 +121,7 @@ class SlotMap implements \ArrayAccess, \IteratorAggregate, \Countable
|
||||
public function getSlots($first, $last)
|
||||
{
|
||||
if (!static::isValidRange($first, $last)) {
|
||||
throw new \OutOfBoundsException("Invalid slot range $first-$last");
|
||||
throw new OutOfBoundsException("Invalid slot range $first-$last");
|
||||
}
|
||||
|
||||
return array_intersect_key($this->slots, array_fill($first, $last - $first + 1, null));
|
||||
@@ -125,7 +134,7 @@ class SlotMap implements \ArrayAccess, \IteratorAggregate, \Countable
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
#[ReturnTypeWillChange]
|
||||
public function offsetExists($slot)
|
||||
{
|
||||
return isset($this->slots[$slot]);
|
||||
@@ -136,14 +145,12 @@ class SlotMap implements \ArrayAccess, \IteratorAggregate, \Countable
|
||||
*
|
||||
* @param int $slot Slot index.
|
||||
*
|
||||
* @return string
|
||||
* @return string|null
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
#[ReturnTypeWillChange]
|
||||
public function offsetGet($slot)
|
||||
{
|
||||
if (isset($this->slots[$slot])) {
|
||||
return $this->slots[$slot];
|
||||
}
|
||||
return $this->slots[$slot] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -152,13 +159,13 @@ class SlotMap implements \ArrayAccess, \IteratorAggregate, \Countable
|
||||
* @param int $slot Slot index.
|
||||
* @param NodeConnectionInterface|string $connection ID or connection instance.
|
||||
*
|
||||
* @return string
|
||||
* @return void
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
#[ReturnTypeWillChange]
|
||||
public function offsetSet($slot, $connection)
|
||||
{
|
||||
if (!static::isValid($slot)) {
|
||||
throw new \OutOfBoundsException("Invalid slot $slot for `$connection`");
|
||||
throw new OutOfBoundsException("Invalid slot $slot for `$connection`");
|
||||
}
|
||||
|
||||
$this->slots[(int) $slot] = (string) $connection;
|
||||
@@ -169,9 +176,9 @@ class SlotMap implements \ArrayAccess, \IteratorAggregate, \Countable
|
||||
*
|
||||
* @param int $slot Slot index.
|
||||
*
|
||||
* @return string
|
||||
* @return void
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
#[ReturnTypeWillChange]
|
||||
public function offsetUnset($slot)
|
||||
{
|
||||
unset($this->slots[$slot]);
|
||||
@@ -182,7 +189,7 @@ class SlotMap implements \ArrayAccess, \IteratorAggregate, \Countable
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
#[ReturnTypeWillChange]
|
||||
public function count()
|
||||
{
|
||||
return count($this->slots);
|
||||
@@ -191,11 +198,11 @@ class SlotMap implements \ArrayAccess, \IteratorAggregate, \Countable
|
||||
/**
|
||||
* Returns an iterator over the slot map.
|
||||
*
|
||||
* @return \ArrayIterator
|
||||
* @return ArrayIterator
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
#[ReturnTypeWillChange]
|
||||
public function getIterator()
|
||||
{
|
||||
return new \ArrayIterator($this->slots);
|
||||
return new ArrayIterator($this->slots);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2023 Till Krüss
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
@@ -19,8 +20,6 @@ use Predis\Command\CommandInterface;
|
||||
* keys extracted from supported commands.
|
||||
*
|
||||
* This is mostly useful to support clustering via client-side sharding.
|
||||
*
|
||||
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||
*/
|
||||
interface StrategyInterface
|
||||
{
|
||||
@@ -30,7 +29,7 @@ interface StrategyInterface
|
||||
*
|
||||
* @param CommandInterface $command Command instance.
|
||||
*
|
||||
* @return int
|
||||
* @return int|null
|
||||
*/
|
||||
public function getSlot(CommandInterface $command);
|
||||
|
||||
@@ -40,7 +39,7 @@ interface StrategyInterface
|
||||
*
|
||||
* @param string $key Key string.
|
||||
*
|
||||
* @return int
|
||||
* @return int|null
|
||||
*/
|
||||
public function getSlotByKey($key);
|
||||
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2023 Till Krüss
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
@@ -11,8 +12,10 @@
|
||||
|
||||
namespace Predis\Collection\Iterator;
|
||||
|
||||
use Iterator;
|
||||
use Predis\ClientInterface;
|
||||
use Predis\NotSupportedException;
|
||||
use ReturnTypeWillChange;
|
||||
|
||||
/**
|
||||
* Provides the base implementation for a fully-rewindable PHP iterator that can
|
||||
@@ -24,10 +27,8 @@ use Predis\NotSupportedException;
|
||||
* can change several times during the iteration process.
|
||||
*
|
||||
* @see http://redis.io/commands/scan
|
||||
*
|
||||
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||
*/
|
||||
abstract class CursorBasedIterator implements \Iterator
|
||||
abstract class CursorBasedIterator implements Iterator
|
||||
{
|
||||
protected $client;
|
||||
protected $match;
|
||||
@@ -77,7 +78,7 @@ abstract class CursorBasedIterator implements \Iterator
|
||||
{
|
||||
$this->valid = true;
|
||||
$this->fetchmore = true;
|
||||
$this->elements = array();
|
||||
$this->elements = [];
|
||||
$this->cursor = 0;
|
||||
$this->position = -1;
|
||||
$this->current = null;
|
||||
@@ -90,7 +91,7 @@ abstract class CursorBasedIterator implements \Iterator
|
||||
*/
|
||||
protected function getScanOptions()
|
||||
{
|
||||
$options = array();
|
||||
$options = [];
|
||||
|
||||
if (strlen(strval($this->match)) > 0) {
|
||||
$options['MATCH'] = $this->match;
|
||||
@@ -117,7 +118,7 @@ abstract class CursorBasedIterator implements \Iterator
|
||||
*/
|
||||
protected function fetch()
|
||||
{
|
||||
list($cursor, $elements) = $this->executeCommand();
|
||||
[$cursor, $elements] = $this->executeCommand();
|
||||
|
||||
if (!$cursor) {
|
||||
$this->fetchmore = false;
|
||||
@@ -139,7 +140,7 @@ abstract class CursorBasedIterator implements \Iterator
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
#[ReturnTypeWillChange]
|
||||
public function rewind()
|
||||
{
|
||||
$this->reset();
|
||||
@@ -149,7 +150,7 @@ abstract class CursorBasedIterator implements \Iterator
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
#[ReturnTypeWillChange]
|
||||
public function current()
|
||||
{
|
||||
return $this->current;
|
||||
@@ -158,7 +159,7 @@ abstract class CursorBasedIterator implements \Iterator
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
#[ReturnTypeWillChange]
|
||||
public function key()
|
||||
{
|
||||
return $this->position;
|
||||
@@ -167,10 +168,10 @@ abstract class CursorBasedIterator implements \Iterator
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
#[ReturnTypeWillChange]
|
||||
public function next()
|
||||
{
|
||||
tryFetch: {
|
||||
tryFetch:
|
||||
if (!$this->elements && $this->fetchmore) {
|
||||
$this->fetch();
|
||||
}
|
||||
@@ -182,13 +183,12 @@ abstract class CursorBasedIterator implements \Iterator
|
||||
} else {
|
||||
$this->valid = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
#[ReturnTypeWillChange]
|
||||
public function valid()
|
||||
{
|
||||
return $this->valid;
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2023 Till Krüss
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
@@ -17,9 +18,7 @@ use Predis\ClientInterface;
|
||||
* Abstracts the iteration of fields and values of an hash by leveraging the
|
||||
* HSCAN command (Redis >= 2.8) wrapped in a fully-rewindable PHP iterator.
|
||||
*
|
||||
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||
*
|
||||
* @link http://redis.io/commands/scan
|
||||
* @see http://redis.io/commands/scan
|
||||
*/
|
||||
class HashKey extends CursorBasedIterator
|
||||
{
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2023 Till Krüss
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
@@ -17,9 +18,7 @@ use Predis\ClientInterface;
|
||||
* Abstracts the iteration of the keyspace on a Redis instance by leveraging the
|
||||
* SCAN command (Redis >= 2.8) wrapped in a fully-rewindable PHP iterator.
|
||||
*
|
||||
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||
*
|
||||
* @link http://redis.io/commands/scan
|
||||
* @see http://redis.io/commands/scan
|
||||
*/
|
||||
class Keyspace extends CursorBasedIterator
|
||||
{
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2023 Till Krüss
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
@@ -11,8 +12,11 @@
|
||||
|
||||
namespace Predis\Collection\Iterator;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use Iterator;
|
||||
use Predis\ClientInterface;
|
||||
use Predis\NotSupportedException;
|
||||
use ReturnTypeWillChange;
|
||||
|
||||
/**
|
||||
* Abstracts the iteration of items stored in a list by leveraging the LRANGE
|
||||
@@ -24,11 +28,9 @@ use Predis\NotSupportedException;
|
||||
* guarantees on the returned elements because the collection can change several
|
||||
* times (trimmed, deleted, overwritten) during the iteration process.
|
||||
*
|
||||
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||
*
|
||||
* @link http://redis.io/commands/lrange
|
||||
* @see http://redis.io/commands/lrange
|
||||
*/
|
||||
class ListKey implements \Iterator
|
||||
class ListKey implements Iterator
|
||||
{
|
||||
protected $client;
|
||||
protected $count;
|
||||
@@ -45,14 +47,14 @@ class ListKey implements \Iterator
|
||||
* @param string $key Redis list key.
|
||||
* @param int $count Number of items retrieved on each fetch operation.
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function __construct(ClientInterface $client, $key, $count = 10)
|
||||
{
|
||||
$this->requiredCommand($client, 'LRANGE');
|
||||
|
||||
if ((false === $count = filter_var($count, FILTER_VALIDATE_INT)) || $count < 0) {
|
||||
throw new \InvalidArgumentException('The $count argument must be a positive integer.');
|
||||
throw new InvalidArgumentException('The $count argument must be a positive integer.');
|
||||
}
|
||||
|
||||
$this->client = $client;
|
||||
@@ -85,7 +87,7 @@ class ListKey implements \Iterator
|
||||
{
|
||||
$this->valid = true;
|
||||
$this->fetchmore = true;
|
||||
$this->elements = array();
|
||||
$this->elements = [];
|
||||
$this->position = -1;
|
||||
$this->current = null;
|
||||
}
|
||||
@@ -128,7 +130,7 @@ class ListKey implements \Iterator
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
#[ReturnTypeWillChange]
|
||||
public function rewind()
|
||||
{
|
||||
$this->reset();
|
||||
@@ -138,7 +140,7 @@ class ListKey implements \Iterator
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
#[ReturnTypeWillChange]
|
||||
public function current()
|
||||
{
|
||||
return $this->current;
|
||||
@@ -147,7 +149,7 @@ class ListKey implements \Iterator
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
#[ReturnTypeWillChange]
|
||||
public function key()
|
||||
{
|
||||
return $this->position;
|
||||
@@ -156,7 +158,7 @@ class ListKey implements \Iterator
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
#[ReturnTypeWillChange]
|
||||
public function next()
|
||||
{
|
||||
if (!$this->elements && $this->fetchmore) {
|
||||
@@ -173,7 +175,7 @@ class ListKey implements \Iterator
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
#[ReturnTypeWillChange]
|
||||
public function valid()
|
||||
{
|
||||
return $this->valid;
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2023 Till Krüss
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
@@ -17,9 +18,7 @@ use Predis\ClientInterface;
|
||||
* Abstracts the iteration of members stored in a set by leveraging the SSCAN
|
||||
* command (Redis >= 2.8) wrapped in a fully-rewindable PHP iterator.
|
||||
*
|
||||
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||
*
|
||||
* @link http://redis.io/commands/scan
|
||||
* @see http://redis.io/commands/scan
|
||||
*/
|
||||
class SetKey extends CursorBasedIterator
|
||||
{
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2023 Till Krüss
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
@@ -17,9 +18,7 @@ use Predis\ClientInterface;
|
||||
* Abstracts the iteration of members stored in a sorted set by leveraging the
|
||||
* ZSCAN command (Redis >= 2.8) wrapped in a fully-rewindable PHP iterator.
|
||||
*
|
||||
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||
*
|
||||
* @link http://redis.io/commands/scan
|
||||
* @see http://redis.io/commands/scan
|
||||
*/
|
||||
class SortedSetKey extends CursorBasedIterator
|
||||
{
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2023 Till Krüss
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Predis\Command\Argument;
|
||||
|
||||
/**
|
||||
* Allows to use object-oriented approach to handle complex conditional arguments.
|
||||
*/
|
||||
interface ArrayableArgument
|
||||
{
|
||||
/**
|
||||
* Get the instance as an array.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function toArray(): array;
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2023 Till Krüss
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Predis\Command\Argument\Geospatial;
|
||||
|
||||
use UnexpectedValueException;
|
||||
|
||||
abstract class AbstractBy implements ByInterface
|
||||
{
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
private static $unitEnum = ['m', 'km', 'ft', 'mi'];
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $unit;
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
abstract public function toArray(): array;
|
||||
|
||||
/**
|
||||
* @param string $unit
|
||||
* @return void
|
||||
*/
|
||||
protected function setUnit(string $unit): void
|
||||
{
|
||||
if (!in_array($unit, self::$unitEnum, true)) {
|
||||
throw new UnexpectedValueException('Wrong value given for unit');
|
||||
}
|
||||
|
||||
$this->unit = $unit;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2023 Till Krüss
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Predis\Command\Argument\Geospatial;
|
||||
|
||||
class ByBox extends AbstractBy
|
||||
{
|
||||
private const KEYWORD = 'BYBOX';
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $width;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $height;
|
||||
|
||||
public function __construct(int $width, int $height, string $unit)
|
||||
{
|
||||
$this->width = $width;
|
||||
$this->height = $height;
|
||||
$this->setUnit($unit);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
return [self::KEYWORD, $this->width, $this->height, $this->unit];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2023 Till Krüss
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Predis\Command\Argument\Geospatial;
|
||||
|
||||
use Predis\Command\Argument\ArrayableArgument;
|
||||
|
||||
interface ByInterface extends ArrayableArgument
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2023 Till Krüss
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Predis\Command\Argument\Geospatial;
|
||||
|
||||
class ByRadius extends AbstractBy
|
||||
{
|
||||
private const KEYWORD = 'BYRADIUS';
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $radius;
|
||||
|
||||
public function __construct(int $radius, string $unit)
|
||||
{
|
||||
$this->radius = $radius;
|
||||
$this->setUnit($unit);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
return [self::KEYWORD, $this->radius, $this->unit];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2023 Till Krüss
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Predis\Command\Argument\Geospatial;
|
||||
|
||||
use Predis\Command\Argument\ArrayableArgument;
|
||||
|
||||
interface FromInterface extends ArrayableArgument
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2023 Till Krüss
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Predis\Command\Argument\Geospatial;
|
||||
|
||||
class FromLonLat implements FromInterface
|
||||
{
|
||||
private const KEYWORD = 'FROMLONLAT';
|
||||
|
||||
/**
|
||||
* @var float
|
||||
*/
|
||||
private $longitude;
|
||||
|
||||
/**
|
||||
* @var float
|
||||
*/
|
||||
private $latitude;
|
||||
|
||||
public function __construct(float $longitude, float $latitude)
|
||||
{
|
||||
$this->longitude = $longitude;
|
||||
$this->latitude = $latitude;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
return [self::KEYWORD, $this->longitude, $this->latitude];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2023 Till Krüss
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Predis\Command\Argument\Geospatial;
|
||||
|
||||
class FromMember implements FromInterface
|
||||
{
|
||||
private const KEYWORD = 'FROMMEMBER';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $member;
|
||||
|
||||
public function __construct(string $member)
|
||||
{
|
||||
$this->member = $member;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
return [self::KEYWORD, $this->member];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2023 Till Krüss
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Predis\Command\Argument\Server;
|
||||
|
||||
use Predis\Command\Argument\ArrayableArgument;
|
||||
|
||||
interface LimitInterface extends ArrayableArgument
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2023 Till Krüss
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Predis\Command\Argument\Server;
|
||||
|
||||
class LimitOffsetCount implements LimitInterface
|
||||
{
|
||||
private const KEYWORD = 'LIMIT';
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $offset;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $count;
|
||||
|
||||
public function __construct(int $offset, int $count)
|
||||
{
|
||||
$this->offset = $offset;
|
||||
$this->count = $count;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
return [self::KEYWORD, $this->offset, $this->count];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2023 Till Krüss
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Predis\Command\Argument\Server;
|
||||
|
||||
use Predis\Command\Argument\ArrayableArgument;
|
||||
|
||||
class To implements ArrayableArgument
|
||||
{
|
||||
private const KEYWORD = 'TO';
|
||||
private const FORCE_KEYWORD = 'FORCE';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $host;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $port;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $isForce;
|
||||
|
||||
public function __construct(string $host, int $port, bool $isForce = false)
|
||||
{
|
||||
$this->host = $host;
|
||||
$this->port = $port;
|
||||
$this->isForce = $isForce;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
$arguments = [self::KEYWORD, $this->host, $this->port];
|
||||
|
||||
if ($this->isForce) {
|
||||
$arguments[] = self::FORCE_KEYWORD;
|
||||
}
|
||||
|
||||
return $arguments;
|
||||
}
|
||||
}
|
||||
+17
-8
@@ -3,7 +3,8 @@
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2023 Till Krüss
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
@@ -13,13 +14,11 @@ namespace Predis\Command;
|
||||
|
||||
/**
|
||||
* Base class for Redis commands.
|
||||
*
|
||||
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||
*/
|
||||
abstract class Command implements CommandInterface
|
||||
{
|
||||
private $slot;
|
||||
private $arguments = array();
|
||||
private $arguments = [];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
@@ -70,9 +69,7 @@ abstract class Command implements CommandInterface
|
||||
*/
|
||||
public function getSlot()
|
||||
{
|
||||
if (isset($this->slot)) {
|
||||
return $this->slot;
|
||||
}
|
||||
return $this->slot ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -109,9 +106,21 @@ abstract class Command implements CommandInterface
|
||||
public static function normalizeVariadic(array $arguments)
|
||||
{
|
||||
if (count($arguments) === 2 && is_array($arguments[1])) {
|
||||
return array_merge(array($arguments[0]), $arguments[1]);
|
||||
return array_merge([$arguments[0]], $arguments[1]);
|
||||
}
|
||||
|
||||
return $arguments;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all false values from arguments.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function filterArguments(): void
|
||||
{
|
||||
$this->arguments = array_filter($this->arguments, static function ($argument) {
|
||||
return $argument !== false && $argument !== null;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2023 Till Krüss
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
@@ -13,8 +14,6 @@ namespace Predis\Command;
|
||||
|
||||
/**
|
||||
* Defines an abstraction representing a Redis command.
|
||||
*
|
||||
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||
*/
|
||||
interface CommandInterface
|
||||
{
|
||||
|
||||
+8
-10
@@ -3,7 +3,8 @@
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2023 Till Krüss
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
@@ -11,6 +12,7 @@
|
||||
|
||||
namespace Predis\Command;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use Predis\ClientException;
|
||||
use Predis\Command\Processor\ProcessorInterface;
|
||||
|
||||
@@ -20,8 +22,6 @@ use Predis\Command\Processor\ProcessorInterface;
|
||||
* This class provides all of the common functionalities required for a command
|
||||
* factory to create new instances of Redis commands objects. It also allows to
|
||||
* define or undefine command handler classes for each command ID.
|
||||
*
|
||||
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||
*/
|
||||
abstract class Factory implements FactoryInterface
|
||||
{
|
||||
@@ -49,13 +49,11 @@ abstract class Factory implements FactoryInterface
|
||||
*
|
||||
* @param string $commandID Command ID
|
||||
*
|
||||
* @return ?string
|
||||
* @return string|null
|
||||
*/
|
||||
public function getCommandClass(string $commandID): ?string
|
||||
{
|
||||
if (isset($this->commands[$commandID = strtoupper($commandID)])) {
|
||||
return $this->commands[$commandID];
|
||||
}
|
||||
return $this->commands[strtoupper($commandID)] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -89,12 +87,12 @@ abstract class Factory implements FactoryInterface
|
||||
* @param string $commandID Command ID
|
||||
* @param string $commandClass FQCN of a class implementing Predis\Command\CommandInterface
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function define(string $commandID, string $commandClass): void
|
||||
{
|
||||
if (!is_a($commandClass, 'Predis\Command\CommandInterface', true)) {
|
||||
throw new \InvalidArgumentException(
|
||||
throw new InvalidArgumentException(
|
||||
"Class $commandClass must implement Predis\Command\CommandInterface"
|
||||
);
|
||||
}
|
||||
@@ -136,7 +134,7 @@ abstract class Factory implements FactoryInterface
|
||||
/**
|
||||
* Returns the current command processor.
|
||||
*
|
||||
* @return ?ProcessorInterface
|
||||
* @return ProcessorInterface|null
|
||||
*/
|
||||
public function getProcessor(): ?ProcessorInterface
|
||||
{
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2023 Till Krüss
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
@@ -17,15 +18,13 @@ namespace Predis\Command;
|
||||
* A command factory is used through the library to create instances of commands
|
||||
* classes implementing Predis\Command\CommandInterface mapped to Redis commands
|
||||
* by their command ID string (SET, GET, etc...).
|
||||
*
|
||||
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||
*/
|
||||
interface FactoryInterface
|
||||
{
|
||||
/**
|
||||
* Checks if the command factory supports the specified list of commands.
|
||||
*
|
||||
* @param array $commandIDs List of command IDs
|
||||
* @param string ...$commandIDs List of command IDs
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
@@ -39,5 +38,5 @@ interface FactoryInterface
|
||||
*
|
||||
* @return CommandInterface
|
||||
*/
|
||||
public function create(string $commandID, array $arguments = array()): CommandInterface;
|
||||
public function create(string $commandID, array $arguments = []): CommandInterface;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2023 Till Krüss
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
@@ -13,8 +14,6 @@ namespace Predis\Command;
|
||||
|
||||
/**
|
||||
* Defines a command whose keys can be prefixed.
|
||||
*
|
||||
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||
*/
|
||||
interface PrefixableCommandInterface extends CommandInterface
|
||||
{
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2023 Till Krüss
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
@@ -11,14 +12,13 @@
|
||||
|
||||
namespace Predis\Command\Processor;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use Predis\Command\CommandInterface;
|
||||
use Predis\Command\PrefixableCommandInterface;
|
||||
|
||||
/**
|
||||
* Command processor capable of prefixing keys stored in the arguments of Redis
|
||||
* commands supported.
|
||||
*
|
||||
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||
*/
|
||||
class KeyPrefixProcessor implements ProcessorInterface
|
||||
{
|
||||
@@ -31,142 +31,160 @@ class KeyPrefixProcessor implements ProcessorInterface
|
||||
public function __construct($prefix)
|
||||
{
|
||||
$this->prefix = $prefix;
|
||||
$this->commands = array(
|
||||
|
||||
$prefixFirst = static::class . '::first';
|
||||
$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' => 'static::all',
|
||||
'DEL' => 'static::all',
|
||||
'TYPE' => 'static::first',
|
||||
'KEYS' => 'static::first',
|
||||
'RENAME' => 'static::all',
|
||||
'RENAMENX' => 'static::all',
|
||||
'EXPIRE' => 'static::first',
|
||||
'EXPIREAT' => 'static::first',
|
||||
'TTL' => 'static::first',
|
||||
'MOVE' => 'static::first',
|
||||
'SORT' => 'static::sort',
|
||||
'DUMP' => 'static::first',
|
||||
'RESTORE' => 'static::first',
|
||||
'SET' => 'static::first',
|
||||
'SETNX' => 'static::first',
|
||||
'MSET' => 'static::interleaved',
|
||||
'MSETNX' => 'static::interleaved',
|
||||
'GET' => 'static::first',
|
||||
'MGET' => 'static::all',
|
||||
'GETSET' => 'static::first',
|
||||
'INCR' => 'static::first',
|
||||
'INCRBY' => 'static::first',
|
||||
'DECR' => 'static::first',
|
||||
'DECRBY' => 'static::first',
|
||||
'RPUSH' => 'static::first',
|
||||
'LPUSH' => 'static::first',
|
||||
'LLEN' => 'static::first',
|
||||
'LRANGE' => 'static::first',
|
||||
'LTRIM' => 'static::first',
|
||||
'LINDEX' => 'static::first',
|
||||
'LSET' => 'static::first',
|
||||
'LREM' => 'static::first',
|
||||
'LPOP' => 'static::first',
|
||||
'RPOP' => 'static::first',
|
||||
'RPOPLPUSH' => 'static::all',
|
||||
'SADD' => 'static::first',
|
||||
'SREM' => 'static::first',
|
||||
'SPOP' => 'static::first',
|
||||
'SMOVE' => 'static::skipLast',
|
||||
'SCARD' => 'static::first',
|
||||
'SISMEMBER' => 'static::first',
|
||||
'SINTER' => 'static::all',
|
||||
'SINTERSTORE' => 'static::all',
|
||||
'SUNION' => 'static::all',
|
||||
'SUNIONSTORE' => 'static::all',
|
||||
'SDIFF' => 'static::all',
|
||||
'SDIFFSTORE' => 'static::all',
|
||||
'SMEMBERS' => 'static::first',
|
||||
'SRANDMEMBER' => 'static::first',
|
||||
'ZADD' => 'static::first',
|
||||
'ZINCRBY' => 'static::first',
|
||||
'ZREM' => 'static::first',
|
||||
'ZRANGE' => 'static::first',
|
||||
'ZREVRANGE' => 'static::first',
|
||||
'ZRANGEBYSCORE' => 'static::first',
|
||||
'ZCARD' => 'static::first',
|
||||
'ZSCORE' => 'static::first',
|
||||
'ZREMRANGEBYSCORE' => 'static::first',
|
||||
'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,
|
||||
'SRANDMEMBER' => $prefixFirst,
|
||||
'ZADD' => $prefixFirst,
|
||||
'ZINCRBY' => $prefixFirst,
|
||||
'ZREM' => $prefixFirst,
|
||||
'ZRANGE' => $prefixFirst,
|
||||
'ZREVRANGE' => $prefixFirst,
|
||||
'ZRANGEBYSCORE' => $prefixFirst,
|
||||
'ZCARD' => $prefixFirst,
|
||||
'ZSCORE' => $prefixFirst,
|
||||
'ZREMRANGEBYSCORE' => $prefixFirst,
|
||||
/* ---------------- Redis 2.0 ---------------- */
|
||||
'SETEX' => 'static::first',
|
||||
'APPEND' => 'static::first',
|
||||
'SUBSTR' => 'static::first',
|
||||
'BLPOP' => 'static::skipLast',
|
||||
'BRPOP' => 'static::skipLast',
|
||||
'ZUNIONSTORE' => 'static::zsetStore',
|
||||
'ZINTERSTORE' => 'static::zsetStore',
|
||||
'ZCOUNT' => 'static::first',
|
||||
'ZRANK' => 'static::first',
|
||||
'ZREVRANK' => 'static::first',
|
||||
'ZREMRANGEBYRANK' => 'static::first',
|
||||
'HSET' => 'static::first',
|
||||
'HSETNX' => 'static::first',
|
||||
'HMSET' => 'static::first',
|
||||
'HINCRBY' => 'static::first',
|
||||
'HGET' => 'static::first',
|
||||
'HMGET' => 'static::first',
|
||||
'HDEL' => 'static::first',
|
||||
'HEXISTS' => 'static::first',
|
||||
'HLEN' => 'static::first',
|
||||
'HKEYS' => 'static::first',
|
||||
'HVALS' => 'static::first',
|
||||
'HGETALL' => 'static::first',
|
||||
'SUBSCRIBE' => 'static::all',
|
||||
'UNSUBSCRIBE' => 'static::all',
|
||||
'PSUBSCRIBE' => 'static::all',
|
||||
'PUNSUBSCRIBE' => 'static::all',
|
||||
'PUBLISH' => 'static::first',
|
||||
'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' => 'static::first',
|
||||
'STRLEN' => 'static::first',
|
||||
'SETRANGE' => 'static::first',
|
||||
'GETRANGE' => 'static::first',
|
||||
'SETBIT' => 'static::first',
|
||||
'GETBIT' => 'static::first',
|
||||
'RPUSHX' => 'static::first',
|
||||
'LPUSHX' => 'static::first',
|
||||
'LINSERT' => 'static::first',
|
||||
'BRPOPLPUSH' => 'static::skipLast',
|
||||
'ZREVRANGEBYSCORE' => 'static::first',
|
||||
'WATCH' => 'static::all',
|
||||
'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' => 'static::first',
|
||||
'PEXPIRE' => 'static::first',
|
||||
'PEXPIREAT' => 'static::first',
|
||||
'PSETEX' => 'static::first',
|
||||
'INCRBYFLOAT' => 'static::first',
|
||||
'BITOP' => 'static::skipFirst',
|
||||
'BITCOUNT' => 'static::first',
|
||||
'HINCRBYFLOAT' => 'static::first',
|
||||
'EVAL' => 'static::evalKeys',
|
||||
'EVALSHA' => 'static::evalKeys',
|
||||
'MIGRATE' => 'static::migrate',
|
||||
'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' => 'static::first',
|
||||
'ZSCAN' => 'static::first',
|
||||
'HSCAN' => 'static::first',
|
||||
'PFADD' => 'static::first',
|
||||
'PFCOUNT' => 'static::all',
|
||||
'PFMERGE' => 'static::all',
|
||||
'ZLEXCOUNT' => 'static::first',
|
||||
'ZRANGEBYLEX' => 'static::first',
|
||||
'ZREMRANGEBYLEX' => 'static::first',
|
||||
'ZREVRANGEBYLEX' => 'static::first',
|
||||
'BITPOS' => 'static::first',
|
||||
'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' => 'static::first',
|
||||
'BITFIELD' => 'static::first',
|
||||
'GEOADD' => 'static::first',
|
||||
'GEOHASH' => 'static::first',
|
||||
'GEOPOS' => 'static::first',
|
||||
'GEODIST' => 'static::first',
|
||||
'GEORADIUS' => 'static::georadius',
|
||||
'GEORADIUSBYMEMBER' => 'static::georadius',
|
||||
);
|
||||
'HSTRLEN' => $prefixFirst,
|
||||
'BITFIELD' => $prefixFirst,
|
||||
'GEOADD' => $prefixFirst,
|
||||
'GEOHASH' => $prefixFirst,
|
||||
'GEOPOS' => $prefixFirst,
|
||||
'GEODIST' => $prefixFirst,
|
||||
'GEORADIUS' => $prefixGeoradius,
|
||||
'GEORADIUSBYMEMBER' => $prefixGeoradius,
|
||||
/* ---------------- Redis 5.0 ---------------- */
|
||||
'XADD' => $prefixFirst,
|
||||
'XRANGE' => $prefixFirst,
|
||||
'XDEL' => $prefixFirst,
|
||||
'XLEN' => $prefixFirst,
|
||||
'XACK' => $prefixFirst,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -197,14 +215,7 @@ class KeyPrefixProcessor implements ProcessorInterface
|
||||
if ($command instanceof PrefixableCommandInterface) {
|
||||
$command->prefixKeys($this->prefix);
|
||||
} elseif (isset($this->commands[$commandID = strtoupper($command->getId())])) {
|
||||
$callable = $this->commands[$commandID];
|
||||
|
||||
if (is_string($callable) && strpos($callable, 'static::') === 0) {
|
||||
$callable = explode('::', $this->commands[$commandID]);
|
||||
$callable[0] = $this;
|
||||
}
|
||||
|
||||
call_user_func($callable, $command, $this->prefix);
|
||||
$this->commands[$commandID]($command, $this->prefix);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -222,7 +233,7 @@ class KeyPrefixProcessor implements ProcessorInterface
|
||||
* @param string $commandID The ID of the command to be handled.
|
||||
* @param mixed $callback A valid callable object or NULL.
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function setCommandHandler($commandID, $callback = null)
|
||||
{
|
||||
@@ -235,7 +246,7 @@ class KeyPrefixProcessor implements ProcessorInterface
|
||||
}
|
||||
|
||||
if (!is_callable($callback)) {
|
||||
throw new \InvalidArgumentException(
|
||||
throw new InvalidArgumentException(
|
||||
'Callback must be a valid callable object or NULL'
|
||||
);
|
||||
}
|
||||
@@ -365,7 +376,7 @@ class KeyPrefixProcessor implements ProcessorInterface
|
||||
}
|
||||
break;
|
||||
|
||||
case 'LIMIT';
|
||||
case 'LIMIT':
|
||||
$i += 2;
|
||||
break;
|
||||
}
|
||||
@@ -446,7 +457,6 @@ class KeyPrefixProcessor implements ProcessorInterface
|
||||
case 'STOREDIST':
|
||||
$arguments[$i] = "$prefix{$arguments[++$i]}";
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2023 Till Krüss
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
@@ -11,21 +12,24 @@
|
||||
|
||||
namespace Predis\Command\Processor;
|
||||
|
||||
use ArrayAccess;
|
||||
use ArrayIterator;
|
||||
use InvalidArgumentException;
|
||||
use Predis\Command\CommandInterface;
|
||||
use ReturnTypeWillChange;
|
||||
use Traversable;
|
||||
|
||||
/**
|
||||
* Default implementation of a command processors chain.
|
||||
*
|
||||
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||
*/
|
||||
class ProcessorChain implements \ArrayAccess, ProcessorInterface
|
||||
class ProcessorChain implements ArrayAccess, ProcessorInterface
|
||||
{
|
||||
private $processors = array();
|
||||
private $processors = [];
|
||||
|
||||
/**
|
||||
* @param array $processors List of instances of ProcessorInterface.
|
||||
*/
|
||||
public function __construct($processors = array())
|
||||
public function __construct($processors = [])
|
||||
{
|
||||
foreach ($processors as $processor) {
|
||||
$this->add($processor);
|
||||
@@ -71,11 +75,11 @@ class ProcessorChain implements \ArrayAccess, ProcessorInterface
|
||||
/**
|
||||
* Returns an iterator over the list of command processor in the chain.
|
||||
*
|
||||
* @return \Traversable<int, ProcessorInterface>
|
||||
* @return Traversable<int, ProcessorInterface>
|
||||
*/
|
||||
public function getIterator()
|
||||
{
|
||||
return new \ArrayIterator($this->processors);
|
||||
return new ArrayIterator($this->processors);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -91,7 +95,7 @@ class ProcessorChain implements \ArrayAccess, ProcessorInterface
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
#[ReturnTypeWillChange]
|
||||
public function offsetExists($index)
|
||||
{
|
||||
return isset($this->processors[$index]);
|
||||
@@ -100,7 +104,7 @@ class ProcessorChain implements \ArrayAccess, ProcessorInterface
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
#[ReturnTypeWillChange]
|
||||
public function offsetGet($index)
|
||||
{
|
||||
return $this->processors[$index];
|
||||
@@ -109,11 +113,11 @@ class ProcessorChain implements \ArrayAccess, ProcessorInterface
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
#[ReturnTypeWillChange]
|
||||
public function offsetSet($index, $processor)
|
||||
{
|
||||
if (!$processor instanceof ProcessorInterface) {
|
||||
throw new \InvalidArgumentException(
|
||||
throw new InvalidArgumentException(
|
||||
'Processor chain accepts only instances of `Predis\Command\Processor\ProcessorInterface`'
|
||||
);
|
||||
}
|
||||
@@ -124,7 +128,7 @@ class ProcessorChain implements \ArrayAccess, ProcessorInterface
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
#[ReturnTypeWillChange]
|
||||
public function offsetUnset($index)
|
||||
{
|
||||
unset($this->processors[$index]);
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2023 Till Krüss
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
@@ -15,8 +16,6 @@ use Predis\Command\CommandInterface;
|
||||
|
||||
/**
|
||||
* A command processor processes Redis commands before they are sent to Redis.
|
||||
*
|
||||
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||
*/
|
||||
interface ProcessorInterface
|
||||
{
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2023 Till Krüss
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
@@ -21,8 +22,6 @@ namespace Predis\Command;
|
||||
* of Predis\Client or managing internals like Redis Sentinel or Cluster as they
|
||||
* are not potentially subject to hijacking from third party libraries when they
|
||||
* override command handlers for standard Redis commands.
|
||||
*
|
||||
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||
*/
|
||||
final class RawCommand implements CommandInterface
|
||||
{
|
||||
@@ -34,7 +33,7 @@ final class RawCommand implements CommandInterface
|
||||
* @param string $commandID Command ID
|
||||
* @param array $arguments Command arguments
|
||||
*/
|
||||
public function __construct($commandID, array $arguments = array())
|
||||
public function __construct($commandID, array $arguments = [])
|
||||
{
|
||||
$this->commandID = strtoupper($commandID);
|
||||
$this->setArguments($arguments);
|
||||
@@ -44,11 +43,11 @@ final class RawCommand implements CommandInterface
|
||||
* Creates a new raw command using a variadic method.
|
||||
*
|
||||
* @param string $commandID Redis command ID
|
||||
* @param string ... Arguments list for the command
|
||||
* @param string ...$args Arguments list for the command
|
||||
*
|
||||
* @return CommandInterface
|
||||
*/
|
||||
public static function create($commandID /* [ $arg, ... */)
|
||||
public static function create($commandID, ...$args)
|
||||
{
|
||||
$arguments = func_get_args();
|
||||
|
||||
@@ -111,9 +110,7 @@ final class RawCommand implements CommandInterface
|
||||
*/
|
||||
public function getSlot()
|
||||
{
|
||||
if (isset($this->slot)) {
|
||||
return $this->slot;
|
||||
}
|
||||
return $this->slot ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2023 Till Krüss
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
@@ -21,8 +22,6 @@ namespace Predis\Command;
|
||||
* When using this factory the client does not process arguments before sending
|
||||
* commands to Redis and server responses are not further processed before being
|
||||
* returned to the caller.
|
||||
*
|
||||
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||
*/
|
||||
class RawFactory implements FactoryInterface
|
||||
{
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2023 Till Krüss
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
@@ -14,9 +15,7 @@ namespace Predis\Command\Redis;
|
||||
use Predis\Command\Command as RedisCommand;
|
||||
|
||||
/**
|
||||
* @link http://redis.io/commands/append
|
||||
*
|
||||
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||
* @see http://redis.io/commands/append
|
||||
*/
|
||||
class APPEND extends RedisCommand
|
||||
{
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2023 Till Krüss
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
@@ -14,9 +15,7 @@ namespace Predis\Command\Redis;
|
||||
use Predis\Command\Command as RedisCommand;
|
||||
|
||||
/**
|
||||
* @link http://redis.io/commands/auth
|
||||
*
|
||||
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||
* @see http://redis.io/commands/auth
|
||||
*/
|
||||
class AUTH extends RedisCommand
|
||||
{
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2023 Till Krüss
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Predis\Command\Redis\AbstractCommand;
|
||||
|
||||
use Predis\Command\Command as RedisCommand;
|
||||
use Predis\Command\Traits\Keys;
|
||||
|
||||
abstract class BZPOPBase extends RedisCommand
|
||||
{
|
||||
use Keys {
|
||||
Keys::setArguments as setKeys;
|
||||
}
|
||||
|
||||
protected static $keysArgumentPositionOffset = 0;
|
||||
|
||||
abstract public function getId(): string;
|
||||
|
||||
public function setArguments(array $arguments)
|
||||
{
|
||||
$this->setKeys($arguments, false);
|
||||
}
|
||||
|
||||
public function parseResponse($data)
|
||||
{
|
||||
$key = array_shift($data);
|
||||
|
||||
if (null === $key) {
|
||||
return [$key];
|
||||
}
|
||||
|
||||
return array_combine([$key], [[$data[0] => $data[1]]]);
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,8 @@
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2023 Till Krüss
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
@@ -14,9 +15,7 @@ namespace Predis\Command\Redis;
|
||||
use Predis\Command\Command as RedisCommand;
|
||||
|
||||
/**
|
||||
* @link http://redis.io/commands/bgrewriteaof
|
||||
*
|
||||
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||
* @see http://redis.io/commands/bgrewriteaof
|
||||
*/
|
||||
class BGREWRITEAOF extends RedisCommand
|
||||
{
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2023 Till Krüss
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
@@ -14,9 +15,7 @@ namespace Predis\Command\Redis;
|
||||
use Predis\Command\Command as RedisCommand;
|
||||
|
||||
/**
|
||||
* @link http://redis.io/commands/bgsave
|
||||
*
|
||||
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||
* @see http://redis.io/commands/bgsave
|
||||
*/
|
||||
class BGSAVE extends RedisCommand
|
||||
{
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2023 Till Krüss
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
@@ -12,14 +13,17 @@
|
||||
namespace Predis\Command\Redis;
|
||||
|
||||
use Predis\Command\Command as RedisCommand;
|
||||
use Predis\Command\Traits\BitByte;
|
||||
|
||||
/**
|
||||
* @link http://redis.io/commands/bitcount
|
||||
* @see http://redis.io/commands/bitcount
|
||||
*
|
||||
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||
* Count the number of set bits (population counting) in a string.
|
||||
*/
|
||||
class BITCOUNT extends RedisCommand
|
||||
{
|
||||
use BitByte;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2023 Till Krüss
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
@@ -14,9 +15,7 @@ namespace Predis\Command\Redis;
|
||||
use Predis\Command\Command as RedisCommand;
|
||||
|
||||
/**
|
||||
* @link http://redis.io/commands/bitfield
|
||||
*
|
||||
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||
* @see http://redis.io/commands/bitfield
|
||||
*/
|
||||
class BITFIELD extends RedisCommand
|
||||
{
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2023 Till Krüss
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
@@ -14,9 +15,7 @@ namespace Predis\Command\Redis;
|
||||
use Predis\Command\Command as RedisCommand;
|
||||
|
||||
/**
|
||||
* @link http://redis.io/commands/bitop
|
||||
*
|
||||
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||
* @see http://redis.io/commands/bitop
|
||||
*/
|
||||
class BITOP extends RedisCommand
|
||||
{
|
||||
@@ -34,7 +33,7 @@ class BITOP extends RedisCommand
|
||||
public function setArguments(array $arguments)
|
||||
{
|
||||
if (count($arguments) === 3 && is_array($arguments[2])) {
|
||||
list($operation, $destination) = $arguments;
|
||||
[$operation, $destination] = $arguments;
|
||||
$arguments = $arguments[2];
|
||||
array_unshift($arguments, $operation, $destination);
|
||||
}
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2023 Till Krüss
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
@@ -12,14 +13,17 @@
|
||||
namespace Predis\Command\Redis;
|
||||
|
||||
use Predis\Command\Command as RedisCommand;
|
||||
use Predis\Command\Traits\BitByte;
|
||||
|
||||
/**
|
||||
* @link http://redis.io/commands/bitpos
|
||||
* @see http://redis.io/commands/bitpos
|
||||
*
|
||||
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||
* Return the position of the first bit set to 1 or 0 in a string.
|
||||
*/
|
||||
class BITPOS extends RedisCommand
|
||||
{
|
||||
use BitByte;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2023 Till Krüss
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Predis\Command\Redis;
|
||||
|
||||
class BLMOVE extends LMOVE
|
||||
{
|
||||
public function getId()
|
||||
{
|
||||
return 'BLMOVE';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2023 Till Krüss
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Predis\Command\Redis;
|
||||
|
||||
class BLMPOP extends LMPOP
|
||||
{
|
||||
protected static $keysArgumentPositionOffset = 1;
|
||||
protected static $leftRightArgumentPositionOffset = 2;
|
||||
protected static $countArgumentPositionOffset = 3;
|
||||
|
||||
public function getId()
|
||||
{
|
||||
return 'BLMPOP';
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,8 @@
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2023 Till Krüss
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
@@ -14,9 +15,7 @@ namespace Predis\Command\Redis;
|
||||
use Predis\Command\Command as RedisCommand;
|
||||
|
||||
/**
|
||||
* @link http://redis.io/commands/blpop
|
||||
*
|
||||
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||
* @see http://redis.io/commands/blpop
|
||||
*/
|
||||
class BLPOP extends RedisCommand
|
||||
{
|
||||
@@ -34,7 +33,7 @@ class BLPOP extends RedisCommand
|
||||
public function setArguments(array $arguments)
|
||||
{
|
||||
if (count($arguments) === 2 && is_array($arguments[0])) {
|
||||
list($arguments, $timeout) = $arguments;
|
||||
[$arguments, $timeout] = $arguments;
|
||||
array_push($arguments, $timeout);
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2023 Till Krüss
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
@@ -14,9 +15,7 @@ namespace Predis\Command\Redis;
|
||||
use Predis\Command\Command as RedisCommand;
|
||||
|
||||
/**
|
||||
* @link http://redis.io/commands/brpop
|
||||
*
|
||||
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||
* @see http://redis.io/commands/brpop
|
||||
*/
|
||||
class BRPOP extends RedisCommand
|
||||
{
|
||||
@@ -34,7 +33,7 @@ class BRPOP extends RedisCommand
|
||||
public function setArguments(array $arguments)
|
||||
{
|
||||
if (count($arguments) === 2 && is_array($arguments[0])) {
|
||||
list($arguments, $timeout) = $arguments;
|
||||
[$arguments, $timeout] = $arguments;
|
||||
array_push($arguments, $timeout);
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) Daniele Alessandri <suppakilla@gmail.com>
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2023 Till Krüss
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
@@ -14,9 +15,7 @@ namespace Predis\Command\Redis;
|
||||
use Predis\Command\Command as RedisCommand;
|
||||
|
||||
/**
|
||||
* @link http://redis.io/commands/brpoplpush
|
||||
*
|
||||
* @author Daniele Alessandri <suppakilla@gmail.com>
|
||||
* @see http://redis.io/commands/brpoplpush
|
||||
*/
|
||||
class BRPOPLPUSH extends RedisCommand
|
||||
{
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Predis package.
|
||||
*
|
||||
* (c) 2009-2020 Daniele Alessandri
|
||||
* (c) 2021-2023 Till Krüss
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Predis\Command\Redis;
|
||||
|
||||
/**
|
||||
* @see https://redis.io/commands/bzmpop/
|
||||
*
|
||||
* BZMPOP is the blocking variant of ZMPOP.
|
||||
*/
|
||||
class BZMPOP extends ZMPOP
|
||||
{
|
||||
protected static $keysArgumentPositionOffset = 1;
|
||||
protected static $countArgumentPositionOffset = 3;
|
||||
protected static $modifierArgumentPositionOffset = 2;
|
||||
|
||||
public function getId()
|
||||
{
|
||||
return 'BZMPOP';
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user