db_datadict.php 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. <?php
  2. /* vim: set expandtab sw=4 ts=4 sts=4: */
  3. /**
  4. * Renders data dictionary
  5. *
  6. * @package PhpMyAdmin
  7. */
  8. /**
  9. * Gets the variables sent or posted to this script, then displays headers
  10. */
  11. require_once 'libraries/common.inc.php';
  12. if (! isset($selected_tbl)) {
  13. include 'libraries/db_common.inc.php';
  14. include 'libraries/db_info.inc.php';
  15. }
  16. $response = PMA_Response::getInstance();
  17. $header = $response->getHeader();
  18. $header->enablePrintView();
  19. /**
  20. * Gets the relations settings
  21. */
  22. $cfgRelation = PMA_getRelationsParam();
  23. require_once 'libraries/transformations.lib.php';
  24. require_once 'libraries/Index.class.php';
  25. /**
  26. * Check parameters
  27. */
  28. PMA_Util::checkParameters(array('db'));
  29. /**
  30. * Defines the url to return to in case of error in a sql statement
  31. */
  32. if (strlen($table)) {
  33. $err_url = 'tbl_sql.php?' . PMA_URL_getCommon($db, $table);
  34. } else {
  35. $err_url = 'db_sql.php?' . PMA_URL_getCommon($db);
  36. }
  37. if ($cfgRelation['commwork']) {
  38. $comment = PMA_getDbComment($db);
  39. /**
  40. * Displays DB comment
  41. */
  42. if ($comment) {
  43. echo '<p>' . __('Database comment:')
  44. . ' <i>' . htmlspecialchars($comment) . '</i></p>';
  45. } // end if
  46. }
  47. /**
  48. * Selects the database and gets tables names
  49. */
  50. $GLOBALS['dbi']->selectDb($db);
  51. $tables = $GLOBALS['dbi']->getTables($db);
  52. $count = 0;
  53. foreach ($tables as $table) {
  54. $comments = PMA_getComments($db, $table);
  55. echo '<div>' . "\n";
  56. echo '<h2>' . htmlspecialchars($table) . '</h2>' . "\n";
  57. /**
  58. * Gets table informations
  59. */
  60. $show_comment = PMA_Table::sGetStatusInfo($db, $table, 'TABLE_COMMENT');
  61. /**
  62. * Gets table keys and retains them
  63. */
  64. $GLOBALS['dbi']->selectDb($db);
  65. $indexes = $GLOBALS['dbi']->getTableIndexes($db, $table);
  66. $primary = '';
  67. $indexes = array();
  68. $lastIndex = '';
  69. $indexes_info = array();
  70. $indexes_data = array();
  71. $pk_array = array(); // will be use to emphasis prim. keys in the table
  72. // view
  73. foreach ($indexes as $row) {
  74. // Backups the list of primary keys
  75. if ($row['Key_name'] == 'PRIMARY') {
  76. $primary .= $row['Column_name'] . ', ';
  77. $pk_array[$row['Column_name']] = 1;
  78. }
  79. // Retains keys informations
  80. if ($row['Key_name'] != $lastIndex) {
  81. $indexes[] = $row['Key_name'];
  82. $lastIndex = $row['Key_name'];
  83. }
  84. $indexes_info[$row['Key_name']]['Sequences'][] = $row['Seq_in_index'];
  85. $indexes_info[$row['Key_name']]['Non_unique'] = $row['Non_unique'];
  86. if (isset($row['Cardinality'])) {
  87. $indexes_info[$row['Key_name']]['Cardinality'] = $row['Cardinality'];
  88. }
  89. // I don't know what does following column mean....
  90. // $indexes_info[$row['Key_name']]['Packed'] = $row['Packed'];
  91. $indexes_info[$row['Key_name']]['Comment'] = $row['Comment'];
  92. $indexes_data[$row['Key_name']][$row['Seq_in_index']]['Column_name']
  93. = $row['Column_name'];
  94. if (isset($row['Sub_part'])) {
  95. $indexes_data[$row['Key_name']][$row['Seq_in_index']]['Sub_part']
  96. = $row['Sub_part'];
  97. }
  98. } // end while
  99. /**
  100. * Gets columns properties
  101. */
  102. $columns = $GLOBALS['dbi']->getColumns($db, $table);
  103. if (PMA_MYSQL_INT_VERSION < 50025) {
  104. // We need this to correctly learn if a TIMESTAMP is NOT NULL, since
  105. // SHOW FULL COLUMNS or INFORMATION_SCHEMA incorrectly says NULL
  106. // and SHOW CREATE TABLE says NOT NULL
  107. // http://bugs.mysql.com/20910.
  108. $show_create_table_query = 'SHOW CREATE TABLE '
  109. . PMA_Util::backquote($db) . '.'
  110. . PMA_Util::backquote($table);
  111. $show_create_table = $GLOBALS['dbi']->fetchValue(
  112. $show_create_table_query, 0, 1
  113. );
  114. $analyzed_sql = PMA_SQP_analyze(PMA_SQP_parse($show_create_table));
  115. }
  116. // Check if we can use Relations
  117. if (!empty($cfgRelation['relation'])) {
  118. // Find which tables are related with the current one and write it in
  119. // an array
  120. $res_rel = PMA_getForeigners($db, $table);
  121. if (count($res_rel) > 0) {
  122. $have_rel = true;
  123. } else {
  124. $have_rel = false;
  125. }
  126. } else {
  127. $have_rel = false;
  128. } // end if
  129. /**
  130. * Displays the comments of the table if MySQL >= 3.23
  131. */
  132. if (!empty($show_comment)) {
  133. echo __('Table comments:') . ' ';
  134. echo htmlspecialchars($show_comment) . '<br /><br />';
  135. }
  136. /**
  137. * Displays the table structure
  138. */
  139. echo '<table width="100%" class="print">';
  140. echo '<tr><th width="50">' . __('Column') . '</th>';
  141. echo '<th width="80">' . __('Type') . '</th>';
  142. echo '<th width="40">' . __('Null') . '</th>';
  143. echo '<th width="70">' . __('Default') . '</th>';
  144. if ($have_rel) {
  145. echo ' <th>' . __('Links to') . '</th>' . "\n";
  146. }
  147. echo ' <th>' . __('Comments') . '</th>' . "\n";
  148. if ($cfgRelation['mimework']) {
  149. echo ' <th>MIME</th>' . "\n";
  150. }
  151. echo '</tr>';
  152. $odd_row = true;
  153. foreach ($columns as $row) {
  154. if ($row['Null'] == '') {
  155. $row['Null'] = 'NO';
  156. }
  157. $extracted_columnspec
  158. = PMA_Util::extractColumnSpec($row['Type']);
  159. // reformat mysql query output
  160. // set or enum types: slashes single quotes inside options
  161. if ('set' == $extracted_columnspec['type']
  162. || 'enum' == $extracted_columnspec['type']
  163. ) {
  164. $type_nowrap = '';
  165. } else {
  166. $type_nowrap = ' class="nowrap"';
  167. }
  168. $type = htmlspecialchars($extracted_columnspec['print_type']);
  169. $attribute = $extracted_columnspec['attribute'];
  170. if (! isset($row['Default'])) {
  171. if ($row['Null'] != 'NO') {
  172. $row['Default'] = '<i>NULL</i>';
  173. }
  174. } else {
  175. $row['Default'] = htmlspecialchars($row['Default']);
  176. }
  177. $column_name = $row['Field'];
  178. $tmp_column = $analyzed_sql[0]['create_table_fields'][$column_name];
  179. if (PMA_MYSQL_INT_VERSION < 50025
  180. && ! empty($tmp_column['type'])
  181. && $tmp_column['type'] == 'TIMESTAMP'
  182. && $tmp_column['timestamp_not_null']
  183. ) {
  184. // here, we have a TIMESTAMP that SHOW FULL COLUMNS reports as
  185. // having the NULL attribute, but SHOW CREATE TABLE says the
  186. // contrary. Believe the latter.
  187. /**
  188. * @todo merge this logic with the one in tbl_structure.php
  189. * or move it in a function similar to $GLOBALS['dbi']->getColumnsFull()
  190. * but based on SHOW CREATE TABLE because information_schema
  191. * cannot be trusted in this case (MySQL bug)
  192. */
  193. $row['Null'] = 'NO';
  194. }
  195. echo '<tr class="';
  196. echo $odd_row ? 'odd' : 'even'; $odd_row = ! $odd_row;
  197. echo '">';
  198. echo '<td class="nowrap">';
  199. if (isset($pk_array[$row['Field']])) {
  200. echo '<u>' . htmlspecialchars($column_name) . '</u>';
  201. } else {
  202. echo htmlspecialchars($column_name);
  203. }
  204. echo '</td>';
  205. echo '<td' . $type_nowrap . ' lang="en" dir="ltr">' . $type . '</td>';
  206. echo '<td>';
  207. echo (($row['Null'] == 'NO') ? __('No') : __('Yes'));
  208. echo '</td>';
  209. echo '<td class="nowrap">';
  210. if (isset($row['Default'])) {
  211. echo $row['Default'];
  212. }
  213. echo '</td>';
  214. if ($have_rel) {
  215. echo ' <td>';
  216. if (isset($res_rel[$column_name])) {
  217. echo htmlspecialchars(
  218. $res_rel[$column_name]['foreign_table']
  219. . ' -> '
  220. . $res_rel[$column_name]['foreign_field']
  221. );
  222. }
  223. echo '</td>' . "\n";
  224. }
  225. echo ' <td>';
  226. if (isset($comments[$column_name])) {
  227. echo htmlspecialchars($comments[$column_name]);
  228. }
  229. echo '</td>' . "\n";
  230. if ($cfgRelation['mimework']) {
  231. $mime_map = PMA_getMIME($db, $table, true);
  232. echo ' <td>';
  233. if (isset($mime_map[$column_name])) {
  234. echo htmlspecialchars(
  235. str_replace('_', '/', $mime_map[$column_name]['mimetype'])
  236. );
  237. }
  238. echo '</td>' . "\n";
  239. }
  240. echo '</tr>';
  241. } // end foreach
  242. $count++;
  243. echo '</table>';
  244. // display indexes information
  245. if (count(PMA_Index::getFromTable($table, $db)) > 0) {
  246. echo PMA_Index::getView($table, $db, true);
  247. }
  248. echo '</div>';
  249. } //ends main while
  250. /**
  251. * Displays the footer
  252. */
  253. echo PMA_Util::getButton();
  254. ?>