diff --git a/CHANGELOG.md b/CHANGELOG.md index ecf75a54..bb1ac3e2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ All Notable changes to `Csv` will be documented in this file ### Added - `JsonConverter::withPrettyPrint` now accepts an optional `$identSize` parameter as its unique parameter. +- `Statement::when` to enable conditionable query building. ### Deprecated diff --git a/docs/9.0/reader/statement.md b/docs/9.0/reader/statement.md index a050cdaa..753fc02b 100644 --- a/docs/9.0/reader/statement.md +++ b/docs/9.0/reader/statement.md @@ -406,6 +406,41 @@ $records = $constraints->process($csv); Since a `Statement` instance is independent of the CSV document you can re-use it on different CSV documents or `TabularDataReader` instances if needed. +### Adding constraint on condition + +
+ +The `Statement::class` now allows the building or the CSV query using conditions. + +```php +$stmt = Statement::create(); +if ($condition) { + $stmt = $stmt->where(fn (array $row) => $row['column'] !== 'data'); +} else { + $stmt = $stmt->where(fn (array $row) => $row['column'] === 'data'); +} +``` + +becomes + +```php +$stmt = Statement::create() + ->when( + $condition, + fn (Statement $q) => $q->where(fn (array $row) => $row['column'] !== 'data'), + fn (Statement $q) => $q->where(fn (array $row) => $row['column'] === 'data'), + ); +) +``` + +The `else` expression is not required but if present in **MUST BE** a callable which only +accepts the `Statement` instance and returns `null` or a `Statement` instance. + +The only requirements are: + +- that the condition is a `boolean` or a callable that returns a `boolean`. +- the callback returns a `Statement` instance or null. + ## FragmentFinder diff --git a/src/Statement.php b/src/Statement.php index e89e4889..7cf193e1 100644 --- a/src/Statement.php +++ b/src/Statement.php @@ -292,6 +292,26 @@ public function limit(int $limit): self return $clone; } + /** + * Apply the callback if the given "condition" is (or resolves to) true. + * + * @param (callable($this): bool)|bool $condition + * @param callable($this): (self|null) $onSuccess + * @param ?callable($this): (self|null) $onFail + */ + public function when(callable|bool $condition, callable $onSuccess, ?callable $onFail = null): self + { + if (!is_bool($condition)) { + $condition = $condition($this); + } + + return match (true) { + $condition => $onSuccess($this), + null !== $onFail => $onFail($this), + default => $this, + } ?? $this; + } + /** * Executes the prepared Statement on the {@link TabularDataReader} object. * @@ -437,7 +457,6 @@ protected function buildOrderBy(Iterator $iterator): Iterator return $cmp ?? 0; }; - $class = new class () extends ArrayIterator { public function seek(int $offset): void {