summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDries Buytaert <dries@buytaert.net>2009-05-03 08:56:19 +0000
committerDries Buytaert <dries@buytaert.net>2009-05-03 08:56:19 +0000
commitc5926f4961506ad886e6110bc506bf72e4588bc8 (patch)
tree6efe325fc02f12a6b8e2e12612fe721ac9bbeac5
parentd4193f5178141a3474a08a8f2e77107a5fd5e0a0 (diff)
downloadbrdo-c5926f4961506ad886e6110bc506bf72e4588bc8.tar.gz
brdo-c5926f4961506ad886e6110bc506bf72e4588bc8.tar.bz2
- Patch #396578 by Damien Tournoud: added db_truncate_table() to the database layer.
-rw-r--r--includes/database/database.inc44
-rw-r--r--includes/database/query.inc32
-rw-r--r--includes/database/sqlite/query.inc12
-rw-r--r--modules/simpletest/tests/database_test.test24
4 files changed, 108 insertions, 4 deletions
diff --git a/includes/database/database.inc b/includes/database/database.inc
index f07e07373..60d4b415f 100644
--- a/includes/database/database.inc
+++ b/includes/database/database.inc
@@ -255,6 +255,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.
*
* @var string
@@ -763,6 +770,26 @@ abstract class DatabaseConnection extends PDO {
}
/**
+ * 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.
*
* This method will lazy-load the appropriate schema library file.
@@ -1881,6 +1908,23 @@ function db_delete($table, array $options = array()) {
}
/**
+ * 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.
*
* @param $table
diff --git a/includes/database/query.inc b/includes/database/query.inc
index 8c7281820..8cdaaf5e1 100644
--- a/includes/database/query.inc
+++ b/includes/database/query.inc
@@ -829,6 +829,38 @@ class DeleteQuery extends Query implements QueryConditionInterface {
}
}
+
+/**
+ * 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.
*/
diff --git a/includes/database/sqlite/query.inc b/includes/database/sqlite/query.inc
index ab6e2da50..98fa80754 100644
--- a/includes/database/sqlite/query.inc
+++ b/includes/database/sqlite/query.inc
@@ -136,5 +136,17 @@ class DeleteQuery_sqlite extends DeleteQuery {
}
/**
+ * 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".
*/
diff --git a/modules/simpletest/tests/database_test.test b/modules/simpletest/tests/database_test.test
index a59e321aa..da3add21a 100644
--- a/modules/simpletest/tests/database_test.test
+++ b/modules/simpletest/tests/database_test.test
@@ -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.'));
+ }
}
/**