diff --git a/php/libraries/Database.class.inc b/php/libraries/Database.class.inc index d86ca07de1a..90511fffc38 100644 --- a/php/libraries/Database.class.inc +++ b/php/libraries/Database.class.inc @@ -389,7 +389,7 @@ class Database $query = "INSERT INTO $table SET "; } $prepQ = $query; - $query .= $this->_implodeWithKeys(', ', $set); + $query .= $this->_implodeWithKeys(', ', $set, 'set_'); $exec_params = array(); $prepQ .= $this->_implodeAsPrepared(",", $set, $exec_params); @@ -454,7 +454,7 @@ class Database function replace($table, $set) { $query = "REPLACE INTO $table SET "; - $query .= $this->_implodeWithKeys(', ', $set); + $query .= $this->_implodeWithKeys(', ', $set, 'set_'); if (DEBUG) { fwrite(STDERR, $query."\n"); @@ -531,9 +531,9 @@ class Database * the top of the page when showDatabaseQueries is on. It isn't * actually executed. */ $query = "UPDATE $table SET "; - $query .= $this->_implodeWithKeys(', ', $set); + $query .= $this->_implodeWithKeys(', ', $set, 'set_'); $query .= " WHERE "; - $where = $this->_implodeWithKeys(' AND ', $i_where); + $where = $this->_implodeWithKeys(' AND ', $i_where, 'where_'); /* This generates the version of the update statement which is * executed. */ @@ -590,7 +590,7 @@ class Database function delete($table, $where) { $query = "DELETE FROM $table WHERE "; - $where = $this->_implodeWithKeys(' AND ', $where); + $where = $this->_implodeWithKeys(' AND ', $where, 'where_'); $query .= $where; if (DEBUG) { @@ -937,13 +937,13 @@ class Database * Sets each hash element into the format key='value', and then * implodes the resultant array with the specified glue * - * @param string $glue The glue to pass to php's implode - * function - * @param array $dataArray The array with keys to implode + * @param string $glue The glue to pass to php's implode function + * @param array $dataArray The array with keys to implode + * @param string $clause The type of clause set_|where_ * * @return string */ - function _implodeWithKeys($glue, $dataArray) + function _implodeWithKeys($glue, $dataArray, $clause = 'set_') { $output = array(); if (!is_array($dataArray) || count($dataArray)==0) { @@ -951,8 +951,9 @@ class Database } foreach ($dataArray as $key => $item ) { - if ($item===null || $item==='') { - $output[] = "`$key`=NULL"; + if (is_null($item)) { + $output[] = $clause == 'where_' + ? "`$key` IS NULL" : "`$key` = NULL"; } else { $item = $this->quote($item); $output[] = "`$key`=$item"; @@ -985,12 +986,16 @@ class Database $output = array(); foreach ($dataArray as $key => $item ) { - $varname = str_replace("%", "_percent_", $key); - $output[] = "`$key`=:$prefix$varname"; - if ($exec_vals !== null) { - $exec_vals["$prefix$varname"] = $item; + $varname = str_replace("%", "_percent_", $key); + if (is_null($item)) { + $output[] = $prefix == 'where_' + ? "`$key` IS NULL" : "`$key` = NULL"; + } else { + $output[] = "`$key`=:$prefix$varname"; + if ($exec_vals !== null) { + $exec_vals["$prefix$varname"] = $item; + } } - } return implode($glue, $output); } diff --git a/test/unittests/Database_Test.php b/test/unittests/Database_Test.php index 4c2826fb617..5e72f765a08 100644 --- a/test/unittests/Database_Test.php +++ b/test/unittests/Database_Test.php @@ -73,8 +73,7 @@ function testSetFakeData() { ) ) - ); - + ); } @@ -156,7 +155,157 @@ function testUnsafeInsertDoesntEscapeHTML() { $stub->unsafeinsert("test", array('field' => 'Hello'), array()); } -} + function testDeleteWithIsNull() { + $this->_factory = NDB_Factory::singleton(); + $DB = Database::singleton(); + $DB->setFakeTableData( + "ConfigSettings", + array( + 0 => array( + 'ID' => 99991, + 'Name' => 'test 1', + 'Description' => 'permanent', + 'Visible' => '1' + ), + 1 => array( + 'ID' => 99992, + 'Name' => 'test 2', + 'Description' => null, + 'Visible' => '1' + ) + ) + ); + + $DB->delete("ConfigSettings", array('Visible' => 1, 'Description' => null)); + $allSetting = $DB->pselect("SELECT ID, Name, Description, Visible FROM ConfigSettings", array()); + $DB->run("DROP TEMPORARY TABLE ConfigSettings"); + $this->assertEquals( + $allSetting, + array( + 0 => array( + 'ID' => '99991', + 'Name' => 'test 1', + 'Description' => 'permanent', + 'Visible' => '1' + ) + ) + ); + + } -?> + function testUpdateWithIsNull() { + $this->_factory = NDB_Factory::singleton(); + $DB = Database::singleton(); + $DB->setFakeTableData( + "ConfigSettings", + array( + 0 => array( + 'ID' => 99991, + 'Name' => 'test 1', + 'Description' => 'permanent', + 'Visible' => '1' + ), + 1 => array( + 'ID' => 99992, + 'Name' => 'test 2', + 'Description' => null, + 'Visible' => '1' + ) + ) + ); + $DB->update("ConfigSettings", array('Visible' => null, 'Description' => 'new description'), array('Description' => null)); + $allSetting = $DB->pselect("SELECT ID, Name, Description, Visible FROM ConfigSettings", array()); + $DB->run("DROP TEMPORARY TABLE ConfigSettings"); + $this->assertEquals( + $allSetting, + array( + 0 => array( + 'ID' => 99991, + 'Name' => 'test 1', + 'Description' => 'permanent', + 'Visible' => '1' + ), + 1 => array( + 'ID' => 99992, + 'Name' => 'test 2', + 'Description' => 'new description', + 'Visible' => null + ) + ) + ); + } + + function testInsertWithIsNull() { + $this->_factory = NDB_Factory::singleton(); + $DB = Database::singleton(); + $DB->setFakeTableData( + "ConfigSettings", + array( + 0 => array( + 'ID' => 99991, + 'Name' => 'test 1', + 'Description' => 'permanent', + 'Visible' => '1' + ) + ) + ); + $DB->insert("ConfigSettings", array('ID' => 99992, 'Name' => 'test 2', 'Visible' => 1, 'Description' => null)); + $allSetting = $DB->pselect("SELECT ID, Name, Description, Visible FROM ConfigSettings", array()); + $DB->run("DROP TEMPORARY TABLE ConfigSettings"); + $this->assertEquals( + $allSetting, + array( + 0 => array( + 'ID' => 99991, + 'Name' => 'test 1', + 'Description' => 'permanent', + 'Visible' => '1' + ), + 1 => array( + 'ID' => 99992, + 'Name' => 'test 2', + 'Description' => null, + 'Visible' => '1' + ) + ) + ); + } + + function testReplaceWithIsNull() { + $this->_factory = NDB_Factory::singleton(); + $DB = Database::singleton(); + $DB->setFakeTableData( + "ConfigSettings", + array( + 0 => array( + 'ID' => 99991, + 'Name' => 'test 1', + 'Description' => 'permanent', + 'Visible' => '1' + ) + ) + ); + $DB->replace("ConfigSettings", array('ID' => 99991, 'Name' => 'test 1', 'Visible' => 1, 'Description' => null)); + $DB->replace("ConfigSettings", array('ID' => 99992, 'Name' => 'test 2', 'Visible' => 1, 'Description' => null)); + $allSetting = $DB->pselect("SELECT ID, Name, Description, Visible FROM ConfigSettings", array()); + $DB->run("DROP TEMPORARY TABLE ConfigSettings"); + $this->assertEquals( + $allSetting, + array( + 0 => array( + 'ID' => 99991, + 'Name' => 'test 1', + 'Description' => null, + 'Visible' => '1' + ), + 1 => array( + 'ID' => 99992, + 'Name' => 'test 2', + 'Description' => null, + 'Visible' => '1' + ) + ) + ); + } +}