/** * Test PMA_isJustBrowsing * * @return void */ public function testIsJustBrowsing() { // Test environment. $GLOBALS['_SESSION']['tmpval']['max_rows'] = 10; $GLOBALS['db'] = 'db'; $this->assertTrue(PMA_isJustBrowsing(PMA_parseAndAnalyze('SELECT * FROM db.tbl'), null)); $this->assertTrue(PMA_isJustBrowsing(PMA_parseAndAnalyze('SELECT * FROM tbl WHERE 1'), null)); $this->assertFalse(PMA_isJustBrowsing(PMA_parseAndAnalyze('SELECT * from tbl1, tbl2 LIMIT 0, 10'), null)); }
/** * Function to handle all aspects relating to executing the query * * @param array $analyzed_sql_results analyzed sql results * @param String $full_sql_query full sql query * @param boolean $is_gotofile whether to go to a file * @param String $db current database * @param String $table current table * @param boolean $find_real_end whether to find the real end * @param String $sql_query_for_bookmark sql query to be stored as bookmark * @param array $extra_data extra data * * @return mixed */ function PMA_executeTheQuery($analyzed_sql_results, $full_sql_query, $is_gotofile, $db, $table, $find_real_end, $sql_query_for_bookmark, $extra_data) { $response = PMA_Response::getInstance(); $response->getHeader()->getMenu()->setTable($table); // Only if we ask to see the php code if (isset($GLOBALS['show_as_php'])) { $result = null; $num_rows = 0; $unlim_num_rows = 0; } else { // If we don't ask to see the php code if (isset($_SESSION['profiling']) && PMA_Util::profilingSupported()) { $GLOBALS['dbi']->query('SET PROFILING=1;'); } $result = PMA_executeQueryAndStoreResults($full_sql_query); // Displays an error message if required and stop parsing the script $error = $GLOBALS['dbi']->getError(); if ($error) { PMA_handleQueryExecuteError($is_gotofile, $error, $full_sql_query); } // If there are no errors and bookmarklabel was given, // store the query as a bookmark if (!empty($_POST['bkm_label']) && !empty($sql_query_for_bookmark)) { $cfgBookmark = PMA_Bookmark_getParams(); PMA_storeTheQueryAsBookmark($db, $cfgBookmark['user'], $sql_query_for_bookmark, $_POST['bkm_label'], isset($_POST['bkm_replace']) ? $_POST['bkm_replace'] : null); } // end store bookmarks // Gets the number of rows affected/returned // (This must be done immediately after the query because // mysql_affected_rows() reports about the last query done) $num_rows = PMA_getNumberOfRowsAffectedOrChanged($analyzed_sql_results['is_affected'], $result, isset($num_rows) ? $num_rows : null); // Grabs the profiling results if (isset($_SESSION['profiling']) && PMA_Util::profilingSupported()) { $profiling_results = $GLOBALS['dbi']->fetchResult('SHOW PROFILE;'); } $justBrowsing = PMA_isJustBrowsing($analyzed_sql_results, isset($find_real_end) ? $find_real_end : null); $unlim_num_rows = PMA_countQueryResults($num_rows, $analyzed_sql_results['is_select'], $justBrowsing, $db, $table, $analyzed_sql_results['parsed_sql'], $analyzed_sql_results); $extra_data = PMA_cleanupRelations(isset($db) ? $db : '', isset($table) ? $table : '', isset($_REQUEST['dropped_column']) ? $_REQUEST['dropped_column'] : null, isset($_REQUEST['purge']) ? $_REQUEST['purge'] : null, isset($extra_data) ? $extra_data : null); // Update Indexes list. if (isset($_REQUEST['index_change'])) { $extra_data['indexes_list'] = PMA_Index::getView($table, $db); } } return array($result, $num_rows, $unlim_num_rows, isset($profiling_results) ? $profiling_results : null, $extra_data); }
/** * Prepare a table of results returned by a SQL query. * * @param integer &$dt_result the link id associated to the query * which results have to be displayed * @param array &$displayParts the parts to display * @param array $analyzed_sql_results analyzed sql results * @param boolean $is_limited_display With limited operations or not * * @return string $table_html Generated HTML content for resulted table * * @access public * * @see sql.php file */ public function getTable(&$dt_result, &$displayParts, $analyzed_sql_results, $is_limited_display = false) { /** * The statement this table is built for. * @var \SqlParser\Statements\SelectStatement */ $statement = $analyzed_sql_results['statement']; $table_html = ''; // Following variable are needed for use in isset/empty or // use with array indexes/safe use in foreach $fields_meta = $this->__get('fields_meta'); $showtable = $this->__get('showtable'); $printview = $this->__get('printview'); // why was this called here? (already called from sql.php) //$this->setConfigParamsForDisplayTable(); /** * @todo move this to a central place * @todo for other future table types */ $is_innodb = isset($showtable['Type']) && $showtable['Type'] == self::TABLE_TYPE_INNO_DB; if ($is_innodb && PMA_isJustBrowsing($analyzed_sql_results, true)) { // "j u s t b r o w s i n g" $pre_count = '~'; $after_count = Util::showHint(PMA_sanitize(__('May be approximate. See [doc@faq3-11]FAQ 3.11[/doc].'))); } else { $pre_count = ''; $after_count = ''; } // 1. ----- Prepares the work ----- // 1.1 Gets the information about which functionalities should be // displayed list($displayParts, $total) = $this->_setDisplayPartsAndTotal($displayParts); // 1.2 Defines offsets for the next and previous pages if ($displayParts['nav_bar'] == '1') { list($pos_next, $pos_prev) = $this->_getOffsets(); } // end if // 1.3 Extract sorting expressions. // we need $sort_expression and $sort_expression_nodirection // even if there are many table references $sort_expression = array(); $sort_expression_nodirection = array(); $sort_direction = array(); if (!empty($statement->order)) { foreach ($statement->order as $o) { $sort_expression[] = $o->expr->expr . ' ' . $o->type; $sort_expression_nodirection[] = $o->expr->expr; $sort_direction[] = $o->type; } } else { $sort_expression[] = ''; $sort_expression_nodirection[] = ''; $sort_direction[] = ''; } $number_of_columns = count($sort_expression_nodirection); // 1.4 Prepares display of first and last value of the sorted column $sorted_column_message = ''; for ($i = 0; $i < $number_of_columns; $i++) { $sorted_column_message .= $this->_getSortedColumnMessage($dt_result, $sort_expression_nodirection[$i]); } // 2. ----- Prepare to display the top of the page ----- // 2.1 Prepares a messages with position information if ($displayParts['nav_bar'] == '1' && isset($pos_next)) { $message = $this->_setMessageInformation($sorted_column_message, $analyzed_sql_results, $total, $pos_next, $pre_count, $after_count); $table_html .= Util::getMessage($message, $this->__get('sql_query'), 'success'); } elseif (!isset($printview) || $printview != '1') { $table_html .= Util::getMessage(__('Your SQL query has been executed successfully.'), $this->__get('sql_query'), 'success'); } // 2.3 Prepare the navigation bars if (!mb_strlen($this->__get('table'))) { if ($analyzed_sql_results['querytype'] == 'SELECT') { // table does not always contain a real table name, // for example in MySQL 5.0.x, the query SHOW STATUS // returns STATUS as a table name $this->__set('table', $fields_meta[0]->table); } else { $this->__set('table', ''); } } // can the result be sorted? if ($displayParts['sort_lnk'] == '1') { // At this point, $sort_expression is an array but we only verify // the first element in case we could find that the table is // sorted by one of the choices listed in the // "Sort by key" drop-down list($unsorted_sql_query, $sort_by_key_html) = $this->_getUnsortedSqlAndSortByKeyDropDown($analyzed_sql_results, $sort_expression[0]); } else { $sort_by_key_html = $unsorted_sql_query = ''; } if ($displayParts['nav_bar'] == '1' && empty($statement->limit)) { $table_html .= $this->_getPlacedTableNavigations($pos_next, $pos_prev, self::PLACE_TOP_DIRECTION_DROPDOWN, $is_innodb, $sort_by_key_html); } // 2b ----- Get field references from Database ----- // (see the 'relation' configuration variable) // initialize map $map = array(); $target = array(); if (!empty($statement->from)) { foreach ($statement->from as $field) { if (!empty($field->table)) { $target[] = $field->table; } } } if (mb_strlen($this->__get('table'))) { // This method set the values for $map array $this->_setParamForLinkForeignKeyRelatedTables($map); // Coming from 'Distinct values' action of structure page // We manipulate relations mechanism to show a link to related rows. if ($this->__get('is_browse_distinct')) { $map[$fields_meta[1]->name] = array($this->__get('table'), $fields_meta[1]->name, '', $this->__get('db')); } } // end if // end 2b // 3. ----- Prepare the results table ----- $table_html .= $this->_getTableHeaders($displayParts, $analyzed_sql_results, $unsorted_sql_query, $sort_expression, $sort_expression_nodirection, $sort_direction, $is_limited_display); $table_html .= '<tbody>' . "\n"; $table_html .= $this->_getTableBody($dt_result, $displayParts, $map, $analyzed_sql_results, $is_limited_display); $this->__set('display_params', null); $table_html .= '</tbody>' . "\n" . '</table>'; // 4. ----- Prepares the link for multi-fields edit and delete if ($displayParts['del_lnk'] == self::DELETE_ROW && $displayParts['del_lnk'] != self::KILL_PROCESS) { $table_html .= $this->_getMultiRowOperationLinks($dt_result, $analyzed_sql_results, $displayParts['del_lnk']); } // 5. ----- Get the navigation bar at the bottom if required ----- if ($displayParts['nav_bar'] == '1' && empty($statement->limit)) { $table_html .= $this->_getPlacedTableNavigations($pos_next, $pos_prev, self::PLACE_BOTTOM_DIRECTION_DROPDOWN, $is_innodb, $sort_by_key_html); } elseif (!isset($printview) || $printview != '1') { $table_html .= "\n" . '<br /><br />' . "\n"; } // 6. ----- Prepare "Query results operations" if ((!isset($printview) || $printview != '1') && !$is_limited_display) { $table_html .= $this->_getResultsOperations($displayParts, $analyzed_sql_results); } return $table_html; }