]> git.mjollnir.org Git - moodle.git/commitdiff
MDL-16669 dml: improved sql_substring(), added unit tests
authorskodak <skodak>
Tue, 28 Oct 2008 15:11:10 +0000 (15:11 +0000)
committerskodak <skodak>
Tue, 28 Oct 2008 15:11:10 +0000 (15:11 +0000)
13 files changed:
lang/en_utf8/debug.php
lib/accesslib.php
lib/dml/adodb_moodle_database.php
lib/dml/moodle_database.php
lib/dml/mssql_adodb_moodle_database.php
lib/dml/mysqli_native_moodle_database.php
lib/dml/pdo_moodle_database.php
lib/dml/pgsql_native_moodle_database.php
lib/dml/simpletest/testdml.php
lib/dml/sqlite3_pdo_moodle_database.php
lib/file/file_storage.php
lib/setuplib.php
mod/glossary/sql.php

index c28513a0442ecb5a2e35c5105008aaed59978ae3..01564e6c9bd3eabf283f67a7c81b5d4afa6dee85 100644 (file)
@@ -15,6 +15,7 @@ $string['cannotsetupsite'] = 'Serious Error! Could not set up the site!';
 $string['cannotsetuptable'] = '$a tables could NOT be set up successfully!';
 $string['cannotfindadmin'] = 'Could not find an admin user!';
 $string['cannotupgradedbcustom'] = 'Upgrade of local database customisations failed! (Could not update version in config table)';
+$string['codingerror'] = 'Coding error detected, it must be fixed by a programmer: $a';
 $string['configmoodle'] = 'Moodle has not been configured yet. You need to edit config.php first.';
 $string['dbnotinsert'] = 'Database error - Cannot insert ($a)';
 $string['dbnotupdate'] = 'Database error - Cannot update ($a)';
index 5498074c5d36ec5cb031a25ab54de5b7c2f45def..021dc55271fbcd3f57aba17e41fc89141ae7592f 100755 (executable)
@@ -5402,14 +5402,8 @@ function context_moved($context, $newparent) {
     $params = array($newpath, $frompath);
     $DB->execute($sql, $params);
 
-    $len = strlen($frompath);
-    /// MDL-16655 - Substring MSSQL function *requires* 3rd parameter
-    $substr3rdparam = '';
-    if ($DB->get_dbfamily() == 'mssql') {
-        $substr3rdparam = ', len(path)';
-    }
     $sql = "UPDATE {context}
-               SET path = ".$DB->sql_concat("?", $DB->sql_substr() .'(path, '.$len.' +1'.$substr3rdparam.')')."
+               SET path = ".$DB->sql_concat("?", $DB->sql_substr("path", strlen($frompath)+1))."
                    $setdepth
              WHERE path LIKE ?";
     $params = array($newpath, "{$frompath}/%");
index e8898aa687b6967bd0fc6cb9d7bce789a03291fe..afc3342d9139cc89fadb0801cc5b360d83d1adf0 100644 (file)
@@ -487,10 +487,6 @@ abstract class adodb_moodle_database extends moodle_database {
         }
     }
 
