-
-
Notifications
You must be signed in to change notification settings - Fork 338
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adding support for callback comparison on Column, Offset and TeoColum…
…n constraints
- Loading branch information
Showing
10 changed files
with
205 additions
and
32 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace League\Csv\Query\Constraint; | ||
|
||
use ArrayIterator; | ||
use CallbackFilterIterator; | ||
use Closure; | ||
use Iterator; | ||
use IteratorIterator; | ||
use League\Csv\Query; | ||
use Traversable; | ||
|
||
/** | ||
* Enable filtering a record based on its offset. | ||
* | ||
* When used with PHP's array_filter with the ARRAY_FILTER_USE_BOTH flag | ||
* the record value WILL NOT BE taken into account | ||
*/ | ||
final class Offset implements Query\Predicate | ||
{ | ||
/** | ||
* @throws Query\QueryException | ||
*/ | ||
private function __construct( | ||
public readonly Comparison|Closure $operator, | ||
public readonly mixed $value, | ||
) { | ||
if (!$this->operator instanceof Closure) { | ||
$this->operator->accept($this->value); | ||
} | ||
} | ||
|
||
/** | ||
* @throws Query\QueryException | ||
*/ | ||
public static function filterOn( | ||
Comparison|Closure|string $operator, | ||
mixed $value = null, | ||
): self { | ||
if ($operator instanceof Closure) { | ||
return new self($operator, null); | ||
} | ||
|
||
return new self( | ||
is_string($operator) ? Comparison::fromOperator($operator) : $operator, | ||
$value | ||
); | ||
} | ||
|
||
/** | ||
* @throws Query\QueryException | ||
*/ | ||
public function __invoke(mixed $value, int|string $key): bool | ||
{ | ||
if ($this->operator instanceof Closure) { | ||
return ($this->operator)($key); | ||
} | ||
|
||
return $this->operator->compare($key, $this->value); | ||
} | ||
|
||
public function filter(iterable $value): Iterator | ||
{ | ||
return new CallbackFilterIterator(match (true) { | ||
$value instanceof Iterator => $value, | ||
$value instanceof Traversable => new IteratorIterator($value), | ||
default => new ArrayIterator($value), | ||
}, $this); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
<?php | ||
|
||
/** | ||
* League.Csv (https://csv.thephpleague.com) | ||
* | ||
* (c) Ignace Nyamagana Butera <nyamsprod@gmail.com> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
declare(strict_types=1); | ||
|
||
namespace League\Csv\Query\Constraint; | ||
|
||
use League\Csv\Query\QueryException; | ||
use League\Csv\Query\QueryTestCase; | ||
use PHPUnit\Framework\Attributes\Test; | ||
|
||
final class OffsetTest extends QueryTestCase | ||
{ | ||
#[Test] | ||
public function it_can_filter_the_tabular_data_based_on_the_offset_value(): void | ||
{ | ||
$predicate = Offset::filterOn('<', 2); | ||
$result = $this->stmt->where($predicate)->process($this->document); | ||
|
||
self::assertCount(1, $result); | ||
} | ||
|
||
#[Test] | ||
public function it_can_filter_the_tabular_data_based_on_the_offset_value_and_a_callback(): void | ||
{ | ||
$predicate = Offset::filterOn(fn (int $key): bool => $key % 2 === 0); | ||
$result = $this->stmt->where($predicate)->process($this->document); | ||
|
||
self::assertCount(2, $result); | ||
} | ||
|
||
#[Test] | ||
public function it_will_throw_if_the_offset_values_are_invalidf(): void | ||
{ | ||
$this->expectException(QueryException::class); | ||
|
||
Offset::filterOn('NOT IN', 'Dakar'); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.