Skip to content

Commit

Permalink
Merge pull request #24 from matryoshka-model/develop
Browse files Browse the repository at this point in the history
Preparing 0.8.0
  • Loading branch information
leogr committed Mar 17, 2016
2 parents e84aa99 + 78cec33 commit 69aa653
Show file tree
Hide file tree
Showing 17 changed files with 618 additions and 492 deletions.
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Add the following to your `composer.json` file:

```
"require": {
"matryoshka-model/mongo-wrapper": "~0.7.0"
"matryoshka-model/mongo-wrapper": "~0.8.0"
}
```

Expand Down Expand Up @@ -97,6 +97,12 @@ It's important to always use the `HydratingResultSet` class included in this pac

- `Matryoshka\Model\Wrapper\Mongo\Service` contains abstract service factories generally aimed at instantiation of `\MongoCollection` and `\MongoDb` objects. Use `mongocollection` and `mongodb` configuration nodes to respectively setup them (see [above](#configuration)).

## Continuous integration

**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**.

---

[![Analytics](https://ga-beacon.appspot.com/UA-49657176-2/mongo-wrapper?flat)](https://github.com/igrigorik/ga-beacon)
16 changes: 12 additions & 4 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"require": {
"php": ">=5.5.0",
"ext-mongo": "*",
"matryoshka-model/matryoshka": "0.8.*@dev",
"matryoshka-model/matryoshka": "~0.8.0",
"zendframework/zend-stdlib": "2.*",
"zendframework/zend-paginator": "2.*",
"zendframework/zend-servicemanager": "2.*"
Expand Down Expand Up @@ -40,10 +40,17 @@
],
"autoload": {
"psr-4": {
"Matryoshka\\Model\\Wrapper\\Mongo\\": "library/",
"MatryoshkaModelWrapperMongoTest\\": "tests/"
"Matryoshka\\Model\\Wrapper\\Mongo\\": "library/"
}
},
"autoload-dev": {
"psr-4": {
"MatryoshkaModelWrapperMongoTest\\": "tests/"
},
"files": [
"tests/TestAsset/MongoCollectionMockProxy.php"
]
},
"keywords": [
"model",
"matryoshka",
Expand All @@ -63,6 +70,7 @@
"suggest": {
"matryoshka-model/matryoshka": "A lightweight framework that provides a standard and easy way to implement a model service layer",
"matryoshka-model/zf2-matryoshka-module": "ZF2 module for matryoshka library",
"matryoshka-model/rest-wrapper": "Matryoshka wrapper aimed at creating restful API clients"
"matryoshka-model/rest-wrapper": "Matryoshka wrapper aimed at creating restful API clients",
"matryoshka-model/mongo-transactional": "Perform transactional operations with MongoDB"
}
}
40 changes: 25 additions & 15 deletions library/Criteria/ActiveRecord/ActiveRecordCriteria.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
use Matryoshka\Model\Exception;
use Matryoshka\Model\ModelStubInterface;
use Matryoshka\Model\Wrapper\Mongo\Criteria\HandleResultTrait;
use Zend\Stdlib\Hydrator\AbstractHydrator;

/**
* Class ActiveRecordCriteria
Expand All @@ -35,23 +34,27 @@ class ActiveRecordCriteria extends AbstractCriteria
/**
* @var array
*/
protected $saveOptions = [];
protected $mongoOptions = [];

/**
* Get options for Mongo save and remove operations
*
* @return array
*/
public function getSaveOptions()
public function getMongoOptions()
{
return $this->saveOptions;
return $this->mongoOptions;
}

/**
* Set options for Mongo save and remove operations
*
* @param array $options
* @return $this
*/
public function setSaveOptions(array $options)
public function setMongoOptions(array $options)
{
$this->saveOptions = $options;
$this->mongoOptions = $options;
return $this;
}

Expand All @@ -76,14 +79,16 @@ public function applyWrite(ModelStubInterface $model, array &$data)
/** @var $dataGateway \MongoCollection */
$dataGateway = $model->getDataGateway();

unset($data['_id']);

if ($this->id) {
if ($this->hasId()) {
$data['_id'] = $this->extractId($model);
}

if (array_key_exists('_id', $data) && null === $data['_id']) {
unset($data['_id']);
}

$tmp = $data; // passing a referenced variable to save will fail in update the content
$result = $dataGateway->save($tmp, $this->getSaveOptions());
$result = $dataGateway->save($tmp, $this->getMongoOptions());
$data = $tmp;
return $this->handleResult($result);
}
Expand All @@ -93,7 +98,10 @@ public function applyWrite(ModelStubInterface $model, array &$data)
*/
public function applyDelete(ModelStubInterface $model)
{
$result = $model->getDataGateway()->remove(['_id' => $this->extractId($model)]);
$result = $model->getDataGateway()->remove(
['_id' => $this->extractId($model)],
['justOne' => true] + $this->getMongoOptions()
);
return $this->handleResult($result, true);
}

Expand All @@ -103,11 +111,13 @@ public function applyDelete(ModelStubInterface $model)
*/
protected function extractId(ModelStubInterface $model)
{
if (!$model->getHydrator() instanceof AbstractHydrator) {
$hydrator = $model->getHydrator();
if (!method_exists($hydrator, 'extractValue')) {
throw new Exception\RuntimeException(
'Hydrator must be an instance of \Zend\Stdlib\Hydrator\AbstractHydrator'
);
'Hydrator must have extractValue() method ' .
'in order to extract a single value'
);
}
return $model->getHydrator()->extractValue('_id', $this->getId());
return $hydrator->extractValue('_id', $this->getId());
}
}
15 changes: 6 additions & 9 deletions library/Criteria/FindAllCriteria.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
use Matryoshka\Model\Exception\InvalidArgumentException;
use Matryoshka\Model\ModelStubInterface;
use Matryoshka\Model\Wrapper\Mongo\Paginator\MongoPaginatorAdapter;
use Zend\Stdlib\Hydrator\AbstractHydrator;

/**
* Class FindAllCriteria
Expand Down Expand Up @@ -111,17 +110,15 @@ public function setOrderBy(array $orders = [])
*/
protected function extractValue(ModelStubInterface $model, $name, $value, $object = null)
{
if (!$model->getHydrator() instanceof AbstractHydrator) {
$hydrator = $model->getHydrator();
if (!method_exists($hydrator, 'extractValue')) {
throw new Exception\RuntimeException(
sprintf(
'Hydrator must be an instance of "%s"; detected "%s"',
'\Zend\Stdlib\Hydrator\AbstractHydrator',
get_class($model->getHydrator())
)
);
'Hydrator must have extractValue() method ' .
'in order to extract a single value'
);
}

return $model->getHydrator()->extractValue($name, $value, $object);
return $hydrator->extractValue($name, $value, $object);
}

/**
Expand Down
13 changes: 8 additions & 5 deletions library/Criteria/Isolated/ActiveRecordCriteria.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,16 +39,18 @@ public function apply(ModelStubInterface $model)
*/
public function applyWrite(ModelStubInterface $model, array &$data)
{
unset($data['_id']);

if ($this->id) {
if ($this->hasId()) {
$data['_id'] = $this->extractId($model);
}

if (array_key_exists('_id', $data) && null === $data['_id']) {
unset($data['_id']);
}

return $this->getDocumentStore()->isolatedUpsert(
$model->getDataGateway(),
$data,
$this->getSaveOptions()
$this->getMongoOptions()
);
}

Expand All @@ -60,7 +62,8 @@ public function applyDelete(ModelStubInterface $model)
{
return $this->getDocumentStore()->isolatedRemove(
$model->getDataGateway(),
$this->extractId($model)
$this->extractId($model),
$this->getMongoOptions()
);
}
}
4 changes: 2 additions & 2 deletions library/Criteria/Isolated/DocumentStore.php
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ public function isolatedUpsert(MongoCollection $dataGateway, array &$data, array
$oldDocumentData,
$data, // modifiers and non-modifiers cannot be mixed,
// the _id presence ensure at least one non-modifiers
array_merge($options, ['multi' => false, 'upsert' => false])
['multi' => false, 'upsert' => false] + $options
);
$result = $this->handleResult($result);

Expand Down Expand Up @@ -258,7 +258,7 @@ public function isolatedRemove(MongoCollection $dataGateway, $id, array $options
throw new RuntimeException(sprintf('No local copy found for the document "%s"', $id));
}

$result = $dataGateway->remove($this->get($dataGateway, $id), $options);
$result = $dataGateway->remove($this->get($dataGateway, $id), ['justOne' => true] + $options);
$result = $this->handleResult($result, true);

if ($result != 1) {
Expand Down
43 changes: 33 additions & 10 deletions library/Hydrator/Strategy/MongoBinDataStrategy.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,19 @@
*/
namespace Matryoshka\Model\Wrapper\Mongo\Hydrator\Strategy;

use MongoBinData;
use Zend\Stdlib\Hydrator\Strategy\StrategyInterface;
use Matryoshka\Model\Hydrator\Strategy\NullableStrategyTrait;
use Matryoshka\Model\Hydrator\Strategy\NullableStrategyInterface;
use Matryoshka\Model\Exception;

/**
* Class MongoBinDataStrategy
*/
class MongoBinDataStrategy implements StrategyInterface
class MongoBinDataStrategy implements StrategyInterface, NullableStrategyInterface
{
use NullableStrategyTrait;

/**
* @var int
*/
Expand Down Expand Up @@ -45,24 +51,41 @@ public function setType($type)
$this->type = (int) $type;
return $this;
}

/**
* Ensure the value extracted is typed as \MongoBinData or null
*
* Convert a MongoBinData to binary string
*
* @param mixed $value The original value.
* @return null|\MongoBinData Returns the value that should be extracted.
* @return null|string Returns the value that should be hydrated.
*/
public function extract($value)
public function hydrate($value)
{
return null === $value ? null : new \MongoBinData($value, $this->type);
if ($this->nullable && $value === null) {
return null;
}

if ($value instanceof MongoBinData) {
return $value->bin;
}

throw new Exception\InvalidArgumentException(sprintf(
'Invalid value: must be an instance of MongoBinData, "%s" given',
is_object($value) ? get_class($value) : gettype($value)
));
}

/**
* Ensure the value extracted is typed as MongoBinData or null
*
* @param mixed $value The original value.
* @return null|string Returns the value that should be hydrated.
* @return null|\MongoBinData Returns the value that should be extracted.
*/
public function hydrate($value)
public function extract($value)
{
return $value instanceof \MongoBinData ? $value->bin : null;
if ($this->nullable && $value === null) {
return null;
}

return new MongoBinData($value, $this->type);
}
}
56 changes: 40 additions & 16 deletions library/Hydrator/Strategy/MongoDateStrategy.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,17 @@
use DateTime;
use MongoDate;
use Zend\Stdlib\Hydrator\Strategy\StrategyInterface;
use Matryoshka\Model\Hydrator\Strategy\NullableStrategyInterface;
use Matryoshka\Model\Hydrator\Strategy\NullableStrategyTrait;
use Matryoshka\Model\Exception;

/**
* Class MongoDateStrategy
*/
class MongoDateStrategy implements StrategyInterface
class MongoDateStrategy implements StrategyInterface, NullableStrategyInterface
{
use NullableStrategyTrait;

/**
* @var string
*/
Expand All @@ -34,34 +39,53 @@ public function __construct($format = null)
}
}


/**
* Convert a MongoDate to a DateTime
*
* @param mixed $value
* @return DateTime|mixed
* @return mixed|MongoDate
*/
public function extract($value)
public function hydrate($value)
{
if ($value instanceof DateTime) {
$value = new MongoDate($value->format('U'));
} else {
$value = null;
if ($value instanceof MongoDate) {
return new DateTime(date($this->getFormat(), $value->sec));
}

if ($this->nullable && $value === null) {
return null;
}
return $value;

throw new Exception\InvalidArgumentException(sprintf(
'Invalid value: must be an instance of MongoDate, "%s" given.',
is_object($value) ? get_class($value) : gettype($value)
));
}



/**
* Convert a DateTime to a MongoDate
*
* @param mixed $value
* @return mixed|MongoDate
* @return DateTime|mixed
*/
public function hydrate($value)
public function extract($value)
{
if ($value instanceof MongoDate) {
$value = new DateTime(date($this->getFormat(), $value->sec));
} else {
$value = null;
if ($value instanceof DateTime) {
return new MongoDate($value->format('U'));
}

if ($this->nullable && $value === null) {
return null;
}
return $value;

throw new Exception\InvalidArgumentException(sprintf(
'Invalid value: must be an instance of DateTime, "%s" given.',
is_object($value) ? get_class($value) : gettype($value)
));
}


/**
* @param string $format
* @return $this
Expand Down
Loading

0 comments on commit 69aa653

Please sign in to comment.