Skip to content

Commit

Permalink
Add registry, rename mongodb storage to storage. upd readme.
Browse files Browse the repository at this point in the history
  • Loading branch information
makasim committed Mar 13, 2017
1 parent 9a1b5e2 commit 3a1a3b9
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 141 deletions.
135 changes: 15 additions & 120 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,148 +2,43 @@

[![Build Status](https://travis-ci.org/makasim/values.png?branch=master)](https://travis-ci.org/makasim/yadm)

The schema less ODM. It gives you the fastest hydration and persistent. The easiest solution for building aggregation roots or objects trees. It is a good choice for [aggregation root](http://martinfowler.com/bliki/DDD_Aggregate.html) models because it super easy t build object trees. [bounded context](http://martinfowler.com/bliki/BoundedContext.html) could be easily build too, because that easy to copy object data from one model to another.

This approach tries to gather the best from arrays and objects.
The schema less ODM. It gives you the fastest hydration and persistent. Based on [makasim/values](https://github.com/makasim/values) lib.

## Benchmarks

* [Results](https://docs.google.com/spreadsheets/d/1CzVQuAz6cVAUKZyoQZyagQv48mgA3JAYJ2dNsoALV7A/edit#gid=0)
* [Code](https://github.com/makasim/yadm-benchmark)

## Fast persistence.

To get object state you have to read an array from protected `values` property. You can add a public getter for it or use reflection. There is a handy method for it `get_object_values`.
Once you get the array you can easily persist it.

```php
<?php
namespace Acme;

use function Makasim\Values\get_values;

$price = new Price();
$price->setAmount(100);
$price->setCurrency('USD');

$order = new Order;
$order->setNumber('theNumber');
$order->setPrice($price);

$array = get_values($order);
// [
// 'number' => 'theNumber'
// 'price' => ['amount' => 100, 'currency' => 'USD'],
// ]
```

## Fast hydration

To set object state you have to write to protected `values` property.
You can add a public getter for it or use reflection.
There is a handy method for it `set_object_values`.
Once you set the array you can use the model.

```php
<?php
namespace Acme;
use function Makasim\Values\set_values;

$order = new Order;

set_values($order, [
'number' => 'theNumber',
'price' => ['amount' => 100, 'currency' => 'USD'],
]);

$order->getNumber(); // theNumber
$order->getPrice()->getAmount(); // 100
$order->getPrice()->getCurrency(); // USD
```

## Models

You store everything in `values` property as array.

```php
<?php
namespace Acme;

use Makasim\Values\ValuesTrait;
use Makasim\Values\ObjectsTrait;

class Price
{
use ValuesTrait;

public function getAmount()
{
return $this->getValue('amount');
}

public function setAmount($amount)
{
$this->setValue('amount', $amount);
}

public function getCurrency()
{
return $this->getValue('currency');
}

public function setCurrency($currency)
{
$this->setValue('currency', $currency);
}
}

class Order
{
use ValuesTrait;
use ObjectsTrait;

public function getNumber()
{
return $this->getValue('number');
}

public function setNumber($number)
{
$this->setValue('number', $number);
}

public function getPrice()
{
return $this->getObject('price', Price::class);
}

public function setPrice(Price $price = null)
{
$this->setObject('price', $price);
}
}
```

## Mongodb storage
## Storage example

```php
<?php
namespace Acme;

use MongoDB\Client;
use Makasim\Yadm\Hydrator;
use Makasim\Yadm\MongodbStorage;
use Makasim\Yadm\Storage;

$collection = (new Client())->selectCollection('acme_demo', 'orders');
$hydrator = new Hydrator(Order::class);
$storage = new MongodbStorage($collection, $hydrator);
$storage = new Storage($collection, $hydrator);

$order = $storage->create();
$order = new Order();
$order->setNumber(1234);

$storage->insert($order);

$foundOrder = $storage->find(['_id' => get_object_id($order)]);
$foundOrder->setNumber(4321);
$storage->update($foundOrder);

$storage->delete($foundOrder);
```

## Other examples

In [makasim/values](https://github.com/makasim/values) repo you can find examples on how to build simple objects, object trees, hydrate and retrive data from\to object.

## License

MIT
75 changes: 75 additions & 0 deletions src/Registry.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<?php
namespace Makasim\Yadm;

class Registry
{
/**
* @var array|Storage[]
*/
private $storages;

/**
* @var array|Repository[]
*/
private $repositories;

/**
* @param Storage[]|array $storages
* @param Repository[]|array $repositories
*/
public function __construct(array $storages, array $repositories)
{
$this->storages = $storages;
$this->repositories = $repositories;
}

/**
* @param object|string $modelOrClass
*
* @return Storage
*/
public function getStorage($modelOrClass)
{
$class = is_object($modelOrClass) ? get_class($modelOrClass) : $modelOrClass;

if (false == array_key_exists($class, $this->storages)) {
throw new \InvalidArgumentException(sprintf('The storage for model "%s" does not exist', $class));
}

$storage = $this->storages[$class];
if (false == $storage instanceof Storage) {
throw new \LogicException(sprintf(
'Storage must be instance of %s but got %s',
Storage::class,
is_object($storage) ? get_class($storage) : gettype($storage)
));
}

return $storage;
}

/**
* @param object|string $modelOrClass
*
* @return Repository
*/
public function getRepository($modelOrClass)
{
$class = is_object($modelOrClass) ? get_class($modelOrClass) : $modelOrClass;

if (false == array_key_exists($class, $this->repositories)) {
$this->repositories = new Repository($this->getStorage($class));
}

$repository = $this->repositories[$class];
if (false == $repository instanceof Repository) {
throw new \LogicException(sprintf(
'Repository must be instance of %s but got %s',
Repository::class,
is_object($repository) ? get_class($repository) : gettype($repository)
));
}

return $repository;
}
}
6 changes: 3 additions & 3 deletions src/Repository.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@
class Repository
{
/**
* @var MongodbStorage
* @var Storage
*/
protected $storage;

/**
* @param MongodbStorage $storage
* @param Storage $storage
*/
public function __construct(MongodbStorage $storage)
public function __construct(Storage $storage)
{
$this->storage = $storage;
}
Expand Down
21 changes: 12 additions & 9 deletions src/MongodbStorage.php → src/Storage.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
use MongoDB\BSON\ObjectID;
use MongoDB\Collection;

class MongodbStorage
class Storage
{
/**
* @var Collection
Expand Down Expand Up @@ -187,6 +187,17 @@ public function find(array $filter = [], array $options = [])
}
}

/**
* @param array $filter
* @param array $options
*
* @return int
*/
public function count(array $filter = [], array $options = [])
{
return $this->collection->count($filter, $options);
}

/**
* @param $id
* @param callable $lockCallback
Expand Down Expand Up @@ -214,12 +225,4 @@ public function getCollection()
{
return $this->collection;
}

/**
* @return Repository
*/
public function getRepository()
{
return new Repository($this);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,18 @@

use Makasim\Yadm\Hydrator;
use Makasim\Yadm\PessimisticLock;
use Makasim\Yadm\MongodbStorage;
use Makasim\Yadm\Storage;
use MongoDB\BSON\ObjectID;
use MongoDB\InsertOneResult;

class MongodbStorageTest extends FunctionalTest
class StorageTest extends FunctionalTest
{
public function testCreateModel()
{
$collection = $this->database->selectCollection('storage_test');
$hydrator = new Hydrator(Model::class);

$storage = new MongodbStorage($collection, $hydrator);
$storage = new Storage($collection, $hydrator);


$model = $storage->create();
Expand All @@ -28,7 +28,7 @@ public function testInsertModel()
$collection = $this->database->selectCollection('storage_test');
$hydrator = new Hydrator(Model::class);

$storage = new MongodbStorage($collection, $hydrator);
$storage = new Storage($collection, $hydrator);

$model = new Model();
$model->values = ['foo' => 'fooVal', 'bar' => 'barVal', 'ololo' => ['foo', 'foo' => 'fooVal']];
Expand All @@ -53,7 +53,7 @@ public function testUpdateModel()
$collection = $this->database->selectCollection('storage_test');
$hydrator = new Hydrator(Model::class);

$storage = new MongodbStorage($collection, $hydrator);
$storage = new Storage($collection, $hydrator);

$model = new Model();
$model->values = ['foo' => 'fooVal', 'bar' => 'barVal'];
Expand Down Expand Up @@ -81,7 +81,7 @@ public function testDeleteModel()
$collection = $this->database->selectCollection('storage_test');
$hydrator = new Hydrator(Model::class);

$storage = new MongodbStorage($collection, $hydrator);
$storage = new Storage($collection, $hydrator);

$model = new Model();
$model->values = ['foo' => 'fooVal', 'bar' => 'barVal'];
Expand All @@ -108,7 +108,7 @@ public function testUpdateModelPessimisticLock()
$collection = $this->database->selectCollection('storage_test');
$hydrator = new Hydrator(Model::class);

$storage = new MongodbStorage($collection, $hydrator, null, $pessimisticLock);
$storage = new Storage($collection, $hydrator, null, $pessimisticLock);

$model = new Model();
$model->values = ['foo' => 'fooVal', 'bar' => 'barVal'];
Expand All @@ -122,7 +122,7 @@ public function testUpdateModelPessimisticLock()
self::assertInstanceOf(Model::class, $lockedModel);
self::assertEquals($model->values, $lockedModel->values);

self::assertInstanceOf(MongodbStorage::class, $storage);
self::assertInstanceOf(Storage::class, $storage);

$model->values['ololo'] = 'ololoVal';

Expand All @@ -143,7 +143,7 @@ public function testFindModels()
$collection = $this->database->selectCollection('storage_test');
$hydrator = new Hydrator(Model::class);

$storage = new MongodbStorage($collection, $hydrator);
$storage = new Storage($collection, $hydrator);

$result = $storage->find([]);

Expand Down

0 comments on commit 3a1a3b9

Please sign in to comment.