Skip to content

Commit

Permalink
Merge pull request #27 from matryoshka-model/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
leogr committed Apr 23, 2016
2 parents 69aa653 + d2799c5 commit d69511d
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 20 deletions.
2 changes: 1 addition & 1 deletion .travis/run.bash
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

mkdir -p $HOME/logs

declare -a mongo_ext=("1.4.5" "1.5.0" "1.5.1" "1.5.2" "1.5.3" "1.5.3" "1.5.5" "1.5.6" "1.5.7" "1.5.8" "1.6.0" "1.6.1" "1.6.2" "1.6.3" "1.6.4" "1.6.5" "1.6.6" "1.6.7" "1.6.8" "1.6.9")
declare -a mongo_ext=("1.4.5" "1.5.0" "1.5.1" "1.5.2" "1.5.3" "1.5.3" "1.5.5" "1.5.6" "1.5.7" "1.5.8" "1.6.0" "1.6.1" "1.6.2" "1.6.3" "1.6.4" "1.6.5" "1.6.6" "1.6.7" "1.6.8" "1.6.9" "1.6.10" "1.6.11" "1.6.12" "1.6.13")

echo "> UPDATING: pecl"
pecl channel-update pecl.php.net > $HOME/logs/common.log
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ It's important to always use the `HydratingResultSet` class included in this pac

