Browse Source

Implement resetSequence()

This is an optional method in DboSource that allows datasources to
resetSequence values in tables.  This is useful for datasources like
Postgres, and makes using fixtures much easier.

Fixes #3026
mark_story 13 years ago
parent
commit
55dcb9c3b3

+ 16 - 0
lib/Cake/Model/Datasource/Database/Postgres.php

@@ -292,6 +292,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
  *
  * @param string|Model $table A string or model class representing the table to be truncated

+ 14 - 0
lib/Cake/Model/Datasource/DboSource.php

@@ -2921,6 +2921,20 @@ class DboSource extends DataSource {
 	}
 
 /**
+ * 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.
  *
  * @param string $model Name of model to inspect

+ 22 - 0
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');
+	}
+
 }