From: chriskl Date: Wed, 5 Nov 2003 08:32:03 +0000 (+0000) Subject: mega commit. unify all table browsing, select browsing, view browsing and report... X-Git-Tag: REL_3-2-1~28 X-Git-Url: http://git.postgresql.org/gitweb/static/gitweb.js?a=commitdiff_plain;h=2b46c7877f279675e614fb37f6efa35fb9c6c8da;p=phppgadmin.git mega commit. unify all table browsing, select browsing, view browsing and report browsing. you can now select over a view and then change the order of the results. this needs heaps of testing. greatly upgrade view select feature to use select all and operators. allow use of limit and offset in user queries. allow row edit and delete in select results. view a report and then you can change sorting while viewing --- diff --git a/BUGS b/BUGS index 2983c933..de4cca5c 100644 --- a/BUGS +++ b/BUGS @@ -1,6 +1,9 @@ +better detection for when reports database hasn't been installed. fix getIndexes() and getConstraints() for < 7.3 to know about index type (eg. constraints can only be btree indexes) re-enable help system all DROP and ALTER commands MUST be fully schema-qualified otherwise you can accidentally drop stuff in pg_catalog :( need icons for Casts and Conversions and Languages +submit changes to HTML_TreeMenu maintainer +fix up view select feature (select all) maybe combine this with the table select stuff? diff --git a/CREDITS b/CREDITS index 36b9403b..fe96d3eb 100644 --- a/CREDITS +++ b/CREDITS @@ -41,4 +41,4 @@ Contributors - Brett Toolin - Mark Gibson (Pop-up SQL window) - Nicola Soranzo - +- Oliver Meyer & Sven Kiera (Table icons link to browse table) diff --git a/HISTORY b/HISTORY index d03a1d53..4a247fa2 100644 --- a/HISTORY +++ b/HISTORY @@ -6,6 +6,9 @@ Version 3.2-dev Features * Option to dump table structure, data or structure and data +* Results of table browse, table select, view browsing and report browsing + can now ALL be sorted by column +* Result rows of table selects can now be edited and deleted * Set datestyle and extra_float_digits when dumping data * Extra login security to prevent logging into servers as postgres and no password - a VERY common newbie error. diff --git a/browser.php b/browser.php index 46bc3a5a..6fa65e4e 100644 --- a/browser.php +++ b/browser.php @@ -5,7 +5,7 @@ * if you click on a database it shows a list of database objects in that * database. * - * $Id: browser.php,v 1.23 2003/11/03 01:26:37 chriskl Exp $ + * $Id: browser.php,v 1.24 2003/11/05 08:32:03 chriskl Exp $ */ // Include application functions @@ -56,6 +56,7 @@ $tables = &$localData->getTables(); while (!$tables->EOF) { + $return_url = urlencode("tblproperties.php?table=" . urlencode($tables->f[$data->tbFields['tbname']]) . "&{$querystr}"); $item_node = &new HTML_TreeNode(array( 'text' => addslashes($misc->printVal($tables->f[$data->tbFields['tbname']])), 'link' => addslashes(htmlspecialchars("tblproperties.php?{$querystr}&table=" . @@ -64,7 +65,8 @@ 'expandedIcon' => "../../../images/themes/{$conf['theme']}/tables.png", 'expanded' => false, 'linkTarget' => 'detail', - 'browseLink' => addslashes(htmlspecialchars('tables.php?action=browse&page=1&table='.urlencode($tables->f[$data->tbFields['tbname']]).'&'.$querystr)) + 'browseLink' => addslashes(htmlspecialchars('display.php?table='.urlencode($tables->f[$data->tbFields['tbname']]).'&'.$querystr. + "&return_url={$return_url}&return_desc=" . urlencode($lang['strback']))) )); // Add table folder to schema diff --git a/classes/Reports.php b/classes/Reports.php index c75b80c3..43f90e95 100644 --- a/classes/Reports.php +++ b/classes/Reports.php @@ -4,7 +4,7 @@ * the functions provided by the database driver exclusively, and hence * will work with any database without modification. * - * $Id: Reports.php,v 1.7 2003/10/15 01:23:42 chriskl Exp $ + * $Id: Reports.php,v 1.8 2003/11/05 08:32:03 chriskl Exp $ */ class Reports { @@ -42,7 +42,7 @@ $sql = $this->driver->getSelectSQL('ppa_reports', array('report_id', 'report_name', 'db_name', 'date_created', 'created_by', 'descr', 'report_sql'), - $filter, $ops, array('report_name')); + $filter, $ops, array(2 => 'asc')); return $this->driver->selectSet($sql); } diff --git a/classes/database/BaseDB.php b/classes/database/BaseDB.php index b78a6034..23b47eff 100644 --- a/classes/database/BaseDB.php +++ b/classes/database/BaseDB.php @@ -4,7 +4,7 @@ * A class that implements the DB interface for Postgres * Note: This class uses ADODB and returns RecordSets. * - * $Id: BaseDB.php,v 1.32 2003/10/26 12:12:28 chriskl Exp $ + * $Id: BaseDB.php,v 1.33 2003/11/05 08:32:03 chriskl Exp $ */ include_once('classes/database/ADODB_base.php'); @@ -147,16 +147,26 @@ class BaseDB extends ADODB_base { /** * Generates the SQL for the 'select' function * @param $table The table from which to select - * @param $show An array of columns to show + * @param $show An array of columns to show. Empty array means all columns. * @param $values An array mapping columns to values * @param $ops An array of the operators to use - * @param $orderby (optional) An array of columns to order by + * @param $orderby (optional) An array of column numbers (one based) + * mapped to sort direction (asc or desc or '' or null) to order by * @return The SQL query */ function getSelectSQL($table, $show, $values, $ops, $orderby = array()) { $this->fieldClean($table); + $this->fieldArrayClean($show); - $sql = "SELECT \"" . join('","', $show) . "\" FROM "; + // If an empty array is passed in, then show all columns + if (sizeof($show) == 0) { + if ($this->hasObjectID($table)) + $sql = "SELECT oid, * FROM "; + else + $sql = "SELECT * FROM "; + } + else + $sql = "SELECT \"" . join('","', $show) . "\" FROM "; if ($this->hasSchemas() && isset($_REQUEST['schema'])) { $this->fieldClean($_REQUEST['schema']); $sql .= "\"{$_REQUEST['schema']}\"."; @@ -196,9 +206,13 @@ class BaseDB extends ADODB_base { // ORDER BY if (is_array($orderby) && sizeof($orderby) > 0) { - $sql .= " ORDER BY \"" . join('","', $orderby) . "\""; + $sql .= " ORDER BY "; + foreach ($orderby as $k => $v) { + $sql .= $k; + if (strtoupper($v) == 'DESC') $sql .= " DESC"; + } } - + return $sql; } diff --git a/classes/database/Postgres.php b/classes/database/Postgres.php index 542367ca..fdd98df4 100755 --- a/classes/database/Postgres.php +++ b/classes/database/Postgres.php @@ -4,7 +4,7 @@ * A class that implements the DB interface for Postgres * Note: This class uses ADODB and returns RecordSets. * - * $Id: Postgres.php,v 1.160 2003/10/27 05:43:18 chriskl Exp $ + * $Id: Postgres.php,v 1.161 2003/11/05 08:32:03 chriskl Exp $ */ // @@@ THOUGHT: What about inherits? ie. use of ONLY??? @@ -1295,83 +1295,9 @@ class Postgres extends BaseDB { $sql = "ALTER TABLE \"{$table}\" RENAME TO \"{$newName}\""; - // @@ How do you do this? return $this->execute($sql); } - /** - * Returns a recordset of all columns in a relation. Supports paging. - * @param $relation The name of a relation - * @param $sortkey Field over which to sort. '' for no sort. - * @param $sortdir 'asc' or 'desc' - * @param $page The page of the relation to retrieve - * @param $page_size The number of rows per page - * @param &$max_pages (return-by-ref) The max number of pages in the relation - * @return A recordset on success - * @return -1 transaction error - * @return -2 counting error - * @return -3 page or page_size invalid - */ - function &browseRelation($relation, $sortkey, $sortdir, $page, $page_size, &$max_pages) { - $oldrelation = $relation; - $this->fieldClean($relation); - - // Check that we're not going to divide by zero - if (!is_numeric($page_size) || $page_size != (int)$page_size || $page_size <= 0) return -3; - - // Open a transaction - $status = $this->beginTransaction(); - if ($status != 0) return -1; - - // Count the number of rows - $sql = "SELECT COUNT(*) AS total FROM \"{$relation}\""; - $total = $this->selectField($sql, 'total'); - if ($total < 0) { - $this->rollbackTransaction(); - return -2; - } - - // Calculate max pages - $max_pages = ceil($total / $page_size); - - // Check that page is less than or equal to max pages - if (!is_numeric($page) || $page != (int)$page || $page > $max_pages || $page < 1) { - $this->rollbackTransaction(); - return -3; - } - - // Figure out ORDER BY - if ($sortkey != '') { - $this->fieldClean($sortkey); - $orderby = " ORDER BY \"{$sortkey}\""; - // Add sort order - if ($sortdir == 'desc') - $orderby .= ' DESC'; - else - $orderby .= ' ASC'; - } - else $orderby = ''; - - // We need to do a check to see if the relation has an OID column. If so, then - // we need to include it in the result set, in case the user has created a primary key - // constraint on it. - $hasID = $this->hasObjectID($oldrelation); - - // Actually retrieve the rows, with offset and limit - if ($hasID) - $rs = $this->selectSet("SELECT \"{$this->id}\",* FROM \"{$relation}\" {$orderby} LIMIT {$page_size} OFFSET " . ($page - 1) * $page_size); - else - $rs = $this->selectSet("SELECT * FROM \"{$relation}\" {$orderby} LIMIT {$page_size} OFFSET " . ($page - 1) * $page_size); - - $status = $this->endTransaction(); - if ($status != 0) { - $this->rollbackTransaction(); - return -1; - } - - return $rs; - } - /** * Finds the number of rows that would be returned by a * query. @@ -1380,7 +1306,7 @@ class Postgres extends BaseDB { * @return The count of rows * @return -1 error */ - function browseSQLCount($query, $count) { + function browseQueryCount($query, $count) { // Count the number of rows $rs = $this->selectSet($query); if (!is_object($rs)) { @@ -1392,8 +1318,12 @@ class Postgres extends BaseDB { /** * Returns a recordset of all columns in a query. Supports paging. - * @param $query The SQL SELECT query. - * @param $count The same SQL query, but only retrieves the count of the rows (AS total) + * @param $type Either 'QUERY' if it is an SQL query, or 'TABLE' if it is a table identifier, + * or 'SELECT" if it's a select query + * @param $table The base table of the query. NULL for no table. + * @param $query The query that is being executed. NULL for no query. + * @param $sortkey The column number to sort by, or '' or null for no sorting + * @param $sortdir The direction in which to sort the specified column ('asc' or 'desc') * @param $page The page of the relation to retrieve * @param $page_size The number of rows per page * @param &$max_pages (return-by-ref) The max number of pages in the relation @@ -1401,17 +1331,40 @@ class Postgres extends BaseDB { * @return -1 transaction error * @return -2 counting error * @return -3 page or page_size invalid + * @return -4 unknown type */ - function &browseSQL($query, $count, $page, $page_size, &$max_pages) { + function &browseQuery($type, $table, $query, $sortkey, $sortdir, $page, $page_size, &$max_pages) { // Check that we're not going to divide by zero if (!is_numeric($page_size) || $page_size != (int)$page_size || $page_size <= 0) return -3; + // If $type is TABLE, then generate the query + switch ($type) { + case 'TABLE': + if (ereg('^[0-9]+$', $sortkey) && $sortkey > 0) $orderby = array($sortkey => $sortdir); + else $orderby = array(); + $query = $this->getSelectSQL($table, array(), array(), array(), $orderby); + break; + case 'QUERY': + case 'SELECT': + // Trim query + $query = trim($query); + // Trim off trailing semi-colon if there is one + if (substr($query, strlen($query) - 1, 1) == ';') + $query = substr($query, 0, strlen($query) - 1); + break; + default: + return -4; + } + + // Generate count query + $count = "SELECT COUNT(*) AS total FROM ($query) AS sub"; + // Open a transaction $status = $this->beginTransaction(); if ($status != 0) return -1; // Count the number of rows - $total = $this->browseSQLCount($query, $count); + $total = $this->browseQueryCount($query, $count); if ($total < 0) { $this->rollbackTransaction(); return -2; @@ -1427,11 +1380,24 @@ class Postgres extends BaseDB { } // Set fetch mode to NUM so that duplicate field names are properly returned - $this->conn->setFetchMode(ADODB_FETCH_NUM); + // for non-table queries. Since the SELECT feature only allows selecting one + // table, duplicate fields shouldn't appear. + if ($type == 'QUERY') $this->conn->setFetchMode(ADODB_FETCH_NUM); + + // Figure out ORDER BY. Sort key is always the column number (based from one) + // of the column to order by. Only need to do this for non-TABLE queries + if ($type != 'TABLE' && ereg('^[0-9]+$', $sortkey) && $sortkey > 0) { + $orderby = " ORDER BY {$sortkey}"; + // Add sort order + if ($sortdir == 'desc') + $orderby .= ' DESC'; + else + $orderby .= ' ASC'; + } + else $orderby = ''; // Actually retrieve the rows, with offset and limit - $rs = $this->selectSet("{$query} LIMIT {$page_size} OFFSET " . ($page - 1) * $page_size); - + $rs = $this->selectSet("SELECT * FROM ({$query}) AS sub {$orderby} LIMIT {$page_size} OFFSET " . ($page - 1) * $page_size); $status = $this->endTransaction(); if ($status != 0) { $this->rollbackTransaction(); diff --git a/classes/database/Postgres71.php b/classes/database/Postgres71.php index d8e12c80..58c98eac 100644 --- a/classes/database/Postgres71.php +++ b/classes/database/Postgres71.php @@ -4,7 +4,7 @@ * A class that implements the DB interface for Postgres * Note: This class uses ADODB and returns RecordSets. * - * $Id: Postgres71.php,v 1.44 2003/10/22 07:22:43 chriskl Exp $ + * $Id: Postgres71.php,v 1.45 2003/11/05 08:32:03 chriskl Exp $ */ // @@@ THOUGHT: What about inherits? ie. use of ONLY??? @@ -116,7 +116,7 @@ class Postgres71 extends Postgres { * @return The count of rows * @return -1 error */ - function browseSQLCount($query, $count) { + function browseQueryCount($query, $count) { return $this->selectField($count, 'total'); } diff --git a/classes/database/Postgres73.php b/classes/database/Postgres73.php index 3a52beda..78a1b18a 100644 --- a/classes/database/Postgres73.php +++ b/classes/database/Postgres73.php @@ -4,7 +4,7 @@ * A class that implements the DB interface for Postgres * Note: This class uses ADODB and returns RecordSets. * - * $Id: Postgres73.php,v 1.76 2003/10/28 04:02:15 chriskl Exp $ + * $Id: Postgres73.php,v 1.77 2003/11/05 08:32:04 chriskl Exp $ */ // @@@ THOUGHT: What about inherits? ie. use of ONLY??? @@ -222,7 +222,7 @@ class Postgres73 extends Postgres72 { $status = $this->beginTransaction(); if ($status != 0) return -1; - + // Get the first primary or unique index (sorting primary keys first) that // is NOT a partial index. $sql = "SELECT indrelid, indkey FROM pg_catalog.pg_index WHERE indisunique AND diff --git a/display.php b/display.php index 06d8e640..ad1401d3 100644 --- a/display.php +++ b/display.php @@ -9,7 +9,7 @@ * @param $return_desc The return link name * @param $page The current page * - * $Id: display.php,v 1.28 2003/09/10 07:25:49 chriskl Exp $ + * $Id: display.php,v 1.29 2003/11/05 08:32:03 chriskl Exp $ */ // Include application functions @@ -20,72 +20,362 @@ $action = (isset($_REQUEST['action'])) ? $_REQUEST['action'] : ''; $PHP_SELF = $_SERVER['PHP_SELF']; - $misc->printHeader($lang['strqueryresults']); - $misc->printBody(); + /** + * Show confirmation of edit and perform actual update + */ + function doEditRow($confirm, $msg = '') { + global $localData, $database, $misc; + global $lang; + global $PHP_SELF; - echo "

