PageRenderTime 52ms CodeModel.GetById 25ms RepoModel.GetById 1ms app.codeStats 0ms

/lib/ezc/DatabaseSchema/src/handlers/mysql/reader.php

https://bitbucket.org/crevillo/enetcall
PHP | 279 lines | 163 code | 33 blank | 83 comment | 33 complexity | ccfc55a858f61f89963fc874572ccc26 MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause, LGPL-2.1
  1. <?php
  2. /**
  3. * File containing the ezcDbSchemaMysqlReader class.
  4. *
  5. * @package DatabaseSchema
  6. * @version //autogentag//
  7. * @copyright Copyright (C) 2005-2010 eZ Systems AS. All rights reserved.
  8. * @license http://ez.no/licenses/new_bsd New BSD License
  9. */
  10. /**
  11. * Handler for files containing PHP arrays that represent DB schema.
  12. *
  13. * @package DatabaseSchema
  14. * @version //autogentag//
  15. */
  16. class ezcDbSchemaMysqlReader extends ezcDbSchemaCommonSqlReader implements ezcDbSchemaDbReader
  17. {
  18. /**
  19. * Contains a type map from MySQL native types to generic DbSchema types.
  20. *
  21. * @var array
  22. */
  23. static private $typeMap = array(
  24. 'bit' => 'integer',
  25. 'tinyint' => 'integer',
  26. 'smallint' => 'integer',
  27. 'mediumint' => 'integer',
  28. 'int' => 'integer',
  29. 'bigint' => 'integer',
  30. 'integer' => 'integer',
  31. 'bool' => 'boolean',
  32. 'boolean' => 'boolean',
  33. 'float' => 'float',
  34. 'double' => 'float',
  35. 'dec' => 'decimal',
  36. 'decimal' => 'decimal',
  37. 'numeric' => 'decimal',
  38. 'fixed' => 'decimal',
  39. 'date' => 'date',
  40. 'datetime' => 'timestamp',
  41. 'timestamp' => 'timestamp',
  42. 'time' => 'time',
  43. 'year' => 'integer',
  44. 'char' => 'text',
  45. 'varchar' => 'text',
  46. 'binary' => 'blob',
  47. 'varbinary' => 'blob',
  48. 'tinyblob' => 'blob',
  49. 'blob' => 'blob',
  50. 'mediumblob' => 'blob',
  51. 'longblob' => 'blob',
  52. 'tinytext' => 'clob',
  53. 'text' => 'clob',
  54. 'mediumtext' => 'clob',
  55. 'longtext' => 'clob',
  56. );
  57. /**
  58. * Loops over all the tables in the database and extracts schema information.
  59. *
  60. * This method extracts information about a database's schema from the
  61. * database itself and returns this schema as an ezcDbSchema object.
  62. *
  63. * @return ezcDbSchema
  64. */
  65. protected function fetchSchema()
  66. {
  67. $tables = $this->db->query( "SHOW TABLES" )->fetchAll();
  68. return $this->processSchema( $tables );
  69. }
  70. /**
  71. * Fetch fields definition for the table $tableName
  72. *
  73. * This method loops over all the fields in the table $tableName and
  74. * returns an array with the field specification. The key in the returned
  75. * array is the name of the field.
  76. *
  77. * @param string $tableName
  78. * @return array(string=>ezcDbSchemaField)
  79. */
  80. protected function fetchTableFields( $tableName )
  81. {
  82. $fields = array();
  83. $resultArray = $this->db->query( "DESCRIBE `$tableName`" );
  84. $resultArray->setFetchMode( PDO::FETCH_ASSOC );
  85. foreach ( $resultArray as $row )
  86. {
  87. $fieldLength = false;
  88. // bool and boolean is synonyms for TINYINT(1) in MySQL
  89. if ( $row['type'] == 'tinyint(1)' )
  90. {
  91. $fieldType = 'boolean';
  92. }
  93. else
  94. {
  95. $fieldType = self::convertToGenericType( $row['type'], $fieldLength, $fieldPrecision );
  96. if ( !$fieldLength )
  97. {
  98. $fieldLength = false;
  99. }
  100. }
  101. $fieldNotNull = false;
  102. if ( strlen( $row['null'] ) == 0 || $row['null'][0] != 'Y' || $fieldType == 'timestamp' )
  103. {
  104. $fieldNotNull = true;
  105. }
  106. $fieldDefault = null;
  107. if ( strlen( $row['default'] ) != 0 )
  108. {
  109. if ( $fieldType == 'boolean' )
  110. {
  111. $fieldDefault = ( $row['default'] == '0' ) ? 'false' : 'true';
  112. }
  113. else if ( $fieldType != 'timestamp' )
  114. {
  115. $fieldDefault = $row['default'];
  116. }
  117. }
  118. if ( $fieldType == 'integer' && $row['default'] !== null )
  119. {
  120. $fieldDefault = (int) $fieldDefault;
  121. }
  122. $fieldAutoIncrement = false;
  123. if ( strstr ( $row['extra'], 'auto_increment' ) !== false )
  124. {
  125. $fieldAutoIncrement = true;
  126. }
  127. // FIXME: unsigned needs to be implemented
  128. $fieldUnsigned = false;
  129. $fields[$row['field']] = ezcDbSchema::createNewField( $fieldType, $fieldLength, $fieldNotNull, $fieldDefault, $fieldAutoIncrement, $fieldUnsigned );
  130. }
  131. return $fields;
  132. }
  133. /**
  134. * Converts the native MySQL type in $typeString to a generic DbSchema type.
  135. *
  136. * This method converts a string like "float(5,10)" to the generic DbSchema
  137. * type and uses the by-reference parameters $typeLength and $typePrecision
  138. * to communicate the optional length and precision of the field's type.
  139. *
  140. * @param string $typeString
  141. * @param int &$typeLength
  142. * @param int &$typePrecision
  143. * @return string
  144. */
  145. static function convertToGenericType( $typeString, &$typeLength, &$typePrecision )
  146. {
  147. preg_match( "@([a-z]*)(\((\d*)(,(\d+))?\))?@", $typeString, $matches );
  148. if ( !isset( self::$typeMap[$matches[1]] ) )
  149. {
  150. throw new ezcDbSchemaUnsupportedTypeException( 'MySQL', $matches[1] );
  151. }
  152. $genericType = self::$typeMap[$matches[1]];
  153. if ( in_array( $genericType, array( 'text', 'decimal', 'float', 'integer' ) ) && isset( $matches[3] ) && $typeString != 'bigint(20)' )
  154. {
  155. $typeLength = $matches[3];
  156. if ( is_numeric( $typeLength ) )
  157. {
  158. $typeLength = (int) $typeLength;
  159. }
  160. }
  161. if ( in_array( $genericType, array( 'decimal', 'float' ) ) && isset( $matches[5] ) )
  162. {
  163. $typePrecision = $matches[5];
  164. }
  165. return $genericType;
  166. }
  167. /**
  168. * Returns whether the type $type is a numeric type
  169. *
  170. * @param string $type
  171. * @return bool
  172. */
  173. private function isNumericType( $type )
  174. {
  175. $types = array( 'float', 'int' );
  176. return in_array( $type, $types );
  177. }
  178. /**
  179. * Returns whether the type $type is a string type
  180. *
  181. * @param string $type
  182. * @return bool
  183. */
  184. private function isStringType( $type )
  185. {
  186. $types = array( 'tinytext', 'text', 'mediumtext', 'longtext' );
  187. return in_array( $type, $types );
  188. }
  189. /**
  190. * Returns whether the type $type is a blob type
  191. *
  192. * @param string $type
  193. * @return bool
  194. */
  195. private function isBlobType( $type )
  196. {
  197. $types = array( 'varchar', 'char' );
  198. return in_array( $type, $types );
  199. }
  200. /**
  201. * Loops over all the indexes in the table $table and extracts information.
  202. *
  203. * This method extracts information about the table $tableName's indexes
  204. * from the database and returns this schema as an array of
  205. * ezcDbSchemaIndex objects. The key in the array is the index' name.
  206. *
  207. * @param string $tableName
  208. * @return array(string=>ezcDbSchemaIndex)
  209. */
  210. protected function fetchTableIndexes( $tableName )
  211. {
  212. $indexBuffer = array();
  213. $resultArray = $this->db->query( "SHOW INDEX FROM `$tableName`" );
  214. foreach ( $resultArray as $row )
  215. {
  216. $keyName = $row['key_name'];
  217. if ( $keyName == 'PRIMARY' )
  218. {
  219. $keyName = 'primary';
  220. }
  221. $indexBuffer[$keyName]['primary'] = false;
  222. $indexBuffer[$keyName]['unique'] = true;
  223. if ( $keyName == 'primary' )
  224. {
  225. $indexBuffer[$keyName]['primary'] = true;
  226. $indexBuffer[$keyName]['unique'] = true;
  227. }
  228. else
  229. {
  230. $indexBuffer[$keyName]['unique'] = $row['non_unique'] ? false : true;
  231. }
  232. $indexBuffer[$keyName]['fields'][$row['column_name']] = ezcDbSchema::createNewIndexField();
  233. // if ( $row['sub_part'] )
  234. // {
  235. // $indexBuffer[$keyName]['options']['limitations'][$row['column_name']] = $row['sub_part'];
  236. // }
  237. }
  238. $indexes = array();
  239. foreach ( $indexBuffer as $indexName => $indexInfo )
  240. {
  241. $indexes[$indexName] = ezcDbSchema::createNewIndex( $indexInfo['fields'], $indexInfo['primary'], $indexInfo['unique'] );
  242. }
  243. return $indexes;
  244. }
  245. }
  246. ?>