Skip to content

Commit 8ace2bb

Browse files
authored
Merge pull request #32 from redthor/fix-get-migrated-timestamp
Fix get migrated timestamp
2 parents 1b8fb30 + 5cbeb6a commit 8ace2bb

File tree

5 files changed

+259
-35
lines changed

5 files changed

+259
-35
lines changed

src/AntiMattr/MongoDB/Migrations/Configuration/Configuration.php

+6-2
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,7 @@ public function getMigratedVersions()
304304
* @return string
305305
*
306306
* @throws AntiMattr\MongoDB\Migrations\Exception\UnknownVersionException Throws exception if migration version does not exist
307+
* @throws DomainException If more than one version exists
307308
*/
308309
public function getMigratedTimestamp($version)
309310
{
@@ -318,14 +319,17 @@ public function getMigratedTimestamp($version)
318319
}
319320

320321
if ($cursor->count() > 1) {
321-
throw \DomainException(
322+
throw new \DomainException(
322323
'Unexpected duplicate version records in the database'
323324
);
324325
}
325326

326327
$returnVersion = $cursor->getNext();
327328

328-
return (string) $returnVersion['t'];
329+
// Convert to normalised timestamp
330+
$ts = new Timestamp($returnVersion['t']);
331+
332+
return (string) $ts;
329333
}
330334

331335
/**
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the AntiMattr MongoDB Migrations Library, a library by Matthew Fitzgerald.
5+
*
6+
* (c) 2014 Matthew Fitzgerald
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace AntiMattr\MongoDB\Migrations\Configuration;
13+
14+
/**
15+
* This class is to normalise the potential values from the 't' version
16+
* attribute.
17+
*
18+
* @author Douglas Reith <douglas@reith.com.au>
19+
*/
20+
class Timestamp
21+
{
22+
private $t;
23+
24+
/**
25+
* @param mixed $t
26+
*/
27+
public function __construct($t)
28+
{
29+
$this->t = $t;
30+
}
31+
32+
/**
33+
* Normalise based on the different options for backward/forward
34+
* compatibility.
35+
*
36+
* @return int Time in seconds since 1970
37+
*/
38+
public function getTimestamp(): int
39+
{
40+
$supportedClasses = implode(
41+
', ',
42+
[
43+
'\MongoTimestamp',
44+
'\MongoDate',
45+
'\MongoDB\BSON\Timestamp',
46+
'\MongoDB\BSON\UTCDateTime',
47+
'\DateTimeInterface',
48+
]
49+
);
50+
51+
if (!$this->t || !is_object($this->t)) {
52+
throw new \DomainException(
53+
'The timestamp to normalise must be one of ' . $supportedClasses . ' but it is not an object'
54+
);
55+
}
56+
57+
switch (get_class($this->t)) {
58+
case 'MongoTimestamp':
59+
return (int) $this->t->__toString();
60+
61+
case 'MongoDate':
62+
return $this->t->sec;
63+
64+
case 'MongoDB\BSON\Timestamp':
65+
return $this->t->getTimestamp();
66+
67+
case 'MongoDB\BSON\UTCDateTime':
68+
return (int) $this->t->toDateTime()->format('U');
69+
}
70+
71+
if ($this->t instanceof \DateTimeInterface) {
72+
return $this->t->getTimestamp();
73+
}
74+
75+
throw new \DomainException(
76+
'The normalised timestamp must be one of ' . $supportedClasses
77+
);
78+
}
79+
80+
/**
81+
* @return string
82+
*/
83+
public function __toString(): string
84+
{
85+
return (string) $this->getTimestamp();
86+
}
87+
}

tests/AntiMattr/Tests/MongoDB/Migrations/Configuration/ConfigurationTest.php

+92-26
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,12 @@ public function testGetCollection()
3434
$this->connection->expects($this->once())
3535
->method('selectDatabase')
3636
->with('test_antimattr_migrations')
37-
->will($this->returnValue($database));
37+
->willReturn($database);
3838

3939
$database->expects($this->once())
4040
->method('selectCollection')
4141
->with('antimattr_migration_versions_test')
42-
->will($this->returnValue($expectedCollection));
42+
->willReturn($expectedCollection);
4343