", $misc->printVal($_REQUEST['database']), ": {$lang['strqueryresults']}

\n"; - - // If current page is not set, default to first page - if (!isset($_REQUEST['page'])) $_REQUEST['page'] = 1; - - $sub = trim($_REQUEST['query']); - // Trim off trailing semi-colon if there is one - if (substr($sub, strlen($sub) - 1, 1) == ';') - $sub = substr($sub, 0, strlen($sub) - 1); - - // If 'count' variable is not set, then set it to select count(*) from - // 'query' - if (!isset($_REQUEST['count'])) { - $_REQUEST['count'] = "SELECT COUNT(*) AS total FROM ({$sub}) AS sub"; + $key = $_REQUEST['key']; + + if ($confirm) { + echo "

", $misc->printVal($_REQUEST['database']), ": {$lang['strtables']}: ", $misc->printVal($_REQUEST['table']), ": {$lang['streditrow']}

\n"; + $misc->printMsg($msg); + + $attrs = &$localData->getTableAttributes($_REQUEST['table']); + $rs = &$localData->browseRow($_REQUEST['table'], $key); + + echo "
\n"; + $error = true; + if ($rs->recordCount() == 1 && $attrs->recordCount() > 0) { + echo "\n"; + + // Output table header + echo ""; + echo "\n"; + echo ""; + + $i = 0; + while (!$attrs->EOF) { + $attrs->f['attnotnull'] = $localData->phpBool($attrs->f['attnotnull']); + $id = (($i % 2) == 0 ? '1' : '2'); + + // Initialise variables + if (!isset($_REQUEST['format'][$attrs->f['attname']])) + $_REQUEST['format'][$attrs->f['attname']] = 'VALUE'; + + echo "\n"; + echo ""; + echo ""; + echo "\n"; + echo ""; + } + else + echo " "; + + echo ""; + echo "\n"; + $i++; + $attrs->moveNext(); + } + echo "
{$lang['strfield']}{$lang['strtype']}{$lang['strformat']}{$lang['strnull']}{$lang['strvalue']}
", $misc->printVal($attrs->f['attname']), "\n"; + echo $misc->printVal($localData->formatType($attrs->f['type'], $attrs->f['atttypmod'])); + echo "f['attname']), "]\" value=\"", + htmlspecialchars($attrs->f['type']), "\" />\n"; + echo "\n"; + // Output null box if the column allows nulls (doesn't look at CHECKs or ASSERTIONS) + if (!$attrs->f['attnotnull']) { + // Set initial null values + if ($_REQUEST['action'] == 'confeditrow' && $rs->f[$attrs->f['attname']] === null) { + $_REQUEST['nulls'][$attrs->f['attname']] = 'on'; + } + echo "f['attname']}]\"", + isset($_REQUEST['nulls'][$attrs->f['attname']]) ? ' checked="checked"' : '', " />", $localData->printField("values[{$attrs->f['attname']}]", + $rs->f[$attrs->f['attname']], $attrs->f['type']), "

