Skip to content

Commit 32b1581

Browse files
committed
Always send create/modified timestamps to/from database
1 parent 60ab863 commit 32b1581

File tree

10 files changed

+97
-22
lines changed

10 files changed

+97
-22
lines changed

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
"require-dev": {
2828
"robmorgan/phinx": "^0.10.7",
2929
"vlucas/phpdotenv": "^3.3",
30-
"wyrihaximus/async-test-utilities": "^1.0"
30+
"wyrihaximus/async-test-utilities": "^1.1"
3131
},
3232
"config": {
3333
"platform": {

composer.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

etc/db/migrations/20190327192030_InitialMigration.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ public function change(): void
99
$this->table('users', ['id' => false, 'primary_key' => ['id']])
1010
->addColumn('id', 'uuid')
1111
->addColumn('name', 'string')
12+
->addColumn('created', 'datetime')
13+
->addColumn('modified', 'datetime')
1214
->create();
1315

1416
$this->table('blog_posts', ['id' => false, 'primary_key' => ['id']])
@@ -18,13 +20,17 @@ public function change(): void
1820
->addColumn('title', 'string')
1921
->addColumn('contents', 'string')
2022
->addColumn('views', 'integer')
23+
->addColumn('created', 'datetime')
24+
->addColumn('modified', 'datetime')
2125
->create();
2226

2327
$this->table('comments', ['id' => false, 'primary_key' => ['id']])
2428
->addColumn('id', 'uuid')
2529
->addColumn('author_id', 'uuid')
2630
->addColumn('blog_post_id', 'uuid')
2731
->addColumn('contents', 'string')
32+
->addColumn('created', 'datetime')
33+
->addColumn('modified', 'datetime')
2834
->create();
2935
}
3036
}

etc/db/seeds/BlogPostsSeed.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ public function run(): void
1313
'title' => 'Cats!',
1414
'contents' => 'qliwuhe uofq2hep fuoq2pho fp2uhu pu2p 2qpoh weh uwqhfu wqif',
1515
'views' => 133,
16+
'created' => (new DateTimeImmutable())->format('Y-m-d H:i:s'),
17+
'modified' => (new DateTimeImmutable())->format('Y-m-d H:i:s'),
1618
],
1719
[
1820
'id' => '090fa83b-5c5a-4042-9f05-58d9ab649a1a',
@@ -21,6 +23,8 @@ public function run(): void
2123
'title' => 'Moar Cats!',
2224
'contents' => 'qlqweofu b02qw yu9 dqiwuhe uofq2hep fuoq2pho fp2uhu pu2p 2qpoh weh uwqhfu wqif',
2325
'views' => 166,
26+
'created' => (new DateTimeImmutable())->format('Y-m-d H:i:s'),
27+
'modified' => (new DateTimeImmutable())->format('Y-m-d H:i:s'),
2428
],
2529
];
2630

etc/db/seeds/CommentsSeed.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,24 @@ public function run(): void
1111
'author_id' => 'fb175cbc-04cc-41c7-8e35-6b817ac016ca',
1212
'blog_post_id' => '090fa83b-5c5a-4042-9f05-58d9ab649a1a',
1313
'contents' => 'abc',
14+
'created' => (new DateTimeImmutable())->format('Y-m-d H:i:s'),
15+
'modified' => (new DateTimeImmutable())->format('Y-m-d H:i:s'),
1416
],
1517
[
1618
'id' => '82aafe95-d37e-4525-90f0-08a9fe674591',
1719
'author_id' => '2fa0d077-d374-4409-b1ef-9687c6729158',
1820
'blog_post_id' => '53ab5832-9a90-4e6e-988b-06b8b5fed763',
1921
'contents' => 'def',
22+
'created' => (new DateTimeImmutable())->format('Y-m-d H:i:s'),
23+
'modified' => (new DateTimeImmutable())->format('Y-m-d H:i:s'),
2024
],
2125
[
2226
'id' => '2443dfa0-b964-4a2a-9d4f-7e3c8aac23a3',
2327
'author_id' => '15f25357-4b3d-4d4d-b6a5-2ceb93864b77',
2428
'blog_post_id' => '53ab5832-9a90-4e6e-988b-06b8b5fed763',
2529
'contents' => 'ghi',
30+
'created' => (new DateTimeImmutable())->format('Y-m-d H:i:s'),
31+
'modified' => (new DateTimeImmutable())->format('Y-m-d H:i:s'),
2632
],
2733
];
2834

