diff --git a/lib/Cake/Model/Datasource/Database/Postgres.php b/lib/Cake/Model/Datasource/Database/Postgres.php index 9b1fbcf3d..5b79ea57d 100644 --- a/lib/Cake/Model/Datasource/Database/Postgres.php +++ b/lib/Cake/Model/Datasource/Database/Postgres.php @@ -291,6 +291,22 @@ class Postgres extends DboSource { } } +/** + * Reset a sequence based on the MAX() value of $column. Useful + * for resetting sequences after using insertMulti(). + * + * @param string $table The name of the table to update. + * @param string $column The column to use when reseting the sequence value, the + * sequence name will be fetched using Postgres::getSequence(); + * @return boolean success. + */ + public function resetSequence($table, $column) { + $sequence = $this->value($this->getSequence($table, $column)); + $table = $this->fullTableName($table); + $this->execute("SELECT setval($sequence, (SELECT MAX(id) FROM $table))"); + return true; + } + /** * Deletes all the records in a table and drops all associated auto-increment sequences * diff --git a/lib/Cake/Model/Datasource/DboSource.php b/lib/Cake/Model/Datasource/DboSource.php index 01c0cf5ba..4d4843b42 100644 --- a/lib/Cake/Model/Datasource/DboSource.php +++ b/lib/Cake/Model/Datasource/DboSource.php @@ -2920,6 +2920,20 @@ class DboSource extends DataSource { return $this->commit(); } +/** + * Reset a sequence based on the MAX() value of $column. Useful + * for resetting sequences after using insertMulti(). + * + * This method should be implmented by datasources that require sequences to be used. + * + * @param string $table The name of the table to update. + * @param string $column The column to use when reseting the sequence value. + * @return boolean success. + */ + public function resetSequence($table, $column) { + + } + /** * Returns an array of the indexes in given datasource name. * diff --git a/lib/Cake/Test/Case/Model/Datasource/Database/PostgresTest.php b/lib/Cake/Test/Case/Model/Datasource/Database/PostgresTest.php index 154920262..7015750d3 100644 --- a/lib/Cake/Test/Case/Model/Datasource/Database/PostgresTest.php +++ b/lib/Cake/Test/Case/Model/Datasource/Database/PostgresTest.php @@ -950,4 +950,26 @@ class PostgresTest extends CakeTestCase { $this->assertNotEmpty($model->read(null, 1)); } + public function testResetSequence() { + $model = new Article(); + + $table = $this->Dbo->fullTableName($model, false); + $fields = array( + 'id', 'user_id', 'title', 'body', 'published', + ); + $values = array( + array(1, 1, 'test', 'first post', false), + array(2, 1, 'test 2', 'second post post', false), + ); + $this->Dbo->insertMulti($table, $fields, $values); + $sequence = $this->Dbo->getSequence($table); + $result = $this->Dbo->rawQuery("SELECT nextval('$sequence')"); + $original = $result->fetch(PDO::FETCH_ASSOC); + + $this->assertTrue($this->Dbo->resetSequence($table, 'id')); + $result = $this->Dbo->rawQuery("SELECT currval('$sequence')"); + $new = $result->fetch(PDO::FETCH_ASSOC); + $this->assertTrue($new['currval'] > $original['nextval'], 'Sequence did not update'); + } + }