]> git.mjollnir.org Git - moodle.git/commitdiff
MDL-20734 empties and zeros - implemented the normalise_value() function in
authorEloy Lafuente <stronk7@moodle.org>
Tue, 3 Nov 2009 23:34:43 +0000 (23:34 +0000)
committerEloy Lafuente <stronk7@moodle.org>
Tue, 3 Nov 2009 23:34:43 +0000 (23:34 +0000)
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)

lib/dml/mysqli_native_moodle_database.php
lib/dml/pgsql_native_moodle_database.php

index 280ba2ae1d8fb65ed06ac152a691747310e4c305..05ff0548293e01f116d53437f883f37048cc657d 100644 (file)
@@ -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);
index efdfff3776a21bda6bc84c487b1eeecca000c4f1..d2be127c9878abd82675885a3a5600d9379030f8 100644 (file)
@@ -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";