Skip to content

Commit

Permalink
Adopt for last changes
Browse files Browse the repository at this point in the history
  • Loading branch information
Gerych1984 committed Nov 23, 2023
1 parent 3496ff7 commit 15addeb
Show file tree
Hide file tree
Showing 6 changed files with 197 additions and 13 deletions.
21 changes: 14 additions & 7 deletions src/AbstractQueryDataReader.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@
use Yiisoft\Data\Reader\FilterInterface;
use Yiisoft\Data\Reader\Sort;
use Yiisoft\Db\Query\QueryInterface;

use function array_key_first;
use function is_array;
use function is_object;
use function sprintf;

/**
Expand Down Expand Up @@ -107,8 +107,9 @@ public function getIterator(): Generator
} else {
$iterator = $this->getPreparedQuery()->each($this->batchSize);

/** @var array|object $row */
foreach ($iterator as $index => $row) {
yield $index => $row;
yield $index => $this->createItem($row);

Check warning on line 112 in src/AbstractQueryDataReader.php

View check run for this annotation

Codecov / codecov/patch

src/AbstractQueryDataReader.php#L112

Added line #L112 was not covered by tests
}
}
}
Expand Down Expand Up @@ -158,8 +159,12 @@ public function getPreparedQuery(): QueryInterface
return $query;
}

protected function getHandlerByOperation(string $operation): QueryHandlerInterface
public function getHandlerByOperation(string|FilterInterface $operation): QueryHandlerInterface
{
if (is_object($operation)) {
$operation = $operation::getOperator();
}

if (!isset($this->filterHandlers[$operation])) {
throw new RuntimeException(sprintf('Operation "%s" is not supported', $operation));
}
Expand All @@ -170,7 +175,7 @@ protected function getHandlerByOperation(string $operation): QueryHandlerInterfa
protected function applyFilter(QueryInterface $query): QueryInterface
{
if ($this->filter !== null) {
$query = $this->getHandlerByOperation($this->filter::getOperator())
$query = $this->getHandlerByOperation($this->filter)
->applyFilter($query, $this->filter);
}

Expand All @@ -180,7 +185,7 @@ protected function applyFilter(QueryInterface $query): QueryInterface
protected function applyHaving(QueryInterface $query): QueryInterface
{
if ($this->having !== null) {
$query = $this->getHandlerByOperation($this->having::getOperator())
$query = $this->getHandlerByOperation($this->having)
->applyHaving($query, $this->having);
}

Expand Down Expand Up @@ -366,11 +371,13 @@ public function readOne(): array|object|null
return $key === null ? null : $this->data[$key];
}

return $this->withLimit(1)->getIterator()->current();
$current = $this->withLimit(1)->getIterator()->current();

return $current === null ? null : $this->createItem($current);
}

/**
* @psalm-return TValue
*/
abstract protected function createItem(array $row): array|object;
abstract protected function createItem(array|object $row): array|object;
}
2 changes: 1 addition & 1 deletion src/QueryDataReader.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
*/
final class QueryDataReader extends AbstractQueryDataReader
{
protected function createItem(array $row): array
protected function createItem(array|object $row): array|object

Check warning on line 17 in src/QueryDataReader.php

View check run for this annotation

Codecov / codecov/patch

src/QueryDataReader.php#L17

Added line #L17 was not covered by tests
{
/** @psalm-var TValue */
return $row;
Expand Down
115 changes: 110 additions & 5 deletions tests/DataReaderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,32 @@
namespace Yiisoft\Data\Db\Tests;

use PHPUnit\Framework\TestCase;
use Yiisoft\Data\Db\Filter\Between;
use Yiisoft\Data\Db\Filter\Equals;
use Yiisoft\Data\Db\Filter\GreaterThan;
use Yiisoft\Data\Db\Filter\GreaterThanOrEqual;
use Yiisoft\Data\Db\Filter\ILike;
use Yiisoft\Data\Db\Filter\In;
use Yiisoft\Data\Db\Filter\LessThan;
use Yiisoft\Data\Db\Filter\LessThanOrEqual;
use Yiisoft\Data\Db\Filter\Like;
use Yiisoft\Data\Db\Filter\NotEquals;
use Yiisoft\Data\Db\FilterHandler\BetweenHandler;
use Yiisoft\Data\Db\FilterHandler\EqualsHandler;
use Yiisoft\Data\Db\FilterHandler\GreaterThanHandler;
use Yiisoft\Data\Db\FilterHandler\GreaterThanOrEqualHandler;
use Yiisoft\Data\Db\FilterHandler\ILikeHandler;
use Yiisoft\Data\Db\FilterHandler\InHandler;
use Yiisoft\Data\Db\FilterHandler\LessThanHandler;
use Yiisoft\Data\Db\FilterHandler\LessThanOrEqualHandler;
use Yiisoft\Data\Db\FilterHandler\LikeHandler;
use Yiisoft\Data\Db\FilterHandler\NotEqualsHandler;
use Yiisoft\Data\Db\QueryDataReader;
use Yiisoft\Data\Db\Tests\Support\CustomerDataReader;
use Yiisoft\Data\Db\Tests\Support\CustomerDTO;
use Yiisoft\Data\Db\Tests\Support\CustomerQuery;
use Yiisoft\Data\Db\Tests\Support\TestTrait;
use Yiisoft\Data\Reader\FilterInterface;
use Yiisoft\Data\Reader\Sort;
use Yiisoft\Db\Expression\Expression;
use Yiisoft\Db\Query\Query;
Expand Down Expand Up @@ -42,8 +66,8 @@ public function testOffset(): void
$actual = $dataReader->getPreparedQuery()->createCommand()->getRawSql();
$expected = $query->createCommand()->getRawSql();

$this->assertSame($expected, $actual);
$this->assertStringEndsWith('OFFSET 2', $actual);
self::assertSame($expected, $actual);
self::assertStringEndsWith('OFFSET 2', $actual);
}

public function testLimit(): void
Expand All @@ -62,8 +86,8 @@ public function testLimit(): void
$actual = $dataReader->getPreparedQuery()->createCommand()->getRawSql();
$expected = $query->createCommand()->getRawSql();

$this->assertSame($expected, $actual);
$this->assertStringEndsWith('LIMIT 1 OFFSET 1', $actual);
self::assertSame($expected, $actual);
self::assertStringEndsWith('LIMIT 1 OFFSET 1', $actual);
}

