PageRenderTime 65ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/dmllib.php

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