4444
$collection = $this->configuration->getCollection();
4545
$this->assertEquals($expectedCollection, $collection);
@@ -58,12 +58,12 @@ public function testGetCurrentVersion()
5858
$this->connection->expects($this->once())
5959
->method('selectDatabase')
6060
->with('test_antimattr_migrations')
61-
->will($this->returnValue($database));
61+
->willReturn($database);
6262

6363
$database->expects($this->once())
6464
->method('selectCollection')
6565
->with('antimattr_migration_versions_test')
66-
->will($this->returnValue($collection));
66+
->willReturn($collection);
6767

6868
$cursor = $this->buildMock('Doctrine\MongoDB\Cursor');
6969

@@ -72,21 +72,21 @@ public function testGetCurrentVersion()
7272
$collection->expects($this->once())
7373
->method('find')
7474
->with($in)
75-
->will($this->returnValue($cursor));
75+
->willReturn($cursor);
7676

7777
$cursor->expects($this->once())
7878
->method('sort')
7979
->with(['v' => -1])
80-
->will($this->returnValue($cursor));
80+
->willReturn($cursor);
8181

8282
$cursor->expects($this->once())
8383
->method('limit')
8484
->with(1)
85-
->will($this->returnValue($cursor));
85+
->willReturn($cursor);
8686

8787
$cursor->expects($this->once())
8888
->method('getNext')
89-
->will($this->returnValue(['v' => '20140822185743']));
89+
->willReturn(['v' => '20140822185743']);
9090

9191
$version = $this->configuration->getCurrentVersion();
9292

@@ -102,7 +102,7 @@ public function testGetDatabase()
102102
$this->connection->expects($this->once())
103103
->method('selectDatabase')
104104
->with('test_antimattr_migrations')
105-
->will($this->returnValue($expectedDatabase));
105+
->willReturn($expectedDatabase);
106106

107107
$database = $this->configuration->getDatabase();
108108
$this->assertEquals($expectedDatabase, $database);
@@ -118,12 +118,12 @@ public function testGetMigratedVersions()
118118
$this->connection->expects($this->once())
119119
->method('selectDatabase')
120120
->with('test_antimattr_migrations')
121-
->will($this->returnValue($database));
121+
->willReturn($database);
122122

123123
$database->expects($this->once())
124124
->method('selectCollection')
125125
->with('antimattr_migration_versions_test')
126-
->will($this->returnValue($collection));
126+
->willReturn($collection);
127127

128128
$foundVersions = [
129129
['v' => 'found1'],
@@ -137,7 +137,7 @@ public function testGetMigratedVersions()
137137

138138
$collection->expects($this->once())
139139
->method('find')
140-
->will($this->returnValue($foundVersions));
140+
->willReturn($foundVersions);
141141

142142
$versions = $this->configuration->getMigratedVersions();
143143
$this->assertEquals($expectedVersions, $versions);
@@ -153,22 +153,22 @@ public function testGetNumberOfExecutedMigrations()
153153
$this->connection->expects($this->once())
154154
->method('selectDatabase')
155155
->with('test_antimattr_migrations')
156-
->will($this->returnValue($database));
156+
->willReturn($database);
157157

158158
$database->expects($this->once())
159159
->method('selectCollection')
160160
->with('antimattr_migration_versions_test')
161-
->will($this->returnValue($collection));
161+
->willReturn($collection);
162162

163163
$cursor = $this->buildMock('Doctrine\MongoDB\Cursor');
164164

165165
$collection->expects($this->once())
166166
->method('find')
167-
->will($this->returnValue($cursor));
167+
->willReturn($cursor);
168168

169169
$cursor->expects($this->once())
170170
->method('count')
171-
->will($this->returnValue(2));
171+
->willReturn(2);
172172

173173
$this->assertEquals(2, $this->configuration->getNumberOfExecutedMigrations());
174174
}
@@ -211,32 +211,30 @@ public function testHasVersionMigrated()
211211
$this->connection->expects($this->once())
212212
->method('selectDatabase')
213213
->with('test_antimattr_migrations')
214-
->will($this->returnValue($database));
214+
->willReturn($database);
215215

