Proyectos de Subversion Moodle

Rev

Rev 1 | | Comparar con el anterior | Ultima modificación | Ver Log |

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