**CI** provided through [TravisCI](http://travis-ci.org/matryoshka-model/mongo-wrapper).

This wrapper is tested against the following MongoDB PHP clients: **1.4.5**, **1.5.0**, **1.5.1**, **1.5.2**, **1.5.3**, **1.5.3**, **1.5.5**, **1.5.6**, **1.5.7**, **1.5.8**, **1.6.0**, **1.6.1**, **1.6.2**, **1.6.3**, **1.6.4**, **1.6.5**, **1.6.6**, **1.6.7**, **1.6.8**, **1.6.9**.
This wrapper is tested against the following MongoDB PHP clients: **1.4.5**, **1.5.0**, **1.5.1**, **1.5.2**, **1.5.3**, **1.5.3**, **1.5.5**, **1.5.6**, **1.5.7**, **1.5.8**, **1.6.0**, **1.6.1**, **1.6.2**, **1.6.3**, **1.6.4**, **1.6.5**, **1.6.6**, **1.6.7**, **1.6.8**, **1.6.9**, **1.6.10**, **1.6.11**, **1.6.12**, **1.6.13**.

---

Expand Down
19 changes: 10 additions & 9 deletions library/Criteria/Isolated/DocumentStore.php
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ public function has(MongoCollection $dataGateway, $id)
*
* @param MongoCollection $dataGateway
* @param $id
* @return mixed
* @return mixed|null
*/
public function get(MongoCollection $dataGateway, $id)
{
Expand All @@ -135,8 +135,6 @@ public function get(MongoCollection $dataGateway, $id)
if ($this->has($dataGateway, $id)) {
return $this->splObjectStorage[$dataGateway][$id];
}

// FIXME: missing return
}

/**
Expand Down Expand Up @@ -177,11 +175,14 @@ public function initIsolationFromCursor(MongoCollection $dataGateway, MongoCurso
{
$return = [];
foreach ($cursor as $document) {
$id = $document['_id']; // FIXME: check id presence
if (!isset($document['_id'])) {
throw new RuntimeException('Cannot init isolation: missing _id field in document');
}
$id = $document['_id'];
$localDocument = $this->get($dataGateway, $id);
if ($localDocument && $document != $localDocument) {
throw new Exception\DocumentModifiedException(sprintf(
'The local copy of the document "%s" no longer reflects the current state of the document in the database',
'The local copy of the document "%s" no longer reflects the current state of the document in the db\'s collection',
$id
));
}
Expand All @@ -208,11 +209,11 @@ public function isolatedUpsert(MongoCollection $dataGateway, array &$data, array
try {
$result = $dataGateway->insert($tmp, $options); // modifiers are not allowed with insert
} catch (MongoCursorException $e) {
if ($e->getCode() == 11000) {
if (isset($data['_id']) && $e->getCode() == 11000 && preg_match('/\.\$_id_\s/', $e->getMessage())) {
$e = new Exception\DocumentModifiedException(
sprintf(
'Cannot insert the local copy of the new document "%s" because another ' .
' document with the same ID already exists in the database',
'document with the same ID already exists in the db\'s collection',
$data['_id']
),
11000,
Expand All @@ -236,7 +237,7 @@ public function isolatedUpsert(MongoCollection $dataGateway, array &$data, array

if ($result != 1) {
throw new Exception\DocumentModifiedException(sprintf(
'The local copy of the document "%s" no longer reflects the current state of the document in the database',
'The local copy of the document "%s" no longer reflects the current state of the document in the db\'s collection',
$data['_id']
));
}
Expand All @@ -263,7 +264,7 @@ public function isolatedRemove(MongoCollection $dataGateway, $id, array $options

if ($result != 1) {
throw new Exception\DocumentModifiedException(sprintf(
'The local copy of the document "%s" no longer reflects the current state of the document in the database',
'The local copy of the document "%s" no longer reflects the current state of the document in the db\'s collection',
$id
));
}
Expand Down
57 changes: 48 additions & 9 deletions tests/Criteria/Isolated/DocumentStoreTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -174,10 +174,31 @@ public function testInitIsolationFromCursorShouldThrowDocumentModifiedException(
$saveMethod->invoke($this->documentStore, $this->mongoCollection, $data['_id'], $data + ['foo' => 'bar']);

$this->setExpectedException('\Matryoshka\Model\Wrapper\Mongo\Exception\DocumentModifiedException');
$this->assertSame(
[$data],
$this->documentStore->initIsolationFromCursor($this->mongoCollection, $mongoCursorMock)
);
$this->documentStore->initIsolationFromCursor($this->mongoCollection, $mongoCursorMock);
}

public function testInitIsolationFromCursorShouldThrowRuntimeExceptionWhenMissingId()
{
$data = ['test' => 'test'];

$mongoCursorMock = $this->getMockBuilder('\MongoCursor')
->disableOriginalConstructor()
->getMock();

//Emulate foreach behavior
$mongoCursorMock->expects($this->at(0))
->method('rewind');

$mongoCursorMock->expects($this->at(1))
->method('valid')
->will($this->returnValue(true));

$mongoCursorMock->expects($this->at(2))
->method('current')
->will($this->returnValue($data));

$this->setExpectedException('\Matryoshka\Model\Exception\RuntimeException');
$this->documentStore->initIsolationFromCursor($this->mongoCollection, $mongoCursorMock);
}

public function testIsolatedUpsert()
Expand Down Expand Up @@ -244,23 +265,41 @@ public function testIsolatedUpsertShouldThrowDocumentModifiedException()
$this->assertEquals(1, $this->documentStore->isolatedUpsert($this->mongoCollection, $testData, $options));
}

public function testIsolatedUpsertShouldThrowDocumentModifiedExceptionWhenDuplicateKey()
public function testIsolatedUpsertShouldThrowDocumentModifiedExceptionWhenDuplicateId()
{
$testData = ['test' => 'test', '_id' => 'foo'];
$options = ['w' => 1];

$dupKeyEx = new \MongoCursorException('E11000 duplicate key error', 11000);
$dupKeyEx = new \MongoCursorException('E11000 duplicate key error index: foo.bar.$_id_ dup key: { : "foo" }', 11000);

//simulate duplicate key error
$this->mongoCollectionMock->expects($this->atLeastOnce())
->method('insert')
->with($this->equalTo($testData), $this->equalTo($options))
->will($this->throwException($dupKeyEx));
->method('insert')
->with($this->equalTo($testData), $this->equalTo($options))
->will($this->throwException($dupKeyEx));


$this->setExpectedException('\Matryoshka\Model\Wrapper\Mongo\Exception\DocumentModifiedException');
$this->documentStore->isolatedUpsert($this->mongoCollection, $testData, $options);
}

public function testIsolatedUpsertShouldNotThrowDocumentModifiedExceptionWhenDuplicateKeyOnAnotherField()
{
$testData = ['test' => 'test', '_id' => 'baz'];
$options = ['w' => 1];

$dupKeyEx = new \MongoCursorException('E11000 duplicate key error index: foo.bar.$uid_1 dup key: { : 1 }', 11000);

//simulate duplicate key error
$this->mongoCollectionMock->expects($this->atLeastOnce())
->method('insert')
->with($this->equalTo($testData), $this->equalTo($options))
->will($this->throwException($dupKeyEx));


$this->setExpectedException('\MongoCursorException');
$this->documentStore->isolatedUpsert($this->mongoCollection, $testData, $options);
}

public function testIsolatedRemove()
{
Expand Down

0 comments on commit d69511d

Please sign in to comment.