Feature #569 Load/Save Query By Example

Implement possibility to save/load/delete a QBE on a DB.

Signed-off-by: Hugues Peccatte <hugues.peccatte@gmail.com>
This commit is contained in:
Hugues Peccatte 2014-02-23 14:52:48 +01:00
parent b7f5acff6b
commit 8b84cf0d91
12 changed files with 796 additions and 101 deletions

View File

@ -60,6 +60,7 @@ $cfg['Servers'][$i]['AllowNoPassword'] = false;
// $cfg['Servers'][$i]['users'] = 'pma__users';
// $cfg['Servers'][$i]['usergroups'] = 'pma__usergroups';
// $cfg['Servers'][$i]['navigationhiding'] = 'pma__navigationhiding';
// $cfg['Servers'][$i]['savedsearches'] = 'pma__savedsearches';
/* Contrib / Swekey authentication */
// $cfg['Servers'][$i]['auth_swekey_config'] = '/etc/swekey-pma.conf';
@ -145,7 +146,7 @@ $cfg['SaveDir'] = '';
/**
* Should error reporting be enabled for JavaScript errors
*
* default = 'ask'
* default = 'ask'
*/
//$cfg['SendErrorReports'] = 'ask';

View File

@ -19,6 +19,47 @@ $response = PMA_Response::getInstance();
// Gets the relation settings
$cfgRelation = PMA_getRelationsParam();
$savedSearchList = array();
$currentSearchId = null;
if ($cfgRelation['savedsearcheswork']) {
include 'libraries/SavedSearches.php';
$header = $response->getHeader();
$scripts = $header->getScripts();
$scripts->addFile('db_qbe.js');
//Get saved search list.
$savedSearch = new PMA_SavedSearches($GLOBALS);
$savedSearch->setId($_REQUEST['searchId'])
->setUsername($GLOBALS['cfg']['Server']['user'])
->setDbname($_REQUEST['db'])
->setSearchName($_REQUEST['searchName']);
//Criterias field is filled only when clicking on "Save search".
if (!empty($_REQUEST['action'])) {
if ('save' === $_REQUEST['action']) {
$saveResult = $savedSearch->setCriterias($_REQUEST)
->save();
/*if (!$saveResult) {
$response->addHTML('raté');
exit();
}*/
} elseif ('delete' === $_REQUEST['action']) {
$deleteResult = $savedSearch->delete();
//After deletion, reset search.
$savedSearch = new PMA_SavedSearches($GLOBALS);
$savedSearch->setUsername($GLOBALS['cfg']['Server']['user'])
->setDbname($_REQUEST['db']);
$_REQUEST = array();
} elseif ('load' === $_REQUEST['action']) {
$loadResult = $savedSearch->load();
}
//Else, it's an "update query"
}
$savedSearchList = $savedSearch->getList();
$currentSearchId = $savedSearch->getId();
}
/**
* A query has been submitted -> (maybe) execute it
*/
@ -52,7 +93,7 @@ if ($message_to_display) {
unset($message_to_display);
// create new qbe search instance
$db_qbe = new PMA_DBQbe($GLOBALS['db']);
$db_qbe = new PMA_DBQbe($GLOBALS['db'], $savedSearchList, $savedSearch);
/**
* Displays the Query by example form

View File

@ -47,4 +47,5 @@ foreach ($hosts as $host) {
$cfg['Servers'][$i]['users'] = 'pma__users';
$cfg['Servers'][$i]['usergroups'] = 'pma__usergroups';
$cfg['Servers'][$i]['navigationhiding'] = 'pma__navigationhiding';
$cfg['Servers'][$i]['savedsearches'] = 'pma__savedsearches';
}

View File

@ -1,40 +1,40 @@
-- --------------------------------------------------------
-- SQL Commands to set up the pmadb as described in the documentation.
--
--
-- This file is meant for use with MySQL 5 and above!
--
--
-- This script expects the user pma to already be existing. If we would put a
-- line here to create him too many users might just use this script and end
-- up with having the same password for the controluser.
--
-- This user "pma" must be defined in config.inc.php (controluser/controlpass)
--
-- Please don't forget to set up the tablenames in config.inc.php
--
--
-- This user "pma" must be defined in config.inc.php (controluser/controlpass)
--
-- Please don't forget to set up the tablenames in config.inc.php
--
-- --------------------------------------------------------
--
--
-- Database : `phpmyadmin`
--
--
CREATE DATABASE IF NOT EXISTS `phpmyadmin`
DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;
USE phpmyadmin;
-- --------------------------------------------------------
--
--
-- Privileges
--
--
-- (activate this statement if necessary)
-- GRANT SELECT, INSERT, DELETE, UPDATE ON `phpmyadmin`.* TO
-- 'pma'@localhost;
-- --------------------------------------------------------
--
--
-- Table structure for table `pma__bookmark`
--
--
CREATE TABLE IF NOT EXISTS `pma__bookmark` (
`id` int(11) NOT NULL auto_increment,
@ -49,9 +49,9 @@ CREATE TABLE IF NOT EXISTS `pma__bookmark` (
-- --------------------------------------------------------
--
--
-- Table structure for table `pma__column_info`
--
--
CREATE TABLE IF NOT EXISTS `pma__column_info` (
`id` int(5) unsigned NOT NULL auto_increment,
@ -70,9 +70,9 @@ CREATE TABLE IF NOT EXISTS `pma__column_info` (
-- --------------------------------------------------------
--
--
-- Table structure for table `pma__history`
--
--
CREATE TABLE IF NOT EXISTS `pma__history` (
`id` bigint(20) unsigned NOT NULL auto_increment,
@ -89,9 +89,9 @@ CREATE TABLE IF NOT EXISTS `pma__history` (
-- --------------------------------------------------------
--
--
-- Table structure for table `pma__pdf_pages`
--
--
CREATE TABLE IF NOT EXISTS `pma__pdf_pages` (
`db_name` varchar(64) NOT NULL default '',
@ -136,9 +136,9 @@ CREATE TABLE IF NOT EXISTS `pma__table_uiprefs` (
-- --------------------------------------------------------
--
--
-- Table structure for table `pma__relation`
--
--
CREATE TABLE IF NOT EXISTS `pma__relation` (
`master_db` varchar(64) NOT NULL default '',
@ -155,9 +155,9 @@ CREATE TABLE IF NOT EXISTS `pma__relation` (
-- --------------------------------------------------------
--
--
-- Table structure for table `pma__table_coords`
--
--
CREATE TABLE IF NOT EXISTS `pma__table_coords` (
`db_name` varchar(64) NOT NULL default '',
@ -172,9 +172,9 @@ CREATE TABLE IF NOT EXISTS `pma__table_coords` (
-- --------------------------------------------------------
--
--
-- Table structure for table `pma__table_info`
--
--
CREATE TABLE IF NOT EXISTS `pma__table_info` (
`db_name` varchar(64) NOT NULL default '',
@ -187,9 +187,9 @@ CREATE TABLE IF NOT EXISTS `pma__table_info` (
-- --------------------------------------------------------
--
--
-- Table structure for table `pma__designer_coords`
--
--
CREATE TABLE IF NOT EXISTS `pma__designer_coords` (
`db_name` varchar(64) NOT NULL default '',
@ -205,9 +205,9 @@ CREATE TABLE IF NOT EXISTS `pma__designer_coords` (
-- --------------------------------------------------------
--
--
-- Table structure for table `pma__tracking`
--
--
CREATE TABLE IF NOT EXISTS `pma__tracking` (
`db_name` varchar(64) NOT NULL,
@ -250,7 +250,7 @@ CREATE TABLE IF NOT EXISTS `pma__users` (
`username` varchar(64) NOT NULL,
`usergroup` varchar(64) NOT NULL,
PRIMARY KEY (`username`,`usergroup`)
)
)
COMMENT='Users and their assignments to user groups'
DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;
@ -265,10 +265,10 @@ CREATE TABLE IF NOT EXISTS `pma__usergroups` (
`tab` varchar(64) NOT NULL,
`allowed` enum('Y','N') NOT NULL DEFAULT 'N',
PRIMARY KEY (`usergroup`,`tab`,`allowed`)
)
)
COMMENT='User groups with configured menu items'
DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;
-- --------------------------------------------------------
--
@ -282,6 +282,24 @@ CREATE TABLE IF NOT EXISTS `pma__navigationhiding` (
`db_name` varchar(64) NOT NULL,
`table_name` varchar(64) NOT NULL,
PRIMARY KEY (`username`,`item_name`,`item_type`,`db_name`,`table_name`)
)
)
COMMENT='Hidden items of navigation tree'
DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;
-- --------------------------------------------------------
--
-- Table structure for table `pma__savedsearches`
--
CREATE TABLE IF NOT EXISTS `pma__savedsearches` (
`id` int(5) unsigned NOT NULL auto_increment,
`username` varchar(64) NOT NULL default '',
`db_name` varchar(64) NOT NULL default '',
`search_name` varchar(64) NOT NULL default '',
`search_data` text NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `u_savedsearches_username_dbname` (`username`,`db_name`,`search_name`)
)
COMMENT='Saved searches'
DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;

View File

@ -1,27 +1,27 @@
-- --------------------------------------------------------
-- SQL Commands to set up the pmadb as described in the documentation.
--
--
-- This file is meant for use with Drizzle 2011.03.13 and above!
--
--
-- This script expects that you take care of database permissions.
--
-- Please don't forget to set up the tablenames in config.inc.php
--
--
-- --------------------------------------------------------
--
--
-- Database : `phpmyadmin`
--
--
CREATE DATABASE IF NOT EXISTS `phpmyadmin`
COLLATE utf8_bin;
USE phpmyadmin;
-- --------------------------------------------------------
--
--
-- Table structure for table `pma__bookmark`
--
--
CREATE TABLE IF NOT EXISTS `pma__bookmark` (
`id` int(11) NOT NULL auto_increment,
@ -36,9 +36,9 @@ CREATE TABLE IF NOT EXISTS `pma__bookmark` (
-- --------------------------------------------------------
--
--
-- Table structure for table `pma__column_info`
--
--
CREATE TABLE IF NOT EXISTS `pma__column_info` (
`id` int(5) NOT NULL auto_increment,
@ -57,9 +57,9 @@ CREATE TABLE IF NOT EXISTS `pma__column_info` (
-- --------------------------------------------------------
--
--
-- Table structure for table `pma__history`
--
--
CREATE TABLE IF NOT EXISTS `pma__history` (
`id` bigint(20) NOT NULL auto_increment,
@ -76,9 +76,9 @@ CREATE TABLE IF NOT EXISTS `pma__history` (
-- --------------------------------------------------------
--
--
-- Table structure for table `pma__pdf_pages`
--
--
CREATE TABLE IF NOT EXISTS `pma__pdf_pages` (
`db_name` varchar(64) NOT NULL default '',
@ -123,9 +123,9 @@ CREATE TABLE IF NOT EXISTS `pma__table_uiprefs` (
-- --------------------------------------------------------
--
--
-- Table structure for table `pma__relation`
--
--
CREATE TABLE IF NOT EXISTS `pma__relation` (
`master_db` varchar(64) NOT NULL default '',
@ -142,9 +142,9 @@ CREATE TABLE IF NOT EXISTS `pma__relation` (
-- --------------------------------------------------------
--
--
-- Table structure for table `pma__table_coords`
--
--
CREATE TABLE IF NOT EXISTS `pma__table_coords` (
`db_name` varchar(64) NOT NULL default '',
@ -159,9 +159,9 @@ CREATE TABLE IF NOT EXISTS `pma__table_coords` (
-- --------------------------------------------------------
--
--
-- Table structure for table `pma__table_info`
--
--
CREATE TABLE IF NOT EXISTS `pma__table_info` (
`db_name` varchar(64) NOT NULL default '',
@ -174,9 +174,9 @@ CREATE TABLE IF NOT EXISTS `pma__table_info` (
-- --------------------------------------------------------
--
--
-- Table structure for table `pma__designer_coords`
--
--
CREATE TABLE IF NOT EXISTS `pma__designer_coords` (
`db_name` varchar(64) NOT NULL default '',
@ -192,9 +192,9 @@ CREATE TABLE IF NOT EXISTS `pma__designer_coords` (
-- --------------------------------------------------------
--
--
-- Table structure for table `pma__tracking`
--
--
CREATE TABLE IF NOT EXISTS `pma__tracking` (
`db_name` varchar(64) NOT NULL,
@ -236,7 +236,7 @@ CREATE TABLE IF NOT EXISTS `pma__users` (
`username` varchar(64) NOT NULL,
`usergroup` varchar(64) NOT NULL,
PRIMARY KEY (`username`,`usergroup`)
)
)
COMMENT='Users and their assignments to user groups'
COLLATE utf8_bin;
@ -251,10 +251,10 @@ CREATE TABLE IF NOT EXISTS `pma__usergroups` (
`tab` varchar(64) NOT NULL,
`allowed` enum('Y','N') NOT NULL DEFAULT 'N',
PRIMARY KEY (`usergroup`,`tab`,`allowed`)
)
)
COMMENT='User groups with configured menu items'
COLLATE utf8_bin;
-- --------------------------------------------------------
--
@ -268,6 +268,24 @@ CREATE TABLE IF NOT EXISTS `pma__navigationhiding` (
`db_name` varchar(64) NOT NULL,
`table_name` varchar(64) NOT NULL,
PRIMARY KEY (`username`,`item_name`,`item_type`,`db_name`,`table_name`)
)
)
COMMENT='Hidden items of navigation tree'
COLLATE utf8_bin;
-- --------------------------------------------------------
--
-- Table structure for table `pma__savedsearches`
--
CREATE TABLE IF NOT EXISTS `pma__savedsearches` (
`id` int(5) unsigned NOT NULL auto_increment,
`username` varchar(64) NOT NULL default '',
`db_name` varchar(64) NOT NULL default '',
`search_name` varchar(64) NOT NULL default '',
`search_data` text NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `u_savedsearches_username_dbname` (`username`,`db_name`,`search_name`)
)
COMMENT='Saved searches'
DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;

55
js/db_qbe.js Normal file
View File

@ -0,0 +1,55 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* @fileoverview function used in QBE for DB
* @name Database Operations
*
* @requires jQuery
* @requires jQueryUI
* @requires js/functions.js
*
*/
/**
* Ajax event handlers here for db_qbe.php
*
* Actions Ajaxified here:
* Select saved search
*/
/**
* Unbind all event handlers before tearing down a page
*/
AJAX.registerTeardown('db_qbe.js', function () {
$("#searchId").die('change');
$("#saveSearch").die('click');
$("#deleteSearch").die('click');
});
AJAX.registerOnload('db_qbe.js', function () {
/**
* Ajax event handlers for 'Select saved search'
*/
$("#searchId").live('change', function (event) {
if ('' == $(this).val()) {
return false;
}
$('#action').val('load');
$('#formQBE').submit();
});
/**
* Ajax event handlers for 'Save search'
*/
$("#saveSearch").live('click', function (event) {
$('#action').val('save');
});
/**
* Ajax event handlers for 'Delete search'
*/
$("#deleteSearch").live('click', function (event) {
$('#action').val('delete');
});
});

View File

@ -72,6 +72,13 @@ class PMA_DbQbe
* @var array
*/
private $_criteriaRowInsert;
/**
* Whether to delete a row
*
* @access private
* @var array
*/
private $_criteriaRowDelete;
/**
* Already set criteria values
*
@ -149,6 +156,13 @@ class PMA_DbQbe
* @var array
*/
private $_curAndOrCol;
/**
* Current criteria AND/OR row relations
*
* @access private
* @var array
*/
private $_curAndOrRow;
/**
* New column count in case of add/delete
*
@ -163,15 +177,64 @@ class PMA_DbQbe
* @var integer
*/
private $_new_row_count;
/**
* List of saved searches
*
* @access private
* @var array
*/
private $_savedSearchList = null;
/**
* Current search
*
* @access private
* @var PMA_SavedSearches
*/
private $_currentSearch = null;
/**
* Initialize criterias
*
* @return static
*/
private function _loadCriterias()
{
if (null === $this->_currentSearch
|| null === $this->_currentSearch->getCriterias()
) {
return $this;
}
$criterias = $this->_currentSearch->getCriterias();
$_REQUEST = $criterias + $_REQUEST;
return $this;
}
/**
* Getter for current search
*
* @return PMA_SavedSearches
*/
private function _getCurrentSearch()
{
return $this->_currentSearch;
}
/**
* Public Constructor
*
* @param string $db Database name
* @param string $dbname Database name
* @param array $savedSearchList List of saved searches
* @param PMA_SavedSearches $currentSearch Current search id
*/
public function __construct($db)
{
$this->_db = $db;
public function __construct(
$dbname, $savedSearchList = array(), $currentSearch = null
) {
$this->_db = $dbname;
$this->_savedSearchList = $savedSearchList;
$this->_currentSearch = $currentSearch;
$this->_loadCriterias();
// Sets criteria parameters
$this->_setSearchParams();
$this->_setCriteriaTablesAndColumns();
@ -184,26 +247,7 @@ class PMA_DbQbe
*/
private function _setSearchParams()
{
// sets column count
$criteriaColumnCount = PMA_ifSetOr(
$_REQUEST['criteriaColumnCount'],
3,
'numeric'
);
$criteriaColumnAdd = PMA_ifSetOr(
$_REQUEST['criteriaColumnAdd'],
0,
'numeric'
);
$this->_criteria_column_count = max(
$criteriaColumnCount + $criteriaColumnAdd,
0
);
// sets row count
$rows = PMA_ifSetOr($_REQUEST['rows'], 0, 'numeric');
$criteriaRowAdd = PMA_ifSetOr($_REQUEST['criteriaRowAdd'], 0, 'numeric');
$this->_criteria_row_count = max($rows + $criteriaRowAdd, 0);
$criteriaColumnCount = $this->_initializeCriteriasCount();
$this->_criteriaColumnInsert = PMA_ifSetOr(
$_REQUEST['criteriaColumnInsert'],
@ -1130,20 +1174,10 @@ class PMA_DbQbe
$unique_columns = $indexes['unique'];
$index_columns = $indexes['index'];
// now we want to find the best.
if (isset($unique_columns) && count($unique_columns) > 0) {
$candidate_columns = $unique_columns;
$needsort = 1;
} elseif (isset($index_columns) && count($index_columns) > 0) {
$candidate_columns = $index_columns;
$needsort = 1;
} elseif (isset($where_clause_columns) && count($where_clause_columns) > 0) {
$candidate_columns = $where_clause_columns;
$needsort = 0;
} else {
$candidate_columns = $all_tables;
$needsort = 0;
}
list($candidate_columns, $needsort)
= $this->_getLeftJoinColumnCandidatesBest(
$all_tables, $where_clause_columns, $unique_columns, $index_columns
);
// If we came up with $unique_columns (very good) or $index_columns (still
// good) as $candidate_columns we want to check if we have any 'Y' there
@ -1348,8 +1382,13 @@ class PMA_DbQbe
*/
public function getSelectionForm($cfgRelation)
{
$html_output = '<form action="db_qbe.php" method="post">';
$html_output = '<form action="db_qbe.php" method="post" id="formQBE">';
$html_output .= '<fieldset>';
if ($GLOBALS['cfgRelation']['savedsearcheswork']) {
$html_output .= $this->_getSavedSearchesField();
}
$html_output .= '<table class="data" style="width: 100%;">';
// Get table's <tr> elements
$html_output .= $this->_getColumnNamesRow();
@ -1397,5 +1436,111 @@ class PMA_DbQbe
$html_output .= '</form>';
return $html_output;
}
/**
* Get fields to display
*
* @return string
*/
private function _getSavedSearchesField()
{
$html_output = __('Saved searches : ');
$html_output .= '<select name="searchId" id="searchId">';
$html_output .= '<option value="">New search</option>';
$currentSearch = $this->_getCurrentSearch();
$currentSearchId = null;
$currentSearchName = null;
if (null != $currentSearch) {
$currentSearchId = $currentSearch->getId();
$currentSearchName = $currentSearch->getSearchName();
}
foreach ($this->_savedSearchList as $id => $name) {
$html_output .= '<option value="' . htmlspecialchars($id)
. '" ' . (
$id == $currentSearchId
? 'selected="selected" '
: ''
)
. '>'
. htmlspecialchars($name)
. '</option>';
}
$html_output .= '</select>';
$html_output .= '<input type="text" name="searchName" id="searchName" '
. 'value="' . $currentSearchName . '" />';
$html_output .= '<input type="hidden" name="action" id="action" value="" />';
$html_output .= '<input type="submit" name="saveSearch" id="saveSearch" '
. 'value="' . __('Save search') . '" />';
$html_output .= '<input type="submit" name="deleteSearch" id="deleteSearch" '
. 'value="' . __('Delete search') . '" />';
return $html_output;
}
/**
* Initialize _criteria_column_count
*
* @return int Previous number of columns
*/
private function _initializeCriteriasCount()
{
// sets column count
$criteriaColumnCount = PMA_ifSetOr(
$_REQUEST['criteriaColumnCount'],
3,
'numeric'
);
$criteriaColumnAdd = PMA_ifSetOr(
$_REQUEST['criteriaColumnAdd'],
0,
'numeric'
);
$this->_criteria_column_count = max(
$criteriaColumnCount + $criteriaColumnAdd,
0
);
// sets row count
$rows = PMA_ifSetOr($_REQUEST['rows'], 0, 'numeric');
$criteriaRowAdd = PMA_ifSetOr($_REQUEST['criteriaRowAdd'], 0, 'numeric');
$this->_criteria_row_count = max($rows + $criteriaRowAdd, 0);
return $criteriaColumnCount;
}
/**
* Get best
*
* @param array $all_tables All tables
* @param array $where_clause_columns Columns with where clause
* @param array $unique_columns Unique columns
* @param array $index_columns Indexed columns
*
* @return array
*/
private function _getLeftJoinColumnCandidatesBest(
$all_tables, $where_clause_columns, $unique_columns, $index_columns
) {
// now we want to find the best.
if (isset($unique_columns) && count($unique_columns) > 0) {
$candidate_columns = $unique_columns;
$needsort = 1;
return array($candidate_columns, $needsort);
} elseif (isset($index_columns) && count($index_columns) > 0) {
$candidate_columns = $index_columns;
$needsort = 1;
return array($candidate_columns, $needsort);
} elseif (isset($where_clause_columns) && count($where_clause_columns) > 0) {
$candidate_columns = $where_clause_columns;
$needsort = 0;
return array($candidate_columns, $needsort);
} else {
$candidate_columns = $all_tables;
$needsort = 0;
return array($candidate_columns, $needsort);
}
}
}
?>

397
libraries/SavedSearches.php Normal file
View File

@ -0,0 +1,397 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Saved searches managing
*
* @package PhpMyAdmin
*/
if (! defined('PHPMYADMIN')) {
exit;
}
/**
* Saved searches managing
*
* @package PhpMyAdmin
*/
class PMA_SavedSearches
{
/**
* Global configuration
* @var array
*/
private $_config = null;
/**
* Id
* @var int|null
*/
private $_id = null;
/**
* Username
* @var string
*/
private $_username = null;
/**
* DB name
* @var string
*/
private $_dbname = null;
/**
* Saved search name
* @var string
*/
private $_searchName = null;
/**
* Setter of id
*
* @param int|null $searchId Id of search
*
* @return static
*/
public function setId($searchId)
{
$searchId = (int)$searchId;
if (empty($searchId)) {
$searchId = null;
}
$this->_id = $searchId;
return $this;
}
/**
* Getter of id
*
* @return int|null
*/
public function getId()
{
return $this->_id;
}
/**
* Setter of searchName
*
* @param string $searchName Saved search name
*
* @return static
*/
public function setSearchName($searchName)
{
$this->_searchName = $searchName;
return $this;
}
/**
* Getter of searchName
*
* @return string
*/
public function getSearchName()
{
return $this->_searchName;
}
/**
* Criterias
* @var array
*/
private $_criterias = null;
/**
* Setter of config
*
* @param array $config Global configuration
*
* @return static
*/
public function setConfig($config)
{
$this->_config = $config;
return $this;
}
/**
* Getter of config
*
* @return array
*/
public function getConfig()
{
return $this->_config;
}
/**
* Setter for criterias
*
* @param array $criterias Criterias of saved searches
* @param bool $json Criterias are in JSON format
*
* @return static
*/
public function setCriterias($criterias, $json = false)
{
if (true === $json) {
$this->_criterias = json_decode($criterias, true);
return $this;
}
$aListFieldsToGet = array(
'criteriaColumn',
'criteriaSort',
'criteriaShow',
'criteria',
'criteriaAndOrRow',
'criteriaAndOrColumn',
'rows'
);
$data = array();
$data['criteriaColumnCount'] = count($criterias['criteriaColumn']);
foreach ($aListFieldsToGet as $field) {
$data[$field] = $criterias[$field];
}
for ($i = 0; $i <= $data['rows']; $i++) {
$data['Or' . $i] = $criterias['Or' . $i];
}
$this->_criterias = $data;
return $this;
}
/**
* Getter for criterias
*
* @return array
*/
public function getCriterias()
{
return $this->_criterias;
}
/**
* Setter for username
*
* @param string $username Username
*
* @return static
*/
public function setUsername($username)
{
$this->_username = $username;
return $this;
}
/**
* Getter for username
*
* @return string
*/
public function getUsername()
{
return $this->_username;
}
/**
* Setter for DB name
*
* @param string $dbname DB name
*
* @return static
*/
public function setDbname($dbname)
{
$this->_dbname = $dbname;
return $this;
}
/**
* Getter for DB name
*
* @return string
*/
public function getDbname()
{
return $this->_dbname;
}
/**
* Public constructor
*
* @param array $config Global configuration
*/
public function __construct($config)
{
$this->setConfig($config);
}
/**
* Save the search
*
* @return boolean
*/
public function save()
{
if (null == $this->getUsername()
|| null == $this->getDbname()
|| null == $this->getSearchName()
|| null == $this->getCriterias()
) {
PMA_Util::mysqlDie(__('Missing information to save the search.'));
}
$savedSearchesTbl
= PMA_Util::backquote($this->_config['cfgRelation']['db']) . "."
. PMA_Util::backquote($this->_config['cfgRelation']['savedsearches']);
//If it's an insert.
if (null === $this->getId()) {
$wheres = array(
"search_name = '" . PMA_Util::sqlAddSlashes($this->getSearchName())
. "'"
);
$existingSearches = $this->getList($wheres);
if (!empty($existingSearches)) {
PMA_Util::mysqlDie(__('An entry with this name already exists.'));
}
$sqlQuery = "INSERT INTO " . $savedSearchesTbl
. "(`username`, `db_name`, `search_name`, `search_data`)"
. " VALUES ("
. "'" . PMA_Util::sqlAddSlashes($this->getUsername()) . "',"
. "'" . PMA_Util::sqlAddSlashes($this->getDbname()) . "',"
. "'" . PMA_Util::sqlAddSlashes($this->getSearchName()) . "',"
. "'" . PMA_Util::sqlAddSlashes(json_encode($this->getCriterias()))
. "')";
$result = (bool)PMA_queryAsControlUser($sqlQuery);
if (!$result) {
return false;
}
$this->setId($GLOBALS['dbi']->insertId());
return true;
}
//Else, it's an update.
$wheres = array(
"id != " . $this->getId(),
"search_name = '" . PMA_Util::sqlAddSlashes($this->getSearchName()) . "'"
);
$existingSearches = $this->getList($wheres);
if (!empty($existingSearches)) {
PMA_Util::mysqlDie(__('An entry with this name already exists.'));
}
$sqlQuery = "UPDATE " . $savedSearchesTbl
. "SET `search_name` = '"
. PMA_Util::sqlAddSlashes($this->getSearchName()) . "', "
. "`search_data` = '"
. PMA_Util::sqlAddSlashes(json_encode($this->getCriterias())) . "' "
. "WHERE id = " . $this->getId();
return (bool)PMA_queryAsControlUser($sqlQuery);
}
/**
* Delete the search
*
* @return boolean
*/
public function delete()
{
if (null == $this->getId()) {
PMA_Util::mysqlDie(__('Missing information to delete the search.'));
}
$savedSearchesTbl
= PMA_Util::backquote($this->_config['cfgRelation']['db']) . "."
. PMA_Util::backquote($this->_config['cfgRelation']['savedsearches']);
$sqlQuery = "DELETE FROM " . $savedSearchesTbl
. "WHERE id = '" . PMA_Util::sqlAddSlashes($this->getId()) . "'";
return (bool)PMA_queryAsControlUser($sqlQuery);
}
/**
* Load the current search from an id.
*
* @return bool Success
*/
public function load()
{
if (null == $this->getId()) {
PMA_Util::mysqlDie(__('Missing information to load the search.'));
}
$savedSearchesTbl = PMA_Util::backquote($this->_config['cfgRelation']['db'])
. "."
. PMA_Util::backquote($this->_config['cfgRelation']['savedsearches']);
$sqlQuery = "SELECT id, search_name, search_data "
. "FROM " . $savedSearchesTbl . " "
. "WHERE id = '" . PMA_Util::sqlAddSlashes($this->getId()) . "' ";
$resList = PMA_queryAsControlUser($sqlQuery);
if (false === ($oneResult = $GLOBALS['dbi']->fetchArray($resList))) {
PMA_Util::mysqlDie(__('Error while loading the search.'));
}
$this->setSearchName($oneResult['search_name'])
->setCriterias($oneResult['search_data'], true);
return true;
}
/**
* Get the list of saved search of a user on a DB
*
* @param array $wheres List of filters
*
* @return array|bool List of saved search or false on failure
*/
public function getList(array $wheres = array())
{
if (null == $this->getUsername()
|| null == $this->getDbname()
) {
return false;
}
$savedSearchesTbl = PMA_Util::backquote($this->_config['cfgRelation']['db'])
. "."
. PMA_Util::backquote($this->_config['cfgRelation']['savedsearches']);
$sqlQuery = "SELECT id, search_name "
. "FROM " . $savedSearchesTbl . " "
. "WHERE "
. "username = '" . PMA_Util::sqlAddSlashes($this->getUsername()) . "' "
. "AND db_name = '" . PMA_Util::sqlAddSlashes($this->getDbname()) . "' ";
foreach ($wheres as $where) {
$sqlQuery .= "AND " . $where . " ";
}
$sqlQuery .= "order by search_name ASC ";
$resList = PMA_queryAsControlUser($sqlQuery);
$list = array();
while ($oneResult = $GLOBALS['dbi']->fetchArray($resList)) {
$list[$oneResult['id']] = $oneResult['search_name'];
}
return $list;
}
}

View File

@ -465,6 +465,15 @@ $cfg['Servers'][$i]['usergroups'] = '';
*/
$cfg['Servers'][$i]['navigationhiding'] = '';
/**
* table to store information about saved searches from query-by-example on a db
* - leave blank to disable saved searches feature
* SUGGESTED: 'pma__savedsearches'
*
* @global string $cfg['Servers'][$i]['savedsearches']
*/
$cfg['Servers'][$i]['savedsearches'] = '';
/**
* Maximum number of records saved in $cfg['Servers'][$i]['table_uiprefs'] table.
*

View File

@ -79,6 +79,7 @@ $forms['Servers']['Server_pmadb'] = array('Servers' => array(1 => array(
'table_coords' => 'pma__table_coords',
'pdf_pages' => 'pma__pdf_pages',
'designer_coords' => 'pma__designer_coords',
'saved_searches' => 'pma__savedsearches',
'MaxTableUiprefs' => 100)));
$forms['Servers']['Server_tracking'] = array('Servers' => array(1 => array(
'tracking_version_auto_create',

View File

@ -395,6 +395,7 @@ function PMA_checkRelationsParam()
$cfgRelation['menuswork'] = false;
$cfgRelation['navwork'] = false;
$cfgRelation['allworks'] = false;
$cfgRelation['savedsearcheswork'] = false;
$cfgRelation['user'] = null;
$cfgRelation['db'] = null;
@ -463,6 +464,8 @@ function PMA_checkRelationsParam()
$cfgRelation['usergroups'] = $curr_table[0];
} elseif ($curr_table[0] == $GLOBALS['cfg']['Server']['navigationhiding']) {
$cfgRelation['navigationhiding'] = $curr_table[0];
} elseif ($curr_table[0] == $GLOBALS['cfg']['Server']['savedsearches']) {
$cfgRelation['savedsearches'] = $curr_table[0];
}
} // end while
$GLOBALS['dbi']->freeResult($tab_rs);
@ -521,6 +524,10 @@ function PMA_checkRelationsParam()
$cfgRelation['navwork'] = true;
}
if (isset($cfgRelation['savedsearches'])) {
$cfgRelation['savedsearcheswork'] = true;
}
if ($cfgRelation['relwork'] && $cfgRelation['displaywork']
&& $cfgRelation['pdfwork'] && $cfgRelation['commwork']
&& $cfgRelation['mimework'] && $cfgRelation['historywork']
@ -528,6 +535,7 @@ function PMA_checkRelationsParam()
&& $cfgRelation['trackingwork'] && $cfgRelation['userconfigwork']
&& $cfgRelation['bookmarkwork'] && $cfgRelation['designerwork']
&& $cfgRelation['menuswork'] && $cfgRelation['navwork']
&& $cfgRelation['savedsearcheswork']
) {
$cfgRelation['allworks'] = true;
}

View File

@ -52,6 +52,7 @@ class PMA_Relation_Cleanup_Test extends PHPUnit_Framework_TestCase
$GLOBALS['cfg']['Server']['users'] = 'users';
$GLOBALS['cfg']['Server']['usergroups'] = 'usergroups';
$GLOBALS['cfg']['Server']['navigationhiding'] = 'navigationhiding';
$GLOBALS['cfg']['Server']['savedsearches'] = 'savedsearches';
$this->redefineRelation();
}