etc/db/seeds/UsersSeed.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,20 @@ public function run(): void
99
[
1010
'id' => 'fb175cbc-04cc-41c7-8e35-6b817ac016ca',
1111
'name' => 'Deathwing',
12+
'created' => (new DateTimeImmutable())->format('Y-m-d H:i:s'),
13+
'modified' => (new DateTimeImmutable())->format('Y-m-d H:i:s'),
1214
],
1315
[
1416
'id' => '15f25357-4b3d-4d4d-b6a5-2ceb93864b77',
1517
'name' => 'Gandalf',
18+
'created' => (new DateTimeImmutable())->format('Y-m-d H:i:s'),
19+
'modified' => (new DateTimeImmutable())->format('Y-m-d H:i:s'),
1620
],
1721
[
1822
'id' => '2fa0d077-d374-4409-b1ef-9687c6729158',
1923
'name' => 'Floki',
24+
'created' => (new DateTimeImmutable())->format('Y-m-d H:i:s'),
25+
'modified' => (new DateTimeImmutable())->format('Y-m-d H:i:s'),
2026
],
2127
];
2228

src/Repository.php

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010

1111
final class Repository implements RepositoryInterface
1212
{
13+
private const SINGLE = 1;
14+
1315
/** @var InspectedEntity */
1416
private $entity;
1517

@@ -45,7 +47,7 @@ public function count(): PromiseInterface
4547
QueryBuilder::create()->from($this->entity->getTable())->select([
4648
'COUNT(*) AS count',
4749
])
48-
)->take(1)->toPromise()->then(function (array $row): int {
50+
)->take(self::SINGLE)->toPromise()->then(function (array $row): int {
4951
return (int)$row['count'];
5052
});
5153
}
@@ -69,7 +71,11 @@ public function fetch(array $where = [], array $order = []): Observable
6971

7072
public function create(array $fields): PromiseInterface
7173
{
72-
$fields['id'] = Uuid::getFactory()->uuid4();
74+
$fields['id'] = Uuid::getFactory()->uuid4()->toString();
75+
$fields['created'] = new \DateTimeImmutable();
76+
$fields['modified'] = new \DateTimeImmutable();
77+
78+
$fields = $this->prepareFields($fields);
7379

7480
return $this->client->query(
7581
QueryBuilder::create()->insert($fields)->into($this->entity->getTable())->returning()
@@ -81,13 +87,9 @@ public function create(array $fields): PromiseInterface
8187
public function update(EntityInterface $entity): PromiseInterface
8288
{
8389
$fields = $this->hydrator->extract($this->entity, $entity);
84-
foreach ($fields as $key => $value) {
85-
if (\is_scalar($value)) {
86-
continue;
87-
}
90+
$fields['modified'] = new \DateTimeImmutable();
8891

89-
unset($fields[$key]);
90-
}
92+
$fields = $this->prepareFields($fields);
9193

9294
return $this->client->query(
9395
QueryBuilder::create()->
@@ -97,7 +99,7 @@ public function update(EntityInterface $entity): PromiseInterface
9799
)->toPromise()->then(function () use ($entity) {
98100
return $this->fetch([
99101
['id', '=', $entity->getId()],
100-
])->take(1)->toPromise();
102+
])->take(self::SINGLE)->toPromise();
101103
});
102104
}
103105