\n"; + $error = false; + } + elseif ($rs->recordCount() != 1) { + echo "

{$lang['strrownotunique']}

\n"; + } + else { + echo "

{$lang['strinvalidparam']}

\n"; + } + + echo "\n"; + echo $misc->form; + if (isset($_REQUEST['table'])) + echo "\n"; + if (isset($_REQUEST['query'])) + echo "\n"; + if (isset($_REQUEST['count'])) + echo "\n"; + if (isset($_REQUEST['return_url'])) + echo "\n"; + if (isset($_REQUEST['return_desc'])) + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + echo "

"; + if (!$error) echo "\n"; + echo "

\n"; + echo "
\n"; + } + else { + if (!isset($_POST['values'])) $_POST['values'] = array(); + if (!isset($_POST['nulls'])) $_POST['nulls'] = array(); + + $status = $localData->editRow($_POST['table'], $_POST['values'], $_POST['nulls'], + $_POST['format'], $_POST['types'], unserialize($_POST['key'])); + if ($status == 0) + doBrowse($lang['strrowupdated']); + elseif ($status == -2) + doEditRow(true, $lang['strrownotunique']); + else + doEditRow(true, $lang['strrowupdatedbad']); + } + + } + + /** + * Show confirmation of drop and perform actual drop + */ + function doDelRow($confirm) { + global $localData, $database, $misc; + global $lang; + global $PHP_SELF; + + if ($confirm) { + echo "

