Skip to content

Commit

Permalink
Improve FragmentFinder public API
Browse files Browse the repository at this point in the history
  • Loading branch information
nyamsprod committed Aug 9, 2024
1 parent e9eb5d7 commit 67b81ab
Show file tree
Hide file tree
Showing 11 changed files with 720 additions and 215 deletions.
19 changes: 19 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,25 @@

All Notable changes to `Csv` will be documented in this file

## [Next] - TBD

### Added

- `League\Csv\Fragment\Expression`

### Deprecated

- None

### Fixed

- `FragmentFinder` now removes duplicate selection.
- `Cast*` methods are accept more input.

### Removed

- None

## [9.16.0](https://github.com/thephpleague/csv/compare/9.15.0...9.16.0) - 2024-05-24

### Added
Expand Down
71 changes: 71 additions & 0 deletions docs/9.0/reader/statement.md
Original file line number Diff line number Diff line change
Expand Up @@ -468,3 +468,74 @@ is invalid;

Both classes, `FragmentFinder` and `Statement` returns an instance that implements the `TabularDataReader` interface
which returns the found data in a consistent way.

### Fragment Expression builder

<p class="message-info">This mechanism is introduced with version <code>9.17.0</code>.</p>

The `Expression` class provides an immutable, fluent interface to create valid expressions.
We can rewrite the previous example as followed:

```php
use League\Csv\Reader;
use League\Csv\Fragment\Expression;
use League\Csv\FragmentFinder;

$reader = Reader::createFromPath('/path/to/file.csv');
$finder = FragmentFinder::create();
$expression = Expression::fromRow('7-5', '8-9');

$finder->findAll($expression, $reader); // return an Iterator<TabularDataReader>
$finder->findFirst($expression, $reader); // return an TabularDataReader
$finder->findFirstOrFail($expression, $reader); // will throw
```

The `Expression` validates that your selections are valid according to the selection scheme chosen.
The class exposes method to create fragment expression for:

- cell selection using `Expression::fromCell`;
- row selection using `Expression::fromRow`;
- column selection using `Expression::fromColumn`;

```php
use League\Csv\Fragment\Expression;

$expression = Expression::fromRow('7-5', '8-9');
echo $expression;
// returns 'row=8-9' and removes `7-5` because it is an invalid selection
```

You can even gradually create your expression using a fluent and immutable API
using the `push`, `unshift` and `remove` methods. And there are convenient method to
inspect the class to know how nmany selections are present and to select them according
to their indices using the `get` a `has` methods. You are also able to tell if a specific
selection in present via the `contains` method.

```php
use League\Csv\Fragment\Expression;

$expression = Expression::fromRow()
->push('5-8')
->unshift('12-15')
->replace('5-8', '12-*')
->remove('12-15');

echo $expression->toString();
// or
echo $expression;
// returns 'row=12-*'
```

You can use que `Expression` to directly query a `TabularDataReader` using the query method.
The result will be an iterable structure containing `Statement` instances. You will still need
to call the `Statement::process` on them in order to get access to the resulting `TabularDataReader`
instances if any exist that fulfill the statement constraints.

```php
$csv = Reader::createFromPath('/path/to/file.csv');
$results = array_map(
fn (Statement $stmt): TabularDataReader => $stmt->process($csv),
Expression::fromRow('7-5', '8-9')->query($csv)
);
//$results is an iterable<TabularDataReader>
```
1 change: 1 addition & 0 deletions docs/9.0/reader/tabular-data-reader.md
Original file line number Diff line number Diff line change
Expand Up @@ -506,6 +506,7 @@ $reader->matchingFirstOrFail('row=3-1;4-6'); // will throw

<p class="message-info"> Wraps the functionality of <code>FragmentFinder</code> class.</p>
<p class="message-notice">Added in version <code>9.12.0</code> for <code>Reader</code> and <code>ResultSet</code>.</p>
<p class="message-info">In addition to using a string expression, starting with version <code>9.17.0</code> you can alternatively use an `Expression` object.</p>

### chunkBy

Expand Down
Loading

0 comments on commit 67b81ab

Please sign in to comment.