Skip to content

Commit 1237e5e

Browse files
authored
Merge pull request #6 from compositephp/dev
0.4.0 setup Add CombinedTransaction saveMany and deleteMany Rework $where param, add flexibility to use simple assoc array or Where class Move raw selects to separate trait and build entities by default
2 parents c63426c + b477a3a commit 1237e5e

37 files changed

+586
-680
lines changed

.gitattributes

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
/.gitattributes export-ignore
22
/.gitignore export-ignore
33
/.github export-ignore
4+
/.scrutinizer.yml export-ignore
45
/doc export-ignore
56
/phpunit.xml export-ignore
67
/tests export-ignore

doc/cache.md

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ To start using auto-cache feature you need:
66
to `Composite\DB\AbstractCachedTable`
77
3. Implement method `getFlushCacheKeys()`
88
4. Change all internal select methods to their cached versions (example: `findByPkInternal()`
9-
to `findByPkCachedInternal()` etc.)
9+
to `_findByPkCached()` etc.)
1010

1111
You can also generate cached version of your table with console command:
1212

@@ -46,23 +46,20 @@ class PostsTable extends AbstractCachedTable
4646

4747
public function findByPk(int $id): ?Post
4848
{
49-
return $this->createEntity($this->findByPkInternalCached($id));
49+
return $this->_findByPkCached($id);
5050
}
5151

5252
/**
5353
* @return Post[]
5454
*/
5555
public function findAllFeatured(): array
5656
{
57-
return $this->createEntities($this->findAllInternal(
58-
'is_featured = :is_featured',
59-
['is_featured' => true],
60-
));
57+
return $this->_findAll(['is_featured' => true]);
6158
}
6259

6360
public function countAllFeatured(): int
6461
{
65-
return $this->countAllCachedInternal(
62+
return $this->_countAllCached(
6663
'is_featured = :is_featured',
6764
['is_featured' => true],
6865
);

doc/example.md

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -43,25 +43,21 @@ class UsersTable extends \Composite\DB\AbstractTable
4343

4444
public function findByPk(int $id): ?User
4545
{
46-
return $this->createEntity($this->findByPkInternal($id));
46+
return $this->_findByPk($id);
4747
}
4848

4949
/**
5050
* @return User[]
5151
*/
5252
public function findAllActive(): array
5353
{
54-
return $this->createEntities($this->findAllInternal(
55-
'status = :status',
56-
['status' => Status::ACTIVE->name],
57-
));
54+
return $this->_findAll(['status' => Status::ACTIVE]);
5855
}
5956

6057
public function countAllActive(): int
6158
{
62-
return $this->countAllInternal(
63-
'status = :status',
64-
['status' => Status::ACTIVE->name],
59+
return $this->_countAll(
60+
['status' => Status::ACTIVE],
6561
);
6662
}
6763

doc/table.md

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -38,20 +38,20 @@ class UsersTable extends AbstractTable
3838

3939
public function findOne(int $id): ?User
4040
{
41-
return $this->createEntity($this->findOneInternal($id));
41+
return $this->_findByPk($id);
4242
}
4343

4444
/**
4545
* @return User[]
4646
*/
4747
public function findAll(): array
4848
{
49-
return $this->createEntities($this->findAllInternal());
49+
return $this->_findAll();
5050
}
5151

5252
public function countAll(): int
5353
{
54-
return $this->countAllInternal();
54+
return $this->_countAll();
5555
}
5656
}
5757
```
@@ -67,15 +67,30 @@ Example with internal helper:
6767
*/
6868
public function findAllActiveAdults(): array
6969
{
70-
$rows = $this->findAllInternal(
71-
'age > :age AND status = :status',
72-
['age' => 18, 'status' => Status::ACTIVE->name],
70+
return $this->_findAll(
71+
new Where(
72+
'age > :age AND status = :status',
73+
['age' => 18, 'status' => Status::ACTIVE->name],
74+
)
7375
);
74-
return $this->createEntities($rows);
7576
}
7677
```
7778

78-
Example with pure query builder
79+
Or it might be simplified to:
80+
```php
81+
/**
82+
* @return User[]
83+
*/
84+
public function findAllActiveAdults(): array
85+
{
86+
return $this->_findAll([
87+
'age' => ['>', 18],
88+
'status' => Status:ACTIVE,
89+
]);
90+
}
91+
```
92+
93+
Or you can use standard Doctrine QueryBuilder
7994
```php
8095
/**
8196
* @return User[]

phpunit.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.1/phpunit.xsd" bootstrap="tests/bootstrap.php"
44
executionOrder="depends,defects" beStrictAboutOutputDuringTests="true" failOnRisky="true" failOnWarning="true"
55
colors="true" cacheDirectory=".phpunit.cache" requireCoverageMetadata="false"
6+
displayDetailsOnTestsThatTriggerWarnings="true"
67
beStrictAboutCoverageMetadata="true">
78
<testsuites>
89
<testsuite name="default">

src/AbstractCachedTable.php

Lines changed: 48 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,14 @@
22

33
namespace Composite\DB;
44

5-
use Composite\DB\Exceptions\DbException;
65
use Composite\Entity\AbstractEntity;
76
use Psr\SimpleCache\CacheInterface;
87
use Ramsey\Uuid\UuidInterface;
98

109
abstract class AbstractCachedTable extends AbstractTable
1110
{
11+
use SelectRawTrait;
12+
1213
protected const CACHE_VERSION = 1;
1314

1415
public function __construct(
@@ -93,59 +94,60 @@ private function collectCacheKeysByEntity(AbstractEntity $entity): array
9394
}
9495

9596
/**
96-
* @return array<string, mixed>|null
97+
* @return AbstractEntity|null
9798
*/
98-
protected function findByPkCachedInternal(mixed $pk, null|int|\DateInterval $ttl = null): ?array
99+
protected function _findByPkCached(mixed $pk, null|int|\DateInterval $ttl = null): mixed
99100
{
100-
return $this->findOneCachedInternal($this->getPkCondition($pk), $ttl);
101+
return $this->_findOneCached($this->getPkCondition($pk), $ttl);
101102
}
102103

103104
/**
104-
* @param array<string, mixed> $condition
105+
* @param array<string, mixed> $where
105106
* @param int|\DateInterval|null $ttl
106-
* @return array<string, mixed>|null
107+
* @return AbstractEntity|null
107108
*/
108-
protected function findOneCachedInternal(array $condition, null|int|\DateInterval $ttl = null): ?array
109+
protected function _findOneCached(array $where, null|int|\DateInterval $ttl = null): mixed
109110
{
110-
return $this->getCached(
111-
$this->getOneCacheKey($condition),
112-
fn() => $this->findOneInternal($condition),
111+
$row = $this->getCached(
112+
$this->getOneCacheKey($where),
113+
fn() => $this->_findOneRaw($where),
113114
$ttl,
114-
) ?: null;
115+
);
116+
return $this->createEntity($row);
115117
}
116118

117119
/**
118-
* @param array<string, mixed> $whereParams
120+
* @param array<string, mixed>|Where $where
119121
* @param array<string, string>|string $orderBy
120-
* @return array<string, mixed>[]
122+
* @return array<AbstractEntity>|array<array-key, AbstractEntity>
121123
*/
122-
protected function findAllCachedInternal(
123-
string $whereString = '',
124-
array $whereParams = [],
124+
protected function _findAllCached(
125+
array|Where $where = [],
125126
array|string $orderBy = [],
126127
?int $limit = null,
127128
null|int|\DateInterval $ttl = null,
129+
?string $keyColumnName = null,
128130
): array
129131
{
130-
return $this->getCached(
131-
$this->getListCacheKey($whereString, $whereParams, $orderBy, $limit),
132-
fn() => $this->findAllInternal(whereString: $whereString, whereParams: $whereParams, orderBy: $orderBy, limit: $limit),
132+
$rows = $this->getCached(
133+
$this->getListCacheKey($where, $orderBy, $limit),
134+
fn() => $this->_findAllRaw(where: $where, orderBy: $orderBy, limit: $limit),
133135
$ttl,
134136
);
137+
return $this->createEntities($rows, $keyColumnName);
135138
}
136139

137140
/**
138-
* @param array<string, mixed> $whereParams
141+
* @param array<string, mixed>|Where $where
139142
*/
140-
protected function countAllCachedInternal(
141-
string $whereString = '',
142-
array $whereParams = [],
143+
protected function _countByAllCached(
144+
array|Where $where = [],
143145
null|int|\DateInterval $ttl = null,
144146
): int
145147
{
146148
return (int)$this->getCached(
147-
$this->getCountCacheKey($whereString, $whereParams),
148-
fn() => $this->countAllInternal(whereString: $whereString, whereParams: $whereParams),
149+
$this->getCountCacheKey($where),
150+
fn() => $this->_countAll(where: $where),
149151
$ttl,
150152
);
151153
}
@@ -166,10 +168,14 @@ protected function getCached(string $cacheKey, callable $dataCallback, null|int|
166168
/**
167169
* @param mixed[] $ids
168170
* @param int|\DateInterval|null $ttl
169-
* @return array<array<string, mixed>>
171+
* @return array<AbstractEntity>|array<array-key, AbstractEntity>
170172
* @throws \Psr\SimpleCache\InvalidArgumentException
171173
*/
172-
protected function findMultiCachedInternal(array $ids, null|int|\DateInterval $ttl = null): array
174+
protected function _findMultiCached(
175+
array $ids,
176+
null|int|\DateInterval $ttl = null,
177+
?string $keyColumnName = null,
178+
): array
173179
{
174180
$result = $cacheKeys = $foundIds = [];
175181
foreach ($ids as $id) {
@@ -188,11 +194,11 @@ protected function findMultiCachedInternal(array $ids, null|int|\DateInterval $t
188194
}
189195
$ids = array_diff($ids, $foundIds);
190196
foreach ($ids as $id) {
191-
if ($row = $this->findByPkCachedInternal($id, $ttl)) {
197+
if ($row = $this->_findByPkCached($id, $ttl)) {
192198
$result[] = $row;
193199
}
194200
}
195-
return $result;
201+
return $this->createEntities($result, $keyColumnName);
196202
}
197203

198204
/**
@@ -209,37 +215,35 @@ protected function getOneCacheKey(string|int|array|AbstractEntity|UuidInterface
209215
}
210216

211217
/**
212-
* @param array<string, mixed> $whereParams
218+
* @param array<string, mixed>|Where $where
213219
* @param array<string, string>|string $orderBy
214220
*/
215221
protected function getListCacheKey(
216-
string $whereString = '',
217-
array $whereParams = [],
222+
array|Where $where = [],
218223
array|string $orderBy = [],
219224
?int $limit = null
220225
): string
221226
{
222-
$wherePart = $this->prepareWhereKey($whereString, $whereParams);
227+
$wherePart = is_array($where) ? $where : $this->prepareWhereKey($where);
223228
return $this->buildCacheKey(
224229
'l',
225-
$wherePart ?? 'all',
230+
$wherePart ?: 'all',
226231
$orderBy ? ['ob' => $orderBy] : null,
227232
$limit ? ['limit' => $limit] : null,
228233
);
229234
}
230235

231236
/**
232-
* @param array<string, mixed> $whereParams
237+
* @param array<string, mixed>|Where $where
233238
*/
234239
protected function getCountCacheKey(
235-
string $whereString = '',
236-
array $whereParams = [],
240+
array|Where $where = [],
237241
): string
238242
{
239-
$wherePart = $this->prepareWhereKey($whereString, $whereParams);
243+
$wherePart = is_array($where) ? $where : $this->prepareWhereKey($where);
240244
return $this->buildCacheKey(
241245
'c',
242-
$wherePart ?? 'all',
246+
$wherePart ?: 'all',
243247
);
244248
}
245249

@@ -274,24 +278,18 @@ protected function buildCacheKey(mixed ...$parts): string
274278

275279
private function formatStringForCacheKey(string $string): string
276280
{
277-
$string = mb_strtolower($string);
281+
$string = strtolower($string);
278282
$string = str_replace(['!=', '<>', '>', '<', '='], ['_not_', '_not_', '_gt_', '_lt_', '_eq_'], $string);
279283
$string = (string)preg_replace('/\W/', '_', $string);
280284
return trim((string)preg_replace('/_+/', '_', $string), '_');
281285
}
282286

283-
/**
284-
* @param array<string, mixed> $whereParams
285-
*/
286-
private function prepareWhereKey(string $whereString, array $whereParams): ?string
287+
private function prepareWhereKey(Where $where): string
287288
{
288-
if (!$whereString) {
289-
return null;
290-
}
291289
return str_replace(
292-
array_map(fn (string $key): string => ':' . $key, array_keys($whereParams)),
293-
array_values($whereParams),
294-
$whereString,
290+
array_map(fn (string $key): string => ':' . $key, array_keys($where->params)),
291+
array_values($where->params),
292+
$where->condition,
295293
);
296294
}
297295
}

0 commit comments

Comments
 (0)