From: skodak Date: Fri, 21 Nov 2008 20:09:13 +0000 (+0000) Subject: MDL-17317 DML: Exceptions used by all drivers now :-) expect some more commits/cleanu... X-Git-Url: http://git.mjollnir.org/gw?a=commitdiff_plain;h=22d77567a9ffce4d0e771e18fe35940c398437ae;p=moodle.git MDL-17317 DML: Exceptions used by all drivers now :-) expect some more commits/cleanup soon --- diff --git a/lib/ddl/simpletest/testddl.php b/lib/ddl/simpletest/testddl.php index 0c77620553..db5dac4cd3 100755 --- a/lib/ddl/simpletest/testddl.php +++ b/lib/ddl/simpletest/testddl.php @@ -292,7 +292,7 @@ class ddl_test extends UnitTestCase { $dbman->create_table($table); $record = new object(); - $recorf->course = 2; + $record->onenumber = 2; $DB->insert_record('test_table_cust0', $record); $field = new xmldb_field('onenumber'); diff --git a/lib/dml/adodb_moodle_database.php b/lib/dml/adodb_moodle_database.php index afc3342d91..c729cc06a0 100644 --- a/lib/dml/adodb_moodle_database.php +++ b/lib/dml/adodb_moodle_database.php @@ -85,8 +85,10 @@ abstract class adodb_moodle_database extends moodle_database { * @return array */ public function get_server_info() { - //TODO: make all dblibraries return this info in a structured way (new server_info class or so, like database_column_info class) - return $this->adodb->ServerInfo(); + $this->query_start("--adodb-ServerInfo", null, SQL_QUERY_AUX); + $info = $this->adodb->ServerInfo(); + $this->query_end(true); + return $info; } /** @@ -94,7 +96,10 @@ abstract class adodb_moodle_database extends moodle_database { * @return array of table names in lowercase and without prefix */ public function get_tables() { + $this->query_start("--adodb-MetaTables", null, SQL_QUERY_AUX); $metatables = $this->adodb->MetaTables(); + $this->query_end(true); + $tables = array(); foreach ($metatables as $table) { @@ -112,8 +117,11 @@ abstract class adodb_moodle_database extends moodle_database { * @return array of arrays */ public function get_indexes($table) { - $this->reads++; - if (!$indexes = $this->adodb->MetaIndexes($this->prefix.$table)) { + $this->query_start("--adodb-MetaIndexes", null, SQL_QUERY_AUX); + $indexes = $this->adodb->MetaIndexes($this->prefix.$table); + $this->query_end(true); + + if (!$indexes) { return array(); } $indexes = array_change_key_case($indexes, CASE_LOWER); @@ -132,8 +140,11 @@ abstract class adodb_moodle_database extends moodle_database { return $this->columns[$table]; } - $this->reads++; - if (!$columns = $this->adodb->MetaColumns($this->prefix.$table)) { + $this->query_start("--adodb-MetaColumns", null, SQL_QUERY_AUX); + $columns = $this->adodb->MetaColumns($this->prefix.$table); + $this->query_end(true); + + if (!$columns) { return array(); } @@ -160,50 +171,22 @@ abstract class adodb_moodle_database extends moodle_database { return $this->adodb->ErrorMsg(); } - /** - * Enable/disable very detailed debugging - * @param bool $state - */ - public function set_debug($state) { - if ($this->adodb) { - $this->adodb->debug = $state; - } - } - - /** - * Returns debug status - * @return bool $state - */ - public function get_debug() { - return $this->adodb->debug; - } - - /** - * Enable/disable detailed sql logging - * @param bool $state - */ - public function set_logging($state) { - // TODO: adodb sql logging shares one table without prefix per db - this is no longer acceptable :-( - // we must create one table shared by all drivers - } - /** * Do NOT use in code, to be used by database_manager only! * @param string $sql query - * @return bool success + * @return bool true + * @throws dml_exception if error */ public function change_database_structure($sql) { - $this->writes++; - - if ($rs = $this->adodb->Execute($sql)) { - $result = true; - } else { - $result = false; - $this->report_error($sql); - } - // structure changed, reset columns cache $this->reset_columns(); - return $result; + + $this->query_start($sql, null, SQL_QUERY_STRUCTURE); + $rs = $this->adodb->Execute($sql); + $this->query_end($rs); + + $rs->Close(); + + return true; } /** @@ -211,26 +194,23 @@ abstract class adodb_moodle_database extends moodle_database { * Do NOT use this to make changes in db structure, use database_manager::execute_sql() instead! * @param string $sql query * @param array $params query parameters - * @return bool success + * @return bool true + * @throws dml_exception if error */ public function execute($sql, array $params=null) { list($sql, $params, $type) = $this->fix_sql_params($sql, $params); if (strpos($sql, ';') !== false) { - debugging('Error: Multiple sql statements found or bound parameters not used properly in query!'); - return false; + throw new coding_exception('moodle_database::execute() Multiple sql statements found or bound parameters not used properly in query!'); } - $this->writes++; + $this->query_start($sql, $params, SQL_QUERY_UPDATE); + $rs = $this->adodb->Execute($sql, $params); + $this->query_end($rs); - if ($rs = $this->adodb->Execute($sql, $params)) { - $result = true; - $rs->Close(); - } else { - $result = false; - $this->report_error($sql, $params); - } - return $result; + $rs->Close(); + + return true; } /** @@ -240,7 +220,8 @@ abstract class adodb_moodle_database extends moodle_database { * @param bool $returnit return it of inserted record * @param bool $bulk true means repeated inserts expected * @param bool $customsequence true if 'id' included in $params, disables $returnid - * @return mixed success or new id + * @return mixed true or new id + * @throws dml_exception if error */ public function insert_record_raw($table, $params, $returnid=true, $bulk=false, $customsequence=false) { if (!is_array($params)) { @@ -249,7 +230,7 @@ abstract class adodb_moodle_database extends moodle_database { if ($customsequence) { if (!isset($params['id'])) { - return false; + throw new coding_exception('moodle_database::insert_record_raw() id field must be specified if custom sequences used.'); } $returnid = false; } else { @@ -257,28 +238,29 @@ abstract class adodb_moodle_database extends moodle_database { } if (empty($params)) { - return false; + throw new coding_exception('moodle_database::insert_record_raw() no fields found.'); } - $this->writes++; - $fields = implode(',', array_keys($params)); $qms = array_fill(0, count($params), '?'); $qms = implode(',', $qms); $sql = "INSERT INTO {$this->prefix}$table ($fields) VALUES($qms)"; - if (!$rs = $this->adodb->Execute($sql, $params)) { - $this->report_error($sql, $params); - return false; - } + $this->query_start($sql, $params, SQL_QUERY_INSERT); + $rs = $this->adodb->Execute($sql, $params); + $this->query_end($rs); + $rs->Close(); + if (!$returnid) { return true; } - if ($id = $this->adodb->Insert_ID()) { - return (int)$id; + + if (!$id = $this->adodb->Insert_ID()) { + throw new dml_write_exception('unknown error fetching inserted id'); } - return false; + + return (int)$id; } /** @@ -286,24 +268,23 @@ abstract class adodb_moodle_database extends moodle_database { * @param string $table name * @param mixed $params data record as object or array * @param bool true means repeated updates expected - * @return bool success + * @return bool true + * @throws dml_exception if error */ public function update_record_raw($table, $params, $bulk=false) { if (!is_array($params)) { $params = (array)$params; } if (!isset($params['id'])) { - return false; + throw new coding_exception('moodle_database::update_record_raw() id field must be specified.'); } $id = $params['id']; unset($params['id']); if (empty($params)) { - return false; + throw new coding_exception('moodle_database::update_record_raw() no fields found.'); } - $this->writes++; - $sets = array(); foreach ($params as $field=>$value) { $sets[] = "$field = ?"; @@ -314,10 +295,11 @@ abstract class adodb_moodle_database extends moodle_database { $sets = implode(',', $sets); $sql = "UPDATE {$this->prefix}$table SET $sets WHERE id=?"; - if (!$rs = $this->adodb->Execute($sql, $params)) { - $this->report_error($sql, $params); - return false; - } + $this->query_start($sql, $params, SQL_QUERY_UPDATE); + $rs = $this->adodb->Execute($sql, $params); + $this->query_end($rs); + $rs->Close(); + return true; } @@ -327,7 +309,8 @@ abstract class adodb_moodle_database extends moodle_database { * @param string $table The database table to be checked against. * @param string $select A fragment of SQL to be used in a where clause in the SQL call (used to define the selection criteria). * @param array $params array of sql parameters - * @return returns success. + * @return bool true + * @throws dml_exception if error */ public function delete_records_select($table, $select, array $params=null) { if ($select) { @@ -337,16 +320,12 @@ abstract class adodb_moodle_database extends moodle_database { list($sql, $params, $type) = $this->fix_sql_params($sql, $params); - $this->writes++; + $this->query_start($sql, $params, SQL_QUERY_UPDATE); + $rs = $this->adodb->Execute($sql, $params); + $this->query_end($rs); + $rs->Close(); - $result = false; - if ($rs = $this->adodb->Execute($sql, $params)) { - $result = true; - $rs->Close(); - } else { - $this->report_error($sql, $params); - } - return $result; + return true; } /** @@ -361,26 +340,25 @@ abstract class adodb_moodle_database extends moodle_database { * @param array $params array of sql parameters * @param int $limitfrom return a subset of records, starting at this point (optional, required if $limitnum is set). * @param int $limitnum return a subset comprising this many records (optional, required if $limitfrom is set). - * @return mixed an moodle_recorset object, or false if an error occured. + * @return object moodle_recordset instance + * @throws dml_exception if error */ public function get_recordset_sql($sql, array $params=null, $limitfrom=0, $limitnum=0) { list($sql, $params, $type) = $this->fix_sql_params($sql, $params); - $this->reads++; - if ($limitfrom || $limitnum) { ///Special case, 0 must be -1 for ADOdb $limitfrom = empty($limitfrom) ? -1 : $limitfrom; $limitnum = empty($limitnum) ? -1 : $limitnum; + $this->query_start($sql." --LIMIT $limitfrom, $limitnum", $params, SQL_QUERY_SELECT); $rs = $this->adodb->SelectLimit($sql, $limitnum, $limitfrom, $params); - } else { - $rs = $this->adodb->Execute($sql, $params); - } - if (!$rs) { - $this->report_error($sql, $params); - return false; + $this->query_end($rs); + return $this->create_recordset($rs); } + $this->query_start($sql, $params, SQL_QUERY_SELECT); + $rs = $this->adodb->Execute($sql, $params); + $this->query_end($rs); return $this->create_recordset($rs); } @@ -399,27 +377,28 @@ abstract class adodb_moodle_database extends moodle_database { * @param array $params array of sql parameters * @param int $limitfrom return a subset of records, starting at this point (optional, required if $limitnum is set). * @param int $limitnum return a subset comprising this many records (optional, required if $limitfrom is set). - * @return mixed an array of objects, or empty array if no records were found, or false if an error occured. + * @return array of objects indexed by first column + * @throws dml_exception if error */ public function get_records_sql($sql, array $params=null, $limitfrom=0, $limitnum=0) { list($sql, $params, $type) = $this->fix_sql_params($sql, $params); - $this->reads++; - + $rs = null; if ($limitfrom || $limitnum) { ///Special case, 0 must be -1 for ADOdb $limitfrom = empty($limitfrom) ? -1 : $limitfrom; $limitnum = empty($limitnum) ? -1 : $limitnum; + $this->query_start($sql." --LIMIT $limitfrom, $limitnum", $params, SQL_QUERY_SELECT); $rs = $this->adodb->SelectLimit($sql, $limitnum, $limitfrom, $params); + $this->query_end($rs); } else { + $this->query_start($sql, $params, SQL_QUERY_SELECT); $rs = $this->adodb->Execute($sql, $params); - } - if (!$rs) { - $this->report_error($sql, $params); - return false; + $this->query_end($rs); } $return = $this->adodb_recordset_to_array($rs); - $rs->close(); + $rs->Close(); + return $return; } @@ -428,17 +407,16 @@ abstract class adodb_moodle_database extends moodle_database { * * @param string $sql The SQL query * @param array $params array of sql parameters - * @return mixed array of values or false if an error occured + * @return mixed array of values + * @throws dml_exception if error */ public function get_fieldset_sql($sql, array $params=null) { list($sql, $params, $type) = $this->fix_sql_params($sql, $params); - $this->reads++; + $this->query_start($sql, $params, SQL_QUERY_SELECT); + $rs = $this->adodb->Execute($sql, $params); + $this->query_end($rs); - if (!$rs = $this->adodb->Execute($sql, $params)) { - $this->report_error($sql, $params); - return false; - } $results = array(); while (!$rs->EOF) { $res = reset($rs->fields); @@ -503,8 +481,6 @@ abstract class adodb_moodle_database extends moodle_database { return call_user_func_array(array($this->adodb, 'Concat'), $elements); } - - public function begin_sql() { $this->adodb->BeginTrans(); return true; diff --git a/lib/dml/moodle_database.php b/lib/dml/moodle_database.php index abe7436622..7ef862844f 100644 --- a/lib/dml/moodle_database.php +++ b/lib/dml/moodle_database.php @@ -68,6 +68,9 @@ abstract class moodle_database { */ protected $writes = 0; + /** Debug level */ + protected $debug = 0; + protected $last_sql; protected $last_params; protected $last_type; @@ -312,17 +315,6 @@ abstract class moodle_database { */ public abstract function get_last_error(); - /** - * Report database error somewhere - * TODO: do we need some message with hints? - * @param string $sql query which caused problems - * @param array $params optional query parameters - * @param mixed $obj optional library specific object - */ - protected function report_error($sql, array $params=null, $obj=null) { - debugging(s($this->get_last_error()).'

'.s($sql).'
['.s(var_export($params, true)).']'); - } - /** * Print sql debug info * @param string $sql query which caused problems @@ -624,28 +616,34 @@ abstract class moodle_database { /** * Enable/disable very detailed debugging - * TODO: do we need levels? * @param bool $state */ - public abstract function set_debug($state); + public function set_debug($state) { + $this->debug = $state; + } /** * Returns debug status * @return bool $state */ - public abstract function get_debug(); + public function get_debug() { + return $this->debug; + } /** * Enable/disable detailed sql logging - * TODO: do we need levels? * @param bool $state */ - public abstract function set_logging($state); + public function set_logging($state) { + // TODO: adodb sql logging shares one table without prefix per db - this is no longer acceptable :-( + // we must create one table shared by all drivers + } /** * Do NOT use in code, to be used by database_manager only! * @param string $sql query - * @return bool success + * @return bool true + * @throws dml_exception if error */ public abstract function change_database_structure($sql); @@ -654,7 +652,8 @@ abstract class moodle_database { * Do NOT use this to make changes in db structure, use database_manager::execute_sql() instead! * @param string $sql query * @param array $params query parameters - * @return bool success + * @return bool true + * @throws dml_exception if error */ public abstract function execute($sql, array $params=null); @@ -689,7 +688,8 @@ abstract class moodle_database { * @param string $fields a comma separated list of fields to return (optional, by default all fields are returned). * @param int $limitfrom return a subset of records, starting at this point (optional, required if $limitnum is set). * @param int $limitnum return a subset comprising this many records (optional, required if $limitfrom is set). - * @return mixed an moodle_recorset object, or false if an error occured. + * @return object moodle_recordset instance + * @throws dml_exception if error */ public function get_recordset($table, array $conditions=null, $sort='', $fields='*', $limitfrom=0, $limitnum=0) { list($select, $params) = $this->where_clause($conditions); @@ -711,7 +711,8 @@ abstract class moodle_database { * @param string $fields a comma separated list of fields to return (optional, by default all fields are returned). * @param int $limitfrom return a subset of records, starting at this point (optional, required if $limitnum is set). * @param int $limitnum return a subset comprising this many records (optional, required if $limitfrom is set). - * @return mixed an moodle_recorset object, or false if an error occured. + * @return object moodle_recordset instance + * @throws dml_exception if error */ public function get_recordset_list($table, $field, array $values, $sort='', $fields='*', $limitfrom=0, $limitnum=0) { $params = array(); @@ -746,7 +747,8 @@ abstract class moodle_database { * @param string $fields a comma separated list of fields to return (optional, by default all fields are returned). * @param int $limitfrom return a subset of records, starting at this point (optional, required if $limitnum is set). * @param int $limitnum return a subset comprising this many records (optional, required if $limitfrom is set). - * @return mixed an moodle_recorset object, or false if an error occured. + * @return object moodle_recordset instance + * @throws dml_exception if error */ public function get_recordset_select($table, $select, array $params=null, $sort='', $fields='*', $limitfrom=0, $limitnum=0) { if ($select) { @@ -771,7 +773,8 @@ abstract class moodle_database { * @param array $params array of sql parameters * @param int $limitfrom return a subset of records, starting at this point (optional, required if $limitnum is set). * @param int $limitnum return a subset comprising this many records (optional, required if $limitfrom is set). - * @return mixed an moodle_recorset object, or false if an error occured. + * @return object moodle_recordset instance + * @throws dml_exception if error */ public abstract function get_recordset_sql($sql, array $params=null, $limitfrom=0, $limitnum=0); @@ -792,7 +795,8 @@ abstract class moodle_database { * array so must be a unique field such as 'id'. * @param int $limitfrom return a subset of records, starting at this point (optional, required if $limitnum is set). * @param int $limitnum return a subset comprising this many records (optional, required if $limitfrom is set). - * @return mixed an array of objects, or empty array if no records were found, or false if an error occured. + * @return array of objects indexed by first column + * @throws dml_exception if error */ public function get_records($table, array $conditions=null, $sort='', $fields='*', $limitfrom=0, $limitnum=0) { list($select, $params) = $this->where_clause($conditions); @@ -811,7 +815,8 @@ abstract class moodle_database { * @param string $fields A comma separated list of fields to be returned from the chosen table. If specified, * the first field should be a unique one such as 'id' since it will be used as a key in the associative * array. - * @return mixed an array of objects, or empty array if no records were found, or false if an error occured. + * @return array of objects indexed by first column + * @throws dml_exception if error */ public function get_records_list($table, $field, array $values, $sort='', $fields='*', $limitfrom=0, $limitnum=0) { $params = array(); @@ -850,7 +855,8 @@ abstract class moodle_database { * array so must be a unique field such as 'id'. * @param int $limitfrom return a subset of records, starting at this point (optional, required if $limitnum is set). * @param int $limitnum return a subset comprising this many records (optional, required if $limitfrom is set). - * @return mixed an array of objects, or empty array if no records were found, or false if an error occured. + * @return array of objects indexed by first column + * @throws dml_exception if error */ public function get_records_select($table, $select, array $params=null, $sort='', $fields='*', $limitfrom=0, $limitnum=0) { if ($select) { @@ -873,7 +879,8 @@ abstract class moodle_database { * @param array $params array of sql parameters * @param int $limitfrom return a subset of records, starting at this point (optional, required if $limitnum is set). * @param int $limitnum return a subset comprising this many records (optional, required if $limitfrom is set). - * @return mixed an array of objects, or empty array if no records were found, or false if an error occured. + * @return array of objects indexed by first column + * @throws dml_exception if error */ public abstract function get_records_sql($sql, array $params=null, $limitfrom=0, $limitnum=0); @@ -893,7 +900,8 @@ abstract class moodle_database { * @param string $fields a comma separated list of fields to return - the number of fields should be 2! * @param int $limitfrom return a subset of records, starting at this point (optional, required if $limitnum is set). * @param int $limitnum return a subset comprising this many records (optional, required if $limitfrom is set). - * @return mixed an associative array, or false if an error occured. + * @return array an associative array + * @throws dml_exception if error */ public function get_records_menu($table, array $conditions=null, $sort='', $fields='*', $limitfrom=0, $limitnum=0) { $menu = array(); @@ -921,7 +929,8 @@ abstract class moodle_database { * @param string $fields A comma separated list of fields to be returned from the chosen table - the number of fields should be 2! * @param int $limitfrom return a subset of records, starting at this point (optional, required if $limitnum is set). * @param int $limitnum return a subset comprising this many records (optional, required if $limitfrom is set). - * @return mixed an associative array, or false if an error occured. + * @return array an associative array + * @throws dml_exception if error */ public function get_records_select_menu($table, $select, array $params=null, $sort='', $fields='*', $limitfrom=0, $limitnum=0) { $menu = array(); @@ -946,7 +955,8 @@ abstract class moodle_database { * @param array $params array of sql parameters * @param int $limitfrom return a subset of records, starting at this point (optional, required if $limitnum is set). * @param int $limitnum return a subset comprising this many records (optional, required if $limitfrom is set). - * @return mixed an associative array, or false if an error occured. + * @return array an associative array + * @throws dml_exception if error */ public function get_records_sql_menu($sql, array $params=null, $limitfrom=0, $limitnum=0) { $menu = array(); @@ -968,7 +978,8 @@ abstract class moodle_database { * @param array $conditions optional array $fieldname=>requestedvalue with AND in between * @param string $fields A comma separated list of fields to be returned from the chosen table. * @param bool $ignoremultiple ignore multiple records if found - * @return mixed a fieldset object containing the first mathcing record, or false if none found. + * @return maixed a fieldset object containing the first mathcing record or false if not found + * @throws dml_exception if error */ public function get_record($table, array $conditions, $fields='*', $ignoremultiple=false) { list($select, $params) = $this->where_clause($conditions); @@ -983,7 +994,8 @@ abstract class moodle_database { * @param array $params array of sql parameters * @param string $fields A comma separated list of fields to be returned from the chosen table. * @param bool $ignoremultiple ignore multiple records if found - * @return mixed a fieldset object containing the first mathcing record, or false if none found. + * @return maixed a fieldset object containing the first mathcing record or false if not found + * @throws dml_exception if error */ public function get_record_select($table, $select, array $params=null, $fields='*', $ignoremultiple=false) { if ($select) { @@ -1004,13 +1016,14 @@ abstract class moodle_database { * @param string $sql The SQL string you wish to be executed, should normally only return one record. * @param array $params array of sql parameters * @param bool $ignoremultiple ignore multiple records if found - * @return mixed a fieldset object containing the first matching record, or false if none found. + * @return maixed a fieldset object containing the first mathcing record or false if not found + * @throws dml_exception if error */ public function get_record_sql($sql, array $params=null, $ignoremultiple=false) { $count = $ignoremultiple ? 1 : 2; if (!$records = $this->get_records_sql($sql, $params, 0, $count)) { - // error or not found + // not found return false; } @@ -1028,7 +1041,8 @@ abstract class moodle_database { * @param string $table the table to query. * @param string $return the field to return the value of. * @param array $conditions optional array $fieldname=>requestedvalue with AND in between - * @return mixed the specified value, or false if an error occured. + * @return mixed the specified value false if not found + * @throws dml_exception if error */ public function get_field($table, $return, array $conditions) { list($select, $params) = $this->where_clause($conditions); @@ -1042,7 +1056,8 @@ abstract class moodle_database { * @param string $return the field to return the value of. * @param string $select A fragment of SQL to be used in a where clause returning one row with one column * @param array $params array of sql parameters - * @return mixed the specified value, or false if an error occured. + * @return mixed the specified value false if not found + * @throws dml_exception if error */ public function get_field_select($table, $return, $select, array $params=null) { if ($select) { @@ -1058,7 +1073,8 @@ abstract class moodle_database { * @param string $return the field to return the value of. * @param string $sql The SQL query returning one row with one column * @param array $params array of sql parameters - * @return mixed the specified value, or false if an error occured. + * @return mixed the specified value false if not found + * @throws dml_exception if error */ public function get_field_sql($sql, array $params=null) { if ($records = $this->get_records_sql($sql, $params, 0, 1)) { @@ -1076,7 +1092,8 @@ abstract class moodle_database { * @param string $return the field we are intered in * @param string $select A fragment of SQL to be used in a where clause in the SQL call. * @param array $params array of sql parameters - * @return mixed array of values or false if an error occured + * @return mixed array of values + * @throws dml_exception if error */ public function get_fieldset_select($table, $return, $select, array $params=null) { if ($select) { @@ -1090,7 +1107,8 @@ abstract class moodle_database { * * @param string $sql The SQL query * @param array $params array of sql parameters - * @return mixed array of values or false if an error occured + * @return mixed array of values + * @throws dml_exception if error */ public abstract function get_fieldset_sql($sql, array $params=null); @@ -1101,7 +1119,8 @@ abstract class moodle_database { * @param bool $returnit return it of inserted record * @param bool $bulk true means repeated inserts expected * @param bool $customsequence true if 'id' included in $params, disables $returnid - * @return mixed success or new id + * @return mixed true or new id + * @throws dml_exception if error */ public abstract function insert_record_raw($table, $params, $returnid=true, $bulk=false, $customsequence=false); @@ -1114,7 +1133,8 @@ abstract class moodle_database { * @param string $table The database table to be inserted into * @param object $data A data object with values for one or more fields in the record * @param bool $returnid Should the id of the newly created record entry be returned? If this option is not requested then true/false is returned. - * @return mixed success or new ID + * @return mixed true or new id + * @throws dml_exception if error */ public abstract function insert_record($table, $dataobject, $returnid=true, $bulk=false); @@ -1124,7 +1144,8 @@ abstract class moodle_database { * * @param string $table name of database table to be inserted into * @param object $dataobject A data object with values for one or more fields in the record - * @return bool success + * @return bool true + * @throws dml_exception if error */ public abstract function import_record($table, $dataobject); @@ -1133,7 +1154,8 @@ abstract class moodle_database { * @param string $table name * @param mixed $params data record as object or array * @param bool true means repeated updates expected - * @return bool success + * @return bool true + * @throws dml_exception if error */ public abstract function update_record_raw($table, $params, $bulk=false); @@ -1147,7 +1169,8 @@ abstract class moodle_database { * @param string $table The database table to be checked against. * @param object $dataobject An object with contents equal to fieldname=>fieldvalue. Must have an entry for 'id' to map to the table specified. * @param bool true means repeated updates expected - * @return bool success + * @return bool true + * @throws dml_exception if error */ public abstract function update_record($table, $dataobject, $bulk=false); @@ -1159,7 +1182,8 @@ abstract class moodle_database { * @param string $newfield the field to set. * @param string $newvalue the value to set the field to. * @param array $conditions optional array $fieldname=>requestedvalue with AND in between - * @return bool success + * @return bool true + * @throws dml_exception if error */ public function set_field($table, $newfield, $newvalue, array $conditions=null) { list($select, $params) = $this->where_clause($conditions); @@ -1174,7 +1198,8 @@ abstract class moodle_database { * @param string $newvalue the value to set the field to. * @param string $select A fragment of SQL to be used in a where clause in the SQL call. * @param array $params array of sql parameters - * @return bool success + * @return bool true + * @throws dml_exception if error */ public abstract function set_field_select($table, $newfield, $newvalue, $select, array $params=null); @@ -1185,6 +1210,7 @@ abstract class moodle_database { * @param string $table The table to query. * @param array $conditions optional array $fieldname=>requestedvalue with AND in between * @return int The count of records returned from the specified criteria. + * @throws dml_exception if error */ public function count_records($table, array $conditions=null) { list($select, $params) = $this->where_clause($conditions); @@ -1199,6 +1225,7 @@ abstract class moodle_database { * @param array $params array of sql parameters * @param string $countitem The count string to be used in the SQL call. Default is COUNT('x'). * @return int The count of records returned from the specified criteria. + * @throws dml_exception if error */ public function count_records_select($table, $select, array $params=null, $countitem="COUNT('x')") { if ($select) { @@ -1217,7 +1244,8 @@ abstract class moodle_database { * * @param string $sql The SQL string you wish to be executed. * @param array $params array of sql parameters - * @return int the count. If an error occurrs, 0 is returned. + * @return int the count + * @throws dml_exception if error */ public function count_records_sql($sql, array $params=null) { if ($count = $this->get_field_sql($sql, $params)) { @@ -1236,6 +1264,7 @@ abstract class moodle_database { * @param string $table The table to check. * @param array $conditions optional array $fieldname=>requestedvalue with AND in between * @return bool true if a matching record exists, else false. + * @throws dml_exception if error */ public function record_exists($table, array $conditions) { list($select, $params) = $this->where_clause($conditions); @@ -1249,6 +1278,7 @@ abstract class moodle_database { * @param string $select A fragment of SQL to be used in a WHERE clause in the SQL call. * @param array $params array of sql parameters * @return bool true if a matching record exists, else false. + * @throws dml_exception if error */ public function record_exists_select($table, $select, array $params=null) { if ($select) { @@ -1266,6 +1296,7 @@ abstract class moodle_database { * @param string $sql The SQL statement to execute. * @param array $params array of sql parameters * @return bool true if the SQL executes without errors and returns at least one record. + * @throws dml_exception if error */ public function record_exists_sql($sql, array $params=null) { if ($mrs = $this->get_recordset_sql($sql, $params, 0, 1)) { @@ -1282,7 +1313,8 @@ abstract class moodle_database { * * @param string $table the table to delete from. * @param array $conditions optional array $fieldname=>requestedvalue with AND in between - * @return returns success. + * @return bool true. + * @throws dml_exception if error */ public function delete_records($table, array $conditions=null) { if (is_null($conditions)) { @@ -1298,7 +1330,8 @@ abstract class moodle_database { * @param string $table The database table to be checked against. * @param string $select A fragment of SQL to be used in a where clause in the SQL call (used to define the selection criteria). * @param array $params array of sql parameters - * @return returns success. + * @return bool true. + * @throws dml_exception if error */ public abstract function delete_records_select($table, $select, array $params=null); diff --git a/lib/dml/mssql_adodb_moodle_database.php b/lib/dml/mssql_adodb_moodle_database.php index ed4898a8ec..49be8e1a12 100644 --- a/lib/dml/mssql_adodb_moodle_database.php +++ b/lib/dml/mssql_adodb_moodle_database.php @@ -44,10 +44,16 @@ class mssql_adodb_moodle_database extends adodb_moodle_database { /// No need to set charset. It must be specified in the driver conf /// Allow quoted identifiers - $this->adodb->Execute('SET QUOTED_IDENTIFIER ON'); + $sql = "SET QUOTED_IDENTIFIER ON"; + $this->query_start($sql, null, SQL_QUERY_AUX); + $rs = $this->adodb->Execute($sql); + $this->query_end($rs); /// Force ANSI nulls so the NULL check was done by IS NULL and NOT IS NULL /// instead of equal(=) and distinct(<>) simbols - $this->adodb->Execute('SET ANSI_NULLS ON'); + $sql = "SET ANSI_NULLS ON"; + $this->query_start($sql, null, SQL_QUERY_AUX); + $rs = $this->adodb->Execute($sql); + $this->query_end($rs); return true; } @@ -169,17 +175,14 @@ class mssql_adodb_moodle_database extends adodb_moodle_database { * @param string $table The database table to be checked against. * @param object $dataobject An object with contents equal to fieldname=>fieldvalue. Must have an entry for 'id' to map to the table specified. * @param bool true means repeated updates expected - * @return bool success + * @return bool true + * @throws dml_exception if error */ public function update_record($table, $dataobject, $bulk=false) { if (!is_object($dataobject)) { $dataobject = (object)$dataobject; } - if (! isset($dataobject->id) ) { /// We always need the id to update records - return false; - } - $columns = $this->get_columns($table); $cleaned = array(); $blobs = array(); @@ -211,24 +214,17 @@ class mssql_adodb_moodle_database extends adodb_moodle_database { $cleaned[$field] = $value; } - if (empty($cleaned)) { - return false; - } - if (empty($blobs)) { /// Without BLOBs, execute the raw update and return return $this->update_record_raw($table, $cleaned, $bulk); } /// We have BLOBs to postprocess, execute the raw update and then update blobs - if (!$this->update_record_raw($table, $cleaned, $bulk)) { - return false; - } + $this->update_record_raw($table, $cleaned, $bulk); foreach ($blobs as $key=>$value) { - $this->writes++; - if (!$this->adodb->UpdateBlob($this->prefix.$table, $key, $value, "id = {$dataobject->id}")) { - return false; - } + $this->query_start('--adodb-UpdateBlob', null, SQL_QUERY_UPDATE); + $result = $this->adodb->UpdateBlob($this->prefix.$table, $key, $value, "id = {$dataobject->id}"); + $this->query_end($result); } return true; @@ -242,7 +238,8 @@ class mssql_adodb_moodle_database extends adodb_moodle_database { * @param string $newvalue the value to set the field to. * @param string $select A fragment of SQL to be used in a where clause in the SQL call. * @param array $params array of sql parameters - * @return bool success + * @return bool true + * @throws dml_exception if error */ public function set_field_select($table, $newfield, $newvalue, $select, array $params=null) { @@ -257,8 +254,9 @@ class mssql_adodb_moodle_database extends adodb_moodle_database { if ($column->meta_type == 'B') { /// If the column is a BLOB (IMAGE) /// Update BLOB column and return $select = $this->emulate_bound_params($select, $params); // adodb does not use bound parameters for blob updates :-( - $this->writes++; - return $this->adodb->UpdateBlob($this->prefix.$table, $newfield, $newvalue, $select); + $this->query_start('--adodb-UpdateBlob', null, SQL_QUERY_UPDATE); + $result = $this->adodb->UpdateBlob($this->prefix.$table, $newfield, $newvalue, $select); + $this->query_end($result); } /// Arrived here, normal update (without BLOBs) @@ -284,12 +282,11 @@ class mssql_adodb_moodle_database extends adodb_moodle_database { } $sql = "UPDATE {$this->prefix}$table SET $newfield WHERE $select"; - $this->writes++; + $this->query_start($sql, $params, SQL_QUERY_UPDATE); + $rs = $this->adodb->Execute($sql, $params); + $this->query_end($rs); + $rs->Close(); - if (!$rs = $this->adodb->Execute($sql, $params)) { - $this->report_error($sql, $params); - return false; - } return true; } @@ -302,7 +299,8 @@ class mssql_adodb_moodle_database extends adodb_moodle_database { * @param object $data A data object with values for one or more fields in the record * @param bool $returnid Should the id of the newly created record entry be returned? If this option is not requested then true/false is returned. * @param bool $bulk true means repeated inserts expected - * @return mixed success or new ID + * @return mixed true or new id + * @throws dml_exception if error */ public function insert_record($table, $dataobject, $returnid=true, $bulk=false) { if (!is_object($dataobject)) { @@ -342,25 +340,17 @@ class mssql_adodb_moodle_database extends adodb_moodle_database { $cleaned[$field] = $value; } - if (empty($cleaned)) { - return false; - } - if (empty($blobs)) { /// Without BLOBs, execute the raw insert and return return $this->insert_record_raw($table, $cleaned, $returnid, $bulk); } /// We have BLOBs to postprocess, insert the raw record fetching the id to be used later - if (!$id = $this->insert_record_raw($table, $cleaned, true, $bulk)) { - return false; - } - + $id = $this->insert_record_raw($table, $cleaned, true, $bulk); foreach ($blobs as $key=>$value) { - $this->writes++; - if (!$this->adodb->UpdateBlob($this->prefix.$table, $key, $value, "id = $id")) { - return false; - } + $this->query_start('--adodb-UpdateBlob', null, SQL_QUERY_UPDATE); + $result = $this->adodb->UpdateBlob($this->prefix.$table, $key, $value, "id = $id"); + $this->query_end($result); } return ($returnid ? $id : true); @@ -369,7 +359,8 @@ class mssql_adodb_moodle_database extends adodb_moodle_database { /** * Reset a sequence to the id field of a table. * @param string $table name of table - * @return bool success + * @return bool true + * @throws dml_exception if error */ public function reset_sequence($table) { // From http://msdn.microsoft.com/en-us/library/ms176057.aspx @@ -389,7 +380,8 @@ class mssql_adodb_moodle_database extends adodb_moodle_database { * Basic safety checks only. Lobs are supported. * @param string $table name of database table to be inserted into * @param mixed $dataobject object or array with fields in the record - * @return bool success + * @return bool true + * @throws dml_exception if error */ public function import_record($table, $dataobject) { $dataobject = (object)$dataobject; @@ -417,9 +409,7 @@ class mssql_adodb_moodle_database extends adodb_moodle_database { $cleaned[$field] = $value; } - if (!$this->insert_record_raw($table, $cleaned, false, true, true)) { - return false; - } + $this->insert_record_raw($table, $cleaned, false, true, true); if (empty($blobs)) { return true; @@ -428,10 +418,9 @@ class mssql_adodb_moodle_database extends adodb_moodle_database { /// We have BLOBs to postprocess foreach ($blobs as $key=>$value) { - $this->writes++; - if (!$this->adodb->UpdateBlob($this->prefix.$table, $key, $value, "id = $id")) { - return false; - } + $this->query_start('--adodb-UpdateBlob', null, SQL_QUERY_UPDATE); + $result = $this->adodb->UpdateBlob($this->prefix.$table, $key, $value, "id = $id"); + $this->query_end($result); } return true; diff --git a/lib/dml/mysqli_adodb_moodle_database.php b/lib/dml/mysqli_adodb_moodle_database.php index a231208b7d..5d4a3f1014 100644 --- a/lib/dml/mysqli_adodb_moodle_database.php +++ b/lib/dml/mysqli_adodb_moodle_database.php @@ -15,8 +15,8 @@ class mysqli_adodb_moodle_database extends adodb_moodle_database { * @param string $dbuser * @param string $dbpass * @param string $dbname - * * @return bool success + * @throws dml_exception if error */ public function create_database($dbhost, $dbuser, $dbpass, $dbname) { $this->adodb->database = ''; // reset database name cached by ADODB. Trick from MDL-9609 @@ -50,7 +50,12 @@ class mysqli_adodb_moodle_database extends adodb_moodle_database { protected function configure_dbconnection() { $this->adodb->SetFetchMode(ADODB_FETCH_ASSOC); - $this->adodb->Execute("SET NAMES 'utf8'"); + + $sql = "SET NAMES 'utf8'"; + $this->query_start($sql, null, SQL_QUERY_AUX); + $result = $this->adodb->Execute($sql); + $this->query_end($result); + return true; } @@ -94,8 +99,12 @@ class mysqli_adodb_moodle_database extends adodb_moodle_database { * @return bool true if db in unicode mode */ function setup_is_unicodedb() { - $this->reads++; - $rs = $this->adodb->Execute("SHOW LOCAL VARIABLES LIKE 'character_set_database'"); + + $sql = "SHOW LOCAL VARIABLES LIKE 'character_set_database'"; + $this->query_start($sql, null, SQL_QUERY_AUX); + $rs = $this->adodb->Execute($sql); + $this->query_end($rs); + if ($rs && !$rs->EOF) { $records = $rs->GetAssoc(true); $encoding = $records['character_set_database']['Value']; @@ -109,14 +118,20 @@ class mysqli_adodb_moodle_database extends adodb_moodle_database { /** /* Tries to change default db encoding to utf8, if empty db * @return bool sucecss + * @throws dml_exception if error */ public function change_db_encoding() { // try forcing utf8 collation, if mysql db and no tables present - $this->reads++; - if (!$this->adodb->Metatables()) { - $SQL = 'ALTER DATABASE '.$this->dbname.' CHARACTER SET utf8'; - $this->writes++; - $this->adodb->Execute($SQL); + $this->query_start("--adodb-MetaTables", null, SQL_QUERY_AUX); + // TODO: maybe add separate empty database test because this ignores tables without prefix + $metatables = $this->adodb->MetaTables(); + $this->query_end(true); + + if (!$metatables) { + $sql = "ALTER DATABASE $this->dbname CHARACTER SET utf8"; + $this->query_start($sql, null, SQL_QUERY_AUX); + $rs = $this->adodb->Execute($sql); + $this->query_end($rs); if ($this->setup_is_unicodedb()) { $this->configure_dbconnection(); return true; @@ -137,7 +152,8 @@ class mysqli_adodb_moodle_database extends adodb_moodle_database { * @param object $data A data object with values for one or more fields in the record * @param bool $returnid Should the id of the newly created record entry be returned? If this option is not requested then true/false is returned. * @param bool $bulk true means repeated inserts expected - * @return mixed success or new ID + * @return true or new id + * @throws dml_exception if error */ public function insert_record($table, $dataobject, $returnid=true, $bulk=false) { if (!is_object($dataobject)) { @@ -163,18 +179,13 @@ class mysqli_adodb_moodle_database extends adodb_moodle_database { // ok - nulls allowed } else { if (!in_array((string)$value, $column->enums)) { - debugging('Enum value '.s($value).' not allowed in field '.$field.' table '.$table.'.'); - return false; + throw new dml_write_exception('Enum value '.s($value).' not allowed in field '.$field.' table '.$table.'.'); } } } $cleaned[$field] = $value; } - if (empty($cleaned)) { - return false; - } - return $this->insert_record_raw($table, $cleaned, $returnid, $bulk); } @@ -188,17 +199,14 @@ class mysqli_adodb_moodle_database extends adodb_moodle_database { * @param string $table The database table to be checked against. * @param object $dataobject An object with contents equal to fieldname=>fieldvalue. Must have an entry for 'id' to map to the table specified. * @param bool true means repeated updates expected - * @return bool success + * @return bool true + * @throws dml_exception if error */ public function update_record($table, $dataobject, $bulk=false) { if (!is_object($dataobject)) { $dataobject = (object)$dataobject; } - if (!isset($dataobject->id) ) { - return false; - } - $columns = $this->get_columns($table); $cleaned = array(); @@ -223,7 +231,8 @@ class mysqli_adodb_moodle_database extends adodb_moodle_database { * @param string $newvalue the value to set the field to. * @param string $select A fragment of SQL to be used in a where clause in the SQL call. * @param array $params array of sql parameters - * @return bool success + * @return bool true + * @throws dml_exception if error */ public function set_field_select($table, $newfield, $newvalue, $select, array $params=null) { if ($select) { @@ -245,12 +254,10 @@ class mysqli_adodb_moodle_database extends adodb_moodle_database { } $sql = "UPDATE {$this->prefix}$table SET $newfield $select"; - $this->writes++; + $this->query_start($sql, $params, SQL_QUERY_UPDATE); + $rs = $this->adodb->Execute($sql, $params); + $this->query_end($rs); - if (!$rs = $this->adodb->Execute($sql, $params)) { - $this->report_error($sql, $params); - return false; - } return true; } @@ -295,15 +302,12 @@ class mysqli_adodb_moodle_database extends adodb_moodle_database { * Basic safety checks only. Lobs are supported. * @param string $table name of database table to be inserted into * @param mixed $dataobject object or array with fields in the record - * @return bool success + * @return bool true + * @throws dml_exception if error */ public function import_record($table, $dataobject) { $dataobject = (object)$dataobject; - if (empty($dataobject->id)) { - return false; - } - $columns = $this->get_columns($table); $cleaned = array(); diff --git a/lib/dml/mysqli_native_moodle_database.php b/lib/dml/mysqli_native_moodle_database.php index acb85928dc..758e85e6ba 100644 --- a/lib/dml/mysqli_native_moodle_database.php +++ b/lib/dml/mysqli_native_moodle_database.php @@ -10,7 +10,6 @@ require_once($CFG->libdir.'/dml/mysqli_native_moodle_recordset.php'); class mysqli_native_moodle_database extends moodle_database { protected $mysqli = null; - protected $debug = false; /** * Detects if all needed PHP stuff installed. @@ -330,7 +329,8 @@ class mysqli_native_moodle_database extends moodle_database { /** * Reset a sequence to the id field of a table. * @param string $table name of table - * @return success + * @return bool true + * @throws dml_exception if error */ public function reset_sequence($table) { // From http://dev.mysql.com/doc/refman/5.0/en/alter-table.html @@ -359,34 +359,11 @@ class mysqli_native_moodle_database extends moodle_database { return false; } - /** - * Enable/disable very detailed debugging - * @param bool $state - */ - public function set_debug($state) { - $this->debug = $state; - } - - /** - * Returns debug status - * @return bool $state - */ - public function get_debug() { - return $this->debug; - } - - /** - * Enable/disable detailed sql logging - * @param bool $state - */ - public function set_logging($state) { - //TODO - } - /** * Do NOT use in code, to be used by database_manager only! * @param string $sql query - * @return bool success + * @return bool true + * @throws dml_exception if error */ public function change_database_structure($sql) { $this->reset_columns(); @@ -395,10 +372,6 @@ class mysqli_native_moodle_database extends moodle_database { $result = $this->mysqli->query($sql); $this->query_end($result); - if ($result === false) { - $this->report_error($sql); - return false; - } return true; } @@ -433,14 +406,14 @@ class mysqli_native_moodle_database extends moodle_database { * Do NOT use this to make changes in db structure, use database_manager::execute_sql() instead! * @param string $sql query * @param array $params query parameters - * @return bool success + * @return bool true + * @throws dml_exception if error */ public function execute($sql, array $params=null) { list($sql, $params, $type) = $this->fix_sql_params($sql, $params); if (strpos($sql, ';') !== false) { - debugging('Error: Multiple sql statements found or bound parameters not used properly in query!'); - return false; + throw new coding_exception('moodle_database::execute() Multiple sql statements found or bound parameters not used properly in query!'); } $rawsql = $this->emulate_bound_params($sql, $params); @@ -449,11 +422,7 @@ class mysqli_native_moodle_database extends moodle_database { $result = $this->mysqli->query($rawsql); $this->query_end($result); - if ($result === false) { - $this->report_error($sql, $params); - return false; - - } else if ($result === true) { + if ($result === true) { return true; } else { @@ -475,7 +444,8 @@ class mysqli_native_moodle_database extends moodle_database { * @param array $params array of sql parameters * @param int $limitfrom return a subset of records, starting at this point (optional, required if $limitnum is set). * @param int $limitnum return a subset comprising this many records (optional, required if $limitfrom is set). - * @return mixed an moodle_recorset object, or false if an error occured. + * @return mixed an moodle_recordset object + * @throws dml_exception if error */ public function get_recordset_sql($sql, array $params=null, $limitfrom=0, $limitnum=0) { if ($limitfrom or $limitnum) { @@ -495,11 +465,6 @@ class mysqli_native_moodle_database extends moodle_database { $result = $this->mysqli->query($rawsql, MYSQLI_STORE_RESULT); $this->query_end($result); - if ($result === false) { - $this->report_error($sql, $params); - return false; - } - return $this->create_recordset($result); } @@ -518,7 +483,8 @@ class mysqli_native_moodle_database extends moodle_database { * @param array $params array of sql parameters * @param int $limitfrom return a subset of records, starting at this point (optional, required if $limitnum is set). * @param int $limitnum return a subset comprising this many records (optional, required if $limitfrom is set). - * @return mixed an array of objects, or empty array if no records were found, or false if an error occured. + * @return mixed an array of objects, or empty array if no records were found + * @throws dml_exception if error */ public function get_records_sql($sql, array $params=null, $limitfrom=0, $limitnum=0) { if ($limitfrom or $limitnum) { @@ -537,11 +503,6 @@ class mysqli_native_moodle_database extends moodle_database { $result = $this->mysqli->query($rawsql, MYSQLI_STORE_RESULT); $this->query_end($result); - if ($result === false) { - $this->report_error($sql, $params); - return false; - } - $return = array(); while($row = $result->fetch_assoc()) { @@ -559,7 +520,8 @@ class mysqli_native_moodle_database extends moodle_database { * * @param string $sql The SQL query * @param array $params array of sql parameters - * @return mixed array of values or false if an error occured + * @return mixed array of values + * @throws dml_exception if error */ public function get_fieldset_sql($sql, array $params=null) { list($sql, $params, $type) = $this->fix_sql_params($sql, $params); @@ -569,11 +531,6 @@ class mysqli_native_moodle_database extends moodle_database { $result = $this->mysqli->query($rawsql, MYSQLI_STORE_RESULT); $this->query_end($result); - if ($result === false) { - $this->report_error($sql, $params); - return false; - } - $return = array(); while($row = $result->fetch_assoc()) { @@ -591,7 +548,8 @@ class mysqli_native_moodle_database extends moodle_database { * @param bool $returnit return it of inserted record * @param bool $bulk true means repeated inserts expected * @param bool $customsequence true if 'id' included in $params, disables $returnid - * @return mixed success or new id + * @return true or new id + * @throws dml_exception if error */ public function insert_record_raw($table, $params, $returnid=true, $bulk=false, $customsequence=false) { if (!is_array($params)) { @@ -600,7 +558,7 @@ class mysqli_native_moodle_database extends moodle_database { if ($customsequence) { if (!isset($params['id'])) { - return false; + throw new coding_exception('moodle_database::insert_record_raw() id field must be specified if custom sequences used.'); } $returnid = false; } else { @@ -608,7 +566,7 @@ class mysqli_native_moodle_database extends moodle_database { } if (empty($params)) { - return false; + throw new coding_exception('moodle_database::insert_record_raw() no fields found.'); } $fields = implode(',', array_keys($params)); @@ -622,13 +580,8 @@ class mysqli_native_moodle_database extends moodle_database { $result = $this->mysqli->query($rawsql); $this->query_end($result); - if ($result === false) { - $this->report_error($sql, $params); - return false; - } - if (!$id = $this->mysqli->insert_id) { - return false; + throw new dml_write_exception('unknown error fetching inserted id'); } if (!$returnid) { @@ -647,7 +600,8 @@ class mysqli_native_moodle_database extends moodle_database { * @param string $table The database table to be inserted into * @param object $data A data object with values for one or more fields in the record * @param bool $returnid Should the id of the newly created record entry be returned? If this option is not requested then true/false is returned. - * @return mixed success or new ID + * @return true or new id + * @throws dml_exception if error */ public function insert_record($table, $dataobject, $returnid=true, $bulk=false) { if (!is_object($dataobject)) { @@ -673,18 +627,13 @@ class mysqli_native_moodle_database extends moodle_database { // ok - nulls allowed } else { if (!in_array((string)$value, $column->enums)) { - debugging('Enum value '.s($value).' not allowed in field '.$field.' table '.$table.'.'); - return false; + throw new dml_write_exception('Enum value '.s($value).' not allowed in field '.$field.' table '.$table.'.'); } } } $cleaned[$field] = $value; } - if (empty($cleaned)) { - return false; - } - return $this->insert_record_raw($table, $cleaned, $returnid, $bulk); } @@ -694,15 +643,12 @@ class mysqli_native_moodle_database extends moodle_database { * * @param string $table name of database table to be inserted into * @param object $dataobject A data object with values for one or more fields in the record - * @return bool success + * @return bool true + * @throws dml_exception if error */ public function import_record($table, $dataobject) { $dataobject = (object)$dataobject; - if (empty($dataobject->id)) { - return false; - } - $columns = $this->get_columns($table); $cleaned = array(); @@ -721,20 +667,21 @@ class mysqli_native_moodle_database extends moodle_database { * @param string $table name * @param mixed $params data record as object or array * @param bool true means repeated updates expected - * @return bool success + * @return bool true + * @throws dml_exception if error */ public function update_record_raw($table, $params, $bulk=false) { if (!is_array($params)) { $params = (array)$params; } if (!isset($params['id'])) { - return false; + throw new coding_exception('moodle_database::update_record_raw() id field must be specified.'); } $id = $params['id']; unset($params['id']); if (empty($params)) { - return false; + throw new coding_exception('moodle_database::update_record_raw() no fields found.'); } $sets = array(); @@ -752,11 +699,6 @@ class mysqli_native_moodle_database extends moodle_database { $result = $this->mysqli->query($rawsql); $this->query_end($result); - if ($result === false) { - $this->report_error($sql, $params); - return false; - } - return true; } @@ -770,17 +712,14 @@ class mysqli_native_moodle_database extends moodle_database { * @param string $table The database table to be checked against. * @param object $dataobject An object with contents equal to fieldname=>fieldvalue. Must have an entry for 'id' to map to the table specified. * @param bool true means repeated updates expected - * @return bool success + * @return bool true + * @throws dml_exception if error */ public function update_record($table, $dataobject, $bulk=false) { if (!is_object($dataobject)) { $dataobject = (object)$dataobject; } - if (!isset($dataobject->id) ) { - return false; - } - $columns = $this->get_columns($table); $cleaned = array(); @@ -805,7 +744,8 @@ class mysqli_native_moodle_database extends moodle_database { * @param string $newvalue the value to set the field to. * @param string $select A fragment of SQL to be used in a where clause in the SQL call. * @param array $params array of sql parameters - * @return bool success + * @return bool true + * @throws dml_exception if error */ public function set_field_select($table, $newfield, $newvalue, $select, array $params=null) { if ($select) { @@ -832,11 +772,6 @@ class mysqli_native_moodle_database extends moodle_database { $result = $this->mysqli->query($rawsql); $this->query_end($result); - if ($result === false) { - $this->report_error($sql, $params); - return false; - } - return true; } @@ -846,7 +781,8 @@ class mysqli_native_moodle_database extends moodle_database { * @param string $table The database table to be checked against. * @param string $select A fragment of SQL to be used in a where clause in the SQL call (used to define the selection criteria). * @param array $params array of sql parameters - * @return returns success. + * @return bool true + * @throws dml_exception if error */ public function delete_records_select($table, $select, array $params=null) { if ($select) { @@ -861,11 +797,6 @@ class mysqli_native_moodle_database extends moodle_database { $result = $this->mysqli->query($rawsql); $this->query_end($result); - if ($result === false) { - $this->report_error($sql, $params); - return false; - } - return true; } @@ -922,18 +853,11 @@ class mysqli_native_moodle_database extends moodle_database { $result = $this->mysqli->query($sql); $this->query_end($result); - if ($result === false) { - return false; - } - $sql = "BEGIN"; $this->query_start($sql, NULL, SQL_QUERY_AUX); $result = $this->mysqli->query($sql); $this->query_end($result); - if ($result === false) { - return false; - } return true; } @@ -946,9 +870,6 @@ class mysqli_native_moodle_database extends moodle_database { $result = $this->mysqli->query($sql); $this->query_end($result); - if ($result === false) { - return false; - } return true; } @@ -961,9 +882,6 @@ class mysqli_native_moodle_database extends moodle_database { $result = $this->mysqli->query($sql); $this->query_end($result); - if ($result === false) { - return false; - } return true; } } diff --git a/lib/dml/oci8po_adodb_moodle_database.php b/lib/dml/oci8po_adodb_moodle_database.php index 73d8ee295b..00b37d1e12 100644 --- a/lib/dml/oci8po_adodb_moodle_database.php +++ b/lib/dml/oci8po_adodb_moodle_database.php @@ -56,7 +56,10 @@ class oci8po_adodb_moodle_database extends adodb_moodle_database { /// Now set the decimal separator to DOT, Moodle & PHP will always send floats to /// DB using DOTS. Manually introduced floats (if using other characters) must be /// converted back to DOTs (like gradebook does) - $this->adodb->Execute("ALTER SESSION SET NLS_NUMERIC_CHARACTERS='.,'"); + $sql = "ALTER SESSION SET NLS_NUMERIC_CHARACTERS='.,'"; + $rs = $this->query_start($sql, null, SQL_QUERY_AUX); + $this->adodb->Execute($sql); + $this->query_end($rs); return true; } @@ -107,8 +110,11 @@ class oci8po_adodb_moodle_database extends adodb_moodle_database { * @return bool true if db in unicode mode */ function setup_is_unicodedb() { - $this->reads++; - $rs = $this->adodb->Execute("SELECT parameter, value FROM nls_database_parameters where parameter = 'NLS_CHARACTERSET'"); + $sql = "SELECT parameter, value FROM nls_database_parameters where parameter = 'NLS_CHARACTERSET'"; + $rs = $this->query_start($sql, null, SQL_QUERY_AUX); + $this->adodb->Execute($sql); + $this->query_end($rs); + if ($rs && !$rs->EOF) { $encoding = $rs->fields['value']; if (strtoupper($encoding) == 'AL32UTF8') { @@ -123,7 +129,8 @@ class oci8po_adodb_moodle_database extends adodb_moodle_database { * * @param string $sql The SQL query * @param array $params array of sql parameters - * @return mixed array of values or false if an error occured + * @return mixed array of values + * @throws dml_exception if error */ public function get_fieldset_sql($sql, array $params=null) { if ($result = parent::get_fieldset_sql($sql, $params)) { @@ -215,17 +222,14 @@ class oci8po_adodb_moodle_database extends adodb_moodle_database { * @param string $table The database table to be checked against. * @param object $dataobject An object with contents equal to fieldname=>fieldvalue. Must have an entry for 'id' to map to the table specified. * @param bool true means repeated updates expected - * @return bool success + * @return bool true + * @throws dml_exception if error */ public function update_record($table, $dataobject, $bulk=false) { if (!is_object($dataobject)) { $dataobject = (object)$dataobject; } - if (! isset($dataobject->id) ) { - return false; - } - $columns = $this->get_columns($table); $cleaned = array(); $clobs = array(); @@ -265,31 +269,24 @@ class oci8po_adodb_moodle_database extends adodb_moodle_database { $cleaned[$field] = $value; } - if (empty($cleaned)) { - return false; - } if (empty($blobs) && empty($clobs)) { /// Without BLOBs and CLOBs, execute the raw update and return return $this->update_record_raw($table, $cleaned, $bulk); } /// We have BLOBs or CLOBs to postprocess, execute the raw update and then update blobs - if (!$this->update_record_raw($table, $cleaned, $bulk)) { - return false; - } + $this->update_record_raw($table, $cleaned, $bulk); foreach ($blobs as $key=>$value) { - $this->writes++; - if (!$this->adodb->UpdateBlob($this->prefix.$table, $key, $value, "id = {$dataobject->id}")) { - return false; - } + $this->query_start('--adodb-UpdateBlob', null, SQL_QUERY_UPDATE); + $result = $this->adodb->UpdateBlob($this->prefix.$table, $key, $value, "id = {$dataobject->id}"); + $this->query_end($result); } foreach ($clobs as $key=>$value) { - $this->writes++; - if (!$this->adodb->UpdateClob($this->prefix.$table, $key, $value, "id = {$dataobject->id}")) { - return false; - } + $this->query_start('--adodb-UpdateClob', null, SQL_QUERY_UPDATE); + $result = $this->adodb->UpdateClob($this->prefix.$table, $key, $value, "id = {$dataobject->id}"); + $this->query_end($result); } return true; @@ -304,7 +301,8 @@ class oci8po_adodb_moodle_database extends adodb_moodle_database { * @param object $data A data object with values for one or more fields in the record * @param bool $returnid Should the id of the newly created record entry be returned? If this option is not requested then true/false is returned. * @param bool $bulk true means repeated inserts expected - * @return mixed success or new ID + * @return true or new id + * @throws dml_exception if error */ public function insert_record($table, $dataobject, $returnid=true, $bulk=false) { if (!is_object($dataobject)) { @@ -350,31 +348,23 @@ class oci8po_adodb_moodle_database extends adodb_moodle_database { $cleaned[$field] = $value; } - if (empty($cleaned)) { - return false; - } - if (empty($blobs) && empty($clobs)) { /// Without BLOBs and CLOBs, execute the raw insert and return return $this->insert_record_raw($table, $cleaned, $returnid, $bulk); } /// We have BLOBs or CLOBs to postprocess, insert the raw record fetching the id to be used later - if (!$id = $this->insert_record_raw($table, $cleaned, true, $bulk)) { - return false; - } + $id = $this->insert_record_raw($table, $cleaned, true, $bulk); foreach ($blobs as $key=>$value) { - $this->writes++; - if (!$this->adodb->UpdateBlob($this->prefix.$table, $key, $value, "id = $id")) { - return false; - } + $this->query_start('--adodb-UpdateBlob', null, SQL_QUERY_UPDATE); + $result = $this->adodb->UpdateBlob($this->prefix.$table, $key, $value, "id = $id"); + $this->query_end($result); } foreach ($clobs as $key=>$value) { - $this->writes++; - if (!$this->adodb->UpdateClob($this->prefix.$table, $key, $value, "id = $id")) { - return false; - } + $this->query_start('--adodb-UpdateClob', null, SQL_QUERY_UPDATE); + $result = $this->adodb->UpdateClob($this->prefix.$table, $key, $value, "id = $id"); + $this->query_end($result); } return ($returnid ? $id : true); @@ -388,7 +378,8 @@ class oci8po_adodb_moodle_database extends adodb_moodle_database { * @param string $newvalue the value to set the field to. * @param string $select A fragment of SQL to be used in a where clause in the SQL call. * @param array $params array of sql parameters - * @return bool success + * @return bool true + * @throws dml_exception if error */ public function set_field_select($table, $newfield, $newvalue, $select, array $params=null) { @@ -407,15 +398,19 @@ class oci8po_adodb_moodle_database extends adodb_moodle_database { if ($column->meta_type == 'B') { /// If the column is a BLOB /// Update BLOB column and return $select = $this->emulate_bound_params($select, $params); // adodb does not use bound parameters for blob updates :-( - $this->writes++; - return $this->adodb->UpdateBlob($this->prefix.$table, $newfield, $newvalue, $select); + $this->query_start('--adodb-UpdateBlob', null, SQL_QUERY_UPDATE); + $result = $this->adodb->UpdateBlob($this->prefix.$table, $newfield, $newvalue, $select); + $this->query_end($result); + return true; } if ($column->meta_type == 'X' && strlen($newvalue) > 4000) { /// If the column is a CLOB with lenght > 4000 /// Update BLOB column and return $select = $this->emulate_bound_params($select, $params); // adodb does not use bound parameters for blob updates :-( - $this->writes++; - return $this->adodb->UpdateClob($this->prefix.$table, $newfield, $newvalue, $select); + $this->query_start('--adodb-UpdateClob', null, SQL_QUERY_UPDATE); + $result = $this->adodb->UpdateClob($this->prefix.$table, $newfield, $newvalue, $select); + $this->query_end($result); + return true; } /// Arrived here, normal update (without BLOBs) @@ -435,11 +430,10 @@ class oci8po_adodb_moodle_database extends adodb_moodle_database { } $sql = "UPDATE {$this->prefix}$table SET $newfield WHERE $select"; - $this->writes++; - if (!$rs = $this->adodb->Execute($sql, $params)) { - $this->report_error($sql, $params); - return false; - } + $this->query_start($sql, $params, SQL_QUERY_UPDATE); + $rs = $rs = $this->adodb->Execute($sql, $params); + $this->query_end($rs); + return true; } @@ -451,7 +445,8 @@ class oci8po_adodb_moodle_database extends adodb_moodle_database { * @param bool $returnit return it of inserted record * @param bool $bulk true means repeated inserts expected * @param bool $customsequence true if 'id' included in $params, disables $returnid - * @return mixed success or new id + * @return true or new id + * @throws dml_exception if error */ public function insert_record_raw($table, $params, $returnid=true, $bulk=false, $customsequence=false) { if (!is_array($params)) { @@ -460,7 +455,7 @@ class oci8po_adodb_moodle_database extends adodb_moodle_database { if ($customsequence) { if (!isset($params['id'])) { - return false; + throw new coding_exception('moodle_database::insert_record_raw() id field must be specified if custom sequences used.'); } $returnid = false; } else { @@ -470,22 +465,27 @@ class oci8po_adodb_moodle_database extends adodb_moodle_database { if ($returnid) { $dbman = $this->get_manager(); $xmldb_table = new xmldb_table($table); - $this->reads++; + $this->query_start('--find_sequence_name', null, SQL_QUERY_AUX); $seqname = $dbman->find_sequence_name($xmldb_table); + $this->query_end(true); if (!$seqname) { /// Fallback, seqname not found, something is wrong. Inform and use the alternative getNameForObject() method $generator = $this->get_dbman()->generator; $generator->setPrefix($this->getPrefix()); $seqname = $generator->getNameForObject($table, 'id', 'seq'); } - $this->reads++; - if ($nextval = $this->adodb->GenID($seqname)) { + $xmldb_table = new xmldb_table($table); + $this->query_start('--adodb-GenID', null, SQL_QUERY_AUX); + $nextval = $this->adodb->GenID($seqname); + $this->query_end(true); + + if ($nextval) { $params['id'] = (int)$nextval; } } if (empty($params)) { - return false; + throw new coding_exception('moodle_database::insert_record_raw() no fields found.'); } $fields = implode(',', array_keys($params)); @@ -508,18 +508,18 @@ class oci8po_adodb_moodle_database extends adodb_moodle_database { $sql = "INSERT INTO {$this->prefix}$table ($fields) VALUES($qms)"; - $this->writes++; - if (!$rs = $this->adodb->Execute($sql, $params)) { - $this->report_error($sql, $params); - return false; - } + $this->query_start($sql, $params, SQL_QUERY_INSERT); + $rs = $rs = $this->adodb->Execute($sql, $params); + $this->query_end($rs); + if (!$returnid) { return true; } if (!empty($params['id'])) { return (int)$params['id']; } - return false; + + throw new dml_write_exception('unknown error fetching inserted id'); } /** @@ -617,7 +617,8 @@ class oci8po_adodb_moodle_database extends adodb_moodle_database { /** * Reset a sequence to the id field of a table. * @param string $table name of table - * @return bool success + * @return bool true + * @throws dml_exception if error */ public function reset_sequence($table) { // From http://www.acs.ilstu.edu/docs/oracle/server.101/b10759/statements_2011.htm @@ -628,8 +629,10 @@ class oci8po_adodb_moodle_database extends adodb_moodle_database { $value = (int)$this->get_field_sql('SELECT MAX(id) FROM {'.$table.'}'); $value++; $xmldb_table = new xmldb_table($table); - $this->reads++; + $this->query_start('--find_sequence_name', null, SQL_QUERY_AUX); $seqname = $dbman->find_sequence_name($xmldb_table); + $this->query_end(true); + if (!$seqname) { /// Fallback, seqname not found, something is wrong. Inform and use the alternative getNameForObject() method $generator = $dbman->generator; @@ -681,9 +684,7 @@ class oci8po_adodb_moodle_database extends adodb_moodle_database { $cleaned[$field] = $value; } - if (!$this->insert_record_raw($table, $cleaned, false, true, true)) { - return false; - } + $this->insert_record_raw($table, $cleaned, false, true, true); if (empty($blobs) and empty($clobs)) { return true; @@ -692,17 +693,15 @@ class oci8po_adodb_moodle_database extends adodb_moodle_database { /// We have BLOBs or CLOBs to postprocess foreach ($blobs as $key=>$value) { - $this->writes++; - if (!$this->adodb->UpdateBlob($this->prefix.$table, $key, $value, "id = $id")) { - return false; - } + $this->query_start('--adodb-UpdateBlob', null, SQL_QUERY_UPDATE); + $result = $this->adodb->UpdateBlob($this->prefix.$table, $key, $value, "id = $id"); + $this->query_end($result); } foreach ($clobs as $key=>$value) { - $this->writes++; - if (!$this->adodb->UpdateClob($this->prefix.$table, $key, $value, "id = $id")) { - return false; - } + $this->query_start('--adodb-UpdateClob', null, SQL_QUERY_UPDATE); + $result = $this->adodb->UpdateClob($this->prefix.$table, $key, $value, "id = $id"); + $this->query_end($result); } return true; diff --git a/lib/dml/pdo_moodle_database.php b/lib/dml/pdo_moodle_database.php index 31c11c248f..8cfbb654e7 100644 --- a/lib/dml/pdo_moodle_database.php +++ b/lib/dml/pdo_moodle_database.php @@ -10,7 +10,6 @@ require_once($CFG->libdir.'/dml/pdo_moodle_recordset.php'); abstract class pdo_moodle_database extends moodle_database { protected $pdb; - protected $debug = false; protected $lastError = null; /** @@ -127,36 +126,6 @@ abstract class pdo_moodle_database extends moodle_database { return $this->lastError; } - protected function report_error($sql, $params, $e) { - debugging($e->getMessage() .'

