[ Index ]

PHP Cross Reference of Joomla 2.5.4 DE

title

Body

[close]

/libraries/cms/schema/ -> changeitemmysql.php (source)

   1  <?php
   2  /**
   3   * @package     CMS.Library
   4   * @subpackage  Schema
   5   *
   6   * @copyright   Copyright (C) 2005 - 2012 Open Source Matters, Inc. All rights reserved.
   7   * @license     GNU General Public License version 2 or later; see LICENSE
   8   */
   9  
  10  defined('_JEXEC') or die;
  11  
  12  /**
  13   * Checks the database schema against one MySQL DDL query to see if it has been run.
  14   *
  15   * @package     CMS.Library
  16   * @subpackage  Schema
  17   * @since       2.5
  18   */
  19  class JSchemaChangeitemmysql extends JSchemaChangeitem
  20  {
  21      /**
  22       *
  23       * Checks a DDL query to see if it is a known type
  24       * If yes, build a check query to see if the DDL has been run on the database.
  25       * If successful, the $msgElements, $queryType, $checkStatus and $checkQuery fields are populated.
  26       * The $msgElements contains the text to create the user message.
  27       * The $checkQuery contains the SQL query to check whether the schema change has
  28       * been run against the current database. The $queryType contains the type of
  29       * DDL query that was run (for example, CREATE_TABLE, ADD_COLUMN, CHANGE_COLUMN_TYPE, ADD_INDEX).
  30       * The $checkStatus field is set to zero if the query is created
  31       *
  32       * If not successful, $checkQuery is empty and , and $checkStatus is -1.
  33       * For example, this will happen if the current line is a non-DDL statement.
  34       *
  35       * @return void
  36       *
  37       * @since  2.5
  38       */
  39  	protected function buildCheckQuery()
  40      {
  41          // Initialize fields in case we can't create a check query
  42          $this->checkStatus = -1; // change status to skipped
  43          $result = null;
  44  
  45          // remove any newlines
  46          $this->updateQuery = str_replace("\n", '', $this->updateQuery);
  47  
  48          // fix up extra spaces around () and in general
  49          $find = array('#((\s*)\(\s*([^)\s]+)\s*)(\))#', '#(\s)(\s*)#');
  50          $replace = array('($3)', '$1');
  51          $updateQuery = preg_replace($find, $replace, $this->updateQuery);
  52          $wordArray = explode(' ', $updateQuery);
  53  
  54          // first, make sure we have an array of at least 6 elements
  55          // if not, we can't make a check query for this one
  56          if (count($wordArray) < 6) {
  57              return; // done with method
  58          }
  59  
  60          // we can only make check queries for alter table and create table queries
  61          $command = strtoupper($wordArray[0] . ' ' . $wordArray[1]);
  62          if ($command === 'ALTER TABLE') {
  63              $alterCommand = strtoupper($wordArray[3] . ' ' . $wordArray[4]);
  64              if ($alterCommand == 'ADD COLUMN') {
  65                  $result = 'SHOW COLUMNS IN ' . $wordArray[2] .
  66                      ' WHERE field = ' . $this->fixQuote($wordArray[5]);
  67                  $this->queryType = 'ADD_COLUMN';
  68                  $this->msgElements = array($this->fixQuote($wordArray[2]), $this->fixQuote($wordArray[5]));
  69              }
  70              elseif ($alterCommand == 'ADD INDEX' || $alterCommand == 'ADD UNIQUE') {
  71                  if ($pos = strpos($wordArray[5], '(')) {
  72                      $index = $this->fixQuote(substr($wordArray[5], 0, $pos));
  73                  } else {
  74                      $index = $this->fixQuote($wordArray[5]);
  75                  }
  76                  $result = 'SHOW INDEXES IN ' . $wordArray[2] . ' WHERE Key_name = ' . $index;
  77                  $this->queryType = 'ADD_INDEX';
  78                  $this->msgElements = array($this->fixQuote($wordArray[2]), $index);
  79              }
  80              elseif ($alterCommand == 'DROP INDEX') {
  81                  $index = $this->fixQuote($wordArray[5]);
  82                  $result = 'SHOW INDEXES IN ' . $wordArray[2] . ' WHERE Key_name = ' . $index;
  83                  $this->queryType = 'DROP_INDEX';
  84                  $this->checkQueryExpected = 0;
  85                  $this->msgElements = array($this->fixQuote($wordArray[2]), $index);
  86              }
  87              elseif (strtoupper($wordArray[3]) == 'MODIFY') {
  88                  // Kludge to fix problem with "integer unsigned"
  89                  $type = $this->fixQuote($wordArray[5]);
  90                  if (isset($wordArray[6])) {
  91                      $type = $this->fixQuote($this->fixInteger($wordArray[5], $wordArray[6]));
  92                  }
  93                  $result = 'SHOW COLUMNS IN ' . $wordArray[2] . ' WHERE field = '
  94                      . $this->fixQuote($wordArray[4]) . ' AND type = ' . $type;
  95                  $this->queryType = 'CHANGE_COLUMN_TYPE';
  96                  $this->msgElements = array($this->fixQuote($wordArray[2]), $this->fixQuote($wordArray[4]), $type);
  97              }
  98              elseif (strtoupper($wordArray[3]) == 'CHANGE') {
  99                  // Kludge to fix problem with "integer unsigned"
 100                  $type = $this->fixQuote($this->fixInteger($wordArray[6], $wordArray[7]));
 101                  $result = 'SHOW COLUMNS IN ' . $wordArray[2] . ' WHERE field = ' .
 102                  $this->fixQuote($wordArray[4]) . ' AND type = ' . $type;
 103                  $this->queryType = 'CHANGE_COLUMN_TYPE';
 104                  $this->msgElements = array($this->fixQuote($wordArray[2]), $this->fixQuote($wordArray[4]), $type);
 105              }
 106          }
 107  
 108          if ($command == 'CREATE TABLE') {
 109              if (strtoupper($wordArray[2].$wordArray[3].$wordArray[4]) == 'IFNOTEXISTS') {
 110                  $table = $wordArray[5];
 111              }
 112              else {
 113                  $table = $wordArray[2];
 114              }
 115              $result = 'SHOW TABLES LIKE ' . $this->fixQuote($table);
 116              $this->queryType = 'CREATE_TABLE';
 117              $this->msgElements = array($this->fixQuote($table));
 118          }
 119  
 120          // set fields based on results
 121          if ($this->checkQuery = $result) {
 122              $this->checkStatus = 0; // unchecked status
 123          }
 124          else {
 125              $this->checkStatus = -1; // skipped
 126          }
 127      }
 128  
 129      /**
 130       * Fix up integer. Fixes problem with MySQL integer descriptions.
 131       * If you change a column to "integer unsigned" it shows
 132       * as "int(10) unsigned" in the check query.
 133       *
 134       * @param  string  $type1  the column type
 135       * @param  string  $type2  the column attributes
 136       *
 137       * @return string  The original or changed column type.
 138       *
 139       * @since  2.5
 140       */
 141  	private function fixInteger($type1, $type2)
 142      {
 143          $result = $type1;
 144          if (strtolower($type1) == "integer" && strtolower(substr($type2, 0, 8)) == 'unsigned') {
 145              $result = 'int(10) unsigned';
 146          }
 147          return $result;
 148      }
 149  
 150      /**
 151       *
 152       * Fixes up a string for inclusion in a query.
 153       * Replaces name quote character with normal quote for literal.
 154       * Drops trailing semi-colon. Injects the database prefix.
 155       *
 156       * @param   string  $string  The input string to be cleaned up.
 157       * @return  string  The modified string.
 158       *
 159       * @since   2.5
 160       */
 161  	private function fixQuote($string)
 162      {
 163          $string = str_replace('`', '', $string);
 164          $string = str_replace(';', '', $string);
 165          $string = str_replace('#__', $this->db->getPrefix(), $string);
 166          return $this->db->quote($string);
 167      }
 168  
 169  }


Generated: Tue Apr 3 11:40:28 2012 Cross-referenced by PHPXref 0.7.1