Proyectos de Subversion Moodle

Rev

Rev 1 | Mostrar el archivo completo | | | Autoría | Ultima modificación | Ver Log |

Rev 1 Rev 1441
Línea 35... Línea 35...
35
define('SQL_PARAMS_QM', 2);
35
define('SQL_PARAMS_QM', 2);
Línea 36... Línea 36...
36
 
36
 
37
/** SQL_PARAMS_DOLLAR - Bitmask, indicates $1, $2, ... type parameters are supported by db backend. */
37
/** SQL_PARAMS_DOLLAR - Bitmask, indicates $1, $2, ... type parameters are supported by db backend. */
Línea -... Línea 38...
-
 
38
define('SQL_PARAMS_DOLLAR', 4);
-
 
39
 
-
 
40
/** SQL_INT_MAX - Size of a large integer with cross database platform support. */
38
define('SQL_PARAMS_DOLLAR', 4);
41
define('SQL_INT_MAX', 9999999999);
39
 
42
 
Línea 40... Línea 43...
40
/** SQL_QUERY_SELECT - Normal select query, reading only. */
43
/** SQL_QUERY_SELECT - Normal select query, reading only. */
41
define('SQL_QUERY_SELECT', 1);
44
define('SQL_QUERY_SELECT', 1);
Línea 183... Línea 186...
183
    /**
186
    /**
184
     * Loads and returns a database instance with the specified type and library.
187
     * Loads and returns a database instance with the specified type and library.
185
     *
188
     *
186
     * The loaded class is within lib/dml directory and of the form: $type.'_'.$library.'_moodle_database'
189
     * The loaded class is within lib/dml directory and of the form: $type.'_'.$library.'_moodle_database'
187
     *
190
     *
188
     * @param string $type Database driver's type. (eg: mysqli, pgsql, mssql, sqldrv, oci, etc.)
191
     * @param string $type Database driver's type. (eg: mysqli, pgsql, mssql, sqldrv, etc.)
189
     * @param string $library Database driver's library (native, pdo, etc.)
192
     * @param string $library Database driver's library (native, pdo, etc.)
190
     * @param bool $external True if this is an external database.
193
     * @param bool $external True if this is an external database.
191
     * @return ?moodle_database driver object or null if error, for example of driver object see {@see mysqli_native_moodle_database}
194
     * @return ?moodle_database driver object or null if error, for example of driver object see {@see mysqli_native_moodle_database}
192
     */
195
     */
193
    public static function get_driver_instance($type, $library, $external = false) {
196
    public static function get_driver_instance($type, $library, $external = false) {
Línea 214... Línea 217...
214
    }
217
    }
Línea 215... Línea 218...
215
 
218
 
216
    /**
219
    /**
217
     * Returns the database family type. (This sort of describes the SQL 'dialect')
220
     * Returns the database family type. (This sort of describes the SQL 'dialect')
218
     * Note: can be used before connect()
221
     * Note: can be used before connect()
219
     * @return string The db family name (mysql, postgres, mssql, oracle, etc.)
222
     * @return string The db family name (mysql, postgres, mssql, etc.)
220
     */
223
     */
Línea 221... Línea 224...
221
    abstract public function get_dbfamily();
224
    abstract public function get_dbfamily();
222
 
225
 
223
    /**
226
    /**
224
     * Returns a more specific database driver type
227
     * Returns a more specific database driver type
225
     * Note: can be used before connect()
228
     * Note: can be used before connect()
226
     * @return string The db type mysqli, pgsql, oci, mssql, sqlsrv
229
     * @return string The db type mysqli, pgsql, mssql, sqlsrv
Línea 227... Línea 230...
227
     */
230
     */
228
    abstract protected function get_dbtype();
231
    abstract protected function get_dbtype();
Línea 299... Línea 302...
299
     * @param mixed $prefix string means moodle db prefix, false used for external databases where prefix not used
302
     * @param mixed $prefix string means moodle db prefix, false used for external databases where prefix not used
300
     * @param array $dboptions driver specific options
303
     * @param array $dboptions driver specific options
301
     * @return bool true
304
     * @return bool true
302
     * @throws dml_connection_exception if error
305
     * @throws dml_connection_exception if error
303
     */
306
     */
304
    abstract public function connect($dbhost, $dbuser, $dbpass, $dbname, $prefix, array $dboptions=null);
307
    abstract public function connect($dbhost, $dbuser, $dbpass, $dbname, $prefix, ?array $dboptions=null);
Línea 305... Línea 308...
305
 
308
 
306
    /**
309
    /**
307
     * Store various database settings
310
     * Store various database settings
308
     * @param string $dbhost The database host.
311
     * @param string $dbhost The database host.
Línea 311... Línea 314...
311
     * @param string $dbname The name of the database being connected to.
314
     * @param string $dbname The name of the database being connected to.
312
     * @param mixed $prefix string means moodle db prefix, false used for external databases where prefix not used
315
     * @param mixed $prefix string means moodle db prefix, false used for external databases where prefix not used
313
     * @param array $dboptions driver specific options
316
     * @param array $dboptions driver specific options
314
     * @return void
317
     * @return void
315
     */
318
     */
