[ Index ]

PHP Cross Reference of MyBB 1.8.27

title

Body

[close]

/inc/ -> db_sqlite.php (source)

   1  <?php
   2  /**
   3   * MyBB 1.8
   4   * Copyright 2014 MyBB Group, All Rights Reserved
   5   *
   6   * Website: http://www.mybb.com
   7   * License: http://www.mybb.com/about/license
   8   *
   9   */
  10  
  11  class DB_SQLite implements DB_Base
  12  {
  13      /**
  14       * The title of this layer.
  15       *
  16       * @var string
  17       */
  18      public $title = "SQLite 3";
  19  
  20      /**
  21       * The short title of this layer.
  22       *
  23       * @var string
  24       */
  25      public $short_title = "SQLite";
  26  
  27      /**
  28       * The type of db software being used.
  29       *
  30       * @var string
  31       */
  32      public $type;
  33  
  34      /**
  35       * PDOStatement objects of performed queries.
  36       *
  37       * @var array 
  38       */
  39      public $query_objects = array();
  40  
  41      /**
  42       * A count of the number of queries.
  43       *
  44       * @var int
  45       */
  46      public $query_count = 0;
  47  
  48      /**
  49       * A list of the performed queries.
  50       *
  51       * @var array
  52       */
  53      public $querylist = array();
  54  
  55      /**
  56       * 1 if error reporting enabled, 0 if disabled.
  57       *
  58       * @var boolean
  59       */
  60      public $error_reporting = 1;
  61  
  62      /**
  63       * The database connection resource.
  64       *
  65       * @var resource
  66       */
  67      public $link;
  68  
  69      /**
  70       * Explanation of a query.
  71       *
  72       * @var string
  73       */
  74      public $explain;
  75  
  76      /**
  77       * The current version of SQLite.
  78       *
  79       * @var string
  80       */
  81      public $version;
  82  
  83      /**
  84       * The current table type in use (myisam/innodb)
  85       *
  86       * @var string
  87       */
  88      public $table_type = "myisam";
  89  
  90      /**
  91       * The table prefix used for simple select, update, insert and delete queries
  92       *
  93       * @var string
  94       */
  95      public $table_prefix;
  96  
  97      /**
  98       * The extension used to run the SQL database
  99       *
 100       * @var string
 101       */
 102      public $engine = "pdo";
 103  
 104      /**
 105       * Weather or not this engine can use the search functionality
 106       *
 107       * @var boolean
 108       */
 109      public $can_search = true;
 110  
 111      /**
 112       * The database encoding currently in use (if supported)
 113       *
 114       * @var string
 115       */
 116      public $db_encoding = "";
 117  
 118      /**
 119       * The time spent performing queries
 120       *
 121       * @var float
 122       */
 123      public $query_time = 0;
 124  
 125      /**
 126       * Our pdo implementation
 127       *
 128       * @var dbpdoEngine
 129       */
 130      var $db;
 131  
 132      /**
 133       * Connect to the database server.
 134       *
 135       * @param array $config Array of DBMS connection details.
 136       * @return bool Returns false on failure, otherwise true
 137       */
 138  	function connect($config)
 139      {
 140          get_execution_time();
 141  
 142          require_once  MYBB_ROOT."inc/db_pdo.php";
 143  
 144          try {
 145              $this->db = new dbpdoEngine("sqlite:{$config['database']}");
 146          } catch (Exception $ex) {
 147              $this->error("[READ] Unable to open the SQLite database");
 148  
 149              return false;
 150          }
 151  
 152          $query_time = get_execution_time();
 153  
 154          $this->query_time += $query_time;
 155  
 156          $this->connections[] = "[WRITE] {$config['database']} (Connected in ".format_time_duration($query_time).")";
 157  
 158          if($this->db)
 159          {
 160              $this->query('PRAGMA short_column_names = 1');
 161              return true;
 162          }
 163          else
 164          {
 165              return false;
 166          }
 167      }
 168  
 169      /**
 170       * Query the database.
 171       *
 172       * @param string $string The query SQL.
 173       * @param boolean|int $hide_errors 1 if hide errors, 0 if not.
 174       * @param integer $write_query 1 if executes on master database, 0 if not.
 175       * @return PDOStatement The query data.
 176       */
 177  	function query($string, $hide_errors=0, $write_query=0)
 178      {
 179          global $mybb;
 180  
 181          get_execution_time();
 182  
 183          if(strtolower(substr(ltrim($string), 0, 5)) == 'alter')
 184          {
 185              $string = preg_replace("#\sAFTER\s([a-z_]+?)(;*?)$#i", "", $string);
 186  
 187              $queryparts = preg_split("/[\s]+/", $string, 4, PREG_SPLIT_NO_EMPTY);
 188              $tablename = $queryparts[2];
 189              $alterdefs = $queryparts[3];
 190              if(strtolower($queryparts[1]) != 'table' || $queryparts[2] == '')
 191              {
 192                  $this->error_msg = "near \"{$queryparts[0]}\": syntax error";
 193              }
 194              else
 195              {
 196                  // SQLITE 3 supports ADD and RENAME TO alter statements
 197                  if(strtolower(substr(ltrim($alterdefs), 0, 3)) == 'add' || strtolower(substr(ltrim($alterdefs), 0, 9)) == "rename to")
 198                  {
 199                      $query = $this->db->query($string);
 200                      $query->closeCursor();
 201                  }
 202                  else
 203                  {
 204                      $query = $this->alter_table_parse($tablename, $alterdefs, $string);
 205                  }
 206              }
 207          }
 208            else
 209            {
 210              try
 211              {
 212                  $query = $this->db->query($string);
 213              }
 214              catch(PDOException $exception)
 215              {
 216                  $error = array(
 217                      "message" => $exception->getMessage(),
 218                      "code" => $exception->getCode()
 219                  );
 220  
 221                  $this->error($error['message'], $error['code']);
 222              }
 223          }
 224  
 225          $this->query_objects[] = $query;
 226  
 227          if($this->error_number($query) > 0 && !$hide_errors)
 228          {
 229              $this->error($string, $query);
 230              exit;
 231          }
 232  
 233          $query_time = get_execution_time();
 234          $this->query_time += $query_time;
 235          $this->query_count++;
 236  
 237          if($mybb->debug_mode)
 238          {
 239              $this->explain_query($string, $query_time);
 240          }
 241  
 242          if(strtolower(substr(ltrim($string), 0, 6)) == "create")
 243          {
 244              $query->closeCursor();
 245              return null;
 246          }
 247  
 248          return $query;
 249      }
 250  
 251      /**
 252       * Explain a query on the database.
 253       *
 254       * @param string $string The query SQL.
 255       * @param string $qtime The time it took to perform the query.
 256       */
 257  	function explain_query($string, $qtime)
 258      {
 259          if(preg_match("#^\s*select#i", $string))
 260          {
 261              $this->explain .= "<table style=\"background-color: #666;\" width=\"95%\" cellpadding=\"4\" cellspacing=\"1\" align=\"center\">\n".
 262                  "<tr>\n".
 263                  "<td colspan=\"8\" style=\"background-color: #ccc;\"><strong>#".$this->query_count." - Select Query</strong></td>\n".
 264                  "</tr>\n".
 265                  "<tr>\n".
 266                  "<td colspan=\"8\" style=\"background-color: #fefefe;\"><span style=\"font-family: Courier; font-size: 14px;\">".htmlspecialchars_uni($string)."</span></td>\n".
 267                  "</tr>\n".
 268                  "<tr>\n".
 269                  "<td colspan=\"8\" style=\"background-color: #fff;\">Query Time: ".format_time_duration($qtime)."</td>\n".
 270                  "</tr>\n".
 271                  "</table>\n".
 272                  "<br />\n";
 273          }
 274          else
 275          {
 276              $this->explain .= "<table style=\"background-color: #666;\" width=\"95%\" cellpadding=\"4\" cellspacing=\"1\" align=\"center\">\n".
 277                  "<tr>\n".
 278                  "<td style=\"background-color: #ccc;\"><strong>#".$this->query_count." - Write Query</strong></td>\n".
 279                  "</tr>\n".
 280                  "<tr style=\"background-color: #fefefe;\">\n".
 281                  "<td><span style=\"font-family: Courier; font-size: 14px;\">".htmlspecialchars_uni($string)."</span></td>\n".
 282                  "</tr>\n".
 283                  "<tr>\n".
 284                  "<td bgcolor=\"#ffffff\">Query Time: ".format_time_duration($qtime)."</td>\n".
 285                  "</tr>\n".
 286                  "</table>\n".
 287                  "<br />\n";
 288          }
 289  
 290          $this->querylist[$this->query_count]['query'] = $string;
 291          $this->querylist[$this->query_count]['time'] = $qtime;
 292      }
 293  
 294      /**
 295       * Execute a write query on the database
 296       *
 297       * @param string $query The query SQL.
 298       * @param boolean|int $hide_errors 1 if hide errors, 0 if not.
 299       * @return PDOStatement The query data.
 300       */
 301  	function write_query($query, $hide_errors=0)
 302      {
 303          return $this->query($query, $hide_errors);
 304      }
 305  
 306      /**
 307       * Return a result array for a query.
 308       *
 309       * @param PDOStatement $query The result data.
 310       * @param int $resulttype One of PDO's constants: FETCH_ASSOC, FETCH_BOUND, FETCH_CLASS, FETCH_INTO, FETCH_LAZY, FETCH_NAMED, FETCH_NUM, FETCH_OBJ or FETCH_BOTH
 311       * @return array The array of results.
 312       */
 313  	function fetch_array($query, $resulttype=PDO::FETCH_BOTH)
 314      {
 315          $array = $this->db->fetch_array($query, $resulttype);
 316          return $array;
 317      }
 318  
 319      /**
 320       * Return a specific field from a query.
 321       *
 322       * @param PDOStatement $query The query ID.
 323       * @param string $field The name of the field to return.
 324       * @param int|bool $row The number of the row to fetch it from.
 325       * @return mixed
 326       */
 327  	function fetch_field($query, $field, $row=false)
 328      {
 329          if($row !== false)
 330          {
 331              $this->data_seek($query, $row);
 332          }
 333          $array = $this->fetch_array($query);
 334          if($array !== null && $array !== false)
 335          {
 336              return $array[$field];
 337          }
 338          return null;
 339      }
 340  
 341      /**
 342       * Moves internal row pointer to the next row
 343       *
 344       * @param PDOStatement $query The query ID.
 345       * @param int $row The pointer to move the row to.
 346       */
 347  	function data_seek($query, $row)
 348      {
 349          $this->db->seek($query, $row);
 350      }
 351  
 352      /**
 353       * Closes cursors of registered queries.
 354       *
 355       */
 356  	function close_cursors()
 357      {
 358          $result = true;
 359  
 360          foreach($this->query_objects as $query)
 361          {
 362              if(!$query->closeCursor())
 363              {
 364                  $result = false;
 365              }
 366          }
 367  
 368          return $result;
 369      }
 370  
 371      /**
 372       * Return the number of rows resulting from a query.
 373       *
 374       * @param PDOStatement $query The query data.
 375       * @return int The number of rows in the result.
 376       */
 377  	function num_rows($query)
 378      {
 379          return $this->db->num_rows($query);
 380      }
 381  
 382      /**
 383       * Return the last id number of inserted data.
 384       *
 385       * @param string $name
 386       * @return int The id number.
 387       */
 388  	function insert_id($name="")
 389      {
 390          return $this->db->insert_id($name);
 391      }
 392  
 393      /**
 394       * Close the connection with the DBMS.
 395       *
 396       */
 397  	function close()
 398      {
 399          return;
 400      }
 401  
 402      /**
 403       * Return an error number.
 404       *
 405       * @param PDOStatement $query
 406       * @return int The error number of the current error.
 407       */
 408  	function error_number($query=null)
 409      {
 410          if($query == null)
 411          {
 412              $query = $this->db->last_query;
 413          }
 414  
 415          $this->error_number = $this->db->error_number($query);
 416  
 417          return $this->error_number;
 418      }
 419  
 420      /**
 421       * Return an error string.
 422       *
 423       * @param PDOStatement $query
 424       * @return string The explanation for the current error.
 425       */
 426  	function error_string($query=null)
 427      {
 428          if($this->error_number != "")
 429          {
 430              if($query == null)
 431              {
 432                  $query = $this->db->last_query;
 433              }
 434  
 435              $error_string = $this->db->error_string($query);
 436              $this->error_number = "";
 437  
 438              return $error_string;
 439          }
 440  
 441          return '';
 442      }
 443  
 444      /**
 445       * Output a database error.
 446       *
 447       * @param string $string The string to present as an error.
 448       * @param PDOStatement $query
 449       * @param string $error
 450       * @param int $error_no
 451       */
 452  	function error($string="", $query=null, $error="", $error_no=0)
 453      {
 454          if($this->error_reporting)
 455          {
 456              if($query == null)
 457              {
 458                  $query = $this->db->last_query;
 459              }
 460  
 461              if($error_no == 0)
 462              {
 463                  $error_no = $this->error_number($query);
 464              }
 465  
 466              if($error == "")
 467              {
 468                  $error = $this->error_string($query);
 469              }
 470  
 471              if(class_exists("errorHandler"))
 472              {
 473                  global $error_handler;
 474  
 475                  if(!is_object($error_handler))
 476                  {
 477                      require_once  MYBB_ROOT."inc/class_error.php";
 478                      $error_handler = new errorHandler();
 479                  }
 480  
 481                  $error = array(
 482                      "error_no" => $error_no,
 483                      "error" => $error,
 484                      "query" => $string
 485                  );
 486                  $error_handler->error(MYBB_SQL, $error);
 487              }
 488              else
 489              {
 490                  trigger_error("<strong>[SQL] [{$error_no}] {$error}</strong><br />{$string}", E_USER_ERROR);
 491              }
 492          }
 493      }
 494  
 495      /**
 496       * Returns the number of affected rows in a query.
 497       *
 498       * @param PDOStatement $query
 499       * @return int The number of affected rows.
 500       */
 501  	function affected_rows($query=null)
 502      {
 503          if($query == null)
 504          {
 505              $query = $this->db->last_query;
 506          }
 507  
 508          return $this->db->affected_rows($query);
 509      }
 510  
 511      /**
 512       * Return the number of fields.
 513       *
 514       * @param PDOStatement $query The query data.
 515       * @return int The number of fields.
 516       */
 517  	function num_fields($query)
 518      {
 519          if(!$query)
 520          {
 521              $query = $this->db->last_query;
 522          }
 523  
 524          return $this->db->num_fields($query);
 525      }
 526  
 527      /**
 528       * Lists all tables in the database.
 529       *
 530       * @param string $database The database name.
 531       * @param string $prefix Prefix of the table (optional)
 532       * @return array The table list.
 533       */
 534  	function list_tables($database, $prefix='')
 535      {
 536          if($prefix)
 537          {
 538              $query = $this->query("SELECT tbl_name FROM sqlite_master WHERE type = 'table' AND tbl_name LIKE '".$this->escape_string($prefix)."%'");
 539          }
 540          else
 541          {
 542              $query = $this->query("SELECT tbl_name FROM sqlite_master WHERE type = 'table'");
 543          }
 544  
 545          $tables = array();
 546          while($table = $this->fetch_array($query))
 547          {
 548              $tables[] = $table['tbl_name'];
 549          }
 550          $query->closeCursor();
 551          return $tables;
 552      }
 553  
 554      /**
 555       * Check if a table exists in a database.
 556       *
 557       * @param string $table The table name.
 558       * @return boolean True when exists, false if not.
 559       */
 560  	function table_exists($table)
 561      {
 562          $query = $this->query("SELECT COUNT(name) as count FROM sqlite_master WHERE type='table' AND name='{$this->table_prefix}{$table}'");
 563          $exists = $this->fetch_field($query, "count");
 564          $query->closeCursor();
 565  
 566          if($exists > 0)
 567          {
 568              return true;
 569          }
 570          else
 571          {
 572              return false;
 573          }
 574      }
 575  
 576      /**
 577       * Check if a field exists in a database.
 578       *
 579       * @param string $field The field name.
 580       * @param string $table The table name.
 581       * @return boolean True when exists, false if not.
 582       */
 583  	function field_exists($field, $table)
 584      {
 585          $query = $this->query("PRAGMA table_info('{$this->table_prefix}{$table}')");
 586  
 587          $exists = 0;
 588  
 589          while($row = $this->fetch_array($query))
 590          {
 591              if($row['name'] == $field)
 592              {
 593                  ++$exists;
 594              }
 595          }
 596  
 597          $query->closeCursor();
 598  
 599          if($exists > 0)
 600          {
 601              return true;
 602          }
 603          else
 604          {
 605              return false;
 606          }
 607      }
 608  
 609      /**
 610       * Add a shutdown query.
 611       *
 612       * @param PDOStatement $query The query data.
 613       * @param string $name An optional name for the query.
 614       */
 615  	function shutdown_query($query, $name="")
 616      {
 617          global $shutdown_queries;
 618          if($name)
 619          {
 620              $shutdown_queries[$name] = $query;
 621          }
 622          else
 623          {
 624              $shutdown_queries[] = $query;
 625          }
 626      }
 627  
 628      /**
 629       * Performs a simple select query.
 630       *
 631       * @param string $table The table name to be queried.
 632       * @param string $fields Comma delimetered list of fields to be selected.
 633       * @param string $conditions SQL formatted list of conditions to be matched.
 634       * @param array $options List of options: group by, order by, order direction, limit, limit start.
 635       * @return PDOStatement The query data.
 636       */
 637  	function simple_select($table, $fields="*", $conditions="", $options=array())
 638      {
 639          $query = "SELECT ".$fields." FROM ".$this->table_prefix.$table;
 640  
 641          if($conditions != "")
 642          {
 643              $query .= " WHERE ".$conditions;
 644          }
 645  
 646          if(isset($options['group_by']))
 647          {
 648              $query .= " GROUP BY ".$options['group_by'];
 649          }
 650  
 651          if(isset($options['order_by']))
 652          {
 653              $query .= " ORDER BY ".$options['order_by'];
 654  
 655              if(isset($options['order_dir']))
 656              {
 657                  $query .= " ".strtoupper($options['order_dir']);
 658              }
 659          }
 660  
 661          if(isset($options['limit_start']) && isset($options['limit']))
 662          {
 663              $query .= " LIMIT ".$options['limit_start'].", ".$options['limit'];
 664          }
 665          else if(isset($options['limit']))
 666          {
 667              $query .= " LIMIT ".$options['limit'];
 668          }
 669  
 670          return $this->query($query);
 671      }
 672  
 673      /**
 674       * Build an insert query from an array.
 675       *
 676       * @param string $table The table name to perform the query on.
 677       * @param array $array An array of fields and their values.
 678       * @return int|bool The insert ID if available or false if an error is found
 679       */
 680  	function insert_query($table, $array)
 681      {
 682          global $mybb;
 683  
 684          if(!is_array($array))
 685          {
 686              return false;
 687          }
 688  
 689          foreach($array as $field => $value)
 690          {
 691              if(isset($mybb->binary_fields[$table][$field]) && $mybb->binary_fields[$table][$field])
 692              {
 693                  if($value[0] != 'X') // Not escaped?
 694                  {
 695                      $value = $this->escape_binary($value);
 696                  }
 697                  
 698                  $array[$field] = $value;
 699              }
 700              else
 701              {
 702                  $array[$field] = $this->quote_val($value);
 703              }
 704          }
 705  
 706          $fields = implode(",", array_keys($array));
 707          $values = implode(",", $array);
 708          $query = $this->write_query("
 709              INSERT
 710              INTO {$this->table_prefix}{$table} (".$fields.")
 711              VALUES (".$values.")
 712          ");
 713          $query->closeCursor();
 714          return $this->insert_id();
 715      }
 716  
 717      /**
 718       * Build one query for multiple inserts from a multidimensional array.
 719       *
 720       * @param string $table The table name to perform the query on.
 721       * @param array $array An array of inserts.
 722       * @return void
 723       */
 724  	function insert_query_multiple($table, $array)
 725      {
 726          global $mybb;
 727  
 728          if(!is_array($array))
 729          {
 730              return;
 731          }
 732          // Field names
 733          $fields = array_keys($array[0]);
 734          $fields = implode(",", $fields);
 735  
 736          $insert_rows = array();
 737          foreach($array as $values)
 738          {
 739              foreach($values as $field => $value)
 740              {
 741                  if(isset($mybb->binary_fields[$table][$field]) && $mybb->binary_fields[$table][$field])
 742                  {
 743                      if($value[0] != 'X') // Not escaped?
 744                      {
 745                          $value = $this->escape_binary($value);
 746                      }
 747                  
 748                      $values[$field] = $value;
 749                  }
 750                  else
 751                  {
 752                      $values[$field] = $this->quote_val($value);
 753                  }
 754              }
 755              $insert_rows[] = "(".implode(",", $values).")";
 756          }
 757          $insert_rows = implode(", ", $insert_rows);
 758  
 759          $query = $this->write_query("
 760              INSERT
 761              INTO {$this->table_prefix}{$table} ({$fields})
 762              VALUES {$insert_rows}
 763          ");
 764          $query->closeCursor();
 765      }
 766  
 767      /**
 768       * Build an update query from an array.
 769       *
 770       * @param string $table The table name to perform the query on.
 771       * @param array $array An array of fields and their values.
 772       * @param string $where An optional where clause for the query.
 773       * @param string $limit An optional limit clause for the query.
 774       * @param boolean $no_quote An option to quote incoming values of the array.
 775       * @return PDOStatement The query data.
 776       */
 777  	function update_query($table, $array, $where="", $limit="", $no_quote=false)
 778      {
 779          global $mybb;
 780  
 781          if(!is_array($array))
 782          {
 783              return false;
 784          }
 785  
 786          $comma = "";
 787          $query = "";
 788          $quote = "'";
 789  
 790          if($no_quote == true)
 791          {
 792              $quote = "";
 793          }
 794  
 795          foreach($array as $field => $value)
 796          {
 797              if(isset($mybb->binary_fields[$table][$field]) && $mybb->binary_fields[$table][$field])
 798              {
 799                  if($value[0] != 'X') // Not escaped?
 800                  {
 801                      $value = $this->escape_binary($value);
 802                  }
 803                  
 804                  $query .= $comma.$field."=".$value;
 805              }
 806              else
 807              {
 808                  $quoted_value = $this->quote_val($value, $quote);
 809  
 810                  $query .= $comma.$field."={$quoted_value}";
 811              }
 812              $comma = ', ';
 813          }
 814  
 815          if(!empty($where))
 816          {
 817              $query .= " WHERE $where";
 818          }
 819  
 820          $query = $this->query("UPDATE {$this->table_prefix}$table SET $query");
 821          $query->closeCursor();
 822          return $query;
 823      }
 824  
 825      /**
 826       * @param int|string $value
 827       * @param string $quote
 828       *
 829       * @return int|string
 830       */
 831  	private function quote_val($value, $quote="'")
 832      {
 833          if(is_int($value))
 834          {
 835              $quoted = $value;
 836          }
 837          else
 838          {
 839              $quoted = $quote . $value . $quote;
 840          }
 841  
 842          return $quoted;
 843      }
 844  
 845      /**
 846       * Build a delete query.
 847       *
 848       * @param string $table The table name to perform the query on.
 849       * @param string $where An optional where clause for the query.
 850       * @param string $limit An optional limit clause for the query.
 851       * @return PDOStatement The query data.
 852       */
 853  	function delete_query($table, $where="", $limit="")
 854      {
 855          $query = "";
 856          if(!empty($where))
 857          {
 858              $query .= " WHERE $where";
 859          }
 860  
 861          $query = $this->query("DELETE FROM {$this->table_prefix}$table $query");
 862          $query->closeCursor();
 863          return $query;
 864      }
 865  
 866      /**
 867       * Escape a string
 868       *
 869       * @param string $string The string to be escaped.
 870       * @return string The escaped string.
 871       */
 872  	function escape_string($string)
 873      {
 874          $string = $this->db->escape_string($string);
 875          return $string;
 876      }
 877  
 878      /**
 879       * Serves no purposes except compatibility
 880       *
 881       * @param PDOStatement $query
 882       * @return boolean Returns true on success, false on failure
 883       */
 884  	function free_result($query)
 885      {
 886          return true;
 887      }
 888  
 889      /**
 890       * Escape a string used within a like command.
 891       *
 892       * @param string $string The string to be escaped.
 893       * @return string The escaped string.
 894       */
 895  	function escape_string_like($string)
 896      {
 897          return $this->escape_string(str_replace(array('\\', '%', '_') , array('\\\\', '\\%' , '\\_') , $string));
 898      }
 899  
 900      /**
 901       * Gets the current version of SQLLite.
 902       *
 903       * @return string Version of MySQL.
 904       */
 905  	function get_version()
 906      {
 907          if($this->version)
 908          {
 909              return $this->version;
 910          }
 911          $this->version = $this->db->get_attribute("ATTR_SERVER_VERSION");
 912  
 913          return $this->version;
 914      }
 915  
 916      /**
 917       * Optimizes a specific table.
 918       *
 919       * @param string $table The name of the table to be optimized.
 920       */
 921  	function optimize_table($table)
 922      {
 923          $query = $this->query("VACUUM ".$this->table_prefix.$table."");
 924          $query->closeCursor();
 925      }
 926  
 927      /**
 928       * Analyzes a specific table.
 929       *
 930       * @param string $table The name of the table to be analyzed.
 931       */
 932  	function analyze_table($table)
 933      {
 934          $query = $this->query("ANALYZE ".$this->table_prefix.$table."");
 935          $query->closeCursor();
 936      }
 937  
 938      /**
 939       * Show the "create table" command for a specific table.
 940       *
 941       * @param string $table The name of the table.
 942       * @return string The SQLite command to create the specified table.
 943       */
 944  	function show_create_table($table)
 945      {
 946          $old_tbl_prefix = $this->table_prefix;
 947          $this->set_table_prefix("");
 948          $query = $this->simple_select("sqlite_master", "sql", "type = 'table' AND name = '{$old_tbl_prefix}{$table}' ORDER BY type DESC, name");
 949          $this->set_table_prefix($old_tbl_prefix);
 950  
 951          $result = $this->fetch_field($query, 'sql');
 952  
 953          $query->closeCursor();
 954  
 955          return $result;
 956      }
 957  
 958      /**
 959       * Show the "show fields from" command for a specific table.
 960       *
 961       * @param string $table The name of the table.
 962       * @return array Field info for that table
 963       */
 964  	function show_fields_from($table)
 965      {
 966          $old_tbl_prefix = $this->table_prefix;
 967          $this->set_table_prefix("");
 968          $query = $this->simple_select("sqlite_master", "sql", "type = 'table' AND name = '{$old_tbl_prefix}{$table}'");
 969          $this->set_table_prefix($old_tbl_prefix);
 970          $table = trim(preg_replace('#CREATE\s+TABLE\s+"?'.$this->table_prefix.$table.'"?#i', '', $this->fetch_field($query, "sql")));
 971          $query->closeCursor();
 972  
 973          preg_match('#\((.*)\)#s', $table, $matches);
 974  
 975          $field_info = array();
 976          $table_cols = explode(',', trim($matches[1]));
 977          foreach($table_cols as $declaration)
 978          {
 979              $entities = preg_split('#\s+#', trim($declaration));
 980              $column_name = preg_replace('/"?([^"]+)"?/', '\1', $entities[0]);
 981  
 982              $field_info[] = array('Extra' => $entities[1], 'Field' => $column_name);
 983          }
 984  
 985          return $field_info;
 986      }
 987  
 988      /**
 989       * Returns whether or not the table contains a fulltext index.
 990       *
 991       * @param string $table The name of the table.
 992       * @param string $index Optionally specify the name of the index.
 993       * @return boolean True or false if the table has a fulltext index or not.
 994       */
 995  	function is_fulltext($table, $index="")
 996      {
 997          return false;
 998      }
 999  
1000      /**
1001       * Returns whether or not this database engine supports fulltext indexing.
1002       *
1003       * @param string $table The table to be checked.
1004       * @return boolean True or false if supported or not.
1005       */
1006  
1007  	function supports_fulltext($table)
1008      {
1009          return false;
1010      }
1011  
1012      /**
1013       * Returns whether or not this database engine supports boolean fulltext matching.
1014       *
1015       * @param string $table The table to be checked.
1016       * @return boolean True or false if supported or not.
1017       */
1018  	function supports_fulltext_boolean($table)
1019      {
1020          return false;
1021      }
1022  
1023      /**
1024       * Creates a fulltext index on the specified column in the specified table with optional index name.
1025       *
1026       * @param string $table The name of the table.
1027       * @param string $column Name of the column to be indexed.
1028       * @param string $name The index name, optional.
1029       * @return bool
1030       */
1031  	function create_fulltext_index($table, $column, $name="")
1032      {
1033          return false;
1034      }
1035  
1036      /**
1037       * Drop an index with the specified name from the specified table
1038       *
1039       * @param string $table The name of the table.
1040       * @param string $name The name of the index.
1041       */
1042  	function drop_index($table, $name)
1043      {
1044          $query = $this->query("ALTER TABLE {$this->table_prefix}$table DROP INDEX $name");
1045          $query->closeCursor();
1046      }
1047  
1048      /**
1049       * Checks to see if an index exists on a specified table
1050       *
1051       * @param string $table The name of the table.
1052       * @param string $index The name of the index.
1053       * @return bool Returns whether index exists
1054       */
1055  	function index_exists($table, $index)
1056      {
1057          return false;
1058      }
1059  
1060      /**
1061       * Drop an table with the specified table
1062       *
1063       * @param string $table The name of the table.
1064       * @param boolean $hard hard drop - no checking
1065       * @param boolean $table_prefix use table prefix
1066       */
1067  	function drop_table($table, $hard=false, $table_prefix=true)
1068      {
1069          if($table_prefix == false)
1070          {
1071              $table_prefix = "";
1072          }
1073          else
1074          {
1075              $table_prefix = $this->table_prefix;
1076          }
1077  
1078          if($hard == false)
1079          {
1080              if($this->table_exists($table))
1081              {
1082                  $query = $this->query('DROP TABLE '.$table_prefix.$table);
1083              }
1084          }
1085          else
1086          {
1087              $query = $this->query('DROP TABLE '.$table_prefix.$table);
1088          }
1089  
1090          if(isset($query))
1091          {
1092              $query->closeCursor();
1093          }
1094      }
1095  
1096      /**
1097       * Renames a table
1098       *
1099       * @param string $old_table The old table name
1100       * @param string $new_table the new table name
1101       * @param boolean $table_prefix use table prefix
1102       * @return PDOStatement
1103       */
1104  	function rename_table($old_table, $new_table, $table_prefix=true)
1105      {
1106          if($table_prefix == false)
1107          {
1108              $table_prefix = "";
1109          }
1110          else
1111          {
1112              $table_prefix = $this->table_prefix;
1113          }
1114  
1115          $query = $this->write_query("ALTER TABLE {$table_prefix}{$old_table} RENAME TO {$table_prefix}{$new_table}");
1116          $query->closeCursor();
1117          return $query;
1118      }
1119  
1120      /**
1121       * Replace contents of table with values
1122       *
1123       * @param string $table The table
1124       * @param array $replacements The replacements
1125       * @param string|array $default_field The default field(s)
1126       * @param boolean $insert_id Whether or not to return an insert id. True by default
1127       * @return int|PDOStatement|bool Returns either the insert id (if a new row is inserted), the query resource (if a row is updated) or false on failure
1128       */
1129  	function replace_query($table, $replacements=array(), $default_field="", $insert_id=true)
1130      {
1131          global $mybb;
1132  
1133          $columns = '';
1134          $values = '';
1135          $comma = '';
1136          foreach($replacements as $column => $value)
1137          {
1138              $columns .= $comma.$column;
1139              if(isset($mybb->binary_fields[$table][$column]) && $mybb->binary_fields[$table][$column])
1140              {
1141                  if($value[0] != 'X') // Not escaped?
1142                  {
1143                      $value = $this->escape_binary($value);
1144                  }
1145                  
1146                  $values .= $comma.$value;
1147              }
1148              else
1149              {
1150                  $values .= $comma.$this->quote_val($value);
1151              }
1152  
1153              $comma = ',';
1154          }
1155  
1156          if(empty($columns) || empty($values))
1157          {
1158               return false;
1159          }
1160  
1161          if($default_field == "")
1162          {
1163              $query = $this->query("REPLACE INTO {$this->table_prefix}{$table} ({$columns}) VALUES({$values})");
1164              $query->closeCursor();
1165              return $query;
1166          }
1167          else
1168          {
1169              $update = false;
1170              if(is_array($default_field) && !empty($default_field))
1171              {
1172                  $search_bit = array();
1173                  foreach($default_field as $field)
1174                  {
1175                      $search_bit[] = "{$field} = '".$replacements[$field]."'";
1176                  }
1177  
1178                  $search_bit = implode(" AND ", $search_bit);
1179                  $query = $this->write_query("SELECT COUNT(".$default_field[0].") as count FROM {$this->table_prefix}{$table} WHERE {$search_bit} LIMIT 1");
1180                  if($this->fetch_field($query, "count") == 1)
1181                  {
1182                      $update = true;
1183                  }
1184              }
1185              else
1186              {
1187                  $query = $this->write_query("SELECT {$default_field} FROM {$this->table_prefix}{$table}");
1188                  $search_bit = "{$default_field}='".$replacements[$default_field]."'";
1189  
1190                  while($column = $this->fetch_array($query))
1191                  {
1192                      if($column[$default_field] == $replacements[$default_field])
1193                      {
1194                          $update = true;
1195                          break;
1196                      }
1197                  }
1198              }
1199  
1200              if($update === true)
1201              {
1202                  return $this->update_query($table, $replacements, $search_bit);
1203              }
1204              else
1205              {
1206                  return $this->insert_query($table, $replacements);
1207              }
1208          }
1209      }
1210  
1211      /**
1212       * Sets the table prefix used by the simple select, insert, update and delete functions
1213       *
1214       * @param string $prefix The new table prefix
1215       */
1216  	function set_table_prefix($prefix)
1217      {
1218          $this->table_prefix = $prefix;
1219      }
1220  
1221      /**
1222       * Fetched the total size of all mysql tables or a specific table
1223       *
1224       * @param string $table The table (optional) (ignored)
1225       * @return integer the total size of all mysql tables or a specific table
1226       */
1227  	function fetch_size($table='')
1228      {
1229          global $config, $lang;
1230  
1231          $total = @filesize($config['database']['database']);
1232          if(!$total || $table != '')
1233          {
1234              $total = $lang->na;
1235          }
1236          return $total;
1237      }
1238  
1239      /**
1240       * Perform an "Alter Table" query in SQLite < 3.2.0 - Code taken from http://code.jenseng.com/db/
1241       *
1242       * @param string $table The table (optional)
1243       * @param string $alterdefs
1244       * @param string $fullquery
1245       * @return bool True on success, false on failure
1246       */
1247  	function alter_table_parse($table, $alterdefs, $fullquery="")
1248      {
1249          if(!$fullquery)
1250          {
1251              $fullquery = " ... {$alterdefs}";
1252          }
1253  
1254          if(!defined("TIME_NOW"))
1255          {
1256              define("TIME_NOW", time());
1257          }
1258  
1259          if($alterdefs != '')
1260          {
1261              $result = $this->query("SELECT sql,name,type FROM sqlite_master WHERE tbl_name = '{$table}' ORDER BY type DESC");
1262              if($this->num_rows($result) > 0)
1263              {
1264                  $row = $this->fetch_array($result); // Table sql
1265                  $result->closeCursor();
1266                  $tmpname = 't'.TIME_NOW;
1267                  $origsql = trim(preg_replace("/[\s]+/", " ", str_replace(",", ", ", preg_replace("/[\(]/","( ", $row['sql'], 1))));
1268                  $createtemptableSQL = 'CREATE TEMPORARY '.substr(trim(preg_replace("'".$table."'", $tmpname, $origsql, 1)), 6);
1269                  $defs = preg_split("/[,]+/", $alterdefs, -1, PREG_SPLIT_NO_EMPTY);
1270                  $prevword = $table;
1271                  $oldcols = preg_split("/[,]+/", substr(trim($createtemptableSQL), strpos(trim($createtemptableSQL), '(')+1), -1, PREG_SPLIT_NO_EMPTY);
1272                  $newcols = array();
1273  
1274                  for($i = 0; $i < sizeof($oldcols); $i++)
1275                  {
1276                      $colparts = preg_split("/[\s]+/", $oldcols[$i], -1, PREG_SPLIT_NO_EMPTY);
1277                      $oldcols[$i] = $colparts[0];
1278                      $newcols[$colparts[0]] = $colparts[0];
1279                  }
1280  
1281                  $newcolumns = '';
1282                  $oldcolumns = '';
1283                  reset($newcols);
1284  
1285                  foreach($newcols as $key => $val)
1286                  {
1287                      $newcolumns .= ($newcolumns ? ', ' : '').$val;
1288                      $oldcolumns .= ($oldcolumns ? ', ' : '').$key;
1289                  }
1290  
1291                  $copytotempsql = 'INSERT INTO '.$tmpname.'('.$newcolumns.') SELECT '.$oldcolumns.' FROM '.$table;
1292                  $dropoldsql = 'DROP TABLE '.$table;
1293                  $createtesttableSQL = $createtemptableSQL;
1294  
1295                  foreach($defs as $def)
1296                  {
1297                      $defparts = preg_split("/[\s]+/", $def, -1, PREG_SPLIT_NO_EMPTY);
1298                      $action = strtolower($defparts[0]);
1299  
1300                      switch($action)
1301                      {
1302                          case 'change':
1303                              if(sizeof($defparts) <= 3)
1304                              {
1305                                  $this->error($alterdefs, 'near "'.$defparts[0].($defparts[1] ? ' '.$defparts[1] : '').($defparts[2] ? ' '.$defparts[2] : '').'": syntax error', E_USER_WARNING);
1306                                  return false;
1307                              }
1308  
1309                              if($severpos = strpos($createtesttableSQL, ' '.$defparts[1].' '))
1310                              {
1311                                  if($newcols[$defparts[1]] != $defparts[1])
1312                                  {
1313                                      $this->error($alterdefs, 'unknown column "'.$defparts[1].'" in "'.$table.'"');
1314                                      return false;
1315                                  }
1316  
1317                                  $newcols[$defparts[1]] = $defparts[2];
1318                                  $nextcommapos = strpos($createtesttableSQL, ',', $severpos);
1319                                  $insertval = '';
1320  
1321                                  for($i = 2; $i < sizeof($defparts); $i++)
1322                                  {
1323                                      $insertval .= ' '.$defparts[$i];
1324                                  }
1325  
1326                                  if($nextcommapos)
1327                                  {
1328                                      $createtesttableSQL = substr($createtesttableSQL, 0, $severpos).$insertval.substr($createtesttableSQL, $nextcommapos);
1329                                  }
1330                                  else
1331                                  {
1332                                      $createtesttableSQL = substr($createtesttableSQL, 0, $severpos-(strpos($createtesttableSQL, ',') ? 0 : 1)).$insertval.')';
1333                                  }
1334                              }
1335                              else
1336                              {
1337                                  $this->error($fullquery, 'unknown column "'.$defparts[1].'" in "'.$table.'"', E_USER_WARNING);
1338                                  return false;
1339                              }
1340                              break;
1341                          case 'drop':
1342                              if(sizeof($defparts) < 2)
1343                              {
1344                                  $this->error($fullquery, 'near "'.$defparts[0].($defparts[1] ? ' '.$defparts[1] : '').'": syntax error');
1345                                  return false;
1346                              }
1347  
1348                              if($severpos = strpos($createtesttableSQL, ' '.$defparts[1].' '))
1349                              {
1350                                  $nextcommapos = strpos($createtesttableSQL, ',', $severpos);
1351  
1352                                  if($nextcommapos)
1353                                  {
1354                                      $createtesttableSQL = substr($createtesttableSQL, 0, $severpos).substr($createtesttableSQL, $nextcommapos + 1);
1355                                  }
1356                                  else
1357                                  {
1358                                      $createtesttableSQL = substr($createtesttableSQL, 0, $severpos-(strpos($createtesttableSQL, ',') ? 0 : 1) - 1).')';
1359                                  }
1360  
1361                                  unset($newcols[$defparts[1]]);
1362                              }
1363                              else
1364                              {
1365                                  $this->error($fullquery, 'unknown column "'.$defparts[1].'" in "'.$table.'"');
1366                                  return false;
1367                              }
1368                              break;
1369                          default:
1370                              $this->error($fullquery, 'near "'.$prevword.'": syntax error');
1371                              return false;
1372                      }
1373  
1374                      $prevword = $defparts[sizeof($defparts)-1];
1375                  }
1376  
1377                  // This block of code generates a test table simply to verify that the columns specifed are valid in an sql statement
1378                  // This ensures that no reserved words are used as columns, for example
1379                  $this->query($createtesttableSQL);
1380  
1381                  $droptempsql = 'DROP TABLE '.$tmpname;
1382                  $query = $this->query($droptempsql, 0);    
1383                  if($query === false)
1384                  {
1385                      return false;
1386                  }
1387                  $query->closeCursor();
1388                  // End block
1389  
1390  
1391                  $createnewtableSQL = 'CREATE '.substr(trim(preg_replace("'{$tmpname}'", $table, $createtesttableSQL, 1)), 17);
1392                  $newcolumns = '';
1393                  $oldcolumns = '';
1394                  reset($newcols);
1395  
1396                  foreach($newcols as $key => $val)
1397                  {
1398                      $newcolumns .= ($newcolumns ? ', ' : '').$val;
1399                      $oldcolumns .= ($oldcolumns ? ', ' : '').$key;
1400                  }
1401  
1402                  $copytonewsql = 'INSERT INTO '.$table.'('.$newcolumns.') SELECT '.$oldcolumns.' FROM '.$tmpname;
1403  
1404  
1405                  $this->query($createtemptableSQL); // Create temp table
1406                  $query = $this->query($copytotempsql); // Copy to table
1407                  $query->closeCursor();
1408                  $query = $this->query($dropoldsql); // Drop old table
1409                  $query->closeCursor();
1410  
1411                  $this->query($createnewtableSQL); // Recreate original table
1412                  $query = $this->query($copytonewsql); // Copy back to original table
1413                  $query->closeCursor();
1414                  $query = $this->query($droptempsql); // Drop temp table
1415                  $query->closeCursor();
1416              }
1417              else
1418              {
1419                  $this->error($fullquery, 'no such table: '.$table);
1420                  return false;
1421              }
1422          }
1423          return true;
1424      }
1425  
1426      /**
1427       * Drops a column
1428       *
1429       * @param string $table The table
1430       * @param string $column The column name
1431       * @return PDOStatement
1432       */
1433  	function drop_column($table, $column)
1434      {
1435          return $this->write_query("ALTER TABLE {$this->table_prefix}{$table} DROP {$column}");
1436      }
1437  
1438      /**
1439       * Adds a column
1440       *
1441       * @param string $table The table
1442       * @param string $column The column name
1443       * @param string $definition the new column definition
1444       * @return PDOStatement
1445       */
1446  	function add_column($table, $column, $definition)
1447      {
1448          $query = $this->write_query("ALTER TABLE {$this->table_prefix}{$table} ADD {$column} {$definition}");
1449          $query->closeCursor();
1450          return $query;
1451      }
1452  
1453      /**
1454       * Modifies a column
1455       *
1456       * @param string $table The table
1457       * @param string $column The column name
1458       * @param string $new_definition the new column definition
1459       * @param boolean|string $new_not_null Whether to "drop" or "set" the NOT NULL attribute (no change if false)
1460       * @param boolean|string $new_default_value The new default value, or false to drop the attribute
1461       * @return bool Returns true if all queries are executed successfully or false if one of them failed
1462       */
1463  	function modify_column($table, $column, $new_definition, $new_not_null=false, $new_default_value=false)
1464      {
1465          // We use a rename query as both need to duplicate the table etc...
1466          return $this->rename_column($table, $column, $column, $new_definition, $new_not_null, $new_default_value);
1467      }
1468  
1469      /**
1470       * Renames a column
1471       *
1472       * @param string $table The table
1473       * @param string $old_column The old column name
1474       * @param string $new_column the new column name
1475       * @param string $new_definition the new column definition
1476       * @param boolean|string $new_not_null Whether to "drop" or "set" the NOT NULL attribute (no change if false)
1477       * @param boolean|string $new_default_value The new default value, or false to drop the attribute
1478       * @return bool Returns true if all queries are executed successfully
1479       */
1480  	function rename_column($table, $old_column, $new_column, $new_definition, $new_not_null=false, $new_default_value=false)
1481      {
1482          if($new_not_null !== false)
1483          {
1484              if(strtolower($new_not_null) == "set")
1485              {
1486                  $not_null = "NOT NULL";
1487              }
1488              else
1489              {
1490                  $not_null = "NULL";
1491              }
1492          }
1493          else
1494          {
1495              $not_null = '';
1496          }
1497  
1498          if($new_default_value !== false)
1499          {
1500              $default = "DEFAULT ".$new_default_value;
1501          }
1502          else
1503          {
1504              $default = '';
1505          }
1506  
1507          // This will trigger the "alter_table_parse" function which will copy the table and rename the column
1508          return (bool) $this->write_query("ALTER TABLE {$this->table_prefix}{$table} CHANGE {$old_column} {$new_column} {$new_definition} {$not_null} {$default}");
1509      }
1510  
1511      /**
1512       * Fetch a list of database character sets this DBMS supports
1513       *
1514       * @return array|bool Array of supported character sets with array key being the name, array value being display name. False if unsupported
1515       */
1516  	function fetch_db_charsets()
1517      {
1518          return false;
1519      }
1520  
1521      /**
1522       * Fetch a database collation for a particular database character set
1523       *
1524       * @param string $charset The database character set
1525       * @return string|bool The matching database collation, false if unsupported
1526       */
1527  	function fetch_charset_collation($charset)
1528      {
1529          return false;
1530      }
1531  
1532      /**
1533       * Fetch a character set/collation string for use with CREATE TABLE statements. Uses current DB encoding
1534       *
1535       * @return string The built string, empty if unsupported
1536       */
1537  	function build_create_table_collation()
1538      {
1539          return '';
1540      }
1541  
1542      /**
1543       * Time how long it takes for a particular piece of code to run. Place calls above & below the block of code.
1544       *
1545       * @deprecated
1546       */
1547  	function get_execution_time()
1548      {
1549          return get_execution_time();
1550      }
1551  
1552      /**
1553       * Binary database fields require special attention.
1554       *
1555       * @param string $string Binary value
1556       * @return string Encoded binary value
1557       */
1558  	function escape_binary($string)
1559      {
1560          return "X'".$this->escape_string(bin2hex($string))."'";
1561      }
1562  
1563      /**
1564       * Unescape binary data.
1565       *
1566       * @param string $string Binary value
1567       * @return string Encoded binary value
1568       */
1569  	function unescape_binary($string)
1570      {
1571          // Nothing to do
1572          return $string;
1573      }
1574  }
1575  


2005 - 2021 © MyBB.de | Alle Rechte vorbehalten! | Sponsor: netcup Cross-referenced by PHPXref