summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--includes/database/database.inc85
-rw-r--r--modules/search/search.extender.inc2
-rw-r--r--modules/simpletest/tests/database_test.test53
3 files changed, 136 insertions, 4 deletions
diff --git a/includes/database/database.inc b/includes/database/database.inc
index 916ca4cc6..98f3497ae 100644
--- a/includes/database/database.inc
+++ b/includes/database/database.inc
@@ -2005,6 +2005,91 @@ class DatabaseStatementBase extends PDOStatement implements DatabaseStatementInt
}
/**
+ * Empty implementation of a database statement.
+ *
+ * This class satisfies the requirements of being a database statement/result
+ * object, but does not actually contain data. It is useful when developers
+ * need to safely return an "empty" result set without connecting to an actual
+ * database. Calling code can then treat it the same as if it were an actual
+ * result set that happens to contain no records.
+ *
+ * @see SearchQuery
+ */
+class DatabaseStatementEmpty implements Iterator, DatabaseStatementInterface {
+
+ public function execute($args = array(), $options = array()) {
+ return FALSE;
+ }
+
+ public function getQueryString() {
+ return '';
+ }
+
+ public function rowCount() {
+ return 0;
+ }
+
+ public function setFetchMode($mode, $a1 = NULL, $a2 = array()) {
+ return;
+ }
+
+ public function fetch($mode = NULL, $cursor_orientation = NULL, $cursor_offset = NULL) {
+ return NULL;
+ }
+
+ public function fetchField($index = 0) {
+ return NULL;
+ }
+
+ public function fetchObject() {
+ return NULL;
+ }
+
+ public function fetchAssoc() {
+ return NULL;
+ }
+
+ function fetchAll($mode = NULL, $column_index = NULL, array $constructor_arguments = array()) {
+ return array();
+ }
+
+ public function fetchCol($index = 0) {
+ return array();
+ }
+
+ public function fetchAllKeyed($key_index = 0, $value_index = 1) {
+ return array();
+ }
+
+ public function fetchAllAssoc($key, $fetch = PDO::FETCH_OBJ) {
+ return array();
+ }
+
+ /* Implementations of Iterator. */
+
+ public function current() {
+ return NULL;
+ }
+
+ public function key() {
+ return NULL;
+ }
+
+ public function rewind() {
+ // Nothing to do: our DatabaseStatement can't be rewound.
+ }
+
+ public function next() {
+ // Do nothing, since this is an always-empty implementation.
+ }
+
+ public function valid() {
+ return FALSE;
+ }
+}
+
+
+/**
* The following utility functions are simply convenience wrappers.
* They should never, ever have any database-specific code in them.
*/
diff --git a/modules/search/search.extender.inc b/modules/search/search.extender.inc
index 2c56ee3c3..99a96057e 100644
--- a/modules/search/search.extender.inc
+++ b/modules/search/search.extender.inc
@@ -404,7 +404,7 @@ class SearchQuery extends SelectQueryExtender {
$this->executeFirstPass();
}
if (!$this->normalize) {
- return FALSE;
+ return new DatabaseStatementEmpty();
}
$this->join('search_dataset', 'd', 'i.sid = d.sid AND i.type = d.type');
diff --git a/modules/simpletest/tests/database_test.test b/modules/simpletest/tests/database_test.test
index 3862f16c0..4af00e69f 100644
--- a/modules/simpletest/tests/database_test.test
+++ b/modules/simpletest/tests/database_test.test
@@ -1889,19 +1889,19 @@ class DatabaseSelectComplexTestCase extends DatabaseTestCase {
$query->fields('test');
$query->orderBy('name');
$count = $query->countQuery();
-
+
// Check that the 'all_fields' statement is handled properly.
$tables = $query->getTables();
$this->assertEqual($tables['test']['all_fields'], 1, t('Query correctly sets \'all_fields\' statement.'));
$tables = $count->getTables();
- $this->assertFalse(isset($tables['test']['all_fields']), t('Count query correctly unsets \'all_fields\' statement.'));
+ $this->assertFalse(isset($tables['test']['all_fields']), t('Count query correctly unsets \'all_fields\' statement.'));
// Check that the ordering clause is handled properly.
$orderby = $query->getOrderBy();
$this->assertEqual($orderby['name'], 'ASC', t('Query correctly sets ordering clause.'));
$orderby = $count->getOrderBy();
$this->assertFalse(isset($orderby['name']), t('Count query correctly unsets ordering caluse.'));
-
+
// Make sure that the count query works.
$count = $count->execute()->fetchField();
@@ -3155,3 +3155,50 @@ class DatabaseNextIdCase extends DrupalWebTestCase {
$this->assertEqual($result, 1001, t('Sequence provides a larger number than the existing ID.'));
}
}
+
+/**
+ * Tests the empty pseudo-statement class.
+ */
+class DatabaseEmptyStatementTestCase extends DrupalWebTestCase {
+ function getInfo() {
+ return array(
+ 'name' => t('Empty statement'),
+ 'description' => t('Test the empty pseudo-statement class.'),
+ 'group' => t('Database'),
+ );
+ }
+
+ /**
+ * Test that the empty result set behaves as empty.
+ */
+ function testEmpty() {
+ $result = new DatabaseStatementEmpty();
+
+ $this->assertTrue($result instanceof DatabaseStatementInterface, t('Class implements expected interface'));
+ $this->assertNull($result->fetchObject(), t('Null result returned.'));
+ }
+
+ /**
+ * Test that the empty result set iterates safely.
+ */
+ function testEmptyIteration() {
+ $result = new DatabaseStatementEmpty();
+
+ foreach ($result as $record) {
+ $this->fail(t('Iterating empty result set should not iterate.'));
+ return;
+ }
+
+ $this->pass(t('Iterating empty result set skipped iteration.'));
+ }
+
+ /**
+ * Test that the empty result set mass-fetches in an expected way.
+ */
+ function testEmptyFetchAll() {
+ $result = new DatabaseStatementEmpty();
+
+ $this->assertEqual($result->fetchAll(), array(), t('Empty array returned from empty result set.'));
+ }
+
+}