diff options
author | Dries Buytaert <dries@buytaert.net> | 2009-05-03 08:56:19 +0000 |
---|---|---|
committer | Dries Buytaert <dries@buytaert.net> | 2009-05-03 08:56:19 +0000 |
commit | c5926f4961506ad886e6110bc506bf72e4588bc8 (patch) | |
tree | 6efe325fc02f12a6b8e2e12612fe721ac9bbeac5 | |
parent | d4193f5178141a3474a08a8f2e77107a5fd5e0a0 (diff) | |
download | brdo-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.inc | 44 | ||||
-rw-r--r-- | includes/database/query.inc | 32 | ||||
-rw-r--r-- | includes/database/sqlite/query.inc | 12 | ||||
-rw-r--r-- | modules/simpletest/tests/database_test.test | 24 |
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.')); + } } /** |