Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 3.11.x will end 14 Nov 2022 (12 months plus 6 months extension).
  • Bug fixes for security issues in 3.11.x will end 13 Nov 2023 (18 months plus 12 months extension).
  • PHP version: minimum PHP 7.3.0 Note: minimum PHP version has increased since Moodle 3.10. PHP 7.4.x is supported too.

Differences Between: [Versions 310 and 311] [Versions 311 and 400] [Versions 311 and 401] [Versions 311 and 402] [Versions 311 and 403] [Versions 39 and 311]

   1  <?php
   2  /*
   3  @version   v5.21.0  2021-02-27
   4  @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
   5  @copyright (c) 2014      Damien Regad, Mark Newnham and the ADOdb community
   6    Released under both BSD license and Lesser GPL library license.
   7    Whenever there is any discrepancy between the two licenses,
   8    the BSD license will take precedence.
   9    Set tabs to 8.
  10  
  11  */
  12  
  13  class ADODB_pdo_mysql extends ADODB_pdo {
  14  
  15  	 var $metaTablesSQL = "SELECT
  16  	 	 	 TABLE_NAME,
  17  	 	 	 CASE WHEN TABLE_TYPE = 'VIEW' THEN 'V' ELSE 'T' END
  18  	 	 FROM INFORMATION_SCHEMA.TABLES
  19  	 	 WHERE TABLE_SCHEMA=";
  20  	 var $metaColumnsSQL = "SHOW COLUMNS FROM `%s`";
  21  	 var $sysDate = 'CURDATE()';
  22  	 var $sysTimeStamp = 'NOW()';
  23  	 var $hasGenID = true;
  24  	 var $_genIDSQL = "UPDATE %s SET id=LAST_INSERT_ID(id+1);";
  25  	 var $_genSeqSQL = "CREATE TABLE  if NOT EXISTS %s (id int not null)";
  26  	 var $_genSeqCountSQL = "SELECT count(*) FROM %s";
  27  	 var $_genSeq2SQL = "INSERT INTO %s VALUES (%s)";
  28  	 var $_dropSeqSQL = "drop table %s";
  29  	 var $fmtTimeStamp = "'Y-m-d H:i:s'";
  30  	 var $nameQuote = '`';
  31  
  32  	function _init($parentDriver)
  33  	 {
  34  	 	 $parentDriver->hasTransactions = false;
  35  	 	 #$parentDriver->_bindInputArray = false;
  36  	 	 $parentDriver->hasInsertID = true;
  37  	 	 $parentDriver->_connectionID->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true);
  38  	 }
  39  
  40  	 // dayFraction is a day in floating point
  41  	function OffsetDate($dayFraction, $date=false)
  42  	 {
  43  	 	 if (!$date) {
  44  	 	 	 $date = $this->sysDate;
  45  	 	 }
  46  
  47  	 	 $fraction = $dayFraction * 24 * 3600;
  48  	 	 return $date . ' + INTERVAL ' .	 $fraction . ' SECOND';
  49  //	 	 return "from_unixtime(unix_timestamp($date)+$fraction)";
  50  	 }
  51  
  52  	function Concat()
  53  	 {
  54  	 	 $s = '';
  55  	 	 $arr = func_get_args();
  56  
  57  	 	 // suggestion by andrew005#mnogo.ru
  58  	 	 $s = implode(',', $arr);
  59  	 	 if (strlen($s) > 0) {
  60  	 	 	 return "CONCAT($s)";
  61  	 	 }
  62  	 	 return '';
  63  	 }
  64  
  65  	function ServerInfo()
  66  	 {
  67  	 	 $arr['description'] = ADOConnection::GetOne('select version()');
  68  	 	 $arr['version'] = ADOConnection::_findvers($arr['description']);
  69  	 	 return $arr;
  70  	 }
  71  
  72  	function MetaTables($ttype=false, $showSchema=false, $mask=false)
  73  	 {
  74  	 	 $save = $this->metaTablesSQL;
  75  	 	 if ($showSchema && is_string($showSchema)) {
  76  	 	 	 $this->metaTablesSQL .= $this->qstr($showSchema);
  77  	 	 } else {
  78  	 	 	 $this->metaTablesSQL .= 'schema()';
  79  	 	 }
  80  
  81  	 	 if ($mask) {
  82  	 	 	 $mask = $this->qstr($mask);
  83  	 	 	 $this->metaTablesSQL .= " like $mask";
  84  	 	 }
  85  	 	 $ret = ADOConnection::MetaTables($ttype, $showSchema);
  86  
  87  	 	 $this->metaTablesSQL = $save;
  88  	 	 return $ret;
  89  	 }
  90  
  91      /**
  92       * @param bool $auto_commit
  93       * @return void
  94       */
  95      function SetAutoCommit($auto_commit)
  96      {
  97          $this->_connectionID->setAttribute(PDO::ATTR_AUTOCOMMIT, $auto_commit);
  98      }
  99  
 100  	function SetTransactionMode($transaction_mode)
 101  	 {
 102  	 	 $this->_transmode  = $transaction_mode;
 103  	 	 if (empty($transaction_mode)) {
 104  	 	 	 $this->Execute('SET TRANSACTION ISOLATION LEVEL REPEATABLE READ');
 105  	 	 	 return;
 106  	 	 }
 107  	 	 if (!stristr($transaction_mode, 'isolation')) {
 108  	 	 	 $transaction_mode = 'ISOLATION LEVEL ' . $transaction_mode;
 109  	 	 }
 110  	 	 $this->Execute('SET SESSION TRANSACTION ' . $transaction_mode);
 111  	 }
 112  
 113  	function MetaColumns($table, $normalize=true)
 114  	 {
 115  	 	 $this->_findschema($table, $schema);
 116  	 	 if ($schema) {
 117  	 	 	 $dbName = $this->database;
 118  	 	 	 $this->SelectDB($schema);
 119  	 	 }
 120  	 	 global $ADODB_FETCH_MODE;
 121  	 	 $save = $ADODB_FETCH_MODE;
 122  	 	 $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
 123  
 124  	 	 if ($this->fetchMode !== false) {
 125  	 	 	 $savem = $this->SetFetchMode(false);
 126  	 	 }
 127  	 	 $rs = $this->Execute(sprintf($this->metaColumnsSQL, $table));
 128  
 129  	 	 if ($schema) {
 130  	 	 	 $this->SelectDB($dbName);
 131  	 	 }
 132  
 133  	 	 if (isset($savem)) {
 134  	 	 	 $this->SetFetchMode($savem);
 135  	 	 }
 136  	 	 $ADODB_FETCH_MODE = $save;
 137  	 	 if (!is_object($rs)) {
 138  	 	 	 $false = false;
 139  	 	 	 return $false;
 140  	 	 }
 141  
 142  	 	 $retarr = array();
 143  	 	 while (!$rs->EOF){
 144  	 	 	 $fld = new ADOFieldObject();
 145  	 	 	 $fld->name = $rs->fields[0];
 146  	 	 	 $type = $rs->fields[1];
 147  
 148  	 	 	 // split type into type(length):
 149  	 	 	 $fld->scale = null;
 150  	 	 	 if (preg_match('/^(.+)\((\d+),(\d+)/', $type, $query_array)) {
 151  	 	 	 	 $fld->type = $query_array[1];
 152  	 	 	 	 $fld->max_length = is_numeric($query_array[2]) ? $query_array[2] : -1;
 153  	 	 	 	 $fld->scale = is_numeric($query_array[3]) ? $query_array[3] : -1;
 154  	 	 	 } elseif (preg_match('/^(.+)\((\d+)/', $type, $query_array)) {
 155  	 	 	 	 $fld->type = $query_array[1];
 156  	 	 	 	 $fld->max_length = is_numeric($query_array[2]) ? $query_array[2] : -1;
 157  	 	 	 } elseif (preg_match('/^(enum)\((.*)\)$/i', $type, $query_array)) {
 158  	 	 	 	 $fld->type = $query_array[1];
 159  	 	 	 	 $arr = explode(',', $query_array[2]);
 160  	 	 	 	 $fld->enums = $arr;
 161  	 	 	 	 $zlen = max(array_map('strlen', $arr)) - 2; // PHP >= 4.0.6
 162  	 	 	 	 $fld->max_length = ($zlen > 0) ? $zlen : 1;
 163  	 	 	 } else {
 164  	 	 	 	 $fld->type = $type;
 165  	 	 	 	 $fld->max_length = -1;
 166  	 	 	 }
 167  	 	 	 $fld->not_null = ($rs->fields[2] != 'YES');
 168  	 	 	 $fld->primary_key = ($rs->fields[3] == 'PRI');
 169  	 	 	 $fld->auto_increment = (strpos($rs->fields[5], 'auto_increment') !== false);
 170  	 	 	 $fld->binary = (strpos($type, 'blob') !== false);
 171  	 	 	 $fld->unsigned = (strpos($type, 'unsigned') !== false);
 172  
 173  	 	 	 if (!$fld->binary) {
 174  	 	 	 	 $d = $rs->fields[4];
 175  	 	 	 	 if ($d != '' && $d != 'NULL') {
 176  	 	 	 	 	 $fld->has_default = true;
 177  	 	 	 	 	 $fld->default_value = $d;
 178  	 	 	 	 } else {
 179  	 	 	 	 	 $fld->has_default = false;
 180  	 	 	 	 }
 181  	 	 	 }
 182  
 183  	 	 	 if ($save == ADODB_FETCH_NUM) {
 184  	 	 	 	 $retarr[] = $fld;
 185  	 	 	 } else {
 186  	 	 	 	 $retarr[strtoupper($fld->name)] = $fld;
 187  	 	 	 }
 188  	 	 	 $rs->MoveNext();
 189  	 	 }
 190  
 191  	 	 $rs->Close();
 192  	 	 return $retarr;
 193  	 }
 194  
 195  	 // returns true or false
 196  	function SelectDB($dbName)
 197  	 {
 198  	 	 $this->database = $dbName;
 199  	 	 $this->databaseName = $dbName; # obsolete, retained for compat with older adodb versions
 200  	 	 $try = $this->Execute('use ' . $dbName);
 201  	 	 return ($try !== false);
 202  	 }
 203  
 204  	 // parameters use PostgreSQL convention, not MySQL
 205  	function SelectLimit($sql, $nrows=-1, $offset=-1, $inputarr=false, $secs=0)
 206  	 {
 207  	 	 $nrows = (int) $nrows;
 208  	 	 $offset = (int) $offset;	 	 
 209  	 	 $offsetStr =($offset>=0) ? "$offset," : '';
 210  	 	 // jason judge, see PHPLens Issue No: 9220
 211  	 	 if ($nrows < 0) {
 212  	 	 	 $nrows = '18446744073709551615';
 213  	 	 }
 214  
 215  	 	 if ($secs) {
 216  	 	 	 $rs = $this->CacheExecute($secs, $sql . " LIMIT $offsetStr$nrows", $inputarr);
 217  	 	 } else {
 218  	 	 	 $rs = $this->Execute($sql . " LIMIT $offsetStr$nrows", $inputarr);
 219  	 	 }
 220  	 	 return $rs;
 221  	 }
 222  
 223  	function SQLDate($fmt, $col=false)
 224  	 {
 225  	 	 if (!$col) {
 226  	 	 	 $col = $this->sysTimeStamp;
 227  	 	 }
 228  	 	 $s = 'DATE_FORMAT(' . $col . ",'";
 229  	 	 $concat = false;
 230  	 	 $len = strlen($fmt);
 231  	 	 for ($i=0; $i < $len; $i++) {
 232  	 	 	 $ch = $fmt[$i];
 233  	 	 	 switch($ch) {
 234  
 235  	 	 	 	 default:
 236  	 	 	 	 	 if ($ch == '\\') {
 237  	 	 	 	 	 	 $i++;
 238  	 	 	 	 	 	 $ch = substr($fmt, $i, 1);
 239  	 	 	 	 	 }
 240  	 	 	 	 	 // FALL THROUGH
 241  	 	 	 	 case '-':
 242  	 	 	 	 case '/':
 243  	 	 	 	 	 $s .= $ch;
 244  	 	 	 	 	 break;
 245  
 246  	 	 	 	 case 'Y':
 247  	 	 	 	 case 'y':
 248  	 	 	 	 	 $s .= '%Y';
 249  	 	 	 	 	 break;
 250  
 251  	 	 	 	 case 'M':
 252  	 	 	 	 	 $s .= '%b';
 253  	 	 	 	 	 break;
 254  
 255  	 	 	 	 case 'm':
 256  	 	 	 	 	 $s .= '%m';
 257  	 	 	 	 	 break;
 258  
 259  	 	 	 	 case 'D':
 260  	 	 	 	 case 'd':
 261  	 	 	 	 	 $s .= '%d';
 262  	 	 	 	 	 break;
 263  
 264  	 	 	 	 case 'Q':
 265  	 	 	 	 case 'q':
 266  	 	 	 	 	 $s .= "'),Quarter($col)";
 267  
 268  	 	 	 	 	 if ($len > $i+1) {
 269  	 	 	 	 	 	 $s .= ",DATE_FORMAT($col,'";
 270  	 	 	 	 	 } else {
 271  	 	 	 	 	 	 $s .= ",('";
 272  	 	 	 	 	 }
 273  	 	 	 	 	 $concat = true;
 274  	 	 	 	 	 break;
 275  
 276  	 	 	 	 case 'H':
 277  	 	 	 	 	 $s .= '%H';
 278  	 	 	 	 	 break;
 279  
 280  	 	 	 	 case 'h':
 281  	 	 	 	 	 $s .= '%I';
 282  	 	 	 	 	 break;
 283  
 284  	 	 	 	 case 'i':
 285  	 	 	 	 	 $s .= '%i';
 286  	 	 	 	 	 break;
 287  
 288  	 	 	 	 case 's':
 289  	 	 	 	 	 $s .= '%s';
 290  	 	 	 	 	 break;
 291  
 292  	 	 	 	 case 'a':
 293  	 	 	 	 case 'A':
 294  	 	 	 	 	 $s .= '%p';
 295  	 	 	 	 	 break;
 296  
 297  	 	 	 	 case 'w':
 298  	 	 	 	 	 $s .= '%w';
 299  	 	 	 	 	 break;
 300  
 301  	 	 	 	 case 'W':
 302  	 	 	 	 	 $s .= '%U';
 303  	 	 	 	 	 break;
 304  
 305  	 	 	 	 case 'l':
 306  	 	 	 	 	 $s .= '%W';
 307  	 	 	 	 	 break;
 308  	 	 	 }
 309  	 	 }
 310  	 	 $s .= "')";
 311  	 	 if ($concat) {
 312  	 	 	 $s = "CONCAT($s)";
 313  	 	 }
 314  	 	 return $s;
 315  	 }
 316  
 317  	function GenID($seqname='adodbseq',$startID=1)
 318  	 {
 319  	 	 $getnext = sprintf($this->_genIDSQL,$seqname);
 320  	 	 $holdtransOK = $this->_transOK; // save the current status
 321  	 	 $rs = @$this->Execute($getnext);
 322  	 	 if (!$rs) {
 323  	 	 	 if ($holdtransOK) $this->_transOK = true; //if the status was ok before reset
 324  	 	 	 $this->Execute(sprintf($this->_genSeqSQL,$seqname));
 325  	 	 	 $cnt = $this->GetOne(sprintf($this->_genSeqCountSQL,$seqname));
 326  	 	 	 if (!$cnt) $this->Execute(sprintf($this->_genSeq2SQL,$seqname,$startID-1));
 327  	 	 	 $rs = $this->Execute($getnext);
 328  	 	 }
 329  
 330  	 	 if ($rs) {
 331  	 	 	 $this->genID = $this->_connectionID->lastInsertId($seqname);
 332  	 	 	 $rs->Close();
 333  	 	 } else {
 334  	 	 	 $this->genID = 0;
 335  	 	 }
 336  
 337  	 	 return $this->genID;
 338  	 }
 339  
 340  
 341  	function createSequence($seqname='adodbseq',$startID=1)
 342  	 {
 343  	 	 if (empty($this->_genSeqSQL)) {
 344  	 	 	 return false;
 345  	 	 }
 346  	 	 $ok = $this->Execute(sprintf($this->_genSeqSQL,$seqname,$startID));
 347  	 	 if (!$ok) {
 348  	 	 	 return false;
 349  	 	 }
 350  
 351  	 	 return $this->Execute(sprintf($this->_genSeq2SQL,$seqname,$startID-1));
 352  	 }
 353  }