Skip to content

Commit

Permalink
Adding Statement::select method
Browse files Browse the repository at this point in the history
  • Loading branch information
nyamsprod committed Jan 9, 2024
1 parent 73038ac commit 21d0177
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 32 deletions.
18 changes: 18 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,24 @@

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

## [Next](https://github.com/thephpleague/csv/compare/9.14.0...master) - TBD

### Added

- `Statement::select`

### Deprecated

- None

### Fixed

- `Reader::select` and `ResultSet::select` now internally use `Statement::select`

### Removed

- None

## [9.14.0](https://github.com/thephpleague/csv/compare/9.13.0...9.14.0) - 2023-12-29

### Added
Expand Down
2 changes: 1 addition & 1 deletion src/Reader.php
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,7 @@ public function matchingFirstOrFail(string $expression): TabularDataReader

public function select(string|int ...$columns): TabularDataReader
{
return ResultSet::createFromTabularDataReader($this)->select(...$columns);
return Statement::create()->select(...$columns)->process($this);
}

/**
Expand Down
30 changes: 1 addition & 29 deletions src/ResultSet.php
Original file line number Diff line number Diff line change
Expand Up @@ -177,35 +177,7 @@ public function sorted(Closure $orderBy): TabularDataReader

public function select(string|int ...$columns): TabularDataReader
{
$header = [];
$documentHeader = $this->getHeader();
$hasNoHeader = [] === $documentHeader;
foreach ($columns as $field) {
if (is_string($field)) {
if ($hasNoHeader) {
throw new InvalidArgument(__METHOD__.' can only use named column if the tabular data has a non-empty header.');
}

$index = array_search($field, $this->header, true);
if (false === $index) {
throw InvalidArgument::dueToInvalidColumnIndex($field, 'offset', __METHOD__);
}

$header[$index] = $field;
continue;
}

if (!$hasNoHeader && !array_key_exists($field, $documentHeader)) {
throw InvalidArgument::dueToInvalidColumnIndex($field, 'offset', __METHOD__);
}

$header[$field] = $documentHeader[$field] ?? $field;
}

/** @var array<int, string> $finalHeader */
$finalHeader = $hasNoHeader ? [] : $header;

return new self($this->combineHeader($header), $finalHeader);
return Statement::create()->select(...$columns)->process($this);
}

public function matching(string $expression): iterable
Expand Down
2 changes: 1 addition & 1 deletion src/Serializer/CastToEnum.php
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ private function cast(string $value): BackedEnum|UnitEnum
return $enum->getCase($value)->getValue();
}

$backedValue = 'int' === $enum->getBackingType()?->getName() ? filter_var($value, Type::Int->filterFlag()) : $value;
$backedValue = 'int' === $enum->getBackingType()->getName() ? filter_var($value, Type::Int->filterFlag()) : $value;

return $this->class::from($backedValue); /* @phpstan-ignore-line */
} catch (Throwable $exception) {
Expand Down
63 changes: 62 additions & 1 deletion src/Statement.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ class Statement
protected int $offset = 0;
/** iterator maximum length. */
protected int $limit = -1;
/** @var array<string|int> */
protected array $select = [];

/**
* @throws Exception
Expand Down Expand Up @@ -136,7 +138,7 @@ public function process(TabularDataReader $tabular_data, array $header = []): Ta
/** @var Iterator<array-key, array<array-key, string|null>> $iterator */
$iterator = new LimitIterator($iterator, $this->offset, $this->limit);

return new ResultSet($iterator, $header);
return $this->applySelect(new ResultSet($iterator, $header));
}

/**
Expand Down Expand Up @@ -172,4 +174,63 @@ protected function buildOrderBy(Iterator $iterator): Iterator

return $it;
}

public function select(string|int ...$columns): self
{
if ($columns === $this->select) {
return $this;
}

$clone = clone $this;
$clone->select = $columns;

return $clone;
}

protected function applySelect(TabularDataReader $tabularDataReader): TabularDataReader
{
if ([] === $this->select) {
return $tabularDataReader;
}

$header = [];
$documentHeader = $tabularDataReader->getHeader();
$hasNoHeader = [] === $documentHeader;
foreach ($this->select as $field) {
if (is_string($field)) {
if ($hasNoHeader) {
throw new InvalidArgument(__METHOD__.' can only use named column if the tabular data has a non-empty header.');
}

$index = array_search($field, $documentHeader, true);
if (false === $index) {
throw InvalidArgument::dueToInvalidColumnIndex($field, 'offset', __METHOD__);
}

$header[$index] = $field;
continue;
}

if (!$hasNoHeader && !array_key_exists($field, $documentHeader)) {
throw InvalidArgument::dueToInvalidColumnIndex($field, 'offset', __METHOD__);
}

$header[$field] = $documentHeader[$field] ?? $field;
}

$records = new MapIterator($tabularDataReader, function (array $record) use ($header): array {
$assocRecord = [];
$row = array_values($record);
foreach ($header as $offset => $headerName) {
$assocRecord[$headerName] = $row[$offset] ?? null;
}

return $assocRecord;
});

/** @var array<string>. $finalHeader */
$finalHeader = $hasNoHeader ? [] : $header;

return new ResultSet($records, $finalHeader);
}
}

0 comments on commit 21d0177

Please sign in to comment.