", $misc->printVal($_REQUEST['database']), ": {$lang['strtables']}: ", $misc->printVal($_REQUEST['table']), ": {$lang['strdeleterow']}

\n"; + + echo "

{$lang['strconfdeleterow']}

\n"; + + echo "
\n"; + echo "\n"; + echo $misc->form; + if (isset($_REQUEST['table'])) + echo "\n"; + if (isset($_REQUEST['query'])) + echo "\n"; + if (isset($_REQUEST['count'])) + echo "\n"; + if (isset($_REQUEST['return_url'])) + echo "\n"; + if (isset($_REQUEST['return_desc'])) + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + echo "
\n"; + } + else { + $status = $localData->deleteRow($_POST['table'], unserialize($_POST['key'])); + if ($status == 0) + doBrowse($lang['strrowdeleted']); + elseif ($status == -2) + doBrowse($lang['strrownotunique']); + else + doBrowse($lang['strrowdeletedbad']); + } + } - // Retrieve page from table. $max_pages is returned by reference. - $rs = &$localData->browseSQL($sub, $_REQUEST['count'], $_REQUEST['page'], $conf['max_rows'], $max_pages); - - if (is_object($rs) && $rs->recordCount() > 0) { - // Show page navigation - $misc->printPages($_REQUEST['page'], $max_pages, "display.php?page=%s&{$misc->href}&query=" . - urlencode($_REQUEST['query']) . '&count=' . urlencode($_REQUEST['count']) . '&return_url=' . - urlencode($_REQUEST['return_url']) . '&return_desc=' . urlencode($_REQUEST['return_desc'])); - echo "\n"; + /** + * Displays requested data + */ + function doBrowse() { + global $localData, $conf, $misc, $lang; - foreach ($rs->f as $k => $v) { - $finfo = $rs->fetchField($k); - echo ""; + // If current page is not set, default to first page + if (!isset($_REQUEST['page'])) $_REQUEST['page'] = 1; + + // If 'table' is not set, default to '' and set type + if (isset($_REQUEST['table']) && isset($_REQUEST['query'])) { + echo "

