diff --git a/config.sample.inc.php b/config.sample.inc.php index 83fe50cb96..2b3024d12d 100644 --- a/config.sample.inc.php +++ b/config.sample.inc.php @@ -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'; diff --git a/db_qbe.php b/db_qbe.php index e1ed199d1f..37845edbb4 100644 --- a/db_qbe.php +++ b/db_qbe.php @@ -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 diff --git a/examples/config.manyhosts.inc.php b/examples/config.manyhosts.inc.php index b188aa8b86..bced1fca2c 100644 --- a/examples/config.manyhosts.inc.php +++ b/examples/config.manyhosts.inc.php @@ -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'; } diff --git a/examples/create_tables.sql b/examples/create_tables.sql index 0ac5654dc4..8ffbf5ef84 100644 --- a/examples/create_tables.sql +++ b/examples/create_tables.sql @@ -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; diff --git a/examples/create_tables_drizzle.sql b/examples/create_tables_drizzle.sql index 698a15949d..71318caf77 100644 --- a/examples/create_tables_drizzle.sql +++ b/examples/create_tables_drizzle.sql @@ -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; diff --git a/js/db_qbe.js b/js/db_qbe.js new file mode 100644 index 0000000000..0a37b79aba --- /dev/null +++ b/js/db_qbe.js @@ -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'); + }); +}); \ No newline at end of file diff --git a/libraries/DBQbe.class.php b/libraries/DBQbe.class.php index ccaad0bd88..dd7407d1e1 100644 --- a/libraries/DBQbe.class.php +++ b/libraries/DBQbe.class.php @@ -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 = '