316
    protected function store_settings($dbhost, $dbuser, $dbpass, $dbname, $prefix, array $dboptions=null) {
319
    protected function store_settings($dbhost, $dbuser, $dbpass, $dbname, $prefix, ?array $dboptions=null) {
317
        $this->dbhost    = $dbhost;
320
        $this->dbhost    = $dbhost;
318
        $this->dbuser    = $dbuser;
321
        $this->dbuser    = $dbuser;
319
        $this->dbpass    = $dbpass;
322
        $this->dbpass    = $dbpass;
320
        $this->dbname    = $dbname;
323
        $this->dbname    = $dbname;
321
        $this->prefix    = $prefix;
324
        $this->prefix    = $prefix;
Línea 371... Línea 374...
371
     * @param string $dbname The name of the database being connected to.
374
     * @param string $dbname The name of the database being connected to.
372
     * @param array $dboptions An array of optional database options (eg: dbport)
375
     * @param array $dboptions An array of optional database options (eg: dbport)
373
     *
376
     *
374
     * @return bool success True for successful connection. False otherwise.
377
     * @return bool success True for successful connection. False otherwise.
375
     */
378
     */
376
    public function create_database($dbhost, $dbuser, $dbpass, $dbname, array $dboptions=null) {
379
    public function create_database($dbhost, $dbuser, $dbpass, $dbname, ?array $dboptions=null) {
377
        return false;
380
        return false;
378
    }
381
    }
Línea 379... Línea 382...
379
 
382
 
380
    /**
383
    /**
Línea 595... Línea 598...
595
     * @param string $sql The query which is being debugged.
598
     * @param string $sql The query which is being debugged.
596
     * @param array $params The query parameters. (optional)
599
     * @param array $params The query parameters. (optional)
597
     * @param mixed $obj The library specific object. (optional)
600
     * @param mixed $obj The library specific object. (optional)
598
     * @return void
601
     * @return void
599
     */
602
     */
600
    protected function print_debug($sql, array $params=null, $obj=null) {
603
    protected function print_debug($sql, ?array $params=null, $obj=null) {
601
        if (!$this->get_debug()) {
604
        if (!$this->get_debug()) {
602
            return;
605
            return;
603
        }
606
        }
604
        if (CLI_SCRIPT) {
607
        if (CLI_SCRIPT) {
605
            $separator = "--------------------------------\n";
608
            $separator = "--------------------------------\n";
Línea 656... Línea 659...
656
     * @param string $table The table name that these conditions will be validated against.
659
     * @param string $table The table name that these conditions will be validated against.
657
     * @param array $conditions The conditions to build the where clause. (must not contain numeric indexes)
660
     * @param array $conditions The conditions to build the where clause. (must not contain numeric indexes)
658
     * @return array An array list containing sql 'where' part and 'params'.
661
     * @return array An array list containing sql 'where' part and 'params'.
659
     * @throws dml_exception
662
     * @throws dml_exception
660
     */
663
     */
661
    protected function where_clause($table, array $conditions=null) {
664
    protected function where_clause($table, ?array $conditions=null) {
662
        // We accept nulls in conditions
665
        // We accept nulls in conditions
663
        $conditions = is_null($conditions) ? array() : $conditions;
666
        $conditions = is_null($conditions) ? array() : $conditions;
Línea 664... Línea 667...
664
 
667
 
665
        if (empty($conditions)) {
668
        if (empty($conditions)) {
Línea 889... Línea 892...
889
     * Normalizes sql query parameters and verifies parameters.
892
     * Normalizes sql query parameters and verifies parameters.
890
     * @param string $sql The query or part of it.
893
     * @param string $sql The query or part of it.
891
     * @param array $params The query parameters.
894
     * @param array $params The query parameters.
892
     * @return array (sql, params, type of params)
895
     * @return array (sql, params, type of params)
893
     */
896
     */
894
    public function fix_sql_params($sql, array $params=null) {
897
    public function fix_sql_params($sql, ?array $params=null) {
895
        global $CFG;
898
        global $CFG;
Línea 896... Línea 899...
896
 
899
 
Línea 897... Línea 900...
897
        require_once($CFG->libdir . '/ddllib.php');
900
        require_once($CFG->libdir . '/ddllib.php');
Línea 1287... Línea 1290...
1287
    public function get_debug() {
1290
    public function get_debug() {
1288
        return $this->debug;
1291
        return $this->debug;
1289
    }
1292
    }
Línea 1290... Línea 1293...
1290
 
1293
 
1291
    /**
-
 
1292
     * Enable/disable detailed sql logging
-
 
1293
     *
-
 
1294
     * @deprecated since Moodle 2.9
-
 
1295
     */
-
 
1296
    public function set_logging($state) {
-
 
1297
        throw new coding_exception('set_logging() can not be used any more.');
-
 
1298
    }
-
 
1299
 
-
 
1300
    /**
1294
    /**
1301
     * Do NOT use in code, this is for use by database_manager only!
1295
     * Do NOT use in code, this is for use by database_manager only!
1302
     * @param string|array $sql query or array of queries
1296
     * @param string|array $sql query or array of queries
1303
     * @param array|null $tablenames an array of xmldb table names affected by this request.
1297
     * @param array|null $tablenames an array of xmldb table names affected by this request.
1304
     * @return bool true
1298
     * @return bool true
Línea 1312... Línea 1306...
1312
     * @param string $sql query
1306
     * @param string $sql query
1313
     * @param array $params query parameters
1307
     * @param array $params query parameters
1314
     * @return bool true
1308
     * @return bool true
1315
     * @throws dml_exception A DML specific exception is thrown for any errors.
1309
     * @throws dml_exception A DML specific exception is thrown for any errors.
1316
     */
1310
     */
1317
    abstract public function execute($sql, array $params=null);
1311
    abstract public function execute($sql, ?array $params=null);
Línea 1318... Línea 1312...
1318
 
1312
 
1319
    /**
1313
    /**
1320
     * Get a number of records as a moodle_recordset where all the given conditions met.
1314
     * Get a number of records as a moodle_recordset where all the given conditions met.
1321
     *
1315
     *
Línea 1348... Línea 1342...
1348
     * @param int $limitfrom return a subset of records, starting at this point (optional).
1342
     * @param int $limitfrom return a subset of records, starting at this point (optional).
1349
     * @param int $limitnum return a subset comprising this many records (optional, required if $limitfrom is set).
1343
     * @param int $limitnum return a subset comprising this many records (optional, required if $limitfrom is set).
1350
     * @return moodle_recordset A moodle_recordset instance
1344
     * @return moodle_recordset A moodle_recordset instance
1351
     * @throws dml_exception A DML specific exception is thrown for any errors.
1345
     * @throws dml_exception A DML specific exception is thrown for any errors.
1352
     */
1346
     */
1353
    public function get_recordset($table, array $conditions=null, $sort='', $fields='*', $limitfrom=0, $limitnum=0) {
1347
    public function get_recordset($table, ?array $conditions=null, $sort='', $fields='*', $limitfrom=0, $limitnum=0) {
1354
        list($select, $params) = $this->where_clause($table, $conditions);
1348
        list($select, $params) = $this->where_clause($table, $conditions);
1355
        return $this->get_recordset_select($table, $select, $params, $sort, $fields, $limitfrom, $limitnum);
1349
        return $this->get_recordset_select($table, $select, $params, $sort, $fields, $limitfrom, $limitnum);
1356
    }
1350
    }
Línea 1357... Línea 1351...
1357
 
1351
 
Línea 1394... Línea 1388...
1394
     * @param int $limitfrom return a subset of records, starting at this point (optional).
1388
     * @param int $limitfrom return a subset of records, starting at this point (optional).
1395
     * @param int $limitnum return a subset comprising this many records (optional, required if $limitfrom is set).
1389
     * @param int $limitnum return a subset comprising this many records (optional, required if $limitfrom is set).
1396
     * @return moodle_recordset A moodle_recordset instance.
1390
     * @return moodle_recordset A moodle_recordset instance.
1397
     * @throws dml_exception A DML specific exception is thrown for any errors.
1391
     * @throws dml_exception A DML specific exception is thrown for any errors.
1398
     */
1392
     */
1399
    public function get_recordset_select($table, $select, array $params=null, $sort='', $fields='*', $limitfrom=0, $limitnum=0) {
1393
    public function get_recordset_select($table, $select, ?array $params=null, $sort='', $fields='*', $limitfrom=0, $limitnum=0) {
1400
        $sql = "SELECT $fields FROM {".$table."}";
1394
        $sql = "SELECT $fields FROM {".$table."}";
1401
        if ($select) {
1395
        if ($select) {
1402
            $sql .= " WHERE $select";
1396
            $sql .= " WHERE $select";
1403
        }
1397
        }
1404
        if ($sort) {
1398
        if ($sort) {
Línea 1421... Línea 1415...
1421
     * @param int $limitfrom return a subset of records, starting at this point (optional).
1415
     * @param int $limitfrom return a subset of records, starting at this point (optional).
1422
     * @param int $limitnum return a subset comprising this many records (optional, required if $limitfrom is set).
1416
     * @param int $limitnum return a subset comprising this many records (optional, required if $limitfrom is set).
1423
     * @return moodle_recordset A moodle_recordset instance.
1417
     * @return moodle_recordset A moodle_recordset instance.
1424
     * @throws dml_exception A DML specific exception is thrown for any errors.
1418
     * @throws dml_exception A DML specific exception is thrown for any errors.
1425
     */
1419
     */
1426
    abstract public function get_recordset_sql($sql, array $params=null, $limitfrom=0, $limitnum=0);
1420
    abstract public function get_recordset_sql($sql, ?array $params=null, $limitfrom=0, $limitnum=0);
Línea 1427... Línea 1421...
1427
 
1421
 
1428
    /**
1422
    /**
1429
     * Get all records from a table.
1423
     * Get all records from a table.
1430
     *
1424
     *
Línea 1457... Línea 1451...
1457
     * @param int $limitfrom return a subset of records, starting at this point (optional).
1451
     * @param int $limitfrom return a subset of records, starting at this point (optional).
1458
     * @param int $limitnum return a subset comprising this many records in total (optional, required if $limitfrom is set).
1452
     * @param int $limitnum return a subset comprising this many records in total (optional, required if $limitfrom is set).
1459
     * @return array An array of Objects indexed by first column.
1453
     * @return array An array of Objects indexed by first column.
1460
     * @throws dml_exception A DML specific exception is thrown for any errors.
1454
     * @throws dml_exception A DML specific exception is thrown for any errors.
1461
     */
1455
     */
1462
    public function get_records($table, array $conditions=null, $sort='', $fields='*', $limitfrom=0, $limitnum=0) {
1456
    public function get_records($table, ?array $conditions=null, $sort='', $fields='*', $limitfrom=0, $limitnum=0) {
1463
        list($select, $params) = $this->where_clause($table, $conditions);
1457
        list($select, $params) = $this->where_clause($table, $conditions);
1464
        return $this->get_records_select($table, $select, $params, $sort, $fields, $limitfrom, $limitnum);
1458
        return $this->get_records_select($table, $select, $params, $sort, $fields, $limitfrom, $limitnum);
1465
    }
1459
    }
Línea 1466... Línea 1460...
1466
 
1460
 
Línea 1501... Línea 1495...
1501
     * @param int $limitfrom return a subset of records, starting at this point (optional).
1495
     * @param int $limitfrom return a subset of records, starting at this point (optional).
1502
     * @param int $limitnum return a subset comprising this many records in total (optional, required if $limitfrom is set).
1496
     * @param int $limitnum return a subset comprising this many records in total (optional, required if $limitfrom is set).
1503
     * @return array of objects indexed by first column
1497
     * @return array of objects indexed by first column
1504
     * @throws dml_exception A DML specific exception is thrown for any errors.
1498
     * @throws dml_exception A DML specific exception is thrown for any errors.
1505
     */
1499
     */
1506
    public function get_records_select($table, $select, array $params=null, $sort='', $fields='*', $limitfrom=0, $limitnum=0) {
1500
    public function get_records_select($table, $select, ?array $params=null, $sort='', $fields='*', $limitfrom=0, $limitnum=0) {
1507
        if ($select) {
1501
        if ($select) {
1508
            $select = "WHERE $select";
1502
            $select = "WHERE $select";
1509
        }
1503
        }
1510
        if ($sort) {
1504
        if ($sort) {
1511
            $sort = " ORDER BY $sort";
1505
            $sort = " ORDER BY $sort";
Línea 1525... Línea 1519...
1525
     * @param int $limitfrom return a subset of records, starting at this point (optional).
1519
     * @param int $limitfrom return a subset of records, starting at this point (optional).
1526
     * @param int $limitnum return a subset comprising this many records in total (optional, required if $limitfrom is set).
1520
     * @param int $limitnum return a subset comprising this many records in total (optional, required if $limitfrom is set).
1527
     * @return array of objects indexed by first column
1521
     * @return array of objects indexed by first column
1528
     * @throws dml_exception A DML specific exception is thrown for any errors.
1522
     * @throws dml_exception A DML specific exception is thrown for any errors.
1529
     */
1523
     */
1530
    abstract public function get_records_sql($sql, array $params=null, $limitfrom=0, $limitnum=0);
1524
    abstract public function get_records_sql($sql, ?array $params=null, $limitfrom=0, $limitnum=0);
Línea 1531... Línea 1525...
1531
 
1525
 
1532
    /**
1526
    /**
1533
     * Get the first two columns from a number of records as an associative array where all the given conditions met.
1527
     * Get the first two columns from a number of records as an associative array where all the given conditions met.
1534
     *
1528
     *
Línea 1546... Línea 1540...
1546
     * @param int $limitfrom return a subset of records, starting at this point (optional).
1540
     * @param int $limitfrom return a subset of records, starting at this point (optional).
1547
     * @param int $limitnum return a subset comprising this many records (optional, required if $limitfrom is set).
1541
     * @param int $limitnum return a subset comprising this many records (optional, required if $limitfrom is set).
1548
     * @return array an associative array
1542
     * @return array an associative array
1549
     * @throws dml_exception A DML specific exception is thrown for any errors.
1543
     * @throws dml_exception A DML specific exception is thrown for any errors.
1550
     */
1544
     */
1551
    public function get_records_menu($table, array $conditions=null, $sort='', $fields='*', $limitfrom=0, $limitnum=0) {
1545
    public function get_records_menu($table, ?array $conditions=null, $sort='', $fields='*', $limitfrom=0, $limitnum=0) {
1552
        $menu = array();
1546
        $menu = array();
1553
        if ($records = $this->get_records($table, $conditions, $sort, $fields, $limitfrom, $limitnum)) {
1547
        if ($records = $this->get_records($table, $conditions, $sort, $fields, $limitfrom, $limitnum)) {
1554
            foreach ($records as $record) {
1548
            foreach ($records as $record) {
1555
                $record = (array)$record;
1549
                $record = (array)$record;
1556
                $key   = array_shift($record);
1550
                $key   = array_shift($record);
Línea 1575... Línea 1569...
1575
     * @param int $limitfrom return a subset of records, starting at this point (optional).
1569
     * @param int $limitfrom return a subset of records, starting at this point (optional).
1576
     * @param int $limitnum return a subset comprising this many records (optional, required if $limitfrom is set).
1570
     * @param int $limitnum return a subset comprising this many records (optional, required if $limitfrom is set).
1577
     * @return array an associative array
1571
     * @return array an associative array
1578
     * @throws dml_exception A DML specific exception is thrown for any errors.
1572
     * @throws dml_exception A DML specific exception is thrown for any errors.
1579
     */
1573
     */
1580
    public function get_records_select_menu($table, $select, array $params=null, $sort='', $fields='*', $limitfrom=0, $limitnum=0) {
1574
    public function get_records_select_menu($table, $select, ?array $params=null, $sort='', $fields='*', $limitfrom=0, $limitnum=0) {
1581
        $menu = array();
1575
        $menu = array();
1582
        if ($records = $this->get_records_select($table, $select, $params, $sort, $fields, $limitfrom, $limitnum)) {
1576
        if ($records = $this->get_records_select($table, $select, $params, $sort, $fields, $limitfrom, $limitnum)) {
1583
            foreach ($records as $record) {
1577
            foreach ($records as $record) {
1584
                $record = (array)$record;
1578
                $record = (array)$record;
1585
                $key   = array_shift($record);
1579
                $key   = array_shift($record);
Línea 1601... Línea 1595...
1601
     * @param int $limitfrom return a subset of records, starting at this point (optional).
1595
     * @param int $limitfrom return a subset of records, starting at this point (optional).
1602
     * @param int $limitnum return a subset comprising this many records (optional, required if $limitfrom is set).
1596
     * @param int $limitnum return a subset comprising this many records (optional, required if $limitfrom is set).
1603
     * @return array an associative array
1597
     * @return array an associative array
1604
     * @throws dml_exception A DML specific exception is thrown for any errors.
1598
     * @throws dml_exception A DML specific exception is thrown for any errors.
1605
     */
1599
     */
1606
    public function get_records_sql_menu($sql, array $params=null, $limitfrom=0, $limitnum=0) {
1600
    public function get_records_sql_menu($sql, ?array $params=null, $limitfrom=0, $limitnum=0) {
1607
        $menu = array();
1601
        $menu = array();
1608
        if ($records = $this->get_records_sql($sql, $params, $limitfrom, $limitnum)) {
1602
        if ($records = $this->get_records_sql($sql, $params, $limitfrom, $limitnum)) {
1609
            foreach ($records as $record) {
1603
            foreach ($records as $record) {
1610
                $record = (array)$record;
1604
                $record = (array)$record;
1611
                $key   = array_shift($record);
1605
                $key   = array_shift($record);
Línea 1646... Línea 1640...
1646
     *                        IGNORE_MULTIPLE means return first, ignore multiple records found(not recommended);
1640
     *                        IGNORE_MULTIPLE means return first, ignore multiple records found(not recommended);
1647
     *                        MUST_EXIST means throw exception if no record or multiple records found
1641
     *                        MUST_EXIST means throw exception if no record or multiple records found
1648
     * @return stdClass|false a fieldset object containing the first matching record, false or exception if error not found depending on mode
1642
     * @return stdClass|false a fieldset object containing the first matching record, false or exception if error not found depending on mode
1649
     * @throws dml_exception A DML specific exception is thrown for any errors.
1643
     * @throws dml_exception A DML specific exception is thrown for any errors.
1650
     */
1644
     */
1651
    public function get_record_select($table, $select, array $params=null, $fields='*', $strictness=IGNORE_MISSING) {
1645
    public function get_record_select($table, $select, ?array $params=null, $fields='*', $strictness=IGNORE_MISSING) {
1652
        if ($select) {
1646
        if ($select) {
1653
            $select = "WHERE $select";
1647
            $select = "WHERE $select";
1654
        }
1648
        }
1655
        try {
1649
        try {
1656
            return $this->get_record_sql("SELECT $fields FROM {" . $table . "} $select", $params, $strictness);
1650
            return $this->get_record_sql("SELECT $fields FROM {" . $table . "} $select", $params, $strictness);
Línea 1672... Línea 1666...
1672
     *                        IGNORE_MULTIPLE means return first, ignore multiple records found(not recommended);
1666
     *                        IGNORE_MULTIPLE means return first, ignore multiple records found(not recommended);
1673
     *                        MUST_EXIST means throw exception if no record or multiple records found
1667
     *                        MUST_EXIST means throw exception if no record or multiple records found
1674
     * @return mixed a fieldset object containing the first matching record, false or exception if error not found depending on mode
1668
     * @return mixed a fieldset object containing the first matching record, false or exception if error not found depending on mode
1675
     * @throws dml_exception A DML specific exception is thrown for any errors.
1669
     * @throws dml_exception A DML specific exception is thrown for any errors.
1676
     */
1670
     */
1677
    public function get_record_sql($sql, array $params=null, $strictness=IGNORE_MISSING) {
1671
    public function get_record_sql($sql, ?array $params=null, $strictness=IGNORE_MISSING) {
1678
        $strictness = (int)$strictness; // we support true/false for BC reasons too
1672
        $strictness = (int)$strictness; // we support true/false for BC reasons too
1679
        if ($strictness == IGNORE_MULTIPLE) {
1673
        if ($strictness == IGNORE_MULTIPLE) {
1680
            $count = 1;
1674
            $count = 1;
1681
        } else {
1675
        } else {
1682
            $count = 0;
1676
            $count = 0;
Línea 1728... Línea 1722...
1728
     *                        IGNORE_MULTIPLE means return first, ignore multiple records found(not recommended);
1722
     *                        IGNORE_MULTIPLE means return first, ignore multiple records found(not recommended);
1729
     *                        MUST_EXIST means throw exception if no record or multiple records found
1723
     *                        MUST_EXIST means throw exception if no record or multiple records found
1730
     * @return mixed the specified value false if not found
1724
     * @return mixed the specified value false if not found
1731
     * @throws dml_exception A DML specific exception is thrown for any errors.
1725
     * @throws dml_exception A DML specific exception is thrown for any errors.
1732
     */
1726
     */
1733
    public function get_field_select($table, $return, $select, array $params=null, $strictness=IGNORE_MISSING) {
1727
    public function get_field_select($table, $return, $select, ?array $params=null, $strictness=IGNORE_MISSING) {
1734
        if ($select) {
1728
        if ($select) {
1735
            $select = "WHERE $select";
1729
            $select = "WHERE $select";
1736
        }
1730
        }
1737
        try {
1731
        try {
1738
            return $this->get_field_sql("SELECT $return FROM {" . $table . "} $select", $params, $strictness);
1732
            return $this->get_field_sql("SELECT $return FROM {" . $table . "} $select", $params, $strictness);
Línea 1751... Línea 1745...
1751
     *                        IGNORE_MULTIPLE means return first, ignore multiple records found(not recommended);
1745
     *                        IGNORE_MULTIPLE means return first, ignore multiple records found(not recommended);
1752
     *                        MUST_EXIST means throw exception if no record or multiple records found
1746
     *                        MUST_EXIST means throw exception if no record or multiple records found
1753
     * @return mixed the specified value false if not found
1747
     * @return mixed the specified value false if not found
1754
     * @throws dml_exception A DML specific exception is thrown for any errors.
1748
     * @throws dml_exception A DML specific exception is thrown for any errors.
1755
     */
1749
     */
1756
    public function get_field_sql($sql, array $params=null, $strictness=IGNORE_MISSING) {
1750
    public function get_field_sql($sql, ?array $params=null, $strictness=IGNORE_MISSING) {
1757
        if (!$record = $this->get_record_sql($sql, $params, $strictness)) {
1751
        if (!$record = $this->get_record_sql($sql, $params, $strictness)) {
1758
            return false;
1752
            return false;
1759
        }
1753
        }
Línea 1760... Línea 1754...
1760
 
1754
 
Línea 1784... Línea 1778...
1784
     * @param string $select A fragment of SQL to be used in a where clause in the SQL call.
1778
     * @param string $select A fragment of SQL to be used in a where clause in the SQL call.
1785
     * @param array $params array of sql parameters
1779
     * @param array $params array of sql parameters
1786
     * @return array of values
1780
     * @return array of values
1787
     * @throws dml_exception A DML specific exception is thrown for any errors.
1781
     * @throws dml_exception A DML specific exception is thrown for any errors.
1788
     */
1782
     */
1789
    public function get_fieldset_select($table, $return, $select, array $params=null) {
1783
    public function get_fieldset_select($table, $return, $select, ?array $params=null) {
1790
        if ($select) {
1784
        if ($select) {
1791
            $select = "WHERE $select";
1785
            $select = "WHERE $select";
1792
        }
1786
        }
1793
        return $this->get_fieldset_sql("SELECT $return FROM {" . $table . "} $select", $params);
1787
        return $this->get_fieldset_sql("SELECT $return FROM {" . $table . "} $select", $params);
1794
    }
1788
    }
Línea 1799... Línea 1793...
1799
     * @param string $sql The SQL query
1793
     * @param string $sql The SQL query
1800
     * @param array $params array of sql parameters
1794
     * @param array $params array of sql parameters
1801
     * @return array of values
1795
     * @return array of values
1802
     * @throws dml_exception A DML specific exception is thrown for any errors.
1796
     * @throws dml_exception A DML specific exception is thrown for any errors.
1803
     */
1797
     */
1804
    abstract public function get_fieldset_sql($sql, array $params=null);
1798
    abstract public function get_fieldset_sql($sql, ?array $params=null);
Línea 1805... Línea 1799...
1805
 
1799
 
1806
    /**
1800
    /**
1807
     * Insert new record into database, as fast as possible, no safety checks, lobs not supported.
1801
     * Insert new record into database, as fast as possible, no safety checks, lobs not supported.
1808
     * @param string $table name
1802
     * @param string $table name
Línea 1914... Línea 1908...
1914
     * @param mixed $newvalue the value to set the field to.
1908
     * @param mixed $newvalue the value to set the field to.
1915
     * @param array $conditions optional array $fieldname=>requestedvalue with AND in between
1909
     * @param array $conditions optional array $fieldname=>requestedvalue with AND in between
1916
     * @return bool true
1910
     * @return bool true
1917
     * @throws dml_exception A DML specific exception is thrown for any errors.
1911
     * @throws dml_exception A DML specific exception is thrown for any errors.
1918
     */
1912
     */
1919
    public function set_field($table, $newfield, $newvalue, array $conditions=null) {
1913
    public function set_field($table, $newfield, $newvalue, ?array $conditions=null) {
1920
        list($select, $params) = $this->where_clause($table, $conditions);
1914
        list($select, $params) = $this->where_clause($table, $conditions);
1921
        return $this->set_field_select($table, $newfield, $newvalue, $select, $params);
1915
        return $this->set_field_select($table, $newfield, $newvalue, $select, $params);
1922
    }
1916
    }
Línea 1923... Línea 1917...
1923
 
1917
 
Línea 1930... Línea 1924...
1930
     * @param string $select A fragment of SQL to be used in a where clause in the SQL call.
1924
     * @param string $select A fragment of SQL to be used in a where clause in the SQL call.
1931
     * @param array $params array of sql parameters
1925
     * @param array $params array of sql parameters
1932
     * @return bool true
1926
     * @return bool true
1933
     * @throws dml_exception A DML specific exception is thrown for any errors.
1927
     * @throws dml_exception A DML specific exception is thrown for any errors.
1934
     */
1928
     */
1935
    abstract public function set_field_select($table, $newfield, $newvalue, $select, array $params=null);
1929
    abstract public function set_field_select($table, $newfield, $newvalue, $select, ?array $params=null);
Línea 1936... Línea 1930...
1936
 
1930
 
1937
 
1931
 
1938
    /**
1932
    /**
1939
     * Count the records in a table where all the given conditions met.
1933
     * Count the records in a table where all the given conditions met.
1940
     *
1934
     *
1941
     * @param string $table The table to query.
1935
     * @param string $table The table to query.
1942
     * @param array $conditions optional array $fieldname=>requestedvalue with AND in between
1936
     * @param array $conditions optional array $fieldname=>requestedvalue with AND in between
1943
     * @return int The count of records returned from the specified criteria.
1937
     * @return int The count of records returned from the specified criteria.
1944
     * @throws dml_exception A DML specific exception is thrown for any errors.
1938
     * @throws dml_exception A DML specific exception is thrown for any errors.
1945
     */
1939
     */
1946
    public function count_records($table, array $conditions=null) {
1940
    public function count_records($table, ?array $conditions=null) {
1947
        list($select, $params) = $this->where_clause($table, $conditions);
1941
        list($select, $params) = $this->where_clause($table, $conditions);
Línea 1948... Línea 1942...
1948
        return $this->count_records_select($table, $select, $params);
1942
        return $this->count_records_select($table, $select, $params);
Línea 1956... Línea 1950...
1956
     * @param array $params array of sql parameters
1950
     * @param array $params array of sql parameters
1957
     * @param string $countitem The count string to be used in the SQL call. Default is COUNT('x').
1951
     * @param string $countitem The count string to be used in the SQL call. Default is COUNT('x').
1958
     * @return int The count of records returned from the specified criteria.
1952
     * @return int The count of records returned from the specified criteria.
1959
     * @throws dml_exception A DML specific exception is thrown for any errors.
1953
     * @throws dml_exception A DML specific exception is thrown for any errors.
1960
     */
1954
     */
1961
    public function count_records_select($table, $select, array $params=null, $countitem="COUNT('x')") {
1955
    public function count_records_select($table, $select, ?array $params=null, $countitem="COUNT('x')") {
1962
        if ($select) {
1956
        if ($select) {
1963
            $select = "WHERE $select";
1957
            $select = "WHERE $select";
1964
        }
1958
        }
1965
        return $this->count_records_sql("SELECT $countitem FROM {" . $table . "} $select", $params);
1959
        return $this->count_records_sql("SELECT $countitem FROM {" . $table . "} $select", $params);
1966
    }
1960
    }
Línea 1976... Línea 1970...
1976
     * @param string $sql The SQL string you wish to be executed.
1970
     * @param string $sql The SQL string you wish to be executed.
1977
     * @param array $params array of sql parameters
1971
     * @param array $params array of sql parameters
1978
     * @return int the count
1972
     * @return int the count
1979
     * @throws dml_exception A DML specific exception is thrown for any errors.
1973
     * @throws dml_exception A DML specific exception is thrown for any errors.
1980
     */
1974
     */
1981
    public function count_records_sql($sql, array $params=null) {
1975
    public function count_records_sql($sql, ?array $params=null) {
1982
        $count = $this->get_field_sql($sql, $params);
1976
        $count = $this->get_field_sql($sql, $params);
1983
        if ($count === false or !is_number($count) or $count < 0) {
1977
        if ($count === false or !is_number($count) or $count < 0) {
1984
            throw new coding_exception("count_records_sql() expects the first field to contain non-negative number from COUNT(), '$count' found instead.");
1978
            throw new coding_exception("count_records_sql() expects the first field to contain non-negative number from COUNT(), '$count' found instead.");
1985
        }
1979
        }
1986
        return (int)$count;
1980
        return (int)$count;
Línea 2006... Línea 2000...
2006
     * @param string $select A fragment of SQL to be used in a WHERE clause in the SQL call.
2000
     * @param string $select A fragment of SQL to be used in a WHERE clause in the SQL call.
2007
     * @param array $params array of sql parameters
2001
     * @param array $params array of sql parameters
2008
     * @return bool true if a matching record exists, else false.
2002
     * @return bool true if a matching record exists, else false.
2009
     * @throws dml_exception A DML specific exception is thrown for any errors.
2003
     * @throws dml_exception A DML specific exception is thrown for any errors.
2010
     */
2004
     */
2011
    public function record_exists_select($table, $select, array $params=null) {
2005
    public function record_exists_select($table, $select, ?array $params=null) {
2012
        if ($select) {
2006
        if ($select) {
2013
            $select = "WHERE $select";
2007
            $select = "WHERE $select";
2014
        }
2008
        }
2015
        return $this->record_exists_sql("SELECT 'x' FROM {" . $table . "} $select", $params);
2009
        return $this->record_exists_sql("SELECT 'x' FROM {" . $table . "} $select", $params);
2016
    }
2010
    }
Línea 2024... Línea 2018...
2024
     * @param string $sql The SQL statement to execute.
2018
     * @param string $sql The SQL statement to execute.
2025
     * @param array $params array of sql parameters
2019
     * @param array $params array of sql parameters
2026
     * @return bool true if the SQL executes without errors and returns at least one record.
2020
     * @return bool true if the SQL executes without errors and returns at least one record.
2027
     * @throws dml_exception A DML specific exception is thrown for any errors.
2021
     * @throws dml_exception A DML specific exception is thrown for any errors.
2028
     */
2022
     */
2029
    public function record_exists_sql($sql, array $params=null) {
2023
    public function record_exists_sql($sql, ?array $params=null) {
2030
        $mrs = $this->get_recordset_sql($sql, $params, 0, 1);
2024
        $mrs = $this->get_recordset_sql($sql, $params, 0, 1);
2031
        $return = $mrs->valid();
2025
        $return = $mrs->valid();
2032
        $mrs->close();
2026
        $mrs->close();
2033
        return $return;
2027
        return $return;
2034
    }
2028
    }
Línea 2040... Línea 2034...
2040
     * @param string $table the table to delete from.
2034
     * @param string $table the table to delete from.
2041
     * @param array $conditions optional array $fieldname=>requestedvalue with AND in between
2035
     * @param array $conditions optional array $fieldname=>requestedvalue with AND in between
2042
     * @return bool true.
2036
     * @return bool true.
2043
     * @throws dml_exception A DML specific exception is thrown for any errors.
2037
     * @throws dml_exception A DML specific exception is thrown for any errors.
2044
     */
2038
     */
2045
    public function delete_records($table, array $conditions=null) {
2039
    public function delete_records($table, ?array $conditions=null) {
2046
        // truncate is drop/create (DDL), not transactional safe,
2040
        // truncate is drop/create (DDL), not transactional safe,
2047
        // so we don't use the shortcut within them. MDL-29198
2041
        // so we don't use the shortcut within them. MDL-29198
2048
        if (is_null($conditions) && empty($this->transactions)) {
2042
        if (is_null($conditions) && empty($this->transactions)) {
2049
            return $this->execute("TRUNCATE TABLE {".$table."}");
2043
            return $this->execute("TRUNCATE TABLE {".$table."}");
2050
        }
2044
        }
Línea 2096... Línea 2090...
2096
     * @param string $select A fragment of SQL to be used in a where clause in the SQL call (used to define the selection criteria).
2090
     * @param string $select A fragment of SQL to be used in a where clause in the SQL call (used to define the selection criteria).
2097
     * @param array $params array of sql parameters
2091
     * @param array $params array of sql parameters
2098
     * @return bool true.
2092
     * @return bool true.
2099
     * @throws dml_exception A DML specific exception is thrown for any errors.
2093
     * @throws dml_exception A DML specific exception is thrown for any errors.
2100
     */
2094
     */
2101
    abstract public function delete_records_select($table, $select, array $params=null);
2095
    abstract public function delete_records_select($table, $select, ?array $params=null);
Línea 2102... Línea 2096...
2102
 
2096
 
2103
    /**
2097
    /**
2104
     * Returns the FROM clause required by some DBs in all SELECT statements.
2098
     * Returns the FROM clause required by some DBs in all SELECT statements.
2105
     *
2099
     *
Línea 2874... Línea 2868...
2874
    }
2868
    }
Línea 2875... Línea 2869...
2875
 
2869
 
2876
    /**
2870
    /**
2877
     * Returns whether we want to connect to slave database for read queries.
2871
     * Returns whether we want to connect to slave database for read queries.
-
 
2872
     * @return bool Want read only connection
-
 
2873
     * @deprecated Since Moodle 5.0. See MDL-71257.
2878
     * @return bool Want read only connection
2874
     * @todo Final deprecation in Moodle 6.0. See MDL-83171.
-
 
2875
     */
-
 
2876
    #[\core\attribute\deprecated(
-
 
2877
        replacement: 'want_read_replica',
-
 
2878
        since: '5.0',
-
 
2879
        mdl: 'MDL-71257',
-
 
2880
        reason: 'Renamed'
2879
     */
2881
    )]
-
 
2882
    public function want_read_slave(): bool {
-
 
2883
        \core\deprecation::emit_deprecation(__FUNCTION__);
-
 
2884
        return false;
-
 
2885
    }
-
 
2886
 
-
 
2887
    /**
-
 
2888
     * Returns whether we want to connect to replica database for read queries.
-
 
2889
     *
-
 
2890
     * @return bool Want read only connection.
-
 
2891
     */
2880
    public function want_read_slave(): bool {
2892
    public function want_read_replica(): bool {
2881
        return false;
2893
        return false;
Línea 2882... Línea 2894...
2882
    }
2894
    }
2883
 
2895
 
2884
    /**
2896
    /**
-
 
2897
     * Returns the number of reads before first write done by this database.
-
 
2898
     * @return int Number of reads.
2885
     * Returns the number of reads before first write done by this database.
2899
     * @deprecated Since Moodle 5.0
-
 
2900
     * @todo Final deprecation in Moodle 6.0. See MDL-83171.
-
 
2901
     */
-
 
2902
    #[\core\attribute\deprecated(
-
 
2903
        replacement: 'perf_get_reads_replica',
-
 
2904
        since: '5.0',
-
 
2905
        mdl: 'MDL-71257',
2886
     * @return int Number of reads.
2906
        reason: 'Renamed'
-
 
2907
    )]
-
 
2908
    public function perf_get_reads_slave(): int {
-
 
2909
        \core\deprecation::emit_deprecation(__FUNCTION__);
-
 
2910
        return 0;
-
 
2911
    }
-
 
2912
 
-
 
2913
    /**
-
 
2914
     * Returns the number of reads before first write done by this database.
-
 
2915
     *
-
 
2916
     * @return int Number of reads.
2887
     */
2917
     */
2888
    public function perf_get_reads_slave(): int {
2918
    public function perf_get_reads_replica(): int {
Línea 2889... Línea 2919...
2889
        return 0;
2919
        return 0;
2890
    }
2920
    }
Línea 2920... Línea 2950...
2920
     */
2950
     */
2921
    public function is_fulltext_search_supported() {
2951
    public function is_fulltext_search_supported() {
2922
        // No support unless specified.
2952
        // No support unless specified.
2923
        return false;
2953
        return false;
2924
    }
2954
    }
-
 
2955
 
-
 
2956
    /**
-
 
2957
     * Whether the database is able to support the COUNT() window function and provides a performance improvement.
-
 
2958
     *
-
 
2959
     * @return bool
-
 
2960
     */
-
 
2961
    public function is_count_window_function_supported(): bool {
-
 
2962
        // No support unless specified.
-
 
2963
        return false;
-
 
2964
    }
-
 
2965
 
-
 
2966
    /**
-
 
2967
     * Retrieve records with a select query and count the total number of records.
-
 
2968
     *
-
 
2969
     * @param string $sql The query string.
-
 
2970
     * @param string $fullcountcolumn The column name used for counting total records.
-
 
2971
     * @param string $sort (Optional) Sorting criteria for the records.
-
 
2972
     *                      The reason to separate $sort from $sql are:
-
 
2973
     *                      1. The $sort needs to be placed outside the full count subquery
-
 
2974
     *                         in order to function properly in MariaDB.
-
 
2975
     *                      2. For unsupported databases, it is not allowed to run a query to get the total with the $sort.
-
 
2976
     *                         Please refer to the {@see ::generate_fullcount_sql()} for details.
-
 
2977
     * @param array|null $params (Optional) Parameters to bind with the query.
-
 
2978
     * @param int $limitfrom (Optional) Offset for pagination.
-
 
2979
     * @param int $limitnum (Optional) Limit for pagination.
-
 
2980
     * @return array Fetched records.
-
 
2981
     */
-
 
2982
    public function get_counted_records_sql(
-
 
2983
        string $sql,
-
 
2984
        string $fullcountcolumn,
-
 
2985
        string $sort = '',
-
 
2986
        ?array $params = null,
-
 
2987
        int $limitfrom = 0,
-
 
2988
        int $limitnum = 0,
-
 
2989
    ): array {
-
 
2990
        $fullcountsql = $this->generate_fullcount_sql($sql, $params, $fullcountcolumn);
-
 
2991
        if ($sort) {
-
 
2992
            // Remove "ORDER BY" with any extra spaces from $sort.
-
 
2993
            $sort = preg_replace('/\s*ORDER\s+BY\s*/i', '', $sort);
-
 
2994
            $fullcountsql .= " ORDER BY " . $sort;
-
 
2995
        }
-
 
2996
        return $this->get_records_sql($fullcountsql, $params, $limitfrom, $limitnum);
-
 
2997
    }
-
 
2998
 
-
 
2999
    /**
-
 
3000
     * Retrieve a recordset with a select query and count the total number of records.
-
 
3001
     *
-
 
3002
     * @param string $sql The query string.
-
 
3003
     * @param string $fullcountcolumn The column name used for counting total records.
-
 
3004
     * @param string $sort (Optional) Sorting criteria for the records.
-
 
3005
     *                      The reason to separate $sort from $sql are:
-
 
3006
     *                      1. The $sort needs to be placed outside the full count subquery
-
 
3007
     *                         in order to function properly in MariaDB.
-
 
3008
     *                      2. For unsupported databases, it is not allowed to run a query to get the total with the $sort.
-
 
3009
     *                         Please refer to the {@see ::generate_fullcount_sql()} for details.
-
 
3010
     * @param array|null $params (Optional) Parameters to bind with the query.
-
 
3011
     * @param int $limitfrom (Optional) Offset for pagination.
-
 
3012
     * @param int $limitnum (Optional) Limit for pagination.
-
 
3013
     * @return moodle_recordset A moodle_recordset instance..
-
 
3014
     */
-
 
3015
    public function get_counted_recordset_sql(
-
 
3016
        string $sql,
-
 
3017
        string $fullcountcolumn,
-
 
3018
        string $sort = '',
-
 
3019
        ?array $params = null,
-
 
3020
        int $limitfrom = 0,
-
 
3021
        int $limitnum = 0,
-
 
3022
    ): moodle_recordset {
-
 
3023
        $fullcountsql = $this->generate_fullcount_sql($sql, $params, $fullcountcolumn);
-
 
3024
        if ($sort) {
-
 
3025
            // Remove "ORDER BY" with any extra spaces from $sort.
-
 
3026
            $sort = preg_replace('/\s*ORDER\s+BY\s*/i', '', $sort);
-
 
3027
            $fullcountsql .= " ORDER BY " . $sort;
-
 
3028
        }
-
 
3029
        return $this->get_recordset_sql($fullcountsql, $params, $limitfrom, $limitnum);
-
 
3030
    }
-
 
3031
 
-
 
3032
    /**
-
 
3033
     * Helper function to generate window COUNT() aggregate function to the SQL query.
-
 
3034
     *
-
 
3035
     * @param string $sql The SQL select query to execute.
-
 
3036
     * @param array|null $params array of sql parameters
-
 
3037
     * @param string $fullcountcolumn An alias column name for the window function results.
-
 
3038
     * @return string The generated query.
-
 
3039
     */
-
 
3040
    private function generate_fullcount_sql(
-
 
3041
        string $sql,
-
 
3042
        ?array $params,
-
 
3043
        string $fullcountcolumn,
-
 
3044
    ): string {
-
 
3045
        $fullcountvalue = "COUNT(1) OVER()";
-
 
3046
        if (!$this->is_count_window_function_supported()) {
-
 
3047
            $sqlcount = "SELECT COUNT(1) FROM ($sql) results";
-
 
3048
            $fullcountvalue = $this->count_records_sql($sqlcount, $params);
-
 
3049
        }
-
 
3050
        return "SELECT results.*, $fullcountvalue AS $fullcountcolumn FROM ($sql) results";
-
 
3051
    }
2925
}
3052
}