[ Index ] |
PHP Cross Reference of MyBB |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * MyBB 1.6 4 * Copyright 2010 MyBB Group, All Rights Reserved 5 * 6 * Website: http://mybb.com 7 * License: http://mybb.com/about/license 8 * 9 * $Id$ 10 */ 11 12 class DB_MySQLi 13 { 14 /** 15 * The title of this layer. 16 * 17 * @var string 18 */ 19 public $title = "MySQLi"; 20 21 /** 22 * The short title of this layer. 23 * 24 * @var string 25 */ 26 public $short_title = "MySQLi"; 27 28 /** 29 * The type of db software being used. 30 * 31 * @var string 32 */ 33 public $type; 34 35 /** 36 * A count of the number of queries. 37 * 38 * @var int 39 */ 40 public $query_count = 0; 41 42 /** 43 * A list of the performed queries. 44 * 45 * @var array 46 */ 47 public $querylist = array(); 48 49 /** 50 * 1 if error reporting enabled, 0 if disabled. 51 * 52 * @var boolean 53 */ 54 public $error_reporting = 1; 55 56 /** 57 * The read database connection resource. 58 * 59 * @var resource 60 */ 61 public $read_link; 62 63 /** 64 * The write database connection resource 65 * 66 * @var resource 67 */ 68 public $write_link; 69 70 /** 71 * Reference to the last database connection resource used. 72 * 73 * @var resource 74 */ 75 public $current_link; 76 77 /** 78 * Explanation of a query. 79 * 80 * @var string 81 */ 82 public $explain; 83 84 /** 85 * The current version of MySQL. 86 * 87 * @var string 88 */ 89 public $version; 90 91 /** 92 * The current table type in use (myisam/innodb) 93 * 94 * @var string 95 */ 96 public $table_type = "myisam"; 97 98 /** 99 * The table prefix used for simple select, update, insert and delete queries 100 * 101 * @var string 102 */ 103 public $table_prefix; 104 105 /** 106 * The extension used to run the SQL database 107 * 108 * @var string 109 */ 110 public $engine = "mysqli"; 111 112 /** 113 * Weather or not this engine can use the search functionality 114 * 115 * @var boolean 116 */ 117 public $can_search = true; 118 119 /** 120 * The database encoding currently in use (if supported) 121 * 122 * @var string 123 */ 124 public $db_encoding = "utf8"; 125 126 /** 127 * The time spent performing queries 128 * 129 * @var float 130 */ 131 public $query_time = 0; 132 133 /** 134 * Connect to the database server. 135 * 136 * @param array Array of DBMS connection details. 137 * @return resource The DB connection resource. Returns false on fail or -1 on a db connect failure. 138 */ 139 function connect($config) 140 { 141 // Simple connection to one server 142 if(array_key_exists('hostname', $config)) 143 { 144 $connections['read'][] = $config; 145 } 146 else 147 // Connecting to more than one server 148 { 149 // Specified multiple servers, but no specific read/write servers 150 if(!array_key_exists('read', $config)) 151 { 152 foreach($config as $key => $settings) 153 { 154 if(is_int($key)) $connections['read'][] = $settings; 155 } 156 } 157 // Specified both read & write servers 158 else 159 { 160 $connections = $config; 161 } 162 } 163 164 $this->db_encoding = $config['encoding']; 165 166 // Actually connect to the specified servers 167 foreach(array('read', 'write') as $type) 168 { 169 if(!isset($connections[$type]) || !is_array($connections[$type])) 170 { 171 break; 172 } 173 174 if(array_key_exists('hostname', $connections[$type])) 175 { 176 $details = $connections[$type]; 177 unset($connections); 178 $connections[$type][] = $details; 179 } 180 181 // Shuffle the connections 182 shuffle($connections[$type]); 183 184 // Loop-de-loop 185 foreach($connections[$type] as $single_connection) 186 { 187 $persist = ''; 188 $connect_function = 'mysqli_connect'; 189 if(isset($single_connection['pconnect']) && version_compare(PHP_VERSION, '5.3.0', '>=')) 190 { 191 $persist = 'p:'; 192 } 193 194 $link = "{$type}_link"; 195 196 $this->get_execution_time(); 197 198 // Specified a custom port for this connection? 199 $port = 0; 200 if(strstr($single_connection['hostname'],':')) 201 { 202 list($hostname, $port) = explode(":", $single_connection['hostname'], 2); 203 } 204 205 if($port) 206 { 207 $this->$link = @$connect_function($persist.$hostname, $single_connection['username'], $single_connection['password'], "", $port); 208 } 209 else 210 { 211 $this->$link = @$connect_function($persist.$single_connection['hostname'], $single_connection['username'], $single_connection['password']); 212 } 213 214 $time_spent = $this->get_execution_time(); 215 $this->query_time += $time_spent; 216 217 // Successful connection? break down brother! 218 if($this->$link) 219 { 220 $this->connections[] = "[".strtoupper($type)."] {$single_connection['username']}@{$single_connection['hostname']} (Connected in ".number_format($time_spent, 0)."s)"; 221 break; 222 } 223 else 224 { 225 $this->connections[] = "<span style=\"color: red\">[FAILED] [".strtoupper($type)."] {$single_connection['username']}@{$single_connection['hostname']}</span>"; 226 } 227 } 228 } 229 230 // No write server was specified (simple connection or just multiple servers) - mirror write link 231 if(!array_key_exists('write', $connections)) 232 { 233 $this->write_link = &$this->read_link; 234 } 235 236 // Have no read connection? 237 if(!$this->read_link) 238 { 239 $this->error("[READ] Unable to connect to MySQL server"); 240 return false; 241 } 242 // No write? 243 else if(!$this->write_link) 244 { 245 $this->error("[WRITE] Unable to connect to MySQL server"); 246 return false; 247 } 248 249 // Select databases 250 if(!$this->select_db($config['database'])) 251 { 252 return -1; 253 } 254 255 $this->current_link = &$this->read_link; 256 return $this->read_link; 257 } 258 259 /** 260 * Selects the database to use. 261 * 262 * @param string The database name. 263 * @return boolean True when successfully connected, false if not. 264 */ 265 function select_db($database) 266 { 267 global $mybb; 268 269 $master_success = @mysqli_select_db($this->read_link, $database) or $this->error("[READ] Unable to select database", $this->read_link); 270 if($this->write_link) 271 { 272 $slave_success = @mysqli_select_db($this->write_link, $database) or $this->error("[WRITE] Unable to select slave database", $this->write_link); 273 274 $success = ($master_success && $slave_success ? true : false); 275 } 276 else 277 { 278 $success = $master_success; 279 } 280 281 if($success && $this->db_encoding) 282 { 283 $this->query("SET NAMES '{$this->db_encoding}'"); 284 285 if($slave_success && count($this->connections) > 1) 286 { 287 $this->write_query("SET NAMES '{$this->db_encoding}'"); 288 } 289 } 290 return $success; 291 } 292 293 /** 294 * Query the database. 295 * 296 * @param string The query SQL. 297 * @param boolean 1 if hide errors, 0 if not. 298 * @param integer 1 if executes on slave database, 0 if not. 299 * @return resource The query data. 300 */ 301 function query($string, $hide_errors=0, $write_query=0) 302 { 303 global $pagestarttime, $db, $mybb; 304 305 $this->get_execution_time(); 306 307 // Only execute write queries on slave server 308 if($write_query && $this->write_link) 309 { 310 $this->current_link = &$this->write_link; 311 $query = @mysqli_query($this->write_link, $string); 312 } 313 else 314 { 315 $this->current_link = &$this->read_link; 316 $query = @mysqli_query($this->read_link, $string); 317 } 318 319 if($this->error_number() && !$hide_errors) 320 { 321 $this->error($string); 322 exit; 323 } 324 325 $query_time = $this->get_execution_time(); 326 $this->query_time += $query_time; 327 $this->query_count++; 328 329 if($mybb->debug_mode) 330 { 331 $this->explain_query($string, $query_time); 332 } 333 return $query; 334 } 335 336 /** 337 * Execute a write query on the slave database 338 * 339 * @param string The query SQL. 340 * @param boolean 1 if hide errors, 0 if not. 341 * @return resource The query data. 342 */ 343 function write_query($query, $hide_errors=0) 344 { 345 return $this->query($query, $hide_errors, 1); 346 } 347 348 /** 349 * Explain a query on the database. 350 * 351 * @param string The query SQL. 352 * @param string The time it took to perform the query. 353 */ 354 function explain_query($string, $qtime) 355 { 356 global $plugins; 357 358 $debug_extra = ''; 359 if($plugins->current_hook) 360 { 361 $debug_extra = "<div style=\"float_right\">(Plugin Hook: {$plugins->current_hook})</div>"; 362 } 363 if(preg_match("#^\s*select#i", $string)) 364 { 365 $query = mysqli_query($this->current_link, "EXPLAIN $string"); 366 $this->explain .= "<table style=\"background-color: #666;\" width=\"95%\" cellpadding=\"4\" cellspacing=\"1\" align=\"center\">\n". 367 "<tr>\n". 368 "<td colspan=\"8\" style=\"background-color: #ccc;\">{$debug_extra}<div><strong>#".$this->query_count." - Select Query</strong></div></td>\n". 369 "</tr>\n". 370 "<tr>\n". 371 "<td colspan=\"8\" style=\"background-color: #fefefe;\"><span style=\"font-family: Courier; font-size: 14px;\">".htmlspecialchars_uni($string)."</span></td>\n". 372 "</tr>\n". 373 "<tr style=\"background-color: #efefef;\">\n". 374 "<td><strong>table</strong></td>\n". 375 "<td><strong>type</strong></td>\n". 376 "<td><strong>possible_keys</strong></td>\n". 377 "<td><strong>key</strong></td>\n". 378 "<td><strong>key_len</strong></td>\n". 379 "<td><strong>ref</strong></td>\n". 380 "<td><strong>rows</strong></td>\n". 381 "<td><strong>Extra</strong></td>\n". 382 "</tr>\n"; 383 384 while($table = mysqli_fetch_assoc($query)) 385 { 386 $this->explain .= 387 "<tr bgcolor=\"#ffffff\">\n". 388 "<td>".$table['table']."</td>\n". 389 "<td>".$table['type']."</td>\n". 390 "<td>".$table['possible_keys']."</td>\n". 391 "<td>".$table['key']."</td>\n". 392 "<td>".$table['key_len']."</td>\n". 393 "<td>".$table['ref']."</td>\n". 394 "<td>".$table['rows']."</td>\n". 395 "<td>".$table['Extra']."</td>\n". 396 "</tr>\n"; 397 } 398 $this->explain .= 399 "<tr>\n". 400 "<td colspan=\"8\" style=\"background-color: #fff;\">Query Time: ".$qtime."</td>\n". 401 "</tr>\n". 402 "</table>\n". 403 "<br />\n"; 404 } 405 else 406 { 407 $this->explain .= "<table style=\"background-color: #666;\" width=\"95%\" cellpadding=\"4\" cellspacing=\"1\" align=\"center\">\n". 408 "<tr>\n". 409 "<td style=\"background-color: #ccc;\">{$debug_extra}<div><strong>#".$this->query_count." - Write Query</strong></div></td>\n". 410 "</tr>\n". 411 "<tr style=\"background-color: #fefefe;\">\n". 412 "<td><span style=\"font-family: Courier; font-size: 14px;\">".htmlspecialchars_uni($string)."</span></td>\n". 413 "</tr>\n". 414 "<tr>\n". 415 "<td bgcolor=\"#ffffff\">Query Time: ".$qtime."</td>\n". 416 "</tr>\n". 417 "</table>\n". 418 "<br />\n"; 419 } 420 421 $this->querylist[$this->query_count]['query'] = $string; 422 $this->querylist[$this->query_count]['time'] = $qtime; 423 } 424 425 426 /** 427 * Return a result array for a query. 428 * 429 * @param resource The query data. 430 * @param constant The type of array to return. 431 * @return array The array of results. 432 */ 433 function fetch_array($query) 434 { 435 $array = mysqli_fetch_assoc($query); 436 return $array; 437 } 438 439 /** 440 * Return a specific field from a query. 441 * 442 * @param resource The query ID. 443 * @param string The name of the field to return. 444 * @param int The number of the row to fetch it from. 445 */ 446 function fetch_field($query, $field, $row=false) 447 { 448 if($row !== false) 449 { 450 $this->data_seek($query, $row); 451 } 452 $array = $this->fetch_array($query); 453 return $array[$field]; 454 } 455 456 /** 457 * Moves internal row pointer to the next row 458 * 459 * @param resource The query ID. 460 * @param int The pointer to move the row to. 461 */ 462 function data_seek($query, $row) 463 { 464 return mysqli_data_seek($query, $row); 465 } 466 467 /** 468 * Return the number of rows resulting from a query. 469 * 470 * @param resource The query data. 471 * @return int The number of rows in the result. 472 */ 473 function num_rows($query) 474 { 475 return mysqli_num_rows($query); 476 } 477 478 /** 479 * Return the last id number of inserted data. 480 * 481 * @return int The id number. 482 */ 483 function insert_id() 484 { 485 $id = mysqli_insert_id($this->current_link); 486 return $id; 487 } 488 489 /** 490 * Close the connection with the DBMS. 491 * 492 */ 493 function close() 494 { 495 @mysqli_close($this->read_link); 496 if($this->write_link) 497 { 498 @mysqli_close($this->write_link); 499 } 500 } 501 502 /** 503 * Return an error number. 504 * 505 * @return int The error number of the current error. 506 */ 507 function error_number() 508 { 509 if($this->current_link) 510 { 511 return mysqli_errno($this->current_link); 512 } 513 else 514 { 515 return mysqli_connect_errno(); 516 } 517 } 518 519 /** 520 * Return an error string. 521 * 522 * @return string The explanation for the current error. 523 */ 524 function error_string() 525 { 526 if($this->current_link) 527 { 528 return mysqli_error($this->current_link); 529 } 530 else 531 { 532 return mysqli_connect_error(); 533 } 534 } 535 536 /** 537 * Output a database error. 538 * 539 * @param string The string to present as an error. 540 */ 541 function error($string="") 542 { 543 if($this->error_reporting) 544 { 545 if(class_exists("errorHandler")) 546 { 547 global $error_handler; 548 549 if(!is_object($error_handler)) 550 { 551 require_once MYBB_ROOT."inc/class_error.php"; 552 $error_handler = new errorHandler(); 553 } 554 555 $error = array( 556 "error_no" => $this->error_number(), 557 "error" => $this->error_string(), 558 "query" => $string 559 ); 560 $error_handler->error(MYBB_SQL, $error); 561 } 562 else 563 { 564 trigger_error("<strong>[SQL] [".$this->error_number()."] ".$this->error_string()."</strong><br />{$string}", E_USER_ERROR); 565 } 566 } 567 else 568 { 569 return false; 570 } 571 } 572 573 574 /** 575 * Returns the number of affected rows in a query. 576 * 577 * @return int The number of affected rows. 578 */ 579 function affected_rows() 580 { 581 return mysqli_affected_rows($this->current_link); 582 } 583 584 585 /** 586 * Return the number of fields. 587 * 588 * @param resource The query data. 589 * @return int The number of fields. 590 */ 591 function num_fields($query) 592 { 593 return mysqli_num_fields($query); 594 } 595 596 /** 597 * Lists all functions in the database. 598 * 599 * @param string The database name. 600 * @param string Prefix of the table (optional) 601 * @return array The table list. 602 */ 603 function list_tables($database, $prefix='') 604 { 605 if($prefix) 606 { 607 $query = $this->query("SHOW TABLES FROM `$database` LIKE '".$this->escape_string($prefix)."%'"); 608 } 609 else 610 { 611 $query = $this->query("SHOW TABLES FROM `$database`"); 612 } 613 614 while(list($table) = mysqli_fetch_array($query)) 615 { 616 $tables[] = $table; 617 } 618 return $tables; 619 } 620 621 /** 622 * Check if a table exists in a database. 623 * 624 * @param string The table name. 625 * @return boolean True when exists, false if not. 626 */ 627 function table_exists($table) 628 { 629 // Execute on master server to ensure if we've just created a table that we get the correct result 630 $query = $this->write_query(" 631 SHOW TABLES 632 LIKE '{$this->table_prefix}$table' 633 "); 634 $exists = $this->num_rows($query); 635 636 if($exists > 0) 637 { 638 return true; 639 } 640 else 641 { 642 return false; 643 } 644 } 645 646 /** 647 * Check if a field exists in a database. 648 * 649 * @param string The field name. 650 * @param string The table name. 651 * @return boolean True when exists, false if not. 652 */ 653 function field_exists($field, $table) 654 { 655 $query = $this->write_query(" 656 SHOW COLUMNS 657 FROM {$this->table_prefix}$table 658 LIKE '$field' 659 "); 660 $exists = $this->num_rows($query); 661 662 if($exists > 0) 663 { 664 return true; 665 } 666 else 667 { 668 return false; 669 } 670 } 671 672 /** 673 * Add a shutdown query. 674 * 675 * @param resource The query data. 676 * @param string An optional name for the query. 677 */ 678 function shutdown_query($query, $name=0) 679 { 680 global $shutdown_queries; 681 if($name) 682 { 683 $shutdown_queries[$name] = $query; 684 } 685 else 686 { 687 $shutdown_queries[] = $query; 688 } 689 } 690 691 /** 692 * Performs a simple select query. 693 * 694 * @param string The table name to be queried. 695 * @param string Comma delimetered list of fields to be selected. 696 * @param string SQL formatted list of conditions to be matched. 697 * @param array List of options, order by, order direction, limit, limit start. 698 * @return resource The query data. 699 */ 700 701 function simple_select($table, $fields="*", $conditions="", $options=array()) 702 { 703 $query = "SELECT ".$fields." FROM ".$this->table_prefix.$table; 704 705 if($conditions != "") 706 { 707 $query .= " WHERE ".$conditions; 708 } 709 710 if(isset($options['order_by'])) 711 { 712 $query .= " ORDER BY ".$options['order_by']; 713 if(isset($options['order_dir'])) 714 { 715 $query .= " ".my_strtoupper($options['order_dir']); 716 } 717 } 718 719 if(isset($options['limit_start']) && isset($options['limit'])) 720 { 721 $query .= " LIMIT ".$options['limit_start'].", ".$options['limit']; 722 } 723 else if(isset($options['limit'])) 724 { 725 $query .= " LIMIT ".$options['limit']; 726 } 727 728 return $this->query($query); 729 } 730 731 /** 732 * Build an insert query from an array. 733 * 734 * @param string The table name to perform the query on. 735 * @param array An array of fields and their values. 736 * @return int The insert ID if available 737 */ 738 function insert_query($table, $array) 739 { 740 if(!is_array($array)) 741 { 742 return false; 743 } 744 $fields = "`".implode("`,`", array_keys($array))."`"; 745 $values = implode("','", $array); 746 $this->write_query(" 747 INSERT 748 INTO {$this->table_prefix}{$table} (".$fields.") 749 VALUES ('".$values."') 750 "); 751 return $this->insert_id(); 752 } 753 754 /** 755 * Build one query for multiple inserts from a multidimensional array. 756 * 757 * @param string The table name to perform the query on. 758 * @param array An array of inserts. 759 * @return int The insert ID if available 760 */ 761 function insert_query_multiple($table, $array) 762 { 763 if(!is_array($array)) 764 { 765 return false; 766 } 767 // Field names 768 $fields = array_keys($array[0]); 769 $fields = "`".implode("`,`", $fields)."`"; 770 771 $insert_rows = array(); 772 foreach($array as $values) 773 { 774 $insert_rows[] = "('".implode("','", $values)."')"; 775 } 776 $insert_rows = implode(", ", $insert_rows); 777 778 $this->write_query(" 779 INSERT 780 INTO {$this->table_prefix}{$table} ({$fields}) 781 VALUES {$insert_rows} 782 "); 783 } 784 785 /** 786 * Build an update query from an array. 787 * 788 * @param string The table name to perform the query on. 789 * @param array An array of fields and their values. 790 * @param string An optional where clause for the query. 791 * @param string An optional limit clause for the query. 792 * @param boolean An option to quote incoming values of the array. 793 * @return resource The query data. 794 */ 795 function update_query($table, $array, $where="", $limit="", $no_quote=false) 796 { 797 if(!is_array($array)) 798 { 799 return false; 800 } 801 802 $comma = ""; 803 $query = ""; 804 $quote = "'"; 805 806 if($no_quote == true) 807 { 808 $quote = ""; 809 } 810 811 foreach($array as $field => $value) 812 { 813 $query .= $comma."`".$field."`={$quote}{$value}{$quote}"; 814 $comma = ', '; 815 } 816 817 if(!empty($where)) 818 { 819 $query .= " WHERE $where"; 820 } 821 822 if(!empty($limit)) 823 { 824 $query .= " LIMIT $limit"; 825 } 826 827 return $this->write_query(" 828 UPDATE {$this->table_prefix}$table 829 SET $query 830 "); 831 } 832 833 /** 834 * Build a delete query. 835 * 836 * @param string The table name to perform the query on. 837 * @param string An optional where clause for the query. 838 * @param string An optional limit clause for the query. 839 * @return resource The query data. 840 */ 841 function delete_query($table, $where="", $limit="") 842 { 843 $query = ""; 844 if(!empty($where)) 845 { 846 $query .= " WHERE $where"; 847 } 848 if(!empty($limit)) 849 { 850 $query .= " LIMIT $limit"; 851 } 852 return $this->write_query("DELETE FROM {$this->table_prefix}$table $query"); 853 } 854 855 /** 856 * Escape a string according to the MySQL escape format. 857 * 858 * @param string The string to be escaped. 859 * @return string The escaped string. 860 */ 861 function escape_string($string) 862 { 863 if(function_exists("mysqli_real_escape_string") && $this->read_link) 864 { 865 $string = mysqli_real_escape_string($this->read_link, $string); 866 } 867 else 868 { 869 $string = addslashes($string); 870 } 871 return $string; 872 } 873 874 /** 875 * Frees the resources of a MySQLi query. 876 * 877 * @param object The query to destroy. 878 * @return boolean Returns true on success, false on faliure 879 */ 880 function free_result($query) 881 { 882 return mysqli_free_result($query); 883 } 884 885 /** 886 * Escape a string used within a like command. 887 * 888 * @param string The string to be escaped. 889 * @return string The escaped string. 890 */ 891 function escape_string_like($string) 892 { 893 return $this->escape_string(str_replace(array('%', '_') , array('\\%' , '\\_') , $string)); 894 } 895 896 /** 897 * Gets the current version of MySQL. 898 * 899 * @return string Version of MySQL. 900 */ 901 function get_version() 902 { 903 if($this->version) 904 { 905 return $this->version; 906 } 907 $query = $this->query("SELECT VERSION() as version"); 908 $ver = $this->fetch_array($query); 909 if($ver['version']) 910 { 911 $version = explode(".", $ver['version'], 3); 912 $this->version = intval($version[0]).".".intval($version[1]).".".intval($version[2]); 913 } 914 return $this->version; 915 } 916 917 /** 918 * Optimizes a specific table. 919 * 920 * @param string The name of the table to be optimized. 921 */ 922 function optimize_table($table) 923 { 924 $this->write_query("OPTIMIZE TABLE ".$this->table_prefix.$table.""); 925 } 926 927 /** 928 * Analyzes a specific table. 929 * 930 * @param string The name of the table to be analyzed. 931 */ 932 function analyze_table($table) 933 { 934 $this->write_query("ANALYZE TABLE ".$this->table_prefix.$table.""); 935 } 936 937 /** 938 * Show the "create table" command for a specific table. 939 * 940 * @param string The name of the table. 941 * @return string The MySQL command to create the specified table. 942 */ 943 function show_create_table($table) 944 { 945 $query = $this->write_query("SHOW CREATE TABLE ".$this->table_prefix.$table.""); 946 $structure = $this->fetch_array($query); 947 948 return $structure['Create Table']; 949 } 950 951 /** 952 * Show the "show fields from" command for a specific table. 953 * 954 * @param string The name of the table. 955 * @return string Field info for that table 956 */ 957 function show_fields_from($table) 958 { 959 $query = $this->write_query("SHOW FIELDS FROM ".$this->table_prefix.$table.""); 960 while($field = $this->fetch_array($query)) 961 { 962 $field_info[] = $field; 963 } 964 return $field_info; 965 } 966 967 /** 968 * Returns whether or not the table contains a fulltext index. 969 * 970 * @param string The name of the table. 971 * @param string Optionally specify the name of the index. 972 * @return boolean True or false if the table has a fulltext index or not. 973 */ 974 function is_fulltext($table, $index="") 975 { 976 $structure = $this->show_create_table($table); 977 if($index != "") 978 { 979 if(preg_match("#FULLTEXT KEY (`?)$index(`?)#i", $structure)) 980 { 981 return true; 982 } 983 else 984 { 985 return false; 986 } 987 } 988 if(preg_match('#FULLTEXT KEY#i', $structure)) 989 { 990 return true; 991 } 992 return false; 993 } 994 995 /** 996 * Returns whether or not this database engine supports fulltext indexing. 997 * 998 * @param string The table to be checked. 999 * @return boolean True or false if supported or not. 1000 */ 1001 1002 function supports_fulltext($table) 1003 { 1004 $version = $this->get_version(); 1005 $query = $this->write_query("SHOW TABLE STATUS LIKE '{$this->table_prefix}$table'"); 1006 $status = $this->fetch_array($query); 1007 $table_type = my_strtoupper($status['Engine']); 1008 if($version >= '3.23.23' && $table_type == 'MYISAM') 1009 { 1010 return true; 1011 } 1012 return false; 1013 } 1014 1015 /** 1016 * Returns whether or not this database engine supports boolean fulltext matching. 1017 * 1018 * @param string The table to be checked. 1019 * @return boolean True or false if supported or not. 1020 */ 1021 function supports_fulltext_boolean($table) 1022 { 1023 $version = $this->get_version(); 1024 $supports_fulltext = $this->supports_fulltext($table); 1025 if($version >= '4.0.1' && $supports_fulltext == true) 1026 { 1027 return true; 1028 } 1029 return false; 1030 } 1031 1032 /** 1033 * Checks to see if an index exists on a specified table 1034 * 1035 * @param string The name of the table. 1036 * @param string The name of the index. 1037 */ 1038 function index_exists($table, $index) 1039 { 1040 $index_exists = false; 1041 $query = $this->write_query("SHOW INDEX FROM {$this->table_prefix}{$table}"); 1042 while($ukey = $this->fetch_array($query)) 1043 { 1044 if($ukey['Key_name'] == $index) 1045 { 1046 $index_exists = true; 1047 break; 1048 } 1049 } 1050 1051 if($index_exists) 1052 { 1053 return true; 1054 } 1055 1056 return false; 1057 } 1058 1059 /** 1060 * Creates a fulltext index on the specified column in the specified table with optional index name. 1061 * 1062 * @param string The name of the table. 1063 * @param string Name of the column to be indexed. 1064 * @param string The index name, optional. 1065 */ 1066 function create_fulltext_index($table, $column, $name="") 1067 { 1068 $this->write_query("ALTER TABLE {$this->table_prefix}$table ADD FULLTEXT $name ($column)"); 1069 } 1070 1071 /** 1072 * Drop an index with the specified name from the specified table 1073 * 1074 * @param string The name of the table. 1075 * @param string The name of the index. 1076 */ 1077 function drop_index($table, $name) 1078 { 1079 $this->write_query("ALTER TABLE {$this->table_prefix}$table DROP INDEX $name"); 1080 } 1081 1082 /** 1083 * Drop an table with the specified table 1084 * 1085 * @param boolean hard drop - no checking 1086 * @param boolean use table prefix 1087 */ 1088 function drop_table($table, $hard=false, $table_prefix=true) 1089 { 1090 if($table_prefix == false) 1091 { 1092 $table_prefix = ""; 1093 } 1094 else 1095 { 1096 $table_prefix = $this->table_prefix; 1097 } 1098 1099 if($hard == false) 1100 { 1101 $this->write_query('DROP TABLE IF EXISTS '.$table_prefix.$table); 1102 } 1103 else 1104 { 1105 $this->write_query('DROP TABLE '.$table_prefix.$table); 1106 } 1107 } 1108 1109 /** 1110 * Replace contents of table with values 1111 * 1112 * @param string The table 1113 * @param array The replacements 1114 */ 1115 function replace_query($table, $replacements=array()) 1116 { 1117 $values = ''; 1118 $comma = ''; 1119 foreach($replacements as $column => $value) 1120 { 1121 $values .= $comma."`".$column."`='".$value."'"; 1122 1123 $comma = ','; 1124 } 1125 1126 if(empty($replacements)) 1127 { 1128 return false; 1129 } 1130 1131 return $this->write_query("REPLACE INTO {$this->table_prefix}{$table} SET {$values}"); 1132 } 1133 1134 /** 1135 * Drops a column 1136 * 1137 * @param string The table 1138 * @param string The column name 1139 */ 1140 function drop_column($table, $column) 1141 { 1142 return $this->write_query("ALTER TABLE {$this->table_prefix}{$table} DROP {$column}"); 1143 } 1144 1145 /** 1146 * Adds a column 1147 * 1148 * @param string The table 1149 * @param string The column name 1150 * @param string the new column definition 1151 */ 1152 function add_column($table, $column, $definition) 1153 { 1154 return $this->write_query("ALTER TABLE {$this->table_prefix}{$table} ADD {$column} {$definition}"); 1155 } 1156 1157 /** 1158 * Modifies a column 1159 * 1160 * @param string The table 1161 * @param string The column name 1162 * @param string the new column definition 1163 */ 1164 function modify_column($table, $column, $new_definition) 1165 { 1166 return $this->write_query("ALTER TABLE {$this->table_prefix}{$table} MODIFY {$column} {$new_definition}"); 1167 } 1168 1169 /** 1170 * Renames a column 1171 * 1172 * @param string The table 1173 * @param string The old column name 1174 * @param string the new column name 1175 * @param string the new column definition 1176 */ 1177 function rename_column($table, $old_column, $new_column, $new_definition) 1178 { 1179 return $this->write_query("ALTER TABLE {$this->table_prefix}{$table} CHANGE {$old_column} {$new_column} {$new_definition}"); 1180 } 1181 1182 /** 1183 * Sets the table prefix used by the simple select, insert, update and delete functions 1184 * 1185 * @param string The new table prefix 1186 */ 1187 function set_table_prefix($prefix) 1188 { 1189 $this->table_prefix = $prefix; 1190 } 1191 1192 /** 1193 * Fetched the total size of all mysql tables or a specific table 1194 * 1195 * @param string The table (optional) 1196 * @return integer the total size of all mysql tables or a specific table 1197 */ 1198 function fetch_size($table='') 1199 { 1200 if($table != '') 1201 { 1202 $query = $this->query("SHOW TABLE STATUS LIKE '".$this->table_prefix.$table."'"); 1203 } 1204 else 1205 { 1206 $query = $this->query("SHOW TABLE STATUS"); 1207 } 1208 $total = 0; 1209 while($table = $this->fetch_array($query)) 1210 { 1211 $total += $table['Data_length']+$table['Index_length']; 1212 } 1213 return $total; 1214 } 1215 1216 /** 1217 * Fetch a list of database character sets this DBMS supports 1218 * 1219 * @return array Array of supported character sets with array key being the name, array value being display name. False if unsupported 1220 */ 1221 function fetch_db_charsets() 1222 { 1223 if($this->link && version_compare($this->get_version(), "4.1", "<")) 1224 { 1225 return false; 1226 } 1227 return array( 1228 'big5' => 'Big5 Traditional Chinese', 1229 'dec8' => 'DEC West European', 1230 'cp850' => 'DOS West European', 1231 'hp8' => 'HP West European', 1232 'koi8r' => 'KOI8-R Relcom Russian', 1233 'latin1' => 'cp1252 West European', 1234 'latin2' => 'ISO 8859-2 Central European', 1235 'swe7' => '7bit Swedish', 1236 'ascii' => 'US ASCII', 1237 'ujis' => 'EUC-JP Japanese', 1238 'sjis' => 'Shift-JIS Japanese', 1239 'hebrew' => 'ISO 8859-8 Hebrew', 1240 'tis620' => 'TIS620 Thai', 1241 'euckr' => 'EUC-KR Korean', 1242 'koi8u' => 'KOI8-U Ukrainian', 1243 'gb2312' => 'GB2312 Simplified Chinese', 1244 'greek' => 'ISO 8859-7 Greek', 1245 'cp1250' => 'Windows Central European', 1246 'gbk' => 'GBK Simplified Chinese', 1247 'latin5' => 'ISO 8859-9 Turkish', 1248 'armscii8' => 'ARMSCII-8 Armenian', 1249 'utf8' => 'UTF-8 Unicode', 1250 'ucs2' => 'UCS-2 Unicode', 1251 'cp866' => 'DOS Russian', 1252 'keybcs2' => 'DOS Kamenicky Czech-Slovak', 1253 'macce' => 'Mac Central European', 1254 'macroman' => 'Mac West European', 1255 'cp852' => 'DOS Central European', 1256 'latin7' => 'ISO 8859-13 Baltic', 1257 'cp1251' => 'Windows Cyrillic', 1258 'cp1256' => 'Windows Arabic', 1259 'cp1257' => 'Windows Baltic', 1260 'binary' => 'Binary pseudo charset', 1261 'geostd8' => 'GEOSTD8 Georgian', 1262 'cp932' => 'SJIS for Windows Japanese', 1263 'eucjpms' => 'UJIS for Windows Japanese', 1264 ); 1265 } 1266 1267 /** 1268 * Fetch a database collation for a particular database character set 1269 * 1270 * @param string The database character set 1271 * @return string The matching database collation, false if unsupported 1272 */ 1273 function fetch_charset_collation($charset) 1274 { 1275 $collations = array( 1276 'big5' => 'big5_chinese_ci', 1277 'dec8' => 'dec8_swedish_ci', 1278 'cp850' => 'cp850_general_ci', 1279 'hp8' => 'hp8_english_ci', 1280 'koi8r' => 'koi8r_general_ci', 1281 'latin1' => 'latin1_swedish_ci', 1282 'latin2' => 'latin2_general_ci', 1283 'swe7' => 'swe7_swedish_ci', 1284 'ascii' => 'ascii_general_ci', 1285 'ujis' => 'ujis_japanese_ci', 1286 'sjis' => 'sjis_japanese_ci', 1287 'hebrew' => 'hebrew_general_ci', 1288 'tis620' => 'tis620_thai_ci', 1289 'euckr' => 'euckr_korean_ci', 1290 'koi8u' => 'koi8u_general_ci', 1291 'gb2312' => 'gb2312_chinese_ci', 1292 'greek' => 'greek_general_ci', 1293 'cp1250' => 'cp1250_general_ci', 1294 'gbk' => 'gbk_chinese_ci', 1295 'latin5' => 'latin5_turkish_ci', 1296 'armscii8' => 'armscii8_general_ci', 1297 'utf8' => 'utf8_general_ci', 1298 'ucs2' => 'ucs2_general_ci', 1299 'cp866' => 'cp866_general_ci', 1300 'keybcs2' => 'keybcs2_general_ci', 1301 'macce' => 'macce_general_ci', 1302 'macroman' => 'macroman_general_ci', 1303 'cp852' => 'cp852_general_ci', 1304 'latin7' => 'latin7_general_ci', 1305 'cp1251' => 'cp1251_general_ci', 1306 'cp1256' => 'cp1256_general_ci', 1307 'cp1257' => 'cp1257_general_ci', 1308 'binary' => 'binary', 1309 'geostd8' => 'geostd8_general_ci', 1310 'cp932' => 'cp932_japanese_ci', 1311 'eucjpms' => 'eucjpms_japanese_ci', 1312 ); 1313 if($collations[$charset]) 1314 { 1315 return $collations[$charset]; 1316 } 1317 return false; 1318 } 1319 1320 /** 1321 * Fetch a character set/collation string for use with CREATE TABLE statements. Uses current DB encoding 1322 * 1323 * @return string The built string, empty if unsupported 1324 */ 1325 function build_create_table_collation() 1326 { 1327 if(!$this->db_encoding) 1328 { 1329 return ''; 1330 } 1331 1332 $collation = $this->fetch_charset_collation($this->db_encoding); 1333 if(!$collation) 1334 { 1335 return ''; 1336 } 1337 return " CHARACTER SET {$this->db_encoding} COLLATE {$collation}"; 1338 } 1339 1340 /** 1341 * Time how long it takes for a particular piece of code to run. Place calls above & below the block of code. 1342 * 1343 * @return float The time taken 1344 */ 1345 function get_execution_time() 1346 { 1347 static $time_start; 1348 1349 $time = microtime(true); 1350 1351 1352 // Just starting timer, init and return 1353 if(!$time_start) 1354 { 1355 $time_start = $time; 1356 return; 1357 } 1358 // Timer has run, return execution time 1359 else 1360 { 1361 $total = $time-$time_start; 1362 if($total < 0) $total = 0; 1363 $time_start = 0; 1364 return $total; 1365 } 1366 } 1367 } 1368 1369 ?>
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Tue Oct 8 19:19:50 2013 | Cross-referenced by PHPXref 0.7.1 |