Commit c5926f49 authored by Dries's avatar Dries

- Patch #396578 by Damien Tournoud: added db_truncate_table() to the database layer.

parent d4193f51
......@@ -254,6 +254,13 @@ abstract class DatabaseConnection extends PDO {
*/
protected $deleteClass = NULL;
/**
* The name of the Truncate class for this connection.
*
* @var string
*/
protected $truncateClass = NULL;
/**
* The name of the Insert class for this connection.
*
......@@ -762,6 +769,26 @@ public function delete($table, array $options = array()) {
return new $class($this, $table, $options);
}
/**
* Prepare and return a TRUNCATE query object.
*
* @see TruncateQuery
* @param $options
* An array of options on the query.
* @return
* A new DeleteQuery object.
*/
public function truncate($table, array $options = array()) {
if (empty($this->truncateClass)) {
$this->truncateClass = 'TruncateQuery_' . $this->driver();
if (!class_exists($this->truncateClass)) {
$this->truncateClass = 'TruncateQuery';
}
}
$class = $this->truncateClass;
return new $class($this, $table, $options);
}
/**
* Returns a DatabaseSchema object for manipulating the schema of this database.
*
......@@ -1880,6 +1907,23 @@ function db_delete($table, array $options = array()) {
return Database::getConnection($options['target'])->delete($table, $options);
}
/**
* Returns a new TruncateQuery object for the active database.
*
* @param $table
* The table from which to delete.
* @param $options
* An array of options to control how the query operates.
* @return
* A new TruncateQuery object for this connection.
*/
function db_truncate($table, array $options = array()) {
if (empty($options['target']) || $options['target'] == 'slave') {
$options['target'] = 'default';
}
return Database::getConnection($options['target'])->truncate($table, $options);
}
/**
* Returns a new SelectQuery object for the active database.
*
......
......@@ -829,6 +829,38 @@ public function __toString() {
}
}
/**
* General class for an abstracted TRUNCATE operation.
*/
class TruncateQuery extends Query {
/**
* The table from which to delete.
*
* @var string
*/
protected $table;
public function __construct(DatabaseConnection $connection, $table, array $options = array()) {
$options['return'] = Database::RETURN_AFFECTED;
parent::__construct($connection, $options);
$this->table = $table;
}
public function compile(DatabaseConnection $connection) {
return $this->condition->compile($connection);
}
public function execute() {
return $this->connection->query((string)$this, array(), $this->queryOptions);
}
public function __toString() {
return 'TRUNCATE {' . $this->connection->escapeTable($this->table) . '} ';
}
}
/**
* General class for an abstracted UPDATE operation.
*/
......
......@@ -135,6 +135,18 @@ public function execute() {
}
}
/**
* SQLite specific implementation of TruncateQuery.
*
* SQLite doesn't support TRUNCATE, but a DELETE query with no condition has
* exactly the effect (it is implemented by DROPing the table).
*/
class TruncateQuery_sqlite extends TruncateQuery {
public function __toString() {
return 'DELETE FROM {' . $this->connection->escapeTable($this->table) . '} ';
}
}
/**
* @} End of "ingroup database".
*/
......@@ -847,19 +847,22 @@ class DatabaseUpdateLOBTestCase extends DatabaseTestCase {
}
/**
* Delete tests.
* Delete/Truncate tests.
*
* The DELETE tests are not as extensive, as all of the interesting code for
* DELETE queries is in the conditional which is identical to the UPDATE and
* SELECT conditional handling.
*
* The TRUNCATE tests are not extensive either, because the behavior of
* TRUNCATE queries is not consistent across database engines. We only test
* that a TRUNCATE query actually deletes all rows from the target table.
*/
class DatabaseDeleteTestCase extends DatabaseTestCase {
class DatabaseDeleteTruncateTestCase extends DatabaseTestCase {
public static function getInfo() {
return array(
'name' => t('Delete tests'),
'description' => t('Test the Delete query builder.'),
'name' => t('Delete/Truncate tests'),
'description' => t('Test the Delete and Truncate query builders.'),
'group' => t('Database'),
);
}
......@@ -876,6 +879,19 @@ class DatabaseDeleteTestCase extends DatabaseTestCase {
$num_records_after = db_query("SELECT COUNT(*) FROM {test}")->fetchField();
$this->assertEqual($num_records_before, $num_records_after + $num_deleted, t('Deletion adds up.'));
}
/**
* Confirm that we can truncate a whole table successfully.
*/
function testTruncate() {
$num_records_before = db_query("SELECT COUNT(*) FROM {test}")->fetchField();
db_truncate('test')->execute();
$num_records_after = db_query("SELECT COUNT(*) FROM {test}")->fetchField();
$this->assertEqual(0, $num_records_after, t('Truncate really deletes everything.'));
}
}
/**
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment