PageRenderTime 53ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 1ms

/phpMyAdmin/libraries/database_interface.lib.php

https://bitbucket.org/izubizarreta/https-bitbucket.org-bityvip
PHP | 1855 lines | 1213 code | 144 blank | 498 comment | 257 complexity | 674ada24651e08eefd2f74fa936e10a4 MD5 | raw file
Possible License(s): LGPL-3.0, LGPL-2.0, JSON, GPL-2.0, BSD-3-Clause, LGPL-2.1, MIT

Large files files are truncated, but you can click here to view the full file

  1. <?php
  2. /* vim: set expandtab sw=4 ts=4 sts=4: */
  3. /**
  4. * Common Option Constants For DBI Functions
  5. *
  6. * @package PhpMyAdmin
  7. */
  8. if (! defined('PHPMYADMIN')) {
  9. exit;
  10. }
  11. /**
  12. * Force STORE_RESULT method, ignored by classic MySQL.
  13. */
  14. define('PMA_DBI_QUERY_STORE', 1);
  15. /**
  16. * Do not read whole query.
  17. */
  18. define('PMA_DBI_QUERY_UNBUFFERED', 2);
  19. /**
  20. * Get session variable.
  21. */
  22. define('PMA_DBI_GETVAR_SESSION', 1);
  23. /**
  24. * Get global variable.
  25. */
  26. define('PMA_DBI_GETVAR_GLOBAL', 2);
  27. /**
  28. * Checks whether database extension is loaded
  29. *
  30. * @param string $extension mysql extension to check
  31. *
  32. * @return bool
  33. */
  34. function PMA_DBI_checkDbExtension($extension = 'mysql')
  35. {
  36. if ($extension == 'drizzle' && function_exists('drizzle_create')) {
  37. return true;
  38. } else if (function_exists($extension . '_connect')) {
  39. return true;
  40. }
  41. return false;
  42. }
  43. /**
  44. * check for requested extension
  45. */
  46. if (! PMA_DBI_checkDbExtension($GLOBALS['cfg']['Server']['extension'])) {
  47. // if it fails try alternative extension ...
  48. // and display an error ...
  49. /**
  50. * @todo add different messages for alternative extension
  51. * and complete fail (no alternative extension too)
  52. */
  53. PMA_warnMissingExtension(
  54. $GLOBALS['cfg']['Server']['extension'],
  55. false,
  56. PMA_showDocu('faqmysql')
  57. );
  58. if ($GLOBALS['cfg']['Server']['extension'] === 'mysql') {
  59. $alternativ_extension = 'mysqli';
  60. } else {
  61. $alternativ_extension = 'mysql';
  62. }
  63. if (! PMA_DBI_checkDbExtension($alternativ_extension)) {
  64. // if alternative fails too ...
  65. PMA_warnMissingExtension(
  66. $GLOBALS['cfg']['Server']['extension'],
  67. true,
  68. PMA_showDocu('faqmysql')
  69. );
  70. }
  71. $GLOBALS['cfg']['Server']['extension'] = $alternativ_extension;
  72. unset($alternativ_extension);
  73. }
  74. /**
  75. * Including The DBI Plugin
  76. */
  77. require_once './libraries/dbi/'
  78. . $GLOBALS['cfg']['Server']['extension'] . '.dbi.lib.php';
  79. /**
  80. * runs a query
  81. *
  82. * @param string $query SQL query to execte
  83. * @param mixed $link optional database link to use
  84. * @param int $options optional query options
  85. * @param bool $cache_affected_rows whether to cache affected rows
  86. *
  87. * @return mixed
  88. */
  89. function PMA_DBI_query($query, $link = null, $options = 0, $cache_affected_rows = true)
  90. {
  91. $res = PMA_DBI_try_query($query, $link, $options, $cache_affected_rows)
  92. or PMA_mysqlDie(PMA_DBI_getError($link), $query);
  93. return $res;
  94. }
  95. /**
  96. * runs a query and returns the result
  97. *
  98. * @param string $query query to run
  99. * @param resource $link mysql link resource
  100. * @param integer $options query options
  101. * @param bool $cache_affected_rows whether to cache affected row
  102. *
  103. * @return mixed
  104. */
  105. function PMA_DBI_try_query($query, $link = null, $options = 0, $cache_affected_rows = true)
  106. {
  107. if (empty($link)) {
  108. if (isset($GLOBALS['userlink'])) {
  109. $link = $GLOBALS['userlink'];
  110. } else {
  111. return false;
  112. }
  113. }
  114. if ($GLOBALS['cfg']['DBG']['sql']) {
  115. $time = microtime(true);
  116. }
  117. $r = PMA_DBI_real_query($query, $link, $options);
  118. if ($cache_affected_rows) {
  119. $GLOBALS['cached_affected_rows'] = PMA_DBI_affected_rows($link, $get_from_cache = false);
  120. }
  121. if ($GLOBALS['cfg']['DBG']['sql']) {
  122. $time = microtime(true) - $time;
  123. $hash = md5($query);
  124. if (isset($_SESSION['debug']['queries'][$hash])) {
  125. $_SESSION['debug']['queries'][$hash]['count']++;
  126. } else {
  127. $_SESSION['debug']['queries'][$hash] = array();
  128. if ($r == false) {
  129. $_SESSION['debug']['queries'][$hash]['error'] = '<b style="color:red">'.mysqli_error($link).'</b>';
  130. }
  131. $_SESSION['debug']['queries'][$hash]['count'] = 1;
  132. $_SESSION['debug']['queries'][$hash]['query'] = $query;
  133. $_SESSION['debug']['queries'][$hash]['time'] = $time;
  134. }
  135. $trace = array();
  136. foreach (debug_backtrace() as $trace_step) {
  137. $trace[] = PMA_Error::relPath($trace_step['file']) . '#'
  138. . $trace_step['line'] . ': '
  139. . (isset($trace_step['class']) ? $trace_step['class'] : '')
  140. //. (isset($trace_step['object']) ? get_class($trace_step['object']) : '')
  141. . (isset($trace_step['type']) ? $trace_step['type'] : '')
  142. . (isset($trace_step['function']) ? $trace_step['function'] : '')
  143. . '('
  144. . (isset($trace_step['params']) ? implode(', ', $trace_step['params']) : '')
  145. . ')'
  146. ;
  147. }
  148. $_SESSION['debug']['queries'][$hash]['trace'][] = $trace;
  149. }
  150. if ($r != false && PMA_Tracker::isActive() == true ) {
  151. PMA_Tracker::handleQuery($query);
  152. }
  153. return $r;
  154. }
  155. /**
  156. * converts charset of a mysql message, usually coming from mysql_error(),
  157. * into PMA charset, usally UTF-8
  158. * uses language to charset mapping from mysql/share/errmsg.txt
  159. * and charset names to ISO charset from information_schema.CHARACTER_SETS
  160. *
  161. * @param string $message the message
  162. *
  163. * @return string $message
  164. */
  165. function PMA_DBI_convert_message($message)
  166. {
  167. // latin always last!
  168. $encodings = array(
  169. 'japanese' => 'EUC-JP', //'ujis',
  170. 'japanese-sjis' => 'Shift-JIS', //'sjis',
  171. 'korean' => 'EUC-KR', //'euckr',
  172. 'russian' => 'KOI8-R', //'koi8r',
  173. 'ukrainian' => 'KOI8-U', //'koi8u',
  174. 'greek' => 'ISO-8859-7', //'greek',
  175. 'serbian' => 'CP1250', //'cp1250',
  176. 'estonian' => 'ISO-8859-13', //'latin7',
  177. 'slovak' => 'ISO-8859-2', //'latin2',
  178. 'czech' => 'ISO-8859-2', //'latin2',
  179. 'hungarian' => 'ISO-8859-2', //'latin2',
  180. 'polish' => 'ISO-8859-2', //'latin2',
  181. 'romanian' => 'ISO-8859-2', //'latin2',
  182. 'spanish' => 'CP1252', //'latin1',
  183. 'swedish' => 'CP1252', //'latin1',
  184. 'italian' => 'CP1252', //'latin1',
  185. 'norwegian-ny' => 'CP1252', //'latin1',
  186. 'norwegian' => 'CP1252', //'latin1',
  187. 'portuguese' => 'CP1252', //'latin1',
  188. 'danish' => 'CP1252', //'latin1',
  189. 'dutch' => 'CP1252', //'latin1',
  190. 'english' => 'CP1252', //'latin1',
  191. 'french' => 'CP1252', //'latin1',
  192. 'german' => 'CP1252', //'latin1',
  193. );
  194. if ($server_language = PMA_DBI_fetch_value('SHOW VARIABLES LIKE \'language\';', 0, 1)) {
  195. $found = array();
  196. if (preg_match('&(?:\\\|\\/)([^\\\\\/]*)(?:\\\|\\/)$&i', $server_language, $found)) {
  197. $server_language = $found[1];
  198. }
  199. }
  200. if (! empty($server_language) && isset($encodings[$server_language])) {
  201. if (function_exists('iconv')) {
  202. if ((@stristr(PHP_OS, 'AIX'))
  203. && (@strcasecmp(ICONV_IMPL, 'unknown') == 0)
  204. && (@strcasecmp(ICONV_VERSION, 'unknown') == 0)
  205. ) {
  206. include_once './libraries/iconv_wrapper.lib.php';
  207. $message = PMA_aix_iconv_wrapper(
  208. $encodings[$server_language],
  209. 'utf-8' . $GLOBALS['cfg']['IconvExtraParams'],
  210. $message
  211. );
  212. } else {
  213. $message = iconv(
  214. $encodings[$server_language],
  215. 'utf-8' . $GLOBALS['cfg']['IconvExtraParams'],
  216. $message
  217. );
  218. }
  219. } elseif (function_exists('recode_string')) {
  220. $message = recode_string(
  221. $encodings[$server_language] . '..' . 'utf-8',
  222. $message
  223. );
  224. } elseif (function_exists('libiconv')) {
  225. $message = libiconv($encodings[$server_language], 'utf-8', $message);
  226. } elseif (function_exists('mb_convert_encoding')) {
  227. // do not try unsupported charsets
  228. if (! in_array($server_language, array('ukrainian', 'greek', 'serbian'))) {
  229. $message = mb_convert_encoding(
  230. $message,
  231. 'utf-8',
  232. $encodings[$server_language]
  233. );
  234. }
  235. }
  236. } else {
  237. /**
  238. * @todo lang not found, try all, what TODO ?
  239. */
  240. }
  241. return $message;
  242. }
  243. /**
  244. * returns array with table names for given db
  245. *
  246. * @param string $database name of database
  247. * @param mixed $link mysql link resource|object
  248. *
  249. * @return array tables names
  250. */
  251. function PMA_DBI_get_tables($database, $link = null)
  252. {
  253. return PMA_DBI_fetch_result(
  254. 'SHOW TABLES FROM ' . PMA_backquote($database) . ';',
  255. null,
  256. 0,
  257. $link,
  258. PMA_DBI_QUERY_STORE
  259. );
  260. }
  261. /**
  262. * usort comparison callback
  263. *
  264. * @param string $a first argument to sort
  265. * @param string $b second argument to sort
  266. *
  267. * @return integer a value representing whether $a should be before $b in the
  268. * sorted array or not
  269. *
  270. * @access private
  271. */
  272. function PMA_usort_comparison_callback($a, $b)
  273. {
  274. if ($GLOBALS['cfg']['NaturalOrder']) {
  275. $sorter = 'strnatcasecmp';
  276. } else {
  277. $sorter = 'strcasecmp';
  278. }
  279. /* No sorting when key is not present */
  280. if (! isset($a[$GLOBALS['callback_sort_by']]) || ! isset($b[$GLOBALS['callback_sort_by']])) {
  281. return 0;
  282. }
  283. // produces f.e.:
  284. // return -1 * strnatcasecmp($a["SCHEMA_TABLES"], $b["SCHEMA_TABLES"])
  285. return ($GLOBALS['callback_sort_order'] == 'ASC' ? 1 : -1) * $sorter($a[$GLOBALS['callback_sort_by']], $b[$GLOBALS['callback_sort_by']]);
  286. } // end of the 'PMA_usort_comparison_callback()' function
  287. /**
  288. * returns array of all tables in given db or dbs
  289. * this function expects unquoted names:
  290. * RIGHT: my_database
  291. * WRONG: `my_database`
  292. * WRONG: my\_database
  293. * if $tbl_is_group is true, $table is used as filter for table names
  294. * if $tbl_is_group is 'comment, $table is used as filter for table comments
  295. *
  296. * <code>
  297. * PMA_DBI_get_tables_full('my_database');
  298. * PMA_DBI_get_tables_full('my_database', 'my_table'));
  299. * PMA_DBI_get_tables_full('my_database', 'my_tables_', true));
  300. * PMA_DBI_get_tables_full('my_database', 'my_tables_', 'comment'));
  301. * </code>
  302. *
  303. * @param string $database database
  304. * @param string|bool $table table or false
  305. * @param boolean|string $tbl_is_group $table is a table group
  306. * @param mixed $link mysql link
  307. * @param integer $limit_offset zero-based offset for the count
  308. * @param boolean|integer $limit_count number of tables to return
  309. * @param string $sort_by table attribute to sort by
  310. * @param string $sort_order direction to sort (ASC or DESC)
  311. *
  312. * @todo move into PMA_Table
  313. *
  314. * @return array list of tables in given db(s)
  315. */
  316. function PMA_DBI_get_tables_full($database, $table = false, $tbl_is_group = false, $link = null,
  317. $limit_offset = 0, $limit_count = false, $sort_by = 'Name', $sort_order = 'ASC')
  318. {
  319. if (true === $limit_count) {
  320. $limit_count = $GLOBALS['cfg']['MaxTableList'];
  321. }
  322. // prepare and check parameters
  323. if (! is_array($database)) {
  324. $databases = array($database);
  325. } else {
  326. $databases = $database;
  327. }
  328. $tables = array();
  329. if (! $GLOBALS['cfg']['Server']['DisableIS']) {
  330. // get table information from information_schema
  331. if ($table) {
  332. if (true === $tbl_is_group) {
  333. $sql_where_table = 'AND t.`TABLE_NAME` LIKE \''
  334. . PMA_escape_mysql_wildcards(PMA_sqlAddSlashes($table)) . '%\'';
  335. } elseif ('comment' === $tbl_is_group) {
  336. $sql_where_table = 'AND t.`TABLE_COMMENT` LIKE \''
  337. . PMA_escape_mysql_wildcards(PMA_sqlAddSlashes($table)) . '%\'';
  338. } else {
  339. $sql_where_table = 'AND t.`TABLE_NAME` = \'' . PMA_sqlAddSlashes($table) . '\'';
  340. }
  341. } else {
  342. $sql_where_table = '';
  343. }
  344. // for PMA bc:
  345. // `SCHEMA_FIELD_NAME` AS `SHOW_TABLE_STATUS_FIELD_NAME`
  346. //
  347. // on non-Windows servers,
  348. // added BINARY in the WHERE clause to force a case sensitive
  349. // comparison (if we are looking for the db Aa we don't want
  350. // to find the db aa)
  351. $this_databases = array_map('PMA_sqlAddSlashes', $databases);
  352. if (PMA_DRIZZLE) {
  353. $engine_info = PMA_cacheGet('drizzle_engines', true);
  354. $stats_join = "LEFT JOIN (SELECT 0 NUM_ROWS) AS stat ON false";
  355. if (isset($engine_info['InnoDB'])
  356. && $engine_info['InnoDB']['module_library'] == 'innobase'
  357. ) {
  358. $stats_join = "LEFT JOIN data_dictionary.INNODB_SYS_TABLESTATS stat ON (t.ENGINE = 'InnoDB' AND stat.NAME = (t.TABLE_SCHEMA || '/') || t.TABLE_NAME)";
  359. }
  360. // data_dictionary.table_cache may not contain any data for some tables, it's just a table cache
  361. // auto_increment == 0 is cast to NULL because currently (2011.03.13 GA) Drizzle doesn't provide correct value
  362. $sql = "
  363. SELECT t.*,
  364. t.TABLE_SCHEMA AS `Db`,
  365. t.TABLE_NAME AS `Name`,
  366. t.TABLE_TYPE AS `TABLE_TYPE`,
  367. t.ENGINE AS `Engine`,
  368. t.ENGINE AS `Type`,
  369. t.TABLE_VERSION AS `Version`,-- VERSION
  370. t.ROW_FORMAT AS `Row_format`,
  371. coalesce(tc.ROWS, stat.NUM_ROWS)
  372. AS `Rows`,-- TABLE_ROWS,
  373. coalesce(tc.ROWS, stat.NUM_ROWS)
  374. AS `TABLE_ROWS`,
  375. tc.AVG_ROW_LENGTH AS `Avg_row_length`, -- AVG_ROW_LENGTH
  376. tc.TABLE_SIZE AS `Data_length`, -- DATA_LENGTH
  377. NULL AS `Max_data_length`, -- MAX_DATA_LENGTH
  378. NULL AS `Index_length`, -- INDEX_LENGTH
  379. NULL AS `Data_free`, -- DATA_FREE
  380. nullif(t.AUTO_INCREMENT, 0)
  381. AS `Auto_increment`,
  382. t.TABLE_CREATION_TIME AS `Create_time`, -- CREATE_TIME
  383. t.TABLE_UPDATE_TIME AS `Update_time`, -- UPDATE_TIME
  384. NULL AS `Check_time`, -- CHECK_TIME
  385. t.TABLE_COLLATION AS `Collation`,
  386. NULL AS `Checksum`, -- CHECKSUM
  387. NULL AS `Create_options`, -- CREATE_OPTIONS
  388. t.TABLE_COMMENT AS `Comment`
  389. FROM data_dictionary.TABLES t
  390. LEFT JOIN data_dictionary.TABLE_CACHE tc ON tc.TABLE_SCHEMA = t.TABLE_SCHEMA AND tc.TABLE_NAME = t.TABLE_NAME
  391. $stats_join
  392. WHERE t.TABLE_SCHEMA IN ('" . implode("', '", $this_databases) . "')
  393. " . $sql_where_table;
  394. } else {
  395. $sql = '
  396. SELECT *,
  397. `TABLE_SCHEMA` AS `Db`,
  398. `TABLE_NAME` AS `Name`,
  399. `TABLE_TYPE` AS `TABLE_TYPE`,
  400. `ENGINE` AS `Engine`,
  401. `ENGINE` AS `Type`,
  402. `VERSION` AS `Version`,
  403. `ROW_FORMAT` AS `Row_format`,
  404. `TABLE_ROWS` AS `Rows`,
  405. `AVG_ROW_LENGTH` AS `Avg_row_length`,
  406. `DATA_LENGTH` AS `Data_length`,
  407. `MAX_DATA_LENGTH` AS `Max_data_length`,
  408. `INDEX_LENGTH` AS `Index_length`,
  409. `DATA_FREE` AS `Data_free`,
  410. `AUTO_INCREMENT` AS `Auto_increment`,
  411. `CREATE_TIME` AS `Create_time`,
  412. `UPDATE_TIME` AS `Update_time`,
  413. `CHECK_TIME` AS `Check_time`,
  414. `TABLE_COLLATION` AS `Collation`,
  415. `CHECKSUM` AS `Checksum`,
  416. `CREATE_OPTIONS` AS `Create_options`,
  417. `TABLE_COMMENT` AS `Comment`
  418. FROM `information_schema`.`TABLES` t
  419. WHERE ' . (PMA_IS_WINDOWS ? '' : 'BINARY') . ' `TABLE_SCHEMA` IN (\'' . implode("', '", $this_databases) . '\')
  420. ' . $sql_where_table;
  421. }
  422. // Sort the tables
  423. $sql .= " ORDER BY $sort_by $sort_order";
  424. if ($limit_count) {
  425. $sql .= ' LIMIT ' . $limit_count . ' OFFSET ' . $limit_offset;
  426. }
  427. $tables = PMA_DBI_fetch_result(
  428. $sql, array('TABLE_SCHEMA', 'TABLE_NAME'), null, $link
  429. );
  430. unset($sql_where_table, $sql);
  431. if (PMA_DRIZZLE) {
  432. // correct I_S and D_D names returned by D_D.TABLES - Drizzle generally uses lower case for them,
  433. // but TABLES returns uppercase
  434. foreach ((array)$database as $db) {
  435. $db_upper = strtoupper($db);
  436. if (!isset($tables[$db]) && isset($tables[$db_upper])) {
  437. $tables[$db] = $tables[$db_upper];
  438. unset($tables[$db_upper]);
  439. }
  440. }
  441. }
  442. if ($sort_by == 'Name' && $GLOBALS['cfg']['NaturalOrder']) {
  443. // here, the array's first key is by schema name
  444. foreach ($tables as $one_database_name => $one_database_tables) {
  445. uksort($one_database_tables, 'strnatcasecmp');
  446. if ($sort_order == 'DESC') {
  447. $one_database_tables = array_reverse($one_database_tables);
  448. }
  449. $tables[$one_database_name] = $one_database_tables;
  450. }
  451. }
  452. } // end (get information from table schema)
  453. // If permissions are wrong on even one database directory,
  454. // information_schema does not return any table info for any database
  455. // this is why we fall back to SHOW TABLE STATUS even for MySQL >= 50002
  456. if (empty($tables) && !PMA_DRIZZLE) {
  457. foreach ($databases as $each_database) {
  458. if ($table || (true === $tbl_is_group)) {
  459. $sql = 'SHOW TABLE STATUS FROM '
  460. . PMA_backquote($each_database)
  461. .' LIKE \'' . PMA_escape_mysql_wildcards(PMA_sqlAddSlashes($table, true)) . '%\'';
  462. } else {
  463. $sql = 'SHOW TABLE STATUS FROM '
  464. . PMA_backquote($each_database);
  465. }
  466. $each_tables = PMA_DBI_fetch_result($sql, 'Name', null, $link);
  467. // Sort naturally if the config allows it and we're sorting
  468. // the Name column.
  469. if ($sort_by == 'Name' && $GLOBALS['cfg']['NaturalOrder']) {
  470. uksort($each_tables, 'strnatcasecmp');
  471. if ($sort_order == 'DESC') {
  472. $each_tables = array_reverse($each_tables);
  473. }
  474. } else {
  475. // Prepare to sort by creating array of the selected sort
  476. // value to pass to array_multisort
  477. // Size = Data_length + Index_length
  478. if ($sort_by == 'Data_length') {
  479. foreach ($each_tables as $table_name => $table_data) {
  480. ${$sort_by}[$table_name] = strtolower($table_data['Data_length'] + $table_data['Index_length']);
  481. }
  482. } else {
  483. foreach ($each_tables as $table_name => $table_data) {
  484. ${$sort_by}[$table_name] = strtolower($table_data[$sort_by]);
  485. }
  486. }
  487. if ($sort_order == 'DESC') {
  488. array_multisort($$sort_by, SORT_DESC, $each_tables);
  489. } else {
  490. array_multisort($$sort_by, SORT_ASC, $each_tables);
  491. }
  492. // cleanup the temporary sort array
  493. unset($$sort_by);
  494. }
  495. if ($limit_count) {
  496. $each_tables = array_slice($each_tables, $limit_offset, $limit_count);
  497. }
  498. foreach ($each_tables as $table_name => $each_table) {
  499. if ('comment' === $tbl_is_group
  500. && 0 === strpos($each_table['Comment'], $table)
  501. ) {
  502. // remove table from list
  503. unset($each_tables[$table_name]);
  504. continue;
  505. }
  506. if (! isset($each_tables[$table_name]['Type'])
  507. && isset($each_tables[$table_name]['Engine'])
  508. ) {
  509. // pma BC, same parts of PMA still uses 'Type'
  510. $each_tables[$table_name]['Type']
  511. =& $each_tables[$table_name]['Engine'];
  512. } elseif (! isset($each_tables[$table_name]['Engine'])
  513. && isset($each_tables[$table_name]['Type'])) {
  514. // old MySQL reports Type, newer MySQL reports Engine
  515. $each_tables[$table_name]['Engine']
  516. =& $each_tables[$table_name]['Type'];
  517. }
  518. // MySQL forward compatibility
  519. // so pma could use this array as if every server is of version >5.0
  520. $each_tables[$table_name]['TABLE_SCHEMA'] = $each_database;
  521. $each_tables[$table_name]['TABLE_NAME'] =& $each_tables[$table_name]['Name'];
  522. $each_tables[$table_name]['ENGINE'] =& $each_tables[$table_name]['Engine'];
  523. $each_tables[$table_name]['VERSION'] =& $each_tables[$table_name]['Version'];
  524. $each_tables[$table_name]['ROW_FORMAT'] =& $each_tables[$table_name]['Row_format'];
  525. $each_tables[$table_name]['TABLE_ROWS'] =& $each_tables[$table_name]['Rows'];
  526. $each_tables[$table_name]['AVG_ROW_LENGTH'] =& $each_tables[$table_name]['Avg_row_length'];
  527. $each_tables[$table_name]['DATA_LENGTH'] =& $each_tables[$table_name]['Data_length'];
  528. $each_tables[$table_name]['MAX_DATA_LENGTH'] =& $each_tables[$table_name]['Max_data_length'];
  529. $each_tables[$table_name]['INDEX_LENGTH'] =& $each_tables[$table_name]['Index_length'];
  530. $each_tables[$table_name]['DATA_FREE'] =& $each_tables[$table_name]['Data_free'];
  531. $each_tables[$table_name]['AUTO_INCREMENT'] =& $each_tables[$table_name]['Auto_increment'];
  532. $each_tables[$table_name]['CREATE_TIME'] =& $each_tables[$table_name]['Create_time'];
  533. $each_tables[$table_name]['UPDATE_TIME'] =& $each_tables[$table_name]['Update_time'];
  534. $each_tables[$table_name]['CHECK_TIME'] =& $each_tables[$table_name]['Check_time'];
  535. $each_tables[$table_name]['TABLE_COLLATION'] =& $each_tables[$table_name]['Collation'];
  536. $each_tables[$table_name]['CHECKSUM'] =& $each_tables[$table_name]['Checksum'];
  537. $each_tables[$table_name]['CREATE_OPTIONS'] =& $each_tables[$table_name]['Create_options'];
  538. $each_tables[$table_name]['TABLE_COMMENT'] =& $each_tables[$table_name]['Comment'];
  539. if (strtoupper($each_tables[$table_name]['Comment']) === 'VIEW'
  540. && $each_tables[$table_name]['Engine'] == null
  541. ) {
  542. $each_tables[$table_name]['TABLE_TYPE'] = 'VIEW';
  543. } else {
  544. /**
  545. * @todo difference between 'TEMPORARY' and 'BASE TABLE' but how to detect?
  546. */
  547. $each_tables[$table_name]['TABLE_TYPE'] = 'BASE TABLE';
  548. }
  549. }
  550. $tables[$each_database] = $each_tables;
  551. }
  552. }
  553. // cache table data
  554. // so PMA_Table does not require to issue SHOW TABLE STATUS again
  555. // Note: I don't see why we would need array_merge_recursive() here,
  556. // as it creates double entries for the same table (for example a double
  557. // entry for Comment when changing the storage engine in Operations)
  558. // Note 2: Instead of array_merge(), simply use the + operator because
  559. // array_merge() renumbers numeric keys starting with 0, therefore
  560. // we would lose a db name thats consists only of numbers
  561. foreach ($tables as $one_database => $its_tables) {
  562. if (isset(PMA_Table::$cache[$one_database])) {
  563. PMA_Table::$cache[$one_database] = PMA_Table::$cache[$one_database] + $tables[$one_database];
  564. } else {
  565. PMA_Table::$cache[$one_database] = $tables[$one_database];
  566. }
  567. }
  568. unset($one_database, $its_tables);
  569. if (! is_array($database)) {
  570. if (isset($tables[$database])) {
  571. return $tables[$database];
  572. } elseif (isset($tables[strtolower($database)])) {
  573. // on windows with lower_case_table_names = 1
  574. // MySQL returns
  575. // with SHOW DATABASES or information_schema.SCHEMATA: `Test`
  576. // but information_schema.TABLES gives `test`
  577. // bug #1436171
  578. // http://sf.net/support/tracker.php?aid=1436171
  579. return $tables[strtolower($database)];
  580. } else {
  581. // one database but inexact letter case match
  582. // as Drizzle is always case insensitive, we can safely return the only result
  583. if (PMA_DRIZZLE && count($tables) == 1) {
  584. $keys = array_keys($tables);
  585. if (strlen(array_pop($keys)) == strlen($database)) {
  586. return array_pop($tables);
  587. }
  588. }
  589. return $tables;
  590. }
  591. } else {
  592. return $tables;
  593. }
  594. }
  595. /**
  596. * returns array with databases containing extended infos about them
  597. *
  598. * @param string $database database
  599. * @param boolean $force_stats retrieve stats also for MySQL < 5
  600. * @param resource $link mysql link
  601. * @param string $sort_by column to order by
  602. * @param string $sort_order ASC or DESC
  603. * @param integer $limit_offset starting offset for LIMIT
  604. * @param bool|int $limit_count row count for LIMIT or true for $GLOBALS['cfg']['MaxDbList']
  605. *
  606. * @todo move into PMA_List_Database?
  607. *
  608. * @return array $databases
  609. */
  610. function PMA_DBI_get_databases_full($database = null, $force_stats = false,
  611. $link = null, $sort_by = 'SCHEMA_NAME', $sort_order = 'ASC',
  612. $limit_offset = 0, $limit_count = false)
  613. {
  614. $sort_order = strtoupper($sort_order);
  615. if (true === $limit_count) {
  616. $limit_count = $GLOBALS['cfg']['MaxDbList'];
  617. }
  618. // initialize to avoid errors when there are no databases
  619. $databases = array();
  620. $apply_limit_and_order_manual = true;
  621. if (! $GLOBALS['cfg']['Server']['DisableIS']) {
  622. /**
  623. * if $GLOBALS['cfg']['NaturalOrder'] is enabled, we cannot use LIMIT
  624. * cause MySQL does not support natural ordering, we have to do it afterward
  625. */
  626. $limit = '';
  627. if (!$GLOBALS['cfg']['NaturalOrder']) {
  628. if ($limit_count) {
  629. $limit = ' LIMIT ' . $limit_count . ' OFFSET ' . $limit_offset;
  630. }
  631. $apply_limit_and_order_manual = false;
  632. }
  633. // get table information from information_schema
  634. if ($database) {
  635. $sql_where_schema = 'WHERE `SCHEMA_NAME` LIKE \''
  636. . PMA_sqlAddSlashes($database) . '\'';
  637. } else {
  638. $sql_where_schema = '';
  639. }
  640. if (PMA_DRIZZLE) {
  641. // data_dictionary.table_cache may not contain any data for some
  642. // tables, it's just a table cache
  643. $sql = 'SELECT
  644. s.SCHEMA_NAME,
  645. s.DEFAULT_COLLATION_NAME';
  646. if ($force_stats) {
  647. // no TABLE_CACHE data, stable results are better than
  648. // constantly changing
  649. $sql .= ',
  650. COUNT(t.TABLE_SCHEMA) AS SCHEMA_TABLES,
  651. SUM(stat.NUM_ROWS) AS SCHEMA_TABLE_ROWS';
  652. }
  653. $sql .= '
  654. FROM data_dictionary.SCHEMAS s';
  655. if ($force_stats) {
  656. $engine_info = PMA_cacheGet('drizzle_engines', true);
  657. $stats_join = "LEFT JOIN (SELECT 0 NUM_ROWS) AS stat ON false";
  658. if (isset($engine_info['InnoDB']) && $engine_info['InnoDB']['module_library'] == 'innobase') {
  659. $stats_join = "LEFT JOIN data_dictionary.INNODB_SYS_TABLESTATS stat ON (t.ENGINE = 'InnoDB' AND stat.NAME = (t.TABLE_SCHEMA || '/') || t.TABLE_NAME)";
  660. }
  661. $sql .= "
  662. LEFT JOIN data_dictionary.TABLES t
  663. ON t.TABLE_SCHEMA = s.SCHEMA_NAME
  664. $stats_join";
  665. }
  666. $sql .= $sql_where_schema . '
  667. GROUP BY s.SCHEMA_NAME
  668. ORDER BY ' . PMA_backquote($sort_by) . ' ' . $sort_order
  669. . $limit;
  670. } else {
  671. $sql = 'SELECT
  672. s.SCHEMA_NAME,
  673. s.DEFAULT_COLLATION_NAME';
  674. if ($force_stats) {
  675. $sql .= ',
  676. COUNT(t.TABLE_SCHEMA) AS SCHEMA_TABLES,
  677. SUM(t.TABLE_ROWS) AS SCHEMA_TABLE_ROWS,
  678. SUM(t.DATA_LENGTH) AS SCHEMA_DATA_LENGTH,
  679. SUM(t.MAX_DATA_LENGTH) AS SCHEMA_MAX_DATA_LENGTH,
  680. SUM(t.INDEX_LENGTH) AS SCHEMA_INDEX_LENGTH,
  681. SUM(t.DATA_LENGTH + t.INDEX_LENGTH)
  682. AS SCHEMA_LENGTH,
  683. SUM(t.DATA_FREE) AS SCHEMA_DATA_FREE';
  684. }
  685. $sql .= '
  686. FROM `information_schema`.SCHEMATA s';
  687. if ($force_stats) {
  688. $sql .= '
  689. LEFT JOIN `information_schema`.TABLES t
  690. ON BINARY t.TABLE_SCHEMA = BINARY s.SCHEMA_NAME';
  691. }
  692. $sql .= $sql_where_schema . '
  693. GROUP BY BINARY s.SCHEMA_NAME
  694. ORDER BY BINARY ' . PMA_backquote($sort_by) . ' ' . $sort_order
  695. . $limit;
  696. }
  697. $databases = PMA_DBI_fetch_result($sql, 'SCHEMA_NAME', null, $link);
  698. $mysql_error = PMA_DBI_getError($link);
  699. if (! count($databases) && $GLOBALS['errno']) {
  700. PMA_mysqlDie($mysql_error, $sql);
  701. }
  702. // display only databases also in official database list
  703. // f.e. to apply hide_db and only_db
  704. $drops = array_diff(array_keys($databases), (array) $GLOBALS['pma']->databases);
  705. if (count($drops)) {
  706. foreach ($drops as $drop) {
  707. unset($databases[$drop]);
  708. }
  709. unset($drop);
  710. }
  711. unset($sql_where_schema, $sql, $drops);
  712. } else {
  713. foreach ($GLOBALS['pma']->databases as $database_name) {
  714. // MySQL forward compatibility
  715. // so pma could use this array as if every server is of version >5.0
  716. $databases[$database_name]['SCHEMA_NAME'] = $database_name;
  717. if ($force_stats) {
  718. include_once './libraries/mysql_charsets.lib.php';
  719. $databases[$database_name]['DEFAULT_COLLATION_NAME']
  720. = PMA_getDbCollation($database_name);
  721. // get additional info about tables
  722. $databases[$database_name]['SCHEMA_TABLES'] = 0;
  723. $databases[$database_name]['SCHEMA_TABLE_ROWS'] = 0;
  724. $databases[$database_name]['SCHEMA_DATA_LENGTH'] = 0;
  725. $databases[$database_name]['SCHEMA_MAX_DATA_LENGTH'] = 0;
  726. $databases[$database_name]['SCHEMA_INDEX_LENGTH'] = 0;
  727. $databases[$database_name]['SCHEMA_LENGTH'] = 0;
  728. $databases[$database_name]['SCHEMA_DATA_FREE'] = 0;
  729. $res = PMA_DBI_query('SHOW TABLE STATUS FROM ' . PMA_backquote($database_name) . ';');
  730. while ($row = PMA_DBI_fetch_assoc($res)) {
  731. $databases[$database_name]['SCHEMA_TABLES']++;
  732. $databases[$database_name]['SCHEMA_TABLE_ROWS']
  733. += $row['Rows'];
  734. $databases[$database_name]['SCHEMA_DATA_LENGTH']
  735. += $row['Data_length'];
  736. $databases[$database_name]['SCHEMA_MAX_DATA_LENGTH']
  737. += $row['Max_data_length'];
  738. $databases[$database_name]['SCHEMA_INDEX_LENGTH']
  739. += $row['Index_length'];
  740. // for InnoDB, this does not contain the number of
  741. // overhead bytes but the total free space
  742. if ('InnoDB' != $row['Engine']) {
  743. $databases[$database_name]['SCHEMA_DATA_FREE']
  744. += $row['Data_free'];
  745. }
  746. $databases[$database_name]['SCHEMA_LENGTH']
  747. += $row['Data_length'] + $row['Index_length'];
  748. }
  749. PMA_DBI_free_result($res);
  750. unset($res);
  751. }
  752. }
  753. }
  754. /**
  755. * apply limit and order manually now
  756. * (caused by older MySQL < 5 or $GLOBALS['cfg']['NaturalOrder'])
  757. */
  758. if ($apply_limit_and_order_manual) {
  759. $GLOBALS['callback_sort_order'] = $sort_order;
  760. $GLOBALS['callback_sort_by'] = $sort_by;
  761. usort($databases, 'PMA_usort_comparison_callback');
  762. unset($GLOBALS['callback_sort_order'], $GLOBALS['callback_sort_by']);
  763. /**
  764. * now apply limit
  765. */
  766. if ($limit_count) {
  767. $databases = array_slice($databases, $limit_offset, $limit_count);
  768. }
  769. }
  770. return $databases;
  771. }
  772. /**
  773. * returns detailed array with all columns for given table in database,
  774. * or all tables/databases
  775. *
  776. * @param string $database name of database
  777. * @param string $table name of table to retrieve columns from
  778. * @param string $column name of specific column
  779. * @param mixed $link mysql link resource
  780. *
  781. * @return array
  782. */
  783. function PMA_DBI_get_columns_full($database = null, $table = null,
  784. $column = null, $link = null)
  785. {
  786. $columns = array();
  787. if (! $GLOBALS['cfg']['Server']['DisableIS']) {
  788. $sql_wheres = array();
  789. $array_keys = array();
  790. // get columns information from information_schema
  791. if (null !== $database) {
  792. $sql_wheres[] = '`TABLE_SCHEMA` = \'' . PMA_sqlAddSlashes($database) . '\' ';
  793. } else {
  794. $array_keys[] = 'TABLE_SCHEMA';
  795. }
  796. if (null !== $table) {
  797. $sql_wheres[] = '`TABLE_NAME` = \'' . PMA_sqlAddSlashes($table) . '\' ';
  798. } else {
  799. $array_keys[] = 'TABLE_NAME';
  800. }
  801. if (null !== $column) {
  802. $sql_wheres[] = '`COLUMN_NAME` = \'' . PMA_sqlAddSlashes($column) . '\' ';
  803. } else {
  804. $array_keys[] = 'COLUMN_NAME';
  805. }
  806. // for PMA bc:
  807. // `[SCHEMA_FIELD_NAME]` AS `[SHOW_FULL_COLUMNS_FIELD_NAME]`
  808. if (PMA_DRIZZLE) {
  809. $sql = "SELECT TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME,
  810. column_name AS `Field`,
  811. (CASE
  812. WHEN character_maximum_length > 0
  813. THEN concat(lower(data_type), '(', character_maximum_length, ')')
  814. WHEN numeric_precision > 0 OR numeric_scale > 0
  815. THEN concat(lower(data_type), '(', numeric_precision, ',', numeric_scale, ')')
  816. WHEN enum_values IS NOT NULL
  817. THEN concat(lower(data_type), '(', enum_values, ')')
  818. ELSE lower(data_type) END)
  819. AS `Type`,
  820. collation_name AS `Collation`,
  821. (CASE is_nullable
  822. WHEN 1 THEN 'YES'
  823. ELSE 'NO' END) AS `Null`,
  824. (CASE
  825. WHEN is_used_in_primary THEN 'PRI'
  826. ELSE '' END) AS `Key`,
  827. column_default AS `Default`,
  828. (CASE
  829. WHEN is_auto_increment THEN 'auto_increment'
  830. WHEN column_default_update THEN 'on update ' || column_default_update
  831. ELSE '' END) AS `Extra`,
  832. NULL AS `Privileges`,
  833. column_comment AS `Comment`
  834. FROM data_dictionary.columns";
  835. } else {
  836. $sql = '
  837. SELECT *,
  838. `COLUMN_NAME` AS `Field`,
  839. `COLUMN_TYPE` AS `Type`,
  840. `COLLATION_NAME` AS `Collation`,
  841. `IS_NULLABLE` AS `Null`,
  842. `COLUMN_KEY` AS `Key`,
  843. `COLUMN_DEFAULT` AS `Default`,
  844. `EXTRA` AS `Extra`,
  845. `PRIVILEGES` AS `Privileges`,
  846. `COLUMN_COMMENT` AS `Comment`
  847. FROM `information_schema`.`COLUMNS`';
  848. }
  849. if (count($sql_wheres)) {
  850. $sql .= "\n" . ' WHERE ' . implode(' AND ', $sql_wheres);
  851. }
  852. $columns = PMA_DBI_fetch_result($sql, $array_keys, null, $link);
  853. unset($sql_wheres, $sql);
  854. } else {
  855. if (null === $database) {
  856. foreach ($GLOBALS['pma']->databases as $database) {
  857. $columns[$database] = PMA_DBI_get_columns_full(
  858. $database, null, null, $link
  859. );
  860. }
  861. return $columns;
  862. } elseif (null === $table) {
  863. $tables = PMA_DBI_get_tables($database);
  864. foreach ($tables as $table) {
  865. $columns[$table] = PMA_DBI_get_columns_full(
  866. $database, $table, null, $link
  867. );
  868. }
  869. return $columns;
  870. }
  871. $sql = 'SHOW FULL COLUMNS FROM '
  872. . PMA_backquote($database) . '.' . PMA_backquote($table);
  873. if (null !== $column) {
  874. $sql .= " LIKE '" . PMA_sqlAddSlashes($column, true) . "'";
  875. }
  876. $columns = PMA_DBI_fetch_result($sql, 'Field', null, $link);
  877. }
  878. $ordinal_position = 1;
  879. foreach ($columns as $column_name => $each_column) {
  880. // MySQL forward compatibility
  881. // so pma could use this array as if every server is of version >5.0
  882. $columns[$column_name]['COLUMN_NAME'] =& $columns[$column_name]['Field'];
  883. $columns[$column_name]['COLUMN_TYPE'] =& $columns[$column_name]['Type'];
  884. $columns[$column_name]['COLLATION_NAME'] =& $columns[$column_name]['Collation'];
  885. $columns[$column_name]['IS_NULLABLE'] =& $columns[$column_name]['Null'];
  886. $columns[$column_name]['COLUMN_KEY'] =& $columns[$column_name]['Key'];
  887. $columns[$column_name]['COLUMN_DEFAULT'] =& $columns[$column_name]['Default'];
  888. $columns[$column_name]['EXTRA'] =& $columns[$column_name]['Extra'];
  889. $columns[$column_name]['PRIVILEGES'] =& $columns[$column_name]['Privileges'];
  890. $columns[$column_name]['COLUMN_COMMENT'] =& $columns[$column_name]['Comment'];
  891. $columns[$column_name]['TABLE_CATALOG'] = null;
  892. $columns[$column_name]['TABLE_SCHEMA'] = $database;
  893. $columns[$column_name]['TABLE_NAME'] = $table;
  894. $columns[$column_name]['ORDINAL_POSITION'] = $ordinal_position;
  895. $columns[$column_name]['DATA_TYPE']
  896. = substr(
  897. $columns[$column_name]['COLUMN_TYPE'],
  898. 0,
  899. strpos($columns[$column_name]['COLUMN_TYPE'], '(')
  900. );
  901. /**
  902. * @todo guess CHARACTER_MAXIMUM_LENGTH from COLUMN_TYPE
  903. */
  904. $columns[$column_name]['CHARACTER_MAXIMUM_LENGTH'] = null;
  905. /**
  906. * @todo guess CHARACTER_OCTET_LENGTH from CHARACTER_MAXIMUM_LENGTH
  907. */
  908. $columns[$column_name]['CHARACTER_OCTET_LENGTH'] = null;
  909. $columns[$column_name]['NUMERIC_PRECISION'] = null;
  910. $columns[$column_name]['NUMERIC_SCALE'] = null;
  911. $columns[$column_name]['CHARACTER_SET_NAME']
  912. = substr(
  913. $columns[$column_name]['COLLATION_NAME'],
  914. 0,
  915. strpos($columns[$column_name]['COLLATION_NAME'], '_')
  916. );
  917. $ordinal_position++;
  918. }
  919. if (null !== $column) {
  920. reset($columns);
  921. $columns = current($columns);
  922. }
  923. return $columns;
  924. }
  925. /**
  926. * Returns SQL query for fetching columns for a table
  927. *
  928. * The 'Key' column is not calculated properly, use PMA_DBI_get_columns() to get
  929. * correct values.
  930. *
  931. * @param string $database name of database
  932. * @param string $table name of table to retrieve columns from
  933. * @param string $column name of column, null to show all columns
  934. * @param boolean $full whether to return full info or only column names
  935. *
  936. * @see PMA_DBI_get_columns()
  937. *
  938. * @return string
  939. */
  940. function PMA_DBI_get_columns_sql($database, $table, $column = null, $full = false)
  941. {
  942. if (PMA_DRIZZLE) {
  943. // `Key` column:
  944. // * used in primary key => PRI
  945. // * unique one-column => UNI
  946. // * indexed, one-column or first in multi-column => MUL
  947. // Promotion of UNI to PRI in case no promary index exists is done after query is executed
  948. $sql = "SELECT
  949. column_name AS `Field`,
  950. (CASE
  951. WHEN character_maximum_length > 0
  952. THEN concat(lower(data_type), '(', character_maximum_length, ')')
  953. WHEN numeric_precision > 0 OR numeric_scale > 0
  954. THEN concat(lower(data_type), '(', numeric_precision, ',', numeric_scale, ')')
  955. WHEN enum_values IS NOT NULL
  956. THEN concat(lower(data_type), '(', enum_values, ')')
  957. ELSE lower(data_type) END)
  958. AS `Type`,
  959. " . ($full ? "
  960. collation_name AS `Collation`," : '') . "
  961. (CASE is_nullable
  962. WHEN 1 THEN 'YES'
  963. ELSE 'NO' END) AS `Null`,
  964. (CASE
  965. WHEN is_used_in_primary THEN 'PRI'
  966. WHEN is_unique AND NOT is_multi THEN 'UNI'
  967. WHEN is_indexed AND (NOT is_multi OR is_first_in_multi) THEN 'MUL'
  968. ELSE '' END) AS `Key`,
  969. column_default AS `Default`,
  970. (CASE
  971. WHEN is_auto_increment THEN 'auto_increment'
  972. WHEN column_default_update <> '' THEN 'on update ' || column_default_update
  973. ELSE '' END) AS `Extra`
  974. " . ($full ? " ,
  975. NULL AS `Privileges`,
  976. column_comment AS `Comment`" : '') . "
  977. FROM data_dictionary.columns
  978. WHERE table_schema = '" . PMA_sqlAddSlashes($database) . "'
  979. AND table_name = '" . PMA_sqlAddSlashes($table) . "'
  980. " . (($column != null) ? "
  981. AND column_name = '" . PMA_sqlAddSlashes($column) . "'" : '');
  982. // ORDER BY ordinal_position
  983. } else {
  984. $sql = 'SHOW ' . ($full ? 'FULL' : '') . ' COLUMNS
  985. FROM ' . PMA_backquote($database) . '.' . PMA_backquote($table)
  986. . (($column != null) ? "LIKE '" . PMA_sqlAddSlashes($column, true) . "'" : '');
  987. }
  988. return $sql;
  989. }
  990. /**
  991. * Returns descriptions of columns in given table (all or given by $column)
  992. *
  993. * @param string $database name of database
  994. * @param string $table name of table to retrieve columns from
  995. * @param string $column name of column, null to show all columns
  996. * @param boolean $full whether to return full info or only column names
  997. * @param mixed $link mysql link resource
  998. *
  999. * @return false|array array indexed by column names or,
  1000. * if $column is given, flat array description
  1001. */
  1002. function PMA_DBI_get_columns($database, $table, $column = null, $full = false, $link = null)
  1003. {
  1004. $sql = PMA_DBI_get_columns_sql($database, $table, $column, $full);
  1005. $fields = PMA_DBI_fetch_result($sql, 'Field', null, $link);
  1006. if (! is_array($fields) || count($fields) == 0) {
  1007. return null;
  1008. }
  1009. if (PMA_DRIZZLE) {
  1010. // fix Key column, it's much simpler in PHP than in SQL
  1011. $has_pk = false;
  1012. $has_pk_candidates = false;
  1013. foreach ($fields as $f) {
  1014. if ($f['Key'] == 'PRI') {
  1015. $has_pk = true;
  1016. break;
  1017. } else if ($f['Null'] == 'NO' && ($f['Key'] == 'MUL' || $f['Key'] == 'UNI')) {
  1018. $has_pk_candidates = true;
  1019. }
  1020. }
  1021. if (!$has_pk && $has_pk_candidates) {
  1022. // check whether we can promote some unique index to PRI
  1023. $sql = "
  1024. SELECT i.index_name, p.column_name
  1025. FROM data_dictionary.indexes i
  1026. JOIN data_dictionary.index_parts p USING (table_schema, table_name)
  1027. WHERE i.table_schema = '" . PMA_sqlAddSlashes($database) . "'
  1028. AND i.table_name = '" . PMA_sqlAddSlashes($table) . "'
  1029. AND i.is_unique
  1030. AND NOT i.is_nullable";
  1031. $fs = PMA_DBI_fetch_result($sql, 'index_name', null, $link);
  1032. $fs = $fs ? array_shift($fs) : array();
  1033. foreach ($fs as $f) {
  1034. $fields[$f]['Key'] = 'PRI';
  1035. }
  1036. }
  1037. }
  1038. return ($column != null) ? array_shift($fields) : $fields;
  1039. }
  1040. /**
  1041. * Returns SQL for fetching information on table indexes (SHOW INDEXES)
  1042. *
  1043. * @param string $database name of database
  1044. * @param string $table name of the table whose indexes are to be retreived
  1045. * @param string $where additional conditions for WHERE
  1046. *
  1047. * @return array $indexes
  1048. */
  1049. function PMA_DBI_get_table_indexes_sql($database, $table, $where = null)
  1050. {
  1051. if (PMA_DRIZZLE) {
  1052. $sql = "SELECT
  1053. ip.table_name AS `Table`,
  1054. (NOT ip.is_unique) AS Non_unique,
  1055. ip.index_name AS Key_name,
  1056. ip.sequence_in_index+1 AS Seq_in_index,
  1057. ip.column_name AS Column_name,
  1058. (CASE
  1059. WHEN i.index_type = 'BTREE' THEN 'A'
  1060. ELSE NULL END) AS Collation,
  1061. NULL AS Cardinality,
  1062. compare_length AS Sub_part,
  1063. NULL AS Packed,
  1064. ip.is_nullable AS `Null`,
  1065. i.index_type AS Index_type,
  1066. NULL AS Comment,
  1067. i.index_comment AS Index_comment
  1068. FROM data_dictionary.index_parts ip
  1069. LEFT JOIN data_dictionary.indexes i USING (table_schema, table_name, index_name)
  1070. WHERE table_schema = '" . PMA_sqlAddSlashes($database) . "'
  1071. AND table_name = '" . PMA_sqlAddSlashes($table) . "'
  1072. ";
  1073. } else {
  1074. $sql = 'SHOW INDEXES FROM ' . PMA_backquote($database) . '.' . PMA_backquote($table);
  1075. }
  1076. if ($where) {
  1077. $sql .= (PMA_DRIZZLE ? ' AND (' : ' WHERE (') . $where . ')';
  1078. }
  1079. return $sql;
  1080. }
  1081. /**
  1082. * Returns indexes of a table
  1083. *
  1084. * @param string $database name of database
  1085. * @param string $table name of the table whose indexes are to be retrieved
  1086. * @param mixed $link mysql link resource
  1087. *
  1088. * @return array $indexes
  1089. */
  1090. function PMA_DBI_get_table_indexes($database, $table, $link = null)
  1091. {
  1092. $sql = PMA_DBI_get_table_indexes_sql($database, $table);
  1093. $indexes = PMA_DBI_fetch_result($sql, null, null, $link);
  1094. if (! is_array($indexes) || count($indexes) < 1) {
  1095. return array();
  1096. }
  1097. return $indexes;
  1098. }
  1099. /**
  1100. * returns value of given mysql server variable
  1101. *
  1102. * @param string $var mysql server variable name
  1103. * @param int $type PMA_DBI_GETVAR_SESSION|PMA_DBI_GETVAR_GLOBAL
  1104. * @param mixed $link mysql link resource|object
  1105. *
  1106. * @return mixed value for mysql server variable
  1107. */
  1108. function PMA_DBI_get_variable($var, $type = PMA_DBI_GETVAR_SESSION, $link = null)
  1109. {
  1110. if ($link === null) {
  1111. if (isset($GLOBALS['userlink'])) {
  1112. $link = $GLOBALS['userlink'];
  1113. } else {
  1114. return false;
  1115. }
  1116. }
  1117. switch ($type) {
  1118. case PMA_DBI_GETVAR_SESSION:
  1119. $modifier = ' SESSION';
  1120. break;
  1121. case PMA_DBI_GETVAR_GLOBAL:
  1122. $modifier = ' GLOBAL';
  1123. break;
  1124. default:
  1125. $modifier = '';
  1126. }
  1127. return PMA_DBI_fetch_value(
  1128. 'SHOW' . $modifier . ' VARIABLES LIKE \'' . $var . '\';', 0, 1, $link
  1129. );
  1130. }
  1131. /**
  1132. * Function called just after a connection to the MySQL database server has
  1133. * been established. It sets the connection collation, and determins the
  1134. * version of MySQL which is running.
  1135. *
  1136. * @param mixed $link mysql link resource|object
  1137. * @param boolean $is_controluser whether link is for control user
  1138. */
  1139. function PMA_DBI_postConnect($link, $is_controluser = false)
  1140. {
  1141. if (! defined('PMA_MYSQL_INT_VERSION')) {
  1142. if (PMA_cacheExists('PMA_MYSQL_INT_VERSION', true)) {
  1143. define(
  1144. 'PMA_MYSQL_INT_VERSION',
  1145. PMA_cacheGet('PMA_MYSQL_INT_VERSION', true)
  1146. );
  1147. define(
  1148. 'PMA_MYSQL_MAJOR_VERSION',
  1149. PMA_cacheGet('PMA_MYSQL_MAJOR_VERSION', true)

Large files files are truncated, but you can click here to view the full file