", $misc->printVal($_REQUEST['database']), ": {$lang['strtables']}: ", $misc->printVal($_REQUEST['table']), ": {$lang['strselect']}

\n"; + $type = 'SELECT'; + } + elseif (isset($_REQUEST['table'])) { + echo "

", $misc->printVal($_REQUEST['database']), ": {$lang['strtables']}: ", $misc->printVal($_REQUEST['table']), ": {$lang['strbrowse']}

\n"; + $type = 'TABLE'; + } + else { + echo "

", $misc->printVal($_REQUEST['database']), ": {$lang['strqueryresults']}

\n"; + $type = 'QUERY'; } - echo "\n"; + // If 'sortkey' is not set, default to '' + if (!isset($_REQUEST['sortkey'])) $_REQUEST['sortkey'] = ''; + + // If 'sortdir' is not set, default to '' + if (!isset($_REQUEST['sortdir'])) $_REQUEST['sortdir'] = ''; + + // If 'strings' is not set, default to collapsed + if (!isset($_REQUEST['strings'])) $_REQUEST['strings'] = 'collapsed'; + + // Fetch unique row identifier, if this is a table browse request. + if (isset($_REQUEST['table'])) + $key = $localData->getRowIdentifier($_REQUEST['table']); + else + $key = array(); + + // Retrieve page from query. $max_pages is returned by reference. + $rs = &$localData->browseQuery($type, + isset($_REQUEST['table']) ? $_REQUEST['table'] : null, + isset($_REQUEST['query']) ? $_REQUEST['query'] : null, + $_REQUEST['sortkey'], $_REQUEST['sortdir'], $_REQUEST['page'], + $conf['max_rows'], $max_pages); + + // Build strings for GETs + $str = $misc->href . "&page=" . urlencode($_REQUEST['page']); + if (isset($_REQUEST['table'])) $str .= "&table=" . urlencode($_REQUEST['table']); + if (isset($_REQUEST['query'])) $str .= "&query=" . urlencode($_REQUEST['query']); + if (isset($_REQUEST['count'])) $str .= "&count=" . urlencode($_REQUEST['count']); + if (isset($_REQUEST['return_url'])) $str .= "&return_url=" . urlencode($_REQUEST['return_url']); + if (isset($_REQUEST['return_desc'])) $str .= "&return_desc=" . urlencode($_REQUEST['return_desc']); + + // This string just contains sort info + $str2 = "sortkey=" . urlencode($_REQUEST['sortkey']) . + "&sortdir=" . urlencode($_REQUEST['sortdir']); + + if (is_object($rs) && $rs->recordCount() > 0) { + // Show page navigation + $misc->printPages($_REQUEST['page'], $max_pages, "display.php?page=%s&{$str}&{$str2}"); + echo "
", $misc->printVal($finfo->name), "
\n"; + + // Check that the key is actually in the result set. This can occur for select + // operations where the key fields aren't part of the select. XXX: We should + // be able to support this, somehow. + foreach ($key as $v) { + // If a key column is not found in the record set, then we + // can't use the key. + if (!in_array($v, array_keys($rs->f))) { + $key = array(); + break; + } + } + // Display edit and delete actions if we have a key + if (sizeof($key) > 0) + echo "\n"; - $i = 0; - while (!$rs->EOF) { - $id = (($i % 2) == 0 ? '1' : '2'); - echo "\n"; + $j = 0; foreach ($rs->f as $k => $v) { - $finfo = $rs->fetchField($k); - echo ""; - } + if (isset($_REQUEST['table']) && $k == $localData->id && !$conf['show_oids']) { + $j++; + continue; + } + $finfo = $rs->fetchField($j); + // Display column headers with sorting options + echo "\n"; + $j++; + } + echo "\n"; - $rs->moveNext(); - $i++; + + $i = 0; + reset($rs->f); + while (!$rs->EOF) { + $id = (($i % 2) == 0 ? '1' : '2'); + echo "\n"; + // Display edit and delete links if we have a key + if (sizeof($key) > 0) { + $key_str = ''; + $has_nulls = false; + foreach ($key as $v) { + if ($rs->f[$v] === null) { + $has_nulls = true; + break; + } + if ($key_str != '') $key_str .= '&'; + $key_str .= urlencode("key[{$v}]") . '=' . urlencode($rs->f[$v]); + } + if ($has_nulls) { + echo "\n"; + } else { + echo "\n"; + echo "\n"; + } + } + $j = 0; + foreach ($rs->f as $k => $v) { + $finfo = $rs->fetchField($j++); + if (isset($_REQUEST['table']) && $k == $localData->id && !$conf['show_oids']) continue; + elseif ($v !== null && $v == '') echo ""; + else { + // Trim strings if over length + if ($_REQUEST['strings'] == 'collapsed' && strlen($v) > $conf['max_chars']) { + $v = substr($v, 0, $conf['max_chars'] - 1) . $lang['strellipsis']; + } + echo ""; + } + } + echo "\n"; + $rs->moveNext(); + $i++; + } + echo "
{$lang['stractions']}
", $misc->printVal($v, true, $finfo->type), "", + $misc->printVal($finfo->name), "
 {$lang['stredit']}{$lang['strdelete']} ", $misc->printVal($v, true, $finfo->type), "
