├── .gitattributes
├── .gitignore
├── .noninteractive
├── .scrutinizer.yml
├── .travis.yml
├── CHANGELOG.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── composer.json
├── example
├── basic_example.php
├── conn_example.php
├── core_example.php
├── hash_set_example.php
├── hyperlog_example.php
├── key_val_example.php
├── list_example.php
├── set_example.php
└── transaction_example.php
├── phpunit.xml
├── src
└── Redis
│ ├── Command
│ ├── Api
│ │ ├── ApiChannelInterface.php
│ │ ├── ApiClusterInterface.php
│ │ ├── ApiConnInterface.php
│ │ ├── ApiCoreInterface.php
│ │ ├── ApiGeospatialInterface.php
│ │ ├── ApiHyperLogInterface.php
│ │ ├── ApiKeyValInterface.php
│ │ ├── ApiListInterface.php
│ │ ├── ApiSetHashInterface.php
│ │ ├── ApiSetInterface.php
│ │ ├── ApiSetSortedInterface.php
│ │ └── ApiTransactionInterface.php
│ ├── Builder.php
│ ├── CommandInterface.php
│ ├── Compose
│ │ ├── ApiChannelTrait.php
│ │ ├── ApiClusterTrait.php
│ │ ├── ApiConnTrait.php
│ │ ├── ApiCoreTrait.php
│ │ ├── ApiGeospatialTrait.php
│ │ ├── ApiHyperLogTrait.php
│ │ ├── ApiKeyValTrait.php
│ │ ├── ApiListTrait.php
│ │ ├── ApiSetHashTrait.php
│ │ ├── ApiSetSortedTrait.php
│ │ ├── ApiSetTrait.php
│ │ └── ApiTransactionTrait.php
│ └── Enum.php
│ ├── Driver
│ ├── Driver.php
│ ├── DriverInterface.php
│ ├── Request.php
│ └── RequestInterface.php
│ ├── Redis.php
│ └── RedisInterface.php
└── test
├── Callback.php
├── TModule.php
├── TModule
├── Command
│ ├── RedisApiChannelTest.php
│ ├── RedisApiConnTest.php
│ ├── RedisApiCoreTest.php
│ ├── RedisApiHyperLogTest.php
│ ├── RedisApiKeyValTest.php
│ ├── RedisApiListTest.php
│ ├── RedisApiSetHashTest.php
│ ├── RedisApiSetSortedTest.php
│ ├── RedisApiSetTest.php
│ └── RedisApiTransactionTest.php
└── _Support
│ └── RedisTrait.php
├── TUnit.php
├── _Simulation
├── Event.php
├── EventCollection.php
├── Simulation.php
└── SimulationInterface.php
└── bootstrap.php
/.gitattributes:
--------------------------------------------------------------------------------
1 | * text=auto
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | vendor/
2 | .idea/
3 | .DS_Store/
4 | composer.lock
5 | composer.phar
6 |
--------------------------------------------------------------------------------
/.noninteractive:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dazzle-php/redis/0203b71564b27eac641ec3d3858425452b80c235/.noninteractive
--------------------------------------------------------------------------------
/.scrutinizer.yml:
--------------------------------------------------------------------------------
1 | filter:
2 | excluded_paths:
3 | - 'build/*'
4 | - 'build-ci/*'
5 | - 'example/*'
6 | - 'example-bench/*'
7 | - 'test/*'
8 | - 'vendor/*'
9 |
10 | checks:
11 | php:
12 | return_doc_comments: true
13 | remove_extra_empty_lines: true
14 |
15 | coding_style:
16 | php:
17 | indentation:
18 | general:
19 | use_tabs: false
20 | size: 4
21 | switch:
22 | indent_case: true
23 | spaces:
24 | general:
25 | linefeed_character: newline
26 | before_parentheses:
27 | function_declaration: false
28 | closure_definition: false
29 | function_call: false
30 | if: true
31 | for: true
32 | while: true
33 | switch: true
34 | catch: true
35 | array_initializer: false
36 | around_operators:
37 | assignment: true
38 | logical: true
39 | equality: true
40 | relational: true
41 | bitwise: true
42 | additive: true
43 | multiplicative: true
44 | shift: true
45 | unary_additive: false
46 | concatenation: true
47 | negation: false
48 | before_left_brace:
49 | class: true
50 | function: true
51 | if: true
52 | else: true
53 | for: true
54 | while: true
55 | do: true
56 | switch: true
57 | try: true
58 | catch: true
59 | finally: true
60 | before_keywords:
61 | else: true
62 | while: true
63 | catch: true
64 | finally: true
65 | within:
66 | brackets: false
67 | array_initializer: false
68 | grouping: false
69 | function_call: false
70 | function_declaration: false
71 | if: false
72 | for: false
73 | while: false
74 | switch: false
75 | catch: false
76 | type_cast: false
77 | ternary_operator:
78 | before_condition: true
79 | after_condition: true
80 | before_alternative: true
81 | after_alternative: true
82 | in_short_version: false
83 | other:
84 | before_comma: false
85 | after_comma: true
86 | before_semicolon: false
87 | after_semicolon: true
88 | after_type_cast: true
89 | braces:
90 | classes_functions:
91 | class: new-line
92 | function: new-line
93 | closure: end-of-line
94 | if:
95 | opening: new-line
96 | always: false
97 | else_on_new_line: true
98 | for:
99 | opening: new-line
100 | always: true
101 | while:
102 | opening: new-line
103 | always: true
104 | do_while:
105 | opening: new-line
106 | always: true
107 | while_on_new_line: true
108 | switch:
109 | opening: new-line
110 | try:
111 | opening: new-line
112 | catch_on_new_line: true
113 | finally_on_new_line: true
114 | upper_lower_casing:
115 | keywords:
116 | general: lower
117 | constants:
118 | true_false_null: lower
119 |
120 | tools:
121 | external_code_coverage:
122 | timeout: 1800
123 | runs: 1
124 | php_code_coverage: false
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: php
2 |
3 | dist: trusty
4 | sudo: required
5 |
6 | php:
7 | - 5.6
8 | - 7.0
9 | - 7.1
10 |
11 | services:
12 | - redis-server
13 |
14 | env:
15 | global:
16 | - TEST_DB_REDIS_ENDPOINT="tcp://127.0.0.1:6379"
17 |
18 | before_install:
19 | - export PHP_MAJOR="$(echo $TRAVIS_PHP_VERSION | cut -d '.' -f 1,2)"
20 |
21 | install:
22 | - travis_retry composer self-update
23 | - travis_retry composer install --prefer-source --no-interaction
24 | - php -m
25 |
26 | script:
27 | - vendor/bin/phpunit -d memory_limit=1024M --coverage-text --coverage-clover=coverage.clover
28 |
29 | after_script:
30 | - if [ "$TRAVIS_PHP_VERSION" = "7.1" ]; then wget https://scrutinizer-ci.com/ocular.phar; fi
31 | - if [ "$TRAVIS_PHP_VERSION" = "7.1" ]; then php ocular.phar code-coverage:upload --format=php-clover coverage.clover; fi
32 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Release Notes
2 |
3 | This changelog references the relevant changes, bug and security fixes done.
4 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing
2 |
3 | Contributions are **welcome** and accepted via **Pull Requests** on [GitHub](https://github.com/dazzle-php/redis).
4 |
5 | ## Pull Requests
6 |
7 | - **Naming convention** - all pull requests fixing a problem should match "Fix #issue Message" pattern, the new features and non-fix changes should match "Resolve #issue Message", the rest should contain only "Message".
8 | - **Follow our template of code** - all contributions have to follow [PSR-2 coding standard](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md) with an exception of control structures, which have to have opening parenthesis always placed in the next line instead of the same.
9 | - **Add tests** - the contribution won't be accepted if it doesn't have tests.
10 | - **Document any change in behaviour** - make sure the `README.md` is kept up to date.
11 | - **Create feature branches** - don't create pull requests from your master branch.
12 | - **One pull request per feature** - for multiple things that you want to do, send also multiple pull requests.
13 | - **Keep coherent history** - make sure each individual commit in your pull request is meaningful. If you had to make multiple commits during development cycle, please squash them before submitting.
14 |
15 | ## Running Tests
16 |
17 | ```
18 | $> vendor/bin/phpunit
19 | ```
20 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2015-2017 Kamil Jamróz
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is furnished
8 | to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in all
11 | copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | THE SOFTWARE.
20 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Dazzle Async Redis Driver
2 |
3 | [](https://travis-ci.org/dazzle-php/redis)
4 | [](https://scrutinizer-ci.com/g/dazzle-php/redis/?branch=master)
5 | [](https://scrutinizer-ci.com/g/dazzle-php/redis/?branch=master)
6 | [](https://packagist.org/packages/dazzle-php/redis)
7 | [](https://packagist.org/packages/dazzle-php/redis)
8 | [](https://packagist.org/packages/dazzle-php/redis/license)
9 |
10 | > **Note:** This repository is part of [Dazzle Project](https://github.com/dazzle-php/dazzle) - the next-gen library for PHP. The project's purpose is to provide PHP developers with a set of complete tools to build functional async applications. Please, make sure you read the attached README carefully and it is guaranteed you will be surprised how easy to use and powerful it is. In the meantime, you might want to check out the rest of our async libraries in [Dazzle repository](https://github.com/dazzle-php) for the full extent of Dazzle experience.
11 |
12 |
13 |
14 |
15 |
16 |
17 | ## Description
18 |
19 | TODO
20 |
21 | ## Feature Highlights
22 |
23 | Dazzle Redis features:
24 |
25 | TODO
26 |
27 | ## Provided Example(s)
28 |
29 | ### Quickstart
30 |
31 | TODO
32 |
33 | ### Additional
34 |
35 | TODO
36 |
37 | ## Comparison
38 |
39 | This section contains Dazzle vs React comparison many users requested. If you are wondering why this section has been created, see the author note at the end of it.
40 |
41 | #### Performance
42 |
43 | TODO
44 |
45 | #### Details
46 |
47 | TODO
48 |
49 | #### Note from the author
50 |
51 | > Few years ago, whenever I needed async tools in PHP, I was actively using other, hugely popular php library called React. Back then it was mind-blowing experience for me and I was astonished how easy it was to simulate async behaviour in PHP. I started to trust this aproach more and more and began to use it in more complicated projects. However, the bigger the project I was working on was, the more defects I was able to find. Its code, in my experience, suffered from uneven performance, leaking memory, the occasional bugs and what had upset me most - lacking interfaces which focused only on async side of things, ignoring functionality of its components as a whole. I started to write my own extensions for the library, including missing boilerplate and fixes needed. I wanted to share that with the community, created PRs with some of them, but they were never approved or rejected. React project was dead at that time, but in fact, I still needed those tools. That prompted me to create Dazzle Project. It was designed as modern, more reliable and more complete replacement for React library. Although I hold React library dear to my heart up to this day, I believe I was able to achieve that goal perfectly. Since the first day Dazzle was published I received many requests to include comparisons and benchmarks that proves the previous statement. That's why this section has been attached to the README. I hope the readers will be able to find all the necessary pieces of information they are looking for in it.
52 |
53 | ## Requirements
54 |
55 | Dazzle Redis requires:
56 |
57 | * PHP-5.6 or PHP-7.0+,
58 | * UNIX or Windows OS.
59 |
60 | ## Installation
61 |
62 | To install this library make sure you have [composer](https://getcomposer.org/) installed, then run following command:
63 |
64 | ```
65 | $> composer require dazzle-php/redis
66 | ```
67 |
68 | ## Tests
69 |
70 | Tests can be run via:
71 |
72 | ```
73 | $> vendor/bin/phpunit -d memory_limit=1024M
74 | ```
75 |
76 | ## Versioning
77 |
78 | Versioning of Dazzle libraries is being shared between all packages included in [Dazzle Project](https://github.com/dazzle-php/dazzle). That means the releases are being made concurrently for all of them. On one hand this might lead to "empty" releases for some packages at times, but don't worry. In the end it is far much easier for contributors to maintain and -- what's the most important -- much more straight-forward for users to understand the compatibility and inter-operability of the packages.
79 |
80 | ## Contributing
81 |
82 | Thank you for considering contributing to this repository!
83 |
84 | - The contribution guide can be found in the [contribution tips](https://github.com/dazzle-php/redis/blob/master/CONTRIBUTING.md).
85 | - Open tickets can be found in [issues section](https://github.com/dazzle-php/redis/issues).
86 | - Current contributors are listed in [graphs section](https://github.com/dazzle-php/redis/graphs/contributors)
87 | - To contact the author(s) see the information attached in [composer.json](https://github.com/dazzle-php/redis/blob/master/composer.json) file.
88 |
89 | ## License
90 |
91 | Dazzle Redis is open-sourced software licensed under the [MIT license](http://opensource.org/licenses/MIT).
92 |
93 |
94 |
95 | "Everything is possible. The impossible just takes longer." ― Dan Brown
96 |
97 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "dazzle-php/redis",
3 | "description": "Dazzle Asynchronous Redis Driver.",
4 | "keywords": [
5 | "dazzle", "dazzle-php", "async", "async-redis", "redis", "redis-client", "cache", "queue", "client"
6 | ],
7 | "license": "MIT",
8 | "support": {
9 | "issues": "https://github.com/dazzle-php/redis/issues",
10 | "source": "https://github.com/dazzle-php/redis"
11 | },
12 | "authors": [
13 | {
14 | "name": "Kamil Jamroz",
15 | "homepage": "https://github.com/khelle"
16 | },
17 | {
18 | "name": "Hidehalo",
19 | "homepage": "https://github.com/hidehalo"
20 | },
21 | {
22 | "name": "The contributors",
23 | "homepage": "http://github.com/dazzle-php/channel/contributors"
24 | }
25 | ],
26 | "require": {
27 | "php": ">=5.6.7",
28 | "dazzle-php/event": "0.5.*",
29 | "dazzle-php/loop": "0.5.*",
30 | "dazzle-php/promise": "0.5.*",
31 | "dazzle-php/socket": "0.5.*",
32 | "dazzle-php/throwable": "0.5.*",
33 | "dazzle-php/util": "0.5.*",
34 | "clue/redis-protocol": "0.3.*"
35 | },
36 | "require-dev": {
37 | "phpunit/phpunit": ">=4.8.0 <5.4.0"
38 | },
39 | "autoload": {
40 | "psr-4": {
41 | "Dazzle\\Redis\\": "src/Redis",
42 | "Dazzle\\Redis\\Test\\": "test"
43 | }
44 | },
45 | "extra": {
46 | "branch-alias": {
47 | "dev-master": "0.5-dev"
48 | }
49 | },
50 | "minimum-stability": "dev",
51 | "prefer-stable": true
52 | }
53 |
--------------------------------------------------------------------------------
/example/basic_example.php:
--------------------------------------------------------------------------------
1 | on('start', function(Redis $redis) {
15 |
16 | $redis->flushDb();
17 |
18 | $redis->set('test','Hello Dazzle Redis!')->then(function ($value) {
19 | printf('result is %s'.PHP_EOL, $value);
20 | });
21 |
22 | $redis->get('test')->then(function ($value) {
23 | printf('result is %s'.PHP_EOL, $value);
24 | });
25 |
26 | $redis->end();
27 | });
28 | //redis client stop handler
29 | $redis->on('stop', function() use ($loop) {
30 | echo 'stop right now'.PHP_EOL;
31 | $loop->stop();
32 | });
33 | //redis client error handler
34 | $redis->on('error', function(Exception $ex) {
35 | printf('error message is %s'.PHP_EOL, $ex->getMessage());
36 | });
37 | //set redis client run when global loop start
38 | $loop->onStart(function () use ($redis) {
39 | $redis->start();
40 | });
41 | //then the global loop run...
42 | $loop->start();
43 |
44 |
45 |
--------------------------------------------------------------------------------
/example/conn_example.php:
--------------------------------------------------------------------------------
1 | on('start', function () use ($redis) {
19 | $redis->auth('no password')->then(function ($value) {
20 | printf("Auth result is %s\n", $value);
21 | }, function (Exception $e) {
22 | printf("Auth is failed cauz %s\n", $e->getMessage());
23 | });
24 |
25 | $redis->select(0)->then(function ($value) {
26 | printf("Select result is %s\n", $value);
27 | });
28 |
29 | $redis->ping()->then(function ($value) {
30 | printf("Hello %s message\n", $value);
31 | });
32 |
33 | $redis->quit()->then(function ($value) {
34 | printf("Quit result is %s\n", $value);
35 | });
36 | });
37 |
38 | $redis->on('stop', function () use ($loop) {
39 | $loop->stop();
40 | });
41 |
42 | $loop->onStart(function () use ($redis) {
43 | $redis->start();
44 | });
45 |
46 | $loop->start();
47 |
48 |
--------------------------------------------------------------------------------
/example/core_example.php:
--------------------------------------------------------------------------------
1 | on('start', function (Redis $redis) {
17 | $redis->info()->then(function ($value) {
18 | var_export($value);
19 | });
20 |
21 | $redis->end();
22 | });
23 |
24 | $redis->on('stop', function () use ($loop) {
25 | $loop->stop();
26 | });
27 |
28 | $loop->onStart(function () use ($redis) {
29 | $redis->start();
30 | });
31 |
32 | $loop->start();
--------------------------------------------------------------------------------
/example/hash_set_example.php:
--------------------------------------------------------------------------------
1 | on('start', function (Redis $redis) {
17 | $redis->flushDb();
18 |
19 | $redis->hSet('t_key','f', 1)->then(function ($value) {
20 | printf("Set hash set filed \"f\"=1: %s\n", $value>0?'OK':'Failed');
21 | });
22 | $redis->hGet('t_key', 'f')->then(function ($value) {
23 | printf("Get hash set filed \"f\": %s\n", $value);
24 | });
25 | $redis->hGetAll('t_key')->then(function ($value) {
26 | printf("Get all fileds %s and values: %s\n",
27 | implode(',', array_keys($value)),
28 | implode(',', array_values($value))
29 | );
30 | });
31 | $redis->hMSet('t_key', [
32 | 'f_1' => 1,
33 | 'f_2' => 2,
34 | ])->then(function ($value) {
35 | printf("Multi set: %s\n", $value);
36 | });
37 | $redis->hMGet('t_key', 'f_1', 'f_2')->then(function ($value) {
38 | printf("Multi get: %s\n", implode(',', $value));
39 | });
40 | $redis->hExists('t_key', 'f_1')->then(function ($value) {
41 | printf("[t_key] filed \"f\" exist: %s\n", $value > 0 ? 'Y':'N');
42 | });
43 | $redis->hIncrBy('t_key', 'f', 5)->then(function ($value) {
44 | printf("1 increment by 5: %s\n", $value);
45 | });
46 | $redis->hVals('t_key')->then(function ($value) {
47 | printf("All values of hashes sets: %s\n", implode(',', $value));
48 | });
49 | $redis->hDel('t_key', 'f')->then(function ($value) {
50 | printf("Delete: %s\n", $value > 0 ? 'OK' : "Failed");
51 | });
52 |
53 | $redis->end();
54 | });
55 |
56 | $redis->on('stop', function () use ($loop) {
57 | $loop->stop();
58 | });
59 |
60 | $loop->onStart(function () use ($redis) {
61 | $redis->start();
62 | });
63 |
64 | $loop->start();
--------------------------------------------------------------------------------
/example/hyperlog_example.php:
--------------------------------------------------------------------------------
1 | on('start', function (Redis $redis) {
17 | $redis->flushDb();
18 |
19 | $redis->pFAdd('t_hll',1, 2, 3, 4, 5, 6)->then(function ($value) {
20 | printf("Add [t_hll]: %s\n", $value > 0? 'OK' : 'Failed');
21 | });
22 | $redis->pFAdd('t_hll_1', 7, 8, 9)->then(function ($value) {
23 | printf("Add another [t_hll_1]: %s\n", $value > 0? 'OK' : 'Failed');
24 | });
25 | $redis->pFCount('t_hll')->then(function ($value) {
26 | printf("Count log(s) for [t_hll]: %s\n", $value);
27 | });
28 | $redis->pFMerge('t_hll', 't_hll_1')->then(function ($value) {
29 | printf("Merge [t_hll_1] into [t_hll_1] log(s): %s\n", $value);
30 | });
31 | $redis->pFCount('t_hll')->then(function ($value) {
32 | printf("Count log(s) for [t_hll] again: %s\n", $value);
33 | });
34 |
35 | $redis->end();
36 | });
37 |
38 | $redis->on('stop', function () use ($loop) {
39 | $loop->stop();
40 | });
41 |
42 | $loop->onStart(function () use ($redis) {
43 | $redis->start();
44 | });
45 |
46 | $loop->start();
--------------------------------------------------------------------------------
/example/key_val_example.php:
--------------------------------------------------------------------------------
1 | on('start', function (Redis $redis) {
18 | $redis->flushDb();
19 | //normal string opts
20 | $redis->set('t_key', 'Hello Dazzle Redis!', ['ex', 60])->then(function ($value) {
21 | printf("Set [t_key] equals \"Hello Dazzle Redis!\": %s\n", $value);
22 | });
23 | $redis->append('t_key', 'XD')->then(function ($value) {
24 | printf("Append \"XD\" to [t_key]: %s\n", $value>0?'OK':'Failed');
25 | });
26 | $redis->get('t_key')->then(function ($value) {
27 | printf("Get [t_key]: %s\n", $value);
28 | });
29 | $redis->strLen('t_key')->then(function ($value) {
30 | printf("String length: %s\n", $value);
31 | });
32 | //multi opts
33 | $redis->mSet([
34 | 't_key_1' => 1,
35 | 't_key_2' => 2
36 | ])->then(function ($value) {
37 | printf("Multi set [t_key_1, t_key_2] keys %s\n", $value);
38 | });
39 | $redis->mGet('t_key_1', 't_key_2')->then(function ($value) {
40 | printf("Multi get [t_key_1, t_key_2]: %s\n", implode(',', $value));
41 | });
42 | //increment and decrement
43 | $redis->incrBy('t_key_1', 5)->then(function ($value) {
44 | printf("The result of 1 increment by 5: %s\n", $value);
45 | });
46 |
47 | $redis->decr('t_key_1')->then(function ($value) {
48 | printf("The result of 6 increment by 1: %s\n", $value);
49 | });
50 |
51 | //bit opts
52 | $redis->setBit('t_b_1', 0, 1);
53 | $redis->setBit('t_b_2', 0, 1);
54 | $redis->bitOp('AND', 'answer', 't_b_1', 't_b_2');
55 | $redis->getBit('answer', 0)->then(function ($value) {
56 | printf("The answer of \"1&1\" is: %d\n", $value);
57 | });
58 |
59 | //generic key opts
60 | $redis->exists('t_b_1', 't_b_2', 't_key_1')->then(function ($value) {
61 | printf("%s given key(s) is exist\n", $value);
62 | });
63 | $redis->expire('t_key_1', 60)->then(function ($value) {
64 | printf("Expire result: %s\n", $value);
65 | });
66 | $redis->expireAt('t_key_2', time() + 60)->then(function ($value) {
67 | printf("Expire at unix timestamp + 60 result: %s\n", $value);
68 | });
69 | $redis->persist('t_key')->then(function ($value) {
70 | printf("Persist result: %s\n", $value > 0 ? 'OK' : 'Failed');
71 | });
72 | $redis->type('t_key')->then(function ($value) {
73 | printf("Type: %s\n", $value);
74 | });
75 | $redis->ttl('t_key_1')->then(function ($value) {
76 | printf("TTL: %s(secs)\n", $value);
77 | });
78 | $redis->del('t_key', 't_key_1', 't_key_2', 'answer')->then(function ($value) {
79 | printf("Delete %d key(s)\n", $value);
80 | });
81 |
82 | $redis->end();
83 | });
84 |
85 | $redis->on('stop', function () use ($loop) {
86 | $loop->stop();
87 | });
88 |
89 | $loop->onStart(function () use ($redis) {
90 | $redis->start();
91 | });
92 |
93 | $loop->start();
--------------------------------------------------------------------------------
/example/list_example.php:
--------------------------------------------------------------------------------
1 | on('start', function (Redis $redis) {
18 | //this one is not a command of redis list commands part
19 | $redis->flushDb();
20 |
21 | $redis->lPush('t_list', 1, 2, 3, 4, 5)->then(function ($value) {
22 | printf("Push %d elements to a new list\n", $value);
23 | });
24 | $redis->lPop('t_list')->then(function ($value) {
25 | printf("Pop \"%s\" elements from list\n", $value);
26 | });
27 | $redis->lIndex('t_list', 0)->then(function ($value) {
28 | printf("Index 0 element: \"%s\" elements from list\n", $value);
29 |
30 | });
31 | $redis->lInsert('t_list', 'after', 4, 10)->then(function ($_) {
32 | printf("New element: \"%s\" insert to list\n", '10');
33 | });
34 | $redis->lLen('t_list')->then(function ($value) {
35 | printf("Now list length: %d\n", $value);
36 | });
37 | $redis->lRange('t_list')->then(function ($value) {
38 | printf("All elements: %s\n", implode(',', $value));
39 | });
40 | $redis->lRem('t_list', 0, 4)->then(function ($value) {
41 | printf("Remove %d element(s) of that value equals 4\n", $value);
42 | });
43 | $redis->lSet('t_list', 0, 3)->then(function ($_) {
44 | printf("Set index 0 elements value to 3.");
45 | });
46 | $redis->lRange('t_list')->then(function ($value) {
47 | printf("In the end,the results should be: %s", implode(',', $value));
48 |
49 | });
50 |
51 | $redis->end();
52 | });
53 |
54 | $redis->on('stop', function () use ($loop) {
55 | $loop->stop();
56 | });
57 |
58 | $loop->onStart(function () use ($redis) {
59 | $redis->start();
60 | });
61 |
62 | $loop->start();
--------------------------------------------------------------------------------
/example/set_example.php:
--------------------------------------------------------------------------------
1 | on('start', function (Redis $redis) {
18 | $redis->flushDb();
19 |
20 | $redis->sAdd('t_set', 1, 2, 3, 4, 5)->then(function ($value) {
21 | printf("Add %d elements to set\n", $value);
22 | });
23 |
24 | $redis->sMembers('t_set')->then(function ($value) {
25 | printf("All elements are: %s\n", implode(',', $value));
26 | });
27 |
28 | $redis->sAdd('t_a_set', 4, 5, 6, 7, 8, 9)->then(function ($value) {
29 | printf("Then add %d elements to another set\n", $value);
30 | });
31 |
32 | $redis->sMembers('t_a_set')->then(function ($value) {
33 | printf("All elements are: %s\n", implode(',', $value));
34 | });
35 |
36 | $redis->sDiff('t_set', 't_a_set')->then(function ($value) {
37 | printf("Difference set [t_set - t_a_set] is: %s\n", implode(',', $value));
38 | });
39 |
40 | $redis->sUnion('t_set', 't_a_set')->then(function ($value) {
41 | printf("Intersection [t_set %s t_a_set] is: %s\n", "\u{2229}" ,implode(',', $value));
42 | });
43 |
44 | $redis->sMove('t_set', 't_a_set', 1)->then(function ($value) use ($redis) {
45 | printf("Move %d elements from t_set to t_a_set\n", $value);
46 | });
47 |
48 | $redis->sCard('t_set')->then(function ($value) use ($redis) {
49 | printf("Now t_set has %d elements,", $value);
50 | });
51 |
52 | $redis->sCard('t_a_set')->then(function ($value) use ($redis) {
53 | printf("t_set has %d elements\n", $value);
54 | });
55 |
56 | $redis->sRem('t_set', 2)->then(function ($value) {
57 | printf("Remove %d element from t_set and it is %s\n", $value, '"2"');
58 | });
59 |
60 | $redis->sIsMember('test', 2)->then(function ($value) {
61 | printf("In the end %s %s exist in t_set too\n", '"2"', $value ? 'is' : 'is not');
62 | });
63 |
64 | //And more than those commands that you could use...
65 | $redis->end();
66 | });
67 |
68 | //stop global loop cauz that loop run for only one component(redis)
69 | //if use more than one dazzle component,do not use like that
70 | $redis->on('stop', function () use ($loop) {
71 | $loop->stop();
72 | });
73 |
74 | $redis->on('error', function (Exception $e) use ($redis) {
75 | echo $e->getMessage().PHP_EOL;
76 | $redis->stop();
77 | });
78 |
79 | $loop->onStart(function () use ($redis) {
80 | $redis->start();
81 | });
82 |
83 | $loop->start();
--------------------------------------------------------------------------------
/example/transaction_example.php:
--------------------------------------------------------------------------------
1 | on('start', function (Redis $redis) {
14 | $redis->multi()->then(function ($value) {
15 | printf("Transactions start %s\n", $value);
16 | });
17 | //declare transactions
18 | $redis->set('1', 1);
19 | $redis->get('1');
20 | //execute transactions
21 | $redis->exec()->then(function ($value) {
22 | printf("Transactions executed results: %s\n", implode(',', $value));
23 | });
24 |
25 | $redis->end();
26 | });
27 |
28 | $redis->on('stop', function () use ($loop) {
29 | $loop->stop();
30 | });
31 |
32 | $loop->onStart(function () use ($redis) {
33 | $redis->start();
34 | });
35 |
36 | $loop->start();
--------------------------------------------------------------------------------
/phpunit.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
19 |
20 | test/TModule
21 |
22 |
23 |
24 | test/TUnit
25 |
26 |
27 |
28 |
29 |
30 | src
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/src/Redis/Command/Api/ApiChannelInterface.php:
--------------------------------------------------------------------------------
1 | dispatch(Builder::build($command, $args));
28 | }
29 |
30 | /**
31 | * @override
32 | * @inheritDoc
33 | */
34 | public function pubSub($command, array $args = [])
35 | {
36 | // TODO: Implement pubSub() method.
37 | $command = Enum::PUBSUB;
38 |
39 | return $this->dispatch(Builder::build($command, $args));
40 | }
41 |
42 | /**
43 | * @override
44 | * @inheritDoc
45 | */
46 | public function publish($channel, $message)
47 | {
48 | // TODO: Implement publish() method.
49 | $command = Enum::PUBLISH;
50 | $args = [$channel, $message];
51 |
52 | return $this->dispatch(Builder::build($command, $args));
53 | }
54 |
55 | /**
56 | * @override
57 | * @inheritDoc
58 | */
59 | public function pUnsubscribe(...$patterns)
60 | {
61 | // TODO: Implement pUnsubscribe() method.
62 | $command = Enum::PUNSUBSCRIBE;
63 | $args = $patterns;
64 |
65 | return $this->dispatch(Builder::build($command, $args));
66 | }
67 |
68 | /**
69 | * @override
70 | * @inheritDoc
71 | */
72 | public function unSubscribe(...$channels)
73 | {
74 | // TODO: Implement unSubscribe() method.
75 | $command = Enum::UNSUBSCRIBE;
76 | $args = $channels;
77 |
78 | return $this->dispatch(Builder::build($command, $args));
79 | }
80 |
81 | /**
82 | * @override
83 | * @inheritDoc
84 | */
85 | public function subscribe(...$channels)
86 | {
87 | // TODO: Implement subscribe() method.
88 | $command = Enum::SUBSCRIBE;
89 | $args = $channels;
90 |
91 | return $this->dispatch(Builder::build($command, $args));
92 | }
93 | }
--------------------------------------------------------------------------------
/src/Redis/Command/Compose/ApiClusterTrait.php:
--------------------------------------------------------------------------------
1 | dispatch(Builder::build($command, $args));
28 | }
29 |
30 | /**
31 | * @override
32 | * @inheritDoc
33 | */
34 | public function clusterCountFailureReports($nodeId)
35 | {
36 | // TODO: Implement clusterCountFailureReports() method.
37 | $command = Enum::CLUSTER_COUNT_FAILURE_REPORTS;
38 | $args = [$nodeId];
39 |
40 | return $this->dispatch(Builder::build($command, $args));
41 | }
42 |
43 | /**
44 | * @override
45 | * @inheritDoc
46 | */
47 | public function clusterCountKeysInSlot($slot)
48 | {
49 | // TODO: Implement clusterCountKeysInSlot() method.
50 | $command = Enum::CLUSTER_COUNTKEYSINSLOT;
51 | $args = $slot;
52 |
53 | return $this->dispatch(Builder::build($command, $args));
54 | }
55 |
56 | /**
57 | * @override
58 | * @inheritDoc
59 | */
60 | public function clusterDelSlots(...$slots)
61 | {
62 | // TODO: Implement clusterDelSlots() method.
63 | $command = Enum::CLUSTER_DELSLOTS;
64 | $args = $slots;
65 |
66 | return $this->dispatch(Builder::build($command, $args));
67 | }
68 |
69 | /**
70 | * @override
71 | * @inheritDoc
72 | */
73 | public function clusterFailOver($operation)
74 | {
75 | // TODO: Implement clusterFailOver() method.
76 | }
77 |
78 | /**
79 | * @override
80 | * @inheritDoc
81 | */
82 | public function clusterForget($nodeId)
83 | {
84 | // TODO: Implement clusterForget() method.
85 | }
86 |
87 | /**
88 | * @override
89 | * @inheritDoc
90 | */
91 | public function clusterGetKeyInSlot($slot, $count)
92 | {
93 | // TODO: Implement clusterGetKeyInSlot() method.
94 | }
95 |
96 | /**
97 | * @override
98 | * @inheritDoc
99 | */
100 | public function clusterInfo()
101 | {
102 | // TODO: Implement clusterInfo() method.
103 | $command = Enum::CLUSTER_INFO;
104 |
105 | return $this->dispatch(Builder::build($command));
106 | }
107 |
108 | /**
109 | * @override
110 | * @inheritDoc
111 | */
112 | public function clusterKeySlot($key)
113 | {
114 | // TODO: Implement clusterKeySlot() method.
115 | $command = Enum::CLUSTER_KEYSLOT;
116 | $args = [$key];
117 |
118 | return $this->dispatch(Builder::build($command, $args));
119 | }
120 |
121 | /**
122 | * @override
123 | * @inheritDoc
124 | */
125 | public function clusterMeet($ip, $port)
126 | {
127 | // TODO: Implement clusterMeet() method.
128 | $command = Enum::CLUSTER_MEET;
129 | $args = [$ip, $port];
130 |
131 | return $this->dispatch(Builder::build($command, $args));
132 | }
133 |
134 | /**
135 | * @override
136 | * @inheritDoc
137 | */
138 | public function clusterNodes()
139 | {
140 | // TODO: Implement clusterNodes() method.
141 | }
142 |
143 | /**
144 | * @override
145 | * @inheritDoc
146 | */
147 | public function clusterReplicate($nodeId)
148 | {
149 | // TODO: Implement clusterReplicate() method.
150 | }
151 |
152 | /**
153 | * @override
154 | * @inheritDoc
155 | */
156 | public function clusterReset($mode)
157 | {
158 | // TODO: Implement clusterReset() method.
159 | }
160 |
161 | /**
162 | * @override
163 | * @inheritDoc
164 | */
165 | public function clusterSaveConfig()
166 | {
167 | // TODO: Implement clusterSaveConfig() method.
168 | }
169 |
170 | /**
171 | * @override
172 | * @inheritDoc
173 | */
174 | public function clusterSetConfigEpoch($configEpoch)
175 | {
176 | // TODO: Implement clusterSetConfigEpoch() method.
177 | }
178 |
179 | /**
180 | * @inheritDoc
181 | */
182 | public function clusterSetSlot($command, $nodeId)
183 | {
184 | // TODO: Implement clusterSetSlot() method.
185 | $command = Enum::CLUSTER_SETSLOT;
186 | $args = [$command, $nodeId];
187 |
188 | return $this->dispatch(Builder::build($command, $args));
189 | }
190 |
191 | /**
192 | * @override
193 | * @inheritDoc
194 | */
195 | public function clusterSlaves($nodeId)
196 | {
197 | // TODO: Implement clusterSlaves() method.
198 | $command = Enum::CLUSTER_SLAVES;
199 | $args = [$nodeId];
200 |
201 | return $this->dispatch(Builder::build($command, $args));
202 | }
203 |
204 | /**
205 | * @override
206 | * @inheritDoc
207 | */
208 | public function clusterSlots()
209 | {
210 | // TODO: Implement clusterSlots() method.
211 | $command = Enum::CLUSTER_SLOTS;
212 |
213 | return $this->dispatch(Builder::build($command));
214 | }
215 |
216 | /**
217 | * @override
218 | * @inheritDoc
219 | */
220 | public function readOnly()
221 | {
222 | // TODO: Implement readOnly() method.
223 | $command = Enum::READONLY;
224 |
225 | return $this->dispatch(Builder::build($command));
226 | }
227 |
228 | /**
229 | * @override
230 | * @inheritDoc
231 | */
232 | public function readWrite()
233 | {
234 | // TODO: Implement readWrite() method.
235 | $command = Enum::READWRITE;
236 |
237 | return $this->dispatch(Builder::build($command));
238 | }
239 | }
--------------------------------------------------------------------------------
/src/Redis/Command/Compose/ApiConnTrait.php:
--------------------------------------------------------------------------------
1 | dispatch(Builder::build($command, $args));
27 | }
28 |
29 | /**
30 | * @override
31 | * @inheritDoc
32 | */
33 | public function ping($message = 'PING')
34 | {
35 | $command = Enum::PING;
36 | $args = [$message];
37 |
38 | return $this->dispatch(Builder::build($command, $args));
39 | }
40 |
41 | /**
42 | * @override
43 | * @inheritDoc
44 | */
45 | public function quit()
46 | {
47 | $command = Enum::QUIT;
48 |
49 | return $this->dispatch(Builder::build($command));
50 | }
51 |
52 | /**
53 | * @override
54 | * @inheritDoc
55 | */
56 | public function select($index)
57 | {
58 | $command = Enum::SELECT;
59 | $args = [$index];
60 |
61 | return $this->dispatch(Builder::build($command, $args));
62 | }
63 |
64 | /**
65 | * @override
66 | * @inheritDoc
67 | */
68 | public function swapBb($opt, $dst)
69 | {
70 | $command = Enum::SWAPDB;
71 | $args = [$opt, $dst];
72 |
73 | return $this->dispatch(Builder::build($command, $args));
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/src/Redis/Command/Compose/ApiCoreTrait.php:
--------------------------------------------------------------------------------
1 | dispatch(Builder::build($command));
26 | }
27 |
28 | /**
29 | * @override
30 | * @inheritDoc
31 | */
32 | public function bgSave()
33 | {
34 | $command = Enum::BGSAVE;
35 |
36 | return $this->dispatch(Builder::build($command));
37 | }
38 |
39 | /**
40 | * @override
41 | * @inheritDoc
42 | */
43 | public function sync()
44 | {
45 | $command = Enum::SYNC;
46 |
47 | return $this->dispatch(Builder::build($command));
48 | }
49 |
50 | /**
51 | * @override
52 | * @inheritDoc
53 | */
54 | public function time()
55 | {
56 | $command = Enum::TIME;
57 |
58 | return $this->dispatch(Builder::build($command));
59 | }
60 |
61 | /**
62 | * @override
63 | * @inheritDoc
64 | */
65 | public function monitor()
66 | {
67 | $command = Enum::MONITOR;
68 |
69 | return $this->dispatch(Builder::build($command));
70 | }
71 |
72 | /**
73 | * @override
74 | * @inheritDoc
75 | */
76 | public function flushAll()
77 | {
78 | $command = Enum::FLUSHALL;
79 |
80 | return $this->dispatch(Builder::build($command));
81 | }
82 |
83 | /**
84 | * @override
85 | * @inheritDoc
86 | */
87 | public function flushDb()
88 | {
89 | $command = Enum::FLUSHDB;
90 |
91 | return $this->dispatch(Builder::build($command));
92 | }
93 |
94 | /**
95 | * @override
96 | * @inheritDoc
97 | */
98 | public function info($section = [])
99 | {
100 | $command = Enum::INFO;
101 |
102 | return $this->dispatch(Builder::build($command, $section))->then(function ($value) {
103 | if ($value) {
104 | $ret = explode("\r\n", $value);
105 | $handled = [];
106 | $lastKey = '';
107 |
108 | foreach ($ret as $_ => $v)
109 | {
110 | if (($pos = strpos($v, '#')) !== false)
111 | {
112 | $lastKey = strtolower(substr($v,$pos+2));
113 | $handled[$lastKey] = [];
114 | continue;
115 | }
116 | if ($v === '') {
117 | continue;
118 | }
119 | if (($statMap = explode(':', $v)) && $statMap[0] && $statMap[1])
120 | {
121 | list($name, $stat) = explode(':', $v);
122 | $handled[$lastKey][$name] = $stat;
123 | }
124 | }
125 |
126 | return $handled;
127 | }
128 |
129 | return $value;
130 | });
131 | }
132 |
133 | /**
134 | * @override
135 | * @inheritDoc
136 | */
137 | public function slaveOf($host, $port)
138 | {
139 | $command = Enum::SLAVEOF;
140 | $args = [$host, $port];
141 |
142 | return $this->dispatch(Builder::build($command, $args));
143 | }
144 |
145 | /**
146 | * @override
147 | * @inheritDoc
148 | */
149 | public function slowLog($subCommand, array $args = [])
150 | {
151 | $command = Enum::SLOWLOG;
152 | $args = array_merge([$subCommand],$args);
153 |
154 | return $this->dispatch(Builder::build($command, $args));
155 | }
156 |
157 | /**
158 | * @override
159 | * @inheritDoc
160 | */
161 | public function save()
162 | {
163 | $command = Enum::SAVE;
164 |
165 | return $this->dispatch(Builder::build($command));
166 | }
167 | }
168 |
--------------------------------------------------------------------------------
/src/Redis/Command/Compose/ApiGeospatialTrait.php:
--------------------------------------------------------------------------------
1 | dispatch(Builder::build($command, $args));
29 | }
30 |
31 | /**
32 | * @override
33 | * @inheritDoc
34 | */
35 | public function geoHash($key, ...$members)
36 | {
37 | // TODO: Implement geoHash() method.
38 | $command = Enum::GEOHASH;
39 | }
40 |
41 | /**
42 | * @override
43 | * @inheritDoc
44 | */
45 | public function geoPos($key, ...$members)
46 | {
47 | // TODO: Implement geoPos() method.
48 | $command = Enum::GEOPOS;
49 | $args = [$key];
50 | $args = array_merge($args, $members);
51 |
52 | return $this->dispatch(Builder::build($command, $args));
53 | }
54 |
55 | /**
56 | * @override
57 | * @inheritDoc
58 | */
59 | public function geoDist($key, $memberA, $memberB, $unit)
60 | {
61 | // TODO: Implement geoDist() method.
62 | $command = Enum::GEODIST;
63 | $args = [$key, $memberA, $memberB ,$unit];
64 |
65 | return $this->dispatch(Builder::build($command, $args));
66 | }
67 |
68 | /**
69 | * @override
70 | * @inheritDoc
71 | */
72 | public function geoRadius($key, $longitude, $latitude, $unit, $command, $count, $sort)
73 | {
74 | // TODO: Implement geoRadius() method.
75 | $command = Enum::GEORADIUS;
76 | $args = [$key, $longitude, $latitude, $unit, $command, $count, $sort];
77 |
78 | return $this->dispatch(Builder::build($command, $args));
79 | }
80 |
81 | /**
82 | * @override
83 | * @inheritDoc
84 | */
85 | public function geoRadiusByMember($key, $member, $unit, $command, $count, $sort, $store, $storeDist)
86 | {
87 | // TODO: Implement geoRadiusByMember() method.
88 | $command = Enum::GEORADIUSBYMEMBER;
89 | $args = [$key, $member, $unit, $command, $count, $sort, $store, $storeDist];
90 |
91 | return $this->dispatch(Builder::build($command, $args));
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/src/Redis/Command/Compose/ApiHyperLogTrait.php:
--------------------------------------------------------------------------------
1 | dispatch(Builder::build($command, $args));
28 | }
29 |
30 | /**
31 | * @override
32 | * @inheritDoc
33 | */
34 | public function pFCount(...$keys)
35 | {
36 | $command = Enum::PFCOUNT;
37 | $args = $keys;
38 |
39 | return $this->dispatch(Builder::build($command, $args));
40 | }
41 |
42 | /**
43 | * @override
44 | * @inheritDoc
45 | */
46 | public function pFMerge($dstKey, ...$srcKeys)
47 | {
48 | $command = Enum::PFMERGE;
49 | $args = array_merge([$dstKey], $srcKeys);
50 |
51 | return $this->dispatch(Builder::build($command, $args));
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/Redis/Command/Compose/ApiKeyValTrait.php:
--------------------------------------------------------------------------------
1 | dispatch(Builder::build($command, $args));
27 | }
28 |
29 | /**
30 | * @override
31 | * @inheritDoc
32 | */
33 | public function bitCount($key, $start = 0, $end = -1)
34 | {
35 | $command = Enum::BITCOUNT;
36 | $args = [$key, $start, $end];
37 |
38 | return $this->dispatch(Builder::build($command, $args));
39 | }
40 |
41 | /**
42 | * @override
43 | * @inheritDoc
44 | */
45 | public function bitField($key, $subCommand, ...$param)
46 | {
47 | $command = Enum::BITFIELD;
48 | $subCommand = strtoupper($subCommand);
49 | //TODO: control flow improvement
50 | switch ($subCommand) {
51 | case 'GET' : {
52 | @list ($type, $offset) = $param;
53 | $args = [$key, $subCommand, $type, $offset];
54 | break;
55 | }
56 | case 'SET' : {
57 | @list ($type, $offset, $value) = $param;
58 | $args = [$key, $subCommand, $type, $offset, $value];
59 | break;
60 | }
61 | case 'INCRBY' : {
62 | @list ($type, $offset, $increment) = $param;
63 | $args = [$key, $type, $offset, $increment];
64 | break;
65 | }
66 | case 'OVERFLOW' : {
67 | @list ($behavior) = $param;
68 | $args = [$key, $subCommand, $behavior];
69 | break;
70 | }
71 | default : {
72 | $args = [];
73 | break;
74 | }
75 | }
76 |
77 | return $this->dispatch(Builder::build($command, $args));
78 | }
79 |
80 | /**
81 | * @override
82 | * @inheritDoc
83 | */
84 | public function bitOp($operation, $dstKey, $srcKey, ...$keys)
85 | {
86 | $command = Enum::BITOP;
87 | $args = [$operation, $dstKey, $srcKey];
88 | $args = array_merge($args, $keys);
89 |
90 | return $this->dispatch(Builder::build($command, $args));
91 | }
92 |
93 | /**
94 | * @override
95 | * @inheritDoc
96 | */
97 | public function bitPos($key, $bit, $start = 0, $end = -1)
98 | {
99 | $command = Enum::BITPOS;
100 | $args = [$key, $bit, $start, $end];
101 |
102 | return $this->dispatch(Builder::build($command, $args));
103 | }
104 |
105 | /**
106 | * @override
107 | * @inheritDoc
108 | */
109 | public function decr($key)
110 | {
111 | $command = Enum::DECR;
112 | $args = [$key];
113 |
114 | return $this->dispatch(Builder::build($command, $args));
115 | }
116 |
117 | /**
118 | * @override
119 | * @inheritDoc
120 | */
121 | public function decrBy($key, $decrement)
122 | {
123 | $command = Enum::DECRBY;
124 | $args = [$key, $decrement];
125 |
126 | return $this->dispatch(Builder::build($command, $args));
127 | }
128 |
129 | /**
130 | * @override
131 | * @inheritDoc
132 | */
133 | public function get($key)
134 | {
135 | $command = Enum::GET;
136 | $args = [$key];
137 |
138 | return $this->dispatch(Builder::build($command, $args));
139 | }
140 |
141 | /**
142 | * @override
143 | * @inheritDoc
144 | */
145 | public function getBit($key, $offset)
146 | {
147 | $command = Enum::GETBIT;
148 | $args = [$key, $offset];
149 |
150 | return $this->dispatch(Builder::build($command, $args));
151 | }
152 |
153 | /**
154 | * @override
155 | * @inheritDoc
156 | */
157 | public function getRange($key, $start, $end)
158 | {
159 | $command = Enum::GETRANGE;
160 | $args = [$key, $start, $end];
161 |
162 | return $this->dispatch(Builder::build($command, $args));
163 | }
164 |
165 | /**
166 | * @override
167 | * @inheritDoc
168 | */
169 | public function getSet($key, $value)
170 | {
171 | $command = Enum::GETSET;
172 | $args = [$key, $value];
173 |
174 | return $this->dispatch(Builder::build($command, $args));
175 | }
176 |
177 | /**
178 | * @override
179 | * @inheritDoc
180 | */
181 | public function incr($key)
182 | {
183 | $command = Enum::INCR;
184 | $args = [$key];
185 |
186 | return $this->dispatch(Builder::build($command, $args));
187 | }
188 |
189 | /**
190 | * @override
191 | * @inheritDoc
192 | */
193 | public function incrBy($key, $increment)
194 | {
195 | $command = Enum::INCRBY;
196 | $args = [$key, $increment];
197 |
198 | return $this->dispatch(Builder::build($command, $args));
199 | }
200 |
201 | /**
202 | * @override
203 | * @inheritDoc
204 | */
205 | public function incrByFloat($key, $increment)
206 | {
207 | $command = Enum::INCRBYFLOAT;
208 | $args = [$key, $increment];
209 |
210 | return $this->dispatch(Builder::build($command, $args));
211 | }
212 |
213 | /**
214 | * @override
215 | * @inheritDoc
216 | */
217 | public function set($key, $value, array $options = [])
218 | {
219 | $command = Enum::SET;
220 | array_unshift($options, $key, $value);
221 | $args = $options;
222 |
223 | return $this->dispatch(Builder::build($command, $args));
224 | }
225 |
226 | /**
227 | * @override
228 | * @inheritDoc
229 | */
230 | public function setBit($key, $offset, $value)
231 | {
232 | $command = Enum::SETBIT;
233 | $args = [$key, $offset, $value];
234 |
235 | return $this->dispatch(Builder::build($command, $args));
236 | }
237 |
238 | /**
239 | * @override
240 | * @inheritDoc
241 | */
242 | public function setEx($key, $seconds, $value)
243 | {
244 | $command = Enum::SETEX;
245 | $args = [$key, $seconds, $value];
246 |
247 | return $this->dispatch(Builder::build($command, $args));
248 | }
249 |
250 | /**
251 | * @override
252 | * @inheritDoc
253 | */
254 | public function setNx($key, $value)
255 | {
256 | $command = Enum::SETNX;
257 | $args = [$key, $value];
258 |
259 | return $this->dispatch(Builder::build($command, $args));
260 | }
261 |
262 | /**
263 | * @override
264 | * @inheritDoc
265 | */
266 | public function setRange($key, $offset, $value)
267 | {
268 | $command = Enum::SETRANGE;
269 | $args = [$key, $offset, $value];
270 |
271 | return $this->dispatch(Builder::build($command, $args));
272 | }
273 |
274 | /**
275 | * @override
276 | * @inheritDoc
277 | */
278 | public function pSetEx($key, $milliseconds, $value)
279 | {
280 | $command = Enum::PSETEX;
281 | $args = [$key, $milliseconds, $value];
282 |
283 | return $this->dispatch(Builder::build($command, $args));
284 | }
285 |
286 | /**
287 | * @override
288 | * @inheritDoc
289 | */
290 | public function mGet($key, ...$keys)
291 | {
292 | $command = Enum::MGET;
293 | $args = [$key];
294 | $args = array_merge($args, $keys);
295 |
296 | return $this->dispatch(Builder::build($command, $args));
297 | }
298 |
299 | /**
300 | * @override
301 | * @inheritDoc
302 | */
303 | public function mSet(array $kvMap)
304 | {
305 | //TODO: change the param $kvMap to ...$kv,cauz map not allow duplicate key
306 | $command = Enum::MSET;
307 | $args = [];
308 | if (!empty($kvMap)) {
309 | foreach ($kvMap as $key => $val) {
310 | $args[] = $key;
311 | $args[] = $val;
312 | }
313 | }
314 |
315 | return $this->dispatch(Builder::build($command, $args));
316 | }
317 |
318 | /**
319 | * @override
320 | * @inheritDoc
321 | */
322 | public function mSetNx($kvMap)
323 | {
324 | $command = Enum::MSETNX;
325 | $args = [];
326 | if (!empty($kvMap)) {
327 | foreach ($kvMap as $key => $val) {
328 | $args[] = $key;
329 | $args[] = $val;
330 | }
331 | }
332 |
333 | return $this->dispatch(Builder::build($command, $args));
334 | }
335 |
336 | /**
337 | * @override
338 | * @inheritDoc
339 | */
340 | public function strLen($key)
341 | {
342 | $command = Enum::STRLEN;
343 | $args = [$key];
344 |
345 | return $this->dispatch(Builder::build($command, $args));
346 | }
347 |
348 | /**
349 | * @override
350 | * @inheritDoc
351 | */
352 | public function del($key,...$keys)
353 | {
354 | $command = Enum::DEL;
355 | $keys[] = $key;
356 | $args = $keys;
357 |
358 | return $this->dispatch(Builder::build($command, $args));
359 | }
360 |
361 | /**
362 | * @override
363 | * @inheritDoc
364 | */
365 | public function dump($key)
366 | {
367 | $command = Enum::DUMP;
368 | $args = [$key];
369 |
370 | return $this->dispatch(Builder::build($command, $args));
371 | }
372 |
373 | /**
374 | * @override
375 | * @inheritDoc
376 | */
377 | public function exists($key, ...$keys)
378 | {
379 | $command = Enum::EXISTS;
380 | $args = [$key];
381 | $args = array_merge($args, $keys);
382 |
383 | return $this->dispatch(Builder::build($command, $args));
384 | }
385 |
386 | /**
387 | * @override
388 | * @inheritDoc
389 | */
390 | public function expire($key, $seconds)
391 | {
392 | $command = Enum::EXPIRE;
393 | $args = [$key, $seconds];
394 |
395 | return $this->dispatch(Builder::build($command, $args));
396 | }
397 |
398 | /**
399 | * @override
400 | * @inheritDoc
401 | */
402 | public function expireAt($key, $timestamp)
403 | {
404 | $command = Enum::EXPIREAT;
405 | $args = [$key, $timestamp];
406 |
407 | return $this->dispatch(Builder::build($command, $args));
408 | }
409 |
410 | /**
411 | * @override
412 | * @inheritDoc
413 | */
414 | public function persist($key)
415 | {
416 | $command = Enum::PERSIST;
417 | $args = [$key];
418 |
419 | return $this->dispatch(Builder::build($command, $args));
420 | }
421 |
422 | /**
423 | * @override
424 | * @inheritDoc
425 | */
426 | public function pExpire($key, $milliseconds)
427 | {
428 | $command = Enum::PEXPIRE;
429 | $args = [$key, $milliseconds];
430 |
431 | return $this->dispatch(Builder::build($command, $args));
432 | }
433 |
434 | /**
435 | * @override
436 | * @inheritDoc
437 | */
438 | public function pExpireAt($key, $milTimestamp)
439 | {
440 | $command = Enum::PEXPIREAT;
441 | $args = [$key, $milTimestamp];
442 |
443 | return $this->dispatch(Builder::build($command, $args));
444 | }
445 |
446 | /**
447 | * @override
448 | * @inheritDoc
449 | */
450 | public function touch($key, ...$keys)
451 | {
452 | $command = Enum::TOUCH;
453 | $args = [$key];
454 | $args = array_merge($args, $keys);
455 |
456 | return $this->dispatch(Builder::build($command, $args));
457 | }
458 |
459 | /**
460 | * @override
461 | * @inheritDoc
462 | */
463 | public function ttl($key)
464 | {
465 | $command = Enum::TTL;
466 | $args = [$key];
467 |
468 | return $this->dispatch(Builder::build($command, $args));
469 | }
470 |
471 | /**
472 | * @override
473 | * @inheritDoc
474 | */
475 | public function type($key)
476 | {
477 | $command = Enum::TYPE;
478 | $args = [$key];
479 |
480 | return $this->dispatch(Builder::build($command, $args));
481 | }
482 |
483 | /**
484 | * @override
485 | * @inheritDoc
486 | */
487 | public function unLink($key, ...$keys)
488 | {
489 | $command = Enum::UNLINK;
490 | $args = [$key];
491 | $args = array_merge($args, $keys);
492 |
493 | return $this->dispatch(Builder::build($command, $args));
494 | }
495 |
496 | /**
497 | * @override
498 | * @inheritDoc
499 | */
500 | public function wait($numSlaves, $timeout)
501 | {
502 | $command = Enum::WAIT;
503 | $args = [$numSlaves, $timeout];
504 |
505 | return $this->dispatch(Builder::build($command, $args));
506 | }
507 |
508 | /**
509 | * @override
510 | * @inheritDoc
511 | */
512 | public function randomKey()
513 | {
514 | $command = Enum::RANDOMKEY;
515 |
516 | return $this->dispatch(Builder::build($command));
517 | }
518 |
519 | /**
520 | * @override
521 | * @inheritDoc
522 | */
523 | public function rename($key, $newKey)
524 | {
525 | $command = Enum::RENAME;
526 | $args = [$key, $newKey];
527 |
528 | return $this->dispatch(Builder::build($command, $args));
529 | }
530 |
531 | /**
532 | * @override
533 | * @inheritDoc
534 | */
535 | public function renameNx($key, $newKey)
536 | {
537 | $command = Enum::RENAMENX;
538 | $args = [$key, $newKey];
539 |
540 | return $this->dispatch(Builder::build($command, $args));
541 | }
542 |
543 | /**
544 | * @override
545 | * @inheritDoc
546 | */
547 | public function restore($key, $ttl, $value)
548 | {
549 | $command = Enum::RESTORE;
550 | $args = [$key, $ttl, $value];
551 |
552 | return $this->dispatch(Builder::build($command, $args));
553 | }
554 |
555 | /**
556 | * @override
557 | * @inheritDoc
558 | */
559 | public function pTtl($key)
560 | {
561 | $command = Enum::PTTL;
562 | $args = [$key];
563 |
564 | return $this->dispatch(Builder::build($command, $args));
565 | }
566 |
567 | /**
568 | * @override
569 | * @inheritDoc
570 | */
571 | public function move($key, $db)
572 | {
573 | $command = Enum::MOVE;
574 | $args = [$key, $db];
575 |
576 | return $this->dispatch(Builder::build($command, $args));
577 | }
578 |
579 | /**
580 | * @override
581 | * @inheritDoc
582 | */
583 | public function scan($cursor, array $options = [])
584 | {
585 | $command = Enum::SCAN;
586 | $args = [$cursor];
587 | $args = array_merge($args, $options);
588 |
589 | return $this->dispatch(Builder::build($command, $args));
590 | }
591 |
592 | /**
593 | * @override
594 | * @inheritDoc
595 | */
596 | public function sort($key, array $options = [])
597 | {
598 | $command = Enum::SORT;
599 | $args = [$key];
600 | $args = array_merge($args, $options);
601 |
602 | return $this->dispatch(Builder::build($command, $args));
603 | }
604 |
605 | /**
606 | * @override
607 | * @inheritDoc
608 | */
609 | public function keys($key = '*')
610 | {
611 | $command = Enum::KEYS;
612 | $args = [$key];
613 |
614 | return $this->dispatch(Builder::build($command, $args));
615 | }
616 | }
617 |
--------------------------------------------------------------------------------
/src/Redis/Command/Compose/ApiListTrait.php:
--------------------------------------------------------------------------------
1 | dispatch(Builder::build($command, $args));
27 | $promise = $promise->then(function ($value) {
28 | if (is_array($value)) {
29 | list($k,$v) = $value;
30 |
31 | return [
32 | 'key'=>$k,
33 | 'value'=>$v
34 | ];
35 | }
36 |
37 | return $value;
38 | });
39 |
40 | return $promise;
41 | }
42 |
43 | /**
44 | * @override
45 | * @inheritDoc
46 | */
47 | public function brPop(array $keys, $timeout)
48 | {
49 | $command = Enum::BRPOP;
50 | $keys[] = $timeout;
51 | $args = $keys;
52 | $promise = $this->dispatch(Builder::build($command, $args));
53 | $promise = $promise->then(function ($value) {
54 | if (is_array($value)) {
55 | list($k,$v) = $value;
56 |
57 | return [
58 | 'key'=>$k,
59 | 'value'=>$v
60 | ];
61 | }
62 |
63 | return $value;
64 | });
65 |
66 | return $promise;
67 | }
68 |
69 | /**
70 | * @override
71 | * @inheritDoc
72 | */
73 | public function brPopLPush($src, $dst, $timeout)
74 | {
75 | $command = Enum::BRPOPLPUSH;
76 | $args = [$src, $dst, $timeout];
77 |
78 | return $this->dispatch(Builder::build($command, $args));
79 | }
80 |
81 | /**
82 | * @override
83 | * @inheritDoc
84 | */
85 | public function lIndex($key, $index)
86 | {
87 | $command = Enum::LINDEX;
88 | $args = [$key, $index];
89 |
90 | return $this->dispatch(Builder::build($command, $args));
91 | }
92 |
93 | /**
94 | * @override
95 | * @inheritDoc
96 | */
97 | public function lInsert($key, $action, $pivot, $value)
98 | {
99 | $command = Enum::LINSERT;
100 | $args = [$key, $action, $pivot, $value];
101 |
102 | return $this->dispatch(Builder::build($command, $args));
103 | }
104 |
105 | /**
106 | * @override
107 | * @inheritDoc
108 | */
109 | public function lLen($key)
110 | {
111 | $command = Enum::LLEN;
112 | $args = [$key];
113 |
114 | return $this->dispatch(Builder::build($command, $args));
115 | }
116 |
117 | /**
118 | * @override
119 | * @inheritDoc
120 | */
121 | public function lPop($key)
122 | {
123 | $command = Enum::LPOP;
124 | $args = [$key];
125 |
126 | return $this->dispatch(Builder::build($command, $args));
127 | }
128 |
129 | /**
130 | * @override
131 | * @inheritDoc
132 | */
133 | public function lPush($key,...$values)
134 | {
135 | $command = Enum::LPUSH;
136 | array_unshift($values, $key);
137 |
138 | return $this->dispatch(Builder::build($command, $values));
139 | }
140 |
141 | public function lPushX($key, $value)
142 | {
143 | $command = Enum::LPUSHX;
144 | $args = [$key, $value];
145 |
146 | return $this->dispatch(Builder::build($command, $args));
147 | }
148 |
149 | /**
150 | * @override
151 | * @inheritDoc
152 | */
153 | public function lRange($key, $start = 0, $stop = -1)
154 | {
155 | $command = Enum::LRANGE;
156 | $args = [$key, $start, $stop];
157 |
158 | return $this->dispatch(Builder::build($command, $args));
159 | }
160 |
161 | /**
162 | * @override
163 | * @inheritDoc
164 | */
165 | public function lRem($key, $count, $value)
166 | {
167 | $command = Enum::LREM;
168 | $args = [$key, $count, $value];
169 |
170 | return $this->dispatch(Builder::build($command, $args));
171 | }
172 |
173 | /**
174 | * @override
175 | * @inheritDoc
176 | */
177 | public function lSet($key, $index, $value)
178 | {
179 | $command = Enum::LSET;
180 | $args = [$key, $index, $value];
181 |
182 | return $this->dispatch(Builder::build($command, $args));
183 | }
184 |
185 | /**
186 | * @override
187 | * @inheritDoc
188 | */
189 | public function lTrim($key, $start, $stop)
190 | {
191 | $command = Enum::LTRIM;
192 | $args = [$key, $start, $stop];
193 |
194 | return $this->dispatch(Builder::build($command, $args));
195 | }
196 |
197 | /**
198 | * @override
199 | * @inheritDoc
200 | */
201 | public function rPop($key)
202 | {
203 | $command = Enum::RPOP;
204 | $args = [$key];
205 |
206 | return $this->dispatch(Builder::build($command, $args));
207 | }
208 |
209 | /**
210 | * @override
211 | * @inheritDoc
212 | */
213 | public function rPopLPush($src, $dst)
214 | {
215 | $command = Enum::RPOPLPUSH;
216 | $args = [$src, $dst];
217 |
218 | return $this->dispatch(Builder::build($command, $args));
219 | }
220 |
221 | /**
222 | * @override
223 | * @inheritDoc
224 | */
225 | public function rPush($key, ...$values)
226 | {
227 | $command = Enum::RPUSH;
228 | $args = [$key];
229 | $args = array_merge($args, $values);
230 |
231 | return $this->dispatch(Builder::build($command, $args));
232 | }
233 |
234 | /**
235 | * @override
236 | * @inheritDoc
237 | */
238 | public function rPushX($key, $value)
239 | {
240 | $command = Enum::RPUSHX;
241 | $args = [$key, $value];
242 |
243 | return $this->dispatch(Builder::build($command, $args));
244 | }
245 | }
246 |
--------------------------------------------------------------------------------
/src/Redis/Command/Compose/ApiSetHashTrait.php:
--------------------------------------------------------------------------------
1 | dispatch(Builder::build($command, $args));
28 | }
29 |
30 | /**
31 | * @override
32 | * @inheritDoc
33 | */
34 | public function hGet($key, $field)
35 | {
36 | $command = Enum::HGET;
37 | $args = [$key, $field];
38 |
39 | return $this->dispatch(Builder::build($command, $args));
40 | }
41 |
42 | /**
43 | * @override
44 | * @inheritDoc
45 | */
46 | public function hGetAll($key)
47 | {
48 | $command = Enum::HGETALL;
49 | $args = [$key];
50 |
51 | return $this->dispatch(Builder::build($command, $args))->then(function ($value) {
52 | if (!empty($value)) {
53 | $tmp = [];
54 | $size = count($value);
55 | for ($i=0; $i<$size; $i+=2) {
56 | $field = $value[$i];
57 | $val = $value[$i+1];
58 | $tmp[$field] = $val;
59 | }
60 | $value = $tmp;
61 | }
62 |
63 | return $value;
64 | });
65 | }
66 |
67 | /**
68 | * @override
69 | * @inheritDoc
70 | */
71 | public function hIncrBy($key, $field, $increment)
72 | {
73 | $command = Enum::HINCRBY;
74 | $args = [$key, $field, $increment];
75 |
76 | return $this->dispatch(Builder::build($command, $args));
77 | }
78 |
79 | /**
80 | * @override
81 | * @inheritDoc
82 | */
83 | public function hIncrByFloat($key, $field, $increment)
84 | {
85 | $command = Enum::HINCRBYFLOAT;
86 | $args = [$key, $field, $increment];
87 |
88 | return $this->dispatch(Builder::build($command, $args));
89 | }
90 |
91 | /**
92 | * @override
93 | * @inheritDoc
94 | */
95 | public function hKeys($key)
96 | {
97 | $command = Enum::HKEYS;
98 | $args = [$key];
99 |
100 | return $this->dispatch(Builder::build($command, $args));
101 | }
102 |
103 | /**
104 | * @override
105 | * @inheritDoc
106 | */
107 | public function hLen($key)
108 | {
109 | $command = Enum::HLEN;
110 | $args = [$key];
111 |
112 | return $this->dispatch(Builder::build($command, $args));
113 | }
114 |
115 | /**
116 | * @override
117 | * @inheritDoc
118 | */
119 | public function hMGet($key, ...$fields)
120 | {
121 | $command = Enum::HMGET;
122 | $args = [$key];
123 | $args = array_merge($args, $fields);
124 |
125 | return $this->dispatch(Builder::build($command, $args));
126 | }
127 |
128 | /**
129 | * @override
130 | * @inheritDoc
131 | */
132 | public function hMSet($key, array $fvMap)
133 | {
134 | //TODO: replace param $fvMap to ...$fvs,cauz hash map not allow duplicate key
135 | $command = Enum::HMSET;
136 | $args = [$key];
137 | if (!empty($fvMap)) {
138 | foreach ($fvMap as $field => $value) {
139 | $tmp[] = $field;
140 | $tmp[] = $value;
141 | }
142 | $fvMap = $tmp;
143 | }
144 | $args = array_merge($args, $fvMap);
145 |
146 | return $this->dispatch(Builder::build($command, $args));
147 | }
148 |
149 | /**
150 | * @override
151 | * @inheritDoc
152 | */
153 | public function hSet($key, $field, $value)
154 | {
155 | $command = Enum::HSET;
156 | $args = [$key, $field, $value];
157 |
158 | return $this->dispatch(Builder::build($command, $args));
159 | }
160 |
161 | /**
162 | * @override
163 | * @inheritDoc
164 | */
165 | public function hSetNx($key, $filed, $value)
166 | {
167 | $command = Enum::HSETNX;
168 | $args = [$key, $filed, $value];
169 |
170 | return $this->dispatch(Builder::build($command, $args));
171 | }
172 |
173 | /**
174 | * @override
175 | * @inheritDoc
176 | */
177 | public function hStrLen($key, $field)
178 | {
179 | $command = Enum::HSTRLEN;
180 | $args = [$key, $field];
181 |
182 | return $this->dispatch(Builder::build($command, $args));
183 | }
184 |
185 | /**
186 | * @override
187 | * @inheritDoc
188 | */
189 | public function hVals($key)
190 | {
191 | $command = Enum::HVALS;
192 | $args = [$key];
193 |
194 | return $this->dispatch(Builder::build($command, $args));
195 | }
196 |
197 | /**
198 | * @override
199 | * @inheritDoc
200 | */
201 | public function hScan($key, $cursor, array $options = [])
202 | {
203 | // TODO: Implement hScan() method.
204 | $command = Enum::HSCAN;
205 | $args = [$key, $cursor];
206 | $args = array_merge($args, $options);
207 |
208 | return $this->dispatch(Builder::build($command, $args));
209 | }
210 |
211 | /**
212 | * @inheritDoc
213 | */
214 | public function hExists($key, $field)
215 | {
216 | $command = Enum::HEXISTS;
217 | $args = [$key, $field];
218 |
219 | return $this->dispatch(Builder::build($command, $args));
220 | }
221 | }
222 |
--------------------------------------------------------------------------------
/src/Redis/Command/Compose/ApiSetSortedTrait.php:
--------------------------------------------------------------------------------
1 | dispatch(Builder::build($command, $args));
27 | }
28 |
29 | /**
30 | * @override
31 | * @inheritDoc
32 | */
33 | public function zCard($key)
34 | {
35 | $command = Enum::ZCARD;
36 | $args = [$key];
37 |
38 | return $this->dispatch(Builder::build($command, $args));
39 | }
40 |
41 | /**
42 | * @override
43 | * @inheritDoc
44 | */
45 | public function zCount($key, $min, $max)
46 | {
47 | $command = Enum::ZCOUNT;
48 | $args = [$key, $min, $max];
49 |
50 | return $this->dispatch(Builder::build($command, $args));
51 | }
52 |
53 | /**
54 | * @override
55 | * @inheritDoc
56 | */
57 | public function zIncrBy($key, $increment, $member)
58 | {
59 | $command = Enum::ZINCRBY;
60 | $args = [$key, $increment, $member];
61 |
62 | return $this->dispatch(Builder::build($command, $args));
63 | }
64 |
65 | /**
66 | * @override
67 | * @inheritDoc
68 | */
69 | public function zInterStore($dst, $numKeys)
70 | {
71 | $command = Enum::ZINTERSTORE;
72 | $args = [$dst, $numKeys];
73 |
74 | return $this->dispatch(Builder::build($command, $args));
75 | }
76 |
77 | /**
78 | * @override
79 | * @inheritDoc
80 | */
81 | public function zLexCount($key, $min, $max)
82 | {
83 | $command = Enum::ZLEXCOUNT;
84 | $args = [$key, $min, $max];
85 |
86 | return $this->dispatch(Builder::build($command, $args));
87 | }
88 |
89 | /**
90 | * @override
91 | * @inheritDoc
92 | */
93 | public function zRange($key, $star = 0, $stop = -1, $withScores = false)
94 | {
95 | $command = Enum::ZRANGE;
96 | $args = [$key, $star, $stop];
97 | if ($withScores) {
98 | $args[] = 'WITHSCORES';
99 | return $this->dispatch(Builder::build($command, $args))->then(function ($value) {
100 | $len = count($value);
101 | $ret = [];
102 | for ($i=0; $i<$len; $i+=2) {
103 | $ret[$value[$i]] = $value[$i+1];
104 | }
105 | return $ret;
106 | });
107 | }
108 |
109 | return $this->dispatch(Builder::build($command, $args));
110 | }
111 |
112 | /**
113 | * @override
114 | * @inheritDoc
115 | */
116 | public function zRangeByLex($key, $min, $max, array $options = [])
117 | {
118 | $command = Enum::ZRANGEBYLEX;
119 | $args = [$key, $min, $max];
120 | $args = array_merge($args, $options);
121 |
122 | return $this->dispatch(Builder::build($command, $args));
123 | }
124 |
125 | /**
126 | * @override
127 | * @inheritDoc
128 | */
129 | public function zRevRangeByLex($key, $max, $min, array $options = [])
130 | {
131 | $command = Enum::ZREVRANGEBYLEX;
132 | $args = [$key, $max,$min];
133 | $args = array_merge($args,$options);
134 |
135 | return $this->dispatch(Builder::build($command, $args));
136 | }
137 |
138 | /**
139 | * @override
140 | * @inheritDoc
141 | */
142 | public function zRangeByScore($key, $min, $max, $withScores = false, $offset = 0, $count = 0)
143 | {
144 | $command = Enum::ZRANGEBYSCORE;
145 | $args = [$key, $min, $max];
146 | if ($withScores === true) {
147 | $args[] = 'WITHSCORES';
148 | }
149 | if ($offset != 0 || $count != 0) {
150 | $args[] = 'LIMIT';
151 | $args[] = $offset;
152 | $args[] = $count;
153 | }
154 | $promise = $this->dispatch(Builder::build($command, $args));
155 |
156 | return $withScores ? $promise->then(function ($value) {
157 | $len = is_array($value) ? count($value) : 0;
158 | if ($len > 0) {
159 | $ret = [];
160 | for ($i=0; $i<$len; $i+=2) {
161 | $ret[$value[$i]] = $value[$i+1];
162 | }
163 |
164 | return $ret;
165 | }
166 |
167 | return $value;
168 | } ) : $promise;
169 | }
170 |
171 | /**
172 | * @override
173 | * @inheritDoc
174 | */
175 | public function zRank($key, $member)
176 | {
177 | $command = Enum::ZRANK;
178 | $args = [$key,$member];
179 |
180 | return $this->dispatch(Builder::build($command, $args));
181 | }
182 |
183 | /**
184 | * @override
185 | * @inheritDoc
186 | */
187 | public function zRem($key, ...$members)
188 | {
189 | $command = Enum::ZREM;
190 | $args = [$key];
191 | $args = array_merge($args, $members);
192 |
193 | return $this->dispatch(Builder::build($command, $args));
194 | }
195 |
196 | /**
197 | * @override
198 | * @inheritDoc
199 | */
200 | public function zRemRangeByLex($key, $min, $max, array $options = [])
201 | {
202 | $command = Enum::ZREMRANGEBYLEX;
203 | $args = [$key, $min, $max];
204 | $args = array_merge($args, $options);
205 |
206 | return $this->dispatch(Builder::build($command, $args));
207 | }
208 |
209 | /**
210 | * @override
211 | * @inheritDoc
212 | */
213 | public function zRemRangeByRank($key, $start, $stop)
214 | {
215 | $command = Enum::ZREMRANGEBYRANK;
216 | $args = [$key, $start,$stop];
217 |
218 | return $this->dispatch(Builder::build($command, $args));
219 | }
220 |
221 | /**
222 | * @override
223 | * @inheritDoc
224 | */
225 | public function zRemRangeByScore($key, $min, $max, array $options = [])
226 | {
227 | $command = Enum::ZREMRANGEBYSCORE;
228 | $args = [$key, $min, $max];
229 | $args = array_merge($args, $options);
230 |
231 | return $this->dispatch(Builder::build($command, $args));
232 | }
233 |
234 | /**
235 | * @override
236 | * @inheritDoc
237 | */
238 | public function zRevRange($key, $start, $stop, $withScores = false)
239 | {
240 | $command = Enum::ZREVRANGE;
241 | $args = [$key, $start, $stop];
242 |
243 | if ($withScores === true) {
244 | $args[] = 'WITHSCORES';
245 |
246 | return $this->dispatch(Builder::build($command, $args))
247 | ->then(function ($value) {
248 | $len = is_array($value) ? count($value) : 0;
249 | if ($len > 0) {
250 | $ret = [];
251 | for ($i=0; $i<$len; $i+=2) {
252 | $member = $value[$i];
253 | $score = $value[$i+1];
254 | $ret[$member] = $score;
255 | }
256 |
257 | return $ret;
258 | }
259 |
260 | return $value;
261 | });
262 | }
263 |
264 | return $promise = $this->dispatch(Builder::build($command, $args));
265 | }
266 |
267 | /**
268 | * @override
269 | * @inheritDoc
270 | */
271 | public function zRevRangeByScore($key, $max, $min, $withScores = false, $offset = 0, $count = 0)
272 | {
273 | $command = Enum::ZREVRANGEBYSCORE;
274 | $args = [$key, $max, $min];
275 | if ($withScores === true) {
276 | $args[] = 'WITHSCORES';
277 | }
278 | if ($offset != 0 || $count != 0) {
279 | $args[] = 'LIMIT';
280 | $args[] = $offset;
281 | $args[] = $count;
282 | }
283 | $promise = $this->dispatch(Builder::build($command, $args));
284 |
285 | return $withScores ? $promise->then(function ($value) {
286 | $len = is_array($value) ? count($value) : 0;
287 | if ($len > 0) {
288 | $ret = [];
289 | for ($i=0; $i<$len; $i+=2) {
290 | $ret[$value[$i]] = $value[$i+1];
291 | }
292 |
293 | return $ret;
294 | }
295 |
296 | return $value;
297 | } ) : $promise;
298 | }
299 |
300 | /**
301 | * @override
302 | * @inheritDoc
303 | */
304 | public function zRevRank($key, $member)
305 | {
306 | $command = Enum::ZREVRANK;
307 | $args = [$key,$member];
308 |
309 | return $this->dispatch(Builder::build($command, $args));
310 | }
311 |
312 | /**
313 | * @override
314 | * @inheritDoc
315 | */
316 | public function zScore($key, $member)
317 | {
318 | $command = Enum::ZSCORE;
319 | $args = [$key,$member];
320 |
321 | return $this->dispatch(Builder::build($command, $args));
322 | }
323 |
324 | /**
325 | * @override
326 | * @inheritDoc
327 | */
328 | public function zScan($key, $cursor, array $options = [])
329 | {
330 | $command = Enum::ZSCAN;
331 | $args = [$key , $cursor];
332 | $args = array_merge($args, $options);
333 |
334 | return $this->dispatch(Builder::build($command, $args));
335 | }
336 |
337 | /**
338 | * @inheritDoc
339 | */
340 | public function zUnionScore($dst, $numKeys)
341 | {
342 | $command = Enum::ZUNIIONSCORE;
343 | $args = [$dst, $numKeys];
344 |
345 | return $this->dispatch(Builder::build($command, $args));
346 | }
347 | }
--------------------------------------------------------------------------------
/src/Redis/Command/Compose/ApiSetTrait.php:
--------------------------------------------------------------------------------
1 | dispatch(Builder::build($command, $args));
28 | }
29 |
30 | /**
31 | * @override
32 | * @inheritDoc
33 | */
34 | public function sInter(...$keys)
35 | {
36 | $command = Enum::SINTER;
37 | $args = $keys;
38 |
39 | return $this->dispatch(Builder::build($command, $args));
40 | }
41 |
42 | /**
43 | * @override
44 | * @inheritDoc
45 | */
46 | public function sInterStore($dst, ...$keys)
47 | {
48 | $command = Enum::SINTERSTORE;
49 | $args = [$dst];
50 | $args = array_merge($args, $keys);
51 |
52 | return $this->dispatch(Builder::build($command, $args));
53 | }
54 |
55 | /**
56 | * @override
57 | * @inheritDoc
58 | */
59 | public function sIsMember($key, $member)
60 | {
61 | $command = Enum::SISMEMBER;
62 | $args = [$key ,$member];
63 |
64 | return $this->dispatch(Builder::build($command, $args));
65 | }
66 |
67 | /**
68 | * @override
69 | * @inheritDoc
70 | */
71 | public function sMembers($key)
72 | {
73 | $command = Enum::SMEMBERS;
74 | $args = [$key];
75 |
76 | return $this->dispatch(Builder::build($command, $args));
77 | }
78 |
79 | /**
80 | * @override
81 | * @inheritDoc
82 | */
83 | public function sMove($src, $dst, $member)
84 | {
85 | $command = Enum::SMOVE;
86 | $args = [$src, $dst, $member];
87 |
88 | return $this->dispatch(Builder::build($command, $args));
89 | }
90 |
91 | /**
92 | * @override
93 | * @inheritDoc
94 | */
95 | public function sPop($key, $count)
96 | {
97 | $command = Enum::SPOP;
98 | $args = [$key, $count];
99 |
100 | return $this->dispatch(Builder::build($command, $args));
101 | }
102 |
103 | /**
104 | * @override
105 | * @inheritDoc
106 | */
107 | public function sRandMember($key, $count)
108 | {
109 | $command = Enum::SRANDMEMBER;
110 | $args = [$key, $count];
111 |
112 | return $this->dispatch(Builder::build($command, $args));
113 | }
114 |
115 | /**
116 | * @override
117 | * @inheritDoc
118 | */
119 | public function sRem($key, ...$members)
120 | {
121 | $command = Enum::SREM;
122 | $args = [$key];
123 | $args = array_merge($args, $members);
124 |
125 | return $this->dispatch(Builder::build($command, $args));
126 | }
127 |
128 | /**
129 | * @override
130 | * @inheritDoc
131 | */
132 | public function sUnion(...$keys)
133 | {
134 | $command = Enum::SUNION;
135 | $args = $keys;
136 |
137 | return $this->dispatch(Builder::build($command, $args));
138 | }
139 |
140 | /**
141 | * @override
142 | * @inheritDoc
143 | */
144 | public function sUnionStore($dst, ...$keys)
145 | {
146 | $command = Enum::SUNIONSTORE;
147 | $args = [$dst];
148 | $args = array_merge($args, $keys);
149 |
150 | return $this->dispatch(Builder::build($command, $args));
151 | }
152 |
153 |
154 | /**
155 | * @override
156 | * @inheritDoc
157 | */
158 | public function sAdd($key, ...$members)
159 | {
160 | $command = Enum::SADD;
161 | $args = [$key];
162 | $args = array_merge($args, $members);
163 |
164 | return $this->dispatch(Builder::build($command, $args));
165 | }
166 |
167 | /**
168 | * @override
169 | * @inheritDoc
170 | */
171 | public function sCard($key)
172 | {
173 | $command = Enum::SCARD;
174 | $args = [$key];
175 |
176 | return $this->dispatch(Builder::build($command, $args));
177 | }
178 |
179 | /**
180 | * @override
181 | * @inheritDoc
182 | */
183 | public function sDiff(...$keys)
184 | {
185 | $command = Enum::SDIFF;
186 | $args = $keys;
187 |
188 | return $this->dispatch(Builder::build($command, $args));
189 | }
190 |
191 | /**
192 | * @override
193 | * @inheritDoc
194 | */
195 | public function sDiffStore($dst, ...$keys)
196 | {
197 | $command = Enum::SDIFFSTORE;
198 | $args = [$dst];
199 | $args = array_merge($args, $keys);
200 |
201 | return $this->dispatch(Builder::build($command, $args));
202 | }
203 | }
204 |
--------------------------------------------------------------------------------
/src/Redis/Command/Compose/ApiTransactionTrait.php:
--------------------------------------------------------------------------------
1 | dispatch(Builder::build($command));
26 | }
27 |
28 | /**
29 | * @override
30 | * @inheritDoc
31 | */
32 | public function exec()
33 | {
34 | $command = Enum::EXEC;
35 |
36 | return $this->dispatch(Builder::build($command));
37 | }
38 |
39 | /**
40 | * @override
41 | * @inheritDoc
42 | */
43 | public function multi()
44 | {
45 | $command = Enum::MULTI;
46 |
47 | return $this->dispatch(Builder::build($command));
48 | }
49 |
50 | /**
51 | * @override
52 | * @inheritDoc
53 | */
54 | public function unWatch()
55 | {
56 | $command = Enum::UNWATCH;
57 |
58 | return $this->dispatch(Builder::build($command));
59 | }
60 |
61 | /**
62 | * @override
63 | * @inheritDoc
64 | */
65 | public function watch($key, ...$keys)
66 | {
67 | $command = Enum::WATCH;
68 | $args = [$key];
69 | $args = array_merge($args, $keys);
70 |
71 | return $this->dispatch(Builder::build($command, $args));
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/src/Redis/Command/Enum.php:
--------------------------------------------------------------------------------
1 | requestParser = new RequestParser();
33 | $this->responseParser = new ResponseParser();
34 | $this->serializer = new RecursiveSerializer();
35 | }
36 |
37 | /**
38 | * @inheritDoc
39 | */
40 | public function commands(Request $request)
41 | {
42 | return $this->serializer->getRequestMessage(
43 | $request->getCommand(),
44 | $request->getArgs()
45 | );
46 | }
47 |
48 | /**
49 | * @return RecursiveSerializer
50 | */
51 | public function getSerializer()
52 | {
53 | return $this->serializer;
54 | }
55 |
56 | /**
57 | * @return RequestParser
58 | */
59 | public function getRequestParser()
60 | {
61 | return $this->requestParser;
62 | }
63 |
64 | /**
65 | * @return ResponseParser
66 | */
67 | public function getResponseParser()
68 | {
69 | return $this->responseParser;
70 | }
71 |
72 | /**
73 | * @param $data
74 | * @return ModelInterface[]
75 | */
76 | public function parseResponse($data)
77 | {
78 | return $this->responseParser->pushIncoming($data);
79 | }
80 |
81 | /**
82 | * @param $data
83 | * @return string
84 | */
85 | public function buildResponse($data)
86 | {
87 | return $this->serializer->getReplyMessage($data);
88 | }
89 |
90 | }
--------------------------------------------------------------------------------
/src/Redis/Driver/DriverInterface.php:
--------------------------------------------------------------------------------
1 | endpoint = $endpoint;
83 | $this->loop = $loop;
84 | $this->stream = null;
85 | $this->driver = new Driver();
86 |
87 | $this->isConnected = false;
88 | $this->isBeingDisconnected = false;
89 | $this->endPromise = null;
90 |
91 | $this->reqs = [];
92 | }
93 |
94 | /**
95 | *
96 | */
97 | public function __destruct()
98 | {
99 | $this->stop();
100 | parent::__destruct();
101 | }
102 |
103 | /**
104 | * @override
105 | * @inheritDoc
106 | */
107 | public function isPaused()
108 | {
109 | return $this->stream === null ? false : $this->stream->isPaused();
110 | }
111 |
112 | /**
113 | * @override
114 | * @inheritDoc
115 | */
116 | public function pause()
117 | {
118 | if ($this->stream !== null)
119 | {
120 | $this->stream->pause();
121 | }
122 | }
123 |
124 | /**
125 | * @override
126 | * @inheritDoc
127 | */
128 | public function resume()
129 | {
130 | if ($this->stream !== null)
131 | {
132 | $this->stream->resume();
133 | }
134 | }
135 |
136 | /**
137 | * @override
138 | * @inheritDoc
139 | */
140 | public function isStarted()
141 | {
142 | return $this->isConnected;
143 | }
144 |
145 | /**
146 | * @override
147 | * @inheritDoc
148 | */
149 | public function isBusy()
150 | {
151 | return !empty($this->reqs);
152 | }
153 |
154 | /**
155 | * @override
156 | * @inheritDoc
157 | */
158 | public function start()
159 | {
160 | if ($this->isStarted())
161 | {
162 | return Promise::doResolve($this);
163 | }
164 |
165 | $ex = null;
166 | $stream = null;
167 |
168 | try
169 | {
170 | $stream = $this->createClient($this->endpoint);
171 | }
172 | catch (Error $ex)
173 | {}
174 | catch (Exception $ex)
175 | {}
176 |
177 | if ($ex !== null)
178 | {
179 | return Promise::doReject($ex);
180 | }
181 |
182 | $this->isConnected = true;
183 | $this->isBeingDisconnected = false;
184 | $this->stream = $stream;
185 | $this->handleStart();
186 | $this->emit('start', [ $this ]);
187 |
188 | return Promise::doResolve($this);
189 | }
190 |
191 | /**
192 | * @override
193 | * @inheritDoc
194 | */
195 | public function stop()
196 | {
197 | if (!$this->isStarted())
198 | {
199 | return Promise::doResolve($this);
200 | }
201 |
202 | $this->isBeingDisconnected = true;
203 | $this->isConnected = false;
204 |
205 | $this->stream->close();
206 | $this->stream = null;
207 |
208 | foreach ($this->reqs as $req)
209 | {
210 | $req->reject(new ExecutionException('Connection has been closed!'));
211 | }
212 |
213 | $this->reqs = [];
214 | $this->handleStop();
215 | $this->emit('stop', [ $this ]);
216 |
217 | if ($this->endPromise !== null)
218 | {
219 | $promise = $this->endPromise;
220 | $this->endPromise = null;
221 | $promise->resolve($this);
222 | }
223 |
224 | return Promise::doResolve($this);
225 | }
226 |
227 | /**
228 | * @override
229 | * @inheritDoc
230 | */
231 | public function end()
232 | {
233 | if (!$this->isStarted())
234 | {
235 | return Promise::doResolve($this);
236 | }
237 | if ($this->isBeingDisconnected)
238 | {
239 | return Promise::doReject(new WriteException('Tried to double end same connection.'));
240 | }
241 | if (!$this->isBusy())
242 | {
243 | return $this->stop();
244 | }
245 |
246 | $promise = new Promise();
247 | $this->isBeingDisconnected = true;
248 | $this->endPromise = $promise;
249 |
250 | return $promise;
251 | }
252 |
253 | /**
254 | * Dispatch Redis request.
255 | *
256 | * @param Request $command
257 | * @return PromiseInterface
258 | */
259 | protected function dispatch(Request $command)
260 | {
261 | $request = new Deferred();
262 | $promise = $request->getPromise();
263 |
264 | if ($this->isBeingDisconnected)
265 | {
266 | $request->reject(new ExecutionException('Redis client connection is being stopped now.'));
267 | }
268 | else
269 | {
270 | $this->stream->write($this->driver->commands($command));
271 | $this->reqs[] = $request;
272 | }
273 |
274 | return $promise;
275 | }
276 |
277 | /**
278 | * @internal
279 | */
280 | protected function handleStart()
281 | {
282 | if ($this->stream !== null)
283 | {
284 | $this->stream->on('data', [ $this, 'handleData' ]);
285 | $this->stream->on('close', [ $this, 'stop' ]);
286 | }
287 | }
288 |
289 | /**
290 | * @internal
291 | */
292 | protected function handleStop()
293 | {
294 | if ($this->stream !== null)
295 | {
296 | $this->stream->removeListener('data', [ $this, 'handleData' ]);
297 | $this->stream->removeListener('close', [ $this, 'stop' ]);
298 | }
299 | }
300 |
301 | /**
302 | * @internal
303 | * @param SocketInterface $stream
304 | * @param string $chunk
305 | */
306 | public function handleData($stream, $chunk)
307 | {
308 | try
309 | {
310 | $models = $this->driver->parseResponse($chunk);
311 | }
312 | catch (ParserException $error)
313 | {
314 | $this->emit('error', [ $this, $error ]);
315 | $this->stop();
316 | return;
317 | }
318 |
319 | foreach ($models as $data)
320 | {
321 | try
322 | {
323 | $this->handleMessage($data);
324 | }
325 | catch (UnderflowException $error)
326 | {
327 | $this->emit('error', [ $this, $error ]);
328 | $this->stop();
329 | return;
330 | }
331 | }
332 | }
333 |
334 | /**
335 | * @internal
336 | * @param ModelInterface $message
337 | */
338 | protected function handleMessage(ModelInterface $message)
339 | {
340 | if (!$this->reqs)
341 | {
342 | throw new UnderflowException('Unexpected reply received, no matching request found');
343 | }
344 |
345 | $request = array_shift($this->reqs);
346 |
347 | if ($message instanceof ErrorReply)
348 | {
349 | $request->reject($message);
350 | }
351 | else
352 | {
353 | $request->resolve($message->getValueNative());
354 | }
355 |
356 | if ($this->isBeingDisconnected && !$this->isBusy())
357 | {
358 | $this->stop();
359 | }
360 | }
361 |
362 | /**
363 | * Create socket client with connection to Redis database.
364 | *
365 | * @param string $endpoint
366 | * @return SocketInterface
367 | * @throws ExecutionException
368 | */
369 | protected function createClient($endpoint)
370 | {
371 | $ex = null;
372 |
373 | try
374 | {
375 | return new Socket($endpoint, $this->loop);
376 | }
377 | catch (Error $ex)
378 | {}
379 | catch (Exception $ex)
380 | {}
381 |
382 | throw new ExecutionException('Redis connection socket could not be created!', 0, $ex);
383 | }
384 | };
385 |
--------------------------------------------------------------------------------
/src/Redis/RedisInterface.php:
--------------------------------------------------------------------------------
1 | loop = null;
46 | $this->sim = null;
47 | }
48 |
49 | /**
50 | *
51 | */
52 | public function tearDown()
53 | {
54 | unset($this->sim);
55 | unset($this->loop);
56 | }
57 |
58 | /**
59 | * @return LoopInterface|null
60 | */
61 | public function getLoop()
62 | {
63 | return $this->loop;
64 | }
65 |
66 | /**
67 | * Run test scenario as simulation.
68 | *
69 | * @param callable(Simulation) $scenario
70 | * @return TModule
71 | */
72 | public function simulate(callable $scenario)
73 | {
74 | try
75 | {
76 | $this->loop = new Loop(new SelectLoop);
77 | $this->loop->erase(true);
78 |
79 | $this->sim = new Simulation($this->loop);
80 | $this->sim->setScenario($scenario);
81 | $this->sim->begin();
82 | }
83 | catch (Exception $ex)
84 | {
85 | $this->fail($ex->getMessage());
86 | }
87 |
88 | if ($this->sim->getState() === Simulation::STATE_FAILED)
89 | {
90 | $this->fail($this->sim->getStateMessage());
91 | }
92 |
93 | if ($this->sim->getState() === Simulation::STATE_SKIPPED)
94 | {
95 | $this->markTestSkipped($this->sim->getStateMessage());
96 | }
97 |
98 | return $this;
99 | }
100 |
101 | /**
102 | * @param $events
103 | * @param int $flags
104 | * @return TModule
105 | */
106 | public function expect($events, $flags = Simulation::EVENTS_COMPARE_IN_ORDER)
107 | {
108 | $expectedEvents = [];
109 |
110 | foreach ($events as $event)
111 | {
112 | $data = isset($event[1]) ? $event[1] : [];
113 | $expectedEvents[] = new Event($event[0], $data);
114 | }
115 |
116 | $this->assertEvents(
117 | $this->sim->getExpectations(),
118 | $expectedEvents,
119 | $flags
120 | );
121 |
122 | return $this;
123 | }
124 |
125 | /**
126 | * @param Event[] $actualEvents
127 | * @param Event[] $expectedEvents
128 | * @param int $flags
129 | */
130 | public function assertEvents($actualEvents = [], $expectedEvents = [], $flags = Simulation::EVENTS_COMPARE_IN_ORDER)
131 | {
132 | $count = max(count($actualEvents), count($expectedEvents));
133 |
134 | if ($flags === Simulation::EVENTS_COMPARE_RANDOMLY)
135 | {
136 | sort($actualEvents);
137 | sort($expectedEvents);
138 | }
139 |
140 | for ($i=0; $i<$count; $i++)
141 | {
142 | if (!isset($actualEvents[$i]))
143 | {
144 | $this->fail(
145 | sprintf(self::MSG_EVENT_GET_ASSERTION_FAILED, $i, $expectedEvents[$i]->name(), 'null')
146 | );
147 | }
148 | else if (!isset($expectedEvents[$i]))
149 | {
150 | $this->fail(
151 | sprintf(self::MSG_EVENT_GET_ASSERTION_FAILED, $i, 'null', $actualEvents[$i]->name())
152 | );
153 | }
154 |
155 | $actualEvent = $actualEvents[$i];
156 | $expectedEvent = $expectedEvents[$i];
157 |
158 | $this->assertSame(
159 | $expectedEvent->name(),
160 | $actualEvent->name(),
161 | sprintf(self::MSG_EVENT_NAME_ASSERTION_FAILED, $i)
162 | );
163 | $this->assertSame(
164 | $expectedEvent->data(),
165 | $actualEvent->data(),
166 | sprintf(self::MSG_EVENT_DATA_ASSERTION_FAILED, $i)
167 | );
168 | }
169 | }
170 | }
171 |
--------------------------------------------------------------------------------
/test/TModule/Command/RedisApiChannelTest.php:
--------------------------------------------------------------------------------
1 | checkRedisVersionedCommand($redis, '1.0.0', function(RedisInterface $redis) {
23 | $params = [];
24 |
25 | return Promise::doResolve()->then(function () use ($redis, $params) {});
26 | });
27 | }
28 |
29 | /**
30 | * @group testing
31 | * @dataProvider redisProvider
32 | * @param RedisInterface $redis
33 | */
34 | public function testRedis_pSubscribe(RedisInterface $redis)
35 | {
36 | //TODO: Implementation
37 | $this->checkRedisVersionedCommand($redis, '2.0.0', function(RedisInterface $redis) {
38 | $params = [];
39 |
40 | return Promise::doResolve()->then(function () use ($redis, $params) {});
41 | });
42 | }
43 |
44 | /**
45 | * @group testing
46 | * @dataProvider redisProvider
47 | * @param RedisInterface $redis
48 | */
49 | public function testRedis_pubSub(RedisInterface $redis)
50 | {
51 | //TODO: Implementation
52 | $this->checkRedisVersionedCommand($redis, '2.8.0', function(RedisInterface $redis) {
53 | $params = [];
54 |
55 | return Promise::doResolve()->then(function () use ($redis, $params) {});
56 | });
57 | }
58 |
59 | /**
60 | * @group testing
61 | * @dataProvider redisProvider
62 | * @param RedisInterface $redis
63 | */
64 | public function testRedis_publish(RedisInterface $redis)
65 | {
66 | //TODO: Implementation
67 | $this->checkRedisVersionedCommand($redis, '2.0.0', function(RedisInterface $redis) {
68 | $params = [];
69 |
70 | return Promise::doResolve()->then(function () use ($redis, $params) {});
71 | });
72 | }
73 |
74 | /**
75 | * @group testing
76 | * @dataProvider redisProvider
77 | * @param RedisInterface $redis
78 | */
79 | public function testRedis_pUnsubscribe(RedisInterface $redis)
80 | {
81 | //TODO: Implementation
82 | $this->checkRedisVersionedCommand($redis, '2.0.0', function(RedisInterface $redis) {
83 | $params = [];
84 |
85 | return Promise::doResolve()->then(function () use ($redis, $params) {});
86 | });
87 | }
88 |
89 | /**
90 | * @group testing
91 | * @dataProvider redisProvider
92 | * @param RedisInterface $redis
93 | */
94 | public function testRedis_unSubscribe(RedisInterface $redis)
95 | {
96 | //TODO: Implementation
97 | $this->checkRedisVersionedCommand($redis, '2.0.0', function(RedisInterface $redis) {
98 | $params = [];
99 |
100 | return Promise::doResolve()->then(function () use ($redis, $params) {});
101 | });
102 | }
103 |
104 | /**
105 | * @group testing
106 | * @dataProvider redisProvider
107 | * @param RedisInterface $redis
108 | */
109 | public function testRedis_subscribe(RedisInterface $redis)
110 | {
111 | //TODO: Implementation
112 | $this->checkRedisVersionedCommand($redis, '2.0.0', function(RedisInterface $redis) {
113 | $params = [];
114 |
115 | return Promise::doResolve()->then(function () use ($redis, $params) {});
116 | });
117 | }
118 | }
--------------------------------------------------------------------------------
/test/TModule/Command/RedisApiConnTest.php:
--------------------------------------------------------------------------------
1 | checkRedisVersionedCommand($redis, '1.0.0', function(RedisInterface $redis) {
23 | $params = [];
24 |
25 | return Promise::doResolve()->then(function () use ($redis, $params) {});
26 | });
27 | }
28 |
29 | /**
30 | * @group passed
31 | * @dataProvider redisProvider
32 | * @param RedisInterface $redis
33 | */
34 | public function testRedis_ping(RedisInterface $redis)
35 | {
36 | $this->checkRedisVersionedCommand($redis, '1.0.0', function(RedisInterface $redis) {
37 | $params = [
38 | 'MSG' => 'MESSAGE'
39 | ];
40 |
41 | return Promise::doResolve()->then(function () use ($redis, $params) {
42 | return $redis->ping($params['MSG']);
43 | })
44 | ->then(function ($value) use ($params) {
45 | $this->assertSame($value, $params['MSG']);
46 | });
47 | });
48 | }
49 |
50 | /**
51 | * @group passed
52 | * @dataProvider redisProvider
53 | * @param RedisInterface $redis
54 | */
55 | public function testRedis_quit(RedisInterface $redis)
56 | {
57 | $this->checkRedisVersionedCommand($redis, '1.0.0', function(RedisInterface $redis) {
58 | $params = [];
59 |
60 | return Promise::doResolve()->then(function () use ($redis, $params) {
61 | return $redis->quit();
62 | })
63 | ->then(function ($value) {
64 | $this->assertSame($value, 'OK');
65 | });
66 | });
67 | }
68 |
69 | /**
70 | * @group passed
71 | * @dataProvider redisProvider
72 | * @param RedisInterface $redis
73 | */
74 | public function testRedis_select(RedisInterface $redis)
75 | {
76 | $this->checkRedisVersionedCommand($redis, '1.0.0', function(RedisInterface $redis) {
77 | $params = [
78 | 'INDEX' => 0,
79 | ];
80 |
81 | return Promise::doResolve()->then(function () use ($redis, $params) {
82 | return $redis->select($params['INDEX']);
83 | })
84 | ->then(function ($value) {
85 | $this->assertSame($value, 'OK');
86 | });
87 | });
88 | }
89 |
90 | /**
91 | * @group ignored
92 | * @dataProvider redisProvider
93 | * @param RedisInterface $redis
94 | */
95 | public function testRedis_swapBb(RedisInterface $redis)
96 | {
97 | $this->checkRedisVersionedCommand($redis, '4.0.0', function(RedisInterface $redis) {
98 | return Promise::doResolve()->then(function () use ($redis) {
99 | return $redis->swapBb(0, 1);
100 | })
101 | ->then(function ($value) {
102 | $this->assertSame('OK', $value);
103 | });
104 | });
105 | }
106 | }
--------------------------------------------------------------------------------
/test/TModule/Command/RedisApiCoreTest.php:
--------------------------------------------------------------------------------
1 | checkRedisVersionedCommand($redis, '1.0.0', function(RedisInterface $redis) {
23 | $params = [];
24 |
25 | return Promise::doResolve()->then(function () use ($redis, $params) {
26 |
27 | });
28 | });
29 | }
30 |
31 | /**
32 | * @group passed
33 | * @dataProvider redisProvider
34 | * @param RedisInterface $redis
35 | */
36 | public function testRedis_bgRewriteAoF(RedisInterface $redis)
37 | {
38 | $this->checkRedisVersionedCommand($redis, '1.0.0', function(RedisInterface $redis) {
39 | $params = [];
40 |
41 | return Promise::doResolve()->then(function () use ($redis, $params) {
42 | return $redis->bgRewriteAoF();
43 | })
44 | ->then(function ($value) {
45 | $this->assertSame('Background append only file rewriting started', $value);
46 | });
47 | });
48 | }
49 |
50 | /**
51 | * @group passed
52 | * @dataProvider redisProvider
53 | * @param RedisInterface $redis
54 | */
55 | public function testRedis_bgSave(RedisInterface $redis)
56 | {
57 | $this->checkRedisVersionedCommand($redis, '1.0.0', function(RedisInterface $redis) {
58 | $params = [];
59 |
60 | return Promise::doResolve()->then(function () use ($redis, $params) {
61 | return $redis->info(['persistence']);
62 | })
63 | ->then(function ($value) use ($redis) {
64 | if ($value['persistence']['aof_rewrite_in_progress'] <= 0) {
65 | return $redis->bgSave();
66 | }
67 |
68 | return 'An AOF log rewriting in progress';
69 | })
70 | ->then(function ($value) {
71 | $this->assertSame('An AOF log rewriting in progress', $value);
72 | });
73 | });
74 | }
75 |
76 | /**
77 | * @group ignored
78 | * @dataProvider redisProvider
79 | * @param RedisInterface $redis
80 | */
81 | public function testRedis_sync(RedisInterface $redis)
82 | {
83 | //TODO: Implementation
84 | $this->checkRedisVersionedCommand($redis, '1.0.0', function(RedisInterface $redis) {
85 | $params = [];
86 |
87 | return Promise::doResolve()->then(function () use ($redis, $params) {
88 | // return $redis->sync();
89 | });
90 | });
91 | }
92 |
93 | /**
94 | * @group passed
95 | * @dataProvider redisProvider
96 | * @param RedisInterface $redis
97 | */
98 | public function testRedis_time(RedisInterface $redis)
99 | {
100 | $this->checkRedisVersionedCommand($redis, '2.6.0', function(RedisInterface $redis) {
101 | $params = [];
102 |
103 | return Promise::doResolve()->then(function () use ($redis, $params) {
104 | return $redis->time();
105 | })
106 | ->then(function ($value) {
107 | $this->assertNotEmpty($value);
108 | });
109 | });
110 | }
111 |
112 | /**
113 | * @group passed
114 | * @dataProvider redisProvider
115 | * @param RedisInterface $redis
116 | */
117 | public function testRedis_monitor(RedisInterface $redis)
118 | {
119 | $this->checkRedisVersionedCommand($redis, '1.0.0', function(RedisInterface $redis) {
120 | $params = [];
121 |
122 | return Promise::doResolve()->then(function () use ($redis, $params) {
123 | return $redis->monitor();
124 | })
125 | ->then(function ($value) {
126 | $this->assertSame('OK', $value);
127 | });
128 | });
129 | }
130 |
131 |
132 | /**
133 | * @group passed
134 | * @dataProvider redisProvider
135 | * @param RedisInterface $redis
136 | */
137 | public function testRedis_flushAll(RedisInterface $redis)
138 | {
139 | $this->checkRedisVersionedCommand($redis, '1.0.0', function(RedisInterface $redis) {
140 | $params = [];
141 |
142 | return Promise::doResolve()->then(function () use ($redis, $params) {
143 | return $redis->flushAll();
144 | })
145 | ->then(function ($value) {
146 | $this->assertSame('OK', $value);
147 | });
148 | });
149 | }
150 |
151 | /**
152 | * @group passed
153 | * @dataProvider redisProvider
154 | * @param RedisInterface $redis
155 | */
156 | public function testRedis_flushDb(RedisInterface $redis)
157 | {
158 | $this->checkRedisVersionedCommand($redis, '1.0.0', function(RedisInterface $redis) {
159 | $params = [];
160 |
161 | return Promise::doResolve()->then(function () use ($redis, $params) {
162 | return $redis->flushDb();
163 | })
164 | ->then(function ($value) {
165 | $this->assertSame('OK', $value);
166 | });
167 | });
168 | }
169 |
170 | /**
171 | * @group passed
172 | * @dataProvider redisProvider
173 | * @param RedisInterface $redis
174 | */
175 | public function testRedis_info(RedisInterface $redis)
176 | {
177 | $this->checkRedisVersionedCommand($redis, '1.0.0', function(RedisInterface $redis) {
178 | $params = [];
179 |
180 | return Promise::doResolve()->then(function () use ($redis, $params) {
181 | return $redis->info();
182 | })
183 | ->then(function ($value) {
184 | $this->assertArrayHasKey('cpu', $value);
185 | $this->assertArrayHasKey('persistence', $value);
186 | $this->assertArrayHasKey('memory', $value);
187 | $this->assertArrayHasKey('clients', $value);
188 | $this->assertArrayHasKey('server', $value);
189 | });
190 | });
191 | }
192 |
193 | /**
194 | * @group passed
195 | * @dataProvider redisProvider
196 | * @param RedisInterface $redis
197 | */
198 | public function testRedis_slaveOf(RedisInterface $redis)
199 | {
200 | $this->checkRedisVersionedCommand($redis, '1.0.0', function(RedisInterface $redis) {
201 | $params = [];
202 |
203 | return Promise::doResolve()->then(function () use ($redis, $params) {
204 | return $redis->slaveOf('127.0.0.1',6379);
205 | })
206 | ->then(function ($value) use ($redis) {
207 | $redis->slaveOf('no', 'one');
208 | $this->assertSame('OK', $value);
209 | });
210 | });
211 | }
212 |
213 | /**
214 | * @group ignored
215 | * @dataProvider redisProvider
216 | * @param RedisInterface $redis
217 | */
218 | public function testRedis_slowLog(RedisInterface $redis)
219 | {
220 | //TODO: Implementation
221 | $this->checkRedisVersionedCommand($redis, '2.2.12', function(RedisInterface $redis) {
222 | $params = [];
223 |
224 | return Promise::doResolve()->then(function () use ($redis, $params) {
225 | // $redis->slowLog();
226 | });
227 | });
228 | }
229 |
230 | /**
231 | * @group passed
232 | * @dataProvider redisProvider
233 | * @param RedisInterface $redis
234 | */
235 | public function testRedis_save(RedisInterface $redis)
236 | {
237 | $this->checkRedisVersionedCommand($redis, '1.0.0', function(RedisInterface $redis) {
238 | $params = [];
239 |
240 | return Promise::doResolve()->then(function () use ($redis, $params) {
241 | return $redis->save();
242 | })
243 | ->then(function ($value) {
244 | $this->assertSame('OK', $value);
245 | });
246 | });
247 | }
248 | }
--------------------------------------------------------------------------------
/test/TModule/Command/RedisApiHyperLogTest.php:
--------------------------------------------------------------------------------
1 | checkRedisVersionedCommand($redis, '2.8.9', function (RedisInterface $redis) {
22 | $params = [
23 | 'KEY' => 'T_KEY',
24 | 'E_1' => 'T_ELEMENT_1',
25 | 'E_2' => 'T_ELEMENT_2',
26 | 'E_3' => 'T_ELEMENT_3',
27 | 'E_4' => 'T_ELEMENT_4',
28 | ];
29 |
30 | return Promise::doResolve()->then(function () use ($redis, $params) {
31 | return $redis->pFAdd($params['KEY'], $params['E_1'], $params['E_2'], $params['E_3'], $params['E_4']);
32 | })
33 | ->then(function ($value) {
34 | $this->assertSame(1, $value);
35 | });
36 | });
37 | }
38 |
39 | /**
40 | * @group passed
41 | * @dataProvider redisProvider
42 | * @param RedisInterface $redis
43 | */
44 | public function testRedis_pFCount(RedisInterface $redis)
45 | {
46 | $this->checkRedisVersionedCommand($redis, '2.8.9', function (RedisInterface $redis) {
47 | $params = [
48 | 'KEY' => 'T_KEY',
49 | 'E_1' => 'T_ELEMENT_1',
50 | 'E_2' => 'T_ELEMENT_2',
51 | 'E_3' => 'T_ELEMENT_3',
52 | 'E_4' => 'T_ELEMENT_4',
53 | ];
54 |
55 | return Promise::doResolve()->then(function () use ($redis, $params) {
56 | $redis->pFAdd($params['KEY'], $params['E_1'], $params['E_2'], $params['E_3'], $params['E_4']);
57 |
58 | return $redis->pFCount($params['KEY']);
59 | })
60 | ->then(function ($value) {
61 | $this->assertSame(4, $value);
62 | });
63 | });
64 | }
65 |
66 | /**
67 | * @group passed
68 | * @dataProvider redisProvider
69 | * @param RedisInterface $redis
70 | */
71 | public function testRedis_pFMerge(RedisInterface $redis)
72 | {
73 | $this->checkRedisVersionedCommand($redis, '2.8.9', function (RedisInterface $redis) {
74 | $params = [
75 | 'KEY_1' => 'T_KEY_1',
76 | 'E_1' => 'T_ELEMENT_1',
77 | 'E_2' => 'T_ELEMENT_2',
78 | 'E_3' => 'T_ELEMENT_3',
79 | 'E_4' => 'T_ELEMENT_4',
80 | 'KEY_2' => 'T_KEY_2',
81 | 'E_5' => 'T_ELEMENT_5',
82 | 'E_6' => 'T_ELEMENT_6',
83 | 'E_7' => 'T_ELEMENT_7',
84 | 'E_8' => 'T_ELEMENT_8',
85 | ];
86 |
87 | return Promise::doResolve()->then(function () use ($redis, $params) {
88 | $redis->pFAdd($params['KEY_1'], $params['E_1'], $params['E_2'], $params['E_3'], $params['E_4']);
89 | $redis->pFAdd($params['KEY_2'], $params['E_5'], $params['E_6'], $params['E_7'], $params['E_8']);
90 | $redis->pFMerge($params['KEY_1'], $params['KEY_2']);
91 |
92 | return $redis->pFCount($params['KEY_1']);
93 | })
94 | ->then(function ($value) {
95 | $this->assertSame(8, $value);
96 | });
97 | });
98 | }
99 | }
--------------------------------------------------------------------------------
/test/TModule/Command/RedisApiSetTest.php:
--------------------------------------------------------------------------------
1 | checkRedisVersionedCommand($redis, '1.0.0', function(RedisInterface $redis) {
22 | $params = [
23 | 'SET' => 'T_SET',
24 | 'E_1' => 'Hello',
25 | 'E_2' => 'World',
26 | ];
27 |
28 | return Promise::doResolve()->then(function () use ($redis, $params) {
29 | return $redis->sAdd($params['SET'], $params['E_1'], $params['E_2'])
30 | ->then(function ($value) {
31 | $this->assertSame(2, $value);
32 | });
33 | });
34 | });
35 | }
36 |
37 | /**
38 | * @group passed
39 | * @dataProvider redisProvider
40 | * @param RedisInterface $redis
41 | */
42 | public function testRedis_sInterStore(RedisInterface $redis)
43 | {
44 | $this->checkRedisVersionedCommand($redis, '1.0.0', function(RedisInterface $redis) {
45 | $params = [
46 | 'SET_1' => 'T_SET_1',
47 | 'S1_E1' => 'T_S1_E1',
48 | 'SET_2' => 'T_SET_2',
49 | 'S2_E1' => 'T_S2_E1',
50 | 'SET_3' => 'T_SET_3',
51 | 'INTER' => 'E_INTER',
52 | ];
53 |
54 | return Promise::doResolve()->then(function () use ($redis, $params) {
55 | $redis->sAdd($params['SET_1'], $params['S1_E1'], $params['INTER']);
56 | $redis->sAdd($params['SET_2'], $params['S2_E1'], $params['INTER']);
57 | })
58 | ->then(function () use ($redis, $params) {
59 | return $redis->sInterStore($params['SET_3'], $params['SET_1'], $params['SET_2']);
60 | })
61 | ->then(function ($value) {
62 | $this->assertSame(1, $value);
63 | });
64 | });
65 | }
66 |
67 | /**
68 | * @group passed
69 | * @dataProvider redisProvider
70 | * @param RedisInterface $redis
71 | */
72 | public function testRedis_sIsMember(RedisInterface $redis)
73 | {
74 | $this->checkRedisVersionedCommand($redis, '1.0.0', function(RedisInterface $redis) {
75 | $params = [
76 | 'SET' => 'T_SET',
77 | 'E_1' => 'T_E_1',
78 | ];
79 |
80 | return Promise::doResolve()->then(function () use ($redis, $params) {
81 | return $redis->sIsMember($params['SET'], $params['E_1']);
82 | })
83 | ->then(function ($value) use ($redis, $params) {
84 | $this->assertSame(0, $value);
85 | $redis->sAdd($params['SET'], $params['E_1']);
86 |
87 | return $redis->sIsMember($params['SET'], $params['E_1']);
88 | })
89 | ->then(function ($value) {
90 | $this->assertSame(1, $value);
91 | });
92 | });
93 | }
94 |
95 | /**
96 | * @group passed
97 | * @dataProvider redisProvider
98 | * @param RedisInterface $redis
99 | */
100 | public function testRedis_sMembers(RedisInterface $redis)
101 | {
102 | $this->checkRedisVersionedCommand($redis, '1.0.0', function(RedisInterface $redis) {
103 | $params = [
104 | 'SET' => 'T_SET',
105 | 'E_1' => 'T_E_1',
106 | ];
107 |
108 | return Promise::doResolve()->then(function () use ($redis, $params) {
109 | return $redis->sAdd($params['SET'], $params['E_1']);
110 | })
111 | ->then(function () use ($redis, $params) {
112 | return $redis->sMembers($params['SET']);
113 | })
114 | ->then(function ($value) use ($params) {
115 | $this->assertSame([$params['E_1']], $value);
116 | });
117 | });
118 | }
119 |
120 | /**
121 | * @group passed
122 | * @dataProvider redisProvider
123 | * @param RedisInterface $redis
124 | */
125 | public function testRedis_sMove(RedisInterface $redis)
126 | {
127 | $this->checkRedisVersionedCommand($redis, '1.0.0', function(RedisInterface $redis) {
128 | $params = [
129 | 'SET_1' => 'T_SET_1',
130 | 'S1_E1' => 'T_S1_E1',
131 | 'SET_2' => 'T_SET_2',
132 | 'S2_E1' => 'T_S2_E1',
133 | ];
134 |
135 | return Promise::doResolve()->then(function () use ($redis, $params) {
136 | $redis->sAdd($params['SET_1'], $params['S1_E1']);
137 | $redis->sAdd($params['SET_2'], $params['S2_E1']);
138 | })
139 | ->then(function () use ($redis, $params) {
140 | return $redis->sMove($params['SET_1'], $params['SET_2'], $params['S1_E1']);
141 | })
142 | ->then(function ($value) {
143 | $this->assertSame(1, $value);
144 | });
145 | });
146 | }
147 |
148 | /**
149 | * @group passed
150 | * @dataProvider redisProvider
151 | * @param RedisInterface $redis
152 | */
153 | public function testRedis_sPop(RedisInterface $redis)
154 | {
155 | $this->checkRedisVersionedCommand($redis, '1.0.0', function(RedisInterface $redis) {
156 | $params = [
157 | 'SET' => 'T_SET',
158 | 'E_1' => 'T_E_1',
159 | ];
160 |
161 | return Promise::doResolve()->then(function () use ($redis, $params) {
162 | return $redis->sAdd($params['SET'], $params['E_1']);
163 | })
164 | ->then(function () use ($redis, $params) {
165 | return $redis->sPop($params['SET'], 1);
166 | })
167 | ->then(function ($value) use ($params) {
168 | $this->assertSame([$params['E_1']], $value);
169 | });
170 | });
171 | }
172 |
173 | /**
174 | * @group passed
175 | * @dataProvider redisProvider
176 | * @param RedisInterface $redis
177 | */
178 | public function testRedis_sRandMember(RedisInterface $redis)
179 | {
180 | $this->checkRedisVersionedCommand($redis, '1.0.0', function(RedisInterface $redis) {
181 | $params = [
182 | 'SET' => 'T_SET',
183 | 'E_1' => 'T_E_1',
184 | ];
185 |
186 | return Promise::doResolve()->then(function () use ($redis, $params) {
187 | return $redis->sAdd($params['SET'], $params['E_1']);
188 | })
189 | ->then(function () use ($redis, $params) {
190 | return $redis->sRandMember($params['SET'], 1);
191 | })
192 | ->then(function ($value) use ($params) {
193 | $this->assertSame([$params['E_1']], $value);
194 | });
195 | });
196 | }
197 |
198 | /**
199 | * @group passed
200 | * @dataProvider redisProvider
201 | * @param RedisInterface $redis
202 | */
203 | public function testRedis_sRem(RedisInterface $redis)
204 | {
205 | $this->checkRedisVersionedCommand($redis, '1.0.0', function(RedisInterface $redis) {
206 | $params = [
207 | 'SET' => 'T_SET',
208 | 'E_1' => 'T_E_1',
209 | ];
210 |
211 | return Promise::doResolve()->then(function () use ($redis, $params) {
212 | return $redis->sAdd($params['SET'], $params['E_1']);
213 | })
214 | ->then(function () use ($redis, $params) {
215 | return $redis->sRem($params['SET'], $params['E_1']);
216 | })
217 | ->then(function ($value) use ($params) {
218 | $this->assertSame(1, $value);
219 | });
220 | });
221 | }
222 |
223 | /**
224 | * @group ignored
225 | * @dataProvider redisProvider
226 | * @param RedisInterface $redis
227 | */
228 | public function testRedis_sScan(RedisInterface $redis)
229 | {
230 | $this->checkRedisVersionedCommand($redis, '2.8.0', function(RedisInterface $redis) {
231 | return Promise::doResolve()->then(function () use ($redis) {
232 | //TODO: implementation
233 | });
234 | });
235 | }
236 |
237 | /**
238 | * @group passed
239 | * @dataProvider redisProvider
240 | * @param RedisInterface $redis
241 | */
242 | public function testRedis_sUnion(RedisInterface $redis)
243 | {
244 | $this->checkRedisVersionedCommand($redis, '1.0.0', function(RedisInterface $redis) {
245 | $params = [
246 | 'SET_1' => 'T_SET_1',
247 | 'S1_E1' => '1',
248 | 'SET_2' => 'T_SET_2',
249 | 'S2_E1' => '2',
250 | ];
251 | return Promise::doResolve()->then(function () use ($redis, $params) {
252 | $redis->sAdd($params['SET_1'], $params['S1_E1']);
253 | $redis->sAdd($params['SET_2'], $params['S2_E1']);
254 | })
255 | ->then(function () use ($redis, $params) {
256 | return $redis->sUnion($params['SET_1'], $params['SET_2']);
257 | })
258 | ->then(function ($value) use ($params) {
259 | $this->assertSame([
260 | $params['S1_E1'],
261 | $params['S2_E1'],
262 | ], $value);
263 | });
264 | });
265 | }
266 |
267 | /**
268 | * @group passed
269 | * @dataProvider redisProvider
270 | * @param RedisInterface $redis
271 | */
272 | public function testRedis_sUnionStore(RedisInterface $redis)
273 | {
274 | $this->checkRedisVersionedCommand($redis, '1.0.0', function(RedisInterface $redis) {
275 | $params = [
276 | 'SET_1' => 'T_SET_1',
277 | 'S1_E1' => 'T_S1_E1',
278 | 'SET_2' => 'T_SET_2',
279 | 'S2_E1' => 'T_S2_E1',
280 | 'SET_3' => 'T_SET_3',
281 | ];
282 | return Promise::doResolve()->then(function () use ($redis, $params) {
283 | $redis->sAdd($params['SET_1'], $params['S1_E1']);
284 | $redis->sAdd($params['SET_2'], $params['S2_E1']);
285 | })
286 | ->then(function () use ($redis, $params) {
287 | return $redis->sUnionStore($params['SET_3'], $params['SET_1'], $params['SET_2']);
288 | })
289 | ->then(function ($value) {
290 | $this->assertSame(2, $value);
291 | });
292 | });
293 | }
294 |
295 | /**
296 | * @group passed
297 | * @dataProvider redisProvider
298 | * @param RedisInterface $redis
299 | */
300 | public function testRedis_sAdd(RedisInterface $redis)
301 | {
302 | $this->checkRedisVersionedCommand($redis, '1.0.0', function(RedisInterface $redis) {
303 | $params = [
304 | 'SET' => 'T_SET',
305 | 'E_1' => 'T_E_1',
306 | ];
307 | return Promise::doResolve()->then(function () use ($redis, $params) {
308 | return $redis->sAdd($params['SET'], $params['E_1']);
309 | })
310 | ->then(function ($value) use ($params) {
311 | $this->assertSame(1, $value);
312 | });
313 | });
314 | }
315 |
316 | /**
317 | * @group passed
318 | * @dataProvider redisProvider
319 | * @param RedisInterface $redis
320 | */
321 | public function testRedis_sCard(RedisInterface $redis)
322 | {
323 | $this->checkRedisVersionedCommand($redis, '1.0.0', function(RedisInterface $redis) {
324 | $params = [
325 | 'SET' => 'T_SET',
326 | 'E_1' => 'T_E_1',
327 | ];
328 | return Promise::doResolve()->then(function () use ($redis, $params) {
329 | $redis->sAdd($params['SET'], $params['E_1']);
330 |
331 | return $redis->sCard($params['SET']);
332 | })
333 | ->then(function ($value) use ($params) {
334 | $this->assertSame(1, $value);
335 | });
336 | });
337 | }
338 |
339 | /**
340 | * @group passed
341 | * @dataProvider redisProvider
342 | * @param RedisInterface $redis
343 | */
344 | public function testRedis_sDiff(RedisInterface $redis)
345 | {
346 | $this->checkRedisVersionedCommand($redis, '1.0.0', function(RedisInterface $redis) {
347 | $params = [
348 | 'SET_1' => 'T_SET_1',
349 | 'S1_E1' => 'T_S1_E1',
350 | 'SET_2' => 'T_SET_2',
351 | 'S2_E1' => 'T_S2_E1',
352 | ];
353 | return Promise::doResolve()->then(function () use ($redis, $params) {
354 | $redis->sAdd($params['SET_1'], $params['S1_E1']);
355 | $redis->sAdd($params['SET_2'], $params['S2_E1']);
356 | })
357 | ->then(function () use ($redis, $params) {
358 | return $redis->sDiff($params['SET_1'], $params['SET_2']);
359 | })
360 | ->then(function ($value) use ($params) {
361 | $this->assertSame([
362 | $params['S1_E1'],
363 | ], $value);
364 | });
365 | });
366 | }
367 |
368 | /**
369 | * @group passed
370 | * @dataProvider redisProvider
371 | * @param RedisInterface $redis
372 | */
373 | public function testRedis_sDiffStore(RedisInterface $redis)
374 | {
375 | $this->checkRedisVersionedCommand($redis, '1.0.0', function(RedisInterface $redis) {
376 | $params = [
377 | 'SET_1' => 'T_SET_1',
378 | 'S1_E1' => 'T_S1_E1',
379 | 'SET_2' => 'T_SET_2',
380 | 'S2_E1' => 'T_S2_E1',
381 | 'SET_3' => 'T_SET_3',
382 | ];
383 |
384 | return Promise::doResolve()->then(function () use ($redis, $params) {
385 | $redis->sAdd($params['SET_1'], $params['S1_E1']);
386 | $redis->sAdd($params['SET_2'], $params['S2_E1']);
387 | })
388 | ->then(function () use ($redis, $params) {
389 | return $redis->sDiffStore($params['SET_3'], $params['SET_1'], $params['SET_2']);
390 | })
391 | ->then(function ($value) use ($params) {
392 | $this->assertSame(1, $value);
393 | });
394 | });
395 | }
396 |
397 | }
--------------------------------------------------------------------------------
/test/TModule/Command/RedisApiTransactionTest.php:
--------------------------------------------------------------------------------
1 | checkRedisVersionedCommand($redis, '2.0.0', function(RedisInterface $redis) {
22 | $params = [
23 | 'U_KEY' => 'UNKNOWN_KEY'
24 | ];
25 | return Promise::doResolve()->then(function () use ($redis, $params) {
26 | $redis->multi();
27 | $redis->set($params['U_KEY'], 'OK');
28 | $redis->get($params['U_KEY']);
29 |
30 | return $redis->discard();
31 | })
32 | ->then(function ($value) {
33 | $this->assertSame('OK', $value);
34 | });
35 | });
36 | }
37 |
38 | /**
39 | * @group passed
40 | * @dataProvider redisProvider
41 | * @param RedisInterface $redis
42 | */
43 | public function testRedis_exec(RedisInterface $redis)
44 | {
45 | $this->checkRedisVersionedCommand($redis, '1.2.0', function(RedisInterface $redis) {
46 | $params = [
47 | 'KEY' => 'T_KEY',
48 | 'VAL' => 'T_VAL',
49 | ];
50 | return Promise::doResolve()->then(function () use ($redis, $params) {
51 | $redis->multi();
52 | $redis->set($params['KEY'], $params['VAL']);
53 | $redis->get($params['KEY']);
54 |
55 | return $redis->exec();
56 | })
57 | ->then(function ($value) use ($params) {
58 | $this->assertSame([
59 | 'OK',
60 | $params['VAL'],
61 | ], $value);
62 | });
63 | });
64 | }
65 |
66 | /**
67 | * @group passed
68 | * @dataProvider redisProvider
69 | * @param RedisInterface $redis
70 | */
71 | public function testRedis_multi(RedisInterface $redis)
72 | {
73 | $this->checkRedisVersionedCommand($redis, '1.2.0', function(RedisInterface $redis) {
74 | $params = [
75 |
76 | ];
77 | return Promise::doResolve()->then(function () use ($redis, $params) {
78 | return $redis->multi();
79 | })
80 | ->then(function ($value) use ($redis) {
81 | $this->assertSame('OK', $value);
82 | $redis->discard();
83 | });
84 | });
85 | }
86 |
87 | /**
88 | * @group passed
89 | * @dataProvider redisProvider
90 | * @param RedisInterface $redis
91 | */
92 | public function testRedis_unWatch(RedisInterface $redis)
93 | {
94 | $this->checkRedisVersionedCommand($redis, '2.2.0', function(RedisInterface $redis) {
95 | $params = [
96 | 'KEY_1' => 'T_KEY_1',
97 | 'KEY_2' => 'T_KEY_2',
98 | ];
99 | return Promise::doResolve()->then(function () use ($redis, $params) {
100 | $redis->watch($params['KEY_1'], $params['KEY_2']);
101 |
102 | return $redis->unWatch();
103 | })
104 | ->then(function ($value) {
105 | $this->assertSame('OK', $value);
106 | });
107 | });
108 | }
109 |
110 | /**
111 | * @group passed
112 | * @dataProvider redisProvider
113 | * @param RedisInterface $redis
114 | */
115 | public function testRedis_watch(RedisInterface $redis)
116 | {
117 | $this->checkRedisVersionedCommand($redis, '2.2.0', function(RedisInterface $redis) {
118 | $params = [
119 | 'KEY_1' => 'T_KEY_1',
120 | 'KEY_2' => 'T_KEY_2',
121 | ];
122 | return Promise::doResolve()->then(function () use ($redis, $params) {
123 | return $redis->watch($params['KEY_1'], $params['KEY_2']);
124 | })
125 | ->then(function ($value) {
126 | $this->assertSame('OK', $value);
127 | });
128 | });
129 | }
130 | }
--------------------------------------------------------------------------------
/test/TModule/_Support/RedisTrait.php:
--------------------------------------------------------------------------------
1 | checkRedisVersionedCommand($redis, '1.0.0', $scenario);
33 | }
34 |
35 | /**
36 | * @param RedisInterface $redis
37 | * @param string $minVersion
38 | * @param callable $scenario
39 | */
40 | public function checkRedisVersionedCommand(RedisInterface $redis, $minVersion, callable $scenario)
41 | {
42 | $this->simulate(function(SimulationInterface $sim) use($redis, $minVersion, $scenario) {
43 | $loop = $sim->getLoop();
44 | $redis->setLoop($loop);
45 |
46 | $redis->on('start', function(RedisInterface $redis) use($minVersion, $scenario, $sim) {
47 | return Promise::doResolve()
48 | ->then(function() use($redis) {
49 | return $redis->flushDb();
50 | })
51 | ->then(function() use($redis) {
52 | return $redis->info();
53 | })
54 | ->then(function($info) use($redis, $minVersion, $scenario, $sim) {
55 | if (!$info || !isset($info['server']) || !isset($info['server']['redis_version'])) {
56 | throw new Exception('Test skipped due to insufficient Redis version!');
57 | }
58 | $current = $info['server']['redis_version'];
59 | $minimal = $minVersion;
60 | $cv = explode('.', $current);
61 | $mv = explode('.', $minimal);
62 | if (($mv[0] > $cv[0]) || ($mv[0] === $cv[0] && $mv[1] > $cv[1]) || ($mv[0] === $cv[0] && $mv[1] === $cv[1] && $mv[2] > $cv[2])) {
63 | throw new Exception(
64 | sprintf('Test skipped due to insufficient Redis version! Expected v%s, got v%s', $minimal, $current)
65 | );
66 | }
67 | return Promise::doResolve($scenario($redis))
68 | ->then(function() use($sim) {
69 | $sim->done();
70 | })
71 | ->failure(function($ex) use($sim) {
72 | $sim->fail((string)$ex);
73 | });
74 | })
75 | ->failure(function($ex) use($sim) {
76 | $sim->skip($ex->getMessage());
77 | });
78 | });
79 |
80 | $sim->onStart(function() use($redis) {
81 | $redis->start();
82 | });
83 | $sim->onStop(function() use($redis) {
84 | $redis->stop();
85 | });
86 | });
87 | }
88 |
89 | /**
90 | * @return mixed[][]
91 | */
92 | public function redisProvider()
93 | {
94 | return [
95 | [ $this->createRedis() ]
96 | ];
97 | }
98 |
99 | /**
100 | * @param LoopInterface $loop
101 | * @return RedisInterface
102 | */
103 | public function createRedis(LoopInterface $loop = null)
104 | {
105 | $loop = $loop === null ? new Loop(new SelectLoop()) : $loop;
106 | return new Redis(TEST_DB_REDIS_ENDPOINT, $loop);
107 | }
108 | }
109 |
--------------------------------------------------------------------------------
/test/TUnit.php:
--------------------------------------------------------------------------------
1 | exactly(2);
34 | }
35 |
36 | /**
37 | * Creates a callback that must be called $amount times or the test will fail.
38 | *
39 | * @param $amount
40 | * @return callable|\PHPUnit_Framework_MockObject_MockObject
41 | */
42 | public function expectCallableExactly($amount)
43 | {
44 | $mock = $this->createCallableMock();
45 | $mock
46 | ->expects($this->exactly($amount))
47 | ->method('__invoke');
48 |
49 | return $mock;
50 | }
51 |
52 | /**
53 | * Creates a callback that must be called once.
54 | *
55 | * @return callable|\PHPUnit_Framework_MockObject_MockObject
56 | */
57 | public function expectCallableOnce()
58 | {
59 | $mock = $this->createCallableMock();
60 | $mock
61 | ->expects($this->once())
62 | ->method('__invoke');
63 |
64 | return $mock;
65 | }
66 |
67 | /**
68 | * Creates a callback that must be called twice.
69 | *
70 | * @return callable|\PHPUnit_Framework_MockObject_MockObject
71 | */
72 | public function expectCallableTwice()
73 | {
74 | $mock = $this->createCallableMock();
75 | $mock
76 | ->expects($this->exactly(2))
77 | ->method('__invoke');
78 |
79 | return $mock;
80 | }
81 |
82 | /**
83 | * Creates a callable that must not be called once.
84 | *
85 | * @return callable|\PHPUnit_Framework_MockObject_MockObject
86 | */
87 | public function expectCallableNever()
88 | {
89 | $mock = $this->createCallableMock();
90 | $mock
91 | ->expects($this->never())
92 | ->method('__invoke');
93 |
94 | return $mock;
95 | }
96 |
97 | /**
98 | * Creates a callable mock.
99 | *
100 | * @return callable|\PHPUnit_Framework_MockObject_MockObject
101 | */
102 | public function createCallableMock()
103 | {
104 | return $this->getMock(Callback::class);
105 | }
106 |
107 | /**
108 | * @return LoopInterface|\PHPUnit_Framework_MockObject_MockObject
109 | */
110 | public function createLoopMock()
111 | {
112 | return $this->getMock('Dazzle\Loop\LoopInterface');
113 | }
114 |
115 | /**
116 | * @return LoopInterface|\PHPUnit_Framework_MockObject_MockObject
117 | */
118 | public function createWritableLoopMock()
119 | {
120 | $loop = $this->createLoopMock();
121 | $loop
122 | ->expects($this->once())
123 | ->method('addWriteStream')
124 | ->will($this->returnCallback(function($stream, $listener) {
125 | call_user_func($listener, $stream);
126 | }));
127 |
128 | return $loop;
129 | }
130 |
131 | /**
132 | * @return LoopInterface|\PHPUnit_Framework_MockObject_MockObject
133 | */
134 | public function createReadableLoopMock()
135 | {
136 | $loop = $this->createLoopMock();
137 | $loop
138 | ->expects($this->once())
139 | ->method('addReadStream')
140 | ->will($this->returnCallback(function($stream, $listener) {
141 | call_user_func($listener, $stream);
142 | }));
143 |
144 | return $loop;
145 | }
146 |
147 | /**
148 | * Check if protected property exists.
149 | *
150 | * @param object $object
151 | * @param string $property
152 | * @return bool
153 | */
154 | public function existsProtectedProperty($object, $property)
155 | {
156 | $reflection = new ReflectionClass($object);
157 | return $reflection->hasProperty($property);
158 | }
159 |
160 | /**
161 | * Get protected property from given object via reflection.
162 | *
163 | * @param object $object
164 | * @param string $property
165 | * @return mixed
166 | */
167 | public function getProtectedProperty($object, $property)
168 | {
169 | $reflection = new ReflectionClass($object);
170 | $reflection_property = $reflection->getProperty($property);
171 | $reflection_property->setAccessible(true);
172 |
173 | return $reflection_property->getValue($object);
174 | }
175 |
176 | /**
177 | * Set protected property on a given object via reflection.
178 | *
179 | * @param object $object
180 | * @param string $property
181 | * @param mixed $value
182 | * @return object
183 | */
184 | public function setProtectedProperty($object, $property, $value)
185 | {
186 | $reflection = new ReflectionClass($object);
187 | $reflection_property = $reflection->getProperty($property);
188 | $reflection_property->setAccessible(true);
189 | $reflection_property->setValue($object, $value);
190 |
191 | return $object;
192 | }
193 |
194 | /**
195 | * Call protected method on a given object via reflection.
196 | *
197 | * @param object|string $objectOrClass
198 | * @param string $method
199 | * @param mixed[] $args
200 | * @return mixed
201 | */
202 | public function callProtectedMethod($objectOrClass, $method, $args = [])
203 | {
204 | $reflection = new ReflectionClass($objectOrClass);
205 | $reflectionMethod = $reflection->getMethod($method);
206 | $reflectionMethod->setAccessible(true);
207 | $reflectionTarget = is_object($objectOrClass) ? $objectOrClass : null;
208 |
209 | return $reflectionMethod->invokeArgs($reflectionTarget, $args);
210 | }
211 | }
212 |
--------------------------------------------------------------------------------
/test/_Simulation/Event.php:
--------------------------------------------------------------------------------
1 | name = $name;
24 | $this->data = $data;
25 | }
26 |
27 | /**
28 | * @return mixed
29 | */
30 | public function name()
31 | {
32 | return $this->name;
33 | }
34 |
35 | /**
36 | * @return mixed[]
37 | */
38 | public function data()
39 | {
40 | return $this->data;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/test/_Simulation/EventCollection.php:
--------------------------------------------------------------------------------
1 | loop = $loop;
95 | $this->scenario = function() {};
96 | $this->state = static::STATE_PENDING;
97 | $this->events = [];
98 | $this->stateMessage = null;
99 | $this->skipMessage = null;
100 | $this->startCallback = function() {};
101 | $this->stopCallback = function() {};
102 | $this->stopFlags = false;
103 | }
104 |
105 | /**
106 | *
107 | */
108 | public function __destruct()
109 | {
110 | $this->stop();
111 |
112 | unset($loop);
113 | unset($this->scenario);
114 | unset($this->events);
115 | unset($this->state);
116 | unset($this->stateMessage);
117 | unset($this->startCallback);
118 | unset($this->stopCallback);
119 | unset($this->stopFlags);
120 | }
121 |
122 | /**
123 | * @param string $key
124 | * @param mixed $val
125 | */
126 | public function setParam($key, $val)
127 | {
128 | $this->params[$key] = $val;
129 | }
130 |
131 | /**
132 | * @param string $key
133 | * @return mixed|null
134 | */
135 | public function getParam($key)
136 | {
137 | return isset($this->params[$key]) ? $this->params[$key] : null;
138 | }
139 |
140 | /**
141 | * @param callable(SimulationInterface) $scenario
142 | */
143 | public function setScenario(callable $scenario)
144 | {
145 | $this->scenario = $scenario;
146 | }
147 |
148 | /**
149 | * @return callable(SimulationInterface)|null $scenario
150 | */
151 | public function getScenario()
152 | {
153 | return $this->scenario;
154 | }
155 |
156 | /**
157 | * @return LoopInterface
158 | */
159 | public function getLoop()
160 | {
161 | return $this->loop;
162 | }
163 |
164 | /**
165 | * @return int
166 | */
167 | public function getState()
168 | {
169 | return $this->state;
170 | }
171 |
172 | /**
173 | * @return int
174 | */
175 | public function getStateMessage()
176 | {
177 | return $this->stateMessage;
178 | }
179 |
180 | /**
181 | *
182 | */
183 | public function begin()
184 | {
185 | $this->start();
186 | }
187 |
188 | /**
189 | *
190 | */
191 | public function done()
192 | {
193 | $this->state = static::STATE_SUCCEED;
194 | $this->stop();
195 | }
196 |
197 | /**
198 | *
199 | */
200 | public function skip($message)
201 | {
202 | $this->stateMessage = $message;
203 | $this->state = static::STATE_SKIPPED;
204 | $this->stop();
205 | }
206 |
207 | /**
208 | *
209 | */
210 | public function fail($message)
211 | {
212 | $this->stateMessage = $message;
213 | $this->state = static::STATE_FAILED;
214 | $this->stop();
215 | }
216 |
217 | /**
218 | * @param mixed $expected
219 | * @param mixed $actual
220 | * @param string $message
221 | */
222 | public function assertSame($expected, $actual, $message = "Assertion failed, expected \"%s\" got \"%s\"")
223 | {
224 | if ($expected !== $actual)
225 | {
226 | $stringExpected = (is_object($expected) || is_array($expected)) ? json_encode($expected) : (string) $expected;
227 | $stringActual = (is_object($actual) || is_array($actual)) ? json_encode($actual) : (string) $actual;
228 |
229 | $this->fail(sprintf($message, $stringExpected, $stringActual));
230 | }
231 | }
232 |
233 | /**
234 | * @param string $name
235 | * @param mixed $data
236 | */
237 | public function expect($name, $data = [])
238 | {
239 | $this->events[] = new Event($name, $data);
240 | }
241 |
242 | /**
243 | * @return Event[]
244 | */
245 | public function getExpectations()
246 | {
247 | return $this->events;
248 | }
249 |
250 | /**
251 | * @param callable $callable
252 | */
253 | public function onStart(callable $callable)
254 | {
255 | $this->startCallback = $callable;
256 | }
257 |
258 | /**
259 | * @param callable $callable
260 | */
261 | public function onStop(callable $callable)
262 | {
263 | $this->stopCallback = $callable;
264 | }
265 |
266 | /**
267 | * @param string $model
268 | * @param mixed[] $config
269 | * @return object
270 | */
271 | public function reflect($model, $config = [])
272 | {
273 | foreach ($config as $key=>$value)
274 | {
275 | if ($value === 'Dazzle\Loop\Loop' || $value === 'Dazzle\Loop\LoopInterface')
276 | {
277 | $config[$key] = $this->getLoop();
278 | }
279 | }
280 |
281 | return (new ReflectionClass($model))->newInstanceArgs($config);
282 | }
283 |
284 | /**
285 | * @throws Exception
286 | */
287 | private function start()
288 | {
289 | $sim = $this;
290 |
291 | $scenario = $this->scenario;
292 | $scenario($sim);
293 |
294 | if ($this->stopFlags === true)
295 | {
296 | return;
297 | }
298 |
299 | $onStart = $this->startCallback;
300 | $loop = $this->loop;
301 |
302 | $loop->onStart(function() use($sim, $onStart) {
303 | $onStart($sim);
304 | });
305 | $loop->addTimer(5, function() use($sim) {
306 | $sim->fail('Timeout for test has been reached.');
307 | });
308 |
309 | $loop->start();
310 | }
311 |
312 | /**
313 | *
314 | */
315 | private function stop()
316 | {
317 | if ($this->loop !== null && $this->loop->isRunning())
318 | {
319 | $this->loop->stop();
320 | }
321 |
322 | if ($this->stopFlags === false)
323 | {
324 | $callable = $this->stopCallback;
325 | $callable($this);
326 | }
327 |
328 | $this->stopFlags = true;
329 | }
330 | }
331 |
--------------------------------------------------------------------------------
/test/_Simulation/SimulationInterface.php:
--------------------------------------------------------------------------------
1 |