Commit 193ba01e authored by webchick's avatar webchick

#343999 by Crell, chx, and Alexander Pas: Add facility for doing NULL / NOT...

#343999 by Crell, chx, and Alexander Pas: Add facility for doing NULL / NOT NULL conditions to DBTNG.
parent 38969b48
......@@ -47,6 +47,26 @@ public function condition($field, $value = NULL, $operator = NULL);
*/
public function where($snippet, $args = array());
/**
* Set a condition that the specified field be NULL.
*
* @param $field
* The name of the field to check.
* @return
* The called object.
*/
public function isNull($field);
/**
* Set a condition that the specified field be NOT NULL.
*
* @param $field
* The name of the field to check.
* @return
* The called object.
*/
public function isNotNull($field);
/**
* Gets a complete list of all conditions in this conditional clause.
*
......@@ -749,6 +769,16 @@ public function condition($field, $value = NULL, $operator = '=') {
return $this;
}
public function isNull($field) {
$this->condition->isNull($field);
return $this;
}
public function isNotNull($field) {
$this->condition->isNotNull($field);
return $this;
}
public function &conditions() {
return $this->condition->conditions();
}
......@@ -852,6 +882,16 @@ public function condition($field, $value = NULL, $operator = '=') {
return $this;
}
public function isNull($field) {
$this->condition->isNull($field);
return $this;
}
public function isNotNull($field) {
$this->condition->isNotNull($field);
return $this;
}
public function &conditions() {
return $this->condition->conditions();
}
......@@ -1012,6 +1052,14 @@ public function where($snippet, $args = array()) {
return $this;
}
public function isNull($field) {
return $this->condition($field, NULL, 'IS NULL');
}
public function isNotNull($field) {
return $this->condition($field, NULL, 'IS NOT NULL');
}
public function &conditions() {
return $this->conditions;
}
......@@ -1061,6 +1109,7 @@ public function compile(DatabaseConnection $connection) {
'postfix' => '',
'delimiter' => '',
'operator' => $condition['operator'],
'use_value' => TRUE,
);
$operator = $connection->mapConditionOperator($condition['operator']);
if (!isset($operator)) {
......@@ -1079,10 +1128,12 @@ public function compile(DatabaseConnection $connection) {
$condition['value'] = array($condition['value']);
}
$placeholders = array();
foreach ($condition['value'] as $value) {
$placeholder = ':db_condition_placeholder_' . $next_placeholder++;
$arguments[$placeholder] = $value;
$placeholders[] = $placeholder;
if ($operator['use_value']) {
foreach ($condition['value'] as $value) {
$placeholder = ':db_condition_placeholder_' . $next_placeholder++;
$arguments[$placeholder] = $value;
$placeholders[] = $placeholder;
}
}
$condition_fragments[] = ' (' . $condition['field'] . ' ' . $operator['operator'] . ' ' . $operator['prefix'] . implode($operator['delimiter'], $placeholders) . $operator['postfix'] . ') ';
......@@ -1122,6 +1173,8 @@ protected function mapConditionOperator($operator) {
'IN' => array('delimiter' => ', ', 'prefix' => ' (', 'postfix' => ')'),
'NOT IN' => array('delimiter' => ', ', 'prefix' => ' (', 'postfix' => ')'),
'LIKE' => array('operator' => 'LIKE'),
'IS NULL' => array('use_value' => FALSE),
'IS NOT NULL' => array('use_value' => FALSE),
);
$return = isset($specials[$operator]) ? $specials[$operator] : array();
......
......@@ -579,6 +579,16 @@ public function countQuery() {
return $count;
}
function isNull($field) {
$this->query->isNull($field);
return $this;
}
function isNotNull($field) {
$this->query->isNotNull($field);
return $this;
}
public function __toString() {
return (string)$this->query;
}
......@@ -760,6 +770,17 @@ public function where($snippet, $args = array()) {
return $this;
}
public function isNull($field) {
$this->where->isNull($field);
return $this;
}
public function isNotNull($field) {
$this->where->isNotNull($field);
return $this;
}
public function compile(DatabaseConnection $connection) {
return $this->where->compile($connection);
}
......@@ -801,6 +822,17 @@ public function extend($extender_name) {
return new $extender_name($this, $this->connection);
}
public function havingIsNull($field) {
$this->having->isNull($field);
return $this;
}
public function havingIsNotNull($field) {
$this->having->isNotNull($field);
return $this;
}
/* Alter accessors to expose the query data to alter hooks. */
public function &getFields() {
......
......@@ -166,6 +166,37 @@ function database_test_schema() {
'primary key' => array('id'),
);
$schema['test_null'] = array(
'description' => 'Basic test table for NULL value handling.',
'fields' => array(
'id' => array(
'type' => 'serial',
'unsigned' => TRUE,
'not null' => TRUE,
),
'name' => array(
'description' => "A person's name.",
'type' => 'varchar',
'length' => 255,
'not null' => FALSE,
'default' => '',
),
'age' => array(
'description' => "The person's age.",
'type' => 'int',
'unsigned' => TRUE,
'not null' => FALSE,
'default' => 0),
),
'primary key' => array('id'),
'unique keys' => array(
'name' => array('name')
),
'indexes' => array(
'ages' => array('age'),
),
);
return $schema;
}
......
......@@ -27,6 +27,18 @@ class DatabaseTestCase extends DrupalWebTestCase {
$schema['test_two_blobs'] = drupal_get_schema('test_two_blobs');
$schema['test_task'] = drupal_get_schema('test_task');
$this->installTables($schema);
$this->addSampleData();
}
/**
* Set up several tables needed by a certain test.
*
* @param $schema
* An array of table definitions to install.
*/
function installTables($schema) {
// This ends up being a test for table drop and create, too, which is nice.
$ret = array();
foreach ($schema as $name => $data) {
......@@ -39,8 +51,30 @@ class DatabaseTestCase extends DrupalWebTestCase {
foreach ($schema as $name => $data) {
$this->assertTrue(db_table_exists($name), t('Table @name created successfully.', array('@name' => $name)));
}
}
$this->addSampleData();
/**
* Set up tables for NULL handling.
*/
function ensureSampleDataNull() {
$schema['test_null'] = drupal_get_schema('test_null');
$this->installTables($schema);
db_insert('test_null')
->fields(array('name', 'age'))
->values(array(
'name' => 'Kermit',
'age' => 25,
))
->values(array(
'name' => 'Fozzie',
'age' => NULL,
))
->values(array(
'name' => 'Gonzo',
'age' => 27,
))
->execute();
}
/**
......@@ -641,6 +675,7 @@ class DatabaseUpdateTestCase extends DatabaseTestCase {
$num_matches = db_query("SELECT COUNT(*) FROM {test} WHERE job = :job", array(':job' => 'Musician'))->fetchField();
$this->assertIdentical($num_matches, '1', t('Updated fields successfully.'));
}
}
/**
......@@ -1033,7 +1068,6 @@ class DatabaseMergeTestCase extends DatabaseTestCase {
/**
* Test the SELECT builder.
*
*/
class DatabaseSelectTestCase extends DatabaseTestCase {
......@@ -1169,6 +1203,38 @@ class DatabaseSelectTestCase extends DatabaseTestCase {
$this->assertEqual($record->age, 27, t('Age field has the correct value.'));
$this->assertEqual($record->job, 'Singer', t('Job field has the correct value.'));
}
/**
* Test that we can find a record with a NULL value.
*/
function testNullCondition() {
$this->ensureSampleDataNull();
$names = db_select('test_null', 'tn')
->fields('tn', array('name'))
->isNull('age')
->execute()->fetchCol();
$this->assertEqual(count($names), 1, t('Correct number of records found with NULL age.'));
$this->assertEqual($names[0], 'Fozzie', t('Correct record returned for NULL age.'));
}
/**
* Test that we can find a record without a NULL value.
*/
function testNotNullCondition() {
$this->ensureSampleDataNull();
$names = db_select('test_null', 'tn')
->fields('tn', array('name'))
->isNotNull('tn.age')
->orderBy('name')
->execute()->fetchCol();
$this->assertEqual(count($names), 2, t('Correct number of records found withNOT NULL age.'));
$this->assertEqual($names[0], 'Gonzo', t('Correct record returned for NOT NULL age.'));
$this->assertEqual($names[1], 'Kermit', t('Correct record returned for NOT NULL age.'));
}
}
/**
......
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