Skip to content

Commit ffd2a94

Browse files
gam6itkoroxblnfk
authored andcommitted
Add pagination test; fix Select::count()
1 parent 0b65906 commit ffd2a94

File tree

18 files changed

+442
-11
lines changed

18 files changed

+442
-11
lines changed

src/Select.php

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -141,11 +141,10 @@ public function wherePK(string|int|array|object ...$ids): self
141141
public function count(?string $column = null): int
142142
{
143143
if ($column === null) {
144-
// @tuneyourserver solves the issue with counting on queries with joins.
145-
$pk = $this->loader->getPK();
146-
$column = \is_array($pk)
144+
$pk = (array) $this->loader->getPK();
145+
$column = \count($pk) > 1
147146
? '*'
148-
: \sprintf('DISTINCT(%s)', $pk);
147+
: \sprintf('DISTINCT(%s)', \reset($pk));
149148
}
150149

151150
return (int) $this->__call('count', [$column]);

src/Transaction/TupleStorage.php

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,10 @@
44

55
namespace Cycle\ORM\Transaction;
66

7-
use IteratorAggregate;
8-
97
/**
108
* @internal
119
*
12-
* @implements IteratorAggregate<object, Tuple>
10+
* @implements \IteratorAggregate<object, Tuple>
1311
*/
1412
final class TupleStorage implements \IteratorAggregate, \Countable
1513
{
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Cycle\ORM\Tests\Functional\Driver\Common\Integration\Issue528;
6+
7+
use Cycle\ORM\Select;
8+
use Cycle\ORM\Tests\Functional\Driver\Common\BaseTest;
9+
use Cycle\ORM\Tests\Functional\Driver\Common\Integration\IntegrationTestTrait;
10+
use Cycle\ORM\Tests\Functional\Driver\Common\Integration\Issue528\Entity\Country;
11+
use Cycle\ORM\Tests\Traits\TableTrait;
12+
use Spiral\Pagination\Paginator;
13+
14+
abstract class AbstractTestCase extends BaseTest
15+
{
16+
use IntegrationTestTrait;
17+
use TableTrait;
18+
19+
public function testLoadWherePagination(): void
20+
{
21+
$select = (new Select($this->orm, Country::class))
22+
->load('translations')
23+
->where('translations.locale_id', 1);
24+
/** @var Paginator $paginator */
25+
$paginator = (new Paginator(2))->paginate($select);
26+
$data = $select->fetchData();
27+
$this->assertSame(10, $paginator->count());
28+
$this->assertCount(2, $data);
29+
}
30+
31+
public function setUp(): void
32+
{
33+
// Init DB
34+
parent::setUp();
35+
$this->makeTables();
36+
$this->fillData();
37+
38+
$this->loadSchema(__DIR__ . '/schema.php');
39+
}
40+
41+
private function makeTables(): void
42+
{
43+
// Make tables
44+
$this->makeTable('country', [
45+
'id' => 'primary', // autoincrement
46+
'name' => 'string',
47+
]);
48+
49+
$this->makeTable('locale', [
50+
'id' => 'primary',
51+
'code' => 'string',
52+
]);
53+
54+
$this->makeTable('translation', [
55+
'id' => 'primary',
56+
'title' => 'string',
57+
'country_id' => 'int',
58+
'locale_id' => 'int',
59+
]);
60+
$this->makeFK('translation', 'country_id', 'country', 'id', 'NO ACTION', 'NO ACTION');
61+
$this->makeFK('translation', 'locale_id', 'locale', 'id', 'NO ACTION', 'NO ACTION');
62+
}
63+
64+
private function fillData(): void
65+
{
66+
$this->getDatabase()->table('translation')->delete()->run();
67+
$this->getDatabase()->table('country')->delete()->run();
68+
$this->getDatabase()->table('locale')->delete()->run();
69+
70+
$locales = [
71+
['en'],
72+
['ru'],
73+
];
74+
$this->getDatabase()->table('locale')->insertMultiple(
75+
['code'],
76+
$locales,
77+
);
78+
$countries = [
79+
['Russia'],
80+
['USA'],
81+
['China'],
82+
['Kazakhstan'],
83+
['Japan'],
84+
['Germany'],
85+
['France'],
86+
['Italy'],
87+
['Spain'],
88+
['India'],
89+
];
90+
$this->getDatabase()->table('country')->insertMultiple(
91+
['name'],
92+
$countries,
93+
);
94+
95+
$values = [];
96+
foreach ($countries as $i => $country) {
97+
// Duplicate translations for each locale.
98+
// There are 2 same translations for each country.
99+
for ($k = 0; $k < 2; $k++) {
100+
foreach ($locales as $j => $locale) {
101+
$values[] = [$i + 1, $j + 1, "{$country[0]}-{$locale[0]}"];
102+
}
103+
}
104+
}
105+
$this->getDatabase()->table('translation')->insertMultiple(
106+
['country_id', 'locale_id', 'title'],
107+
$values,
108+
);
109+
}
110+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Cycle\ORM\Tests\Functional\Driver\Common\Integration\Issue528\Entity;
6+
7+
class Country
8+
{
9+
public ?int $id = null;
10+
public string $name;
11+
12+
/** @var iterable<Translation> */
13+
public iterable $translations = [];
14+
15+
public function __construct(string $name)
16+
{
17+
$this->name = $name;
18+
}
19+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Cycle\ORM\Tests\Functional\Driver\Common\Integration\Issue528\Entity;
6+
7+
class Locale
8+
{
9+
public ?int $id = null;
10+
public string $code;
11+
12+
/** @var iterable<Translation> */
13+
public iterable $translations = [];
14+
15+
public function __construct(string $code)
16+
{
17+
$this->code = $code;
18+
}
19+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Cycle\ORM\Tests\Functional\Driver\Common\Integration\Issue528\Entity;
6+
7+
class Translation
8+
{
9+
public ?int $id = null;
10+
public Country $country;
11+
public Locale $locale;
12+
public string $title;
13+
14+
public function __construct(Country $country, Locale $locale, string $title)
15+
{
16+
$this->country = $country;
17+
$this->locale = $locale;
18+
$this->title = $title;
19+
}
20+
}
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
use Cycle\ORM\Mapper\Mapper;
6+
use Cycle\ORM\Relation;
7+
use Cycle\ORM\SchemaInterface as Schema;
8+
use Cycle\ORM\Select\Repository;
9+
use Cycle\ORM\Select\Source;
10+
use Cycle\ORM\Tests\Functional\Driver\Common\Integration\Issue528\Entity\Translation;
11+
use Cycle\ORM\Tests\Functional\Driver\Common\Integration\Issue528\Entity\Country;
12+
use Cycle\ORM\Tests\Functional\Driver\Common\Integration\Issue528\Entity\Locale;
13+
14+
return [
15+
'country' => [
16+
Schema::ENTITY => Country::class,
17+
Schema::SOURCE => Source::class,
18+
Schema::DATABASE => 'default',
19+
Schema::MAPPER => Mapper::class,
20+
Schema::TABLE => 'country',
21+
Schema::PRIMARY_KEY => ['id'],
22+
Schema::FIND_BY_KEYS => ['id'],
23+
Schema::COLUMNS => [
24+
'id' => 'id',
25+
'name' => 'name',
26+
],
27+
Schema::RELATIONS => [
28+
'translations' => [
29+
Relation::TYPE => Relation::HAS_MANY,
30+
Relation::TARGET => 'translation',
31+
Relation::COLLECTION_TYPE => 'array',
32+
Relation::LOAD => Relation::LOAD_PROMISE,
33+
Relation::SCHEMA => [
34+
Relation::CASCADE => true,
35+
Relation::NULLABLE => false,
36+
Relation::WHERE => [],
37+
Relation::ORDER_BY => [],
38+
Relation::INNER_KEY => ['id'],
39+
Relation::OUTER_KEY => 'country_id',
40+
],
41+
],
42+
],
43+
Schema::TYPECAST => [
44+
'id' => 'int',
45+
'name' => 'string',
46+
'code' => 'string',
47+
'isFriendly' => 'bool',
48+
],
49+
Schema::SCHEMA => [],
50+
],
51+
'translation' => [
52+
Schema::ENTITY => Translation::class,
53+
Schema::SOURCE => Source::class,
54+
Schema::DATABASE => 'default',
55+
Schema::TABLE => 'translation',
56+
Schema::PRIMARY_KEY => ['id'],
57+
Schema::FIND_BY_KEYS => ['id'],
58+
Schema::COLUMNS => [
59+
'id' => 'id',
60+
'country_id' => 'country_id',
61+
'locale_id' => 'locale_id',
62+
'title' => 'title',
63+
],
64+
Schema::RELATIONS => [
65+
'country' => [
66+
Relation::TYPE => Relation::BELONGS_TO,
67+
Relation::TARGET => 'country',
68+
Relation::LOAD => Relation::LOAD_EAGER,
69+
Relation::SCHEMA => [
70+
Relation::CASCADE => true,
71+
Relation::NULLABLE => false,
72+
Relation::INNER_KEY => 'country_id',
73+
Relation::OUTER_KEY => ['id'],
74+
],
75+
],
76+
'locale' => [
77+
Relation::TYPE => Relation::BELONGS_TO,
78+
Relation::TARGET => 'locale',
79+
Relation::LOAD => Relation::LOAD_PROMISE,
80+
Relation::SCHEMA => [
81+
Relation::CASCADE => true,
82+
Relation::NULLABLE => false,
83+
Relation::INNER_KEY => 'locale_id',
84+
Relation::OUTER_KEY => ['id'],
85+
],
86+
],
87+
],
88+
Schema::TYPECAST => [
89+
'id' => 'int',
90+
'country_id' => 'int',
91+
'locale_id' => 'int',
92+
'title' => 'string',
93+
],
94+
Schema::SCHEMA => [],
95+
],
96+
'locale' => [
97+
Schema::ENTITY => Locale::class,
98+
Schema::MAPPER => Mapper::class,
99+
Schema::SOURCE => Source::class,
100+
Schema::REPOSITORY => Repository::class,
101+
Schema::DATABASE => 'default',
102+
Schema::TABLE => 'locale',
103+
Schema::PRIMARY_KEY => ['id'],
104+
Schema::FIND_BY_KEYS => ['id'],
105+
Schema::COLUMNS => [
106+
'id' => 'id',
107+
'code' => 'code',
108+
],
109+
Schema::RELATIONS => [
110+
'translations' => [
111+
Relation::TYPE => Relation::HAS_MANY,
112+
Relation::TARGET => 'translation',
113+
Relation::COLLECTION_TYPE => 'array',
114+
Relation::LOAD => Relation::LOAD_PROMISE,
115+
Relation::SCHEMA => [
116+
Relation::CASCADE => true,
117+
Relation::NULLABLE => false,
118+
Relation::WHERE => [],
119+
Relation::ORDER_BY => [],
120+
Relation::INNER_KEY => ['id'],
121+
Relation::OUTER_KEY => 'locale_id',
122+
],
123+
],
124+
],
125+
Schema::SCOPE => null,
126+
Schema::TYPECAST => [
127+
'id' => 'int',
128+
'code' => 'string',
129+
],
130+
Schema::SCHEMA => [],
131+
],
132+
];
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Cycle\ORM\Tests\Functional\Driver\MySQL\Integration\Issue482;
6+
7+
// phpcs:ignore
8+
use Cycle\ORM\Tests\Functional\Driver\Common\Integration\Issue482\AbstractTestCase as CommonClass;
9+
10+
/**
11+
* @group driver
12+
* @group driver-mysql
13+
*/
14+
class AbstractTestCase extends CommonClass
15+
{
16+
public const DRIVER = 'mysql';
17+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Cycle\ORM\Tests\Functional\Driver\MySQL\Integration\Issue528;
6+
7+
// phpcs:ignore
8+
use Cycle\ORM\Tests\Functional\Driver\Common\Integration\Issue528\AbstractTestCase as CommonClass;
9+
10+
/**
11+
* @group driver
12+
* @group driver-mysql
13+
*/
14+
class CaseTest extends CommonClass
15+
{
16+
public const DRIVER = 'mysql';
17+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Cycle\ORM\Tests\Functional\Driver\Postgres\Integration\Issue482;
6+
7+
// phpcs:ignore
8+
use Cycle\ORM\Tests\Functional\Driver\Common\Integration\Issue482\AbstractTestCase as CommonClass;
9+
10+
/**
11+
* @group driver
12+
* @group driver-postgres
13+
*/
14+
class AbstractTestCase extends CommonClass
15+
{
16+
public const DRIVER = 'postgres';
17+
}

0 commit comments

Comments
 (0)