[ Index ]

PHP Cross Reference of MyBB

title

Body

[close]

/inc/ -> db_mysql.php (source)

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


Generated: Tue Oct 8 19:19:50 2013 Cross-referenced by PHPXref 0.7.1