aboutsummaryrefslogtreecommitdiff
path: root/srcs/phpmyadmin/libraries/classes/Sql.php
diff options
context:
space:
mode:
Diffstat (limited to 'srcs/phpmyadmin/libraries/classes/Sql.php')
-rw-r--r--srcs/phpmyadmin/libraries/classes/Sql.php2328
1 files changed, 0 insertions, 2328 deletions
diff --git a/srcs/phpmyadmin/libraries/classes/Sql.php b/srcs/phpmyadmin/libraries/classes/Sql.php
deleted file mode 100644
index fb4b07f..0000000
--- a/srcs/phpmyadmin/libraries/classes/Sql.php
+++ /dev/null
@@ -1,2328 +0,0 @@
-<?php
-/* vim: set expandtab sw=4 ts=4 sts=4: */
-/**
- * Set of functions for the SQL executor
- *
- * @package PhpMyAdmin
- */
-declare(strict_types=1);
-
-namespace PhpMyAdmin;
-
-use PhpMyAdmin\Bookmark;
-use PhpMyAdmin\Core;
-use PhpMyAdmin\DatabaseInterface;
-use PhpMyAdmin\Display\Results as DisplayResults;
-use PhpMyAdmin\Index;
-use PhpMyAdmin\Message;
-use PhpMyAdmin\Operations;
-use PhpMyAdmin\ParseAnalyze;
-use PhpMyAdmin\Relation;
-use PhpMyAdmin\RelationCleanup;
-use PhpMyAdmin\Response;
-use PhpMyAdmin\SqlParser\Statements\AlterStatement;
-use PhpMyAdmin\SqlParser\Statements\DropStatement;
-use PhpMyAdmin\SqlParser\Statements\SelectStatement;
-use PhpMyAdmin\SqlParser\Utils\Query;
-use PhpMyAdmin\Table;
-use PhpMyAdmin\Transformations;
-use PhpMyAdmin\Url;
-use PhpMyAdmin\Util;
-
-/**
- * Set of functions for the SQL executor
- *
- * @package PhpMyAdmin
- */
-class Sql
-{
- /**
- * @var Relation
- */
- private $relation;
-
- /**
- * @var RelationCleanup
- */
- private $relationCleanup;
-
- /**
- * @var Transformations
- */
- private $transformations;
-
- /**
- * @var Operations
- */
- private $operations;
-
- /**
- * @var Template
- */
- private $template;
-
- /**
- * Constructor
- */
- public function __construct()
- {
- $this->relation = new Relation($GLOBALS['dbi']);
- $this->relationCleanup = new RelationCleanup($GLOBALS['dbi'], $this->relation);
- $this->operations = new Operations($GLOBALS['dbi'], $this->relation);
- $this->transformations = new Transformations();
- $this->template = new Template();
- }
-
- /**
- * Parses and analyzes the given SQL query.
- *
- * @param string $sql_query SQL query
- * @param string $db DB name
- *
- * @return mixed
- */
- public function parseAndAnalyze($sql_query, $db = null)
- {
- if ($db === null && isset($GLOBALS['db']) && strlen($GLOBALS['db'])) {
- $db = $GLOBALS['db'];
- }
- list($analyzed_sql_results,,) = ParseAnalyze::sqlQuery($sql_query, $db);
- return $analyzed_sql_results;
- }
-
- /**
- * 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
- */
- private function handleSortOrder(
- $db,
- $table,
- array &$analyzed_sql_results,
- &$full_sql_query
- ) {
- $pmatable = new Table($table, $db);
-
- if (empty($analyzed_sql_results['order'])) {
- // Retrieving the name of the column we should sort after.
- $sortCol = $pmatable->getUiProp(Table::PROP_SORTED_COLUMN);
- if (empty($sortCol)) {
- return;
- }
-
- // Remove the name of the table from the retrieved field name.
- $sortCol = str_replace(
- Util::backquote($table) . '.',
- '',
- $sortCol
- );
-
- // Create the new query.
- $full_sql_query = Query::replaceClause(
- $analyzed_sql_results['statement'],
- $analyzed_sql_results['parser']->list,
- 'ORDER BY ' . $sortCol
- );
-
- // TODO: Avoid reparsing the query.
- $analyzed_sql_results = Query::getAll($full_sql_query);
- } else {
- // Store the remembered table into session.
- $pmatable->setUiProp(
- Table::PROP_SORTED_COLUMN,
- Query::getClause(
- $analyzed_sql_results['statement'],
- $analyzed_sql_results['parser']->list,
- 'ORDER BY'
- )
- );
- }
- }
-
- /**
- * Append limit clause to SQL query
- *
- * @param array $analyzed_sql_results the analyzed query results
- *
- * @return string limit clause appended SQL query
- */
- private function getSqlWithLimitClause(array &$analyzed_sql_results)
- {
- return Query::replaceClause(
- $analyzed_sql_results['statement'],
- $analyzed_sql_results['parser']->list,
- 'LIMIT ' . $_SESSION['tmpval']['pos'] . ', '
- . $_SESSION['tmpval']['max_rows']
- );
- }
-
- /**
- * 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
- */
- private function resultSetHasJustOneTable(array $fields_meta)
- {
- $just_one_table = true;
- $prev_table = '';
- foreach ($fields_meta as $one_field_meta) {
- if ($one_field_meta->table != ''
- && $prev_table != ''
- && $one_field_meta->table != $prev_table
- ) {
- $just_one_table = false;
- }
- if ($one_field_meta->table != '') {
- $prev_table = $one_field_meta->table;
- }
- }
- return $just_one_table && $prev_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
- */
- private function resultSetContainsUniqueKey($db, $table, array $fields_meta)
- {
- $columns = $GLOBALS['dbi']->getColumns($db, $table);
- $resultSetColumnNames = [];
- foreach ($fields_meta as $oneMeta) {
- $resultSetColumnNames[] = $oneMeta->name;
- }
- foreach (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++;
- } elseif (! in_array($indexColumnName, $columns)) {
- $numberFound++;
- } elseif (strpos($columns[$indexColumnName]['Extra'], 'INVISIBLE') !== false) {
- $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 html for the dropdown
- */
- private function getHtmlForRelationalColumnDropdown($db, $table, $column, $curr_value)
- {
- $foreigners = $this->relation->getForeigners($db, $table, $column);
-
- $foreignData = $this->relation->getForeignData(
- $foreigners,
- $column,
- false,
- '',
- ''
- );
-
- if ($foreignData['disp_row'] == null) {
- //Handle the case when number of values
- //is more than $cfg['ForeignKeyMaxLimit']
- $_url_params = [
- 'db' => $db,
- 'table' => $table,
- 'field' => $column,
- ];
-
- $dropdown = $this->template->render('sql/relational_column_dropdown', [
- 'current_value' => $_POST['curr_value'],
- 'params' => $_url_params,
- ]);
- } else {
- $dropdown = $this->relation->foreignDropdown(
- $foreignData['disp_row'],
- $foreignData['foreign_field'],
- $foreignData['foreign_display'],
- $curr_value,
- $GLOBALS['cfg']['ForeignKeyMaxLimit']
- );
- $dropdown = '<select>' . $dropdown . '</select>';
- }
-
- return $dropdown;
- }
-
- /**
- * Get the HTML for the profiling table and accompanying chart if profiling is set.
- * Otherwise returns null
- *
- * @param string|null $urlQuery url query
- * @param string $database current database
- * @param array $profilingResults array containing the profiling info
- *
- * @return string html for the profiling table and chart
- */
- private function getHtmlForProfilingChart($urlQuery, $database, $profilingResults): string
- {
- if (! empty($profilingResults)) {
- $urlQuery = isset($urlQuery) ? $urlQuery : Url::getCommon(['db' => $database]);
-
- list(
- $detailedTable,
- $chartJson,
- $profilingStats
- ) = $this->analyzeAndGetTableHtmlForProfilingResults($profilingResults);
-
- return $this->template->render('sql/profiling_chart', [
- 'url_query' => $urlQuery,
- 'detailed_table' => $detailedTable,
- 'states' => $profilingStats['states'],
- 'total_time' => $profilingStats['total_time'],
- 'chart_json' => $chartJson,
- ]);
- }
- return '';
- }
-
- /**
- * 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
- */
- private function analyzeAndGetTableHtmlForProfilingResults(
- $profiling_results
- ) {
- $profiling_stats = [
- 'total_time' => 0,
- 'states' => [],
- ];
- $chart_json = [];
- $i = 1;
- $table = '';
- foreach ($profiling_results as $one_result) {
- if (! isset($profiling_stats['states'][ucwords($one_result['Status'])])) {
- $profiling_stats['states'][ucwords($one_result['Status'])] = [
- 'total_time' => $one_result['Duration'],
- 'calls' => 1,
- ];
- }
- $profiling_stats['total_time'] += $one_result['Duration'];
-
- $table .= $this->template->render('sql/detailed_table', [
- 'index' => $i++,
- 'status' => $one_result['Status'],
- 'duration' => $one_result['Duration'],
- ]);
-
- 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 [
- $table,
- $chart_json,
- $profiling_stats,
- ];
- }
-
- /**
- * 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 html for the dropdown
- */
- private function getHtmlForEnumColumnDropdown($db, $table, $column, $curr_value)
- {
- $values = $this->getValuesForColumn($db, $table, $column);
- return $this->template->render('sql/enum_column_dropdown', [
- 'values' => $values,
- 'selected_values' => [$curr_value],
- ]);
- }
-
- /**
- * Get value of a column for a specific row (marked by $where_clause)
- *
- * @param string $db current database
- * @param string $table current table
- * @param string $column current column
- * @param string $where_clause where clause to select a particular row
- *
- * @return string with value
- */
- private function getFullValuesForSetColumn($db, $table, $column, $where_clause)
- {
- $result = $GLOBALS['dbi']->fetchSingleRow(
- "SELECT `$column` FROM `$db`.`$table` WHERE $where_clause"
- );
-
- return $result[$column];
- }
-
- /**
- * 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 html for the set column
- */
- private function getHtmlForSetColumn($db, $table, $column, $curr_value): string
- {
- $values = $this->getValuesForColumn($db, $table, $column);
-
- $full_values = isset($_POST['get_full_values']) ? $_POST['get_full_values'] : false;
- $where_clause = isset($_POST['where_clause']) ? $_POST['where_clause'] : null;
-
- // If the $curr_value was truncated, we should
- // fetch the correct full values from the table
- if ($full_values && ! empty($where_clause)) {
- $curr_value = $this->getFullValuesForSetColumn(
- $db,
- $table,
- $column,
- $where_clause
- );
- }
-
- //converts characters of $curr_value to HTML entities
- $converted_curr_value = htmlentities(
- $curr_value,
- ENT_COMPAT,
- "UTF-8"
- );
-
- $selected_values = explode(',', $converted_curr_value);
- $select_size = (count($values) > 10) ? 10 : count($values);
-
- return $this->template->render('sql/set_column', [
- 'size' => $select_size,
- 'values' => $values,
- 'selected_values' => $selected_values,
- ]);
- }
-
- /**
- * 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 array containing the value list for the column
- */
- private function getValuesForColumn($db, $table, $column)
- {
- $field_info_query = $GLOBALS['dbi']->getColumnsSql($db, $table, $column);
-
- $field_info_result = $GLOBALS['dbi']->fetchResult(
- $field_info_query,
- null,
- null,
- DatabaseInterface::CONNECT_USER,
- DatabaseInterface::QUERY_STORE
- );
-
- return Util::parseEnumSetValues($field_info_result[0]['Type']);
- }
-
- /**
- * Function to get html for bookmark support if bookmarks are enabled. Else will
- * return null
- *
- * @param array $displayParts the parts to display
- * @param array $cfgBookmark configuration setting for bookmarking
- * @param string $sql_query sql query
- * @param string $db current database
- * @param string $table current table
- * @param string|null $complete_query complete query
- * @param string $bkm_user bookmarking user
- *
- * @return string
- */
- public function getHtmlForBookmark(
- array $displayParts,
- array $cfgBookmark,
- $sql_query,
- $db,
- $table,
- ?string $complete_query,
- $bkm_user
- ): string {
- if ($displayParts['bkm_form'] == '1'
- && (! empty($cfgBookmark) && empty($_GET['id_bookmark']))
- && ! empty($sql_query)
- ) {
- return $this->template->render('sql/bookmark', [
- 'db' => $db,
- 'goto' => 'sql.php' . Url::getCommon([
- 'db' => $db,
- 'table' => $table,
- 'sql_query' => $sql_query,
- 'id_bookmark' => 1,
- ]),
- 'user' => $bkm_user,
- 'sql_query' => isset($complete_query) ? $complete_query : $sql_query,
- ]);
- }
- return '';
- }
-
- /**
- * Function to check whether to remember the sorting order or not
- *
- * @param array $analyzed_sql_results the analyzed query and other variables set
- * after analyzing the query
- *
- * @return boolean
- */
- private function isRememberSortingOrder(array $analyzed_sql_results)
- {
- return $GLOBALS['cfg']['RememberSorting']
- && ! ($analyzed_sql_results['is_count']
- || $analyzed_sql_results['is_export']
- || $analyzed_sql_results['is_func']
- || $analyzed_sql_results['is_analyse'])
- && $analyzed_sql_results['select_from']
- && isset($analyzed_sql_results['select_expr'])
- && isset($analyzed_sql_results['select_tables'])
- && (empty($analyzed_sql_results['select_expr'])
- || ((count($analyzed_sql_results['select_expr']) === 1)
- && ($analyzed_sql_results['select_expr'][0] == '*')))
- && count($analyzed_sql_results['select_tables']) === 1;
- }
-
- /**
- * Function to check whether the LIMIT clause should be appended or not
- *
- * @param array $analyzed_sql_results the analyzed query and other variables set
- * after analyzing the query
- *
- * @return boolean
- */
- private function isAppendLimitClause(array $analyzed_sql_results)
- {
- // Assigning LIMIT clause to an syntactically-wrong query
- // is not needed. Also we would want to show the true query
- // and the true error message to the query executor
-
- return (isset($analyzed_sql_results['parser'])
- && count($analyzed_sql_results['parser']->errors) === 0)
- && ($_SESSION['tmpval']['max_rows'] != 'all')
- && ! ($analyzed_sql_results['is_export']
- || $analyzed_sql_results['is_analyse'])
- && ($analyzed_sql_results['select_from']
- || $analyzed_sql_results['is_subquery'])
- && empty($analyzed_sql_results['limit']);
- }
-
- /**
- * Function to check whether this query is for just browsing
- *
- * @param array $analyzed_sql_results the analyzed query and other variables set
- * after analyzing the query
- * @param boolean|null $find_real_end whether the real end should be found
- *
- * @return boolean
- */
- public function isJustBrowsing(array $analyzed_sql_results, ?bool $find_real_end): bool
- {
- return ! $analyzed_sql_results['is_group']
- && ! $analyzed_sql_results['is_func']
- && empty($analyzed_sql_results['union'])
- && empty($analyzed_sql_results['distinct'])
- && $analyzed_sql_results['select_from']
- && (count($analyzed_sql_results['select_tables']) === 1)
- && (empty($analyzed_sql_results['statement']->where)
- || (count($analyzed_sql_results['statement']->where) === 1
- && $analyzed_sql_results['statement']->where[0]->expr === '1'))
- && empty($analyzed_sql_results['group'])
- && ! isset($find_real_end)
- && ! $analyzed_sql_results['is_subquery']
- && ! $analyzed_sql_results['join']
- && empty($analyzed_sql_results['having']);
- }
-
- /**
- * Function to check whether the related transformation information should be deleted
- *
- * @param array $analyzed_sql_results the analyzed query and other variables set
- * after analyzing the query
- *
- * @return boolean
- */
- private function isDeleteTransformationInfo(array $analyzed_sql_results)
- {
- return ! empty($analyzed_sql_results['querytype'])
- && (($analyzed_sql_results['querytype'] == 'ALTER')
- || ($analyzed_sql_results['querytype'] == 'DROP'));
- }
-
- /**
- * Function to check whether the user has rights to drop the database
- *
- * @param array $analyzed_sql_results the analyzed query and other variables set
- * after analyzing the query
- * @param boolean $allowUserDropDatabase whether the user is allowed to drop db
- * @param boolean $is_superuser whether this user is a superuser
- *
- * @return boolean
- */
- public function hasNoRightsToDropDatabase(
- array $analyzed_sql_results,
- $allowUserDropDatabase,
- $is_superuser
- ) {
- return ! $allowUserDropDatabase
- && isset($analyzed_sql_results['drop_database'])
- && $analyzed_sql_results['drop_database']
- && ! $is_superuser;
- }
-
- /**
- * Function to set a column property
- *
- * @param Table $pmatable Table instance
- * @param string $request_index col_order|col_visib
- *
- * @return boolean
- */
- private function setColumnProperty($pmatable, $request_index)
- {
- $property_value = array_map('intval', explode(',', $_POST[$request_index]));
- switch ($request_index) {
- case 'col_order':
- $property_to_set = Table::PROP_COLUMN_ORDER;
- break;
- case 'col_visib':
- $property_to_set = Table::PROP_COLUMN_VISIB;
- break;
- default:
- $property_to_set = '';
- }
- $retval = $pmatable->setUiProp(
- $property_to_set,
- $property_value,
- isset($_POST['table_create_time']) ? $_POST['table_create_time'] : null
- );
- if (gettype($retval) != 'boolean') {
- $response = Response::getInstance();
- $response->setRequestStatus(false);
- $response->addJSON('message', $retval->getString());
- exit;
- }
-
- return $retval;
- }
-
- /**
- * Function to check the request for setting the column order or visibility
- *
- * @param string $table the current table
- * @param string $db the current database
- *
- * @return void
- */
- public function setColumnOrderOrVisibility($table, $db)
- {
- $pmatable = new Table($table, $db);
- $retval = false;
-
- // set column order
- if (isset($_POST['col_order'])) {
- $retval = $this->setColumnProperty($pmatable, 'col_order');
- }
-
- // set column visibility
- if ($retval === true && isset($_POST['col_visib'])) {
- $retval = $this->setColumnProperty($pmatable, 'col_visib');
- }
-
- $response = Response::getInstance();
- $response->setRequestStatus($retval === true);
- exit;
- }
-
- /**
- * Function to add a bookmark
- *
- * @param string $goto goto page URL
- *
- * @return void
- */
- public function addBookmark($goto)
- {
- $bookmark = Bookmark::createBookmark(
- $GLOBALS['dbi'],
- $GLOBALS['cfg']['Server']['user'],
- $_POST['bkm_fields'],
- (isset($_POST['bkm_all_users'])
- && $_POST['bkm_all_users'] == 'true' ? true : false
- )
- );
- $result = $bookmark->save();
- $response = Response::getInstance();
- if ($response->isAjax()) {
- if ($result) {
- $msg = Message::success(__('Bookmark %s has been created.'));
- $msg->addParam($_POST['bkm_fields']['bkm_label']);
- $response->addJSON('message', $msg);
- } else {
- $msg = Message::error(__('Bookmark not created!'));
- $response->setRequestStatus(false);
- $response->addJSON('message', $msg);
- }
- exit;
- } else {
- // go back to sql.php to redisplay query; do not use &amp; in this case:
- /**
- * @todo In which scenario does this happen?
- */
- Core::sendHeaderLocation(
- './' . $goto
- . '&label=' . $_POST['bkm_fields']['bkm_label']
- );
- }
- }
-
- /**
- * Function to find the real end of rows
- *
- * @param string $db the current database
- * @param string $table the current table
- *
- * @return mixed the number of rows if "retain" param is true, otherwise true
- */
- public function findRealEndOfRows($db, $table)
- {
- $unlim_num_rows = $GLOBALS['dbi']->getTable($db, $table)->countRecords(true);
- $_SESSION['tmpval']['pos'] = $this->getStartPosToDisplayRow($unlim_num_rows);
-
- return $unlim_num_rows;
- }
-
- /**
- * Function to get values for the relational columns
- *
- * @param string $db the current database
- * @param string $table the current table
- *
- * @return void
- */
- public function getRelationalValues($db, $table)
- {
- $column = $_POST['column'];
- if ($_SESSION['tmpval']['relational_display'] == 'D'
- && isset($_POST['relation_key_or_display_column'])
- && $_POST['relation_key_or_display_column']
- ) {
- $curr_value = $_POST['relation_key_or_display_column'];
- } else {
- $curr_value = $_POST['curr_value'];
- }
- $dropdown = $this->getHtmlForRelationalColumnDropdown(
- $db,
- $table,
- $column,
- $curr_value
- );
- $response = Response::getInstance();
- $response->addJSON('dropdown', $dropdown);
- exit;
- }
-
- /**
- * Function to get values for Enum or Set Columns
- *
- * @param string $db the current database
- * @param string $table the current table
- * @param string $columnType whether enum or set
- *
- * @return void
- */
- public function getEnumOrSetValues($db, $table, $columnType)
- {
- $column = $_POST['column'];
- $curr_value = $_POST['curr_value'];
- $response = Response::getInstance();
- if ($columnType == "enum") {
- $dropdown = $this->getHtmlForEnumColumnDropdown(
- $db,
- $table,
- $column,
- $curr_value
- );
- $response->addJSON('dropdown', $dropdown);
- } else {
- $select = $this->getHtmlForSetColumn(
- $db,
- $table,
- $column,
- $curr_value
- );
- $response->addJSON('select', $select);
- }
- exit;
- }
-
- /**
- * Function to get the default sql query for browsing page
- *
- * @param string $db the current database
- * @param string $table the current table
- *
- * @return string the default $sql_query for browse page
- */
- public function getDefaultSqlQueryForBrowse($db, $table)
- {
- $bookmark = Bookmark::get(
- $GLOBALS['dbi'],
- $GLOBALS['cfg']['Server']['user'],
- $db,
- $table,
- 'label',
- false,
- true
- );
-
- if (! empty($bookmark) && ! empty($bookmark->getQuery())) {
- $GLOBALS['using_bookmark_message'] = Message::notice(
- __('Using bookmark "%s" as default browse query.')
- );
- $GLOBALS['using_bookmark_message']->addParam($table);
- $GLOBALS['using_bookmark_message']->addHtml(
- Util::showDocu('faq', 'faq6-22')
- );
- $sql_query = $bookmark->getQuery();
- } else {
- $defaultOrderByClause = '';
-
- if (isset($GLOBALS['cfg']['TablePrimaryKeyOrder'])
- && ($GLOBALS['cfg']['TablePrimaryKeyOrder'] !== 'NONE')
- ) {
- $primaryKey = null;
- $primary = Index::getPrimary($table, $db);
-
- if ($primary !== false) {
- $primarycols = $primary->getColumns();
-
- foreach ($primarycols as $col) {
- $primaryKey = $col->getName();
- break;
- }
-
- if ($primaryKey != null) {
- $defaultOrderByClause = ' ORDER BY '
- . Util::backquote($table) . '.'
- . Util::backquote($primaryKey) . ' '
- . $GLOBALS['cfg']['TablePrimaryKeyOrder'];
- }
- }
- }
-
- $sql_query = 'SELECT * FROM ' . Util::backquote($table)
- . $defaultOrderByClause;
- }
-
- return $sql_query;
- }
-
- /**
- * Responds an error when an error happens when executing the query
- *
- * @param boolean $is_gotofile whether goto file or not
- * @param string $error error after executing the query
- * @param string $full_sql_query full sql query
- *
- * @return void
- */
- private function handleQueryExecuteError($is_gotofile, $error, $full_sql_query)
- {
- if ($is_gotofile) {
- $message = Message::rawError($error);
- $response = Response::getInstance();
- $response->setRequestStatus(false);
- $response->addJSON('message', $message);
- } else {
- Util::mysqlDie($error, $full_sql_query, '', '');
- }
- exit;
- }
-
- /**
- * Function to store the query as a bookmark
- *
- * @param string $db the current database
- * @param string $bkm_user the bookmarking user
- * @param string $sql_query_for_bookmark the query to be stored in bookmark
- * @param string $bkm_label bookmark label
- * @param boolean|null $bkm_replace whether to replace existing bookmarks
- *
- * @return void
- */
- public function storeTheQueryAsBookmark(
- $db,
- $bkm_user,
- $sql_query_for_bookmark,
- $bkm_label,
- ?bool $bkm_replace
- ) {
- $bfields = [
- 'bkm_database' => $db,
- 'bkm_user' => $bkm_user,
- 'bkm_sql_query' => $sql_query_for_bookmark,
- 'bkm_label' => $bkm_label,
- ];
-
- // Should we replace bookmark?
- if (isset($bkm_replace)) {
- $bookmarks = Bookmark::getList(
- $GLOBALS['dbi'],
- $GLOBALS['cfg']['Server']['user'],
- $db
- );
- foreach ($bookmarks as $bookmark) {
- if ($bookmark->getLabel() == $bkm_label) {
- $bookmark->delete();
- }
- }
- }
-
- $bookmark = Bookmark::createBookmark(
- $GLOBALS['dbi'],
- $GLOBALS['cfg']['Server']['user'],
- $bfields,
- isset($_POST['bkm_all_users'])
- );
- $bookmark->save();
- }
-
- /**
- * Executes the SQL query and measures its execution time
- *
- * @param string $full_sql_query the full sql query
- *
- * @return array ($result, $querytime)
- */
- private function executeQueryAndMeasureTime($full_sql_query)
- {
- // close session in case the query takes too long
- session_write_close();
-
- // Measure query time.
- $querytime_before = array_sum(explode(' ', microtime()));
-
- $result = @$GLOBALS['dbi']->tryQuery(
- $full_sql_query,
- DatabaseInterface::CONNECT_USER,
- DatabaseInterface::QUERY_STORE
- );
- $querytime_after = array_sum(explode(' ', microtime()));
-
- // reopen session
- session_start();
-
- return [
- $result,
- $querytime_after - $querytime_before,
- ];
- }
-
- /**
- * Function to get the affected or changed number of rows after executing a query
- *
- * @param boolean $is_affected whether the query affected a table
- * @param mixed $result results of executing the query
- *
- * @return int number of rows affected or changed
- */
- private function getNumberOfRowsAffectedOrChanged($is_affected, $result)
- {
- if (! $is_affected) {
- $num_rows = $result ? @$GLOBALS['dbi']->numRows($result) : 0;
- } else {
- $num_rows = @$GLOBALS['dbi']->affectedRows();
- }
-
- return $num_rows;
- }
-
- /**
- * Checks if the current database has changed
- * This could happen if the user sends a query like "USE `database`;"
- *
- * @param string $db the database in the query
- *
- * @return bool whether to reload the navigation(1) or not(0)
- */
- private function hasCurrentDbChanged($db): bool
- {
- if (strlen($db) > 0) {
- $current_db = $GLOBALS['dbi']->fetchValue('SELECT DATABASE()');
- // $current_db is false, except when a USE statement was sent
- return ($current_db != false) && ($db !== $current_db);
- }
-
- return false;
- }
-
- /**
- * If a table, database or column gets dropped, clean comments.
- *
- * @param string $db current database
- * @param string $table current table
- * @param string|null $column current column
- * @param bool $purge whether purge set or not
- *
- * @return void
- */
- private function cleanupRelations($db, $table, ?string $column, $purge)
- {
- if (! empty($purge) && strlen($db) > 0) {
- if (strlen($table) > 0) {
- if (isset($column) && strlen($column) > 0) {
- $this->relationCleanup->column($db, $table, $column);
- } else {
- $this->relationCleanup->table($db, $table);
- }
- } else {
- $this->relationCleanup->database($db);
- }
- }
- }
-
- /**
- * Function to count the total number of rows for the same 'SELECT' query without
- * the 'LIMIT' clause that may have been programatically added
- *
- * @param int $num_rows number of rows affected/changed by the query
- * @param bool $justBrowsing whether just browsing or not
- * @param string $db the current database
- * @param string $table the current table
- * @param array $analyzed_sql_results the analyzed query and other variables set
- * after analyzing the query
- *
- * @return int unlimited number of rows
- */
- private function countQueryResults(
- $num_rows,
- $justBrowsing,
- $db,
- $table,
- array $analyzed_sql_results
- ) {
-
- /* Shortcut for not analyzed/empty query */
- if (empty($analyzed_sql_results)) {
- return 0;
- }
-
- if (! $this->isAppendLimitClause($analyzed_sql_results)) {
- // if we did not append a limit, set this to get a correct
- // "Showing rows..." message