\n"; + echo "

", $rs->recordCount(), " {$lang['strrows']}

\n"; } - - echo "\n"; - echo "

", $rs->recordCount(), " {$lang['strrows']}

\n"; - } - else echo "

{$lang['strnodata']}

\n"; + else echo "

{$lang['strnodata']}

\n"; - echo "

{$_REQUEST['return_desc']}"; - if ($conf['show_reports'] && isset($rs) && is_object($rs) && $rs->recordCount() > 0) { - echo " | {$lang['strcreatereport']}\n"; + // Return + echo "

{$_REQUEST['return_desc']}\n"; + // Expand/Collapse + if ($_REQUEST['strings'] == 'expanded') + echo "| {$lang['strcollapse']}\n"; + else + echo "| {$lang['strexpand']}\n"; + // Create report + if (isset($_REQUEST['query']) && $conf['show_reports'] && isset($rs) && is_object($rs) && $rs->recordCount() > 0) { + echo " | {$lang['strcreatereport']}\n"; + } + // Create view and download + if (isset($_REQUEST['query']) && isset($rs) && is_object($rs) && $rs->recordCount() > 0) { + echo " | href}\">{$lang['strcreateview']}\n"; + echo " | href}\">{$lang['strdownload']}\n"; + } + // Refresh + echo "| {$lang['strrefresh']}

\n"; + + echo "

\n"; } - if (isset($rs) && is_object($rs) && $rs->recordCount() > 0) { - echo " | href}\">{$lang['strcreateview']}\n"; - echo " | href}\">{$lang['strdownload']}\n"; + + // If a table is specified, then set the title differently + if (isset($_REQUEST['table'])) + $misc->printHeader($lang['strtables']); + else + $misc->printHeader($lang['strqueryresults']); + $misc->printBody(); + + switch ($action) { + case 'editrow': + if (isset($_POST['save'])) doEditRow(false); + else doBrowse(); + break; + case 'confeditrow': + doEditRow(true); + break; + case 'delrow': + if (isset($_POST['yes'])) doDelRow(false); + else doBrowse(); + break; + case 'confdelrow': + doDelRow(true); + break; + default: + doBrowse(); + break; } - echo "

\n"; $misc->printFooter(); ?> diff --git a/tables.php b/tables.php index 43cbc82e..83938915 100644 --- a/tables.php +++ b/tables.php @@ -3,7 +3,7 @@ /** * List tables in a database * - * $Id: tables.php,v 1.38 2003/10/13 08:50:03 chriskl Exp $ + * $Id: tables.php,v 1.39 2003/11/05 08:32:03 chriskl Exp $ */ // Include application functions @@ -428,268 +428,6 @@ } - /** - * Show confirmation of edit and perform actual update - */ - function doEditRow($confirm, $msg = '') { - global $localData, $database, $misc; - global $lang; - global $PHP_SELF; - - $key = $_REQUEST['key']; - - if ($confirm) { - echo "

", $misc->printVal($_REQUEST['database']), ": {$lang['strtables']}: ", $misc->printVal($_REQUEST['table']), ": {$lang['streditrow']}

\n"; - $misc->printMsg($msg); - - $attrs = &$localData->getTableAttributes($_REQUEST['table']); - $rs = &$localData->browseRow($_REQUEST['table'], $key); - - echo "
\n"; - $error = true; - if ($rs->recordCount() == 1 && $attrs->recordCount() > 0) { - echo "\n"; - - // Output table header - echo ""; - echo "\n"; - echo ""; - - // @@ CHECK THAT KEY ACTUALLY IS IN THE RESULT SET... - - $i = 0; - while (!$attrs->EOF) { - $attrs->f['attnotnull'] = $localData->phpBool($attrs->f['attnotnull']); - $id = (($i % 2) == 0 ? '1' : '2'); - - // Initialise variables - if (!isset($_REQUEST['format'][$attrs->f['attname']])) - $_REQUEST['format'][$attrs->f['attname']] = 'VALUE'; - - echo "\n"; - echo ""; - echo ""; - echo "\n"; - echo ""; - } - else - echo " "; - - echo ""; - echo "\n"; - $i++; - $attrs->moveNext(); - } - echo "
{$lang['strfield']}{$lang['strtype']}{$lang['strformat']}{$lang['strnull']}{$lang['strvalue']}
", $misc->printVal($attrs->f['attname']), "\n"; - echo $misc->printVal($localData->formatType($attrs->f['type'], $attrs->f['atttypmod'])); - echo "f['attname']), "]\" value=\"", - htmlspecialchars($attrs->f['type']), "\" />\n"; - echo "\n"; - // Output null box if the column allows nulls (doesn't look at CHECKs or ASSERTIONS) - if (!$attrs->f['attnotnull']) { - // Set initial null values - if ($_REQUEST['action'] == 'confeditrow' && $rs->f[$attrs->f['attname']] === null) { - $_REQUEST['nulls'][$attrs->f['attname']] = 'on'; - } - echo "f['attname']}]\"", - isset($_REQUEST['nulls'][$attrs->f['attname']]) ? ' checked="checked"' : '', " />", $localData->printField("values[{$attrs->f['attname']}]", - $rs->f[$attrs->f['attname']], $attrs->f['type']), "

