Skip to content

Commit

Permalink
rfe #933 Manage multiple variable in bookmarked query
Browse files Browse the repository at this point in the history
Signed-off-by: Madhura Jayaratne <madhura.cj@gmail.com>
  • Loading branch information
madhuracj committed Mar 23, 2015
1 parent 856b984 commit b48f1ea
Show file tree
Hide file tree
Showing 8 changed files with 101 additions and 38 deletions.
1 change: 1 addition & 0 deletions ChangeLog
Expand Up @@ -10,6 +10,7 @@ phpMyAdmin - ChangeLog
+ rfe #1620 Support MySQL 5.7 syntax for password change
+ rfe #1626 Display/edit index name
+ rfe #1625 Toggle autocomplete of table and column names
+ rfe #933 Manage multiple variable in bookmarked query

4.4.0.0 (not yet released)
+ rfe #1553 InnoDB presently supports one FULLTEXT index creation at a time
Expand Down
32 changes: 12 additions & 20 deletions doc/faq.rst
Expand Up @@ -1601,7 +1601,7 @@ mimetypes by heart so he/she can enter it at will?

.. _faqbookmark:

6.18 Bookmarks: Where can I store bookmarks? Why can't I see any bookmarks below the query box? What is this variable for?
6.18 Bookmarks: Where can I store bookmarks? Why can't I see any bookmarks below the query box? What are these variables for?
--------------------------------------------------------------------------------------------------------------------------

Any query you have executed can be stored as a bookmark on the page
Expand All @@ -1611,39 +1611,38 @@ stored a bookmark, it is related to the database you run the query on.
You can now access a bookmark dropdown on each page, the query box
appears on for that database.

You can also have, inside the query, a placeholder for a variable.
This is done by inserting into the query a SQL comment between ``/*`` and
``*/``. Inside the comment, the special string ``[VARIABLE]`` is used.
Be aware that the whole query minus the SQL comment must be
You can also have, inside the query, placeholders for variables.
This is done by inserting into the query SQL comments between ``/*`` and
``*/``. Inside the comments, the special strings ``[VARIABLE{variable-number}]`` is used.
Be aware that the whole query minus the SQL comments must be
valid by itself, otherwise you won't be able to store it as a bookmark.

When you execute the bookmark, everything typed into the *value*
input box on the query box page will replace the string ``/*[VARIABLE]*/`` in
When you execute the bookmark, everything typed into the *Variables*
input boxes on the query box page will replace the strings ``/*[VARIABLE{variable-number}]*/`` in
your stored query.

Also remember, that everything else inside the ``/*[VARIABLE]*/`` string for
Also remember, that everything else inside the ``/*[VARIABLE{variable-number}]*/`` string for
your query will remain the way it is, but will be stripped of the ``/**/``
chars. So you can use:

.. code-block:: mysql
/*, [VARIABLE] AS myname */
/*, [VARIABLE1] AS myname */
which will be expanded to

.. code-block:: mysql
, VARIABLE as myname
, VARIABLE1 as myname
in your query, where VARIABLE is the string you entered in the input box. If an
empty string is provided, no replacements are made.
in your query, where VARIABLE1 is the string you entered in the Variable 1 input box.

A more complex example. Say you have stored
this query:

.. code-block:: mysql
SELECT Name, Address FROM addresses WHERE 1 /* AND Name LIKE '%[VARIABLE]%' */
SELECT Name, Address FROM addresses WHERE 1 /* AND Name LIKE '%[VARIABLE1]%' */
Say, you now enter "phpMyAdmin" as the variable for the stored query, the full
query will be:
Expand All @@ -1652,18 +1651,11 @@ query will be:
SELECT Name, Address FROM addresses WHERE 1 AND Name LIKE '%phpMyAdmin%'
You can use multiple occurrences of ``/*[VARIABLE]*/`` in a single query
(that is, multiple occurrences of the *same* variable).

**NOTE THE ABSENCE OF SPACES** inside the ``/**/`` construct. Any spaces
inserted there will be later also inserted as spaces in your query and may lead
to unexpected results especially when using the variable expansion inside of a
"LIKE ''" expression.

Your initial query which is going to be stored as a bookmark has to yield at
least one result row so you can store the bookmark. You may have that to work
around using well positioned ``/**/`` comments.

.. _faq6_19:

