PageRenderTime 57ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 0ms

/pma/libraries/database_interface.lib.php

https://bitbucket.org/StasPiv/playzone
PHP | 1342 lines | 765 code | 117 blank | 460 comment | 148 complexity | 719768d29b4715239f37461e9bdb8c32 MD5 | raw file
Possible License(s): Apache-2.0, BSD-3-Clause, GPL-2.0, LGPL-2.1

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

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