/libraries/cms/schema/changeitemsqlsrv.php

https://bitbucket.org/dreamriks/giftjaipur · PHP · 150 lines · 77 code · 10 blank · 63 comment · 16 complexity · 5af9f4dcc83a4b63dec5464a28e5180f MD5 · raw file

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