Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions documentation/model_manager.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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

<?php
// …
// truncate {relation} {cascade} {restart}
$employee_model->truncate(false, false);


Complex queries
~~~~~~~~~~~~~~~

Expand Down
36 changes: 36 additions & 0 deletions sources/lib/Model/ModelTrait/WriteQueries.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
*
Expand Down
16 changes: 16 additions & 0 deletions sources/tests/Fixture/ForeignKeyFixture.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php
/*
* This file is part of the PommProject/ModelManager package.
*
* (c) 2014 - 2015 Grégoire HUBERT <hubert.greg@gmail.com>
*
* 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
{
}
37 changes: 37 additions & 0 deletions sources/tests/Fixture/ForeignKeyFixtureModel.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php
/*
* This file is part of the PommProject/ModelManager package.
*
* (c) 2014 - 2015 Grégoire HUBERT <hubert.greg@gmail.com>
*
* 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;
}
}
24 changes: 24 additions & 0 deletions sources/tests/Fixture/ForeignKeyFixtureStructure.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php
/*
* This file is part of the PommProject/ModelManager package.
*
* (c) 2014 - 2015 Grégoire HUBERT <hubert.greg@gmail.com>
*
* 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']
;
}
}
24 changes: 24 additions & 0 deletions sources/tests/Fixture/TruncateFixtureModel.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php
/*
* This file is part of the PommProject/ModelManager package.
*
* (c) 2014 - 2015 Grégoire HUBERT <hubert.greg@gmail.com>
*
* 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');
}
}
96 changes: 96 additions & 0 deletions sources/tests/Unit/Model/Model.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not keen on myFunc(true, false) It would make more sense to me to have ->truncate("CASCADE AND MORE OPTIONS");
This IMHO let the developer with full control of future Pg extensions to the truncate command. The only issue I see is a security concern, it would imply to cut everything after a semicolon character to ensure a brain dead developer that passes truncate options from an external environment would still be safe.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another option can be instead of "true, false" use some constant or bit like `truncate(PG_TRUNCATE_CASCADE | PG_TRUNCATE_RESTART)

If any extension is added, a simple define can be added.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm ok with you for postgres developer, but for beginner developer, it's less easy. If you want to use an other syntax for truncate you could be to use ->query('TRUNCATE ....'). For me, the SQL is the best language but for the rest of the world is not a sexy language.
it would be a shame not to help those developpers, no? I thinks our job is to help the rest of the world to discover all the postgresql functionalities :)
Postgresql developer keeps control of his actions and queries, and the junior developer is not afraid of sql

But I'm ok to change the method signature because bool is not a good practice

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ping @chanmix51

->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
Expand Down