From 6209ef46a356ee7245069f85357eccdf51cb3453 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Mi=C5=A1o=20=C4=8Cerve=C5=88=C3=A1k?= Date: Fri, 26 Mar 2021 05:14:22 +0100 Subject: [PATCH] Add storeModel & updateModel methods --- README.md | 2 +- composer.json | 2 +- src/AbstractService.php | 35 ++++++++++++++--- tests/Tests/ServiceOperationTest.phpt | 54 +++++++++++++++++++++++++-- 4 files changed, 81 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 9b4b759..886667c 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # Nette ORM ![GitHub branch checks state](https://img.shields.io/github/checks-status/fykosak/nette-orm/master) - + ## install diff --git a/composer.json b/composer.json index 51d6482..8d12a5f 100644 --- a/composer.json +++ b/composer.json @@ -3,7 +3,7 @@ "name": "fykosak/nette-orm", "type": "library", "license": "GPL-3.0-or-later", - "version": "0.2.1", + "version": "0.2.2", "require": { "php": ">=7.4", "nette/di": "^3.0", diff --git a/src/AbstractService.php b/src/AbstractService.php index 3e4bf2e..5e0ce3a 100644 --- a/src/AbstractService.php +++ b/src/AbstractService.php @@ -4,7 +4,6 @@ use Fykosak\NetteORM\Exceptions\ModelException; use InvalidArgumentException; -use Nette\Database\Conventions; use Nette\Database\Explorer; use Nette\SmartObject; use PDOException; @@ -42,14 +41,10 @@ public function createNewModel(array $data): AbstractModel { $data = $this->filterData($data); try { $result = $this->getTable()->insert($data); - if ($result !== false) { - return ($modelClassName)::createFromActiveRow($result); - } + return ($modelClassName)::createFromActiveRow($result); } catch (PDOException $exception) { throw new ModelException('Error when storing model.', null, $exception); } - $code = $this->explorer->getConnection()->getPdo()->errorCode(); - throw new ModelException("$code: Error when storing a model."); } /** @@ -80,6 +75,7 @@ public function refresh(AbstractModel $model): AbstractModel { * @param array $data * @return bool * @throws ModelException + * @deprecated use updateModel will be removed in 0.3.0 */ public function updateModel2(AbstractModel $model, array $data): bool { try { @@ -91,6 +87,23 @@ public function updateModel2(AbstractModel $model, array $data): bool { } } + /** + * @param AbstractModel $model + * @param array $data + * @return AbstractModel refreshed model + * @throws ModelException + */ + public function updateModel(AbstractModel $model, array $data): AbstractModel { + try { + $this->checkType($model); + $data = $this->filterData($data); + $model->update($data); + return $this->refresh($model); + } catch (PDOException $exception) { + throw new ModelException('Error when storing model.', null, $exception); + } + } + /** * Use this method to delete a model! * (Name chosen not to collide with parent.) @@ -112,6 +125,12 @@ public function getTable(): TypedTableSelection { return new TypedTableSelection($this->getModelClassName(), $this->tableName, $this->explorer, $this->explorer->getConventions()); } + /** + * @param AbstractModel|null $model + * @param array $data + * @return AbstractModel + * @deprecated use storeModel will be removed in 0.3.0 + */ public function store(?AbstractModel $model, array $data): AbstractModel { if ($model) { $this->updateModel2($model, $data); @@ -121,6 +140,10 @@ public function store(?AbstractModel $model, array $data): AbstractModel { } } + public function storeModel(array $data, ?AbstractModel $model = null): AbstractModel { + return isset($model) ? $this->updateModel($model, $data) : $this->createNewModel($data); + } + /** @return string|AbstractModel */ final public function getModelClassName(): string { return $this->modelClassName; diff --git a/tests/Tests/ServiceOperationTest.phpt b/tests/Tests/ServiceOperationTest.phpt index ae396ab..2231d54 100644 --- a/tests/Tests/ServiceOperationTest.phpt +++ b/tests/Tests/ServiceOperationTest.phpt @@ -50,7 +50,15 @@ class ServiceOperationTest extends AbstractTestCase { Assert::null($nullParticipant); } - public function testUpdateSuccess(): void { + public function testFindByPrimaryProtection(): void { + /** @var ServiceParticipant $serviceParticipant */ + $serviceParticipant = $this->container->getByType(ServiceParticipant::class); + $participant = $serviceParticipant->findByPrimary(null); + + Assert::null($participant); + } + + public function testLegacyUpdateSuccess(): void { /** @var ServiceParticipant $serviceParticipant */ $serviceParticipant = $this->container->getByType(ServiceParticipant::class); $participant = $serviceParticipant->findByPrimary(2); @@ -60,7 +68,7 @@ class ServiceOperationTest extends AbstractTestCase { Assert::type(ModelParticipant::class, $newParticipant); } - public function testUpdateError(): void { + public function testLegacyUpdateError(): void { /** @var ServiceParticipant $serviceParticipant */ $serviceParticipant = $this->container->getByType(ServiceParticipant::class); $participant = $serviceParticipant->findByPrimary(2); @@ -72,7 +80,28 @@ class ServiceOperationTest extends AbstractTestCase { Assert::same('Bára', $newParticipant->name); } - public function testStoreExists(): void { + public function testUpdateSuccess(): void { + /** @var ServiceParticipant $serviceParticipant */ + $serviceParticipant = $this->container->getByType(ServiceParticipant::class); + $participant = $serviceParticipant->findByPrimary(2); + $newParticipant = $serviceParticipant->updateModel($participant, ['name' => 'Betka']); + Assert::same('Betka', $newParticipant->name); + Assert::type(ModelParticipant::class, $newParticipant); + } + + public function testUpdateError(): void { + /** @var ServiceParticipant $serviceParticipant */ + $serviceParticipant = $this->container->getByType(ServiceParticipant::class); + $participant = $serviceParticipant->findByPrimary(2); + + Assert::exception(function () use ($participant, $serviceParticipant) { + $serviceParticipant->updateModel($participant, ['event_id' => 4]); + }, ModelException::class); + $newParticipant = $serviceParticipant->refresh($participant); + Assert::same('Bára', $newParticipant->name); + } + + public function testLegacyStoreExists(): void { /** @var ServiceParticipant $serviceParticipant */ $serviceParticipant = $this->container->getByType(ServiceParticipant::class); $participant = $serviceParticipant->findByPrimary(2); @@ -81,7 +110,16 @@ class ServiceOperationTest extends AbstractTestCase { Assert::type(ModelParticipant::class, $newParticipant); } - public function testStoreNew(): void { + public function testStoreExists(): void { + /** @var ServiceParticipant $serviceParticipant */ + $serviceParticipant = $this->container->getByType(ServiceParticipant::class); + $participant = $serviceParticipant->findByPrimary(2); + $newParticipant = $serviceParticipant->storeModel(['name' => 'Betka'], $participant); + Assert::same('Betka', $newParticipant->name); + Assert::type(ModelParticipant::class, $newParticipant); + } + + public function testLegacyStoreNew(): void { /** @var ServiceParticipant $serviceParticipant */ $serviceParticipant = $this->container->getByType(ServiceParticipant::class); $newParticipant = $serviceParticipant->store(null, ['event_id' => 1, 'name' => 'Igor']); @@ -89,6 +127,14 @@ class ServiceOperationTest extends AbstractTestCase { Assert::type(ModelParticipant::class, $newParticipant); } + public function testStoreNew(): void { + /** @var ServiceParticipant $serviceParticipant */ + $serviceParticipant = $this->container->getByType(ServiceParticipant::class); + $newParticipant = $serviceParticipant->storeModel(['event_id' => 1, 'name' => 'Igor'], null); + Assert::same('Igor', $newParticipant->name); + Assert::type(ModelParticipant::class, $newParticipant); + } + public function testDelete(): void { /** @var ServiceParticipant $serviceParticipant */ $serviceParticipant = $this->container->getByType(ServiceParticipant::class);