Merge remote-tracking branch 'origin/master'

This commit is contained in:
Weblate 2017-11-14 04:00:39 +01:00
commit 2da54c8140
5 changed files with 268 additions and 195 deletions

View File

@ -1,58 +1,30 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* query by example the whole database
* Handles database multi-table querying
*
* @package PhpMyAdmin
*/
use PhpMyAdmin\Database\MultiTableQuery;
use PhpMyAdmin\ParseAnalyze;
use PhpMyAdmin\Response;
use PhpMyAdmin\Sql;
require_once 'libraries/common.inc.php';
if (isset($_REQUEST['sql_query'])) {
$sql_query = $_REQUEST['sql_query'];
$db = $_REQUEST['db'];
list(
$analyzed_sql_results,
$db,
$table_from_sql
) = ParseAnalyze::sqlQuery($sql_query, $db);
extract($analyzed_sql_results);
$goto = 'db_multi_table_query.php';
$html_output = Sql::executeQueryAndSendQueryResponse(
null, // analyzed_sql_results
false, // is_gotofile
$db, // db
null, // table
null, // find_real_end
null, // sql_query_for_bookmark - see below
null, // extra_data
null, // message_to_show
null, // message
null, // sql_data
$goto, // goto
$pmaThemeImage, // pmaThemeImage
null, // disp_query
null, // disp_message
null, // query_type
$sql_query, // sql_query
null, // selectedTables
null // complete_query
MultiTableQuery::displayResults(
$_REQUEST['sql_query'],
$_REQUEST['db'],
$pmaThemeImage
);
exit;
} else {
$response = Response::getInstance();
$header = $response->getHeader();
$scripts = $header->getScripts();
$scripts->addFile('vendor/jquery/jquery.md5.js');
$scripts->addFile('db_multi_table_query.js');
$queryInstance = new MultiTableQuery($GLOBALS['dbi'], $db);
$response->addHTML($queryInstance->getFormHtml());
}
$response = Response::getInstance();
$header = $response->getHeader();
$scripts = $header->getScripts();
$scripts->addFile('vendor/jquery/jquery.md5.js');
$scripts->addFile('db_multi_table_query.js');
$QueryInstance = new MultiTableQuery($db);
$response->addHTML($QueryInstance->getFormHTML());

View File

@ -7,6 +7,9 @@
*/
namespace PhpMyAdmin\Database;
use PhpMyAdmin\DatabaseInterface;
use PhpMyAdmin\ParseAnalyze;
use PhpMyAdmin\Sql;
use PhpMyAdmin\Template;
/**
@ -16,44 +19,116 @@ use PhpMyAdmin\Template;
*/
class MultiTableQuery
{
/**
* DatabaseInterface instance
*
* @access private
* @var DatabaseInterface
*/
private $dbi;
/**
* Database name
*
* @access private
* @var string
*/
private $_db;
private $db;
/**
* Default no. of columns
* Default number of columns
*
* @access private
* @var integer
*/
private $_default_no_of_columns;
private $defaultNoOfColumns;
public function __construct($db_name)
{
$this->_db = $db_name;
$this->_default_no_of_columns = 3;
/**
* Table names
*
* @access private
* @var array
*/
private $tables;
/**
* Constructor
*
* @param DatabaseInterface $dbi DatabaseInterface instance
* @param string $dbName Database name
* @param integer $defaultNoOfColumns Default number of columns
*/
public function __construct(
DatabaseInterface $dbi,
$dbName,
$defaultNoOfColumns = 3
) {
$this->dbi = $dbi;
$this->db = $dbName;
$this->defaultNoOfColumns = $defaultNoOfColumns;
$this->tables = $this->dbi->getTables($this->db);
}
private function getColumnsHTML()
{
$tables = $GLOBALS['dbi']->getTables($this->_db);
return Template::get('database/multi_table_query/columns')->render([
'tables' => $tables,
'dbi' => $GLOBALS['dbi'],
'db' => $this->_db,
'default_no_of_columns' => $this->_default_no_of_columns,
]);
}
public function getFormHTML()
/**
* Get Multi-Table query page HTML
*
* @return string Multi-Table query page HTML
*/
public function getFormHtml()
{
$tables = [];
foreach($this->tables as $table) {
$tables[$table]['hash'] = md5($table);
$tables[$table]['columns'] = array_keys(
$this->dbi->getColumns($this->db, $table)
);
}
return Template::get('database/multi_table_query/form')->render([
'db' => $this->_db,
'columns' => $this->getColumnsHTML(),
'db' => $this->db,
'tables' => $tables,
'default_no_of_columns' => $this->defaultNoOfColumns,
]);
}
/**
* Displays multi-table query results
*
* @param string $sqlQuery The query to parse
* @param string $db The current database
* @param string $pmaThemeImage Uri of the PMA theme image
*
* @return void
*/
public static function displayResults($sqlQuery, $db, $pmaThemeImage)
{
list(
$analyzedSqlResults,
$db,
$tableFromSql
) = ParseAnalyze::sqlQuery($sqlQuery, $db);
extract($analyzedSqlResults);
$goto = 'db_multi_table_query.php';
Sql::executeQueryAndSendQueryResponse(
null, // analyzed_sql_results
false, // is_gotofile
$db, // db
null, // table
null, // find_real_end
null, // sql_query_for_bookmark - see below
null, // extra_data
null, // message_to_show
null, // message
null, // sql_data
$goto, // goto
$pmaThemeImage, // pmaThemeImage
null, // disp_query
null, // disp_message
null, // query_type
$sqlQuery, // sql_query
null, // selectedTables
null // complete_query
);
}
}

View File

@ -1,34 +0,0 @@
<fieldset>
{% set tables_count = tables|length - 1 %}
{% for i in 0..tables_count %}
<div style="display:none" id="{{ md5(tables[i]) }}">
{% set table_fields = dbi.getColumns(db, tables[i]) %}
<option value="*">*</option>
{% for key in table_fields|keys %}
<option value="{{ key }}">{{ key }}</option>
{% endfor %}
</div>
{% endfor %}
<div style="display:none" id="new_column_layout">
{% include 'database/multi_table_query/new_column.twig' with {
'id': 0,
'tables': tables
} only %}
</div>
{% for i in 1..default_no_of_columns %}
{% include 'database/multi_table_query/new_column.twig' with {
'id': i,
'tables': tables
} only %}
{% endfor %}
<fieldset style="display:inline">
<input type="button" value="{% trans '+ Add column' %}" id="add_column_button">
<br> &nbsp;
</fieldset>
<fieldset>
<textarea cols="80" rows="4" style="float:left" name="sql_query" id="MultiSqlquery" dir="ltr"></textarea>
</fieldset>
</fieldset>

View File

@ -1,11 +1,165 @@
{{ Util_getDivForSliderEffect('query_div', 'Query window'|trans, 'open') }}
<form action="" id="query_form">
<input type="hidden" id="db_name" value="{{ db }}">
{{ columns|raw }}
<fieldset>
{% for table in tables %}
<div style="display:none" id="{{ table.hash }}">
<option value="*">*</option>
{% for column in table.columns %}
<option value="{{ column }}">{{ column }}</option>
{% endfor %}
</div>
{% endfor %}
{% for id in 0..default_no_of_columns %}
{% if id == 0 %}<div style="display:none" id="new_column_layout">{% endif %}
<fieldset style="display:inline" class="column_details">
<select style="display:inline" class="tableNameSelect">
<option value="">{% trans 'select table' %}</option>
{% for table in tables|keys %}
<option value="{{ table }}">{{ table }}</option>
{% endfor %}
</select>
<span>.</span>
<select style="display:inline" class="columnNameSelect">
<option value="">{% trans 'select column' %}</option>
</select>
<br>
<input type="checkbox" checked="checked" class="show_col">
<span>{% trans 'Show' %}</span>
<br>
<input type="text" placeholder="{% trans 'Table alias' %}" class="table_alias">
<input type="text" placeholder="{% trans 'Column alias' %}" class="col_alias">
<br>
<input type="checkbox"
title="{% trans 'Use this column in criteria' %}"
class="criteria_col">
{% include 'div_for_slider_effect.twig' with {
'id': 'criteria_div' ~ id,
'initial_sliders_state': 'closed',
'message': 'criteria'|trans
} %}
<div>
<table>
<tr class="sort_order" style="background:none">
<td>{% trans 'Sort' %}</td>
<td><input type="radio" name="sort[{{ id }}]">{% trans 'Ascending' %}</td>
<td><input type="radio" name="sort[{{ id }}]">{% trans 'Descending' %}</td>
</tr>
<tr class="logical_operator" style="background:none;display:none">
<td>{% trans 'Add as' %}</td>
<td>
<input type="radio"
name="logical_op[{{ id }}]"
value="AND"
class="logical_op"
checked="checked">
AND
</td>
<td>
<input type="radio"
name="logical_op[{{ id }}]"
value="OR"
class="logical_op">
OR
</td>
</tr>
<tr style="background:none">
<td>Op </td>
<td>
<select class="criteria_op">
<option value="=">=</option>
<option value=">">&gt;</option>
<option value=">=">&gt;=</option>
<option value="<">&lt;</option>
<option value="<=">&lt;=</option>
<option value="!=">!=</option>
<option value="LIKE">LIKE</option>
<option value="LIKE %...%">LIKE %...%</option>
<option value="NOT LIKE">NOT LIKE</option>
<option value="IN (...)">IN (...)</option>
<option value="NOT IN (...)">NOT IN (...)</option>
<option value="BETWEEN">BETWEEN</option>
<option value="NOT BETWEEN">NOT BETWEEN</option>
<option value="IS NULL">IS NULL</option>
<option value="IS NOT NULL">IS NOT NULL</option>
<option value="REGEXP">REGEXP</option>
<option value="REGEXP ^...$">REGEXP ^...$</option>
<option value="NOT REGEXP">NOT REGEXP</option>
</select>
</td>
<td>
<select class="criteria_rhs">
<option value="text">{% trans 'Text' %}</option>
<option value="anotherColumn">{% trans 'Another column' %}</option>
</select>
</td>
</tr>
<tr class="rhs_table" style="display:none;background:none">
<td></td>
<td>
<select class="tableNameSelect">
<option value="">{% trans 'select table' %}</option>
{% for table in tables|keys %}
<option value="{{ table }}">{{ table }}</option>
{% endfor %}
</select><span>.</span>
</td>
<td>
<select style="display:inline" class="columnNameSelect">
<option value="">{% trans 'select column' %}</option>
</select>
</td>
</tr>
<tr style="background:none" class="rhs_text">
<td></td>
<td colspan="2">
<input type="text"
style="width:91%"
class="rhs_text_val"
placeholder="{% trans 'Enter criteria as free text' %}">
</td>
</tr>
</table>
</div>
</div>
<a href="#"
title="{% trans 'Remove this column' %}"
style="float:right;color:red"
class="removeColumn">
X
</a>
</fieldset>
{% if id == 0 %}</div>{% endif %}
{% endfor %}
<fieldset style="display:inline">
<input type="button" value="{% trans '+ Add column' %}" id="add_column_button">
</fieldset>
<fieldset>
{% spaceless %}
<textarea id="MultiSqlquery"
cols="80"
rows="4"
style="float:left"
name="sql_query"
dir="ltr">
</textarea>
{% endspaceless %}
</fieldset>
</fieldset>
<fieldset class="tblFooters">
<input type="button" id="update_query_button" value="{% trans 'Update query' %}">
<input type="button" id="submit_query" value="{% trans 'Submit query' %}">
</fieldset>
</form>
</div>
</div>{# Slider div #}
<div id="sql_results"></div>

View File

@ -1,94 +0,0 @@
<fieldset style="display:inline" class="column_details">
<select style="display:inline" class="tableNameSelect">
<option value="">{% trans 'select table' %}</option>
{% for table in tables %}
<option value="{{ table }}"> {{ table }} </option>
{% endfor %}
</select>
<span>.</span>
<select style="display:inline" class="columnNameSelect">
<option value="">{% trans 'select column' %}</option>
</select>
<br> <input type="checkbox" checked="checked" class="show_col"> <span>{% trans 'Show' %}</span>
<br> <input type="text" placeholder="{% trans 'Table alias' %}" class="table_alias"> <input type="text" placeholder="{% trans 'Column alias' %}" class="col_alias">
<br>
<input type="checkbox" title="{% trans 'Use this column in criteria' %}" class="criteria_col">
{% include 'div_for_slider_effect.twig' with {
'id': 'criteria_div' ~ id,
'initial_sliders_state': 'closed',
'message': 'criteria'|trans
} %}
<div>
<table>
<tr class="sort_order" style="background:none">
<td>{% trans 'Sort' %}</td>
<td><input type="radio" name="sort[{{ id }}]">{% trans 'Ascending' %}</td>
<td><input type="radio" name="sort[{{ id }}]">{% trans 'Descending' %}</td>
</tr>
<tr class="logical_operator" style="background:none;display:none">
<td>{% trans 'Add as' %}</td>
<td><input type="radio" name="logical_op[{{ id }}]" value="AND" class="logical_op" checked="checked">AND</td>
<td><input type="radio" name="logical_op[{{ id }}]" value="OR" class="logical_op">OR</td>
</tr>
<tr style="background:none">
<td>Op </td>
<td>
<select class="criteria_op">
<option value="=">=</option>
<option value=">">&gt;</option>
<option value=">=">&gt;=</option>
<option value="<">&lt;</option>
<option value="<=">&lt;=</option>
<option value="!=">!=</option>
<option value="LIKE">LIKE</option>
<option value="LIKE %...%">LIKE %...%</option>
<option value="NOT LIKE">NOT LIKE</option>
<option value="IN (...)">IN (...)</option>
<option value="NOT IN (...)">NOT IN (...)</option>
<option value="BETWEEN">BETWEEN</option>
<option value="NOT BETWEEN">NOT BETWEEN</option>
<option value="IS NULL">IS NULL</option>
<option value="IS NOT NULL">IS NOT NULL</option>
<option value="REGEXP">REGEXP</option>
<option value="REGEXP ^...$">REGEXP ^...$</option>
<option value="NOT REGEXP">NOT REGEXP</option>
</select>
</td>
<td>
<select class="criteria_rhs">
<option value="text">{% trans 'Text' %}</option>
<option value="anotherColumn">{% trans 'Another column' %}</option>
</select>
</td>
</tr>
<tr class="rhs_table" style="display:none;background:none">
<td></td>
<td>
<select class="tableNameSelect">
<option value="">{% trans 'select table' %}</option>
{% for table in tables %}
<option value="{{ table }}"> {{ table }} </option>
{% endfor %}
</select><span>.</span>
</td>
<td>
<select style="display:inline" class="columnNameSelect">
<option value="">{% trans 'select column' %}</option>
</select>
</td>
</tr>
<tr style="background:none" class="rhs_text">
<td></td>
<td colspan="2"><input type="text" style="width:91%" class="rhs_text_val" placeholder="{% trans 'Enter criteria as free text' %}"></td>
</tr>
</table>
</div>
</div>
<a href="#" title="{% trans 'Remove this column' %}" style="float:right;color:red" class="removeColumn">X</a>
</fieldset>