mirror of
https://github.com/moodle/moodle.git
synced 2025-04-15 21:45:37 +02:00
MDL-20734 empties and zeros - implemented the normalise_value() function in
mysql and postgres to perform central normalisation of values for insert/ update/set_field. Now all DB drivers cast empty strings to 0 when working with numeric columns (integer and decimal)
This commit is contained in:
parent
8843e0bb3c
commit
8fb501e96c
@ -455,6 +455,35 @@ class mysqli_native_moodle_database extends moodle_database {
|
||||
return $this->columns[$table];
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalise values based in RDBMS dependencies (booleans, LOBs...)
|
||||
*
|
||||
* @param database_column_info $column column metadata corresponding with the value we are going to normalise
|
||||
* @param mixed $value value we are going to normalise
|
||||
* @return mixed the normalised value
|
||||
*/
|
||||
private function normalise_value($column, $value) {
|
||||
if (is_bool($value)) { // Always, convert boolean to int
|
||||
$value = (int)$value;
|
||||
|
||||
} else if ($value === '') {
|
||||
if ($column->meta_type == 'I' or $column->meta_type == 'F' or $column->meta_type == 'N') {
|
||||
$value = 0; // prevent '' problems in numeric fields
|
||||
}
|
||||
}
|
||||
// workaround for problem with wrong enums in mysql - TODO: Out in Moodle 2.1
|
||||
if (!empty($column->enums)) {
|
||||
if (is_null($value) and !$column->not_null) {
|
||||
// ok - nulls allowed
|
||||
} else {
|
||||
if (!in_array((string)$value, $column->enums)) {
|
||||
throw new dml_write_exception('Enum value '.s($value).' not allowed in field '.$field.' table '.$table.'.');
|
||||
}
|
||||
}
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is db in unicode mode?
|
||||
* @return bool
|
||||
@ -746,20 +775,7 @@ class mysqli_native_moodle_database extends moodle_database {
|
||||
continue;
|
||||
}
|
||||
$column = $columns[$field];
|
||||
if (is_bool($value)) {
|
||||
$value = (int)$value; // prevent "false" problems
|
||||
}
|
||||
if (!empty($column->enums)) {
|
||||
// workaround for problem with wrong enums in mysql
|
||||
if (is_null($value) and !$column->not_null) {
|
||||
// ok - nulls allowed
|
||||
} else {
|
||||
if (!in_array((string)$value, $column->enums)) {
|
||||
throw new dml_write_exception('Enum value '.s($value).' not allowed in field '.$field.' table '.$table.'.');
|
||||
}
|
||||
}
|
||||
}
|
||||
$cleaned[$field] = $value;
|
||||
$cleaned[$field] = $this->normalise_value($column, $value);
|
||||
}
|
||||
|
||||
return $this->insert_record_raw($table, $cleaned, $returnid, $bulk);
|
||||
@ -857,10 +873,8 @@ class mysqli_native_moodle_database extends moodle_database {
|
||||
if (!isset($columns[$field])) {
|
||||
continue;
|
||||
}
|
||||
if (is_bool($value)) {
|
||||
$value = (int)$value; // prevent "false" problems
|
||||
}
|
||||
$cleaned[$field] = $value;
|
||||
$column = $columns[$field];
|
||||
$cleaned[$field] = $this->normalise_value($column, $value);
|
||||
}
|
||||
|
||||
return $this->update_record_raw($table, $cleaned, $bulk);
|
||||
@ -886,14 +900,17 @@ class mysqli_native_moodle_database extends moodle_database {
|
||||
}
|
||||
list($select, $params, $type) = $this->fix_sql_params($select, $params);
|
||||
|
||||
if (is_bool($newvalue)) {
|
||||
$newvalue = (int)$newvalue; // prevent "false" problems
|
||||
}
|
||||
if (is_null($newvalue)) {
|
||||
// Get column metadata
|
||||
$columns = $this->get_columns($table);
|
||||
$column = $columns[$newfield];
|
||||
|
||||
$normalised_value = $this->normalise_value($column, $newvalue);
|
||||
|
||||
if (is_null($normalised_value)) {
|
||||
$newfield = "$newfield = NULL";
|
||||
} else {
|
||||
$newfield = "$newfield = ?";
|
||||
array_unshift($params, $newvalue);
|
||||
array_unshift($params, $normalised_value);
|
||||
}
|
||||
$sql = "UPDATE {$this->prefix}$table SET $newfield $select";
|
||||
$rawsql = $this->emulate_bound_params($sql, $params);
|
||||
|
@ -501,6 +501,30 @@ class pgsql_native_moodle_database extends moodle_database {
|
||||
return $this->columns[$table];
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalise values based in RDBMS dependencies (booleans, LOBs...)
|
||||
*
|
||||
* @param database_column_info $column column metadata corresponding with the value we are going to normalise
|
||||
* @param mixed $value value we are going to normalise
|
||||
* @return mixed the normalised value
|
||||
*/
|
||||
private function normalise_value($column, $value) {
|
||||
if (is_bool($value)) { // Always, convert boolean to int
|
||||
$value = (int)$value;
|
||||
|
||||
} else if ($column->meta_type == 'B') { // BLOB detected, we return 'blob' array instead of raw value to allow
|
||||
if (!is_null($value)) { // binding/executing code later to know about its nature
|
||||
$value = array('blob' => $value);
|
||||
}
|
||||
|
||||
} else if ($value === '') {
|
||||
if ($column->meta_type == 'I' or $column->meta_type == 'F' or $column->meta_type == 'N') {
|
||||
$value = 0; // prevent '' problems in numeric fields
|
||||
}
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is db in unicode mode?
|
||||
* @return bool
|
||||
@ -777,25 +801,13 @@ class pgsql_native_moodle_database extends moodle_database {
|
||||
continue;
|
||||
}
|
||||
$column = $columns[$field];
|
||||
if ($column->meta_type == 'B') {
|
||||
if (is_null($value)) {
|
||||
$cleaned[$field] = null;
|
||||
} else {
|
||||
$blobs[$field] = $value;
|
||||
$cleaned[$field] = '@#BLOB#@';
|
||||
}
|
||||
continue;
|
||||
|
||||
} else if (is_bool($value)) {
|
||||
$value = (int)$value; // prevent false '' problems
|
||||
|
||||
} else if ($value === '') {
|
||||
if ($column->meta_type == 'I' or $column->meta_type == 'F' or $column->meta_type == 'N') {
|
||||
$value = 0; // prevent '' problems in numeric fields
|
||||
}
|
||||
$normalised_value = $this->normalise_value($column, $value);
|
||||
if (is_array($normalised_value) && array_key_exists('blob', $normalised_value)) {
|
||||
$cleaned[$field] = '@#BLOB#@';
|
||||
$blobs[$field] = $normalised_value['blob'];
|
||||
} else {
|
||||
$cleaned[$field] = $normalised_value;
|
||||
}
|
||||
|
||||
$cleaned[$field] = $value;
|
||||
}
|
||||
|
||||
if (empty($blobs)) {
|
||||
@ -913,25 +925,13 @@ class pgsql_native_moodle_database extends moodle_database {
|
||||
continue;
|
||||
}
|
||||
$column = $columns[$field];
|
||||
if ($column->meta_type == 'B') {
|
||||
if (is_null($value)) {
|
||||
$cleaned[$field] = null;
|
||||
} else {
|
||||
$blobs[$field] = $value;
|
||||
$cleaned[$field] = '@#BLOB#@';
|
||||
}
|
||||
continue;
|
||||
|
||||
} else if (is_bool($value)) {
|
||||
$value = (int)$value; // prevent false '' problems
|
||||
|
||||
} else if ($value === '') {
|
||||
if ($column->meta_type == 'I' or $column->meta_type == 'F' or $column->meta_type == 'N') {
|
||||
$value = 0; // prevent '' problems in numeric fields
|
||||
}
|
||||
$normalised_value = $this->normalise_value($column, $value);
|
||||
if (is_array($normalised_value) && array_key_exists('blob', $normalised_value)) {
|
||||
$cleaned[$field] = '@#BLOB#@';
|
||||
$blobs[$field] = $normalised_value['blob'];
|
||||
} else {
|
||||
$cleaned[$field] = $normalised_value;
|
||||
}
|
||||
|
||||
$cleaned[$field] = $value;
|
||||
}
|
||||
|
||||
$this->update_record_raw($table, $cleaned, $bulk);
|
||||
@ -981,10 +981,11 @@ class pgsql_native_moodle_database extends moodle_database {
|
||||
$columns = $this->get_columns($table);
|
||||
$column = $columns[$newfield];
|
||||
|
||||
if ($column->meta_type == 'B' && $newvalue !== null) { /// If the column is a BLOB and the value is not null
|
||||
$normalised_value = $this->normalise_value($column, $newvalue);
|
||||
if (is_array($normalised_value) && array_key_exists('blob', $normalised_value)) {
|
||||
/// Update BYTEA and return
|
||||
$newvalue = pg_escape_bytea($this->pgsql, $newvalue);
|
||||
$sql = "UPDATE {$this->prefix}$table SET $newfield = '$newvalue'::bytea $select";
|
||||
$normalised_value = pg_escape_bytea($this->pgsql, $normalised_value['blob']);
|
||||
$sql = "UPDATE {$this->prefix}$table SET $newfield = '$normalised_value'::bytea $select";
|
||||
$this->query_start($sql, NULL, SQL_QUERY_UPDATE);
|
||||
$result = pg_query_params($this->pgsql, $sql, $params);
|
||||
$this->query_end($result);
|
||||
@ -992,14 +993,11 @@ class pgsql_native_moodle_database extends moodle_database {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (is_bool($newvalue)) {
|
||||
$newvalue = (int)$newvalue; // prevent "false" problems
|
||||
}
|
||||
if (is_null($newvalue)) {
|
||||
if (is_null($normalised_value)) {
|
||||
$newfield = "$newfield = NULL";
|
||||
} else {
|
||||
$newfield = "$newfield = \$".$i;
|
||||
$params[] = $newvalue;
|
||||
$params[] = $normalised_value;
|
||||
}
|
||||
$sql = "UPDATE {$this->prefix}$table SET $newfield $select";
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user