216216
$database->expects($this->once())
217217
->method('selectCollection')
218218
->with('antimattr_migration_versions_test')
219-
->will($this->returnValue($collection));
219+
->willReturn($collection);
220220

221221
$version1->expects($this->once())
222222
->method('getVersion')
223-
->will($this->returnValue('found'));
223+
->willReturn('found');
224224

225225
$version2->expects($this->once())
226226
->method('getVersion')
227-
->will($this->returnValue('found2'));
228-
229-
$cursor = $this->buildMock('MongoCursor');
227+
->willReturn('found2');
230228

231229
$collection->expects($this->at(1))
232230
->method('findOne')
233231
->with(['v' => 'found'])
234-
->will($this->returnValue('foo'));
232+
->willReturn('foo');
235233

236234
$collection->expects($this->at(2))
237235
->method('findOne')
238236
->with(['v' => 'found2'])
239-
->will($this->returnValue(null));
237+
->willReturn(null);
240238

241239
$this->assertTrue($this->configuration->hasVersionMigrated($version1));
242240
$this->assertFalse($this->configuration->hasVersionMigrated($version2));
@@ -258,10 +256,10 @@ public function testGetUnavailableMigratedVersions()
258256
->getMock();
259257
$configuration->expects($this->once())
260258
->method('getMigratedVersions')
261-
->will($this->returnValue(['1', '2']));
259+
->willReturn(['1', '2']);
262260
$configuration->expects($this->once())
263261
->method('getAvailableVersions')
264-
->will($this->returnValue(['2', '3']));
262+
->willReturn(['2', '3']);
265263

266264
$this->assertEquals(['1'], $configuration->getUnavailableMigratedVersions());
267265
}
@@ -272,6 +270,74 @@ public function testValidate()
272270
self::assertNull($this->configuration->validate());
273271
}
274272

273+
/**
274+
* @expectedException \DomainException
275+
* @expectedExceptionMessage Unexpected duplicate version records in the database
276+
*/
277+
public function testDuplicateInGetMigratedTimestampThrowsException()
278+
{
279+
$this->prepareValidConfiguration();
280+
281+
$collection = $this->buildMock('Doctrine\MongoDB\Collection');
282+
$database = $this->buildMock('Doctrine\MongoDB\Database');
283+
284+
$this->connection->expects($this->once())
285+
->method('selectDatabase')
286+
->with('test_antimattr_migrations')
287+
->willReturn($database);
288+
289+
$database->expects($this->once())
290+
->method('selectCollection')
291+
->with('antimattr_migration_versions_test')
292+
->willReturn($collection);
293+
294+
$cursor = $this->buildMock('Doctrine\MongoDB\Cursor');
295+
296+
$collection->expects($this->once())
297+
->method('find')
298+
->willReturn($cursor);
299+
300+
$cursor->expects($this->exactly(2))
301+
->method('count')
302+
->willReturn(2);
303+
304+
$this->configuration->getMigratedTimestamp('1');
305+
}
306+
307+
public function testGetMigratedTimestamp()
308+
{
309+
$this->prepareValidConfiguration();
310+
311+
$collection = $this->buildMock('Doctrine\MongoDB\Collection');
312+
$database = $this->buildMock('Doctrine\MongoDB\Database');
313+
314+
$this->connection->expects($this->once())
315+
->method('selectDatabase')
316+
->with('test_antimattr_migrations')
317+
->willReturn($database);
318+
319+
$database->expects($this->once())
320+
->method('selectCollection')
321+
->with('antimattr_migration_versions_test')
322+
->willReturn($collection);
323+
324+
$cursor = $this->buildMock('Doctrine\MongoDB\Cursor');
325+
326+
$collection->expects($this->once())
327+
->method('find')
328+
->willReturn($cursor);
329+
330+
$cursor->expects($this->exactly(2))
331+
->method('count')
332+
->willReturn(1);
333+
334+
$cursor->expects($this->once())
335+
->method('getNext')
336+
->willReturn(['t' => new \DateTime()]);
337+
338+
$this->assertTrue(is_numeric($this->configuration->getMigratedTimestamp('1')));
339+
}
340+
275341
private function prepareValidConfiguration()
276342
{
277343
$directory = dirname(__DIR__) . '/Resources/Migrations/';

0 commit comments

Comments
 (0)