strpos($sql, $database['SCHEMA_NAME']) !== false ) { $db = $database['SCHEMA_NAME']; break; } } return $db; } /** * Get the table name in a sql query * If there are several tables in the SQL query, * first table will return * * @param string $sql SQL query * @param array $tables array of names in current database * * @return string $table table name */ function PMA_getTableNameBySQL($sql, $tables) { $table = ''; // loop through all the tables in the database foreach ($tables as $tbl) { if ($GLOBALS['PMA_String']->strpos($sql, $tbl)) { $table .= ' ' . $tbl; } } if (count(explode(' ', trim($table))) > 1) { $tmp_array = explode(' ', trim($table)); return $tmp_array[0]; } return trim($table); } /** * Generate table html when SQL statement have multiple queries * which return displayable results * * @param object $displayResultsObject PMA_DisplayResults 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 $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 editable or not * * @return string $table_html html content */ function PMA_getTableHtmlForMultipleQueries( $displayResultsObject, $db, $sql_data, $goto, $pmaThemeImage, $printview, $url_query, $disp_mode, $sql_limit_to_append, $editable ) { $table_html = ''; $tables_array = $GLOBALS['dbi']->getTables($db); $databases_array = $GLOBALS['dbi']->getDatabasesFull(); $multi_sql = implode(";", $sql_data['valid_sql']); $querytime_before = array_sum(explode(' ', microtime())); // Assignment for variable is not needed since the results are // looping using the connection @$GLOBALS['dbi']->tryMultiQuery($multi_sql); $querytime_after = array_sum(explode(' ', microtime())); $querytime = $querytime_after - $querytime_before; $sql_no = 0; do { $analyzed_sql = array(); $is_affected = false; $showtable = array(); $result = $GLOBALS['dbi']->storeResult(); $fields_meta = ($result !== false) ? $GLOBALS['dbi']->getFieldsMeta($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 ($GLOBALS['PMA_String']->stripos( $sql_data['valid_sql'][$sql_no], "use " )) { $db = PMA_getNewDatabase( $sql_data['valid_sql'][$sql_no], $databases_array ); } $table = PMA_getTableNameBySQL( $sql_data['valid_sql'][$sql_no], $tables_array ); // for the use of the parse_analyze.inc.php $sql_query = $sql_data['valid_sql'][$sql_no]; // Parse and analyze the query include 'libraries/parse_analyze.inc.php'; $unlim_num_rows = PMA_Table::countRecords($db, $table, true); $showtable = PMA_Table::sGetStatusInfo($db, $table, null, true); $url_query = PMA_URL_getCommon(array('db' => $db, 'table' => $table)); // 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['tmpval']['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['tmpval']['pos'] . ', ' . $_SESSION['tmpval']['max_rows'] . " "; $sql_data['valid_sql'][$sql_no] = PMA_getSqlWithLimitClause( $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) ? @$GLOBALS['dbi']->numRows($result) : 0; } elseif (! isset($num_rows)) { $num_rows = @$GLOBALS['dbi']->affectedRows(); } 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, $GLOBALS['text_dir'], $is_maint, $is_explain, $is_show, $showtable, $printview, $url_query, $editable ); } if ($num_rows == 0) { continue; } // With multiple results, operations are limited $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 $GLOBALS['dbi']->freeResult($result); $sql_no++; } while ($GLOBALS['dbi']->moreResults() && $GLOBALS['dbi']->nextResult()); return $table_html; } /** * Handle remembered sorting order, only for single table query * * @param string $db database name * @param string $table table name * @param array &$analyzed_sql_results the analyzed query results * @param string &$full_sql_query SQL query * * @return void */ function PMA_handleSortOrder( $db, $table, &$analyzed_sql_results, &$full_sql_query ) { $pmatable = new PMA_Table($table, $db); if (empty($analyzed_sql_results['analyzed_sql'][0]['order_by_clause'])) { $sorted_col = $pmatable->getUiProp(PMA_Table::PROP_SORTED_COLUMN); if ($sorted_col) { //remove the tablename from retrieved preference //to get just the column name and the sort order $sorted_col = str_replace( PMA_Util::backquote($table) . '.', '', $sorted_col ); // retrieve the remembered sorting order for current table $sql_order_to_append = ' ORDER BY ' . $sorted_col . ' '; $full_sql_query = $analyzed_sql_results['analyzed_sql'][0]['section_before_limit'] . $sql_order_to_append . $analyzed_sql_results['analyzed_sql'][0]['limit_clause'] . ' ' . $analyzed_sql_results['analyzed_sql'][0]['section_after_limit']; // update the $analyzed_sql $analyzed_sql_results['analyzed_sql'][0]['section_before_limit'] .= $sql_order_to_append; $analyzed_sql_results['analyzed_sql'][0]['order_by_clause'] = $sorted_col; } } else { // store the remembered table into session $pmatable->setUiProp( PMA_Table::PROP_SORTED_COLUMN, $analyzed_sql_results['analyzed_sql'][0]['order_by_clause'] ); } } /** * Append limit clause to SQL query * * @param array $analyzed_sql the analyzed query * @param string $sql_limit_to_append clause to append * * @return string limit clause appended SQL query */ function PMA_getSqlWithLimitClause($analyzed_sql, $sql_limit_to_append ) { return $analyzed_sql[0]['section_before_limit'] . "\n" . $sql_limit_to_append . $analyzed_sql[0]['section_after_limit']; } /** * Get column name from a drop SQL statement * * @param string $sql SQL query * * @return string $drop_column Name of the column */ function PMA_getColumnNameInColumnDropSql($sql) { $tmpArray1 = explode('DROP', $sql); $str_to_check = trim($tmpArray1[1]); if ($GLOBALS['PMA_String']->stripos($str_to_check, 'COLUMN') !== false) { $tmpArray2 = explode('COLUMN', $str_to_check); $str_to_check = trim($tmpArray2[1]); } $tmpArray3 = explode(' ', $str_to_check); $str_to_check = trim($tmpArray3[0]); $drop_column = str_replace(';', '', trim($str_to_check)); $drop_column = str_replace('`', '', $drop_column); return $drop_column; } /** * Verify whether the result set has columns from just one table * * @param array $fields_meta meta fields * * @return boolean whether the result set has columns from just one table */ function PMA_resultSetHasJustOneTable($fields_meta) { $just_one_table = true; $prev_table = $fields_meta[0]->table; foreach ($fields_meta as $one_field_meta) { if (! empty($one_field_meta->table) && $one_field_meta->table != $prev_table ) { $just_one_table = false; break; } } return $just_one_table; } /** * Verify whether the result set contains all the columns * of at least one unique key * * @param string $db database name * @param string $table table name * @param array $fields_meta meta fields * * @return boolean whether the result set contains a unique key */ function PMA_resultSetContainsUniqueKey($db, $table, $fields_meta) { $resultSetColumnNames = array(); foreach ($fields_meta as $oneMeta) { $resultSetColumnNames[] = $oneMeta->name; } foreach (PMA_Index::getFromTable($table, $db) as $index) { if ($index->isUnique()) { $indexColumns = $index->getColumns(); $numberFound = 0; foreach ($indexColumns as $indexColumnName => $dummy) { if (in_array($indexColumnName, $resultSetColumnNames)) { $numberFound++; } } if ($numberFound == count($indexColumns)) { return true; } } } return false; } /** * Get the HTML for relational column dropdown * During grid edit, if we have a relational field, returns the html for the * dropdown * * @param string $db current database * @param string $table current table * @param string $column current column * @param string $curr_value current selected value * * @return string $dropdown html for the dropdown */ function PMA_getHtmlForRelationalColumnDropdown($db, $table, $column, $curr_value) { $foreigners = PMA_getForeigners($db, $table, $column); $foreignData = PMA_getForeignData($foreigners, $column, false, '', ''); if ($foreignData['disp_row'] == null) { //Handle the case when number of values //is more than $cfg['ForeignKeyMaxLimit'] $_url_params = array( 'db' => $db, 'table' => $table, 'field' => $column ); $dropdown = '' . htmlspecialchars($_REQUEST['curr_value']) . '' . '' . __('Browse foreign values') . ''; } else { $dropdown = PMA_foreignDropdown( $foreignData['disp_row'], $foreignData['foreign_field'], $foreignData['foreign_display'], $curr_value, $GLOBALS['cfg']['ForeignKeyMaxLimit'] ); $dropdown = ''; } return $dropdown; } /** * Get the HTML for the header of the page in print view if print view is selected. * Otherwise returns null. * * @param string $db current database * @param string $sql_query current sql query * @param int $num_rows the number of rows in result * * @return string $header html for the header */ function PMA_getHtmlForPrintViewHeader($db, $sql_query, $num_rows) { $response = PMA_Response::getInstance(); $header = $response->getHeader(); if (isset($_REQUEST['printview']) && $_REQUEST['printview'] == '1') { PMA_Util::checkParameters(array('db', 'sql_query')); $header->enablePrintView(); if ( $GLOBALS['cfg']['Server']['verbose']) { $hostname = $GLOBALS['cfg']['Server']['verbose']; } else { $hostname = $GLOBALS['cfg']['Server']['host']; if (! empty( $GLOBALS['cfg']['Server']['port'])) { $hostname .= $GLOBALS['cfg']['Server']['port']; } } $versions = "phpMyAdmin " . PMA_VERSION; $versions .= " / "; $versions .= "MySQL " . PMA_MYSQL_STR_VERSION; $print_view_header = ''; $print_view_header .= "

" . __('SQL result') . "

"; $print_view_header .= "

"; $print_view_header .= "" . __('Host:') . " $hostname
"; $print_view_header .= "" . __('Database:') . " " . htmlspecialchars($db) . "
"; $print_view_header .= "" . __('Generation Time:') . " " . PMA_Util::localisedDate() . "
"; $print_view_header .= "" . __('Generated by:') . " $versions
"; $print_view_header .= "" . __('SQL query:') . " " . htmlspecialchars($sql_query) . ";"; if (isset($num_rows)) { $print_view_header .= "
"; $print_view_header .= "" . __('Rows:') . " $num_rows"; } $print_view_header .= "

"; } else { $print_view_header = null; } return $print_view_header; } /** * Get the HTML for the profiling table and accompanying chart if profiling is set. * Otherwise returns null * * @param string $url_query url query * @param string $db current database * @param array $profiling_results array containing the profiling info * * @return string $profiling_table html for the profiling table and chart */ function PMA_getHtmlForProfilingChart($url_query, $db, $profiling_results) { if (isset($profiling_results)) { $pma_token = $_SESSION[' PMA_token ']; $url_query = isset($url_query) ? $url_query : PMA_URL_getCommon(array('db' => $db)); $profiling_table = ''; $profiling_table .= '
' . __('Profiling') . '' . "\n"; $profiling_table .= '
'; $profiling_table .= '

' . __('Detailed profile') . '

'; $profiling_table .= '' . "\n"; $profiling_table .= ' ' . "\n"; $profiling_table .= ' ' . "\n"; $profiling_table .= ' ' . "\n"; $profiling_table .= ' ' . "\n"; $profiling_table .= ' ' . "\n"; list($detailed_table, $chart_json, $profiling_stats) = PMA_analyzeAndGetTableHtmlForProfilingResults($profiling_results); $profiling_table .= $detailed_table; $profiling_table .= '
' . __('Order') . '
' . __('State') . PMA_Util::showMySQLDocu('general-thread-states') . '
' . __('Time') . '
' . "\n"; $profiling_table .= '
'; $profiling_table .= '
'; $profiling_table .= '

' . __('Summary by state') . '

'; $profiling_table .= '' . "\n"; $profiling_table .= ' ' . "\n"; $profiling_table .= ' ' . "\n"; $profiling_table .= ' ' . "\n"; $profiling_table .= ' ' . "\n"; $profiling_table .= ' ' . "\n"; $profiling_table .= ' ' . "\n"; $profiling_table .= ' ' . "\n"; $profiling_table .= PMA_getTableHtmlForProfilingSummaryByState( $profiling_stats ); $profiling_table .= '
' . __('State') . PMA_Util::showMySQLDocu('general-thread-states') . '
' . __('Total Time') . '
' . __('% Time') . '
' . __('Calls') . '
' . __('ΓΈ Time') . '
' . "\n"; $profiling_table .= << pma_token = '$pma_token'; url_query = '$url_query'; EOT; $profiling_table .= "
"; $profiling_table .= "
"; //require_once 'libraries/chart.lib.php'; $profiling_table .= ''; $profiling_table .= ''; $profiling_table .= ''; $profiling_table .= '
' . "\n"; } else { $profiling_table = null; } return $profiling_table; } /** * Function to get HTML for detailed profiling results table, profiling stats, and * $chart_json for displaying the chart. * * @param array $profiling_results profiling results * * @return mixed */ function PMA_analyzeAndGetTableHtmlForProfilingResults( $profiling_results ) { $profiling_stats = array( 'total_time' => 0, 'states' => array(), ); $chart_json = Array(); $i = 1; $table = ''; foreach ($profiling_results as $one_result) { if (isset($profiling_stats['states'][ucwords($one_result['Status'])])) { $states = $profiling_stats['states']; $states[ucwords($one_result['Status'])]['time'] += $one_result['Duration']; $states[ucwords($one_result['Status'])]['calls']++; } else { $profiling_stats['states'][ucwords($one_result['Status'])] = array( 'total_time' => $one_result['Duration'], 'calls' => 1, ); } $profiling_stats['total_time'] += $one_result['Duration']; $table .= ' ' . "\n"; $table .= '' . $i++ . '' . "\n"; $table .= '' . ucwords($one_result['Status']) . '' . "\n"; $table .= '' . (PMA_Util::formatNumber($one_result['Duration'], 3, 1)) . 's' . "\n"; if (isset($chart_json[ucwords($one_result['Status'])])) { $chart_json[ucwords($one_result['Status'])] += $one_result['Duration']; } else { $chart_json[ucwords($one_result['Status'])] = $one_result['Duration']; } } return array($table, $chart_json, $profiling_stats); } /** * Function to get HTML for summary by state table * * @param array $profiling_stats profiling stats * * @return string $table html for the table */ function PMA_getTableHtmlForProfilingSummaryByState($profiling_stats) { $table = ''; foreach ($profiling_stats['states'] as $name => $stats) { $table .= ' ' . "\n"; $table .= '' . $name . '' . "\n"; $table .= '' . PMA_Util::formatNumber($stats['total_time'], 3, 1) . 's' . "\n"; $table .= '' . PMA_Util::formatNumber( 100 * ($stats['total_time'] / $profiling_stats['total_time']), 0, 2 ) . '%' . "\n"; $table .= '' . $stats['calls'] . '' . "\n"; $table .= '' . PMA_Util::formatNumber( $stats['total_time'] / $stats['calls'], 3, 1 ) . 's' . "\n"; $table .= ' ' . "\n"; } return $table; } /** * Get the HTML for the enum column dropdown * During grid edit, if we have a enum field, returns the html for the * dropdown * * @param string $db current database * @param string $table current table * @param string $column current column * @param string $curr_value currently selected value * * @return string $dropdown html for the dropdown */ function PMA_getHtmlForEnumColumnDropdown($db, $table, $column, $curr_value) { $values = PMA_getValuesForColumn($db, $table, $column); $dropdown = ''; $dropdown .= PMA_getHtmlForOptionsList($values, array($curr_value)); $dropdown = ''; return $dropdown; } /** * Get the HTML for the set column dropdown * During grid edit, if we have a set field, returns the html for the * dropdown * * @param string $db current database * @param string $table current table * @param string $column current column * @param string $curr_value currently selected value * * @return string $dropdown html for the set column */ function PMA_getHtmlForSetColumn($db, $table, $column, $curr_value) { $values = PMA_getValuesForColumn($db, $table, $column); $dropdown = ''; //converts characters of $curr_value to HTML entities $converted_curr_value = htmlentities( $curr_value, ENT_COMPAT, "UTF-8" ); $selected_values = explode(',', $converted_curr_value); $dropdown .= PMA_getHtmlForOptionsList($values, $selected_values); $select_size = (sizeof($values) > 10) ? 10 : sizeof($values); $dropdown = ''; return $dropdown; } /** * Get all the values for a enum column or set column in a table * * @param string $db current database * @param string $table current table * @param string $column current column * * @return array $values array containing the value list for the column */ function PMA_getValuesForColumn($db, $table, $column) { $field_info_query = $GLOBALS['dbi']->getColumnsSql($db, $table, $column); $field_info_result = $GLOBALS['dbi']->fetchResult( $field_info_query, null, null, null, PMA_DatabaseInterface::QUERY_STORE ); $values = PMA_Util::parseEnumSetValues($field_info_result[0]['Type']); return $values; } /** * Get HTML for options list * * @param array $values set of values * @param array $selected_values currently selected values * * @return string $options HTML for options list */ function PMA_getHtmlForOptionsList($values, $selected_values) { $options = ''; foreach ($values as $value) { $options .= '