\n"; - $error = false; - } - elseif ($rs->recordCount() != 1) { - echo "

{$lang['strrownotunique']}

\n"; - } - else { - echo "

{$lang['strinvalidparam']}

\n"; - } - - echo "\n"; - echo "\n"; - echo $misc->form; - echo "\n"; - echo "\n"; - echo "\n"; - echo "\n"; - echo "\n"; - echo "

"; - if (!$error) echo "\n"; - echo "

\n"; - echo "
\n"; - } - else { - if (!isset($_POST['values'])) $_POST['values'] = array(); - if (!isset($_POST['nulls'])) $_POST['nulls'] = array(); - - $status = $localData->editRow($_POST['table'], $_POST['values'], $_POST['nulls'], - $_POST['format'], $_POST['types'], unserialize($_POST['key'])); - if ($status == 0) - doBrowse($lang['strrowupdated']); - elseif ($status == -2) - doEditRow(true, $lang['strrownotunique']); - else - doEditRow(true, $lang['strrowupdatedbad']); - } - - } - - /** - * Show confirmation of drop and perform actual drop - */ - function doDelRow($confirm) { - global $localData, $database, $misc; - global $lang; - global $PHP_SELF; - - if ($confirm) { - echo "

", $misc->printVal($_REQUEST['database']), ": {$lang['strtables']}: ", $misc->printVal($_REQUEST['table']), ": {$lang['strdeleterow']}

\n"; - - echo "

{$lang['strconfdeleterow']}

\n"; - - echo "
\n"; - echo "\n"; - echo "\n"; - echo $misc->form; - echo "\n"; - echo "\n"; - echo "\n"; - echo "\n"; - echo "\n"; - echo "\n"; - echo "\n"; - echo "
\n"; - } - else { - $status = $localData->deleteRow($_POST['table'], unserialize($_POST['key'])); - if ($status == 0) - doBrowse($lang['strrowdeleted']); - elseif ($status == -2) - doBrowse($lang['strrownotunique']); - else - doBrowse($lang['strrowdeletedbad']); - } - - } - - /** - * Browse a table - */ - function doBrowse($msg = '') { - global $data, $localData, $misc, $conf; - global $PHP_SELF, $lang; - - echo "

", $misc->printVal($_REQUEST['database']), ": ", $misc->printVal($_REQUEST['table']), ": {$lang['strbrowse']}

\n"; - $misc->printMsg($msg); - - if (!isset($_REQUEST['page'])) $_REQUEST['page'] = 1; - if (!isset($_REQUEST['sortkey'])) $_REQUEST['sortkey'] = ''; - if (!isset($_REQUEST['sortdir'])) $_REQUEST['sortdir'] = ''; - if (!isset($_REQUEST['strings'])) $_REQUEST['strings'] = 'collapsed'; - - // Retrieve page from table. $max_pages is returned by reference. - $rs = &$localData->browseRelation($_REQUEST['table'], $_REQUEST['sortkey'], $_REQUEST['sortdir'], - $_REQUEST['page'], $conf['max_rows'], $max_pages); - - // Fetch unique row identifier, if there is one - $key = $localData->getRowIdentifier($_REQUEST['table']); - - if (is_object($rs) && $rs->recordCount() > 0) { - // Show page navigation - $misc->printPages($_REQUEST['page'], $max_pages, "{$PHP_SELF}?action=browse&page=%s&{$misc->href}&sortkey=" . - urlencode($_REQUEST['sortkey']) . "&sortdir=" . urlencode($_REQUEST['sortdir']) . - "&strings=" . urlencode($_REQUEST['strings']) . "&table=" . urlencode($_REQUEST['table'])); - echo "\n"; - - // @@ CHECK THAT KEY ACTUALLY IS IN THE RESULT SET... - - if (sizeof($key) > 0) - echo "\n"; - - reset($rs->f); - while(list($k, ) = each($rs->f)) { - if ($k == $localData->id && !$conf['show_oids']) continue; - echo "\n"; - } - - $i = 0; - reset($rs->f); - while (!$rs->EOF) { - $id = (($i % 2) == 0 ? '1' : '2'); - echo "\n"; - if (sizeof($key) > 0) { - $key_str = ''; - $has_nulls = false; - foreach ($key as $v) { - if ($rs->f[$v] === null) { - $has_nulls = true; - break; - } - if ($key_str != '') $key_str .= '&'; - $key_str .= urlencode("key[{$v}]") . '=' . urlencode($rs->f[$v]); - } - if ($has_nulls) { - echo "\n"; - } else { - echo "\n"; - echo "\n"; - } - } - $j = 0; - foreach ($rs->f as $k => $v) { - $finfo = $rs->fetchField($j++); - if ($k == $localData->id && !$conf['show_oids']) continue; - elseif ($v !== null && $v == '') echo ""; - else { - // Trim strings if over length - if ($_REQUEST['strings'] == 'collapsed' && strlen($v) > $conf['max_chars']) { - $v = substr($v, 0, $conf['max_chars'] - 1) . $lang['strellipsis']; - } - echo ""; - } - } - echo "\n"; - $rs->moveNext(); - $i++; - } - echo "
{$lang['stractions']}href}&sortkey=", urlencode($k), "&sortdir="; - // Sort direction opposite to current direction, unless it's currently '' - echo ($_REQUEST['sortdir'] == 'asc' && $_REQUEST['sortkey'] == $k) ? 'desc' : 'asc'; - echo "&strings=", urlencode($_REQUEST['strings']), "&table=", - urlencode($_REQUEST['table']), "\">", $misc->printVal($k), "
 href}&sortkey=", - urlencode($_REQUEST['sortkey']), "&sortdir=", urlencode($_REQUEST['sortdir']), - "&table=", urlencode($_REQUEST['table']), "&strings=", urlencode($_REQUEST['strings']), - "&page=", $_REQUEST['page'], "&{$key_str}\">{$lang['stredit']}href}&sortkey=", - urlencode($_REQUEST['sortkey']), "&sortdir=", urlencode($_REQUEST['sortdir']), - "&table=", urlencode($_REQUEST['table']), "&strings=", urlencode($_REQUEST['strings']), - "&page=", $_REQUEST['page'], "&{$key_str}\">{$lang['strdelete']} ", $misc->printVal($v, true, $finfo->type), "
