| Línea 23... |
Línea 23... |
| 23 |
*/
|
23 |
*/
|
| Línea 24... |
Línea 24... |
| 24 |
|
24 |
|
| Línea 25... |
Línea 25... |
| 25 |
defined('MOODLE_INTERNAL') || die();
|
25 |
defined('MOODLE_INTERNAL') || die();
|
| 26 |
|
26 |
|
| 27 |
require_once(__DIR__.'/moodle_database.php');
|
27 |
require_once(__DIR__.'/moodle_database.php');
|
| 28 |
require_once(__DIR__.'/moodle_read_slave_trait.php');
|
28 |
require_once(__DIR__.'/moodle_read_replica_trait.php');
|
| Línea 29... |
Línea 29... |
| 29 |
require_once(__DIR__.'/pgsql_native_moodle_recordset.php');
|
29 |
require_once(__DIR__.'/pgsql_native_moodle_recordset.php');
|
| 30 |
require_once(__DIR__.'/pgsql_native_moodle_temptables.php');
|
30 |
require_once(__DIR__.'/pgsql_native_moodle_temptables.php');
|
| Línea 35... |
Línea 35... |
| 35 |
* @package core_dml
|
35 |
* @package core_dml
|
| 36 |
* @copyright 2008 Petr Skoda (http://skodak.org)
|
36 |
* @copyright 2008 Petr Skoda (http://skodak.org)
|
| 37 |
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
37 |
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
| 38 |
*/
|
38 |
*/
|
| 39 |
class pgsql_native_moodle_database extends moodle_database {
|
39 |
class pgsql_native_moodle_database extends moodle_database {
|
| 40 |
use moodle_read_slave_trait {
|
40 |
use moodle_read_replica_trait {
|
| 41 |
select_db_handle as read_slave_select_db_handle;
|
41 |
select_db_handle as read_replica_select_db_handle;
|
| 42 |
can_use_readonly as read_slave_can_use_readonly;
|
42 |
can_use_readonly as read_replica_can_use_readonly;
|
| 43 |
query_start as read_slave_query_start;
|
43 |
query_start as read_replica_query_start;
|
| 44 |
query_end as read_slave_query_end;
|
44 |
query_end as read_replica_query_end;
|
| 45 |
}
|
45 |
}
|
| Línea 46... |
Línea 46... |
| 46 |
|
46 |
|
| 47 |
/** @var array $sslmodes */
|
47 |
/** @var array $sslmodes */
|
| 48 |
private static $sslmodes = [
|
48 |
private static $sslmodes = [
|
| Línea 85... |
Línea 85... |
| 85 |
}
|
85 |
}
|
| Línea 86... |
Línea 86... |
| 86 |
|
86 |
|
| 87 |
/**
|
87 |
/**
|
| 88 |
* Returns database family type - describes SQL dialect
|
88 |
* Returns database family type - describes SQL dialect
|
| 89 |
* Note: can be used before connect()
|
89 |
* Note: can be used before connect()
|
| 90 |
* @return string db family name (mysql, postgres, mssql, oracle, etc.)
|
90 |
* @return string db family name (mysql, postgres, mssql, etc.)
|
| 91 |
*/
|
91 |
*/
|
| 92 |
public function get_dbfamily() {
|
92 |
public function get_dbfamily() {
|
| 93 |
return 'postgres';
|
93 |
return 'postgres';
|
| Línea 94... |
Línea 94... |
| 94 |
}
|
94 |
}
|
| 95 |
|
95 |
|
| 96 |
/**
|
96 |
/**
|
| 97 |
* Returns more specific database driver type
|
97 |
* Returns more specific database driver type
|
| 98 |
* Note: can be used before connect()
|
98 |
* Note: can be used before connect()
|
| 99 |
* @return string db type mysqli, pgsql, oci, mssql, sqlsrv
|
99 |
* @return string db type mysqli, pgsql, mssql, sqlsrv
|
| 100 |
*/
|
100 |
*/
|
| 101 |
protected function get_dbtype() {
|
101 |
protected function get_dbtype() {
|
| Línea 139... |
Línea 139... |
| 139 |
* @param array $dboptions driver specific options
|
139 |
* @param array $dboptions driver specific options
|
| 140 |
* @return bool true
|
140 |
* @return bool true
|
| 141 |
* @throws moodle_exception
|
141 |
* @throws moodle_exception
|
| 142 |
* @throws dml_connection_exception if error
|
142 |
* @throws dml_connection_exception if error
|
| 143 |
*/
|
143 |
*/
|
| 144 |
public function raw_connect(string $dbhost, string $dbuser, string $dbpass, string $dbname, $prefix, array $dboptions=null): bool {
|
144 |
public function raw_connect(string $dbhost, string $dbuser, string $dbpass, string $dbname, $prefix, ?array $dboptions=null): bool {
|
| 145 |
if ($prefix == '' and !$this->external) {
|
145 |
if ($prefix == '' and !$this->external) {
|
| 146 |
//Enforce prefixes for everybody but mysql
|
146 |
//Enforce prefixes for everybody but mysql
|
| 147 |
throw new dml_exception('prefixcannotbeempty', $this->get_dbfamily());
|
147 |
throw new dml_exception('prefixcannotbeempty', $this->get_dbfamily());
|
| 148 |
}
|
148 |
}
|
| Línea 295... |
Línea 295... |
| 295 |
* @param int $type type of query
|
295 |
* @param int $type type of query
|
| 296 |
* @param string $sql
|
296 |
* @param string $sql
|
| 297 |
* @return void
|
297 |
* @return void
|
| 298 |
*/
|
298 |
*/
|
| 299 |
protected function select_db_handle(int $type, string $sql): void {
|
299 |
protected function select_db_handle(int $type, string $sql): void {
|
| 300 |
$this->read_slave_select_db_handle($type, $sql);
|
300 |
$this->read_replica_select_db_handle($type, $sql);
|
| Línea 301... |
Línea 301... |
| 301 |
|
301 |
|
| 302 |
if (preg_match('/^DECLARE (crs\w*) NO SCROLL CURSOR/', $sql, $match)) {
|
302 |
if (preg_match('/^DECLARE (crs\w*) NO SCROLL CURSOR/', $sql, $match)) {
|
| 303 |
$cursor = $match[1];
|
303 |
$cursor = $match[1];
|
| 304 |
$this->dbhcursor[$cursor] = $this->pgsql;
|
304 |
$this->dbhcursor[$cursor] = $this->pgsql;
|
| Línea 316... |
Línea 316... |
| 316 |
* @param int $type type of query
|
316 |
* @param int $type type of query
|
| 317 |
* @param string $sql
|
317 |
* @param string $sql
|
| 318 |
* @return bool
|
318 |
* @return bool
|
| 319 |
*/
|
319 |
*/
|
| 320 |
protected function can_use_readonly(int $type, string $sql): bool {
|
320 |
protected function can_use_readonly(int $type, string $sql): bool {
|
| 321 |
// ... pg_*lock queries always go to master.
|
321 |
// ... pg_*lock queries always go to primary.
|
| 322 |
if (preg_match('/\bpg_\w*lock/', $sql)) {
|
322 |
if (preg_match('/\bpg_\w*lock/', $sql)) {
|
| 323 |
return false;
|
323 |
return false;
|
| 324 |
}
|
324 |
}
|
| Línea 325... |
Línea 325... |
| 325 |
|
325 |
|
| 326 |
// ... a nuisance - temptables use this.
|
326 |
// ... a nuisance - temptables use this.
|
| 327 |
if (preg_match('/\bpg_catalog/', $sql) && $this->temptables->get_temptables()) {
|
327 |
if (preg_match('/\bpg_catalog/', $sql) && $this->temptables->get_temptables()) {
|
| 328 |
return false;
|
328 |
return false;
|
| Línea 329... |
Línea 329... |
| 329 |
}
|
329 |
}
|
| Línea 330... |
Línea 330... |
| 330 |
|
330 |
|
| Línea 331... |
Línea 331... |
| 331 |
return $this->read_slave_can_use_readonly($type, $sql);
|
331 |
return $this->read_replica_can_use_readonly($type, $sql);
|
| 332 |
|
332 |
|
| Línea 339... |
Línea 339... |
| 339 |
* @param int $type type of query
|
339 |
* @param int $type type of query
|
| 340 |
* @param mixed $extrainfo driver specific extra information
|
340 |
* @param mixed $extrainfo driver specific extra information
|
| 341 |
* @return void
|
341 |
* @return void
|
| 342 |
*/
|
342 |
*/
|
| 343 |
protected function query_start($sql, ?array $params, $type, $extrainfo=null) {
|
343 |
protected function query_start($sql, ?array $params, $type, $extrainfo=null) {
|
| 344 |
$this->read_slave_query_start($sql, $params, $type, $extrainfo);
|
344 |
$this->read_replica_query_start($sql, $params, $type, $extrainfo);
|
| 345 |
// pgsql driver tends to send debug to output, we do not need that.
|
345 |
// pgsql driver tends to send debug to output, we do not need that.
|
| 346 |
$this->last_error_reporting = error_reporting(0);
|
346 |
$this->last_error_reporting = error_reporting(0);
|
| 347 |
}
|
347 |
}
|
| Línea 348... |
Línea 348... |
| 348 |
|
348 |
|
| Línea 353... |
Línea 353... |
| 353 |
*/
|
353 |
*/
|
| 354 |
protected function query_end($result) {
|
354 |
protected function query_end($result) {
|
| 355 |
// reset original debug level
|
355 |
// reset original debug level
|
| 356 |
error_reporting($this->last_error_reporting);
|
356 |
error_reporting($this->last_error_reporting);
|
| 357 |
try {
|
357 |
try {
|
| 358 |
$this->read_slave_query_end($result);
|
358 |
$this->read_replica_query_end($result);
|
| 359 |
if ($this->savepointpresent &&
|
359 |
if ($this->savepointpresent &&
|
| 360 |
!in_array(
|
360 |
!in_array(
|
| 361 |
$this->last_type,
|
361 |
$this->last_type,
|
| 362 |
[SQL_QUERY_AUX, SQL_QUERY_AUX_READONLY, SQL_QUERY_SELECT],
|
362 |
[SQL_QUERY_AUX, SQL_QUERY_AUX_READONLY, SQL_QUERY_SELECT],
|
| 363 |
true
|
363 |
true
|
| Línea 849... |
Línea 849... |
| 849 |
* @param string $sql query
|
849 |
* @param string $sql query
|
| 850 |
* @param array $params query parameters
|
850 |
* @param array $params query parameters
|
| 851 |
* @return bool true
|
851 |
* @return bool true
|
| 852 |
* @throws dml_exception A DML specific exception is thrown for any errors.
|
852 |
* @throws dml_exception A DML specific exception is thrown for any errors.
|
| 853 |
*/
|
853 |
*/
|
| 854 |
public function execute($sql, array $params=null) {
|
854 |
public function execute($sql, ?array $params=null) {
|
| 855 |
list($sql, $params, $type) = $this->fix_sql_params($sql, $params);
|
855 |
list($sql, $params, $type) = $this->fix_sql_params($sql, $params);
|
| Línea 856... |
Línea 856... |
| 856 |
|
856 |
|
| 857 |
if (strpos($sql, ';') !== false) {
|
857 |
if (strpos($sql, ';') !== false) {
|
| 858 |
throw new coding_exception('moodle_database::execute() Multiple sql statements found or bound parameters not used properly in query!');
|
858 |
throw new coding_exception('moodle_database::execute() Multiple sql statements found or bound parameters not used properly in query!');
|
| Línea 881... |
Línea 881... |
| 881 |
* @param int $limitfrom return a subset of records, starting at this point (optional, required if $limitnum is set).
|
881 |
* @param int $limitfrom return a subset of records, starting at this point (optional, required if $limitnum is set).
|
| 882 |
* @param int $limitnum return a subset comprising this many records (optional, required if $limitfrom is set).
|
882 |
* @param int $limitnum return a subset comprising this many records (optional, required if $limitfrom is set).
|
| 883 |
* @return moodle_recordset instance
|
883 |
* @return moodle_recordset instance
|
| 884 |
* @throws dml_exception A DML specific exception is thrown for any errors.
|
884 |
* @throws dml_exception A DML specific exception is thrown for any errors.
|
| 885 |
*/
|
885 |
*/
|
| 886 |
public function get_recordset_sql($sql, array $params=null, $limitfrom=0, $limitnum=0) {
|
886 |
public function get_recordset_sql($sql, ?array $params=null, $limitfrom=0, $limitnum=0) {
|
| Línea 887... |
Línea 887... |
| 887 |
|
887 |
|
| Línea 888... |
Línea 888... |
| 888 |
list($limitfrom, $limitnum) = $this->normalise_limit_from_num($limitfrom, $limitnum);
|
888 |
list($limitfrom, $limitnum) = $this->normalise_limit_from_num($limitfrom, $limitnum);
|
| 889 |
|
889 |
|
| Línea 1026... |
Línea 1026... |
| 1026 |
* @param int $limitfrom return a subset of records, starting at this point (optional, required if $limitnum is set).
|
1026 |
* @param int $limitfrom return a subset of records, starting at this point (optional, required if $limitnum is set).
|
| 1027 |
* @param int $limitnum return a subset comprising this many records (optional, required if $limitfrom is set).
|
1027 |
* @param int $limitnum return a subset comprising this many records (optional, required if $limitfrom is set).
|
| 1028 |
* @return array of objects, or empty array if no records were found
|
1028 |
* @return array of objects, or empty array if no records were found
|
| 1029 |
* @throws dml_exception A DML specific exception is thrown for any errors.
|
1029 |
* @throws dml_exception A DML specific exception is thrown for any errors.
|
| 1030 |
*/
|
1030 |
*/
|
| 1031 |
public function get_records_sql($sql, array $params = null, $limitfrom = 0, $limitnum = 0) {
|
1031 |
public function get_records_sql($sql, ?array $params = null, $limitfrom = 0, $limitnum = 0) {
|
| 1032 |
list($limitfrom, $limitnum) = $this->normalise_limit_from_num($limitfrom, $limitnum);
|
1032 |
list($limitfrom, $limitnum) = $this->normalise_limit_from_num($limitfrom, $limitnum);
|
| Línea 1033... |
Línea 1033... |
| 1033 |
|
1033 |
|
| 1034 |
if ($limitnum) {
|
1034 |
if ($limitnum) {
|
| 1035 |
$sql .= " LIMIT $limitnum";
|
1035 |
$sql .= " LIMIT $limitnum";
|
| Línea 1077... |
Línea 1077... |
| 1077 |
* @param string $sql The SQL query
|
1077 |
* @param string $sql The SQL query
|
| 1078 |
* @param array $params array of sql parameters
|
1078 |
* @param array $params array of sql parameters
|
| 1079 |
* @return array of values
|
1079 |
* @return array of values
|
| 1080 |
* @throws dml_exception A DML specific exception is thrown for any errors.
|
1080 |
* @throws dml_exception A DML specific exception is thrown for any errors.
|
| 1081 |
*/
|
1081 |
*/
|
| 1082 |
public function get_fieldset_sql($sql, array $params=null) {
|
1082 |
public function get_fieldset_sql($sql, ?array $params=null) {
|
| 1083 |
list($sql, $params, $type) = $this->fix_sql_params($sql, $params);
|
1083 |
list($sql, $params, $type) = $this->fix_sql_params($sql, $params);
|
| Línea 1084... |
Línea 1084... |
| 1084 |
|
1084 |
|
| 1085 |
$this->query_start($sql, $params, SQL_QUERY_SELECT);
|
1085 |
$this->query_start($sql, $params, SQL_QUERY_SELECT);
|
| 1086 |
$result = pg_query_params($this->pgsql, $sql, $params);
|
1086 |
$result = pg_query_params($this->pgsql, $sql, $params);
|
| Línea 1403... |
Línea 1403... |
| 1403 |
* @param string $select A fragment of SQL to be used in a where clause in the SQL call.
|
1403 |
* @param string $select A fragment of SQL to be used in a where clause in the SQL call.
|
| 1404 |
* @param array $params array of sql parameters
|
1404 |
* @param array $params array of sql parameters
|
| 1405 |
* @return bool true
|
1405 |
* @return bool true
|
| 1406 |
* @throws dml_exception A DML specific exception is thrown for any errors.
|
1406 |
* @throws dml_exception A DML specific exception is thrown for any errors.
|
| 1407 |
*/
|
1407 |
*/
|
| 1408 |
public function set_field_select($table, $newfield, $newvalue, $select, array $params=null) {
|
1408 |
public function set_field_select($table, $newfield, $newvalue, $select, ?array $params=null) {
|
| Línea 1409... |
Línea 1409... |
| 1409 |
|
1409 |
|
| 1410 |
if ($select) {
|
1410 |
if ($select) {
|
| 1411 |
$select = "WHERE $select";
|
1411 |
$select = "WHERE $select";
|
| 1412 |
}
|
1412 |
}
|
| Línea 1442... |
Línea 1442... |
| 1442 |
* @param string $select A fragment of SQL to be used in a where clause in the SQL call (used to define the selection criteria).
|
1442 |
* @param string $select A fragment of SQL to be used in a where clause in the SQL call (used to define the selection criteria).
|
| 1443 |
* @param array $params array of sql parameters
|
1443 |
* @param array $params array of sql parameters
|
| 1444 |
* @return bool true
|
1444 |
* @return bool true
|
| 1445 |
* @throws dml_exception A DML specific exception is thrown for any errors.
|
1445 |
* @throws dml_exception A DML specific exception is thrown for any errors.
|
| 1446 |
*/
|
1446 |
*/
|
| 1447 |
public function delete_records_select($table, $select, array $params=null) {
|
1447 |
public function delete_records_select($table, $select, ?array $params=null) {
|
| 1448 |
if ($select) {
|
1448 |
if ($select) {
|
| 1449 |
$select = "WHERE $select";
|
1449 |
$select = "WHERE $select";
|
| 1450 |
}
|
1450 |
}
|
| 1451 |
$sql = "DELETE FROM {$this->prefix}$table $select";
|
1451 |
$sql = "DELETE FROM {$this->prefix}$table $select";
|
| Línea 1720... |
Línea 1720... |
| 1720 |
* @return bool
|
1720 |
* @return bool
|
| 1721 |
*/
|
1721 |
*/
|
| 1722 |
public function is_fulltext_search_supported() {
|
1722 |
public function is_fulltext_search_supported() {
|
| 1723 |
return true;
|
1723 |
return true;
|
| 1724 |
}
|
1724 |
}
|
| - |
|
1725 |
|
| - |
|
1726 |
/**
|
| - |
|
1727 |
* Postgresql supports the COUNT() window function and provides a performance improvement.
|
| - |
|
1728 |
*
|
| - |
|
1729 |
* @return bool
|
| - |
|
1730 |
*/
|
| - |
|
1731 |
public function is_count_window_function_supported(): bool {
|
| - |
|
1732 |
return true;
|
| - |
|
1733 |
}
|
| 1725 |
}
|
1734 |
}
|