diff --git a/documentation/model_manager.rst b/documentation/model_manager.rst index 75b319a..9cb0292 100644 --- a/documentation/model_manager.rst +++ b/documentation/model_manager.rst @@ -471,6 +471,19 @@ Mass deletion, return an iterator on deleted results hydrated by the model’s p // delete from {relation} where salary > $* returning {projection} $employees = $employee_model->deleteWhere('salary > $*', [$max_salary]); +truncate +........... + +Remove all data from model. + +.. code:: php + + truncate(false, false); + + Complex queries ~~~~~~~~~~~~~~~ diff --git a/sources/lib/Model/ModelTrait/WriteQueries.php b/sources/lib/Model/ModelTrait/WriteQueries.php index 46b21ce..454ba22 100644 --- a/sources/lib/Model/ModelTrait/WriteQueries.php +++ b/sources/lib/Model/ModelTrait/WriteQueries.php @@ -211,6 +211,42 @@ public function deleteWhere($where, array $values = []) return $collection; } + /** + * truncate + * + * Delete all records. + * + * @param bool $cascade + * @param bool $restart + * @return Model $this + */ + public function truncate($cascade = false, $restart = false) + { + $type_truncate = 'RESTRICT'; + $identity = 'CONTINUE'; + + if ($cascade) { + $type_truncate = 'CASCADE'; + } + + if ($restart) { + $identity = 'RESTART'; + } + + $sql = strtr( + "truncate :relation :identity :type_truncate", + [ + ':relation' => $this->getStructure()->getRelation(), + ':type_truncate' => $type_truncate, + ':identity' => $identity . ' IDENTITY ' + ] + ); + + $this->query($sql, []); + + return $this; + } + /** * createAndSave * diff --git a/sources/tests/Fixture/ForeignKeyFixture.php b/sources/tests/Fixture/ForeignKeyFixture.php new file mode 100644 index 0000000..08db121 --- /dev/null +++ b/sources/tests/Fixture/ForeignKeyFixture.php @@ -0,0 +1,16 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PommProject\ModelManager\Test\Fixture; + +use PommProject\ModelManager\Model\FlexibleEntity; + +class ForeignKeyFixture extends FlexibleEntity +{ +} diff --git a/sources/tests/Fixture/ForeignKeyFixtureModel.php b/sources/tests/Fixture/ForeignKeyFixtureModel.php new file mode 100644 index 0000000..243cde2 --- /dev/null +++ b/sources/tests/Fixture/ForeignKeyFixtureModel.php @@ -0,0 +1,37 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PommProject\ModelManager\Test\Fixture; + +use PommProject\Foundation\Session\Session; +use PommProject\ModelManager\Model\ModelTrait\WriteQueries; + +class ForeignKeyFixtureModel extends WriteFixtureModel +{ + use WriteQueries; + + public function __construct() + { + $this->structure = new ForeignKeyFixtureStructure(); + $this->flexible_entity_class = '\PommProject\ModelManager\Test\Fixture\ForeignKeyFixture'; + $this->getStructure()->setRelation('foreign_key_fixture'); + } + + protected function createTable() + { + $this->executeAnonymousQuery( + sprintf( + "create temporary table %s (id serial primary key, truncate_id int, CONSTRAINT fk_truncate FOREIGN KEY(truncate_id) REFERENCES truncate_fixture(id))", + $this->getStructure()->getRelation() + ) + ); + + return $this; + } +} diff --git a/sources/tests/Fixture/ForeignKeyFixtureStructure.php b/sources/tests/Fixture/ForeignKeyFixtureStructure.php new file mode 100644 index 0000000..d7ba9ed --- /dev/null +++ b/sources/tests/Fixture/ForeignKeyFixtureStructure.php @@ -0,0 +1,24 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PommProject\ModelManager\Test\Fixture; + +use PommProject\ModelManager\Model\RowStructure; + +class ForeignKeyFixtureStructure extends RowStructure +{ + public function __construct() + { + $this + ->addField('id', 'int4') + ->addField('truncate_id', 'int4') + ->primary_key = ['id'] + ; + } +} diff --git a/sources/tests/Fixture/TruncateFixtureModel.php b/sources/tests/Fixture/TruncateFixtureModel.php new file mode 100644 index 0000000..0423f65 --- /dev/null +++ b/sources/tests/Fixture/TruncateFixtureModel.php @@ -0,0 +1,24 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PommProject\ModelManager\Test\Fixture; + +use PommProject\Foundation\Session\Session; +use PommProject\ModelManager\Model\ModelTrait\WriteQueries; + +class TruncateFixtureModel extends WriteFixtureModel +{ + use WriteQueries; + + public function __construct() + { + parent::__construct(); + $this->getStructure()->setRelation('truncate_fixture'); + } +} diff --git a/sources/tests/Unit/Model/Model.php b/sources/tests/Unit/Model/Model.php index 5ba47a6..4568fa8 100644 --- a/sources/tests/Unit/Model/Model.php +++ b/sources/tests/Unit/Model/Model.php @@ -56,6 +56,20 @@ protected function getWriteFixtureModel(Session $session) ; } + protected function getTruncateFixtureModel(Session $session) + { + return $session + ->getModel('PommProject\ModelManager\Test\Fixture\TruncateFixtureModel') + ; + } + + protected function getForeignKeyFixtureModel(Session $session) + { + return $session + ->getModel('PommProject\ModelManager\Test\Fixture\ForeignKeyFixtureModel') + ; + } + protected function getWithoutPKFixtureModel(Session $session) { return $session @@ -468,6 +482,88 @@ public function testGetModel() ->isTrue() ; } + + public function testTruncateNoCascadeNoRestart() + { + $session = $this->buildSession(); + $model = $this->getTruncateFixtureModel($session); + $entity = $model->createAndSave(['a_varchar' => 'abcdef', 'a_boolean' => true]); + $where = new Where(); + + $this + ->integer($entity->getId()) + ->isEqualTo(1) + ->integer($model->countWhere($where)) + ->isEqualTo(1) + ->object($model->truncate()) + ->isInstanceOf('\PommProject\ModelManager\Test\Fixture\TruncateFixtureModel') + ->integer($model->countWhere($where)) + ->isEqualTo(0) + ; + + $entity = $model->createAndSave(['a_varchar' => 'abcdef', 'a_boolean' => true]); + $this + ->integer($entity->getId()) + ->isEqualTo(2); + } + + public function testTruncateNoCascadeRestart() + { + $session = $this->buildSession(); + $model = $this->getTruncateFixtureModel($session); + $entity = $model->createAndSave(['a_varchar' => 'abcdef', 'a_boolean' => true]); + $where = new Where(); + $this + ->integer($entity->getId()) + ->isEqualTo(1) + ->integer($model->countWhere($where)) + ->isEqualTo(1) + ->object($model->truncate(false, true)) + ->isInstanceOf('\PommProject\ModelManager\Test\Fixture\TruncateFixtureModel') + ->integer($model->countWhere($where)) + ->isEqualTo(0) + ; + + $entity = $model->createAndSave(['a_varchar' => 'abcdef', 'a_boolean' => true]); + $this + ->integer($entity->getId()) + ->isEqualTo(1); + } + + public function testTruncateCascadeNoRestart() + { + $session = $this->buildSession(); + $model = $this->getTruncateFixtureModel($session); + $modelFk = $this->getForeignKeyFixtureModel($session); + $entity = $model->createAndSave(['a_varchar' => 'abcdef', 'a_boolean' => true]); + $entityFk = $modelFk->createAndSave(['truncate_id' => $entity->getId()]); + + $where = new Where(); + $this + ->integer($entity->getId()) + ->isEqualTo(1) + ->integer($model->countWhere($where)) + ->isEqualTo(1) + ->integer($modelFk->countWhere($where)) + ->isEqualTo(1) + ->object($model->truncate(true, false)) + ->isInstanceOf('\PommProject\ModelManager\Test\Fixture\TruncateFixtureModel') + ->integer($model->countWhere($where)) + ->isEqualTo(0) + ->integer($modelFk->countWhere($where)) + ->isEqualTo(0) + ; + + $entity = $model->createAndSave(['a_varchar' => 'abcdef', 'a_boolean' => true]); + $entityFk = $modelFk->createAndSave(['truncate_id' => $entity->getId()]); + $this + ->integer($entity->getId()) + ->isEqualTo(2) + ->exception(function () use ($model) {$model->truncate(false, false);}) + ->isInstanceOf('\PommProject\Foundation\Exception\SqlException') + ->message->contains("0A000") + ; + } } class NoStructureNoFlexibleEntityModel extends PommModel