'. s($sql)); - } - - /** - * Enable/disable very detailed debugging - * TODO: do we need levels? - * @param bool $state - */ - public function set_debug($state) { - $this->debug = $state; - } - - /** - * Returns debug status - * @return bool $state - */ - public function get_debug() { - return $this->debug; - } - - /** - * Enable/disable detailed sql logging - * TODO: do we need levels? - * @param bool $state - */ - public function set_logging($state) { - //TODO - } - /** * Function to print/save/ignore debuging messages related to SQL queries. */ @@ -186,7 +155,6 @@ abstract class pdo_moodle_database extends moodle_database { return true; } catch (PDOException $ex) { $this->lastError = $ex->getMessage(); - $this->report_error($sql, null, $ex); return false; } } @@ -230,7 +198,6 @@ abstract class pdo_moodle_database extends moodle_database { return true; } catch (PDOException $ex) { $this->lastError = $ex->getMessage(); - $this->report_error($sql, $params, $ex); return false; } } @@ -247,7 +214,7 @@ abstract class pdo_moodle_database extends moodle_database { * @param array $params array of sql parameters * @param int $limitfrom return a subset of records, starting at this point (optional, required if $limitnum is set). * @param int $limitnum return a subset comprising this many records (optional, required if $limitfrom is set). - * @return mixed an moodle_recorset object, or false if an error occured. + * @return mixed an moodle_recordset object, or false if an error occured. */ public function get_recordset_sql($sql, array $params=null, $limitfrom=0, $limitnum=0) { try { @@ -263,7 +230,6 @@ abstract class pdo_moodle_database extends moodle_database { return $this->create_recordset($sth); } catch (PDOException $ex) { $this->lastError = $ex->getMessage(); - $this->report_error($sql, $params, $ex); return false; } } @@ -335,7 +301,7 @@ abstract class pdo_moodle_database extends moodle_database { * @param bool $returnit return it of inserted record * @param bool $bulk true means repeated inserts expected * @param bool $customsequence true if 'id' included in $params, disables $returnid - * @return mixed success or new id + * @return true or new id */ public function insert_record_raw($table, $params, $returnid=true, $bulk=false, $customsequence=false) { if (!is_array($params)) { @@ -383,7 +349,7 @@ abstract class pdo_moodle_database extends moodle_database { * @param object $data A data object with values for one or more fields in the record * @param bool $returnid Should the id of the newly created record entry be returned? If this option is not requested then true/false is returned. * @param bool $bulk true means repeated inserts expected - * @return mixed success or new ID + * @return true or new id */ public function insert_record($table, $dataobject, $returnid=true, $bulk=false) { if (!is_object($dataobject)) { diff --git a/lib/dml/pgsql_native_moodle_database.php b/lib/dml/pgsql_native_moodle_database.php index c88f9e5638..df78830208 100644 --- a/lib/dml/pgsql_native_moodle_database.php +++ b/lib/dml/pgsql_native_moodle_database.php @@ -10,7 +10,6 @@ require_once($CFG->libdir.'/dml/pgsql_native_moodle_recordset.php'); class pgsql_native_moodle_database extends moodle_database { protected $pgsql = null; - protected $debug = false; protected $bytea_oid = null; protected $last_debug; @@ -454,7 +453,8 @@ class pgsql_native_moodle_database extends moodle_database { /** * Reset a sequence to the id field of a table. * @param string $table name of table - * @return success + * @return bool true + * @throws dml_exception if error */ public function reset_sequence($table) { if (!$this->get_manager()->table_exists($table)) { @@ -486,34 +486,11 @@ class pgsql_native_moodle_database extends moodle_database { return (strtoupper($encoding) == 'UNICODE' || strtoupper($encoding) == 'UTF8'); } - /** - * Enable/disable very detailed debugging - * @param bool $state - */ - public function set_debug($state) { - $this->debug = $state; - } - - /** - * Returns debug status - * @return bool $state - */ - public function get_debug() { - return $this->debug; - } - - /** - * Enable/disable detailed sql logging - * @param bool $state - */ - public function set_logging($state) { - //TODO - } - /** * Do NOT use in code, to be used by database_manager only! * @param string $sql query - * @return bool success + * @return bool true + * @throws dml_exception if error */ public function change_database_structure($sql) { $this->reset_columns(); @@ -522,10 +499,6 @@ class pgsql_native_moodle_database extends moodle_database { $result = pg_query($this->pgsql, $sql); $this->query_end($result); - if ($result === false) { - $this->report_error($sql); - return false; - } pg_free_result($result); return true; } @@ -535,25 +508,20 @@ class pgsql_native_moodle_database extends moodle_database { * Do NOT use this to make changes in db structure, use database_manager::execute_sql() instead! * @param string $sql query * @param array $params query parameters - * @return bool success + * @return bool true + * @throws dml_exception if error */ public function execute($sql, array $params=null) { list($sql, $params, $type) = $this->fix_sql_params($sql, $params); if (strpos($sql, ';') !== false) { - debugging('Error: Multiple sql statements found or bound parameters not used properly in query!'); - return false; + throw new coding_exception('moodle_database::execute() Multiple sql statements found or bound parameters not used properly in query!'); } $this->query_start($sql, $params, SQL_QUERY_UPDATE); $result = pg_query_params($this->pgsql, $sql, $params); $this->query_end($result); - if ($result === false) { - $this->report_error($sql, $params); - return false; - - } pg_free_result($result); return true; } @@ -571,7 +539,8 @@ class pgsql_native_moodle_database extends moodle_database { * @param array $params array of sql parameters * @param int $limitfrom return a subset of records, starting at this point (optional, required if $limitnum is set). * @param int $limitnum return a subset comprising this many records (optional, required if $limitfrom is set). - * @return mixed an moodle_recorset object, or false if an error occured. + * @return mixed an moodle_recordset object + * @throws dml_exception if error */ public function get_recordset_sql($sql, array $params=null, $limitfrom=0, $limitnum=0) { if ($limitfrom or $limitnum) { @@ -589,11 +558,6 @@ class pgsql_native_moodle_database extends moodle_database { $result = pg_query_params($this->pgsql, $sql, $params); $this->query_end($result); - if ($result === false) { - $this->report_error($sql, $params); - return false; - } - return $this->create_recordset($result); } @@ -612,7 +576,8 @@ class pgsql_native_moodle_database extends moodle_database { * @param array $params array of sql parameters * @param int $limitfrom return a subset of records, starting at this point (optional, required if $limitnum is set). * @param int $limitnum return a subset comprising this many records (optional, required if $limitfrom is set). - * @return mixed an array of objects, or empty array if no records were found, or false if an error occured. + * @return mixed an array of objects, or empty array if no records were found + * @throws dml_exception if error */ public function get_records_sql($sql, array $params=null, $limitfrom=0, $limitnum=0) { if ($limitfrom or $limitnum) { @@ -629,10 +594,6 @@ class pgsql_native_moodle_database extends moodle_database { $result = pg_query_params($this->pgsql, $sql, $params); $this->query_end($result); - if ($result === false) { - $this->report_error($sql, $params); - return false; - } // find out if there are any blobs $numrows = pg_num_fields($result); $blobs = array(); @@ -667,7 +628,8 @@ class pgsql_native_moodle_database extends moodle_database { * * @param string $sql The SQL query * @param array $params array of sql parameters - * @return mixed array of values or false if an error occured + * @return mixed array of values + * @throws dml_exception if error */ public function get_fieldset_sql($sql, array $params=null) { list($sql, $params, $type) = $this->fix_sql_params($sql, $params); @@ -676,11 +638,6 @@ class pgsql_native_moodle_database extends moodle_database { $result = pg_query_params($this->pgsql, $sql, $params); $this->query_end($result); - if ($result === false) { - $this->report_error($sql, $params); - return false; - } - $return = pg_fetch_all_columns($result, 0); pg_free_result($result); @@ -694,7 +651,8 @@ class pgsql_native_moodle_database extends moodle_database { * @param bool $returnit return it of inserted record * @param bool $bulk true means repeated inserts expected * @param bool $customsequence true if 'id' included in $params, disables $returnid - * @return mixed success or new id + * @return true or new id + * @throws dml_exception if error */ public function insert_record_raw($table, $params, $returnid=true, $bulk=false, $customsequence=false) { if (!is_array($params)) { @@ -705,7 +663,7 @@ class pgsql_native_moodle_database extends moodle_database { if ($customsequence) { if (!isset($params['id'])) { - return false; + throw new coding_exception('moodle_database::insert_record_raw() id field must be specified if custom sequences used.'); } $returnid = false; } else { @@ -732,7 +690,7 @@ class pgsql_native_moodle_database extends moodle_database { } if (empty($params)) { - return false; + throw new coding_exception('moodle_database::insert_record_raw() no fields found.'); } $fields = implode(',', array_keys($params)); @@ -748,11 +706,6 @@ class pgsql_native_moodle_database extends moodle_database { $result = pg_query_params($this->pgsql, $sql, $params); $this->query_end($result); - if ($result === false) { - $this->report_error($sql, $params); - return false; - } - if ($returning !== "") { $row = pg_fetch_assoc($result); $params['id'] = reset($row); @@ -775,7 +728,8 @@ class pgsql_native_moodle_database extends moodle_database { * @param string $table The database table to be inserted into * @param object $data A data object with values for one or more fields in the record * @param bool $returnid Should the id of the newly created record entry be returned? If this option is not requested then true/false is returned. - * @return mixed success or new ID + * @return true or new id + * @throws dml_exception if error */ public function insert_record($table, $dataobject, $returnid=true, $bulk=false) { if (!is_object($dataobject)) { @@ -814,17 +768,11 @@ class pgsql_native_moodle_database extends moodle_database { $cleaned[$field] = $value; } - if (empty($cleaned)) { - return false; - } - if (empty($blobs)) { return $this->insert_record_raw($table, $cleaned, $returnid, $bulk); } - if (!$id = $this->insert_record_raw($table, $cleaned, true, $bulk)) { - return false; - } + $id = $this->insert_record_raw($table, $cleaned, true, $bulk); foreach ($blobs as $key=>$value) { $value = pg_escape_bytea($this->pgsql, $value); @@ -847,15 +795,12 @@ class pgsql_native_moodle_database extends moodle_database { * * @param string $table name of database table to be inserted into * @param object $dataobject A data object with values for one or more fields in the record - * @return bool success + * @return bool true + * @throws dml_exception if error */ public function import_record($table, $dataobject) { $dataobject = (object)$dataobject; - if (empty($dataobject->id)) { - return false; - } - $columns = $this->get_columns($table); $cleaned = array(); @@ -874,20 +819,21 @@ class pgsql_native_moodle_database extends moodle_database { * @param string $table name * @param mixed $params data record as object or array * @param bool true means repeated updates expected - * @return bool success + * @return bool true + * @throws dml_exception if error */ public function update_record_raw($table, $params, $bulk=false) { if (!is_array($params)) { $params = (array)$params; } if (!isset($params['id'])) { - return false; + throw new coding_exception('moodle_database::update_record_raw() id field must be specified.'); } $id = $params['id']; unset($params['id']); if (empty($params)) { - return false; + throw new coding_exception('moodle_database::update_record_raw() no fields found.'); } $i = 1; @@ -906,11 +852,6 @@ class pgsql_native_moodle_database extends moodle_database { $result = pg_query_params($this->pgsql, $sql, $params); $this->query_end($result); - if ($result === false) { - $this->report_error($sql, $params); - return false; - } - pg_free_result($result); return true; } @@ -925,19 +866,14 @@ class pgsql_native_moodle_database extends moodle_database { * @param string $table The database table to be checked against. * @param object $dataobject An object with contents equal to fieldname=>fieldvalue. Must have an entry for 'id' to map to the table specified. * @param bool true means repeated updates expected - * @return bool success + * @return bool true + * @throws dml_exception if error */ public function update_record($table, $dataobject, $bulk=false) { if (!is_object($dataobject)) { $dataobject = (object)$dataobject; } - if (!isset($dataobject->id) ) { - return false; - } - - $id = (int)$dataobject->id; - $columns = $this->get_columns($table); $cleaned = array(); $blobs = array(); @@ -968,23 +904,21 @@ class pgsql_native_moodle_database extends moodle_database { $cleaned[$field] = $value; } - if (!$this->update_record_raw($table, $cleaned, $bulk)) { - return false; - } + $this->update_record_raw($table, $cleaned, $bulk); if (empty($blobs)) { return true; } + $id = (int)$dataobject->id; + foreach ($blobs as $key=>$value) { $value = pg_escape_bytea($this->pgsql, $value); $sql = "UPDATE {$this->prefix}$table SET $key = '$value'::bytea WHERE id = $id"; $this->query_start($sql, NULL, SQL_QUERY_UPDATE); $result = pg_query($this->pgsql, $sql); $this->query_end($result); - if ($result === false) { - return false; - } + pg_free_result($result); } @@ -999,7 +933,8 @@ class pgsql_native_moodle_database extends moodle_database { * @param string $newvalue the value to set the field to. * @param string $select A fragment of SQL to be used in a where clause in the SQL call. * @param array $params array of sql parameters - * @return bool success + * @return bool true + * @throws dml_exception if error */ public function set_field_select($table, $newfield, $newvalue, $select, array $params=null) { if ($select) { @@ -1026,10 +961,6 @@ class pgsql_native_moodle_database extends moodle_database { $result = pg_query_params($this->pgsql, $sql, $params); $this->query_end($result); - if ($result === false) { - $this->report_error($sql, $params); - return false; - } pg_free_result($result); return true; @@ -1041,7 +972,8 @@ class pgsql_native_moodle_database extends moodle_database { * @param string $table The database table to be checked against. * @param string $select A fragment of SQL to be used in a where clause in the SQL call (used to define the selection criteria). * @param array $params array of sql parameters - * @return returns success. + * @return bool true + * @throws dml_exception if error */ public function delete_records_select($table, $select, array $params=null) { if ($select) { @@ -1055,10 +987,6 @@ class pgsql_native_moodle_database extends moodle_database { $result = pg_query_params($this->pgsql, $sql, $params); $this->query_end($result); - if ($result === false) { - $this->report_error($sql, $params); - return false; - } pg_free_result($result); return true; @@ -1121,9 +1049,6 @@ class pgsql_native_moodle_database extends moodle_database { $result = pg_query($this->pgsql, $sql); $this->query_end($result); - if ($result === false) { - return false; - } pg_free_result($result); return true; } @@ -1137,9 +1062,6 @@ class pgsql_native_moodle_database extends moodle_database { $result = pg_query($this->pgsql, $sql); $this->query_end($result); - if ($result === false) { - return false; - } pg_free_result($result); return true; } @@ -1153,9 +1075,6 @@ class pgsql_native_moodle_database extends moodle_database { $result = pg_query($this->pgsql, $sql); $this->query_end($result); - if ($result === false) { - return false; - } pg_free_result($result); return true; } diff --git a/lib/dml/postgres7_adodb_moodle_database.php b/lib/dml/postgres7_adodb_moodle_database.php index 2e2a17ec5e..2b983948c1 100644 --- a/lib/dml/postgres7_adodb_moodle_database.php +++ b/lib/dml/postgres7_adodb_moodle_database.php @@ -37,7 +37,11 @@ class postgres7_adodb_moodle_database extends adodb_moodle_database { protected function configure_dbconnection() { $this->adodb->SetFetchMode(ADODB_FETCH_ASSOC); - $this->adodb->Execute("SET NAMES 'utf8'"); + + $sql = "SET NAMES 'utf8'"; + $this->query_start($sql, null, SQL_QUERY_AUX); + $result = $this->adodb->Execute($sql); + $this->query_end($result); return true; } @@ -110,8 +114,11 @@ class postgres7_adodb_moodle_database extends adodb_moodle_database { return $this->columns[$table]; } - $this->reads++; - if (!$columns = $this->adodb->MetaColumns($this->prefix.$table)) { + $this->query_start("--adodb-MetaColumns", null, SQL_QUERY_AUX); + $columns = $this->adodb->MetaColumns($this->prefix.$table); + $this->query_end(true); + + if (!$columns) { return array(); } @@ -145,8 +152,11 @@ class postgres7_adodb_moodle_database extends adodb_moodle_database { */ function setup_is_unicodedb() { /// Get PostgreSQL server_encoding value - $this->reads++; - $rs = $this->adodb->Execute("SHOW server_encoding"); + $sql = "SHOW server_encoding"; + $this->query_start($sql, null, SQL_QUERY_AUX); + $rs = $this->adodb->Execute($sql); + $this->query_end($rs); + if ($rs && !$rs->EOF) { $encoding = $rs->fields['server_encoding']; if (strtoupper($encoding) == 'UNICODE' || strtoupper($encoding) == 'UTF8') { @@ -164,7 +174,8 @@ class postgres7_adodb_moodle_database extends adodb_moodle_database { * @param bool $returnit return it of inserted record * @param bool $bulk true means repeated inserts expected * @param bool $customsequence true if 'id' included in $params, disables $returnid - * @return mixed success or new id + * @return true or new id + * @throws dml_exception if error */ public function insert_record_raw($table, $params, $returnid=true, $bulk=false, $customsequence=false) { if (!is_array($params)) { @@ -173,29 +184,30 @@ class postgres7_adodb_moodle_database extends adodb_moodle_database { if ($customsequence) { if (!isset($params['id'])) { - return false; + throw new coding_exception('moodle_database::insert_record_raw() id field must be specified if custom sequences used.'); } $returnid = false; } else { + unset($params['id']); /// Postgres doesn't have the concept of primary key built in /// and will return the OID which isn't what we want. /// The efficient and transaction-safe strategy is to /// move the sequence forward first, and make the insert /// with an explicit id. if ($returnid) { - $this->reads++; $seqname = "{$this->prefix}{$table}_id_seq"; - if ($nextval = $this->adodb->GenID($seqname)) { + $this->query_start('--adodb-GenID', null, SQL_QUERY_AUX); + $nextval = $this->adodb->GenID($seqname); + $this->query_end(true); + if ($nextval) { $params['id'] = (int)$nextval; } - } else { - unset($params['id']); } } if (empty($params)) { - return false; + throw new coding_exception('moodle_database::insert_record_raw() no fields found.'); } $fields = implode(',', array_keys($params)); @@ -203,13 +215,10 @@ class postgres7_adodb_moodle_database extends adodb_moodle_database { $qms = implode(',', $qms); $sql = "INSERT INTO {$this->prefix}$table ($fields) VALUES($qms)"; + $this->query_start($sql, $params, SQL_QUERY_INSERT); + $rs = $this->adodb->Execute($sql, $params); + $this->query_end($rs); - $this->writes++; - - if (!$rs = $this->adodb->Execute($sql, $params)) { - $this->report_error($sql, $params); - return false; - } if (!$returnid) { return true; } @@ -219,17 +228,17 @@ class postgres7_adodb_moodle_database extends adodb_moodle_database { $oid = $this->adodb->Insert_ID(); - $this->reads++; - // try to get the primary key based on id $sql = "SELECT id FROM {$this->prefix}$table WHERE oid = $oid"; - if ( ($rs = $this->adodb->Execute($sql)) - && ($rs->RecordCount() == 1) ) { + $this->query_start($sql, $params, SQL_QUERY_AUX); + $rs = $this->adodb->Execute($sql, $params); + $this->query_end($rs); + + if ( $rs && ($rs->RecordCount() == 1) ) { trigger_error("Retrieved id using oid on table $table because we could not find the sequence."); return (integer)reset($rs->fields); } - trigger_error("Failed to retrieve primary key after insert: $sql"); - return false; + throw new dml_write_exception('unknown error fetching inserted id'); } /** @@ -241,7 +250,8 @@ class postgres7_adodb_moodle_database extends adodb_moodle_database { * @param object $data A data object with values for one or more fields in the record * @param bool $returnid Should the id of the newly created record entry be returned? If this option is not requested then true/false is returned. * @param bool $bulk true means repeated inserts expected - * @return mixed success or new ID + * @return true or new id + * @throws dml_exception if error */ public function insert_record($table, $dataobject, $returnid=true, $bulk=false) { //TODO: add support for blobs BYTEA @@ -280,23 +290,16 @@ class postgres7_adodb_moodle_database extends adodb_moodle_database { $cleaned[$field] = $value; } - if (empty($cleaned)) { - return false; - } - if (empty($blobs)) { return $this->insert_record_raw($table, $cleaned, $returnid, $bulk); } - if (!$id = $this->insert_record_raw($table, $cleaned, true, $bulk)) { - return false; - } + $id = $this->insert_record_raw($table, $cleaned, true, $bulk); foreach ($blobs as $key=>$value) { - $this->writes++; - if (!$this->adodb->UpdateBlob($this->prefix.$table, $key, $value, "id = $id", 'BLOB')) { // adodb does not use bound parameters for blob updates :-( - return false; - } + $this->query_start('--adodb-UpdateBlob', null, SQL_QUERY_UPDATE); + $result = $this->adodb->UpdateBlob($this->prefix.$table, $key, $value, "id = $id", 'BLOB');// adodb does not use bound parameters for blob updates :-( + $this->query_end($result); } return ($returnid ? $id : true); @@ -312,7 +315,8 @@ class postgres7_adodb_moodle_database extends adodb_moodle_database { * @param string $table The database table to be checked against. * @param object $dataobject An object with contents equal to fieldname=>fieldvalue. Must have an entry for 'id' to map to the table specified. * @param bool true means repeated updates expected - * @return bool success + * @return bool true + * @throws dml_exception if error */ public function update_record($table, $dataobject, $bulk=false) { //TODO: add support for blobs BYTEA @@ -320,11 +324,6 @@ class postgres7_adodb_moodle_database extends adodb_moodle_database { $dataobject = (object)$dataobject; } - if (!isset($dataobject->id) ) { - return false; - } - $id = $dataobject->id; - $columns = $this->get_columns($table); $cleaned = array(); $blobs = array(); @@ -354,19 +353,18 @@ class postgres7_adodb_moodle_database extends adodb_moodle_database { $cleaned[$field] = $value; } - if (!$this->update_record_raw($table, $cleaned, $bulk)) { - return false; - } + $this->update_record_raw($table, $cleaned, $bulk); if (empty($blobs)) { return true; } + $id = $dataobject->id; + foreach ($blobs as $key=>$value) { - $this->writes++; - if (!$this->adodb->UpdateBlob($this->prefix.$table, $key, $value, "id = $id", 'BLOB')) { // adodb does not use bound parameters for blob updates :-( - return false; - } + $this->query_start('--adodb-UpdateBlob', null, SQL_QUERY_UPDATE); + $result = $this->adodb->UpdateBlob($this->prefix.$table, $key, $value, "id = $id", 'BLOB');// adodb does not use bound parameters for blob updates :-( + $this->query_end($result); } return true; @@ -380,7 +378,8 @@ class postgres7_adodb_moodle_database extends adodb_moodle_database { * @param string $newvalue the value to set the field to. * @param string $select A fragment of SQL to be used in a where clause in the SQL call. * @param array $params array of sql parameters - * @return bool success + * @return bool true + * @throws dml_exception if error */ public function set_field_select($table, $newfield, $newvalue, $select, array $params=null) { $params = (array)$params; @@ -392,10 +391,9 @@ class postgres7_adodb_moodle_database extends adodb_moodle_database { if ($column->meta_type == 'B') { /// update blobs and return $select = $this->emulate_bound_params($select, $params); // adodb does not use bound parameters for blob updates :-( - $this->writes++; - if (!$this->adodb->UpdateBlob($this->prefix.$table, $newfield, $newvalue, $select, 'BLOB')) { - return false; - } + $this->query_start('--adodb-UpdateBlob', null, SQL_QUERY_UPDATE); + $result = $this->adodb->UpdateBlob($this->prefix.$table, $newfield, $newvalue, $select, 'BLOB'); + $this->query_end($result); return true; } @@ -419,13 +417,9 @@ class postgres7_adodb_moodle_database extends adodb_moodle_database { array_unshift($params, $newvalue); // add as first param } $sql = "UPDATE {$this->prefix}$table SET $newfield $select"; - - $this->writes++; - - if (!$rs = $this->adodb->Execute($sql, $params)) { - $this->report_error($sql, $params); - return false; - } + $this->query_start($sql, $params, SQL_QUERY_UPDATE); + $rs = $this->adodb->Execute($sql, $params); + $this->query_end($rs); return true; } @@ -475,7 +469,8 @@ class postgres7_adodb_moodle_database extends adodb_moodle_database { /** * Reset a sequence to the id field of a table. * @param string $table name of table - * @return bool success + * @return bool true + * @throws dml_exception if error */ public function reset_sequence($table) { // From http://www.postgresql.org/docs/7.4/static/sql-altersequence.html @@ -492,7 +487,8 @@ class postgres7_adodb_moodle_database extends adodb_moodle_database { * Basic safety checks only. Lobs are supported. * @param string $table name of database table to be inserted into * @param mixed $dataobject object or array with fields in the record - * @return bool success + * @return bool true + * @throws dml_exception if error */ public function import_record($table, $dataobject) { $dataobject = (object)$dataobject; @@ -516,9 +512,7 @@ class postgres7_adodb_moodle_database extends adodb_moodle_database { $cleaned[$field] = $value; } - if (!$this->insert_record_raw($table, $cleaned, false, true, true)) { - return false; - } + $this->insert_record_raw($table, $cleaned, false, true, true); if (empty($blobs)) { return true; @@ -527,10 +521,9 @@ class postgres7_adodb_moodle_database extends adodb_moodle_database { /// We have BLOBs to postprocess foreach ($blobs as $key=>$value) { - $this->writes++; - if (!$this->adodb->UpdateBlob($this->prefix.$table, $key, $value, "id = $id", 'BLOB')) { // adodb does not use bound parameters for blob updates :-( - return false; - } + $this->query_start('--adodb-UpdateBlob', null, SQL_QUERY_UPDATE); + $result = $this->adodb->UpdateBlob($this->prefix.$table, $key, $value, "id = $id", 'BLOB'); + $this->query_end($result); } return true; diff --git a/lib/dml/simpletest/testdml.php b/lib/dml/simpletest/testdml.php index 0d45773cb1..fd181e008a 100755 --- a/lib/dml/simpletest/testdml.php +++ b/lib/dml/simpletest/testdml.php @@ -451,6 +451,7 @@ class dml_test extends UnitTestCase { $data = array(array('id' => 1, 'course' => 3, 'name' => 'record1'), array('id' => 2, 'course' => 3, 'name' => 'record2'), array('id' => 3, 'course' => 5, 'name' => 'record3')); + foreach ($data as $record) { $DB->insert_record('testtable', $record); } @@ -482,9 +483,9 @@ class dml_test extends UnitTestCase { $dbman->create_table($table); $this->tables[$table->getName()] = $table; - $data = array(array('id' => 1, 'course' => 3, 'name' => 'record1'), - array('id' => 2, 'course' => 3, 'name' => 'record2'), - array('id' => 3, 'course' => 5, 'name' => 'record3')); + $data = array(array('id'=> 1, 'course' => 3, 'name' => 'record1'), + array('id'=> 2, 'course' => 3, 'name' => 'record2'), + array('id'=> 3, 'course' => 5, 'name' => 'record3')); foreach ($data as $record) { $DB->insert_record('testtable', $record); }