-    public function sql_substr() {
-        return $this->adodb->substr;
-    }
-
     public function sql_concat() {
         $args = func_get_args();
         return call_user_func_array(array($this->adodb, 'Concat'), $args);
index 36d8547b36247a18d0af3762a83cf05cf1a61190..46bfb3735cf82796587035c03895f2c3a72ebeea 100644 (file)
@@ -1398,10 +1398,23 @@ abstract class moodle_database {
 
     /**
      * Returns the proper substr() function for each DB.
+     * NOTE: this was originally returning only function name
      *
-     * Relies on ADOdb $adodb->substr property
+     * @param string $expr some string field, no aggregates
+     * @param mixed $start integer or expresion evaluating to int (1 based value; first char has index 1)
+     * @param mixed $length optional integer or expresion evaluating to int
+     * @return string sql fragment
      */
-    public abstract function sql_substr();
+    public function sql_substr($expr, $start, $length=false) {
+        if (count(func_get_args()) < 2) {
+            throw new coding_exception('moodle_database::sql_substr() requires at least two parameters', 'Originaly this function was only returning name of SQL substring function, it now requires all parameters.');
+        }
+        if ($length === false) {
+            return "SUBSTR($expr, $start";
+        } else {
+            return "SUBSTR($expr, $start, $length)";
+        }
+    }
 
     /**
      * Returns the SQL for returning searching one string for the location of another.
index bfb6886a8a9b128b962cc71bb96511e5c0ea6b52..ed4898a8ec8e9f7f9916130a21fef19a2bf4044f 100644 (file)
@@ -142,6 +142,23 @@ class mssql_adodb_moodle_database extends adodb_moodle_database {
         }
     }
 
+    /**
+     * Returns the proper substr() function for each DB.
+     * NOTE: this was originally returning only function name
+     *
+     * @param string $expr some string field, no aggregates
+     * @param mixed $start integer or expresion evaluating to int
+     * @param mixed $length optional integer or expresion evaluating to int
+     * @return string sql fragment
+     */
+    public function sql_substr($expr, $start, $length=false) {
+        if ($length === false) {
+            return "SUBSTRING($expr, $start, (LEN($expr) - $start + 1))";
+        } else {
+            return "SUBSTRING($expr, $start, $length)";
+        }
+    }
+
     /**
      * Update a record in a table
      *
index 7c3696ba73974a92b923b076382d5d493b997325..9ad9033186b166552ff2ac9ce6a3c57d845b80e8 100644 (file)
@@ -868,11 +868,6 @@ class mysqli_native_moodle_database extends moodle_database {
         return "CONCAT ($s)";
     }
 
-    public function sql_substr() {
-        return "SUBSTRING";
-    }
-
-
     /**
      * Does this driver suppoer regex syntax when searching
      */
index ace30423ef14d5863228167707a61a0c4888bf49..31c11c248f4d3f9eeaff4ff1220ed00f18bcc532 100644 (file)
@@ -541,10 +541,6 @@ abstract class pdo_moodle_database extends moodle_database {
         return $this->execute($sql, $params);
     }
 
-    public function sql_substr() {
-        error('TODO');
-    }
-
     public function sql_concat() {
         error('TODO');
     }
index d0960940a84ba5093f086872f082a539911eb1d3..d18fa8fce7f6e37de04e42a2c3114ccc73341a60 100644 (file)
@@ -1036,10 +1036,6 @@ class pgsql_native_moodle_database extends moodle_database {
         return " $s ";
     }
 
-    public function sql_substr() {
-        return "SUBSTRING";
-    }
-
     public function sql_regex_supported() {
         return true;
     }
index 935a1f223513631a12eca4da8135b8acd48498ad..b92d392f908731405df3999ad1d085259475c09a 100755 (executable)
@@ -1387,6 +1387,37 @@ class dml_test extends UnitTestCase {
         $this->assertEqual(1, $DB->count_records('testtable'));
     }
 
+    function test_sql_substring() {
+        $DB = $this->tdb;
+        $dbman = $DB->get_manager();
+
+        $table = $this->get_test_table($dbman, "testtable");
+        $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
+        $table->add_field('name', XMLDB_TYPE_CHAR, '255', null, null, null, null, null, null);
+        $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
+        $dbman->create_table($table);
+        $this->tables[$table->getName()] = $table;
+
+        $string = 'abcdefghij';
+
+        $DB->insert_record('testtable', array('name'=>$string));
+
+        $sql = "SELECT id, ".$DB->sql_substr("name", 5)." AS name FROM {testtable}";
+        $record = $DB->get_record_sql($sql);
+        $this->assertEqual(substr($string, 5-1), $record->name);
+
+        $sql = "SELECT id, ".$DB->sql_substr("name", 5, 2)." AS name FROM {testtable}";
+        $record = $DB->get_record_sql($sql);
+        $this->assertEqual(substr($string, 5-1, 2), $record->name);
+
+        try {
+            @$DB->sql_substr("name");
+            $this->fail("Expecting an exception, none occurred");
+        } catch (Exception $e) {
+            $this->assertTrue($e instanceof coding_exception);
+        }
+    }
+
     function test_sql_position() {
         $DB = $this->tdb;
         $this->assertEqual($DB->get_field_sql(
@@ -1502,5 +1533,5 @@ class moodle_database_for_testing extends moodle_database {
     public function delete_records_select($table, $select, array $params=null){}
     public function sql_concat(){}
     public function sql_concat_join($separator="' '", $elements=array()){}
-    public function sql_substr(){}
+    public function sql_substr($expr, $start, $length=false){}
 }
index 48acd769605868c44a605ee2348efd6bbbdf16c4..f926cbe073a8197751df7adf94ee3a94eca052ec 100644 (file)
@@ -301,13 +301,6 @@ class sqlite3_pdo_moodle_database extends pdo_moodle_database {
         return $this->delete_records_select($table, $select, $params);
     }
 
-    /**
-     * Returns the proper substr() function for each DB
-     */
-    public function sql_substr() {
-        return 'substr';
-    }
-
     /**
      * Returns the proper SQL to do CONCAT between the elements passed
      * Can take many parameters
index a650c18b8c054d814bbb400feaff88a46ca54a91..d730edb0dea47673be9bb2a8ab2362c6d6488a29 100644 (file)
@@ -183,7 +183,7 @@ class file_storage {
             $sql = "SELECT *
                       FROM {files}
                      WHERE contextid = :contextid AND filearea = :filearea AND itemid = :itemid
-                           AND ".$DB->sql_substr()."(filepath, 1, $length) = :filepath
+                           AND ".$DB->sql_substr("filepath", 1, $length)." = :filepath
                            AND id <> :dirid
                            $dirs
                   ORDER BY $sort";
@@ -212,7 +212,7 @@ class file_storage {
                           FROM {files}
                          WHERE contextid = :contextid AND filearea = :filearea
                                AND itemid = :itemid AND filename = '.'
-                               AND ".$DB->sql_substr()."(filepath, 1, $length) = :filepath
+                               AND ".$DB->sql_substr("filepath", 1, $length)." = :filepath
                                AND id <> :dirid
                       ORDER BY $sort";
                 $reqlevel = substr_count($filepath, '/') + 1;
index 73bb67abcdf071d081e39d865af19a8ea3050b37..b8c151333a6cbb7f9b7b2d2cfde2a7f7dbb6f886 100644 (file)
@@ -44,6 +44,21 @@ class moodle_exception extends Exception {
     }
 }
 
+/**
+ * Exception indicating programming error, must be fixed by a programeer.
+ */
+class coding_exception extends moodle_exception {
+
+    /**
+     * Constructor
+     * @param string $hint short description of problem
+     * @param string $debuginfo detailed information how to fix problem
+     */
+    function __construct($hint, $debuginfo=null) {
+        parent::__construct('codingerror', 'debug', '', $hint, $debuginfo);
+    }
+}
+
 /**
  * Default exception handler, uncought exceptions are equivalent to using print_error()
  */
index f86041d270a33cfae2b3f081455fcf12dcf34831..3d73ecaff64438272219bc156e8e88b74c604091 100644 (file)
@@ -93,7 +93,7 @@
         } else {
             $usernamefield = $DB->sql_fullname('u.lastname' , 'u.firstname');
         }
-        $where = "AND " . $DB->sql_substr() . "(upper($usernamefield),1," .  $textlib->strlen($hook) . ") = :hookup";
+        $where = "AND " . $DB->sql_substr("upper($usernamefield)", 1, $textlib->strlen($hook)) . " = :hookup";
 
         if ( $hook == 'ALL' ) {
             $where = '';
         $params['hookup'] = $textlib->strtoupper($hook);
 
         if ($hook != 'ALL' and $hook != 'SPECIAL') {
-            $where = 'AND ' . $DB->sql_substr() . '(upper(concept),1,' .  $textlib->strlen($hook) . ') = :hookup';
+            $where = "AND " . $DB->sql_substr("upper(concept)", 1, $textlib->strlen($hook)) . " = :hookup";
         }
 
         $sqlselect  = "SELECT ge.*, ge.concept AS glossarypivot";
         case 'letter':
             if ($hook != 'ALL' and $hook != 'SPECIAL') {
                 $params['hookup'] = $textlib->strtoupper($hook);
-                $where = 'AND ' . $DB->sql_substr() . '(upper(concept),1,' .  $textlib->strlen($hook) . ') = :hookup';
+                $where = "AND " . $DB->sql_substr("upper(concept)", 1, $textlib->strlen($hook)) . " = :hookup";
             }
             if ($hook == 'SPECIAL') {
                 //Create appropiate IN contents
                 $alphabet = explode(",", get_string("alphabet"));
                 list($nia, $aparams) = $DB->get_in_or_equal($alphabet, SQL_PARAMS_NAMED, $start='a0', false);
                 $params = array_merge($params, $aparams);
-                $where = 'AND ' . $DB->sql_substr() . "(upper(concept),1,1) $nia";
+                $where = "AND " . $DB->sql_substr("upper(concept)", 1, 1) . " $nia";
             }
         break;
         }