/** * returns array with tables of given db with extended information and grouped * * @uses $cfg['LeftFrameTableSeparator'] * @uses $cfg['LeftFrameTableLevel'] * @uses $cfg['ShowTooltipAliasTB'] * @uses $cfg['NaturalOrder'] * @uses PMA_backquote() * @uses count() * @uses array_merge * @uses uksort() * @uses strstr() * @uses explode() * @param string $db name of db * @param string $tables name of tables * @param integer $limit_offset list offset * @param integer $limit_count max tables to return * return array (recursive) grouped table list */ function PMA_getTableList($db, $tables = null, $limit_offset = 0, $limit_count = false) { $sep = $GLOBALS['cfg']['LeftFrameTableSeparator']; if (null === $tables) { $tables = PMA_DBI_get_tables_full($db, false, false, null, $limit_offset, $limit_count); if ($GLOBALS['cfg']['NaturalOrder']) { uksort($tables, 'strnatcasecmp'); } } if (count($tables) < 1) { return $tables; } $default = array('Name' => '', 'Rows' => 0, 'Comment' => '', 'disp_name' => ''); $table_groups = array(); // for blobstreaming - list of blobstreaming tables - rajk // load PMA configuration $PMA_Config = $_SESSION['PMA_Config']; // if PMA configuration exists if (!empty($PMA_Config)) { $session_bs_tables = $_SESSION['PMA_Config']->get('BLOBSTREAMING_TABLES'); } foreach ($tables as $table_name => $table) { // if BS tables exist if (isset($session_bs_tables)) { // compare table name to tables in list of blobstreaming tables foreach ($session_bs_tables as $table_key => $table_val) { // if table is in list, skip outer foreach loop if ($table_name == $table_key) { continue 2; } } } // check for correct row count if (null === $table['Rows']) { // Do not check exact row count here, // if row count is invalid possibly the table is defect // and this would break left frame; // but we can check row count if this is a view or the // information_schema database // since PMA_Table::countRecords() returns a limited row count // in this case. // set this because PMA_Table::countRecords() can use it $tbl_is_view = PMA_Table::isView($db, $table['Name']); if ($tbl_is_view || 'information_schema' == $db) { $table['Rows'] = PMA_Table::countRecords($db, $table['Name'], $return = true); } } // in $group we save the reference to the place in $table_groups // where to store the table info if ($GLOBALS['cfg']['LeftFrameDBTree'] && $sep && strstr($table_name, $sep)) { $parts = explode($sep, $table_name); $group =& $table_groups; $i = 0; $group_name_full = ''; while ($i < count($parts) - 1 && $i < $GLOBALS['cfg']['LeftFrameTableLevel']) { $group_name = $parts[$i] . $sep; $group_name_full .= $group_name; if (!isset($group[$group_name])) { $group[$group_name] = array(); $group[$group_name]['is' . $sep . 'group'] = true; $group[$group_name]['tab' . $sep . 'count'] = 1; $group[$group_name]['tab' . $sep . 'group'] = $group_name_full; } elseif (!isset($group[$group_name]['is' . $sep . 'group'])) { $table = $group[$group_name]; $group[$group_name] = array(); $group[$group_name][$group_name] = $table; unset($table); $group[$group_name]['is' . $sep . 'group'] = true; $group[$group_name]['tab' . $sep . 'count'] = 1; $group[$group_name]['tab' . $sep . 'group'] = $group_name_full; } else { $group[$group_name]['tab' . $sep . 'count']++; } $group =& $group[$group_name]; $i++; } } else { if (!isset($table_groups[$table_name])) { $table_groups[$table_name] = array(); } $group =& $table_groups; } if ($GLOBALS['cfg']['ShowTooltipAliasTB'] && $GLOBALS['cfg']['ShowTooltipAliasTB'] !== 'nested') { // switch tooltip and name $table['Comment'] = $table['Name']; $table['disp_name'] = $table['Comment']; } else { $table['disp_name'] = $table['Name']; } $group[$table_name] = array_merge($default, $table); } return $table_groups; }
/** * Function to calculate new pos if pos is higher than number of rows * of displayed table * * @param String $db Database name * @param String $table Table name * @param Int|null $pos Initial position * * @return Int Number of pos to display last page */ function PMA_calculatePosForLastPage($db, $table, $pos) { if (null === $pos) { $pos = $_SESSION['tmpval']['pos']; } $unlim_num_rows = PMA_Table::countRecords($db, $table, true); //If position is higher than number of rows if ($unlim_num_rows <= $pos && 0 != $pos) { $pos = PMA_getStartPosToDisplayRow($unlim_num_rows); } return $pos; }
/** * Defines the parts to display for the results of a SQL query * * @param string $displayParts the parts to display (see a few * lines above for explanations) * @param integer &$the_total the total number of rows returned by the SQL * query without any programmatically appended * LIMIT clause * (just a copy of $unlim_num_rows if it exists, * elsecomputed inside this function) * * @return array an array with explicit indexes for all the display * elements * * @access private * * @see getTable() */ private function _setDisplayParts($displayParts, &$the_total) { // 1. Following variables are needed for use in isset/empty or // use with array indexes or safe use in foreach $db = $this->__get('db'); $table = $this->__get('table'); $unlim_num_rows = $this->__get('unlim_num_rows'); $num_rows = $this->__get('num_rows'); $fields_meta = $this->__get('fields_meta'); $printview = $this->__get('printview'); // 2. Updates the display mode if (isset($printview) && $printview == '1') { // 2.0 Print view -> set all elements to false! $displayParts['edit_lnk'] = self::NO_EDIT_OR_DELETE; // no edit link $displayParts['del_lnk'] = self::NO_EDIT_OR_DELETE; // no delete link $displayParts['sort_lnk'] = (string) '0'; $displayParts['nav_bar'] = (string) '0'; $displayParts['ins_row'] = (string) '0'; $displayParts['bkm_form'] = (string) '0'; $displayParts['text_btn'] = (string) '0'; $displayParts['pview_lnk'] = (string) '0'; } elseif ($this->__get('is_count') || $this->__get('is_analyse') || $this->__get('is_maint') || $this->__get('is_explain')) { // 2.1 Statement is a "SELECT COUNT", a // "CHECK/ANALYZE/REPAIR/OPTIMIZE", an "EXPLAIN" one or // contains a "PROC ANALYSE" part $displayParts['edit_lnk'] = self::NO_EDIT_OR_DELETE; // no edit link $displayParts['del_lnk'] = self::NO_EDIT_OR_DELETE; // no delete link $displayParts['sort_lnk'] = (string) '0'; $displayParts['nav_bar'] = (string) '0'; $displayParts['ins_row'] = (string) '0'; $displayParts['bkm_form'] = (string) '1'; if ($this->__get('is_maint')) { $displayParts['text_btn'] = (string) '1'; } else { $displayParts['text_btn'] = (string) '0'; } $displayParts['pview_lnk'] = (string) '1'; } elseif ($this->__get('is_show')) { // 2.2 Statement is a "SHOW..." /** * 2.2.1 * @todo defines edit/delete links depending on show statement */ preg_match('@^SHOW[[:space:]]+(VARIABLES|(FULL[[:space:]]+)?' . 'PROCESSLIST|STATUS|TABLE|GRANTS|CREATE|LOGS|DATABASES|FIELDS' . ')@i', $this->__get('sql_query'), $which); $bIsProcessList = isset($which[1]); if ($bIsProcessList) { $str = ' ' . strtoupper($which[1]); $bIsProcessList = $bIsProcessList && strpos($str, 'PROCESSLIST') > 0; } if ($bIsProcessList) { // no edit link $displayParts['edit_lnk'] = self::NO_EDIT_OR_DELETE; // "kill process" type edit link $displayParts['del_lnk'] = self::KILL_PROCESS; } else { // Default case -> no links // no edit link $displayParts['edit_lnk'] = self::NO_EDIT_OR_DELETE; // no delete link $displayParts['del_lnk'] = self::NO_EDIT_OR_DELETE; } unset($bIsProcessList); // 2.2.2 Other settings $displayParts['sort_lnk'] = (string) '0'; $displayParts['nav_bar'] = (string) '0'; $displayParts['ins_row'] = (string) '0'; $displayParts['bkm_form'] = (string) '1'; $displayParts['text_btn'] = (string) '1'; $displayParts['pview_lnk'] = (string) '1'; } else { // 2.3 Other statements (ie "SELECT" ones) -> updates // $displayParts['edit_lnk'], $displayParts['del_lnk'] and // $displayParts['text_btn'] (keeps other default values) $prev_table = ''; $displayParts['text_btn'] = (string) '1'; for ($i = 0; $i < $this->__get('fields_cnt'); $i++) { $is_link = $displayParts['edit_lnk'] != self::NO_EDIT_OR_DELETE || $displayParts['del_lnk'] != self::NO_EDIT_OR_DELETE || $displayParts['sort_lnk'] != '0' || $displayParts['ins_row'] != '0'; // 2.3.2 Displays edit/delete/sort/insert links? if ($is_link && $prev_table != '' && $fields_meta[$i]->table != '' && $fields_meta[$i]->table != $prev_table) { // don't display links $displayParts['edit_lnk'] = self::NO_EDIT_OR_DELETE; $displayParts['del_lnk'] = self::NO_EDIT_OR_DELETE; /** * @todo May be problematic with same field names * in two joined table. */ // $displayParts['sort_lnk'] = (string) '0'; $displayParts['ins_row'] = (string) '0'; if ($displayParts['text_btn'] == '1') { break; } } // end if (2.3.2) // 2.3.3 Always display print view link $displayParts['pview_lnk'] = (string) '1'; if ($fields_meta[$i]->table != '') { $prev_table = $fields_meta[$i]->table; } } // end for } // end if..elseif...else (2.1 -> 2.3) // 3. Gets the total number of rows if it is unknown if (isset($unlim_num_rows) && $unlim_num_rows != '') { $the_total = $unlim_num_rows; } elseif (($displayParts['nav_bar'] == '1' || $displayParts['sort_lnk'] == '1') && (mb_strlen($db) && !empty($table))) { $the_total = PMA_Table::countRecords($db, $table); } // if for COUNT query, number of rows returned more than 1 (may be being used GROUP BY) if ($this->__get('is_count') && isset($num_rows) && $num_rows > 1) { $displayParts['nav_bar'] = (string) '1'; $displayParts['sort_lnk'] = (string) '1'; } // 4. If navigation bar or sorting fields names URLs should be // displayed but there is only one row, change these settings to // false if ($displayParts['nav_bar'] == '1' || $displayParts['sort_lnk'] == '1') { // - Do not display sort links if less than 2 rows. // - For a VIEW we (probably) did not count the number of rows // so don't test this number here, it would remove the possibility // of sorting VIEW results. if (isset($unlim_num_rows) && $unlim_num_rows < 2 && !PMA_Table::isView($db, $table)) { $displayParts['sort_lnk'] = (string) '0'; } } // end if (3) return $displayParts; }
/** * returns array with tables of given db with extended information and grouped * * @param string $db name of db * @param string $tables name of tables * @param integer $limit_offset list offset * @param int|bool $limit_count max tables to return * * @return array (recursive) grouped table list */ function PMA_getTableList($db, $tables = null, $limit_offset = 0, $limit_count = false) { $sep = $GLOBALS['cfg']['LeftFrameTableSeparator']; if (null === $tables) { $tables = PMA_DBI_get_tables_full($db, false, false, null, $limit_offset, $limit_count); if ($GLOBALS['cfg']['NaturalOrder']) { uksort($tables, 'strnatcasecmp'); } } if (count($tables) < 1) { return $tables; } $default = array('Name' => '', 'Rows' => 0, 'Comment' => '', 'disp_name' => ''); $table_groups = array(); // for blobstreaming - list of blobstreaming tables // load PMA configuration $PMA_Config = $GLOBALS['PMA_Config']; foreach ($tables as $table_name => $table) { // if BS tables exist if (PMA_BS_IsHiddenTable($table_name)) { continue; } // check for correct row count if (null === $table['Rows']) { // Do not check exact row count here, // if row count is invalid possibly the table is defect // and this would break left frame; // but we can check row count if this is a view or the // information_schema database // since PMA_Table::countRecords() returns a limited row count // in this case. // set this because PMA_Table::countRecords() can use it $tbl_is_view = $table['TABLE_TYPE'] == 'VIEW'; if ($tbl_is_view || PMA_is_system_schema($db)) { $table['Rows'] = PMA_Table::countRecords($db, $table['Name'], false, true); } } // in $group we save the reference to the place in $table_groups // where to store the table info if ($GLOBALS['cfg']['LeftFrameDBTree'] && $sep && strstr($table_name, $sep)) { $parts = explode($sep, $table_name); $group =& $table_groups; $i = 0; $group_name_full = ''; $parts_cnt = count($parts) - 1; while ($i < $parts_cnt && $i < $GLOBALS['cfg']['LeftFrameTableLevel']) { $group_name = $parts[$i] . $sep; $group_name_full .= $group_name; if (!isset($group[$group_name])) { $group[$group_name] = array(); $group[$group_name]['is' . $sep . 'group'] = true; $group[$group_name]['tab' . $sep . 'count'] = 1; $group[$group_name]['tab' . $sep . 'group'] = $group_name_full; } elseif (!isset($group[$group_name]['is' . $sep . 'group'])) { $table = $group[$group_name]; $group[$group_name] = array(); $group[$group_name][$group_name] = $table; unset($table); $group[$group_name]['is' . $sep . 'group'] = true; $group[$group_name]['tab' . $sep . 'count'] = 1; $group[$group_name]['tab' . $sep . 'group'] = $group_name_full; } else { $group[$group_name]['tab' . $sep . 'count']++; } $group =& $group[$group_name]; $i++; } } else { if (!isset($table_groups[$table_name])) { $table_groups[$table_name] = array(); } $group =& $table_groups; } if ($GLOBALS['cfg']['ShowTooltipAliasTB'] && $GLOBALS['cfg']['ShowTooltipAliasTB'] !== 'nested' && $table['Comment'] && $table['Comment'] != 'VIEW') { // switch tooltip and name $table['disp_name'] = $table['Comment']; $table['Comment'] = $table['Name']; } else { $table['disp_name'] = $table['Name']; } $group[$table_name] = array_merge($default, $table); } return $table_groups; }
/** * Defines the parts to display for the results of a SQL query * * @param array $displayParts the parts to display (see a few * lines above for explanations) * @param integer &$the_total the total number of rows returned by the SQL * query without any programmatically appended * LIMIT clause * (just a copy of $unlim_num_rows if it exists, * elsecomputed inside this function) * * @return array an array with explicit indexes for all the display * elements * * @access private * * @see getTable() */ private function _setDisplayParts($displayParts, &$the_total) { // 1. Following variables are needed for use in isset/empty or // use with array indexes or safe use in foreach $db = $this->__get('db'); $table = $this->__get('table'); $unlim_num_rows = $this->__get('unlim_num_rows'); $num_rows = $this->__get('num_rows'); $printview = $this->__get('printview'); // 2. Updates the display parts if ($printview == '1') { $displayParts = $this->_setDisplayPartsForPrintView($displayParts); } elseif ($this->__get('is_count') || $this->__get('is_analyse') || $this->__get('is_maint') || $this->__get('is_explain')) { $displayParts = $this->_setDisplayPartsForNonData($displayParts); } elseif ($this->__get('is_show')) { $displayParts = $this->_setDisplayPartsForShow($displayParts); } else { $displayParts = $this->_setDisplayPartsForSelect($displayParts); } // end if..elseif...else // 3. Gets the total number of rows if it is unknown if (isset($unlim_num_rows) && $unlim_num_rows != '') { $the_total = $unlim_num_rows; } elseif (($displayParts['nav_bar'] == '1' || $displayParts['sort_lnk'] == '1') && (mb_strlen($db) && !empty($table))) { $the_total = PMA_Table::countRecords($db, $table); } // if for COUNT query, number of rows returned more than 1 // (may be being used GROUP BY) if ($this->__get('is_count') && isset($num_rows) && $num_rows > 1) { $displayParts['nav_bar'] = (string) '1'; $displayParts['sort_lnk'] = (string) '1'; } // 4. If navigation bar or sorting fields names URLs should be // displayed but there is only one row, change these settings to // false if ($displayParts['nav_bar'] == '1' || $displayParts['sort_lnk'] == '1') { // - Do not display sort links if less than 2 rows. // - For a VIEW we (probably) did not count the number of rows // so don't test this number here, it would remove the possibility // of sorting VIEW results. if (isset($unlim_num_rows) && $unlim_num_rows < 2 && !PMA_Table::isView($db, $table)) { $displayParts['sort_lnk'] = (string) '0'; } } // end if (3) return $displayParts; }
} else { $col_cand = $sg; // None of the candidates where in a where-clause } } // If our array of candidates has more than one member we'll just // find the smallest table. // Of course the actual query would be faster if we check for // the Criteria which gives the smallest result set in its table, // but it would take too much time to check this if (count($col_cand) > 1) { // Of course we only want to check each table once $checked_tables = $col_cand; foreach ($col_cand as $tab) { if ($checked_tables[$tab] != 1) { $tsize[$tab] = PMA_Table::countRecords($db, $tab, true, false); $checked_tables[$tab] = 1; } $csize[$tab] = $tsize[$tab]; } asort($csize); reset($csize); $master = key($csize); // Smallest } else { reset($col_cand); $master = current($col_cand); // Only one single candidate } } // end if (exactly one where clause)
// Merge or BerkleyDB table: Only row count is accurate. if ($is_show_stats) { $formatted_size = ' - '; $unit = ''; } break; // for a view, the ENGINE is sometimes reported as null, // or on some servers it's reported as "SYSTEM VIEW" // for a view, the ENGINE is sometimes reported as null, // or on some servers it's reported as "SYSTEM VIEW" case null: case 'SYSTEM VIEW': // if table is broken, Engine is reported as null, so one more test if ($each_table['TABLE_TYPE'] == 'VIEW') { // countRecords() takes care of $cfg['MaxExactCountViews'] $each_table['TABLE_ROWS'] = PMA_Table::countRecords($db, $each_table['TABLE_NAME'], $force_exact = true, $is_view = true); $table_is_view = true; } break; default: // Unknown table type. if ($is_show_stats) { $formatted_size = 'unknown'; $unit = ''; } } // end switch if (!PMA_Table::isMerge($db, $each_table['TABLE_NAME'])) { $sum_entries += $each_table['TABLE_ROWS']; } if (isset($each_table['Collation'])) {
*/ // lem9: we always show the foreign field in the drop-down; if a display // field is defined, we show it besides the foreign field $foreign_link = false; if ($foreigners && isset($foreigners[$field])) { $foreigner = $foreigners[$field]; $foreign_db = $foreigner['foreign_db']; $foreign_table = $foreigner['foreign_table']; $foreign_field = $foreigner['foreign_field']; // Count number of rows in the foreign table. Currently we do // not use a drop-down if more than 200 rows in the foreign table, // for speed reasons and because we need a better interface for this. // // We could also do the SELECT anyway, with a LIMIT, and ensure that // the current value of the field is one of the choices. $the_total = PMA_Table::countRecords($foreign_db, $foreign_table, TRUE); if (isset($override_total) && $override_total == true || $the_total < $cfg['ForeignKeyMaxLimit']) { // foreign_display can be FALSE if no display field defined: $foreign_display = PMA_getDisplayField($foreign_db, $foreign_table); $f_query_main = 'SELECT ' . PMA_backquote($foreign_field) . ($foreign_display == FALSE ? '' : ', ' . PMA_backquote($foreign_display)); $f_query_from = ' FROM ' . PMA_backquote($foreign_db) . '.' . PMA_backquote($foreign_table); $f_query_filter = empty($foreign_filter) ? '' : ' WHERE ' . PMA_backquote($foreign_field) . ' LIKE "%' . PMA_sqlAddslashes($foreign_filter, TRUE) . '%"' . ($foreign_display == FALSE ? '' : ' OR ' . PMA_backquote($foreign_display) . ' LIKE "%' . PMA_sqlAddslashes($foreign_filter, TRUE) . '%"'); $f_query_order = $foreign_display == FALSE ? '' : ' ORDER BY ' . PMA_backquote($foreign_table) . '.' . PMA_backquote($foreign_display); $f_query_limit = isset($foreign_limit) ? $foreign_limit : ''; if (!empty($foreign_filter)) { $res = PMA_DBI_query('SELECT COUNT(*)' . $f_query_from . $f_query_filter); if ($res) { $the_total = PMA_DBI_fetch_value($res); @PMA_DBI_free_result($res); } else { $the_total = 0;
include_once './libraries/transformations/' . $include_file; if (function_exists('PMA_transformation_' . $transformfunction_name)) { $transform_function = 'PMA_transformation_' . $transformfunction_name; $transform_options = PMA_transformation_getOptions(isset($transformation['transformation_options']) ? $transformation['transformation_options'] : ''); $transform_options['wrapper_link'] = PMA_generate_common_url($_url_params); } } $extra_data['transformations'][$cell_index] = $transform_function($column_data, $transform_options); } } // end of loop for each transformation cell } // end of loop for each $mime_map } /**Get the total row count of the table*/ $extra_data['row_count'] = PMA_Table::countRecords($_REQUEST['db'], $_REQUEST['table']); $extra_data['sql_query'] = PMA_showMessage($message, $GLOBALS['display_query']); PMA_ajaxResponse($message, $message->isSuccess(), $extra_data); } if (isset($return_to_sql_query)) { $disp_query = $GLOBALS['sql_query']; $disp_message = $message; unset($message); $GLOBALS['sql_query'] = $return_to_sql_query; } $GLOBALS['js_include'][] = 'tbl_change.js'; // in case we call sql.php which needs those: $GLOBALS['js_include'][] = 'jquery/jquery-ui-1.8.16.custom.js'; $active_page = $goto_include; /** * If user asked for "and then Insert another new row" we have to remove
/** * returns array with tables of given db with extended information and grouped * * @param string $db name of db * @param string $tables name of tables * @param integer $limit_offset list offset * @param int|bool $limit_count max tables to return * * @return array (recursive) grouped table list */ public static function getTableList($db, $tables = null, $limit_offset = 0, $limit_count = false) { $sep = $GLOBALS['cfg']['NavigationTreeTableSeparator']; if ($tables === null) { $tables = $GLOBALS['dbi']->getTablesFull($db, false, false, null, $limit_offset, $limit_count); if ($GLOBALS['cfg']['NaturalOrder']) { uksort($tables, 'strnatcasecmp'); } } if (count($tables) < 1) { return $tables; } $default = array('Name' => '', 'Rows' => 0, 'Comment' => '', 'disp_name' => ''); $table_groups = array(); foreach ($tables as $table_name => $table) { // check for correct row count if ($table['Rows'] === null) { // Do not check exact row count here, // if row count is invalid possibly the table is defect // and this would break left frame; // but we can check row count if this is a view or the // information_schema database // since PMA_Table::countRecords() returns a limited row count // in this case. // set this because PMA_Table::countRecords() can use it $tbl_is_view = $table['TABLE_TYPE'] == 'VIEW'; if ($tbl_is_view || $GLOBALS['dbi']->isSystemSchema($db)) { $table['Rows'] = PMA_Table::countRecords($db, $table['Name'], false, true); } } // in $group we save the reference to the place in $table_groups // where to store the table info if ($GLOBALS['cfg']['NavigationTreeEnableGrouping'] && $sep && strstr($table_name, $sep)) { $parts = explode($sep, $table_name); $group =& $table_groups; $i = 0; $group_name_full = ''; $parts_cnt = count($parts) - 1; while ($i < $parts_cnt && $i < $GLOBALS['cfg']['NavigationTreeTableLevel']) { $group_name = $parts[$i] . $sep; $group_name_full .= $group_name; if (!isset($group[$group_name])) { $group[$group_name] = array(); $group[$group_name]['is' . $sep . 'group'] = true; $group[$group_name]['tab' . $sep . 'count'] = 1; $group[$group_name]['tab' . $sep . 'group'] = $group_name_full; } elseif (!isset($group[$group_name]['is' . $sep . 'group'])) { $table = $group[$group_name]; $group[$group_name] = array(); $group[$group_name][$group_name] = $table; unset($table); $group[$group_name]['is' . $sep . 'group'] = true; $group[$group_name]['tab' . $sep . 'count'] = 1; $group[$group_name]['tab' . $sep . 'group'] = $group_name_full; } else { $group[$group_name]['tab' . $sep . 'count']++; } $group =& $group[$group_name]; $i++; } } else { if (!isset($table_groups[$table_name])) { $table_groups[$table_name] = array(); } $group =& $table_groups; } $table['disp_name'] = $table['Name']; $group[$table_name] = array_merge($default, $table); } return $table_groups; }
/** * Provides the main table to form the LEFT JOIN clause * * @param array $all_tables Tables involved in the search * @param array $all_columns Columns involved in the search * @param array $where_clause_columns Columns having criteria where clause * @param array $where_clause_tables Tables having criteria where clause * * @return string table name */ private function _getMasterTable($all_tables, $all_columns, $where_clause_columns, $where_clause_tables) { if (count($where_clause_tables) == 1) { // If there is exactly one column that has a decent where-clause // we will just use this $master = key($where_clause_tables); return $master; } // Now let's find out which of the tables has an index // (When the control user is the same as the normal user // because he is using one of his databases as pmadb, // the last db selected is not always the one where we need to work) $candidate_columns = $this->_getLeftJoinColumnCandidates($all_tables, $all_columns, $where_clause_columns); // Generally, we need to display all the rows of foreign (referenced) // table, whether they have any matching row in child table or not. // So we select candidate tables which are foreign tables. $foreign_tables = array(); foreach ($candidate_columns as $one_table) { $foreigners = PMA_getForeigners($this->_db, $one_table); foreach ($foreigners as $key => $foreigner) { if ($key != 'foreign_keys_data') { if (in_array($foreigner['foreign_table'], $candidate_columns)) { $foreign_tables[$foreigner['foreign_table']] = $foreigner['foreign_table']; } continue; } foreach ($foreigner as $one_key) { if (in_array($one_key['ref_table_name'], $candidate_columns)) { $foreign_tables[$one_key['ref_table_name']] = $one_key['ref_table_name']; } } } } if (count($foreign_tables)) { $candidate_columns = $foreign_tables; } // If our array of candidates has more than one member we'll just // find the smallest table. // Of course the actual query would be faster if we check for // the Criteria which gives the smallest result set in its table, // but it would take too much time to check this if (!(count($candidate_columns) > 1)) { reset($candidate_columns); $master = current($candidate_columns); // Only one single candidate return $master; } // Of course we only want to check each table once $checked_tables = $candidate_columns; $tsize = array(); $csize = array(); foreach ($candidate_columns as $table) { if ($checked_tables[$table] != 1) { $tsize[$table] = PMA_Table::countRecords($this->_db, $table, false); $checked_tables[$table] = 1; } $csize[$table] = $tsize[$table]; } arsort($csize); reset($csize); $master = key($csize); // Largest return $master; }
/** * Defines the display mode to use for the results of a SQL query * * It uses a synthetic string that contains all the required informations. * In this string: * - the first two characters stand for the action to do while * clicking on the "edit" link (e.g. 'ur' for update a row, 'nn' for no * edit link...); * - the next two characters stand for the action to do while * clicking on the "delete" link (e.g. 'kp' for kill a process, 'nn' for * no delete link...); * - the next characters are boolean values (1/0) and respectively stand * for sorting links, navigation bar, "insert a new row" link, the * bookmark feature, the expand/collapse text/blob fields button and * the "display printable view" option. * Of course '0'/'1' means the feature won't/will be enabled. * * @param string &$the_disp_mode the synthetic value for display_mode (see a few * lines above for explanations) * @param integer &$the_total the total number of rows returned by the SQL * query without any programmatically appended * LIMIT clause * (just a copy of $unlim_num_rows if it exists, * elsecomputed inside this function) * * @return array an array with explicit indexes for all the display * elements * * @access private * * @see getTable() */ private function _setDisplayMode(&$the_disp_mode, &$the_total) { // Following variables are needed for use in isset/empty or // use with array indexes or safe use in foreach $db = $this->__get('_db'); $table = $this->__get('_table'); $unlim_num_rows = $this->__get('_unlim_num_rows'); $fields_meta = $this->__get('_fields_meta'); $printview = $this->__get('_printview'); // 1. Initializes the $do_display array $do_display = array(); $do_display['edit_lnk'] = $the_disp_mode[0] . $the_disp_mode[1]; $do_display['del_lnk'] = $the_disp_mode[2] . $the_disp_mode[3]; $do_display['sort_lnk'] = (string) $the_disp_mode[4]; $do_display['nav_bar'] = (string) $the_disp_mode[5]; $do_display['ins_row'] = (string) $the_disp_mode[6]; $do_display['bkm_form'] = (string) $the_disp_mode[7]; $do_display['text_btn'] = (string) $the_disp_mode[8]; $do_display['pview_lnk'] = (string) $the_disp_mode[9]; // 2. Display mode is not "false for all elements" -> updates the // display mode if ($the_disp_mode != 'nnnn000000') { if (isset($printview) && $printview == '1') { // 2.0 Print view -> set all elements to false! $do_display['edit_lnk'] = self::NO_EDIT_OR_DELETE; // no edit link $do_display['del_lnk'] = self::NO_EDIT_OR_DELETE; // no delete link $do_display['sort_lnk'] = (string) '0'; $do_display['nav_bar'] = (string) '0'; $do_display['ins_row'] = (string) '0'; $do_display['bkm_form'] = (string) '0'; $do_display['text_btn'] = (string) '0'; $do_display['pview_lnk'] = (string) '0'; } elseif ($this->__get('_is_count') || $this->__get('_is_analyse') || $this->__get('_is_maint') || $this->__get('_is_explain')) { // 2.1 Statement is a "SELECT COUNT", a // "CHECK/ANALYZE/REPAIR/OPTIMIZE", an "EXPLAIN" one or // contains a "PROC ANALYSE" part $do_display['edit_lnk'] = self::NO_EDIT_OR_DELETE; // no edit link $do_display['del_lnk'] = self::NO_EDIT_OR_DELETE; // no delete link $do_display['sort_lnk'] = (string) '0'; $do_display['nav_bar'] = (string) '0'; $do_display['ins_row'] = (string) '0'; $do_display['bkm_form'] = (string) '1'; if ($this->__get('_is_maint')) { $do_display['text_btn'] = (string) '1'; } else { $do_display['text_btn'] = (string) '0'; } $do_display['pview_lnk'] = (string) '1'; } elseif ($this->__get('_is_show')) { // 2.2 Statement is a "SHOW..." /** * 2.2.1 * @todo defines edit/delete links depending on show statement */ $tmp = preg_match('@^SHOW[[:space:]]+(VARIABLES|(FULL[[:space:]]+)?' . 'PROCESSLIST|STATUS|TABLE|GRANTS|CREATE|LOGS|DATABASES|FIELDS' . ')@i', $this->__get('_sql_query'), $which); if (isset($which[1]) && strpos(' ' . strtoupper($which[1]), 'PROCESSLIST') > 0) { // no edit link $do_display['edit_lnk'] = self::NO_EDIT_OR_DELETE; // "kill process" type edit link $do_display['del_lnk'] = self::KILL_PROCESS; } else { // Default case -> no links // no edit link $do_display['edit_lnk'] = self::NO_EDIT_OR_DELETE; // no delete link $do_display['del_lnk'] = self::NO_EDIT_OR_DELETE; } // 2.2.2 Other settings $do_display['sort_lnk'] = (string) '0'; $do_display['nav_bar'] = (string) '0'; $do_display['ins_row'] = (string) '0'; $do_display['bkm_form'] = (string) '1'; $do_display['text_btn'] = (string) '1'; $do_display['pview_lnk'] = (string) '1'; } else { // 2.3 Other statements (ie "SELECT" ones) -> updates // $do_display['edit_lnk'], $do_display['del_lnk'] and // $do_display['text_btn'] (keeps other default values) $prev_table = $fields_meta[0]->table; $do_display['text_btn'] = (string) '1'; for ($i = 0; $i < $this->__get('_fields_cnt'); $i++) { $is_link = $do_display['edit_lnk'] != self::NO_EDIT_OR_DELETE || $do_display['del_lnk'] != self::NO_EDIT_OR_DELETE || $do_display['sort_lnk'] != '0' || $do_display['ins_row'] != '0'; // 2.3.2 Displays edit/delete/sort/insert links? if ($is_link && ($fields_meta[$i]->table == '' || $fields_meta[$i]->table != $prev_table)) { // don't display links $do_display['edit_lnk'] = self::NO_EDIT_OR_DELETE; $do_display['del_lnk'] = self::NO_EDIT_OR_DELETE; /** * @todo May be problematic with same field names * in two joined table. */ // $do_display['sort_lnk'] = (string) '0'; $do_display['ins_row'] = (string) '0'; if ($do_display['text_btn'] == '1') { break; } } // end if (2.3.2) // 2.3.3 Always display print view link $do_display['pview_lnk'] = (string) '1'; $prev_table = $fields_meta[$i]->table; } // end for } // end if..elseif...else (2.1 -> 2.3) } // end if (2) // 3. Gets the total number of rows if it is unknown if (isset($unlim_num_rows) && $unlim_num_rows != '') { $the_total = $unlim_num_rows; } elseif (($do_display['nav_bar'] == '1' || $do_display['sort_lnk'] == '1') && (strlen($db) && !empty($table))) { $the_total = PMA_Table::countRecords($db, $table); } // 4. If navigation bar or sorting fields names URLs should be // displayed but there is only one row, change these settings to // false if ($do_display['nav_bar'] == '1' || $do_display['sort_lnk'] == '1') { // - Do not display sort links if less than 2 rows. // - For a VIEW we (probably) did not count the number of rows // so don't test this number here, it would remove the possibility // of sorting VIEW results. if (isset($unlim_num_rows) && $unlim_num_rows < 2 && !PMA_Table::isView($db, $table)) { // force display of navbar for vertical/horizontal display-choice. // $do_display['nav_bar'] = (string) '0'; $do_display['sort_lnk'] = (string) '0'; } } // end if (3) // 5. Updates the synthetic var $the_disp_mode = join('', $do_display); return $do_display; }
/** * Generate table html when SQL statement have multiple queries * which return displayable results * * @param PMA_DisplayResults $displayResultsObject object * @param string $db database name * @param array $sql_data information about SQL statement * @param string $goto URL to go back in case of errors * @param string $pmaThemeImage path for theme images directory * @param string $text_dir text direction * @param string $printview whether printview is enabled * @param string $url_query URL query * @param array $disp_mode the display mode * @param string $sql_limit_to_append limit clause * @param bool $editable whether result set is editable * * @return string $table_html html content */ function getTableHtmlForMultipleQueries($displayResultsObject, $db, $sql_data, $goto, $pmaThemeImage, $text_dir, $printview, $url_query, $disp_mode, $sql_limit_to_append, $editable) { $table_html = ''; $tables_array = PMA_DBI_get_tables($db); $databases_array = PMA_DBI_get_databases_full(); $multi_sql = implode(";", $sql_data['valid_sql']); $querytime_before = array_sum(explode(' ', microtime())); // Assignment for variable is not needed since the results are // looiping using the connection @PMA_DBI_try_multi_query($multi_sql); $querytime_after = array_sum(explode(' ', microtime())); $querytime = $querytime_after - $querytime_before; $sql_no = 0; do { $analyzed_sql = array(); $is_affected = false; $result = PMA_DBI_store_result(); $fields_meta = $result !== false ? PMA_DBI_get_fields_meta($result) : array(); $fields_cnt = count($fields_meta); // Initialize needed params related to each query in multiquery statement if (isset($sql_data['valid_sql'][$sql_no])) { // 'Use' query can change the database if (stripos($sql_data['valid_sql'][$sql_no], "use ")) { $db = PMA_getNewDatabase($sql_data['valid_sql'][$sql_no], $databases_array); } $parsed_sql = PMA_SQP_parse($sql_data['valid_sql'][$sql_no]); $table = PMA_getTableNameBySQL($sql_data['valid_sql'][$sql_no], $tables_array); $analyzed_sql = PMA_SQP_analyze($parsed_sql); $is_select = isset($analyzed_sql[0]['queryflags']['select_from']); $unlim_num_rows = PMA_Table::countRecords($db, $table, true); $showtable = PMA_Table::sGetStatusInfo($db, $table, null, true); $url_query = PMA_generate_common_url($db, $table); list($is_group, $is_func, $is_count, $is_export, $is_analyse, $is_explain, $is_delete, $is_affected, $is_insert, $is_replace, $is_show, $is_maint) = PMA_getDisplayPropertyParams($sql_data['valid_sql'][$sql_no], $is_select); // Handle remembered sorting order, only for single table query if ($GLOBALS['cfg']['RememberSorting'] && !($is_count || $is_export || $is_func || $is_analyse) && isset($analyzed_sql[0]['select_expr']) && count($analyzed_sql[0]['select_expr']) == 0 && isset($analyzed_sql[0]['queryflags']['select_from']) && count($analyzed_sql[0]['table_ref']) == 1) { PMA_handleSortOrder($db, $table, $analyzed_sql, $sql_data['valid_sql'][$sql_no]); } // Do append a "LIMIT" clause? if ($_SESSION['tmp_user_values']['max_rows'] != 'all' && !($is_count || $is_export || $is_func || $is_analyse) && isset($analyzed_sql[0]['queryflags']['select_from']) && !isset($analyzed_sql[0]['queryflags']['offset']) && empty($analyzed_sql[0]['limit_clause'])) { $sql_limit_to_append = ' LIMIT ' . $_SESSION['tmp_user_values']['pos'] . ', ' . $_SESSION['tmp_user_values']['max_rows'] . " "; $sql_data['valid_sql'][$sql_no] = PMA_getSqlWithLimitClause($sql_data['valid_sql'][$sql_no], $analyzed_sql, $sql_limit_to_append); } // Set the needed properties related to executing sql query $displayResultsObject->__set('db', $db); $displayResultsObject->__set('table', $table); $displayResultsObject->__set('goto', $goto); } if (!$is_affected) { $num_rows = $result ? @PMA_DBI_num_rows($result) : 0; } elseif (!isset($num_rows)) { $num_rows = @PMA_DBI_affected_rows(); } if (isset($sql_data['valid_sql'][$sql_no])) { $displayResultsObject->__set('sql_query', $sql_data['valid_sql'][$sql_no]); $displayResultsObject->setProperties($unlim_num_rows, $fields_meta, $is_count, $is_export, $is_func, $is_analyse, $num_rows, $fields_cnt, $querytime, $pmaThemeImage, $text_dir, $is_maint, $is_explain, $is_show, $showtable, $printview, $url_query, $editable); } if ($num_rows == 0) { continue; } // With multiple results, operations are limied $disp_mode = 'nnnn000000'; $is_limited_display = true; // Collect the tables $table_html .= $displayResultsObject->getTable($result, $disp_mode, $analyzed_sql, $is_limited_display); // Free the result to save the memory PMA_DBI_free_result($result); $sql_no++; } while (PMA_DBI_more_results() && PMA_DBI_next_result()); return $table_html; }
/** * returns array with tables of given db with extended infomation and grouped * * @uses $GLOBALS['cfg']['LeftFrameTableSeparator'] * @uses $GLOBALS['cfg']['LeftFrameTableLevel'] * @uses $GLOBALS['cfg']['ShowTooltipAliasTB'] * @uses $GLOBALS['cfg']['NaturalOrder'] * @uses PMA_DBI_fetch_result() * @uses PMA_backquote() * @uses count() * @uses array_merge * @uses uksort() * @uses strstr() * @uses explode() * @param string $db name of db * return array (rekursive) grouped table list */ function PMA_getTableList($db, $tables = null) { $sep = $GLOBALS['cfg']['LeftFrameTableSeparator']; if (null === $tables) { $tables = PMA_DBI_get_tables_full($db); if ($GLOBALS['cfg']['NaturalOrder']) { uksort($tables, 'strnatcasecmp'); } } if (count($tables) < 1) { return $tables; } $default = array('Name' => '', 'Rows' => 0, 'Comment' => '', 'disp_name' => ''); $table_groups = array(); foreach ($tables as $table_name => $table) { // check for correct row count if (null === $table['Rows']) { // Do not check exact row count here, // if row count is invalid possibly the table is defect // and this would break left frame; // but we can check row count if this is a view, // since PMA_Table::countRecords() returns a limited row count // in this case. // set this because PMA_Table::countRecords() can use it $tbl_is_view = PMA_Table::isView($db, $table['Name']); if ($tbl_is_view) { $table['Rows'] = PMA_Table::countRecords($db, $table['Name'], $return = true); } } // in $group we save the reference to the place in $table_groups // where to store the table info if ($GLOBALS['cfg']['LeftFrameDBTree'] && $sep && strstr($table_name, $sep)) { $parts = explode($sep, $table_name); $group =& $table_groups; $i = 0; $group_name_full = ''; while ($i < count($parts) - 1 && $i < $GLOBALS['cfg']['LeftFrameTableLevel']) { $group_name = $parts[$i] . $sep; $group_name_full .= $group_name; if (!isset($group[$group_name])) { $group[$group_name] = array(); $group[$group_name]['is' . $sep . 'group'] = true; $group[$group_name]['tab' . $sep . 'count'] = 1; $group[$group_name]['tab' . $sep . 'group'] = $group_name_full; } elseif (!isset($group[$group_name]['is' . $sep . 'group'])) { $table = $group[$group_name]; $group[$group_name] = array(); $group[$group_name][$group_name] = $table; unset($table); $group[$group_name]['is' . $sep . 'group'] = true; $group[$group_name]['tab' . $sep . 'count'] = 1; $group[$group_name]['tab' . $sep . 'group'] = $group_name_full; } else { $group[$group_name]['tab' . $sep . 'count']++; } $group =& $group[$group_name]; $i++; } } else { if (!isset($table_groups[$table_name])) { $table_groups[$table_name] = array(); } $group =& $table_groups; } if ($GLOBALS['cfg']['ShowTooltipAliasTB'] && $GLOBALS['cfg']['ShowTooltipAliasTB'] !== 'nested') { // switch tooltip and name $table['Comment'] = $table['Name']; $table['disp_name'] = $table['Comment']; } else { $table['disp_name'] = $table['Name']; } $group[$table_name] = array_merge($default, $table); } return $table_groups; }
$tbl_type = $GLOBALS['strView']; $show_comment = null; } else { $tbl_is_view = false; $tbl_type = isset($showtable['Type']) ? strtoupper($showtable['Type']) : ''; // a new comment could be coming from tbl_operations.php // and we want to show it in the header if (isset($submitcomment) && isset($comment)) { $show_comment = $comment; } else { $show_comment = isset($showtable['Comment']) ? $showtable['Comment'] : ''; } } $tbl_collation = empty($showtable['Collation']) ? '' : $showtable['Collation']; if (null === $showtable['Rows']) { $showtable['Rows'] = PMA_Table::countRecords($GLOBALS['db'], $showtable['Name'], true, true); } $table_info_num_rows = isset($showtable['Rows']) ? $showtable['Rows'] : 0; $auto_increment = isset($showtable['Auto_increment']) ? $showtable['Auto_increment'] : ''; $create_options = isset($showtable['Create_options']) ? explode(' ', $showtable['Create_options']) : array(); // export create options by its name as variables into gloabel namespace // f.e. pack_keys=1 becomes available as $pack_keys with value of '1' unset($pack_keys); foreach ($create_options as $each_create_option) { $each_create_option = explode('=', $each_create_option); if (isset($each_create_option[1])) { ${$each_create_option}[0] = $each_create_option[1]; } } // we need explicit DEFAULT value here (different from '0') $pack_keys = !isset($pack_keys) || strlen($pack_keys) == 0 ? 'DEFAULT' : $pack_keys;
echo __('Rows:'); ?> </h3> <ul> <li> <?php if (isset($_GET['allrows']) && $_GET['allrows'] == 1) { echo '<input type="radio" name="allrows" value="0" id="radio_allrows_0" />'; } else { echo '<input type="radio" name="allrows" value="0" id="radio_allrows_0" checked="checked" />'; } echo '<label for ="radio_allrows_0">' . __('Dump some row(s)') . '</label>'; ?> <ul> <li><label for="limit_to"><?php echo __('Number of rows:') . '</label> <input type="text" id="limit_to" name="limit_to" size="5" value="' . (isset($_GET['limit_to']) ? htmlspecialchars($_GET['limit_to']) : (isset($unlim_num_rows) ? $unlim_num_rows : PMA_Table::countRecords($db, $table))) . '" onfocus="this.select()" />'; ?> </li> <li><label for="limit_from"><?php echo __('Row to begin at:') . '</label> <input type="text" id="limit_from" name="limit_from" value="' . (isset($_GET['limit_from']) ? htmlspecialchars($_GET['limit_from']) : '0') . '" size="5" onfocus="this.select()" />'; ?> </li> </ul> </li> <li> <?php if (isset($_GET['allrows']) && $_GET['allrows'] == 0) { echo '<input type="radio" name="allrows" value="1" id="radio_allrows_1" />'; } else { echo '<input type="radio" name="allrows" value="1" id="radio_allrows_1" checked="checked" />'; }
/** * Prints Html For Export Options Rows * * @param String $db Selected DB * @param String $table Selected Table * @param String $unlim_num_rows Num of Rows * * @return string */ function PMA_getHtmlForExportOptionsRows($db, $table, $unlim_num_rows) { $html = '<div class="exportoptions" id="rows">'; $html .= '<h3>' . __('Rows:') . '</h3>'; $html .= '<ul>'; $html .= '<li>'; $html .= '<input type="radio" name="allrows" value="0" id="radio_allrows_0"'; if (isset($_GET['allrows']) && $_GET['allrows'] == 0) { $html .= ' checked="checked"'; } $html .= '/>'; $html .= '<label for ="radio_allrows_0">' . __('Dump some row(s)') . '</label>'; $html .= '<ul>'; $html .= '<li>'; $html .= '<label for="limit_to">' . __('Number of rows:') . '</label>'; $html .= '<input type="text" id="limit_to" name="limit_to" size="5" value="'; if (isset($_GET['limit_to'])) { $html .= htmlspecialchars($_GET['limit_to']); } elseif (!empty($unlim_num_rows)) { $html .= $unlim_num_rows; } else { $html .= PMA_Table::countRecords($db, $table); } $html .= '" onfocus="this.select()" />'; $html .= '</li>'; $html .= '<li>'; $html .= '<label for="limit_from">' . __('Row to begin at:') . '</label>'; $html .= '<input type="text" id="limit_from" name="limit_from" value="'; if (isset($_GET['limit_from'])) { $html .= htmlspecialchars($_GET['limit_from']); } else { $html .= '0'; } $html .= '" size="5" onfocus="this.select()" />'; $html .= '</li>'; $html .= '</ul>'; $html .= '</li>'; $html .= '<li>'; $html .= '<input type="radio" name="allrows" value="1" id="radio_allrows_1"'; if (!isset($_GET['allrows']) || $_GET['allrows'] == 1) { $html .= ' checked="checked"'; } $html .= '/>'; $html .= ' <label for="radio_allrows_1">' . __('Dump all rows') . '</label>'; $html .= '</li>'; $html .= '</ul>'; $html .= '</div>'; return $html; }
/** * Test for countRecords * * @return void */ public function testCountRecords() { $table = 'PMA_BookMark'; $db = 'PMA'; PMA_Table::$cache[$db][$table] = array('Comment' => "Comment222"); $return = PMA_Table::countRecords($db, $table, false, true); $expect = 20; $this->assertEquals($expect, $return); }
/** * Test for countRecords * * @return void */ public function testCountRecords() { $map = array(array('PMA.PMA_BookMark', null, array('Comment' => "Comment222", 'TABLE_TYPE' => "VIEW")), array('PMA.PMA_BookMark.TABLE_TYPE', null, 'VIEW')); $GLOBALS['dbi']->expects($this->any())->method('getCachedTableContent')->will($this->returnValueMap($map)); $table = 'PMA_BookMark'; $db = 'PMA'; $tableObj = new PMA_Table($table, $db); $return = $tableObj->countRecords(true); $expect = 20; $this->assertEquals($expect, $return); }
/** * Returns the table tabs as an array * * @return array Data for generating table tabs */ private function _getTableTabs() { $db_is_information_schema = PMA_is_system_schema($this->_db); $tbl_is_view = PMA_Table::isView($this->_db, $this->_table); $table_info_num_rows = PMA_Table::countRecords($this->_db, $this->_table); $tabs = array(); $tabs['browse']['icon'] = 'b_browse.png'; $tabs['browse']['text'] = __('Browse'); $tabs['browse']['link'] = 'sql.php'; $tabs['browse']['args']['pos'] = 0; $tabs['structure']['icon'] = 'b_props.png'; $tabs['structure']['link'] = 'tbl_structure.php'; $tabs['structure']['text'] = __('Structure'); $tabs['sql']['icon'] = 'b_sql.png'; $tabs['sql']['link'] = 'tbl_sql.php'; $tabs['sql']['text'] = __('SQL'); $tabs['search']['icon'] = 'b_search.png'; $tabs['search']['text'] = __('Search'); $tabs['search']['link'] = 'tbl_select.php'; $tabs['search']['active'] = in_array(basename($GLOBALS['PMA_PHP_SELF']), array('tbl_select.php', 'tbl_zoom_select.php')); if (!$db_is_information_schema) { $tabs['insert']['icon'] = 'b_insrow.png'; $tabs['insert']['link'] = 'tbl_change.php'; $tabs['insert']['text'] = __('Insert'); } $tabs['export']['icon'] = 'b_tblexport.png'; $tabs['export']['link'] = 'tbl_export.php'; $tabs['export']['args']['single_table'] = 'true'; $tabs['export']['text'] = __('Export'); /** * Don't display "Import" and "Operations" * for views and information_schema */ if (!$tbl_is_view && !$db_is_information_schema) { $tabs['import']['icon'] = 'b_tblimport.png'; $tabs['import']['link'] = 'tbl_import.php'; $tabs['import']['text'] = __('Import'); $tabs['operation']['icon'] = 'b_tblops.png'; $tabs['operation']['link'] = 'tbl_operations.php'; $tabs['operation']['text'] = __('Operations'); } if (PMA_Tracker::isActive()) { $tabs['tracking']['icon'] = 'eye.png'; $tabs['tracking']['text'] = __('Tracking'); $tabs['tracking']['link'] = 'tbl_tracking.php'; } if (!$db_is_information_schema && !PMA_DRIZZLE && PMA_Util::currentUserHasPrivilege('TRIGGER', $this->_db, $this->_table) && !$tbl_is_view) { $tabs['triggers']['link'] = 'tbl_triggers.php'; $tabs['triggers']['text'] = __('Triggers'); $tabs['triggers']['icon'] = 'b_triggers.png'; } /** * Views support a limited number of operations */ if ($tbl_is_view && !$db_is_information_schema) { $tabs['operation']['icon'] = 'b_tblops.png'; $tabs['operation']['link'] = 'view_operations.php'; $tabs['operation']['text'] = __('Operations'); } return $tabs; }
?> </div> </td></tr></table> <script type="text/javascript"> //<![CDATA[ init_options(); //]]> </script> <?php if (strlen($table) && !isset($num_tables)) { ?> <div class="formelementrow"> <?php echo sprintf($strDumpXRows, '<input type="text" name="limit_to" size="5" value="' . (isset($unlim_num_rows) ? $unlim_num_rows : PMA_Table::countRecords($db, $table, TRUE)) . '" onfocus="this.select()" />', '<input type="text" name="limit_from" value="0" size="5"' . ' onfocus="this.select()" /> '); ?> </div> <?php } ?> </fieldset> <fieldset> <legend> <input type="checkbox" name="asfile" value="sendit" id="checkbox_dump_asfile" <?php PMA_exportCheckboxCheck('asfile'); ?> /> <label for="checkbox_dump_asfile"><?php
/** * Gets foreign keys in preparation for a drop-down selector * * @param array $foreigners array of the foreign keys * @param string $field the foreign field name * @param bool $override_total whether to override the total * @param string $foreign_filter a possible filter * @param string $foreign_limit a possible LIMIT clause * * @return array data about the foreign keys * * @access public */ function PMA_getForeignData($foreigners, $field, $override_total, $foreign_filter, $foreign_limit) { // we always show the foreign field in the drop-down; if a display // field is defined, we show it besides the foreign field $foreign_link = false; if ($foreigners && isset($foreigners[$field])) { $foreigner = $foreigners[$field]; $foreign_db = $foreigner['foreign_db']; $foreign_table = $foreigner['foreign_table']; $foreign_field = $foreigner['foreign_field']; // Count number of rows in the foreign table. Currently we do // not use a drop-down if more than 200 rows in the foreign table, // for speed reasons and because we need a better interface for this. // // We could also do the SELECT anyway, with a LIMIT, and ensure that // the current value of the field is one of the choices. $the_total = PMA_Table::countRecords($foreign_db, $foreign_table); if ($override_total == true || $the_total < $GLOBALS['cfg']['ForeignKeyMaxLimit']) { // foreign_display can be false if no display field defined: $foreign_display = PMA_getDisplayField($foreign_db, $foreign_table); $f_query_main = 'SELECT ' . PMA_backquote($foreign_field) . ($foreign_display == false ? '' : ', ' . PMA_backquote($foreign_display)); $f_query_from = ' FROM ' . PMA_backquote($foreign_db) . '.' . PMA_backquote($foreign_table); $f_query_filter = empty($foreign_filter) ? '' : ' WHERE ' . PMA_backquote($foreign_field) . ' LIKE "%' . PMA_sqlAddSlashes($foreign_filter, true) . '%"' . ($foreign_display == false ? '' : ' OR ' . PMA_backquote($foreign_display) . ' LIKE "%' . PMA_sqlAddSlashes($foreign_filter, true) . '%"'); $f_query_order = $foreign_display == false ? '' : ' ORDER BY ' . PMA_backquote($foreign_table) . '.' . PMA_backquote($foreign_display); $f_query_limit = isset($foreign_limit) ? $foreign_limit : ''; if (!empty($foreign_filter)) { $res = PMA_DBI_query('SELECT COUNT(*)' . $f_query_from . $f_query_filter); if ($res) { $the_total = PMA_DBI_fetch_value($res); @PMA_DBI_free_result($res); } else { $the_total = 0; } } $disp = PMA_DBI_query($f_query_main . $f_query_from . $f_query_filter . $f_query_order . $f_query_limit); if ($disp && PMA_DBI_num_rows($disp) > 0) { // If a resultset has been created, pre-cache it in the $disp_row array // This helps us from not needing to use mysql_data_seek by accessing a pre-cached // PHP array. Usually those resultsets are not that big, so a performance hit should // not be expected. $disp_row = array(); while ($single_disp_row = @PMA_DBI_fetch_assoc($disp)) { $disp_row[] = $single_disp_row; } @PMA_DBI_free_result($disp); } } else { $disp_row = null; $foreign_link = true; } } // end if $foreigners $foreignData['foreign_link'] = $foreign_link; $foreignData['the_total'] = isset($the_total) ? $the_total : null; $foreignData['foreign_display'] = isset($foreign_display) ? $foreign_display : null; $foreignData['disp_row'] = isset($disp_row) ? $disp_row : null; $foreignData['foreign_field'] = isset($foreign_field) ? $foreign_field : null; return $foreignData; }
/** * Defines the display mode to use for the results of a sql query * * It uses a synthetic string that contains all the required informations. * In this string: * - the first two characters stand for the action to do while * clicking on the "edit" link (eg 'ur' for update a row, 'nn' for no * edit link...); * - the next two characters stand for the action to do while * clicking on the "delete" link (eg 'kp' for kill a process, 'nn' for * no delete link...); * - the next characters are boolean values (1/0) and respectively stand * for sorting links, navigation bar, "insert a new row" link, the * bookmark feature, the expand/collapse text/blob fields button and * the "display printable view" option. * Of course '0'/'1' means the feature won't/will be enabled. * * @param string the synthetic value for display_mode (see �1 a few * lines above for explanations) * @param integer the total number of rows returned by the sql query * without any programmatically appended "LIMIT" clause * (just a copy of $unlim_num_rows if it exists, else * computed inside this function) * * @return array an array with explicit indexes for all the display * elements * * @global string the database name * @global string the table name * @global integer the total number of rows returned by the sql query * without any programmatically appended "LIMIT" clause * @global array the properties of the fields returned by the query * @global string the url to return to in case of error in a sql * statement * * @access private * * @see PMA_displayTable() */ function PMA_setDisplayMode(&$the_disp_mode, &$the_total) { global $db, $table; global $unlim_num_rows, $fields_meta; global $err_url; // 1. Initializes the $do_display array $do_display = array(); $do_display['edit_lnk'] = $the_disp_mode[0] . $the_disp_mode[1]; $do_display['del_lnk'] = $the_disp_mode[2] . $the_disp_mode[3]; $do_display['sort_lnk'] = (string) $the_disp_mode[4]; $do_display['nav_bar'] = (string) $the_disp_mode[5]; $do_display['ins_row'] = (string) $the_disp_mode[6]; $do_display['bkm_form'] = (string) $the_disp_mode[7]; $do_display['text_btn'] = (string) $the_disp_mode[8]; $do_display['pview_lnk'] = (string) $the_disp_mode[9]; // 2. Display mode is not "false for all elements" -> updates the // display mode if ($the_disp_mode != 'nnnn000000') { // 2.0 Print view -> set all elements to false! if (isset($GLOBALS['printview']) && $GLOBALS['printview'] == '1') { $do_display['edit_lnk'] = 'nn'; // no edit link $do_display['del_lnk'] = 'nn'; // no delete link $do_display['sort_lnk'] = (string) '0'; $do_display['nav_bar'] = (string) '0'; $do_display['ins_row'] = (string) '0'; $do_display['bkm_form'] = (string) '0'; $do_display['text_btn'] = (string) '0'; $do_display['pview_lnk'] = (string) '0'; } elseif ($GLOBALS['is_count'] || $GLOBALS['is_analyse'] || $GLOBALS['is_maint'] || $GLOBALS['is_explain']) { $do_display['edit_lnk'] = 'nn'; // no edit link $do_display['del_lnk'] = 'nn'; // no delete link $do_display['sort_lnk'] = (string) '0'; $do_display['nav_bar'] = (string) '0'; $do_display['ins_row'] = (string) '0'; $do_display['bkm_form'] = (string) '1'; if ($GLOBALS['is_analyse']) { $do_display['text_btn'] = (string) '1'; } else { $do_display['text_btn'] = (string) '0'; } $do_display['pview_lnk'] = (string) '1'; } elseif ($GLOBALS['is_show']) { // 2.2.1 TODO : defines edit/delete links depending on show statement $tmp = preg_match('@^SHOW[[:space:]]+(VARIABLES|(FULL[[:space:]]+)?PROCESSLIST|STATUS|TABLE|GRANTS|CREATE|LOGS|DATABASES|FIELDS)@i', $GLOBALS['sql_query'], $which); if (isset($which[1]) && strpos(' ' . strtoupper($which[1]), 'PROCESSLIST') > 0) { $do_display['edit_lnk'] = 'nn'; // no edit link $do_display['del_lnk'] = 'kp'; // "kill process" type edit link } else { // Default case -> no links $do_display['edit_lnk'] = 'nn'; // no edit link $do_display['del_lnk'] = 'nn'; // no delete link } // 2.2.2 Other settings $do_display['sort_lnk'] = (string) '0'; $do_display['nav_bar'] = (string) '0'; $do_display['ins_row'] = (string) '0'; $do_display['bkm_form'] = (string) '1'; $do_display['text_btn'] = (string) '1'; $do_display['pview_lnk'] = (string) '1'; } else { $prev_table = $fields_meta[0]->table; $do_display['text_btn'] = (string) '1'; for ($i = 0; $i < $GLOBALS['fields_cnt']; $i++) { $is_link = $do_display['edit_lnk'] != 'nn' || $do_display['del_lnk'] != 'nn' || $do_display['sort_lnk'] != '0' || $do_display['ins_row'] != '0'; // 2.3.2 Displays edit/delete/sort/insert links? if ($is_link && ($fields_meta[$i]->table == '' || $fields_meta[$i]->table != $prev_table)) { $do_display['edit_lnk'] = 'nn'; // don't display links $do_display['del_lnk'] = 'nn'; // TODO: May be problematic with same fields names in // two joined table. // $do_display['sort_lnk'] = (string) '0'; $do_display['ins_row'] = (string) '0'; if ($do_display['text_btn'] == '1') { break; } } // end if (2.3.2) // 2.3.3 Always display print view link $do_display['pview_lnk'] = (string) '1'; $prev_table = $fields_meta[$i]->table; } // end for } // end if..elseif...else (2.1 -> 2.3) } // end if (2) // 3. Gets the total number of rows if it is unknown if (isset($unlim_num_rows) && $unlim_num_rows != '') { $the_total = $unlim_num_rows; } elseif (($do_display['nav_bar'] == '1' || $do_display['sort_lnk'] == '1') && (isset($db) && strlen($db) && !empty($table))) { $the_total = PMA_Table::countRecords($db, $table, true); } // 4. If navigation bar or sorting fields names urls should be // displayed but there is only one row, change these settings to // false if ($do_display['nav_bar'] == '1' || $do_display['sort_lnk'] == '1') { if (isset($unlim_num_rows) && $unlim_num_rows < 2) { // garvin: force display of navbar for vertical/horizontal display-choice. // $do_display['nav_bar'] = (string) '0'; $do_display['sort_lnk'] = (string) '0'; } } // end if (3) // 5. Updates the synthetic var $the_disp_mode = join('', $do_display); return $do_display; }
// we do a quick count (which uses MaxExactCount) because // SQL_CALC_FOUND_ROWS is not quick on large InnoDB tables // However, do not count again if we did it previously // due to $find_real_end == true if (! $is_group && ! isset($analyzed_sql[0]['queryflags']['union']) && ! isset($analyzed_sql[0]['queryflags']['distinct']) && ! isset($analyzed_sql[0]['table_ref'][1]['table_name']) && (empty($analyzed_sql[0]['where_clause']) || $analyzed_sql[0]['where_clause'] == '1 ') && ! isset($find_real_end) ) { // "j u s t b r o w s i n g" $unlim_num_rows = PMA_Table::countRecords($db, $table); } else { // n o t " j u s t b r o w s i n g " // add select expression after the SQL_CALC_FOUND_ROWS // for UNION, just adding SQL_CALC_FOUND_ROWS // after the first SELECT works. // take the left part, could be: // SELECT // (SELECT $count_query = PMA_SQP_formatHtml($parsed_sql, 'query_only', 0, $analyzed_sql[0]['position_of_first_select'] + 1); $count_query .= ' SQL_CALC_FOUND_ROWS '; // add everything that was after the first SELECT $count_query .= PMA_SQP_formatHtml($parsed_sql, 'query_only', $analyzed_sql[0]['position_of_first_select'] + 1);
public static function sGetToolTip($db, $table) { return PMA_Table::sGetStatusInfo($db, $table, 'Comment') . ' (' . PMA_Table::countRecords($db, $table) . ')'; }
/** * Get values for InnoDB table * $current_table, $formatted_size, $unit, $sum_size * * @param array $current_table current table * @param boolean $is_show_stats whether stats show or not * @param double $sum_size sum size * * @return array */ function PMA_getValuesForInnodbTable($current_table, $is_show_stats, $sum_size) { $formatted_size = $unit = ''; if ($current_table['ENGINE'] == 'InnoDB' && $current_table['TABLE_ROWS'] < $GLOBALS['cfg']['MaxExactCount'] || !isset($current_table['TABLE_ROWS'])) { $current_table['COUNTED'] = true; $current_table['TABLE_ROWS'] = PMA_Table::countRecords($GLOBALS['db'], $current_table['TABLE_NAME'], true, false); } else { $current_table['COUNTED'] = false; } // Drizzle doesn't provide data and index length, check for null if ($is_show_stats && $current_table['Data_length'] !== null) { $tblsize = $current_table['Data_length'] + $current_table['Index_length']; $sum_size += $tblsize; list($formatted_size, $unit) = PMA_Util::formatByteDown($tblsize, 3, $tblsize > 0 ? 1 : 0); } return array($current_table, $formatted_size, $unit, $sum_size); }
/** * loads structure data */ function loadStructure() { $table_info = PMA_DBI_get_tables_full($this->getDbName(), $this->getName()); if (false === $table_info) { return false; } $this->settings = $table_info; if ($this->get('TABLE_ROWS') === null) { $this->set('TABLE_ROWS', PMA_Table::countRecords($this->getDbName(), $this->getName(), true, true)); } $create_options = explode(' ', $this->get('TABLE_ROWS')); // export create options by its name as variables into gloabel namespace // f.e. pack_keys=1 becomes available as $pack_keys with value of '1' foreach ($create_options as $each_create_option) { $each_create_option = explode('=', $each_create_option); if (isset($each_create_option[1])) { $this->set(${$each_create_option}[0], $each_create_option[1]); } } }
foreach ($mime_map as $transformation) { $column_name = $transformation['column_name']; foreach ($transformation_types as $type) { $file = PMA_securePath($transformation[$type]); $extra_data = PMA_transformEditedValues($db, $table, $transformation, $edited_values, $file, $column_name, $extra_data, $type); } } // end of loop for each $mime_map } // Need to check the inline edited value can be truncated by MySQL // without informing while saving $column_name = $_REQUEST['fields_name']['multi_edit'][0][0]; PMA_verifyWhetherValueCanBeTruncatedAndAppendExtraData($db, $table, $column_name, $extra_data); /**Get the total row count of the table*/ $_table = new PMA_Table($_REQUEST['table'], $_REQUEST['db']); $extra_data['row_count'] = $_table->countRecords(); $extra_data['sql_query'] = PMA_Util::getMessage($message, $GLOBALS['display_query']); $response = PMA_Response::getInstance(); $response->isSuccess($message->isSuccess()); $response->addJSON('message', $message); $response->addJSON($extra_data); exit; } if (!empty($return_to_sql_query)) { $disp_query = $GLOBALS['sql_query']; $disp_message = $message; unset($message); $GLOBALS['sql_query'] = $return_to_sql_query; } $scripts->addFile('tbl_change.js'); $scripts->addFile('big_ints.js');
/** * Gets foreign keys in preparation for a drop-down selector * * @param array|boolean $foreigners array of the foreign keys * @param string $field the foreign field name * @param bool $override_total whether to override the total * @param string $foreign_filter a possible filter * @param string $foreign_limit a possible LIMIT clause * * @return array data about the foreign keys * * @access public */ function PMA_getForeignData($foreigners, $field, $override_total, $foreign_filter, $foreign_limit) { // we always show the foreign field in the drop-down; if a display // field is defined, we show it besides the foreign field $foreign_link = false; do { if (!$foreigners) { break; } $foreigner = PMA_searchColumnInForeigners($foreigners, $field); if ($foreigner != false) { $foreign_db = $foreigner['foreign_db']; $foreign_table = $foreigner['foreign_table']; $foreign_field = $foreigner['foreign_field']; } else { break; } // Count number of rows in the foreign table. Currently we do // not use a drop-down if more than ForeignKeyMaxLimit rows in the // foreign table, // for speed reasons and because we need a better interface for this. // // We could also do the SELECT anyway, with a LIMIT, and ensure that // the current value of the field is one of the choices. $the_total = PMA_Table::countRecords($foreign_db, $foreign_table, true); if ($override_total == true || $the_total < $GLOBALS['cfg']['ForeignKeyMaxLimit']) { // foreign_display can be false if no display field defined: $foreign_display = PMA_getDisplayField($foreign_db, $foreign_table); $f_query_main = 'SELECT ' . PMA_Util::backquote($foreign_field) . ($foreign_display == false ? '' : ', ' . PMA_Util::backquote($foreign_display)); $f_query_from = ' FROM ' . PMA_Util::backquote($foreign_db) . '.' . PMA_Util::backquote($foreign_table); $f_query_filter = empty($foreign_filter) ? '' : ' WHERE ' . PMA_Util::backquote($foreign_field) . ' LIKE "%' . PMA_Util::sqlAddSlashes($foreign_filter, true) . '%"' . ($foreign_display == false ? '' : ' OR ' . PMA_Util::backquote($foreign_display) . ' LIKE "%' . PMA_Util::sqlAddSlashes($foreign_filter, true) . '%"'); $f_query_order = $foreign_display == false ? '' : ' ORDER BY ' . PMA_Util::backquote($foreign_table) . '.' . PMA_Util::backquote($foreign_display); $f_query_limit = isset($foreign_limit) ? $foreign_limit : ''; if (!empty($foreign_filter)) { $the_total = $GLOBALS['dbi']->fetchValue('SELECT COUNT(*)' . $f_query_from . $f_query_filter); if ($the_total === false) { $the_total = 0; } } $disp = $GLOBALS['dbi']->tryQuery($f_query_main . $f_query_from . $f_query_filter . $f_query_order . $f_query_limit); if ($disp && $GLOBALS['dbi']->numRows($disp) > 0) { // If a resultset has been created, pre-cache it in the $disp_row // array. This helps us from not needing to use mysql_data_seek by // accessing a pre-cached PHP array. Usually those resultsets are // not that big, so a performance hit should not be expected. $disp_row = array(); while ($single_disp_row = @$GLOBALS['dbi']->fetchAssoc($disp)) { $disp_row[] = $single_disp_row; } @$GLOBALS['dbi']->freeResult($disp); } else { // Either no data in the foreign table or // user does not have select permission to foreign table/field // Show an input field with a 'Browse foreign values' link $disp_row = null; $foreign_link = true; } } else { $disp_row = null; $foreign_link = true; } } while (false); $foreignData = array(); $foreignData['foreign_link'] = $foreign_link; $foreignData['the_total'] = isset($the_total) ? $the_total : null; $foreignData['foreign_display'] = isset($foreign_display) ? $foreign_display : null; $foreignData['disp_row'] = isset($disp_row) ? $disp_row : null; $foreignData['foreign_field'] = isset($foreign_field) ? $foreign_field : null; return $foreignData; }
/** * Provides the main table to form the LEFT JOIN clause * * @param array $all_tables Tables involved in the search * @param array $all_columns Columns involved in the search * @param array $where_clause_columns Columns having criteria where clause * @param array $where_clause_tables Tables having criteria where clause * * @return string table name */ private function _getMasterTable($all_tables, $all_columns, $where_clause_columns, $where_clause_tables) { $master = ''; if (count($where_clause_tables) == 1) { // If there is exactly one column that has a decent where-clause // we will just use this $master = key($where_clause_tables); } else { // Now let's find out which of the tables has an index // (When the control user is the same as the normal user // because he is using one of his databases as pmadb, // the last db selected is not always the one where we need to work) $candidate_columns = $this->_getLeftJoinColumnCandidates($all_tables, $all_columns, $where_clause_columns); // If our array of candidates has more than one member we'll just // find the smallest table. // Of course the actual query would be faster if we check for // the Criteria which gives the smallest result set in its table, // but it would take too much time to check this if (count($candidate_columns) > 1) { // Of course we only want to check each table once $checked_tables = $candidate_columns; foreach ($candidate_columns as $table) { if ($checked_tables[$table] != 1) { $tsize[$table] = PMA_Table::countRecords($this->_db, $table, false); $checked_tables[$table] = 1; } $csize[$table] = $tsize[$table]; } asort($csize); reset($csize); $master = key($csize); // Smallest } else { reset($candidate_columns); $master = current($candidate_columns); // Only one single candidate } } // end if (exactly one where clause) return $master; }