Commit | Line | Data |
---|---|---|
11e1f828 MH |
1 | <?php |
2 | ||
49926145 | 3 | // This file is part of Moodle - http://moodle.org/ |
4 | // | |
11e1f828 MH |
5 | // Moodle is free software: you can redistribute it and/or modify |
6 | // it under the terms of the GNU General Public License as published by | |
7 | // the Free Software Foundation, either version 3 of the License, or | |
8 | // (at your option) any later version. | |
9 | // | |
10 | // Moodle is distributed in the hope that it will be useful, | |
11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 | // GNU General Public License for more details. | |
49926145 | 14 | // |
11e1f828 MH |
15 | // You should have received a copy of the GNU General Public License |
16 | // along with Moodle. If not, see <http://www.gnu.org/licenses/>. | |
7e13be08 | 17 | |
49926145 | 18 | |
11e1f828 MH |
19 | /** |
20 | * This library contains all the Data Manipulation Language (DML) functions | |
21 | * used to interact with the DB | |
22 | * | |
23 | * This library contains all the Data Manipulation Language (DML) functions | |
24 | * used to interact with the DB. All the dunctions in this library must be | |
25 | * generic and work against the major number of RDBMS possible. This is the | |
26 | * list of currently supported and tested DBs: mysql, postresql, mssql, oracle | |
27 | ||
28 | * This library is automatically included by Moodle core so you never need to | |
29 | * include it yourself. | |
30 | ||
31 | * For more info about the functions available in this library, please visit: | |
32 | * http://docs.moodle.org/en/DML_functions | |
33 | * (feel free to modify, improve and document such page, thanks!) | |
49926145 | 34 | * |
35 | * @package moodlecore | |
36 | * @subpackage DML | |
37 | * @copyright 2008 Petr Skoda (http://skodak.org) | |
38 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
11e1f828 MH |
39 | */ |
40 | ||
49926145 | 41 | // Require the essential |
8aff8482 | 42 | require_once($CFG->libdir.'/dml/moodle_database.php'); |
43 | ||
e6c6531c | 44 | /** Return false if record not found, show debug warning if multiple records found */ |
45 | define('IGNORE_MISSING', 0); | |
46 | /** Similar to IGNORE_MISSING but does not show debug warning if multiple records found, not recommended to be used */ | |
47 | define('IGNORE_MULTIPLE', 1); | |
48 | /** Indicates exactly one record must exist */ | |
af12ea93 | 49 | define('MUST_EXIST', 2); |
50 | ||
49459eb0 | 51 | /** |
52 | * DML exception class, use instead of error() in dml code. | |
53 | */ | |
54 | class dml_exception extends moodle_exception { | |
11e1f828 MH |
55 | /** |
56 | * @param string $errorcode | |
57 | * @param string $a | |
58 | * @param string $debuginfo | |
59 | */ | |
49459eb0 | 60 | function __construct($errorcode, $a=NULL, $debuginfo=null) { |
61 | parent::__construct($errorcode, '', '', $a, $debuginfo); | |
62 | } | |
63 | } | |
64 | ||
ce152606 | 65 | /** |
66 | * DML db connection exception - triggered if database not accessible. | |
67 | */ | |
68 | class dml_connection_exception extends dml_exception { | |
11e1f828 | 69 | /** |
af12ea93 | 70 | * Constructor |
11e1f828 MH |
71 | * @param string $error |
72 | */ | |
ce152606 | 73 | function __construct($error) { |
c5d18164 | 74 | $errorinfo = $error; |
ce152606 | 75 | parent::__construct('dbconnectionfailed', NULL, $errorinfo); |
76 | } | |
77 | } | |
78 | ||
9214025e | 79 | /** |
80 | * DML read exception - triggered by SQL syntax errors, missing tables, etc. | |
81 | */ | |
82 | class dml_read_exception extends dml_exception { | |
11e1f828 | 83 | /** @var string */ |
9214025e | 84 | public $error; |
af12ea93 | 85 | /** @var string */ |
9214025e | 86 | public $sql; |
11e1f828 | 87 | /** @var array */ |
9214025e | 88 | public $params; |
117bd748 | 89 | |
11e1f828 | 90 | /** |
af12ea93 | 91 | * Constructor |
11e1f828 MH |
92 | * @param string $error |
93 | * @param string $sql | |
94 | * @param array $params | |
95 | */ | |
9214025e | 96 | function __construct($error, $sql=null, array $params=null) { |
97 | $this->error = $error; | |
98 | $this->sql = $sql; | |
99 | $this->params = $params; | |
c5d18164 | 100 | $errorinfo = $error."\n".$sql."\n[".var_export($params, true).']'; |
9214025e | 101 | parent::__construct('dmlreadexception', NULL, $errorinfo); |
102 | } | |
103 | } | |
104 | ||
105 | /** | |
af12ea93 | 106 | * Caused by multiple records found in get_record() call. |
107 | */ | |
108 | class dml_multiple_records_exception extends dml_exception { | |
109 | /** @var string */ | |
110 | public $sql; | |
111 | /** @var array */ | |
112 | public $params; | |
117bd748 | 113 | |
af12ea93 | 114 | /** |
115 | * Constructor | |
116 | * @param string $table table name if known, '' if unknown | |
117 | * @param string $sql | |
118 | * @param array $params | |
119 | */ | |
120 | function __construct($sql='', array $params=null) { | |
c5d18164 | 121 | $errorinfo = $sql."\n[".var_export($params, true).']'; |
af12ea93 | 122 | parent::__construct('multiplerecordsfound', null, $errorinfo); |
123 | } | |
124 | } | |
125 | ||
126 | /** | |
127 | * Caused by missing record that is required for normal operation. | |
128 | */ | |
129 | class dml_missing_record_exception extends dml_exception { | |
130 | /** @var string */ | |
131 | public $table; | |
132 | /** @var string */ | |
133 | public $sql; | |
134 | /** @var array */ | |
135 | public $params; | |
117bd748 | 136 | |
af12ea93 | 137 | /** |
138 | * Constructor | |
139 | * @param string $table table name if known, '' if unknown | |
140 | * @param string $sql | |
141 | * @param array $params | |
142 | */ | |
143 | function __construct($tablename, $sql='', array $params=null) { | |
144 | if (empty($tablename)) { | |
145 | $tablename = null; | |
146 | } | |
147 | $this->tablename = $tablename; | |
148 | $this->sql = $sql; | |
149 | $this->params = $params; | |
117bd748 | 150 | |
af12ea93 | 151 | switch ($tablename) { |
152 | case null: | |
153 | $errcode = 'invalidrecordunknown'; | |
154 | break; | |
155 | case 'course': | |
156 | $errocode = empty($sql) ? 'invalidcourseid' : 'invalidrecord'; | |
157 | break; | |
158 | case 'course_module': | |
159 | $errocode = 'invalidcoursemodule'; | |
160 | break; | |
161 | case 'user': | |
162 | $errcode = 'invaliduser'; | |
163 | break; | |
164 | default: | |
165 | $errcode = 'invalidrecord'; | |
166 | break; | |
167 | } | |
c5d18164 | 168 | $errorinfo = $sql."\n[".var_export($params, true).']'; |
af12ea93 | 169 | parent::__construct($errcode, $tablename, $errorinfo); |
170 | } | |
171 | } | |
172 | ||
173 | /** | |
174 | * DML write exception - triggered by SQL syntax errors, missing tables, etc. | |
9214025e | 175 | */ |
176 | class dml_write_exception extends dml_exception { | |
11e1f828 | 177 | /** @var string */ |
9214025e | 178 | public $error; |
af12ea93 | 179 | /** @var string */ |
9214025e | 180 | public $sql; |
11e1f828 | 181 | /** @var array */ |
9214025e | 182 | public $params; |
183 | ||
11e1f828 | 184 | /** |
af12ea93 | 185 | * Constructor |
11e1f828 MH |
186 | * @param string $error |
187 | * @param string $sql | |
188 | * @param array $params | |
189 | */ | |
9214025e | 190 | function __construct($error, $sql=null, array $params=null) { |
191 | $this->error = $error; | |
192 | $this->sql = $sql; | |
193 | $this->params = $params; | |
c5d18164 | 194 | $errorinfo = $error."\n".$sql."\n[".var_export($params, true).']'; |
9214025e | 195 | parent::__construct('dmlwriteexception', NULL, $errorinfo); |
196 | } | |
197 | } | |
198 | ||
d5a8d9aa PS |
199 | /** |
200 | * DML transaction exception - triggered by probles related to DB transactions | |
201 | */ | |
202 | class dml_transaction_exception extends dml_exception { | |
203 | /** @var moodle_transaction */ | |
204 | public $transaction; | |
205 | ||
206 | /** | |
207 | * Constructor | |
208 | * @param array $start_backtrace | |
209 | */ | |
210 | function __construct($debuginfo=null, $transaction=null) { | |
211 | $this->transaction = $transaction; // TODO: MDL-20625 use the info from $transaction for debugging purposes | |
212 | parent::__construct('dmltransactionexception', NULL, $debuginfo); | |
213 | } | |
214 | } | |
215 | ||
8aff8482 | 216 | /** |
217 | * Sets up global $DB moodle_database instance | |
11e1f828 MH |
218 | * |
219 | * @global object | |
220 | * @global object | |
8aff8482 | 221 | * @return void |
222 | */ | |
223 | function setup_DB() { | |
224 | global $CFG, $DB; | |
225 | ||
226 | if (isset($DB)) { | |
227 | return; | |
228 | } | |
229 | ||
230 | if (!isset($CFG->dbuser)) { | |
231 | $CFG->dbuser = ''; | |
232 | } | |
233 | ||
234 | if (!isset($CFG->dbpass)) { | |
235 | $CFG->dbpass = ''; | |
236 | } | |
237 | ||
238 | if (!isset($CFG->dbname)) { | |
239 | $CFG->dbname = ''; | |
240 | } | |
241 | ||
8aff8482 | 242 | if (!isset($CFG->dblibrary)) { |
79f0d55b | 243 | $CFG->dblibrary = 'native'; |
244 | // use new drivers instead of the old adodb driver names | |
3eae57b7 | 245 | switch ($CFG->dbtype) { |
246 | case 'postgres7' : | |
247 | $CFG->dbtype = 'pgsql'; | |
3eae57b7 | 248 | break; |
249 | ||
be127d79 | 250 | case 'mssql_n': |
251 | $CFG->dbtype = 'mssql'; | |
be127d79 | 252 | break; |
253 | ||
212f17c3 | 254 | case 'oci8po': |
255 | $CFG->dbtype = 'oci'; | |
212f17c3 | 256 | break; |
257 | ||
3eae57b7 | 258 | case 'mysql' : |
259 | $CFG->dbtype = 'mysqli'; | |
3eae57b7 | 260 | break; |
3eae57b7 | 261 | } |
8aff8482 | 262 | } |
263 | ||
264 | if (!isset($CFG->dboptions)) { | |
265 | $CFG->dboptions = array(); | |
266 | } | |
267 | ||
beaa43db | 268 | if (isset($CFG->dbpersist)) { |
269 | $CFG->dboptions['dbpersist'] = $CFG->dbpersist; | |
270 | } | |
271 | ||
3eae57b7 | 272 | if (!$DB = moodle_database::get_driver_instance($CFG->dbtype, $CFG->dblibrary)) { |
273 | throw new dml_exception('dbdriverproblem', "Unknown driver $CFG->dblibrary/$CFG->dbtype"); | |
274 | } | |
8aff8482 | 275 | |
3eae57b7 | 276 | try { |
ce152606 | 277 | $DB->connect($CFG->dbhost, $CFG->dbuser, $CFG->dbpass, $CFG->dbname, $CFG->prefix, $CFG->dboptions); |
278 | } catch (moodle_exception $e) { | |
8aff8482 | 279 | if (empty($CFG->noemailever) and !empty($CFG->emailconnectionerrorsto)) { |
280 | if (file_exists($CFG->dataroot.'/emailcount')){ | |
ce152606 | 281 | $fp = @fopen($CFG->dataroot.'/emailcount', 'r'); |
282 | $content = @fread($fp, 24); | |
283 | @fclose($fp); | |
8aff8482 | 284 | if((time() - (int)$content) > 600){ |
285 | @mail($CFG->emailconnectionerrorsto, | |
286 | 'WARNING: Database connection error: '.$CFG->wwwroot, | |
287 | 'Connection error: '.$CFG->wwwroot); | |
ce152606 | 288 | $fp = @fopen($CFG->dataroot.'/emailcount', 'w'); |
289 | @fwrite($fp, time()); | |
8aff8482 | 290 | } |
291 | } else { | |
292 | @mail($CFG->emailconnectionerrorsto, | |
293 | 'WARNING: Database connection error: '.$CFG->wwwroot, | |
294 | 'Connection error: '.$CFG->wwwroot); | |
ce152606 | 295 | $fp = @fopen($CFG->dataroot.'/emailcount', 'w'); |
296 | @fwrite($fp, time()); | |
8aff8482 | 297 | } |
298 | } | |
ce152606 | 299 | // rethrow the exception |
300 | throw $e; | |
8aff8482 | 301 | } |
302 | ||
ce152606 | 303 | $CFG->dbfamily = $DB->get_dbfamily(); // TODO: BC only for now |
304 | ||
8aff8482 | 305 | return true; |
306 | } |