MySqlSchemaManager.php 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. <?php
  2. /*
  3. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  4. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  5. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  6. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  7. * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  8. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  9. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  10. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  11. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  12. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  13. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  14. *
  15. * This software consists of voluntary contributions made by many individuals
  16. * and is licensed under the MIT license. For more information, see
  17. * <http://www.doctrine-project.org>.
  18. */
  19. namespace Doctrine\DBAL\Schema;
  20. /**
  21. * Schema manager for the MySql RDBMS.
  22. *
  23. * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
  24. * @author Konsta Vesterinen <kvesteri@cc.hut.fi>
  25. * @author Lukas Smith <smith@pooteeweet.org> (PEAR MDB2 library)
  26. * @author Roman Borschel <roman@code-factory.org>
  27. * @author Benjamin Eberlei <kontakt@beberlei.de>
  28. * @version $Revision$
  29. * @since 2.0
  30. */
  31. class MySqlSchemaManager extends AbstractSchemaManager
  32. {
  33. protected function _getPortableViewDefinition($view)
  34. {
  35. return new View($view['TABLE_NAME'], $view['VIEW_DEFINITION']);
  36. }
  37. protected function _getPortableTableDefinition($table)
  38. {
  39. return array_shift($table);
  40. }
  41. protected function _getPortableUserDefinition($user)
  42. {
  43. return array(
  44. 'user' => $user['User'],
  45. 'password' => $user['Password'],
  46. );
  47. }
  48. protected function _getPortableTableIndexesList($tableIndexes, $tableName=null)
  49. {
  50. foreach($tableIndexes as $k => $v) {
  51. $v = array_change_key_case($v, CASE_LOWER);
  52. if($v['key_name'] == 'PRIMARY') {
  53. $v['primary'] = true;
  54. } else {
  55. $v['primary'] = false;
  56. }
  57. if (strpos($v['index_type'], 'FULLTEXT') !== false) {
  58. $v['flags'] = array('FULLTEXT');
  59. }
  60. $tableIndexes[$k] = $v;
  61. }
  62. return parent::_getPortableTableIndexesList($tableIndexes, $tableName);
  63. }
  64. protected function _getPortableSequenceDefinition($sequence)
  65. {
  66. return end($sequence);
  67. }
  68. protected function _getPortableDatabaseDefinition($database)
  69. {
  70. return $database['Database'];
  71. }
  72. /**
  73. * Gets a portable column definition.
  74. *
  75. * The database type is mapped to a corresponding Doctrine mapping type.
  76. *
  77. * @param $tableColumn
  78. * @return array
  79. */
  80. protected function _getPortableTableColumnDefinition($tableColumn)
  81. {
  82. $tableColumn = array_change_key_case($tableColumn, CASE_LOWER);
  83. $dbType = strtolower($tableColumn['type']);
  84. $dbType = strtok($dbType, '(), ');
  85. if (isset($tableColumn['length'])) {
  86. $length = $tableColumn['length'];
  87. $decimal = '';
  88. } else {
  89. $length = strtok('(), ');
  90. $decimal = strtok('(), ') ? strtok('(), '):null;
  91. }
  92. $type = array();
  93. $fixed = null;
  94. if ( ! isset($tableColumn['name'])) {
  95. $tableColumn['name'] = '';
  96. }
  97. $scale = null;
  98. $precision = null;
  99. $type = $this->_platform->getDoctrineTypeMapping($dbType);
  100. $type = $this->extractDoctrineTypeFromComment($tableColumn['comment'], $type);
  101. $tableColumn['comment'] = $this->removeDoctrineTypeFromComment($tableColumn['comment'], $type);
  102. switch ($dbType) {
  103. case 'char':
  104. $fixed = true;
  105. break;
  106. case 'float':
  107. case 'double':
  108. case 'real':
  109. case 'numeric':
  110. case 'decimal':
  111. if(preg_match('([A-Za-z]+\(([0-9]+)\,([0-9]+)\))', $tableColumn['type'], $match)) {
  112. $precision = $match[1];
  113. $scale = $match[2];
  114. $length = null;
  115. }
  116. break;
  117. case 'tinyint':
  118. case 'smallint':
  119. case 'mediumint':
  120. case 'int':
  121. case 'integer':
  122. case 'bigint':
  123. case 'tinyblob':
  124. case 'mediumblob':
  125. case 'longblob':
  126. case 'blob':
  127. case 'year':
  128. $length = null;
  129. break;
  130. }
  131. $length = ((int) $length == 0) ? null : (int) $length;
  132. $options = array(
  133. 'length' => $length,
  134. 'unsigned' => (bool) (strpos($tableColumn['type'], 'unsigned') !== false),
  135. 'fixed' => (bool) $fixed,
  136. 'default' => isset($tableColumn['default']) ? $tableColumn['default'] : null,
  137. 'notnull' => (bool) ($tableColumn['null'] != 'YES'),
  138. 'scale' => null,
  139. 'precision' => null,
  140. 'autoincrement' => (bool) (strpos($tableColumn['extra'], 'auto_increment') !== false),
  141. 'comment' => (isset($tableColumn['comment'])) ? $tableColumn['comment'] : null
  142. );
  143. if ($scale !== null && $precision !== null) {
  144. $options['scale'] = $scale;
  145. $options['precision'] = $precision;
  146. }
  147. return new Column($tableColumn['field'], \Doctrine\DBAL\Types\Type::getType($type), $options);
  148. }
  149. protected function _getPortableTableForeignKeysList($tableForeignKeys)
  150. {
  151. $list = array();
  152. foreach ($tableForeignKeys as $key => $value) {
  153. $value = array_change_key_case($value, CASE_LOWER);
  154. if (!isset($list[$value['constraint_name']])) {
  155. if (!isset($value['delete_rule']) || $value['delete_rule'] == "RESTRICT") {
  156. $value['delete_rule'] = null;
  157. }
  158. if (!isset($value['update_rule']) || $value['update_rule'] == "RESTRICT") {
  159. $value['update_rule'] = null;
  160. }
  161. $list[$value['constraint_name']] = array(
  162. 'name' => $value['constraint_name'],
  163. 'local' => array(),
  164. 'foreign' => array(),
  165. 'foreignTable' => $value['referenced_table_name'],
  166. 'onDelete' => $value['delete_rule'],
  167. 'onUpdate' => $value['update_rule'],
  168. );
  169. }
  170. $list[$value['constraint_name']]['local'][] = $value['column_name'];
  171. $list[$value['constraint_name']]['foreign'][] = $value['referenced_column_name'];
  172. }
  173. $result = array();
  174. foreach($list as $constraint) {
  175. $result[] = new ForeignKeyConstraint(
  176. array_values($constraint['local']), $constraint['foreignTable'],
  177. array_values($constraint['foreign']), $constraint['name'],
  178. array(
  179. 'onDelete' => $constraint['onDelete'],
  180. 'onUpdate' => $constraint['onUpdate'],
  181. )
  182. );
  183. }
  184. return $result;
  185. }
  186. }