public function sortDataProvider(): array
Expand Down Expand Up @@ -132,9 +156,90 @@ public function testSort(Sort $sort, string $expected): void
$dataReader = (new QueryDataReader($query))
->withSort($sort);

$this->assertStringEndsWith(
self::assertStringEndsWith(
$expected,
$dataReader->getPreparedQuery()->createCommand()->getRawSql()
);
}

public static function handlerDataProvider(): array
{
return [
[
new Equals('equals', 1),
EqualsHandler::class,
],
[
new Between('column', [100, 300]),
BetweenHandler::class,
],
[
new GreaterThan('column', 1000),
GreaterThanHandler::class,
],
[
new GreaterThanOrEqual('column', 3.5),
GreaterThanOrEqualHandler::class,
],
[
new LessThan('column', 10.7),
LessThanHandler::class,
],
[
new LessThanOrEqual('column', 100),
LessThanOrEqualHandler::class,
],
[
new In('column', [10, 20, 30]),
InHandler::class,
],
[
new NotEquals('column', 40),
NotEqualsHandler::class,
],
[
new Like('column', 'foo'),
LikeHandler::class,
],
[
new ILike('column', 'foo'),
ILikeHandler::class,
],
];
}

/**
* @dataProvider handlerDataProvider
* @param FilterInterface $filter
* @param string $handler
* @return void
*/
public function testHandlerByOperation(FilterInterface $filter, string $handler): void
{
$db = $this->getConnection();

$query = (new Query($db))
->from('customer');

$dataReader = new QueryDataReader($query);
$filterHandler = $dataReader->getHandlerByOperation($filter);
$filterOperatorHandler = $dataReader->getHandlerByOperation($filter::getOperator());

self::assertInstanceOf($handler, $filterHandler);
self::assertInstanceOf($handler, $filterOperatorHandler);
}

public function testCreateItem(): void
{
$query = new CustomerQuery($this->getConnection());
$dataReader = (new CustomerDataReader($query))
->withBatchSize(null);

self::assertEquals($query->count(), $dataReader->count());
self::assertInstanceOf(CustomerDTO::class, $dataReader->readOne());

foreach ($dataReader->read() as $row) {
self::assertInstanceOf(CustomerDTO::class, $row);
}
}
}
9 changes: 9 additions & 0 deletions tests/Support/CustomerDTO.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

declare(strict_types=1);

namespace Yiisoft\Data\Db\Tests\Support;

final class CustomerDTO
{
}
19 changes: 19 additions & 0 deletions tests/Support/CustomerDataReader.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

declare(strict_types=1);

namespace Yiisoft\Data\Db\Tests\Support;

use Yiisoft\Data\Db\AbstractQueryDataReader;

final class CustomerDataReader extends AbstractQueryDataReader
{

/**
* @inheritDoc
*/
protected function createItem(object|array $row): array|object
{
return new CustomerDTO();
}
}
44 changes: 44 additions & 0 deletions tests/Support/CustomerQuery.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php

declare(strict_types=1);

namespace Yiisoft\Data\Db\Tests\Support;

use Yiisoft\Db\Query\Query;
use function count;

final class CustomerQuery extends Query
{
private array $data = [
[
'id' => 1,
'email' => '[email protected]',
'user1' => 'address1',
],
[
'id' => 2,
'email' => '[email protected]',
'user1' => 'address2',
],
[
'id' => 3,
'email' => '[email protected]',
'user1' => 'address3',
]
];

public function all(): array
{
return $this->data;
}

public function one(): ?array
{
return $this->data[0];
}

public function count(string $q = '*'): int|string
{
return count($this->data);
}
}

0 comments on commit 15addeb

Please sign in to comment.