DB2SchemaManager.php 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  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. * IBM Db2 Schema Manager.
  22. *
  23. * @link www.doctrine-project.org
  24. * @since 1.0
  25. * @author Benjamin Eberlei <kontakt@beberlei.de>
  26. */
  27. class DB2SchemaManager extends AbstractSchemaManager
  28. {
  29. /**
  30. * {@inheritdoc}
  31. *
  32. * Apparently creator is the schema not the user who created it:
  33. * {@link http://publib.boulder.ibm.com/infocenter/dzichelp/v2r2/index.jsp?topic=/com.ibm.db29.doc.sqlref/db2z_sysibmsystablestable.htm}
  34. */
  35. public function listTableNames()
  36. {
  37. $sql = $this->_platform->getListTablesSQL();
  38. $sql .= " AND CREATOR = UPPER('".$this->_conn->getUsername()."')";
  39. $tables = $this->_conn->fetchAll($sql);
  40. return $this->_getPortableTablesList($tables);
  41. }
  42. /**
  43. * {@inheritdoc}
  44. */
  45. protected function _getPortableTableColumnDefinition($tableColumn)
  46. {
  47. $tableColumn = array_change_key_case($tableColumn, \CASE_LOWER);
  48. $length = null;
  49. $fixed = null;
  50. $unsigned = false;
  51. $scale = false;
  52. $precision = false;
  53. $default = null;
  54. if (null !== $tableColumn['default'] && 'NULL' != $tableColumn['default']) {
  55. $default = trim($tableColumn['default'], "'");
  56. }
  57. $type = $this->_platform->getDoctrineTypeMapping($tableColumn['typename']);
  58. if (isset($tableColumn['comment'])) {
  59. $type = $this->extractDoctrineTypeFromComment($tableColumn['comment'], $type);
  60. $tableColumn['comment'] = $this->removeDoctrineTypeFromComment($tableColumn['comment'], $type);
  61. }
  62. switch (strtolower($tableColumn['typename'])) {
  63. case 'varchar':
  64. $length = $tableColumn['length'];
  65. $fixed = false;
  66. break;
  67. case 'character':
  68. $length = $tableColumn['length'];
  69. $fixed = true;
  70. break;
  71. case 'clob':
  72. $length = $tableColumn['length'];
  73. break;
  74. case 'decimal':
  75. case 'double':
  76. case 'real':
  77. $scale = $tableColumn['scale'];
  78. $precision = $tableColumn['length'];
  79. break;
  80. }
  81. $options = array(
  82. 'length' => $length,
  83. 'unsigned' => (bool) $unsigned,
  84. 'fixed' => (bool) $fixed,
  85. 'default' => $default,
  86. 'autoincrement' => (boolean) $tableColumn['autoincrement'],
  87. 'notnull' => (bool) ($tableColumn['nulls'] == 'N'),
  88. 'scale' => null,
  89. 'precision' => null,
  90. 'comment' => isset($tableColumn['comment']) && $tableColumn['comment'] !== ''
  91. ? $tableColumn['comment']
  92. : null,
  93. 'platformOptions' => array(),
  94. );
  95. if ($scale !== null && $precision !== null) {
  96. $options['scale'] = $scale;
  97. $options['precision'] = $precision;
  98. }
  99. return new Column($tableColumn['colname'], \Doctrine\DBAL\Types\Type::getType($type), $options);
  100. }
  101. /**
  102. * {@inheritdoc}
  103. */
  104. protected function _getPortableTablesList($tables)
  105. {
  106. $tableNames = array();
  107. foreach ($tables as $tableRow) {
  108. $tableRow = array_change_key_case($tableRow, \CASE_LOWER);
  109. $tableNames[] = $tableRow['name'];
  110. }
  111. return $tableNames;
  112. }
  113. /**
  114. * {@inheritdoc}
  115. */
  116. protected function _getPortableTableIndexesList($tableIndexRows, $tableName = null)
  117. {
  118. foreach ($tableIndexRows as &$tableIndexRow) {
  119. $tableIndexRow = array_change_key_case($tableIndexRow, \CASE_LOWER);
  120. $tableIndexRow['primary'] = (boolean) $tableIndexRow['primary'];
  121. }
  122. return parent::_getPortableTableIndexesList($tableIndexRows, $tableName);
  123. }
  124. /**
  125. * {@inheritdoc}
  126. */
  127. protected function _getPortableTableForeignKeyDefinition($tableForeignKey)
  128. {
  129. return new ForeignKeyConstraint(
  130. $tableForeignKey['local_columns'],
  131. $tableForeignKey['foreign_table'],
  132. $tableForeignKey['foreign_columns'],
  133. $tableForeignKey['name'],
  134. $tableForeignKey['options']
  135. );
  136. }
  137. /**
  138. * {@inheritdoc}
  139. */
  140. protected function _getPortableTableForeignKeysList($tableForeignKeys)
  141. {
  142. $foreignKeys = array();
  143. foreach ($tableForeignKeys as $tableForeignKey) {
  144. $tableForeignKey = array_change_key_case($tableForeignKey, \CASE_LOWER);
  145. if (!isset($foreignKeys[$tableForeignKey['index_name']])) {
  146. $foreignKeys[$tableForeignKey['index_name']] = array(
  147. 'local_columns' => array($tableForeignKey['local_column']),
  148. 'foreign_table' => $tableForeignKey['foreign_table'],
  149. 'foreign_columns' => array($tableForeignKey['foreign_column']),
  150. 'name' => $tableForeignKey['index_name'],
  151. 'options' => array(
  152. 'onUpdate' => $tableForeignKey['on_update'],
  153. 'onDelete' => $tableForeignKey['on_delete'],
  154. )
  155. );
  156. } else {
  157. $foreignKeys[$tableForeignKey['index_name']]['local_columns'][] = $tableForeignKey['local_column'];
  158. $foreignKeys[$tableForeignKey['index_name']]['foreign_columns'][] = $tableForeignKey['foreign_column'];
  159. }
  160. }
  161. return parent::_getPortableTableForeignKeysList($foreignKeys);
  162. }
  163. /**
  164. * {@inheritdoc}
  165. */
  166. protected function _getPortableForeignKeyRuleDef($def)
  167. {
  168. if ($def == "C") {
  169. return "CASCADE";
  170. } elseif ($def == "N") {
  171. return "SET NULL";
  172. }
  173. return null;
  174. }
  175. /**
  176. * {@inheritdoc}
  177. */
  178. protected function _getPortableViewDefinition($view)
  179. {
  180. $view = array_change_key_case($view, \CASE_LOWER);
  181. // sadly this still segfaults on PDO_IBM, see http://pecl.php.net/bugs/bug.php?id=17199
  182. //$view['text'] = (is_resource($view['text']) ? stream_get_contents($view['text']) : $view['text']);
  183. if (!is_resource($view['text'])) {
  184. $pos = strpos($view['text'], ' AS ');
  185. $sql = substr($view['text'], $pos+4);
  186. } else {
  187. $sql = '';
  188. }
  189. return new View($view['name'], $sql);
  190. }
  191. }