See Release Notes
Long Term Support Release
Differences Between: [Versions 310 and 401] [Versions 311 and 401] [Versions 39 and 401] [Versions 401 and 402] [Versions 401 and 403]
1 <?php 2 /** 3 * PDO MySQL driver 4 * 5 * This file is part of ADOdb, a Database Abstraction Layer library for PHP. 6 * 7 * @package ADOdb 8 * @link https://adodb.org Project's web site and documentation 9 * @link https://github.com/ADOdb/ADOdb Source code and issue tracker 10 * 11 * The ADOdb Library is dual-licensed, released under both the BSD 3-Clause 12 * and the GNU Lesser General Public Licence (LGPL) v2.1 or, at your option, 13 * any later version. This means you can use it in proprietary products. 14 * See the LICENSE.md file distributed with this source code for details. 15 * @license BSD-3-Clause 16 * @license LGPL-2.1-or-later 17 * 18 * @copyright 2000-2013 John Lim 19 * @copyright 2014 Damien Regad, Mark Newnham and the ADOdb community 20 */ 21 22 class ADODB_pdo_mysql extends ADODB_pdo { 23 24 var $metaTablesSQL = "SELECT 25 TABLE_NAME, 26 CASE WHEN TABLE_TYPE = 'VIEW' THEN 'V' ELSE 'T' END 27 FROM INFORMATION_SCHEMA.TABLES 28 WHERE TABLE_SCHEMA="; 29 var $metaColumnsSQL = "SHOW COLUMNS FROM `%s`"; 30 var $sysDate = 'CURDATE()'; 31 var $sysTimeStamp = 'NOW()'; 32 var $hasGenID = true; 33 var $_genIDSQL = "UPDATE %s SET id=LAST_INSERT_ID(id+1);"; 34 var $_genSeqSQL = "CREATE TABLE if NOT EXISTS %s (id int not null)"; 35 var $_genSeqCountSQL = "SELECT count(*) FROM %s"; 36 var $_genSeq2SQL = "INSERT INTO %s VALUES (%s)"; 37 var $_dropSeqSQL = "drop table %s"; 38 var $fmtTimeStamp = "'Y-m-d H:i:s'"; 39 var $nameQuote = '`'; 40 41 function _init($parentDriver) 42 { 43 $parentDriver->hasTransactions = false; 44 #$parentDriver->_bindInputArray = false; 45 $parentDriver->hasInsertID = true; 46 $parentDriver->_connectionID->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true); 47 } 48 49 // dayFraction is a day in floating point 50 function OffsetDate($dayFraction, $date=false) 51 { 52 if (!$date) { 53 $date = $this->sysDate; 54 } 55 56 $fraction = $dayFraction * 24 * 3600; 57 return $date . ' + INTERVAL ' . $fraction . ' SECOND'; 58 // return "from_unixtime(unix_timestamp($date)+$fraction)"; 59 } 60 61 /** 62 * Get a list of indexes on the specified table. 63 * 64 * @param string $table The name of the table to get indexes for. 65 * @param bool $primary (Optional) Whether or not to include the primary key. 66 * @param bool $owner (Optional) Unused. 67 * 68 * @return array|bool An array of the indexes, or false if the query to get the indexes failed. 69 */ 70 function metaIndexes($table, $primary = false, $owner = false) 71 { 72 // save old fetch mode 73 global $ADODB_FETCH_MODE; 74 75 $false = false; 76 $save = $ADODB_FETCH_MODE; 77 $ADODB_FETCH_MODE = ADODB_FETCH_NUM; 78 if ($this->fetchMode !== FALSE) { 79 $savem = $this->setFetchMode(FALSE); 80 } 81 82 // get index details 83 $rs = $this->execute(sprintf('SHOW INDEXES FROM %s',$table)); 84 85 // restore fetchmode 86 if (isset($savem)) { 87 $this->setFetchMode($savem); 88 } 89 $ADODB_FETCH_MODE = $save; 90 91 if (!is_object($rs)) { 92 return $false; 93 } 94 95 $indexes = array (); 96 97 // parse index data into array 98 while ($row = $rs->fetchRow()) { 99 if ($primary == FALSE AND $row[2] == 'PRIMARY') { 100 continue; 101 } 102 103 if (!isset($indexes[$row[2]])) { 104 $indexes[$row[2]] = array( 105 'unique' => ($row[1] == 0), 106 'columns' => array() 107 ); 108 } 109 110 $indexes[$row[2]]['columns'][$row[3] - 1] = $row[4]; 111 } 112 113 // sort columns by order in the index 114 foreach ( array_keys ($indexes) as $index ) 115 { 116 ksort ($indexes[$index]['columns']); 117 } 118 119 return $indexes; 120 } 121 122 function Concat() 123 { 124 $s = ''; 125 $arr = func_get_args(); 126 127 // suggestion by andrew005#mnogo.ru 128 $s = implode(',', $arr); 129 if (strlen($s) > 0) { 130 return "CONCAT($s)"; 131 } 132 return ''; 133 } 134 135 function ServerInfo() 136 { 137 $arr['description'] = ADOConnection::GetOne('select version()'); 138 $arr['version'] = ADOConnection::_findvers($arr['description']); 139 return $arr; 140 } 141 142 function MetaTables($ttype=false, $showSchema=false, $mask=false) 143 { 144 $save = $this->metaTablesSQL; 145 if ($showSchema && is_string($showSchema)) { 146 $this->metaTablesSQL .= $this->qstr($showSchema); 147 } else { 148 $this->metaTablesSQL .= 'schema()'; 149 } 150 151 if ($mask) { 152 $mask = $this->qstr($mask); 153 $this->metaTablesSQL .= " like $mask"; 154 } 155 $ret = ADOConnection::MetaTables($ttype, $showSchema); 156 157 $this->metaTablesSQL = $save; 158 return $ret; 159 } 160 161 /** 162 * @param bool $auto_commit 163 * @return void 164 */ 165 function SetAutoCommit($auto_commit) 166 { 167 $this->_connectionID->setAttribute(PDO::ATTR_AUTOCOMMIT, $auto_commit); 168 } 169 170 function SetTransactionMode($transaction_mode) 171 { 172 $this->_transmode = $transaction_mode; 173 if (empty($transaction_mode)) { 174 $this->Execute('SET TRANSACTION ISOLATION LEVEL REPEATABLE READ'); 175 return; 176 } 177 if (!stristr($transaction_mode, 'isolation')) { 178 $transaction_mode = 'ISOLATION LEVEL ' . $transaction_mode; 179 } 180 $this->Execute('SET SESSION TRANSACTION ' . $transaction_mode); 181 } 182 183 function MetaColumns($table, $normalize=true) 184 { 185 $this->_findschema($table, $schema); 186 if ($schema) { 187 $dbName = $this->database; 188 $this->SelectDB($schema); 189 } 190 global $ADODB_FETCH_MODE; 191 $save = $ADODB_FETCH_MODE; 192 $ADODB_FETCH_MODE = ADODB_FETCH_NUM; 193 194 if ($this->fetchMode !== false) { 195 $savem = $this->SetFetchMode(false); 196 } 197 $rs = $this->Execute(sprintf($this->metaColumnsSQL, $table)); 198 199 if ($schema) { 200 $this->SelectDB($dbName); 201 } 202 203 if (isset($savem)) { 204 $this->SetFetchMode($savem); 205 } 206 $ADODB_FETCH_MODE = $save; 207 if (!is_object($rs)) { 208 $false = false; 209 return $false; 210 } 211 212 $retarr = array(); 213 while (!$rs->EOF){ 214 $fld = new ADOFieldObject(); 215 $fld->name = $rs->fields[0]; 216 $type = $rs->fields[1]; 217 218 // split type into type(length): 219 $fld->scale = null; 220 if (preg_match('/^(.+)\((\d+),(\d+)/', $type, $query_array)) { 221 $fld->type = $query_array[1]; 222 $fld->max_length = is_numeric($query_array[2]) ? $query_array[2] : -1; 223 $fld->scale = is_numeric($query_array[3]) ? $query_array[3] : -1; 224 } elseif (preg_match('/^(.+)\((\d+)/', $type, $query_array)) { 225 $fld->type = $query_array[1]; 226 $fld->max_length = is_numeric($query_array[2]) ? $query_array[2] : -1; 227 } elseif (preg_match('/^(enum)\((.*)\)$/i', $type, $query_array)) { 228 $fld->type = $query_array[1]; 229 $arr = explode(',', $query_array[2]); 230 $fld->enums = $arr; 231 $zlen = max(array_map('strlen', $arr)) - 2; // PHP >= 4.0.6 232 $fld->max_length = ($zlen > 0) ? $zlen : 1; 233 } else { 234 $fld->type = $type; 235 $fld->max_length = -1; 236 } 237 $fld->not_null = ($rs->fields[2] != 'YES'); 238 $fld->primary_key = ($rs->fields[3] == 'PRI'); 239 $fld->auto_increment = (strpos($rs->fields[5], 'auto_increment') !== false); 240 $fld->binary = (strpos($type, 'blob') !== false); 241 $fld->unsigned = (strpos($type, 'unsigned') !== false); 242 243 if (!$fld->binary) { 244 $d = $rs->fields[4]; 245 if ($d != '' && $d != 'NULL') { 246 $fld->has_default = true; 247 $fld->default_value = $d; 248 } else { 249 $fld->has_default = false; 250 } 251 } 252 253 if ($save == ADODB_FETCH_NUM) { 254 $retarr[] = $fld; 255 } else { 256 $retarr[strtoupper($fld->name)] = $fld; 257 } 258 $rs->MoveNext(); 259 } 260 261 $rs->Close(); 262 return $retarr; 263 } 264 265 // returns true or false 266 function SelectDB($dbName) 267 { 268 $this->database = $dbName; 269 $this->databaseName = $dbName; # obsolete, retained for compat with older adodb versions 270 $try = $this->Execute('use ' . $dbName); 271 return ($try !== false); 272 } 273 274 // parameters use PostgreSQL convention, not MySQL 275 function SelectLimit($sql, $nrows=-1, $offset=-1, $inputarr=false, $secs=0) 276 { 277 $nrows = (int) $nrows; 278 $offset = (int) $offset; 279 $offsetStr =($offset>=0) ? "$offset," : ''; 280 // jason judge, see PHPLens Issue No: 9220 281 if ($nrows < 0) { 282 $nrows = '18446744073709551615'; 283 } 284 285 if ($secs) { 286 $rs = $this->CacheExecute($secs, $sql . " LIMIT $offsetStr$nrows", $inputarr); 287 } else { 288 $rs = $this->Execute($sql . " LIMIT $offsetStr$nrows", $inputarr); 289 } 290 return $rs; 291 } 292 293 function SQLDate($fmt, $col=false) 294 { 295 if (!$col) { 296 $col = $this->sysTimeStamp; 297 } 298 $s = 'DATE_FORMAT(' . $col . ",'"; 299 $concat = false; 300 $len = strlen($fmt); 301 for ($i=0; $i < $len; $i++) { 302 $ch = $fmt[$i]; 303 switch($ch) { 304 305 default: 306 if ($ch == '\\') { 307 $i++; 308 $ch = substr($fmt, $i, 1); 309 } 310 // FALL THROUGH 311 case '-': 312 case '/': 313 $s .= $ch; 314 break; 315 316 case 'Y': 317 case 'y': 318 $s .= '%Y'; 319 break; 320 321 case 'M': 322 $s .= '%b'; 323 break; 324 325 case 'm': 326 $s .= '%m'; 327 break; 328 329 case 'D': 330 case 'd': 331 $s .= '%d'; 332 break; 333 334 case 'Q': 335 case 'q': 336 $s .= "'),Quarter($col)"; 337 338 if ($len > $i+1) { 339 $s .= ",DATE_FORMAT($col,'"; 340 } else { 341 $s .= ",('"; 342 } 343 $concat = true; 344 break; 345 346 case 'H': 347 $s .= '%H'; 348 break; 349 350 case 'h': 351 $s .= '%I'; 352 break; 353 354 case 'i': 355 $s .= '%i'; 356 break; 357 358 case 's': 359 $s .= '%s'; 360 break; 361 362 case 'a': 363 case 'A': 364 $s .= '%p'; 365 break; 366 367 case 'w': 368 $s .= '%w'; 369 break; 370 371 case 'W': 372 $s .= '%U'; 373 break; 374 375 case 'l': 376 $s .= '%W'; 377 break; 378 } 379 } 380 $s .= "')"; 381 if ($concat) { 382 $s = "CONCAT($s)"; 383 } 384 return $s; 385 } 386 387 function GenID($seqname='adodbseq',$startID=1) 388 { 389 $getnext = sprintf($this->_genIDSQL,$seqname); 390 $holdtransOK = $this->_transOK; // save the current status 391 $rs = @$this->Execute($getnext); 392 if (!$rs) { 393 if ($holdtransOK) $this->_transOK = true; //if the status was ok before reset 394 $this->Execute(sprintf($this->_genSeqSQL,$seqname)); 395 $cnt = $this->GetOne(sprintf($this->_genSeqCountSQL,$seqname)); 396 if (!$cnt) $this->Execute(sprintf($this->_genSeq2SQL,$seqname,$startID-1)); 397 $rs = $this->Execute($getnext); 398 } 399 400 if ($rs) { 401 $this->genID = $this->_connectionID->lastInsertId($seqname); 402 $rs->Close(); 403 } else { 404 $this->genID = 0; 405 } 406 407 return $this->genID; 408 } 409 410 411 function createSequence($seqname='adodbseq',$startID=1) 412 { 413 if (empty($this->_genSeqSQL)) { 414 return false; 415 } 416 $ok = $this->Execute(sprintf($this->_genSeqSQL,$seqname,$startID)); 417 if (!$ok) { 418 return false; 419 } 420 421 return $this->Execute(sprintf($this->_genSeq2SQL,$seqname,$startID-1)); 422 } 423 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body