/**
 * returns array of all tables in given db or dbs
 * this function expects unquoted names:
 * RIGHT: my_database
 * WRONG: `my_database`
 * WRONG: my\_database
 * if $tbl_is_group is true, $table is used as filter for table names
 * if $tbl_is_group is 'comment, $table is used as filter for table comments
 *
 * <code>
 * PMA_DBI_get_tables_full('my_database');
 * PMA_DBI_get_tables_full('my_database', 'my_table'));
 * PMA_DBI_get_tables_full('my_database', 'my_tables_', true));
 * PMA_DBI_get_tables_full('my_database', 'my_tables_', 'comment'));
 * </code>
 *
 * @param string          $database     database
 * @param string|bool     $table        table or false
 * @param boolean|string  $tbl_is_group $table is a table group
 * @param mixed           $link         mysql link
 * @param integer         $limit_offset zero-based offset for the count
 * @param boolean|integer $limit_count  number of tables to return
 * @param string          $sort_by      table attribute to sort by
 * @param string          $sort_order   direction to sort (ASC or DESC)
 *
 * @todo    move into PMA_Table
 *
 * @return array           list of tables in given db(s)
 */
function PMA_DBI_get_tables_full($database, $table = false, $tbl_is_group = false, $link = null, $limit_offset = 0, $limit_count = false, $sort_by = 'Name', $sort_order = 'ASC')
{
    if (true === $limit_count) {
        $limit_count = $GLOBALS['cfg']['MaxTableList'];
    }
    // prepare and check parameters
    if (!is_array($database)) {
        $databases = array($database);
    } else {
        $databases = $database;
    }
    $tables = array();
    if (!$GLOBALS['cfg']['Server']['DisableIS']) {
        // get table information from information_schema
        if ($table) {
            if (true === $tbl_is_group) {
                $sql_where_table = 'AND t.`TABLE_NAME` LIKE \'' . PMA_escapeMysqlWildcards(PMA_sqlAddSlashes($table)) . '%\'';
            } elseif ('comment' === $tbl_is_group) {
                $sql_where_table = 'AND t.`TABLE_COMMENT` LIKE \'' . PMA_escapeMysqlWildcards(PMA_sqlAddSlashes($table)) . '%\'';
            } else {
                $sql_where_table = 'AND t.`TABLE_NAME` = \'' . PMA_sqlAddSlashes($table) . '\'';
            }
        } else {
            $sql_where_table = '';
        }
        // for PMA bc:
        // `SCHEMA_FIELD_NAME` AS `SHOW_TABLE_STATUS_FIELD_NAME`
        //
        // on non-Windows servers,
        // added BINARY in the WHERE clause to force a case sensitive
        // comparison (if we are looking for the db Aa we don't want
        // to find the db aa)
        $this_databases = array_map('PMA_sqlAddSlashes', $databases);
        if (PMA_DRIZZLE) {
            $engine_info = PMA_cacheGet('drizzle_engines', true);
            $stats_join = "LEFT JOIN (SELECT 0 NUM_ROWS) AS stat ON false";
            if (isset($engine_info['InnoDB']) && $engine_info['InnoDB']['module_library'] == 'innobase') {
                $stats_join = "LEFT JOIN data_dictionary.INNODB_SYS_TABLESTATS stat ON (t.ENGINE = 'InnoDB' AND stat.NAME = (t.TABLE_SCHEMA || '/') || t.TABLE_NAME)";
            }
            // data_dictionary.table_cache may not contain any data for some tables, it's just a table cache
            // auto_increment == 0 is cast to NULL because currently (2011.03.13 GA) Drizzle doesn't provide correct value
            $sql = "\n                SELECT t.*,\n                    t.TABLE_SCHEMA        AS `Db`,\n                    t.TABLE_NAME          AS `Name`,\n                    t.TABLE_TYPE          AS `TABLE_TYPE`,\n                    t.ENGINE              AS `Engine`,\n                    t.ENGINE              AS `Type`,\n                    t.TABLE_VERSION       AS `Version`,-- VERSION\n                    t.ROW_FORMAT          AS `Row_format`,\n                    coalesce(tc.ROWS, stat.NUM_ROWS)\n                                          AS `Rows`,-- TABLE_ROWS,\n                    coalesce(tc.ROWS, stat.NUM_ROWS)\n                                          AS `TABLE_ROWS`,\n                    tc.AVG_ROW_LENGTH     AS `Avg_row_length`, -- AVG_ROW_LENGTH\n                    tc.TABLE_SIZE         AS `Data_length`, -- DATA_LENGTH\n                    NULL                  AS `Max_data_length`, -- MAX_DATA_LENGTH\n                    NULL                  AS `Index_length`, -- INDEX_LENGTH\n                    NULL                  AS `Data_free`, -- DATA_FREE\n                    nullif(t.AUTO_INCREMENT, 0)\n                                          AS `Auto_increment`,\n                    t.TABLE_CREATION_TIME AS `Create_time`, -- CREATE_TIME\n                    t.TABLE_UPDATE_TIME   AS `Update_time`, -- UPDATE_TIME\n                    NULL                  AS `Check_time`, -- CHECK_TIME\n                    t.TABLE_COLLATION     AS `Collation`,\n                    NULL                  AS `Checksum`, -- CHECKSUM\n                    NULL                  AS `Create_options`, -- CREATE_OPTIONS\n                    t.TABLE_COMMENT       AS `Comment`\n                FROM data_dictionary.TABLES t\n                    LEFT JOIN data_dictionary.TABLE_CACHE tc ON tc.TABLE_SCHEMA = t.TABLE_SCHEMA AND tc.TABLE_NAME = t.TABLE_NAME\n                    {$stats_join}\n                WHERE t.TABLE_SCHEMA IN ('" . implode("', '", $this_databases) . "')\n                    " . $sql_where_table;
        } else {
            $sql = '
                SELECT *,
                    `TABLE_SCHEMA`       AS `Db`,
                    `TABLE_NAME`         AS `Name`,
                    `TABLE_TYPE`         AS `TABLE_TYPE`,
                    `ENGINE`             AS `Engine`,
                    `ENGINE`             AS `Type`,
                    `VERSION`            AS `Version`,
                    `ROW_FORMAT`         AS `Row_format`,
                    `TABLE_ROWS`         AS `Rows`,
                    `AVG_ROW_LENGTH`     AS `Avg_row_length`,
                    `DATA_LENGTH`        AS `Data_length`,
                    `MAX_DATA_LENGTH`    AS `Max_data_length`,
                    `INDEX_LENGTH`       AS `Index_length`,
                    `DATA_FREE`          AS `Data_free`,
                    `AUTO_INCREMENT`     AS `Auto_increment`,
                    `CREATE_TIME`        AS `Create_time`,
                    `UPDATE_TIME`        AS `Update_time`,
                    `CHECK_TIME`         AS `Check_time`,
                    `TABLE_COLLATION`    AS `Collation`,
                    `CHECKSUM`           AS `Checksum`,
                    `CREATE_OPTIONS`     AS `Create_options`,
                    `TABLE_COMMENT`      AS `Comment`
                FROM `information_schema`.`TABLES` t
                WHERE ' . (PMA_IS_WINDOWS ? '' : 'BINARY') . ' `TABLE_SCHEMA` IN (\'' . implode("', '", $this_databases) . '\')
                    ' . $sql_where_table;
        }
        // Sort the tables
        $sql .= " ORDER BY {$sort_by} {$sort_order}";
        if ($limit_count) {
            $sql .= ' LIMIT ' . $limit_count . ' OFFSET ' . $limit_offset;
        }
        $tables = PMA_DBI_fetch_result($sql, array('TABLE_SCHEMA', 'TABLE_NAME'), null, $link);
        unset($sql_where_table, $sql);
        if (PMA_DRIZZLE) {
            // correct I_S and D_D names returned by D_D.TABLES - Drizzle generally uses lower case for them,
            // but TABLES returns uppercase
            foreach ((array) $database as $db) {
                $db_upper = strtoupper($db);
                if (!isset($tables[$db]) && isset($tables[$db_upper])) {
                    $tables[$db] = $tables[$db_upper];
                    unset($tables[$db_upper]);
                }
            }
        }
        if ($sort_by == 'Name' && $GLOBALS['cfg']['NaturalOrder']) {
            // here, the array's first key is by schema name
            foreach ($tables as $one_database_name => $one_database_tables) {
                uksort($one_database_tables, 'strnatcasecmp');
                if ($sort_order == 'DESC') {
                    $one_database_tables = array_reverse($one_database_tables);
                }
                $tables[$one_database_name] = $one_database_tables;
            }
        }
    }
    // end (get information from table schema)
    // If permissions are wrong on even one database directory,
    // information_schema does not return any table info for any database
    // this is why we fall back to SHOW TABLE STATUS even for MySQL >= 50002
    if (empty($tables) && !PMA_DRIZZLE) {
        foreach ($databases as $each_database) {
            if ($table || true === $tbl_is_group) {
                $sql = 'SHOW TABLE STATUS FROM ' . PMA_backquote($each_database) . ' LIKE \'' . PMA_escapeMysqlWildcards(PMA_sqlAddSlashes($table, true)) . '%\'';
            } else {
                $sql = 'SHOW TABLE STATUS FROM ' . PMA_backquote($each_database);
            }
            $each_tables = PMA_DBI_fetch_result($sql, 'Name', null, $link);
            // Sort naturally if the config allows it and we're sorting
            // the Name column.
            if ($sort_by == 'Name' && $GLOBALS['cfg']['NaturalOrder']) {
                uksort($each_tables, 'strnatcasecmp');
                if ($sort_order == 'DESC') {
                    $each_tables = array_reverse($each_tables);
                }
            } else {
                // Prepare to sort by creating array of the selected sort
                // value to pass to array_multisort
                // Size = Data_length + Index_length
                if ($sort_by == 'Data_length') {
                    foreach ($each_tables as $table_name => $table_data) {
                        ${$sort_by}[$table_name] = strtolower($table_data['Data_length'] + $table_data['Index_length']);
                    }
                } else {
                    foreach ($each_tables as $table_name => $table_data) {
                        ${$sort_by}[$table_name] = strtolower($table_data[$sort_by]);
                    }
                }
                if ($sort_order == 'DESC') {
                    array_multisort(${$sort_by}, SORT_DESC, $each_tables);
                } else {
                    array_multisort(${$sort_by}, SORT_ASC, $each_tables);
                }
                // cleanup the temporary sort array
                unset(${$sort_by});
            }
            if ($limit_count) {
                $each_tables = array_slice($each_tables, $limit_offset, $limit_count);
            }
            foreach ($each_tables as $table_name => $each_table) {
                if ('comment' === $tbl_is_group && 0 === strpos($each_table['Comment'], $table)) {
                    // remove table from list
                    unset($each_tables[$table_name]);
                    continue;
                }
                if (!isset($each_tables[$table_name]['Type']) && isset($each_tables[$table_name]['Engine'])) {
                    // pma BC, same parts of PMA still uses 'Type'
                    $each_tables[$table_name]['Type'] =& $each_tables[$table_name]['Engine'];
                } elseif (!isset($each_tables[$table_name]['Engine']) && isset($each_tables[$table_name]['Type'])) {
                    // old MySQL reports Type, newer MySQL reports Engine
                    $each_tables[$table_name]['Engine'] =& $each_tables[$table_name]['Type'];
                }
                // MySQL forward compatibility
                // so pma could use this array as if every server is of version >5.0
                $each_tables[$table_name]['TABLE_SCHEMA'] = $each_database;
                $each_tables[$table_name]['TABLE_NAME'] =& $each_tables[$table_name]['Name'];
                $each_tables[$table_name]['ENGINE'] =& $each_tables[$table_name]['Engine'];
                $each_tables[$table_name]['VERSION'] =& $each_tables[$table_name]['Version'];
                $each_tables[$table_name]['ROW_FORMAT'] =& $each_tables[$table_name]['Row_format'];
                $each_tables[$table_name]['TABLE_ROWS'] =& $each_tables[$table_name]['Rows'];
                $each_tables[$table_name]['AVG_ROW_LENGTH'] =& $each_tables[$table_name]['Avg_row_length'];
                $each_tables[$table_name]['DATA_LENGTH'] =& $each_tables[$table_name]['Data_length'];
                $each_tables[$table_name]['MAX_DATA_LENGTH'] =& $each_tables[$table_name]['Max_data_length'];
                $each_tables[$table_name]['INDEX_LENGTH'] =& $each_tables[$table_name]['Index_length'];
                $each_tables[$table_name]['DATA_FREE'] =& $each_tables[$table_name]['Data_free'];
                $each_tables[$table_name]['AUTO_INCREMENT'] =& $each_tables[$table_name]['Auto_increment'];
                $each_tables[$table_name]['CREATE_TIME'] =& $each_tables[$table_name]['Create_time'];
                $each_tables[$table_name]['UPDATE_TIME'] =& $each_tables[$table_name]['Update_time'];
                $each_tables[$table_name]['CHECK_TIME'] =& $each_tables[$table_name]['Check_time'];
                $each_tables[$table_name]['TABLE_COLLATION'] =& $each_tables[$table_name]['Collation'];
                $each_tables[$table_name]['CHECKSUM'] =& $each_tables[$table_name]['Checksum'];
                $each_tables[$table_name]['CREATE_OPTIONS'] =& $each_tables[$table_name]['Create_options'];
                $each_tables[$table_name]['TABLE_COMMENT'] =& $each_tables[$table_name]['Comment'];
                if (strtoupper($each_tables[$table_name]['Comment']) === 'VIEW' && $each_tables[$table_name]['Engine'] == null) {
                    $each_tables[$table_name]['TABLE_TYPE'] = 'VIEW';
                } else {
                    /**
                     * @todo difference between 'TEMPORARY' and 'BASE TABLE' but how to detect?
                     */
                    $each_tables[$table_name]['TABLE_TYPE'] = 'BASE TABLE';
                }
            }
            $tables[$each_database] = $each_tables;
        }
    }
    // cache table data
    // so PMA_Table does not require to issue SHOW TABLE STATUS again
    // Note: I don't see why we would need array_merge_recursive() here,
    // as it creates double entries for the same table (for example a double
    // entry for Comment when changing the storage engine in Operations)
    // Note 2: Instead of array_merge(), simply use the + operator because
    //  array_merge() renumbers numeric keys starting with 0, therefore
    //  we would lose a db name thats consists only of numbers
    foreach ($tables as $one_database => $its_tables) {
        if (isset(PMA_Table::$cache[$one_database])) {
            PMA_Table::$cache[$one_database] = PMA_Table::$cache[$one_database] + $tables[$one_database];
        } else {
            PMA_Table::$cache[$one_database] = $tables[$one_database];
        }
    }
    unset($one_database, $its_tables);
    if (!is_array($database)) {
        if (isset($tables[$database])) {
            return $tables[$database];
        } elseif (isset($tables[strtolower($database)])) {
            // on windows with lower_case_table_names = 1
            // MySQL returns
            // with SHOW DATABASES or information_schema.SCHEMATA: `Test`
            // but information_schema.TABLES gives `test`
            // bug #1436171
            // http://sf.net/support/tracker.php?aid=1436171
            return $tables[strtolower($database)];
        } else {
            // one database but inexact letter case match
            // as Drizzle is always case insensitive, we can safely return the only result
            if (PMA_DRIZZLE && count($tables) == 1) {
                $keys = array_keys($tables);
                if (strlen(array_pop($keys)) == strlen($database)) {
                    return array_pop($tables);
                }
            }
            return $tables;
        }
    } else {
        return $tables;
    }
}
 /**
  * PMA_escapeMysqlWildcards tests
  * @dataProvider escapeDataProvider
  */
 public function testEscape($a, $b)
 {
     $this->assertEquals($a, PMA_escapeMysqlWildcards($b));
 }
 }
 $user_form .= '    <tr class="noclick ' . ($odd_row ? 'odd' : 'even') . '">' . "\n" . '        <td';
 if (count($current_privileges) > 1) {
     $user_form .= ' rowspan="' . count($current_privileges) . '"';
 }
 $user_form .= '>' . (empty($current_user) ? '<span style="color: #FF0000">' . __('Any') . '</span>' : htmlspecialchars($current_user)) . "\n" . '        </td>' . "\n" . '        <td';
 if (count($current_privileges) > 1) {
     $user_form .= ' rowspan="' . count($current_privileges) . '"';
 }
 $user_form .= '>' . htmlspecialchars($current_host) . '</td>' . "\n";
 for ($i = 0; $i < count($current_privileges); $i++) {
     $current = $current_privileges[$i];
     $user_form .= '        <td>' . "\n" . '            ';
     if (!isset($current['Db']) || $current['Db'] == '*') {
         $user_form .= __('global');
     } elseif ($current['Db'] == PMA_escapeMysqlWildcards($checkprivs)) {
         $user_form .= __('database-specific');
     } else {
         $user_form .= __('wildcard') . ': <code>' . htmlspecialchars($current['Db']) . '</code>';
     }
     $user_form .= "\n" . '        </td>' . "\n" . '        <td>' . "\n" . '            <code>' . "\n" . '                ' . join(',' . "\n" . '                ', PMA_extractPrivInfo($current, true)) . "\n" . '            </code>' . "\n" . '        </td>' . "\n" . '        <td>' . "\n" . '            ' . ($current['Grant_priv'] == 'Y' ? __('Yes') : __('No')) . "\n" . '        </td>' . "\n" . '        <td>' . "\n";
     $user_form .= sprintf($link_edit, urlencode($current_user), urlencode($current_host), urlencode(!isset($current['Db']) || $current['Db'] == '*' ? '' : $current['Db']), '');
     $user_form .= '</td>' . "\n" . '    </tr>' . "\n";
     if ($i + 1 < count($current_privileges)) {
         $user_form .= '<tr class="noclick ' . ($odd_row ? 'odd' : 'even') . '">' . "\n";
     }
 }
 if (empty($row) && empty($row1) && empty($row2)) {
     break;
 }
 $odd_row = !$odd_row;
