Skip to content

Commit 7fb7d1d

Browse files
committed
RediSearch 2.2.0 compatibility
1 parent 523a273 commit 7fb7d1d

File tree

7 files changed

+312
-2
lines changed

7 files changed

+312
-2
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1313
- Add compatibility for Predis version 2.x
1414
- (dev) Add `make clean` to remove all generated files
1515
- `LOAD ALL` option on Aggregate command (RediSearch `2.0.13`)
16+
- Profile command (RediSearch `2.2.0`) ([Issue#4])
1617

1718
### Fixed
1819

@@ -218,6 +219,7 @@ First version
218219
[1.0.0]: https://github.com/MacFJA/php-redisearch/releases/tag/1.0.0
219220

220221
[Issue#2]: https://github.com/MacFJA/php-redisearch/issues/2
222+
[Issue#4]: https://github.com/MacFJA/php-redisearch/issues/4
221223
[Issue#5]: https://github.com/MacFJA/php-redisearch/issues/5
222224
[Issue#6]: https://github.com/MacFJA/php-redisearch/issues/6
223225
[Issue#9]: https://github.com/MacFJA/php-redisearch/issues/9

src/Redis/Command/AbstractCommand.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
*/
3434
abstract class AbstractCommand implements Command
3535
{
36-
public const MAX_IMPLEMENTED_VERSION = '2.0.13';
36+
public const MAX_IMPLEMENTED_VERSION = '2.2.0';
3737
public const MIN_IMPLEMENTED_VERSION = '2.0.0';
3838

3939
/**

src/Redis/Command/Profile.php

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* Copyright MacFJA
7+
*
8+
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
9+
* documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
10+
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
11+
* permit persons to whom the Software is furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
14+
* Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
17+
* WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18+
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19+
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20+
*/
21+
22+
namespace MacFJA\RediSearch\Redis\Command;
23+
24+
use MacFJA\RediSearch\Redis\Command\Option\CustomValidatorOption as CV;
25+
use MacFJA\RediSearch\Redis\Command\Option\FlagOption;
26+
use MacFJA\RediSearch\Redis\Command\Option\NamelessOption;
27+
use MacFJA\RediSearch\Redis\Command\ProfileCommand\QueryOption;
28+
29+
class Profile extends AbstractCommand
30+
{
31+
public function __construct(string $rediSearchVersion = self::MIN_IMPLEMENTED_VERSION)
32+
{
33+
parent::__construct([
34+
'index' => new NamelessOption(null, '>=2.2.0'),
35+
'type' => CV::allowedValues(new NamelessOption(null, '>=2.2.0'), ['SEARCH', 'AGGREGATE']),
36+
'limited' => new FlagOption('LIMITED', false, '>=2.2.0'),
37+
'query' => new QueryOption('>=2.2.0'),
38+
], $rediSearchVersion);
39+
}
40+
41+
public function setIndex(string $index): self
42+
{
43+
$this->options['index']->setValue($index);
44+
45+
return $this;
46+
}
47+
48+
/**
49+
* @param Aggregate|Search $query
50+
*/
51+
public function setQuery($query): self
52+
{
53+
/** @var QueryOption $queryOption */
54+
$queryOption = $this->options['query'];
55+
$queryOption->setCommand($query);
56+
$this->options['type']->setValue($queryOption->isSearch() ? 'SEARCH' : 'AGGREGATE');
57+
$this->options['index']->setValue($queryOption->getIndex());
58+
59+
return $this;
60+
}
61+
62+
public function setTypeAggregate(): self
63+
{
64+
$this->options['type']->setValue('AGGREGATE');
65+
66+
return $this;
67+
}
68+
69+
public function setTypeSearch(): self
70+
{
71+
$this->options['type']->setValue('SEARCH');
72+
73+
return $this;
74+
}
75+
76+
public function setLimited(bool $active = true): self
77+
{
78+
$this->options['limited']->setActive($active);
79+
80+
return $this;
81+
}
82+
83+
public function getId(): string
84+
{
85+
return 'FT.PROFILE';
86+
}
87+
88+
protected function getRequiredOptions(): array
89+
{
90+
return ['index', 'type', 'query'];
91+
}
92+
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* Copyright MacFJA
7+
*
8+
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
9+
* documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
10+
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
11+
* permit persons to whom the Software is furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
14+
* Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
17+
* WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18+
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19+
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20+
*/
21+
22+
namespace MacFJA\RediSearch\Redis\Command\ProfileCommand;
23+
24+
use function assert;
25+
use MacFJA\RediSearch\Redis\Command\Aggregate;
26+
use MacFJA\RediSearch\Redis\Command\Option\AbstractCommandOption;
27+
use MacFJA\RediSearch\Redis\Command\Search;
28+
29+
class QueryOption extends AbstractCommandOption
30+
{
31+
/**
32+
* @var null|Aggregate|Search
33+
*/
34+
private $command;
35+
36+
/**
37+
* @param Aggregate|Search $command
38+
*/
39+
public function setCommand($command): self
40+
{
41+
$this->command = $command;
42+
43+
return $this;
44+
}
45+
46+
public function isValid(): bool
47+
{
48+
return $this->command instanceof Search || $this->command instanceof Aggregate;
49+
}
50+
51+
public function getOptionData()
52+
{
53+
return [
54+
'command' => $this->command,
55+
];
56+
}
57+
58+
public function isSearch(): bool
59+
{
60+
return $this->command instanceof Search;
61+
}
62+
63+
public function getIndex(): string
64+
{
65+
assert($this->command instanceof Search || $this->command instanceof Aggregate);
66+
67+
return $this->command->getIndex();
68+
}
69+
70+
protected function doRender(?string $version): array
71+
{
72+
assert($this->command instanceof Search || $this->command instanceof Aggregate);
73+
$arguments = $this->command->getArguments();
74+
// remove index
75+
array_shift($arguments);
76+
77+
return array_merge(['QUERY'], $arguments);
78+
}
79+
}

src/Redis/Command/Search.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@
4242
use MacFJA\RediSearch\Redis\Response\SearchResponseItem;
4343

4444
/**
45-
* @method PaginatedResponse<SearchResponseItem> parseResponse(mixed $data)
4645
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
4746
*/
4847
class Search extends AbstractCommand implements PaginatedCommand
@@ -90,6 +89,11 @@ public function setIndex(string $index): self
9089
return $this;
9190
}
9291

92+
public function getIndex(): string
93+
{
94+
return $this->options['index']->getValue();
95+
}
96+
9397
public function setQuery(string $query): self
9498
{
9599
$this->options['query']->setValue($query);
@@ -306,6 +310,7 @@ public function getSize(): ?int
306310
* @param mixed $data
307311
*
308312
* @return PaginatedResponse
313+
* @psalm-return PaginatedResponse<SearchResponseItem>
309314
*
310315
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
311316
* @SuppressWarnings(PHPMD.NPathComplexity)

tests/Redis/Command/ProfileTest.php

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* Copyright MacFJA
7+
*
8+
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
9+
* documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
10+
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
11+
* permit persons to whom the Software is furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
14+
* Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
17+
* WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18+
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19+
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20+
*/
21+
22+
namespace MacFJA\RediSearch\tests\Redis\Command;
23+
24+
use MacFJA\RediSearch\Redis\Command\Aggregate;
25+
use MacFJA\RediSearch\Redis\Command\Profile;
26+
use MacFJA\RediSearch\Redis\Command\Search;
27+
use PHPUnit\Framework\TestCase;
28+
29+
/**
30+
* @covers \MacFJA\RediSearch\Redis\Command\AbstractCommand
31+
*
32+
* @covers \MacFJA\RediSearch\Redis\Command\Profile
33+
* @covers \MacFJA\RediSearch\Redis\Command\ProfileCommand\QueryOption
34+
*
35+
* @uses \MacFJA\RediSearch\Redis\Command\Option\AbstractCommandOption
36+
* @uses \MacFJA\RediSearch\Redis\Command\Option\CustomValidatorOption
37+
* @uses \MacFJA\RediSearch\Redis\Command\Option\NamelessOption
38+
* @uses \MacFJA\RediSearch\Redis\Command\Option\NamedOption
39+
* @uses \MacFJA\RediSearch\Redis\Command\Option\FlagOption
40+
* @uses \MacFJA\RediSearch\Redis\Command\Option\GroupedOption
41+
* @uses \MacFJA\RediSearch\Redis\Command\Option\NotEmptyOption
42+
* @uses \MacFJA\RediSearch\Redis\Command\Option\NumberedOption
43+
* @uses \MacFJA\RediSearch\Redis\Command\Search
44+
* @uses \MacFJA\RediSearch\Redis\Command\Aggregate
45+
* @uses \MacFJA\RediSearch\Redis\Command\SearchCommand\GeoFilterOption
46+
* @uses \MacFJA\RediSearch\Redis\Command\SearchCommand\HighlightOption
47+
* @uses \MacFJA\RediSearch\Redis\Command\SearchCommand\LimitOption
48+
* @uses \MacFJA\RediSearch\Redis\Command\SearchCommand\SortByOption
49+
* @uses \MacFJA\RediSearch\Redis\Command\SearchCommand\SummarizeOption
50+
* @uses \MacFJA\RediSearch\Redis\Command\AggregateCommand\SortByOption
51+
* @uses \MacFJA\RediSearch\Redis\Command\AggregateCommand\WithCursor
52+
*
53+
* @internal
54+
*/
55+
class ProfileTest extends TestCase
56+
{
57+
public function testGetId(): void
58+
{
59+
$command = new Profile();
60+
static::assertSame('FT.PROFILE', $command->getId());
61+
}
62+
63+
public function testFullOption(): void
64+
{
65+
$aggregate = new Aggregate(Profile::MAX_IMPLEMENTED_VERSION);
66+
$aggregate->setQuery('@foo:bar')->setIndex('idx');
67+
$command = new Profile(Profile::MAX_IMPLEMENTED_VERSION);
68+
$command
69+
->setIndex('idx')
70+
->setTypeAggregate()
71+
->setLimited()
72+
->setQuery($aggregate)
73+
;
74+
75+
static::assertSame([
76+
'idx', 'AGGREGATE', 'LIMITED', 'QUERY', '@foo:bar',
77+
], $command->getArguments());
78+
}
79+
80+
public function testSearch(): void
81+
{
82+
$search = new Search('2.2.0');
83+
$search->setIndex('idx')->setQuery('@foo:bar');
84+
$command = new Profile('2.2.0');
85+
$command
86+
->setIndex('idx')
87+
->setTypeSearch()
88+
->setQuery($search)
89+
;
90+
91+
static::assertSame([
92+
'idx', 'SEARCH', 'QUERY', '@foo:bar',
93+
], $command->getArguments());
94+
}
95+
96+
public function testAutoFill(): void
97+
{
98+
$search = new Search('2.2.0');
99+
$search->setIndex('idx')->setQuery('@foo:bar');
100+
$command = new Profile('2.2.0');
101+
$command
102+
->setQuery($search)
103+
;
104+
105+
static::assertSame([
106+
'idx', 'SEARCH', 'QUERY', '@foo:bar',
107+
], $command->getArguments());
108+
}
109+
110+
public function testOverride(): void
111+
{
112+
$search = new Search('2.2.0');
113+
$search->setIndex('idx')->setQuery('@foo:bar');
114+
$command = new Profile('2.2.0');
115+
$command
116+
->setQuery($search)
117+
->setIndex('idx2')
118+
->setTypeAggregate()
119+
;
120+
121+
static::assertSame([
122+
'idx2', 'AGGREGATE', 'QUERY', '@foo:bar',
123+
], $command->getArguments());
124+
}
125+
}

tests/Redis/Command/SearchTest.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,13 @@ public function testGetId(): void
6363
static::assertSame('FT.SEARCH', $command->getId());
6464
}
6565

66+
public function testGetIndex(): void
67+
{
68+
$command = new Search();
69+
$command->setIndex('idx');
70+
static::assertSame('idx', $command->getIndex());
71+
}
72+
6673
public function testSizeOptions(): void
6774
{
6875
$command = new Search();

0 commit comments

Comments
 (0)