\n"; - - // Show page navigation - $misc->printPages($_REQUEST['page'], $max_pages, "{$PHP_SELF}?action=browse&page=%s&{$misc->href}&sortkey=" . - urlencode($_REQUEST['sortkey']) . "&sortdir=" . urlencode($_REQUEST['sortdir']) . - "&strings=" . urlencode($_REQUEST['strings']) . "&table=" . urlencode($_REQUEST['table'])); - - echo "

", $rs->recordCount(), " {$lang['strrows']}

\n"; - } - else echo "

{$lang['strnodata']}

\n"; - - echo "

href}\">{$lang['strshowalltables']} |\n"; - if ($_REQUEST['strings'] == 'expanded') - echo "href}&sortkey=", - urlencode($_REQUEST['sortkey']), "&sortdir=", urlencode($_REQUEST['sortdir']), "&table=", urlencode($_REQUEST['table']), - "&strings=collapsed&page=", $_REQUEST['page'], "\">{$lang['strcollapse']}\n"; - else - echo "href}&sortkey=", - urlencode($_REQUEST['sortkey']), "&sortdir=", urlencode($_REQUEST['sortdir']), "&table=", urlencode($_REQUEST['table']), - "&strings=expanded&page=", $_REQUEST['page'], "\">{$lang['strexpand']}\n"; - echo "| href}&sortkey=", - urlencode($_REQUEST['sortkey']), "&sortdir=", urlencode($_REQUEST['sortdir']), "&table=", urlencode($_REQUEST['table']), - "&strings={$_REQUEST['strings']}&page=", $_REQUEST['page'], "\">{$lang['strrefresh']}

\n"; - - } - /** * Show default list of tables in the database */ @@ -707,20 +445,22 @@ echo "\t{$lang['stractions']}\n\n"; $i = 0; while (!$tables->EOF) { + $return_url = urlencode("tables.php?{$misc->href}"); $id = (($i % 2) == 0 ? '1' : '2'); echo "\n\t", $misc->printVal($tables->f[$data->tbFields['tbname']]), "\n"; echo "\t", $misc->printVal($tables->f[$data->tbFields['tbowner']]), "\n"; - echo "\thref}&table=", - urlencode($tables->f[$data->tbFields['tbname']]), "\">{$lang['strbrowse']}\n"; - echo "\thref}&table=", + echo "\thref}&table=", + urlencode($tables->f[$data->tbFields['tbname']]), "&return_url={$return_url}&return_desc=", + urlencode($lang['strback']), "\">{$lang['strbrowse']}\n"; + echo "\thref}&table=", urlencode($tables->f[$data->tbFields['tbname']]), "\">{$lang['strselect']}\n"; - echo "\thref}&table=", + echo "\thref}&table=", urlencode($tables->f[$data->tbFields['tbname']]), "\">{$lang['strinsert']}\n"; - echo "\thref}&table=", + echo "\thref}&table=", urlencode($tables->f[$data->tbFields['tbname']]), "\">{$lang['strproperties']}\n"; - echo "\thref}&table=", + echo "\thref}&table=", urlencode($tables->f[$data->tbFields['tbname']]), "\">{$lang['strempty']}\n"; - echo "\thref}&table=", + echo "\thref}&table=", urlencode($tables->f[$data->tbFields['tbname']]), "\">{$lang['strdrop']}\n"; echo "\n"; $tables->moveNext(); @@ -732,7 +472,7 @@ echo "

{$lang['strnotables']}

\n"; } - echo "

href}\">{$lang['strcreatetable']}

\n"; + echo "

href}\">{$lang['strcreatetable']}

\n"; } $misc->printHeader($lang['strtables']); @@ -771,23 +511,6 @@ case 'confirm_drop': doDrop(true); break; - case 'editrow': - if (isset($_POST['save'])) doEditRow(false); - else doBrowse(); - break; - case 'confeditrow': - doEditRow(true); - break; - case 'delrow': - if (isset($_POST['yes'])) doDelRow(false); - else doBrowse(); - break; - case 'confdelrow': - doDelRow(true); - break; - case 'browse': - doBrowse(); - break; default: doDefault(); break; diff --git a/tblproperties.php b/tblproperties.php index e7c0fb8d..9b1e3060 100644 --- a/tblproperties.php +++ b/tblproperties.php @@ -3,7 +3,7 @@ /** * List tables in a database * - * $Id: tblproperties.php,v 1.29 2003/10/13 08:50:04 chriskl Exp $ + * $Id: tblproperties.php,v 1.30 2003/11/05 08:32:03 chriskl Exp $ */ // Include application functions @@ -388,7 +388,9 @@ echo "
\n"; echo "