* A class that implements the DB interface for Postgres
* Note: This class uses ADODB and returns RecordSets.
*
- * $Id: Postgres73.php,v 1.99 2004/05/09 02:00:26 chriskl Exp $
+ * $Id: Postgres73.php,v 1.100 2004/05/09 04:31:42 chriskl Exp $
*/
// @@@ THOUGHT: What about inherits? ie. use of ONLY???
function &getTables($all = false) {
if ($all) {
// Exclude pg_catalog and information_schema tables
- $sql = "SELECT schemaname, tablename, tableowner,pg_catalog.obj_description(c.oid, 'pg_class') AS tablecomment
+ $sql = "SELECT schemaname, tablename, tableowner
FROM pg_catalog.pg_tables
WHERE schemaname NOT IN ('pg_catalog', 'information_schema', 'pg_toast')
ORDER BY schemaname, tablename";
}
// Constraint functions
+
+ /**\r
+ * A function for getting all linking fields on the foreign keys based on the table names \r
+ * @param $table array of table names \r
+ * @return an array of linked tables and fields\r
+ */\r
+ function &getLinkingKeys($arrTables) { \r
+ $this->arrayClean($arrTables); \r
+ // Properly quote the tables \r
+ $tables = "'" . implode("', '", $arrTables) . "'";\r
+ \r
+ $sql = "\r
+ SELECT \r
+ pgc1.relname AS p_table, \r
+ pgc2.relname AS f_table,\r
+ pfield.attname AS p_field,\r
+ cfield.attname AS f_field \r
+ FROM\r
+ pg_catalog.pg_constraint AS pc,\r
+ pg_catalog.pg_class AS pgc1,\r
+ pg_catalog.pg_class AS pgc2,\r
+ pg_catalog.pg_attribute AS pfield,\r
+ pg_catalog.pg_attribute AS cfield\r
+ WHERE\r
+ pc.contype = 'f' \r
+ AND pc.conrelid = pgc1.relfilenode\r
+ AND pc.confrelid = pgc2.relfilenode\r
+ AND pfield.attrelid = pc.conrelid\r
+ AND cfield.attrelid = pc.confrelid\r
+ AND pfield.attnum = ANY(pc.conkey)\r
+ AND cfield.attnum = ANY(pc.confkey) \r
+ AND pgc1.relname IN ($tables) \r
+ AND pgc2.relname IN ($tables)\r
+ AND pgc1.relnamespace = (SELECT oid FROM pg_catalog.pg_namespace\r
+ WHERE nspname='{$this->_schema}')\r
+ ";
+ \r
+ return $this->selectSet($sql); \r
+ }
/**
* A helper function for getConstraints that translates
/**
* Manage views in a database
*
- * $Id: views.php,v 1.29 2004/05/08 14:45:10 chriskl Exp $
+ * $Id: views.php,v 1.30 2004/05/09 04:31:24 chriskl Exp $
*/
// Include application functions
include_once('./libraries/lib.inc.php');
+ include_once('./classes/Gui.php');
$action = (isset($_REQUEST['action'])) ? $_REQUEST['action'] : '';
if (!isset($msg)) $msg = '';
}
+ /**\r
+ * Sets up choices for table linkage, and which fields to select for the view we're creating\r
+ */\r
+ function doSetParamsCreate($msg = '') {\r
+ global $data, $misc;\r
+ global $PHP_SELF, $lang;\r
+ \r
+ // Check that they've chosen tables for the view definition\r
+ if (!isset($_POST['formTables']) ) doWizardCreate($lang['strviewneedsdef']);\r
+ else {
+ // Initialise variables
+ if (!isset($_REQUEST['formView'])) $_REQUEST['formView'] = '';
+ if (!isset($_REQUEST['formComment'])) $_REQUEST['formComment'] = '';
+ \r
+ echo "<h2>", $misc->printVal($_REQUEST['database']), ": {$lang['strviews']}: {$lang['strcreateview']}</h2>\n"; \r
+ $misc->printMsg($msg);\r
+ $tblCount = count($_POST['formTables']);\r
+ // If we have a message that means an error occurred in doSaveCreate, which means POST['formTables'] has quotes\r
+ // around the table names, but getTableAttributes doesn't accept quoted table names so we strip them here\r
+ if (strlen($msg)) {\r
+ for ($i = 0; $i < $tblCount; $i++) {\r
+ $_POST['formTables'][$i] = str_replace('"', '', $_POST['formTables'][$i]);\r
+ }\r
+ }\r
+ \r
+ $arrFields = array(); //array that will hold all our table/field names \r
+ \r
+ $rsLinkKeys = $data->getLinkingKeys($_POST['formTables']);\r
+ \r
+ // Update tblcount if we have more foreign keys than tables (perhaps in the case of composite foreign keys)\r
+ $tblCount = $rsLinkKeys->recordCount() > $tblCount ? $rsLinkKeys->recordCount() : $tblCount;\r
+ \r
+ // Get fieldnames\r
+ for ($i = 0; $i < $tblCount; $i++) { \r
+ $attrs = &$data->getTableAttributes($_POST['formTables'][$i]);\r
+ while (!$attrs->EOF) {\r
+ // Quote table/field name\r
+ $arrFields["\"{$_POST['formTables'][$i]}\"." . "\"{$attrs->f['attname']}\""] = "\"{$_POST['formTables'][$i]}\"." . "\"{$attrs->f['attname']}\"";\r
+ $attrs->moveNext();\r
+ }\r
+ }\r
+ asort($arrFields); \r
+ \r
+ echo "<form action=\"$PHP_SELF\" method=\"post\">\n";\r
+ echo "<table>\n";\r
+ echo "<tr><th class=\"data\">{$lang['strviewname']}</th></tr>";\r
+ echo "<tr>\n<td class=\"data1\">\n";\r
+ // View name\r
+ echo "<input name=\"formView\" id=\"formView\" value=\"", htmlspecialchars($_REQUEST['formView']), "\" style=\"width: 100%;\" />\n";\r
+ echo "</td>\n</tr>\n";\r
+ echo "<tr><th class=\"data\">{$lang['strcomment']}</th></tr>";\r
+ echo "<tr>\n<td class=\"data1\">\n";\r
+ // View comments \r
+ echo "<input name=\"formComment\" id=\"formComment\" value=\"", htmlspecialchars($_REQUEST['formComment']), "\" style=\"width: 100%;\" />\n";\r
+ echo "</td>\n</tr>\n"; \r
+ echo "<tr>\n<td class=\"data1\">\n";\r
+ \r
+ // Output selector for fields to be retrieved from view\r
+ echo GUI::printCombo($arrFields, 'formFields[]', false, '', true); \r
+ echo "</td>\n</tr>\n</table>\n<br />\n"; \r
+ \r
+ // Output the Linking keys combo boxes\r
+ $arrLinkOperators = array('INNER JOIN' => 'INNER JOIN', 'LEFT JOIN' => 'LEFT JOIN', 'RIGHT JOIN' => 'RIGHT JOIN');\r
+ echo "<table>\n";\r
+ echo "<tr><th class=\"data\">{$lang['strviewlink']}</th></tr>"; \r
+ $rowClass = 'data1';\r
+ for ($i = 0; $i <= $tblCount; $i++) {
+ // Initialise variables
+ if (!isset($formLink[$i]['operator'])) $formLink[$i]['operator'] = 'INNER JOIN';\r
+ echo "<tr>\n<td class=\"$rowClass\">\n";\r
+ \r
+ if (!$rsLinkKeys->EOF) {\r
+ $curLeftLink = htmlspecialchars("\"{$rsLinkKeys->f['p_table']}\".\"{$rsLinkKeys->f['p_field']}\"");\r
+ $curRightLink = htmlspecialchars("\"{$rsLinkKeys->f['f_table']}\".\"{$rsLinkKeys->f['f_field']}\"");\r
+ $rsLinkKeys->moveNext();\r
+ }\r
+ else {\r
+ $curLeftLink = '';\r
+ $curRightLink = '';\r
+ }\r
+ \r
+ echo GUI::printCombo($arrFields, "formLink[$i][leftlink]", true, $curLeftLink, false );\r
+ echo GUI::printCombo($arrLinkOperators, "formLink[$i][operator]", true, $formLink[$i]['operator']); \r
+ echo GUI::printCombo($arrFields, "formLink[$i][rightlink]", true, $curRightLink, false );\r
+ echo "</td>\n</tr>\n";\r
+ $rowClass = $rowClass == 'data1' ? 'data2' : 'data1';\r
+ \r
+ }\r
+ echo "</table>\n<br />\n"; \r
+ \r
+ // Output additional conditions \r
+ $arrOperators = array('=' => '=', 'LIKE' => 'LIKE', '!=' => '!=', '>' => '>', '<' =>'<', 'IN' => 'IN', '!!=' => '!!=', 'BETWEEN' => 'BETWEEN');\r
+ echo "<table>\n";\r
+ echo "<tr><th class=\"data\">{$lang['strviewconditions']}</th></tr>"; \r
+ $rowClass = 'data1';\r
+ for ($i = 0; $i < 3; $i++) { \r
+ echo "<tr>\n<td class=\"$rowClass\">\n";\r
+ echo GUI::printCombo($arrFields, "formCondition[$i][field]");\r
+ echo GUI::printCombo($arrOperators, "formCondition[$i][operator]", false, false);\r
+ echo "<input type=\"text\" name=\"formCondition[$i][txt]\" />\n";\r
+ echo "</td>\n</tr>\n";\r
+ $rowClass = $rowClass == 'data1' ? 'data2' : 'data1';\r
+ } \r
+ echo "</table>\n";
+ echo "<p><input type=\"hidden\" name=\"action\" id=\"action\" value=\"save_create_wiz\" />\n"; \r
+ echo "<input type=\"submit\" value=\"{$lang['strnext']}\" />\n";
+ echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n";\r
+ \r
+ foreach ($_POST['formTables'] AS $curTable) {\r
+ echo "<input type=\"hidden\" name=\"formTables[]\" id=\"formTables[]\" value=\"" . htmlspecialchars("\"$curTable\"") . "\" />\n";\r
+ }\r
+ \r
+ echo $misc->form;\r
+ echo "</form>\n";\r
+ } \r
+ }\r
+ \r
+ /**\r
+ * Display a wizard where they can enter a new view\r
+ */\r
+ function doWizardCreate($msg = '') {\r
+ global $data, $misc;\r
+ global $PHP_SELF, $lang;\r
+ $tables = &$data->getTables();\r
+ \r
+ echo "<h2>", $misc->printVal($_REQUEST['database']), ": {$lang['strviews']}: {$lang['strcreateview']}</h2>\n"; \r
+ $misc->printMsg($msg);\r
+ echo "<form action=\"$PHP_SELF\" method=\"post\">\n";\r
+ echo "<table>\n";\r
+ echo "<tr><th class=\"data\">{$lang['strtables']}</th></tr>"; \r
+ echo "<tr>\n<td class=\"data1\">\n"; \r
+ \r
+ $arrTables = array();\r
+ while (!$tables->EOF) { \r
+ $arrTables[$tables->f[$data->tbFields['tbname']]] = $tables->f[$data->tbFields['tbname']]; \r
+ $tables->moveNext();\r
+ } \r
+ echo GUI::printCombo($arrTables, 'formTables[]', false, '', true); \r
+ \r
+ echo "</td>\n</tr>\n"; \r
+ echo "</table>\n"; \r
+ echo "<p><input type=\"submit\" value=\"{$lang['strnext']}\" />\n";
+ echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n";\r
+ echo "<input type=\"hidden\" name=\"action\" id=\"action\" value=\"set_params_create\" />\n";\r
+ echo $misc->form;\r
+ echo "</form>\n";\r
+ }\r
+
/**
* Displays a screen where they can enter a new view
*/
}
}
+ /**\r
+ * Actually creates the new wizard view in the database\r
+ */\r
+ function doSaveCreateWiz() {\r
+ global $data, $lang;\r
+ \r
+ // Check that they've given a name and fields they want to select \r
+ if (!strlen($_POST['formView']) || !isset($_POST['formFields']) || !count($_POST['formFields']) ) doSetParamsCreate($lang['strviewneedsdef']);\r
+ else { \r
+ $selTables = implode(', ', $_POST['formTables']); \r
+ $selFields = implode(', ', $_POST['formFields']); \r
+ \r
+ $linkFields = '';\r
+ \r
+ if (is_array($_POST['formLink']) ) {\r
+ \r
+ // Filter out invalid/blank entries for our links\r
+ $arrLinks = array();\r
+ foreach ($_POST['formLink'] AS $curLink) {\r
+ if (strlen($curLink['leftlink']) && strlen($curLink['rightlink']) && strlen($curLink['operator'])) {\r
+ $arrLinks[] = $curLink;\r
+ }\r
+ } \r
+ // We must perform some magic to make sure that we have a valid join order\r
+ $count = count($arrLinks);\r
+ $arrJoined = array();\r
+ $arrUsedTbls = array(); \r
+ \r
+ $j = 0;\r
+ while ($j < $count) { \r
+ foreach ($arrLinks AS $curLink) {\r
+ \r
+ $tbl1 = substr($curLink['leftlink'], 0, strpos($curLink['leftlink'], '.') );\r
+ $tbl2 = substr($curLink['rightlink'], 0, strpos($curLink['rightlink'], '.') );\r
+ \r
+ if ( (!in_array($curLink, $arrJoined) && in_array($tbl1, $arrUsedTbls)) || !count($arrJoined) ) {\r
+ \r
+ $linkFields .= strlen($linkFields) ? "{$curLink['operator']} $tbl2 ON ({$curLink['leftlink']} = {$curLink['rightlink']}) " : "$tbl1 {$curLink['operator']} $tbl2 ON ({$curLink['leftlink']} = {$curLink['rightlink']}) ";\r
+ $arrJoined[] = $curLink;\r
+ if (!in_array($tbl1, $arrUsedTbls) ) $arrUsedTbls[] = $tbl1;\r
+ if (!in_array($tbl2, $arrUsedTbls) ) $arrUsedTbls[] = $tbl2;\r
+ } \r
+ }\r
+ $j++; \r
+ }\r
+ }\r
+ \r
+ $addConditions = '';\r
+ if (is_array($_POST['formCondition']) ) {\r
+ foreach ($_POST['formCondition'] AS $curCondition) {\r
+ if (strlen($curCondition['field']) && strlen($curCondition['txt']) ) {\r
+ $addConditions .= strlen($addConditions) ? ' AND ' . "{$curCondition['field']} {$curCondition['operator']} '{$curCondition['txt']}' " : " {$curCondition['field']} {$curCondition['operator']} '{$curCondition['txt']}' ";\r
+ } \r
+ } \r
+ }\r
+ \r
+ $viewQuery = "SELECT $selFields FROM $linkFields ";\r
+ \r
+ //add where from additional conditions\r
+ if (strlen($addConditions) ) $viewQuery .= ' WHERE ' . $addConditions;\r
+ \r
+ $status = $data->createView($_POST['formView'], $viewQuery, false, $_POST['formComment']);\r
+ \r
+ if ($status == 0)\r
+ doDefault($lang['strviewcreated']);\r
+ else \r
+ doSetParamsCreate($lang['strviewcreatedbad']);\r
+ }\r
+ } \r
+
/**
* Show default list of views in the database
*/
echo "<p>{$lang['strnoviews']}</p>\n";
}
- echo "<p><a class=\"navlink\" href=\"$PHP_SELF?action=create&{$misc->href}\">{$lang['strcreateview']}</a></p>\n";
+ echo "<p><a class=\"navlink\" href=\"$PHP_SELF?action=create&{$misc->href}\">{$lang['strcreateview']}</a> |\n";
+ echo "<a class=\"navlink\" href=\"$PHP_SELF?action=wiz_create&{$misc->href}\">{$lang['strcreateviewwiz']}</a></p>\n";
}
case 'confselectrows':
doSelectRows(true);
break;
+ case 'save_create_wiz':\r
+ if (isset($_REQUEST['cancel'])) doDefault();\r
+ else doSaveCreateWiz();\r
+ break;\r
+ case 'wiz_create':\r
+ doWizardCreate();\r
+ break;\r
+ case 'set_params_create':
+ if (isset($_POST['cancel'])) doDefault();
+ else doSetParamsCreate();\r
+ break;\r
case 'save_create':
if (isset($_REQUEST['cancel'])) doDefault();
else doSaveCreate();