@@ -249,4 +251,21 @@ private function translateFieldName(string $name): string
249251
{
250252
return 't0.' . $name;
251253
}
254+
255+
private function prepareFields(array $fields): array
256+
{
257+
foreach ($fields as $key => $value) {
258+
if ($value instanceof \DateTimeInterface) {
259+
$fields[$key] = $value = $value->format('Y-m-d H:i:s');
260+
}
261+
262+
if (\is_scalar($value)) {
263+
continue;
264+
}
265+
266+
unset($fields[$key]);
267+
}
268+
269+
return $fields;
270+
}
252271
}

tests/EntityInspectorTest.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,14 +54,16 @@ public function inspectWithJoins(): void
5454
self::assertSame('blog_posts', $inspectedEntity->getTable());
5555

5656
$fields = $inspectedEntity->getFields();
57-
self::assertCount(6, $fields);
57+
self::assertCount(8, $fields);
5858

5959
foreach ([
6060
'id' => 'string',
6161
'author_id' => 'string',
6262
'title' => 'string',
6363
'contents' => 'string',
6464
'views' => 'int',
65+
'created' => '\DateTimeImmutable',
66+
'modified' => '\DateTimeImmutable',
6567
] as $key => $type) {
6668
self::assertArrayHasKey($key, $fields, $key);
6769
self::assertSame($type, $fields[$key]->getType(), $key);

tests/FunctionalTest.php

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -251,18 +251,34 @@ public function createUser(): void
251251
*/
252252
public function increaseViews(): void
253253
{
254+
\sleep(3);
255+
254256
$repository = $this->client->getRepository(BlogPostStub::class);
255257

256-
self::assertSame(
257-
167,
258-
$this->await(
259-
$repository->fetch()->takeLast(1)->toPromise()->then(function (BlogPostStub $blogPost) {
260-
return $blogPost->withViews($blogPost->getViews() + 1);
261-
})->then(function (BlogPostStub $blogPost) use ($repository) {
262-
return $repository->update($blogPost);
263-
}),
264-
$this->loop
265-
)->getViews()
258+
/** @var BlogPostStub $originalBlogPost */
259+
$originalBlogPost = null;
260+
261+
/** @var int $timestamp */
262+
$timestamp = null;
263+
264+
/** @var BlogPostStub $updatedBlogPost */
265+
$updatedBlogPost = $this->await(
266+
$repository->fetch()->takeLast(1)->toPromise()->then(function (BlogPostStub $blogPost) use (&$originalBlogPost, &$timestamp) {
267+
self::waitUntilTheNextSecond();
268+
269+
$originalBlogPost = $blogPost;
270+
$timestamp = \time();
271+
272+
return $blogPost->withViews($blogPost->getViews() + 1);
273+
})->then(function (BlogPostStub $blogPost) use ($repository) {
274+
return $repository->update($blogPost);
275+
}),
276+
$this->loop
266277
);
278+
279+
self::assertSame(167, $updatedBlogPost->getViews());
280+
self::assertSame($originalBlogPost->getCreated()->format('U'), $updatedBlogPost->getCreated()->format('U'));
281+
self::assertGreaterThan($originalBlogPost->getModified(), $updatedBlogPost->getModified());
282+
self::assertSame($timestamp, (int)$updatedBlogPost->getModified()->format('U'));
267283
}
268284
}

tests/Stub/BlogPostStub.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,12 @@ class BlogPostStub implements EntityInterface
5959
/** @var int */
6060
protected $views;
6161

62+
/** @var \DateTimeImmutable */
63+
protected $created;
64+
65+
/** @var \DateTimeImmutable */
66+
protected $modified;
67+
6268
public function getId(): string
6369
{
6470
return $this->id;
@@ -101,4 +107,14 @@ public function withViews(int $views): self
101107

102108
return $clone;
103109
}
110+
111+
public function getCreated(): \DateTimeImmutable
112+
{
113+
return new \DateTimeImmutable($this->created);
114+
}
115+
116+
public function getModified(): \DateTimeImmutable
117+
{
118+
return new \DateTimeImmutable($this->modified);
119+
}
104120
}

0 commit comments

Comments
 (0)