Prevent NULL value on NOT NULL column when value is an empty string (MySQL)

This commit is contained in:
Istvan Pusztai 2015-01-05 12:04:24 -05:00
parent b76fbd8da1
commit 22b0275a58
4 changed files with 43 additions and 10 deletions

View file

@ -584,11 +584,12 @@ class Sqlserver extends DboSource {
*
* @param string $data String to be prepared for use in an SQL statement
* @param string $column The column into which this data will be inserted
* @param bool $null Column allows NULL values
* @return string Quoted and escaped data
*/
public function value($data, $column = null) {
public function value($data, $column = null, $null = true) {
if ($data === null || is_array($data) || is_object($data)) {
return parent::value($data, $column);
return parent::value($data, $column, $null);
}
if (in_array($data, array('{$__cakeID__$}', '{$__cakeForeignKey__$}'), true)) {
return $data;
@ -603,7 +604,7 @@ class Sqlserver extends DboSource {
case 'text':
return 'N' . $this->_connection->quote($data, PDO::PARAM_STR);
default:
return parent::value($data, $column);
return parent::value($data, $column, $null);
}
}

View file

@ -312,9 +312,10 @@ class DboSource extends DataSource {
*
* @param string $data String to be prepared for use in an SQL statement
* @param string $column The column datatype into which this data will be inserted.
* @param bool $null Column allows NULL values
* @return string Quoted and escaped data
*/
public function value($data, $column = null) {
public function value($data, $column = null, $null = true) {
if (is_array($data) && !empty($data)) {
return array_map(
array(&$this, 'value'),
@ -348,7 +349,7 @@ class DboSource extends DataSource {
return $this->_connection->quote($data, PDO::PARAM_STR);
default:
if ($data === '') {
return 'NULL';
return $null ? 'NULL' : '""';
}
if (is_float($data)) {
return str_replace(',', '.', strval($data));
@ -994,7 +995,8 @@ class DboSource extends DataSource {
$count = count($fields);
for ($i = 0; $i < $count; $i++) {
$valueInsert[] = $this->value($values[$i], $Model->getColumnType($fields[$i]));
$schema = $Model->schema();
$valueInsert[] = $this->value($values[$i], $Model->getColumnType($fields[$i]), isset($schema[$fields[$i]]) ? $schema[$fields[$i]]['null'] : true);
$fieldInsert[] = $this->name($fields[$i]);
if ($fields[$i] === $Model->primaryKey) {
$id = $values[$i];
@ -2061,6 +2063,7 @@ class DboSource extends DataSource {
*/
protected function _prepareUpdateFields(Model $Model, $fields, $quoteValues = true, $alias = false) {
$quotedAlias = $this->startQuote . $Model->alias . $this->endQuote;
$schema = $Model->schema();
$updates = array();
foreach ($fields as $field => $value) {
@ -2081,7 +2084,7 @@ class DboSource extends DataSource {
$update = $quoted . ' = ';
if ($quoteValues) {
$update .= $this->value($value, $Model->getColumnType($field));
$update .= $this->value($value, $Model->getColumnType($field), isset($schema[$field]) ? $schema[$field]['null'] : true);
} elseif ($Model->getColumnType($field) === 'boolean' && (is_int($value) || is_bool($value))) {
$update .= $this->boolean($value, true);
} elseif (!$alias) {
@ -3563,4 +3566,4 @@ class DboSource extends DataSource {
}
}
}
}

View file

@ -318,8 +318,8 @@ class PostgresTest extends CakeTestCase {
$this->assertEquals("0", $this->Dbo->value('0', 'integer'));
$this->assertEquals('NULL', $this->Dbo->value('', 'integer'));
$this->assertEquals('NULL', $this->Dbo->value('', 'float'));
$this->assertEquals("NULL", $this->Dbo->value('', 'integer', false));
$this->assertEquals("NULL", $this->Dbo->value('', 'float', false));
$this->assertEquals('""', $this->Dbo->value('', 'integer', false));
$this->assertEquals('""', $this->Dbo->value('', 'float', false));
$this->assertEquals("'0.0'", $this->Dbo->value('0.0', 'float'));
$this->assertEquals("'TRUE'", $this->Dbo->value('t', 'boolean'));

View file

@ -784,6 +784,35 @@ class DboSourceTest extends CakeTestCase {
$this->assertTrue($result, 'Query did not return a boolean');
}
/**
* Test NOT NULL on ENUM data type with empty string as a value
*
* @return void
*/
public function testNotNullOnEnum() {
if (!$this->db instanceof Mysql) {
$this->markTestSkipped('This test can only run on MySQL');
}
$name = $this->db->fullTableName('enum_tests');
$query = "CREATE TABLE {$name} (mood ENUM('','happy','sad','ok') NOT NULL);";
$result = $this->db->query($query);
$this->assertTrue($result);
$EnumTest = ClassRegistry::init('EnumTest');
$enumResult = $EnumTest->save(array('mood' => ''));
$query = "DROP TABLE {$name};";
$result = $this->db->query($query);
$this->assertTrue($result);
$this->assertEquals(array(
'EnumTest' => array(
'mood' => '',
'id' => '0'
)
), $enumResult);
}
/**
* test order to generate query order clause for virtual fields
*