Example #4
0
/**
 * @global bool whether selected db is information_schema
 */
$db_is_information_schema = false;
if (PMA_is_system_schema($db)) {
    $is_show_stats = false;
    $db_is_information_schema = true;
}
/**
 * @global array information about tables in db
 */
$tables = array();
// When used in Nested table group mode,
// only show tables matching the given groupname
if (PMA_isValid($tbl_group) && !$cfg['ShowTooltipAliasTB']) {
    $tbl_group_sql = ' LIKE "' . PMA_escapeMysqlWildcards($tbl_group) . '%"';
} else {
    $tbl_group_sql = '';
}
if ($cfg['ShowTooltip']) {
    $tooltip_truename = array();
    $tooltip_aliasname = array();
}
// Special speedup for newer MySQL Versions (in 4.0 format changed)
if (true === $cfg['SkipLockedTables']) {
    $db_info_result = PMA_DBI_query('SHOW OPEN TABLES FROM ' . PMA_backquote($db) . ';');
    // Blending out tables in use
    if ($db_info_result && PMA_DBI_num_rows($db_info_result) > 0) {
        while ($tmp = PMA_DBI_fetch_row($db_info_result)) {
            // if in use memorize tablename
            if (preg_match('@in_use=[1-9]+@i', $tmp[1])) {