[ Index ]

PHP Cross Reference of MyBB

title

Body

[close]

/inc/ -> db_mysqli.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_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  ?>


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