diff --git a/README.md b/README.md index dba2ef1..8d1341c 100644 --- a/README.md +++ b/README.md @@ -2,129 +2,14 @@ [![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 -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 - '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 -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 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 diff --git a/src/Registry.php b/src/Registry.php new file mode 100644 index 0000000..a85183c --- /dev/null +++ b/src/Registry.php @@ -0,0 +1,75 @@ +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; + } +} diff --git a/src/Repository.php b/src/Repository.php index 88a4a26..acd0695 100644 --- a/src/Repository.php +++ b/src/Repository.php @@ -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; } diff --git a/src/MongodbStorage.php b/src/Storage.php similarity index 96% rename from src/MongodbStorage.php rename to src/Storage.php index 49df0f1..fdb92a5 100644 --- a/src/MongodbStorage.php +++ b/src/Storage.php @@ -5,7 +5,7 @@ use MongoDB\BSON\ObjectID; use MongoDB\Collection; -class MongodbStorage +class Storage { /** * @var Collection @@ -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 @@ -214,12 +225,4 @@ public function getCollection() { return $this->collection; } - - /** - * @return Repository - */ - public function getRepository() - { - return new Repository($this); - } } diff --git a/tests/Functional/MongodbStorageTest.php b/tests/Functional/StorageTest.php similarity index 89% rename from tests/Functional/MongodbStorageTest.php rename to tests/Functional/StorageTest.php index bff22df..47fa851 100644 --- a/tests/Functional/MongodbStorageTest.php +++ b/tests/Functional/StorageTest.php @@ -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(); @@ -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']]; @@ -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']; @@ -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']; @@ -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']; @@ -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'; @@ -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([]);