[ Index ] |
PHP Cross Reference of MyBB 1.8.30 |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * MyBB 1.8 4 * Copyright 2020 MyBB Group, All Rights Reserved 5 * 6 * Website: http://www.mybb.com 7 * License: http://www.mybb.com/about/license 8 */ 9 10 class MysqlPdoDbDriver extends AbstractPdoDbDriver 11 { 12 /** 13 * Explanation of a query. 14 * 15 * @var string 16 */ 17 public $explain = ''; 18 19 protected function getDsn($hostname, $db, $port, $encoding) 20 { 21 $dsn = "mysql:host={$hostname};dbname={$db}"; 22 23 if ($port !== null) { 24 $dsn .= ";port={$port}"; 25 } 26 27 if (!empty($encoding)) { 28 $dsn .= ";charset={$encoding}"; 29 } 30 31 return $dsn; 32 } 33 34 function explain_query($string, $qtime) 35 { 36 global $plugins; 37 38 $duration = format_time_duration($qtime); 39 $queryText = htmlspecialchars_uni($string); 40 41 $debug_extra = ''; 42 if ($plugins->current_hook) { 43 $debug_extra = <<<HTML 44 <div style="float_right">(Plugin Hook: {$plugins->current_hook})</div> 45 HTML; 46 } 47 48 if (preg_match('/^\\s*SELECT\\b/i', $string) === 1) { 49 $query = $this->current_link->query("EXPLAIN {$string}"); 50 51 $this->explain .= <<<HTML 52 <table style="background-color: #666;" width="95%" cellpadding="4" cellspacing="1" align="center"> 53 <tr> 54 <td colspan="8" style="background-color: #ccc;"> 55 {$debug_extra}<div><strong>#{$this->query_count} - Select Query</strong></div> 56 </td> 57 </tr> 58 <tr> 59 <td colspan="8" style="background-color: #fefefe;"> 60 <span style="font-family: Courier; font-size: 14px;">{$queryText}</span> 61 </td> 62 </tr> 63 <tr style="background-color: #efefef"> 64 <td><strong>Table</strong></td> 65 <td><strong>Type</strong></td> 66 <td><strong>Possible Keys</strong></td> 67 <td><strong>Key</strong></td> 68 <td><strong>Key Length</strong></td> 69 <td><strong>Ref</strong></td> 70 <td><strong>Rows</strong></td> 71 <td><strong>Extra</strong></td> 72 </tr> 73 HTML; 74 75 while ($table = $query->fetch(PDO::FETCH_ASSOC)) { 76 $this->explain .= <<<HTML 77 <tr bgcolor="#ffffff"> 78 <td>{$table['table']}</td> 79 <td>{$table['type']}</td> 80 <td>{$table['possible_keys']}</td> 81 <td>{$table['key']}</td> 82 <td>{$table['key_len']}</td> 83 <td>{$table['ref']}</td> 84 <td>{$table['rows']}</td> 85 <td>{$table['Extra']}</td> 86 </tr> 87 HTML; 88 } 89 90 $this->explain .= <<<HTML 91 <tr> 92 <td colspan="8" style="background-color: #fff;"> 93 Query Time: {$duration} 94 </td> 95 </tr> 96 </table> 97 <br /> 98 HTML; 99 } else { 100 $this->explain .= <<<HTML 101 <table style="background-color: #666;" width="95%" cellpadding="4" cellspacing="1" align="center"> 102 <tr> 103 <td style="background-color: #ccc;"> 104 {$debug_extra}<div><strong>#{$this->query_count} - Write Query</strong></div> 105 </td> 106 </tr> 107 <tr style="background-color: #fefefe;"> 108 <td><span style="font-family: Courier; font-size: 14px;">{$queryText}</span></td> 109 </tr> 110 <tr> 111 <td bgcolor="#ffffff">Query Time: {$duration}</td> 112 </tr> 113 </table> 114 <br/> 115 HTML; 116 } 117 118 $this->querylist[$this->query_count]['query'] = $string; 119 $this->querylist[$this->query_count]['time'] = $qtime; 120 } 121 122 public function list_tables($database, $prefix = '') 123 { 124 if ($prefix) { 125 if (version_compare($this->get_version(), '5.0.2', '>=')) { 126 $query = $this->query("SHOW FULL TABLES FROM `{$database}` WHERE table_type = 'BASE TABLE' AND `Tables_in_{$database}` LIKE '".$this->escape_string($prefix)."%'"); 127 } else { 128 $query = $this->query("SHOW TABLES FROM `{$database}` LIKE '{$this->escape_string($prefix)}%'"); 129 } 130 } else { 131 if (version_compare($this->get_version(), '5.0.2', '>=')) { 132 $query = $this->query("SHOW FULL TABLES FROM `{$database}` WHERE table_type = 'BASE TABLE'"); 133 } else { 134 $query = $this->query("SHOW TABLES FROM `{$database}`"); 135 } 136 } 137 138 return $query->fetchAll(PDO::FETCH_COLUMN, 0); 139 } 140 141 public function table_exists($table) 142 { 143 // Execute on master server to ensure if we've just created a table that we get the correct result 144 if (version_compare($this->get_version(), '5.0.2', '>=')) { 145 $query = $this->query("SHOW FULL TABLES FROM `{$this->database}` WHERE table_type = 'BASE TABLE' AND `Tables_in_{$this->database}` = '{$this->table_prefix}{$table}'"); 146 } else { 147 $query = $this->query("SHOW TABLES LIKE '{$this->table_prefix}{$table}'"); 148 } 149 150 $count = 0; 151 while ($row = $this->fetch_array($query)) { 152 $count++; 153 } 154 155 return $count > 0; 156 } 157 158 public function field_exists($field, $table) 159 { 160 $query = $this->write_query(" 161 SHOW COLUMNS 162 FROM {$this->table_prefix}{$table} 163 LIKE '{$field}' 164 "); 165 166 $exists = $this->num_rows($query); 167 168 return $exists > 0; 169 } 170 171 public function simple_select($table, $fields = "*", $conditions = "", $options = array()) 172 { 173 $query = "SELECT {$fields} FROM {$this->table_prefix}{$table}"; 174 175 if (!empty($conditions)) { 176 $query .= " WHERE {$conditions}"; 177 } 178 179 if (isset($options['group_by'])) { 180 $query .= " GROUP BY {$options['group_by']}"; 181 } 182 183 if (isset($options['order_by'])) { 184 $query .= " ORDER BY {$options['order_by']}"; 185 186 if (isset($options['order_dir'])) { 187 $query .= " ".my_strtoupper($options['order_dir']); 188 } 189 } 190 191 if (isset($options['limit_start']) && isset($options['limit'])) { 192 $query .= " LIMIT {$options['limit_start']}, {$options['limit']}"; 193 } 194 else if (isset($options['limit'])) { 195 $query .= " LIMIT {$options['limit']}"; 196 } 197 198 return $this->query($query); 199 } 200 201 public function insert_query($table, $array) 202 { 203 global $mybb; 204 205 if (!is_array($array)) { 206 return false; 207 } 208 209 foreach ($array as $field => $value) { 210 if(isset($mybb->binary_fields[$table][$field]) && $mybb->binary_fields[$table][$field]) { 211 if ($value[0] != 'X') { // Not escaped? 212 $value = $this->escape_binary($value); 213 } 214 215 $array[$field] = $value; 216 } else { 217 $array[$field] = $this->quote_val($value); 218 } 219 } 220 221 $fields = "`".implode("`,`", array_keys($array))."`"; 222 223 $values = implode(",", $array); 224 225 $this->write_query(" 226 INSERT 227 INTO {$this->table_prefix}{$table} ({$fields}) 228 VALUES ({$values}) 229 "); 230 231 return $this->insert_id(); 232 } 233 234 public function insert_query_multiple($table, $array) 235 { 236 global $mybb; 237 238 if (!is_array($array)) { 239 return; 240 } 241 242 // Field names 243 $fields = array_keys($array[0]); 244 $fields = "`".implode("`,`", $fields)."`"; 245 246 $insert_rows = array(); 247 foreach ($array as $values) { 248 foreach ($values as $field => $value) { 249 if (isset($mybb->binary_fields[$table][$field]) && $mybb->binary_fields[$table][$field]) { 250 if($value[0] != 'X') { // Not escaped? 251 $value = $this->escape_binary($value); 252 } 253 254 $values[$field] = $value; 255 } else { 256 $values[$field] = $this->quote_val($value); 257 } 258 } 259 260 $insert_rows[] = "(".implode(",", $values).")"; 261 } 262 263 $insert_rows = implode(", ", $insert_rows); 264 265 $this->write_query(" 266 INSERT 267 INTO {$this->table_prefix}{$table} ({$fields}) 268 VALUES {$insert_rows} 269 "); 270 } 271 272 public function update_query($table, $array, $where = "", $limit = "", $no_quote = false) 273 { 274 global $mybb; 275 276 if (!is_array($array)) { 277 return false; 278 } 279 280 $comma = ""; 281 $query = ""; 282 $quote = "'"; 283 284 if ($no_quote == true) { 285 $quote = ""; 286 } 287 288 foreach ($array as $field => $value) { 289 if (isset($mybb->binary_fields[$table][$field]) && $mybb->binary_fields[$table][$field]) { 290 if($value[0] != 'X') { // Not escaped? 291 $value = $this->escape_binary($value); 292 } 293 294 $query .= "{$comma}`{$field}`={$value}"; 295 } else { 296 $quoted_value = $this->quote_val($value, $quote); 297 298 $query .= "{$comma}`{$field}`={$quoted_value}"; 299 } 300 301 $comma = ', '; 302 } 303 304 if (!empty($where)) { 305 $query .= " WHERE {$where}"; 306 } 307 308 if (!empty($limit)) { 309 $query .= " LIMIT {$limit}"; 310 } 311 312 return $this->write_query(" 313 UPDATE {$this->table_prefix}{$table} 314 SET {$query} 315 "); 316 } 317 318 public function delete_query($table, $where = "", $limit = "") 319 { 320 $query = ""; 321 if (!empty($where)) { 322 $query .= " WHERE {$where}"; 323 } 324 325 if (!empty($limit)) { 326 $query .= " LIMIT {$limit}"; 327 } 328 329 return $this->write_query("DELETE FROM {$this->table_prefix}{$table} {$query}"); 330 } 331 332 public function optimize_table($table) 333 { 334 $this->write_query("OPTIMIZE TABLE {$this->table_prefix}{$table}"); 335 } 336 337 public function analyze_table($table) 338 { 339 $this->write_query("ANALYZE TABLE {$this->table_prefix}{$table}"); 340 } 341 342 public function show_create_table($table) 343 { 344 $query = $this->write_query("SHOW CREATE TABLE {$this->table_prefix}{$table}"); 345 $structure = $this->fetch_array($query); 346 347 return $structure['Create Table']; 348 } 349 350 public function show_fields_from($table) 351 { 352 $query = $this->write_query("SHOW FIELDS FROM {$this->table_prefix}{$table}"); 353 354 $field_info = array(); 355 while ($field = $this->fetch_array($query)) { 356 $field_info[] = $field; 357 } 358 359 return $field_info; 360 } 361 362 public function is_fulltext($table, $index = "") 363 { 364 $structure = $this->show_create_table($table); 365 if ($index != "") { 366 if(preg_match("#FULLTEXT KEY (`?){$index}(`?)#i", $structure)) { 367 return true; 368 } 369 370 return false; 371 } 372 373 if (preg_match('#FULLTEXT KEY#i', $structure)) { 374 return true; 375 } 376 377 return false; 378 } 379 380 public function supports_fulltext($table) 381 { 382 $version = $this->get_version(); 383 $query = $this->write_query("SHOW TABLE STATUS LIKE '{$this->table_prefix}$table'"); 384 $status = $this->fetch_array($query); 385 $table_type = my_strtoupper($status['Engine']); 386 387 if (version_compare($version, '3.23.23', '>=') && ($table_type == 'MYISAM' || $table_type == 'ARIA')) { 388 return true; 389 } else if (version_compare($version, '5.6', '>=') && $table_type == 'INNODB') { 390 return true; 391 } 392 393 return false; 394 } 395 396 public function index_exists($table, $index) 397 { 398 $index_exists = false; 399 $query = $this->write_query("SHOW INDEX FROM {$this->table_prefix}{$table}"); 400 while ($ukey = $this->fetch_array($query)) { 401 if ($ukey['Key_name'] == $index) { 402 $index_exists = true; 403 break; 404 } 405 } 406 407 return $index_exists; 408 } 409 410 public function supports_fulltext_boolean($table) 411 { 412 $version = $this->get_version(); 413 $supports_fulltext = $this->supports_fulltext($table); 414 if (version_compare($version, '4.0.1', '>=') && $supports_fulltext == true) { 415 return true; 416 } 417 418 return false; 419 } 420 421 public function create_fulltext_index($table, $column, $name = "") 422 { 423 $this->write_query("ALTER TABLE {$this->table_prefix}{$table} ADD FULLTEXT {$name} ({$column})"); 424 } 425 426 public function drop_index($table, $name) 427 { 428 $this->write_query("ALTER TABLE {$this->table_prefix}{$table} DROP INDEX {$name}"); 429 } 430 431 public function drop_table($table, $hard = false, $table_prefix = true) 432 { 433 if ($table_prefix == false) { 434 $table_prefix = ""; 435 } else { 436 $table_prefix = $this->table_prefix; 437 } 438 439 if ($hard == false) { 440 $this->write_query("DROP TABLE IF EXISTS {$table_prefix}{$table}"); 441 } else { 442 $this->write_query("DROP TABLE {$table_prefix}{$table}"); 443 } 444 } 445 446 public function rename_table($old_table, $new_table, $table_prefix = true) 447 { 448 if ($table_prefix == false) { 449 $table_prefix = ""; 450 } else { 451 $table_prefix = $this->table_prefix; 452 } 453 454 return $this->write_query("RENAME TABLE {$table_prefix}{$old_table} TO {$table_prefix}{$new_table}"); 455 } 456 457 public function replace_query($table, $replacements = array(), $default_field = "", $insert_id = true) 458 { 459 global $mybb; 460 461 $values = ''; 462 $comma = ''; 463 464 foreach ($replacements as $column => $value) { 465 if (isset($mybb->binary_fields[$table][$column]) && $mybb->binary_fields[$table][$column]) { 466 if ($value[0] != 'X') { // Not escaped? 467 $value = $this->escape_binary($value); 468 } 469 470 $values .= $comma."`".$column."`=".$value; 471 } else { 472 $values .= $comma."`".$column."`=".$this->quote_val($value); 473 } 474 475 $comma = ','; 476 } 477 478 if (empty($replacements)) { 479 return false; 480 } 481 482 return $this->write_query("REPLACE INTO {$this->table_prefix}{$table} SET {$values}"); 483 } 484 485 public function drop_column($table, $column) 486 { 487 $column = trim($column, '`'); 488 489 return $this->write_query("ALTER TABLE {$this->table_prefix}{$table} DROP `{$column}`"); 490 } 491 492 public function add_column($table, $column, $definition) 493 { 494 $column = trim($column, '`'); 495 496 return $this->write_query("ALTER TABLE {$this->table_prefix}{$table} ADD `{$column}` {$definition}"); 497 } 498 499 public function modify_column($table, $column, $new_definition, $new_not_null = false, $new_default_value = false) 500 { 501 $column = trim($column, '`'); 502 503 if ($new_not_null !== false) { 504 if (strtolower($new_not_null) == "set") { 505 $not_null = "NOT NULL"; 506 } else { 507 $not_null = "NULL"; 508 } 509 } else { 510 $not_null = ''; 511 } 512 513 if ($new_default_value !== false) { 514 $default = "DEFAULT ".$new_default_value; 515 } 516 else 517 { 518 $default = ''; 519 } 520 521 return (bool)$this->write_query("ALTER TABLE {$this->table_prefix}{$table} MODIFY `{$column}` {$new_definition} {$not_null} {$default}"); 522 } 523 524 public function rename_column($table, $old_column, $new_column, $new_definition, $new_not_null = false, $new_default_value = false) 525 { 526 $old_column = trim($old_column, '`'); 527 $new_column = trim($new_column, '`'); 528 529 if ($new_not_null !== false) { 530 if(strtolower($new_not_null) == "set") { 531 $not_null = "NOT NULL"; 532 } else { 533 $not_null = "NULL"; 534 } 535 } else { 536 $not_null = ''; 537 } 538 539 if ($new_default_value !== false) { 540 $default = "DEFAULT ".$new_default_value; 541 } else { 542 $default = ''; 543 } 544 545 return (bool)$this->write_query("ALTER TABLE {$this->table_prefix}{$table} CHANGE `{$old_column}` `{$new_column}` {$new_definition} {$not_null} {$default}"); 546 } 547 548 public function fetch_size($table = '') 549 { 550 if ($table != '') { 551 $query = $this->query("SHOW TABLE STATUS LIKE '{$this->table_prefix}{$table}'"); 552 } else { 553 $query = $this->query("SHOW TABLE STATUS"); 554 } 555 556 $total = 0; 557 while ($table = $this->fetch_array($query)) { 558 $total += $table['Data_length'] + $table['Index_length']; 559 } 560 561 return $total; 562 } 563 564 public function fetch_db_charsets() 565 { 566 if ($this->write_link && version_compare($this->get_version(), "4.1", "<")) { 567 return false; 568 } 569 570 return array( 571 'big5' => 'Big5 Traditional Chinese', 572 'dec8' => 'DEC West European', 573 'cp850' => 'DOS West European', 574 'hp8' => 'HP West European', 575 'koi8r' => 'KOI8-R Relcom Russian', 576 'latin1' => 'ISO 8859-1 Latin 1', 577 'latin2' => 'ISO 8859-2 Central European', 578 'swe7' => '7bit Swedish', 579 'ascii' => 'US ASCII', 580 'ujis' => 'EUC-JP Japanese', 581 'sjis' => 'Shift-JIS Japanese', 582 'hebrew' => 'ISO 8859-8 Hebrew', 583 'tis620' => 'TIS620 Thai', 584 'euckr' => 'EUC-KR Korean', 585 'koi8u' => 'KOI8-U Ukrainian', 586 'gb2312' => 'GB2312 Simplified Chinese', 587 'greek' => 'ISO 8859-7 Greek', 588 'cp1250' => 'Windows Central European', 589 'gbk' => 'GBK Simplified Chinese', 590 'latin5' => 'ISO 8859-9 Turkish', 591 'armscii8' => 'ARMSCII-8 Armenian', 592 'utf8' => 'UTF-8 Unicode', 593 'utf8mb4' => '4-Byte UTF-8 Unicode (requires MySQL 5.5.3 or above)', 594 'ucs2' => 'UCS-2 Unicode', 595 'cp866' => 'DOS Russian', 596 'keybcs2' => 'DOS Kamenicky Czech-Slovak', 597 'macce' => 'Mac Central European', 598 'macroman' => 'Mac West European', 599 'cp852' => 'DOS Central European', 600 'latin7' => 'ISO 8859-13 Baltic', 601 'cp1251' => 'Windows Cyrillic', 602 'cp1256' => 'Windows Arabic', 603 'cp1257' => 'Windows Baltic', 604 'geostd8' => 'GEOSTD8 Georgian', 605 'cp932' => 'SJIS for Windows Japanese', 606 'eucjpms' => 'UJIS for Windows Japanese', 607 ); 608 } 609 610 public function fetch_charset_collation($charset) 611 { 612 $collations = array( 613 'big5' => 'big5_chinese_ci', 614 'dec8' => 'dec8_swedish_ci', 615 'cp850' => 'cp850_general_ci', 616 'hp8' => 'hp8_english_ci', 617 'koi8r' => 'koi8r_general_ci', 618 'latin1' => 'latin1_swedish_ci', 619 'latin2' => 'latin2_general_ci', 620 'swe7' => 'swe7_swedish_ci', 621 'ascii' => 'ascii_general_ci', 622 'ujis' => 'ujis_japanese_ci', 623 'sjis' => 'sjis_japanese_ci', 624 'hebrew' => 'hebrew_general_ci', 625 'tis620' => 'tis620_thai_ci', 626 'euckr' => 'euckr_korean_ci', 627 'koi8u' => 'koi8u_general_ci', 628 'gb2312' => 'gb2312_chinese_ci', 629 'greek' => 'greek_general_ci', 630 'cp1250' => 'cp1250_general_ci', 631 'gbk' => 'gbk_chinese_ci', 632 'latin5' => 'latin5_turkish_ci', 633 'armscii8' => 'armscii8_general_ci', 634 'utf8' => 'utf8_general_ci', 635 'utf8mb4' => 'utf8mb4_general_ci', 636 'ucs2' => 'ucs2_general_ci', 637 'cp866' => 'cp866_general_ci', 638 'keybcs2' => 'keybcs2_general_ci', 639 'macce' => 'macce_general_ci', 640 'macroman' => 'macroman_general_ci', 641 'cp852' => 'cp852_general_ci', 642 'latin7' => 'latin7_general_ci', 643 'cp1251' => 'cp1251_general_ci', 644 'cp1256' => 'cp1256_general_ci', 645 'cp1257' => 'cp1257_general_ci', 646 'geostd8' => 'geostd8_general_ci', 647 'cp932' => 'cp932_japanese_ci', 648 'eucjpms' => 'eucjpms_japanese_ci', 649 ); 650 651 if (isset($collations[$charset])) { 652 return $collations[$charset]; 653 } 654 655 return false; 656 } 657 658 public function build_create_table_collation() 659 { 660 if (!$this->db_encoding) { 661 return ''; 662 } 663 664 $collation = $this->fetch_charset_collation($this->db_encoding); 665 if (!$collation) { 666 return ''; 667 } 668 669 return " CHARACTER SET {$this->db_encoding} COLLATE {$collation}"; 670 } 671 672 public function escape_binary($string) 673 { 674 return "X'{$this->escape_string(bin2hex($string))}'"; 675 } 676 677 public function unescape_binary($string) 678 { 679 return $string; 680 } 681 682 /** 683 * @param int|string $value 684 * @param string $quote 685 * 686 * @return int|string 687 */ 688 private function quote_val($value, $quote="'") 689 { 690 if (is_int($value)) { 691 return $value; 692 } 693 694 return "{$quote}{$value}{$quote}"; 695 } 696 697 public function __set($name, $value) 698 { 699 if ($name === 'type') { 700 // NOTE: This is to prevent the type being set - this type should appear as `mysqli` to ensure compatibility 701 return; 702 } 703 } 704 705 public function __get($name) 706 { 707 if ($name === 'type') { 708 // NOTE: this is to ensure compatibility checks on the DB type will work 709 return 'mysqli'; 710 } 711 712 return null; 713 } 714 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
2005 - 2021 © MyBB.de | Alle Rechte vorbehalten! | Sponsor: netcup | Cross-referenced by PHPXref |