Moodle  2.2.1
http://www.collinsharper.com
C:/xampp/htdocs/moodle/lib/dml/pdo_moodle_database.php
Go to the documentation of this file.
00001 <?php
00002 
00003 // This file is part of Moodle - http://moodle.org/
00004 //
00005 // Moodle is free software: you can redistribute it and/or modify
00006 // it under the terms of the GNU General Public License as published by
00007 // the Free Software Foundation, either version 3 of the License, or
00008 // (at your option) any later version.
00009 //
00010 // Moodle is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 // GNU General Public License for more details.
00014 //
00015 // You should have received a copy of the GNU General Public License
00016 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
00017 
00018 
00028 defined('MOODLE_INTERNAL') || die();
00029 
00030 require_once($CFG->libdir.'/dml/moodle_database.php');
00031 require_once($CFG->libdir.'/dml/pdo_moodle_recordset.php');
00032 
00036 abstract class pdo_moodle_database extends moodle_database {
00037 
00038     protected $pdb;
00039     protected $lastError = null;
00040 
00046     public function __construct($external=false) {
00047         parent::__construct($external);
00048     }
00049 
00061     public function connect($dbhost, $dbuser, $dbpass, $dbname, $prefix, array $dboptions=null) {
00062         $driverstatus = $this->driver_installed();
00063 
00064         if ($driverstatus !== true) {
00065             throw new dml_exception('dbdriverproblem', $driverstatus);
00066         }
00067 
00068         $this->store_settings($dbhost, $dbuser, $dbpass, $dbname, $prefix, $dboptions);
00069 
00070         try{
00071             $this->pdb = new PDO($this->get_dsn(), $this->dbuser, $this->dbpass, $this->get_pdooptions());
00072             // generic PDO settings to match adodb's default; subclasses can change this in configure_dbconnection
00073             $this->pdb->setAttribute(PDO::ATTR_CASE, PDO::CASE_LOWER);
00074             $this->pdb->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
00075             $this->configure_dbconnection();
00076             return true;
00077         } catch (PDOException $ex) {
00078             throw new dml_connection_exception($ex->getMessage());
00079             return false;
00080         }
00081     }
00082 
00088     abstract protected function get_dsn();
00089 
00095     protected function get_pdooptions() {
00096         return array(PDO::ATTR_PERSISTENT => !empty($this->dboptions['dbpersist']));
00097     }
00098 
00099     protected function configure_dbconnection() {
00101     }
00102 
00108     protected function get_dblibrary() {
00109         return 'pdo';
00110     }
00111 
00117     public function get_name() {
00118         return get_string('pdo'.$this->get_dbtype(), 'install');
00119     }
00120 
00126     public function get_configuration_help() {
00127         return get_string('pdo'.$this->get_dbtype().'help', 'install');
00128     }
00129 
00135     public function get_configuration_hints() {
00136         return get_string('databasesettingssub_' . $this->get_dbtype() . '_pdo', 'install');
00137     }
00138 
00143     public function get_server_info() {
00144         $result = array();
00145         try {
00146             $result['description'] = $this->pdb->getAttribute(PDO::ATTR_SERVER_INFO);
00147         } catch(PDOException $ex) {}
00148         try {
00149             $result['version'] = $this->pdb->getAttribute(PDO::ATTR_SERVER_VERSION);
00150         } catch(PDOException $ex) {}
00151         return $result;
00152     }
00153 
00158     protected function allowed_param_types() {
00159         return SQL_PARAMS_QM | SQL_PARAMS_NAMED;
00160     }
00161 
00166     public function get_last_error() {
00167         return $this->lastError;
00168     }
00169 
00173     protected function debug_query($sql, $params = null) {
00174         echo '<hr /> (', $this->get_dbtype(), '): ',  htmlentities($sql);
00175         if($params) {
00176             echo ' (parameters ';
00177             print_r($params);
00178             echo ')';
00179         }
00180         echo '<hr />';
00181     }
00182 
00188     public function change_database_structure($sql) {
00189         $result = true;
00190         $this->query_start($sql, null, SQL_QUERY_STRUCTURE);
00191 
00192         try {
00193             $this->pdb->exec($sql);
00194             $this->reset_caches();
00195         } catch (PDOException $ex) {
00196             $this->lastError = $ex->getMessage();
00197             $result = false;
00198         }
00199         $this->query_end($result);
00200         return $result;
00201     }
00202 
00203     public function delete_records_select($table, $select, array $params=null) {
00204         $sql = "DELETE FROM {{$table}}";
00205         if ($select) {
00206             $sql .= " WHERE $select";
00207         }
00208         return $this->execute($sql, $params);
00209     }
00210 
00218     protected function create_recordset($sth) {
00219         return new pdo_moodle_recordset($sth);
00220     }
00221 
00229     public function execute($sql, array $params=null) {
00230         list($sql, $params, $type) = $this->fix_sql_params($sql, $params);
00231 
00232         $result = true;
00233         $this->query_start($sql, $params, SQL_QUERY_UPDATE);
00234 
00235         try {
00236             $sth = $this->pdb->prepare($sql);
00237             $sth->execute($params);
00238         } catch (PDOException $ex) {
00239             $this->lastError = $ex->getMessage();
00240             $result = false;
00241         }
00242 
00243         $this->query_end($result);
00244         return $result;
00245     }
00246 
00261     public function get_recordset_sql($sql, array $params=null, $limitfrom=0, $limitnum=0) {
00262 
00263         $result = true;
00264 
00265         list($sql, $params, $type) = $this->fix_sql_params($sql, $params);
00266         $sql = $this->get_limit_clauses($sql, $limitfrom, $limitnum);
00267         $this->query_start($sql, $params, SQL_QUERY_SELECT);
00268 
00269         try {
00270             $sth = $this->pdb->prepare($sql);
00271             $sth->execute($params);
00272             $result = $this->create_recordset($sth);
00273         } catch (PDOException $ex) {
00274             $this->lastError = $ex->getMessage();
00275             $result = false;
00276         }
00277 
00278         $this->query_end($result);
00279         return $result;
00280     }
00281 
00289     public function get_fieldset_sql($sql, array $params=null) {
00290         $rs = $this->get_recordset_sql($sql, $params);
00291         if (!$rs->valid()) {
00292             $rs->close(); // Not going to iterate (but exit), close rs
00293             return false;
00294         }
00295         $result = array();
00296         foreach($rs as $value) {
00297             $result[] = reset($value);
00298         }
00299         $rs->close();
00300         return $result;
00301     }
00302 
00316     public function get_records_sql($sql, array $params=null, $limitfrom=0, $limitnum=0) {
00317         $rs = $this->get_recordset_sql($sql, $params, $limitfrom, $limitnum);
00318         if (!$rs->valid()) {
00319             $rs->close(); // Not going to iterate (but exit), close rs
00320             return false;
00321         }
00322         $objects = array();
00323         $debugging = debugging('', DEBUG_DEVELOPER);
00324         foreach($rs as $value) {
00325             $key = reset($value);
00326             if ($debugging && array_key_exists($key, $objects)) {
00327                 debugging("Did you remember to make the first column something unique in your call to get_records? Duplicate value '$key' found in column first column of '$sql'.", DEBUG_DEVELOPER);
00328             }
00329             $objects[$key] = (object)$value;
00330         }
00331         $rs->close();
00332         return $objects;
00333     }
00334 
00344     public function insert_record_raw($table, $params, $returnid=true, $bulk=false, $customsequence=false) {
00345         if (!is_array($params)) {
00346             $params = (array)$params;
00347         }
00348 
00349         if ($customsequence) {
00350             if (!isset($params['id'])) {
00351                 throw new coding_exception('moodle_database::insert_record_raw() id field must be specified if custom sequences used.');
00352             }
00353             $returnid = false;
00354         } else {
00355             unset($params['id']);
00356         }
00357 
00358         if (empty($params)) {
00359             throw new coding_exception('moodle_database::insert_record_raw() no fields found.');
00360         }
00361 
00362         $fields = implode(',', array_keys($params));
00363         $qms    = array_fill(0, count($params), '?');
00364         $qms    = implode(',', $qms);
00365 
00366         $sql = "INSERT INTO {{$table}} ($fields) VALUES($qms)";
00367         if (!$this->execute($sql, $params)) {
00368             return false;
00369         }
00370         if (!$returnid) {
00371             return true;
00372         }
00373         if ($id = $this->pdb->lastInsertId()) {
00374             return (int)$id;
00375         }
00376         return false;
00377     }
00378 
00390     public function insert_record($table, $dataobject, $returnid=true, $bulk=false) {
00391         $dataobject = (array)$dataobject;
00392 
00393         $columns = $this->get_columns($table);
00394         $cleaned = array();
00395 
00396         foreach ($dataobject as $field=>$value) {
00397             if ($field === 'id') {
00398                 continue;
00399             }
00400             if (!isset($columns[$field])) {
00401                 continue;
00402             }
00403             $column = $columns[$field];
00404             if (is_bool($value)) {
00405                 $value = (int)$value; // prevent "false" problems
00406             }
00407             if (!empty($column->enums)) {
00408                 // workaround for problem with wrong enums
00409                 if (is_null($value) and !$column->not_null) {
00410                     // ok - nulls allowed
00411                 } else {
00412                     if (!in_array((string)$value, $column->enums)) {
00413                         debugging('Enum value '.s($value).' not allowed in field '.$field.' table '.$table.'.');
00414                         return false;
00415                     }
00416                 }
00417             }
00418             $cleaned[$field] = $value;
00419         }
00420 
00421         if (empty($cleaned)) {
00422             return false;
00423         }
00424 
00425         return $this->insert_record_raw($table, $cleaned, $returnid, $bulk);
00426     }
00427 
00435     public function update_record_raw($table, $params, $bulk=false) {
00436         $params = (array)$params;
00437 
00438         if (!isset($params['id'])) {
00439             throw new coding_exception('moodle_database::update_record_raw() id field must be specified.');
00440         }
00441         $id = $params['id'];
00442         unset($params['id']);
00443 
00444         if (empty($params)) {
00445             throw new coding_exception('moodle_database::update_record_raw() no fields found.');
00446         }
00447 
00448         $sets = array();
00449         foreach ($params as $field=>$value) {
00450             $sets[] = "$field = ?";
00451         }
00452 
00453         $params[] = $id; // last ? in WHERE condition
00454 
00455         $sets = implode(',', $sets);
00456         $sql = "UPDATE {{$table}} SET $sets WHERE id=?";
00457         return $this->execute($sql, $params);
00458     }
00459 
00472     public function update_record($table, $dataobject, $bulk=false) {
00473         $dataobject = (array)$dataobject;
00474 
00475         $columns = $this->get_columns($table);
00476         $cleaned = array();
00477 
00478         foreach ($dataobject as $field=>$value) {
00479             if (!isset($columns[$field])) {
00480                 continue;
00481             }
00482             if (is_bool($value)) {
00483                 $value = (int)$value; // prevent "false" problems
00484             }
00485             $cleaned[$field] = $value;
00486         }
00487 
00488         return $this->update_record_raw($table, $cleaned, $bulk);
00489     }
00490 
00501     public function set_field_select($table, $newfield, $newvalue, $select, array $params=null) {
00502         if ($select) {
00503             $select = "WHERE $select";
00504         }
00505         if (is_null($params)) {
00506             $params = array();
00507         }
00508         list($select, $params, $type) = $this->fix_sql_params($select, $params);
00509 
00510         if (is_bool($newvalue)) {
00511             $newvalue = (int)$newvalue; // prevent "false" problems
00512         }
00513         if (is_null($newvalue)) {
00514             $newfield = "$newfield = NULL";
00515         } else {
00516             // make sure SET and WHERE clauses use the same type of parameters,
00517             // because we don't support different types in the same query
00518             switch($type) {
00519             case SQL_PARAMS_NAMED:
00520                 $newfield = "$newfield = :newvalueforupdate";
00521                 $params['newvalueforupdate'] = $newvalue;
00522                 break;
00523             case SQL_PARAMS_QM:
00524                 $newfield = "$newfield = ?";
00525                 array_unshift($params, $newvalue);
00526                 break;
00527             default:
00528                 $this->lastError = __FILE__ . ' LINE: ' . __LINE__ . '.';
00529                 print_error(unknowparamtype, 'error', '', $this->lastError);
00530             }
00531         }
00532         $sql = "UPDATE {{$table}} SET $newfield $select";
00533         return $this->execute($sql, $params);
00534     }
00535 
00536     public function sql_concat() {
00537         print_error('TODO');
00538     }
00539 
00540     public function sql_concat_join($separator="' '", $elements=array()) {
00541         print_error('TODO');
00542     }
00543 
00544     protected function begin_transaction() {
00545         $this->query_start('', NULL, SQL_QUERY_AUX);
00546         try {
00547             $this->pdb->beginTransaction();
00548         } catch(PDOException $ex) {
00549             $this->lastError = $ex->getMessage();
00550         }
00551         $this->query_end($result);
00552     }
00553 
00554     protected function commit_transaction() {
00555         $this->query_start('', NULL, SQL_QUERY_AUX);
00556 
00557         try {
00558             $this->pdb->commit();
00559         } catch(PDOException $ex) {
00560             $this->lastError = $ex->getMessage();
00561         }
00562         $this->query_end($result);
00563     }
00564 
00565     protected function rollback_transaction() {
00566         $this->query_start('', NULL, SQL_QUERY_AUX);
00567 
00568         try {
00569             $this->pdb->rollBack();
00570         } catch(PDOException $ex) {
00571             $this->lastError = $ex->getMessage();
00572         }
00573         $this->query_end($result);
00574     }
00575 
00583     public function import_record($table, $dataobject) {
00584         $dataobject = (object)$dataobject;
00585 
00586         $columns = $this->get_columns($table);
00587         $cleaned = array();
00588         foreach ($dataobject as $field=>$value) {
00589             if (!isset($columns[$field])) {
00590                 continue;
00591             }
00592             $cleaned[$field] = $value;
00593         }
00594 
00595         return $this->insert_record_raw($table, $cleaned, false, true, true);
00596     }
00597 
00609     protected function query_start($sql, array $params=null, $type, $extrainfo=null) {
00610         $this->lastError = null;
00611         parent::query_start($sql, $params, $type, $extrainfo);
00612     }
00613 }
 All Data Structures Namespaces Files Functions Variables Enumerations