Skip to content

Commit

Permalink
Fix bug with Statement implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
nyamsprod committed Jan 13, 2024
1 parent ecef445 commit c075ed4
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 4 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ All Notable changes to `Csv` will be documented in this file
### Fixed

- `Reader::select` and `ResultSet::select` now internally use `Statement::select`
- `Statement` should not throw when `LimitIterator` is used in combinaison with `ArrayIterator`.

### Removed

Expand Down
21 changes: 17 additions & 4 deletions src/Statement.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
use Iterator;
use LimitIterator;

use OutOfBoundsException;

use function array_key_exists;
use function array_reduce;
use function array_search;
Expand Down Expand Up @@ -153,9 +155,8 @@ public function process(TabularDataReader $tabular_data, array $header = []): Ta
$header = $tabular_data->getHeader();
}

$iterator = $this->buildOrderBy(
array_reduce($this->where, $this->filter(...), $tabular_data->getRecords($header))
);
$iterator = array_reduce($this->where, $this->filter(...), $tabular_data->getRecords($header));
$iterator = $this->buildOrderBy($iterator);
/** @var Iterator<array-key, array<array-key, string|null>> $iterator */
$iterator = new LimitIterator($iterator, $this->offset, $this->limit);

Expand Down Expand Up @@ -189,8 +190,20 @@ protected function buildOrderBy(Iterator $iterator): Iterator
return $cmp ?? 0;
};


$class = new class () extends ArrayIterator {
public function seek(int $offset): void
{
try {
parent::seek($offset);
} catch (OutOfBoundsException) {
return;
}
}
};

/** @var ArrayIterator<array-key, array<string|null>> $it */
$it = new ArrayIterator([...$iterator]);
$it = new $class([...$iterator]);
$it->uasort($compare);

return $it;
Expand Down
24 changes: 24 additions & 0 deletions src/StatementTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -156,4 +156,28 @@ public function testHeaderMapperOnStatement(): void
'does not exists' => null,
], $results->first());
}

public function testOrderByDoesNotThrowOnInvalidOffsetOrLimit(): void
{
$document = <<<CSV
Integer,Float,Text,Multiline Text,Date and Time
1,1.11,Foo,"Foo
Bar",2020-01-01 01:01:01
2,1.22,Bar,"Bar
Baz",2020-02-02 02:02:02
3,1.33,Baz,"Baz
Foo",2020-03-03 03:03:03
CSV;

$csv = Reader::createFromString($document);
$csv->setHeaderOffset(0);
$constraints = Statement::create()
->select('Integer', 'Text', 'Date and Time')
->where(fn (array $record): bool => (float) $record['Float'] < 1.3)
->orderBy(fn (array $record1, array $record2): int => (int) $record2['Integer'] <=> (int) $record1['Integer'])
->limit(5)
->offset(2);

self::assertSame([], $constraints->process($csv)->nth(42));
}
}

0 comments on commit c075ed4

Please sign in to comment.