6.19 How can I create simple LATEX document to include exported table?
Expand Down
6 changes: 2 additions & 4 deletions import.php
Expand Up @@ -310,10 +310,8 @@
isset($_REQUEST['action_bookmark_all'])
);
if (! empty($_REQUEST['bookmark_variable'])) {
$import_text = preg_replace(
'|/\*(.*)\[VARIABLE\](.*)\*/|imsU',
'${1}' . PMA_Util::sqlAddSlashes($_REQUEST['bookmark_variable']) . '${2}',
$import_text
$import_text = PMA_Bookmark_applyVariables(
$import_text, $_REQUEST['bookmark_variable']
);
}

Expand Down
1 change: 1 addition & 0 deletions js/messages.php
Expand Up @@ -306,6 +306,7 @@
$js_messages['strNotValidRowNumber'] = __('%d is not valid row number.');
$js_messages['strBrowseForeignValues'] = __('Browse foreign values');
$js_messages['strNoAutoSavedQuery'] = __('No auto-saved query');
$js_messages['strBookmarkVariable'] = __('Variable %d:');

/* For Central list of columns */
$js_messages['pickColumn'] = __('Pick');
Expand Down
26 changes: 26 additions & 0 deletions js/sql.js
Expand Up @@ -91,6 +91,7 @@ AJAX.registerTeardown('sql.js', function () {
$(document).off('stickycolumns', ".sqlqueryresults");
$("#togglequerybox").unbind('click');
$(document).off('click', "#button_submit_query");
$(document).off('change', '#id_bookmark')
$("input[name=bookmark_variable]").unbind("keypress");
$(document).off('submit', "#sqlqueryform.ajax");
$(document).off('click', "input[name=navig].ajax");
Expand Down Expand Up @@ -267,6 +268,31 @@ AJAX.registerOnload('sql.js', function () {
// let normal event propagation happen
});

/**
* Event handler to show appropiate number of variable boxes
* based on the bookmarked query
*/
$(document).on('change', '#id_bookmark', function (event) {

var varCount = $(this).find('option:selected').data('varcount');
if (typeof varCount == 'undefined') {
varCount = 0;
}

var $varDiv = $('#bookmark_variables');
$varDiv.empty();
for (var i = 1; i <= varCount; i++) {
$varDiv.append($('<label for="bookmark_variable_' + i + '">' + PMA_sprintf(PMA_messages.strBookmarkVariable, i) + '</label>'));
$varDiv.append($('<input type="text" size="10" name="bookmark_variable[' + i + ']" id="bookmark_variable_' + i + '"></input>'));
}

if (varCount == 0) {
$varDiv.parent('.formelement').hide();
} else {
$varDiv.parent('.formelement').show();
}
});

/**
* Event handler for hitting enter on sqlqueryform bookmark_variable
* (the Variable textfield in Bookmarked SQL query section)
Expand Down
54 changes: 49 additions & 5 deletions libraries/bookmark.lib.php
Expand Up @@ -65,26 +65,26 @@ function PMA_Bookmark_getList($db = false)
}

if ($db !== false) {
$query = 'SELECT label, id FROM ' . PMA_Util::backquote($cfgBookmark['db'])
$query = 'SELECT query, label, id FROM ' . PMA_Util::backquote($cfgBookmark['db'])
. '.' . PMA_Util::backquote($cfgBookmark['table'])
. ' WHERE dbase = \'' . PMA_Util::sqlAddSlashes($db) . '\''
. ' AND user = \'' . PMA_Util::sqlAddSlashes($cfgBookmark['user']) . '\''
. ' ORDER BY label';
$per_user = $GLOBALS['dbi']->fetchResult(
$query, 'id', 'label', $controllink, PMA_DatabaseInterface::QUERY_STORE
$query, 'id', null, $controllink, PMA_DatabaseInterface::QUERY_STORE
);

$query = 'SELECT label, id FROM ' . PMA_Util::backquote($cfgBookmark['db'])
$query = 'SELECT query, label, id FROM ' . PMA_Util::backquote($cfgBookmark['db'])
. '.' . PMA_Util::backquote($cfgBookmark['table'])
. ' WHERE dbase = \'' . PMA_Util::sqlAddSlashes($db) . '\''
. ' AND user = \'\''
. ' ORDER BY label';
$global = $GLOBALS['dbi']->fetchResult(
$query, 'id', 'label', $controllink, PMA_DatabaseInterface::QUERY_STORE
$query, 'id', null, $controllink, PMA_DatabaseInterface::QUERY_STORE
);

foreach ($global as $key => $val) {
$global[$key] = $val . ' (' . __('shared') . ')';
$global[$key]['label'] = $val['label'] . ' (' . __('shared') . ')';
}

$ret = $global + $per_user;
Expand Down Expand Up @@ -228,4 +228,48 @@ function PMA_Bookmark_delete($id)
return $GLOBALS['dbi']->tryQuery($query, $controllink);
} // end of the 'PMA_Bookmark_delete()' function

/**
* Returns the number of variables in a bookmark
*
* @param string $query bookmarked query
*
* @return number number of variables
*/
function PMA_Bookmark_getVariableCount($query)
{
$matches = array();
preg_match_all("/\[VARIABLE[0-9]*\]/", $query, $matches, PREG_SET_ORDER);
return count($matches);
}

/**
* Replace the placeholders in the bookmark query with variables
*
* @param string $query bookmarked query
* @param array $variables variables to apply
*
* @return string query with variables applied
*/
function PMA_Bookmark_applyVariables($query, $variables)

This comment has been minimized.

Copy link
@lem9

lem9 Apr 9, 2015

Contributor
{
// remove comments that encloses a variable placeholder
$query = preg_replace(
'|/\*(.*\[VARIABLE[0-9]*\].*)\*/|imsU',
'${1}',
$query
);
// replace variable placeholders with values
for ($i = 1; $i <= PMA_Bookmark_getVariableCount($query); $i++) {

This comment has been minimized.

Copy link
@lem9

lem9 Apr 9, 2015

Contributor

This comment has been minimized.

Copy link
@madhuracj

madhuracj Apr 9, 2015

Author Contributor

Thanks Marc.

$var = '';
if (! empty($_REQUEST['bookmark_variable'][$i])) {
$var = PMA_Util::sqlAddSlashes($_REQUEST['bookmark_variable'][$i]);
}
$query = str_replace('[VARIABLE' . $i . ']', $var, $query);
// backward compatibility
if ($i == 1) {
$query = str_replace('[VARIABLE]', $var, $query);
}
}
return $query;
}
?>
2 changes: 1 addition & 1 deletion libraries/sql.lib.php
Expand Up @@ -1084,7 +1084,7 @@ function PMA_storeTheQueryAsBookmark($db, $bkm_user, $sql_query_for_bookmark,
if (isset($bkm_replace)) {
$bookmarks = PMA_Bookmark_getList($db);
foreach ($bookmarks as $key => $val) {
if ($val == $bkm_label) {
if ($val['label'] == $bkm_label) {
PMA_Bookmark_delete($key);
}
}
Expand Down
17 changes: 9 additions & 8 deletions libraries/sql_query_form.lib.php
Expand Up @@ -364,19 +364,15 @@ function PMA_getHtmlForSqlQueryFormBookmark()
$html .= '<select name="id_bookmark" id="id_bookmark">' . "\n";
$html .= '<option value="">&nbsp;</option>' . "\n";
foreach ($bookmark_list as $key => $value) {
$html .= '<option value="' . htmlspecialchars($key) . '">'
. htmlspecialchars($value) . '</option>' . "\n";
$html .= '<option value="' . htmlspecialchars($key) . '"'
. ' data-varcount="' . PMA_Bookmark_getVariableCount($value['query'])
.'">'
. htmlspecialchars($value['label']) . '</option>' . "\n";
}
// &nbsp; is required for correct display with styles/line height
$html .= '</select>&nbsp;' . "\n";
$html .= '</div>' . "\n";
$html .= '<div class="formelement">' . "\n";
$html .= __('Variable');
$html .= PMA_Util::showDocu('faq', 'faqbookmark');
$html .= '<input type="text" name="bookmark_variable" class="textfield"'
. ' size="10" />' . "\n";
$html .= '</div>' . "\n";
$html .= '<div class="formelement">' . "\n";
$html .= '<input type="radio" name="action_bookmark" value="0"'
. ' id="radio_bookmark_exe" checked="checked" />'
. '<label for="radio_bookmark_exe">' . __('Submit')
Expand All @@ -391,6 +387,11 @@ function PMA_getHtmlForSqlQueryFormBookmark()
. '</label>' . "\n";
$html .= '</div>' . "\n";
$html .= '<div class="clearfloat"></div>' . "\n";
$html .= '<div class="formelement hide">' . "\n";
$html .= __('Variables');
$html .= PMA_Util::showDocu('faq', 'faqbookmark');
$html .= '<div id="bookmark_variables"></div>';
$html .= '</div>' . "\n";
$html .= '</fieldset>' . "\n";

$html .= '<fieldset id="fieldsetBookmarkOptionsFooter" class="tblFooters">';
Expand Down

0 comments on commit b48f1ea

Please sign in to comment.