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