* A class that implements the DB interface for Postgres
* Note: This class uses ADODB and returns RecordSets.
*
- * $Id: Postgres73.php,v 1.117 2004/06/03 07:34:56 chriskl Exp $
+ * $Id: Postgres73.php,v 1.118 2004/06/04 05:26:35 chriskl Exp $
*/
// @@@ THOUGHT: What about inherits? ie. use of ONLY???
/**
* A function for getting all columns linked by foreign keys given a group of tables
- * @param $tables Array of table names
+ * @param $tables multi dimensional assoc array that holds schema and table name
* @return An array of linked tables and columns
- * @return -1 $tables isn't an array\r
+ * @return -1 $tables isn't an array
*/
function &getLinkingKeys($tables) {
if (!is_array($tables)) return -1;
- $this->arrayClean($tables);
- $tables_list = "'" . implode("', '", $tables) . "'";
+ $tables_list = "'{$tables[0]['tablename']}'";
+ $schema_list = "'{$tables[0]['schemaname']}'";
+ $schema_tables_list = "'{$tables[0]['schemaname']}.{$tables[0]['tablename']}'";
+ for ($i = 1; $i < sizeof($tables); $i++) {
+ $tables_list .= ", '{$tables[$i]['tablename']}'";
+ $schema_list .= ", '{$tables[$i]['schemaname']}'";
+ $schema_tables_list .= ", '{$tables[$i]['schemaname']}.{$tables[$i]['tablename']}'";
+ }
$maxDimension = 1;
$sql = "
AND pgc1.relname IN ($tables_list)
";
- //parse our output for find the highest dimension of foreign keys since pc.conkey is stored in an array
+ //parse our output to find the highest dimension of foreign keys since pc.conkey is stored in an array
$rs = $this->selectSet($sql);
while (!$rs->EOF) {
$arrData = explode(':', $rs->fields['arr_dim']);
pgc1.relname AS p_table,
pgc2.relname AS f_table,
pfield.attname AS p_field,
- cfield.attname AS f_field
+ cfield.attname AS f_field,
+ pgns1.nspname AS p_schema,
+ pgns2.nspname AS f_schema
FROM
pg_catalog.pg_constraint AS pc,
pg_catalog.pg_class AS pgc1,
pg_catalog.pg_class AS pgc2,
pg_catalog.pg_attribute AS pfield,
- pg_catalog.pg_attribute AS cfield
+ pg_catalog.pg_attribute AS cfield,
+ (SELECT oid AS ns_id, nspname FROM pg_catalog.pg_namespace WHERE nspname IN ($schema_list) ) AS pgns1,
+ (SELECT oid AS ns_id, nspname FROM pg_catalog.pg_namespace WHERE nspname IN ($schema_list) ) AS pgns2
WHERE
pc.contype = 'f'
+ AND pgc1.relnamespace = pgns1.ns_id
+ AND pgc2.relnamespace = pgns2.ns_id
AND pc.conrelid = pgc1.relfilenode
AND pc.confrelid = pgc2.relfilenode
AND pfield.attrelid = pc.conrelid
AND cfield.attrelid = pc.confrelid
AND $cons_str
- AND pgc1.relname IN ($tables_list)
- AND pgc2.relname IN ($tables_list)
- AND pgc1.relnamespace = (SELECT oid FROM pg_catalog.pg_namespace
- WHERE nspname='{$this->_schema}')
- ";
-
+ AND pgns1.nspname || '.' || pgc1.relname IN ($schema_tables_list)
+ AND pgns2.nspname || '.' || pgc2.relname IN ($schema_tables_list)
+ ";
return $this->selectSet($sql);
}
/**
* Manage views in a database
*
- * $Id: views.php,v 1.41 2004/06/03 06:42:20 chriskl Exp $
+ * $Id: views.php,v 1.42 2004/06/04 05:26:35 chriskl Exp $
*/
// Include application functions
echo "<h2>", $misc->printVal($_REQUEST['database']), ": {$lang['strviews']}: {$lang['strcreateviewwiz']}</h2>\n";
$misc->printMsg($msg);
- $tblCount = sizeof($_POST['formTables']);
- // If we have a message that means an error occurred in doSaveCreate, which means POST['formTables'] has quotes
- // around the table names, but getTableAttributes doesn't accept quoted table names so we strip them here
- if (strlen($msg)) {
- for ($i = 0; $i < $tblCount; $i++) {
- $_POST['formTables'][$i] = str_replace('"', '', $_POST['formTables'][$i]);
- }
- }
-
- $arrFields = array(); //array that will hold all our table/field names
-
+
+ $tblCount = sizeof($_POST['formTables']);
+ //unserialize our schema/table information and store in arrSelTables
+ for ($i = 0; $i < $tblCount; $i++) {
+ $arrSelTables[] = unserialize($_POST['formTables'][$i]);
+ }
+
+ $linkCount = $tblCount;
// If we can get foreign key info then get our linking keys
if ($data->hasForeignKeysInfo()) {
- $rsLinkKeys = $data->getLinkingKeys($_POST['formTables']);
-
+ $rsLinkKeys = $data->getLinkingKeys($arrSelTables);
$linkCount = $rsLinkKeys->recordCount() > $tblCount ? $rsLinkKeys->recordCount() : $tblCount;
}
- // Get fieldnames
- for ($i = 0; $i < $tblCount; $i++) {
- $attrs = &$data->getTableAttributes($_POST['formTables'][$i]);
- while (!$attrs->EOF) {
- // Quote table/field name
- $arrFields["\"{$_POST['formTables'][$i]}\"." . "\"{$attrs->f['attname']}\""] = "\"{$_POST['formTables'][$i]}\"." . "\"{$attrs->f['attname']}\"";
+ $arrFields = array(); //array that will hold all our table/field names
+
+ //if we have schemas we need to specify the correct schema for each table we're retrieiving
+ //with getTableAttributes
+ $curSchema = $data->hasSchemas() ? $data->_schema : NULL;
+ for ($i = 0; $i < $tblCount; $i++) {
+ if ($data->hasSchemas() && $data->_schema != $arrSelTables[$i]['schemaname']) {
+ $data->setSchema($arrSelTables[$i]['schemaname']);
+ }
+
+ $attrs = &$data->getTableAttributes($arrSelTables[$i]['tablename']);
+ while (!$attrs->EOF) {
+ if ($data->hasSchemas() ) {
+ $arrFields["{$arrSelTables[$i]['schemaname']}.{$arrSelTables[$i]['tablename']}.{$attrs->f['attname']}"] = serialize(array('schemaname' => $arrSelTables[$i]['schemaname'], 'tablename' => $arrSelTables[$i]['tablename'], 'fieldname' => $attrs->f['attname']) );
+ }
+ else {
+ $arrFields["{$arrSelTables[$i]['tablename']}.{$attrs->f['attname']}"] = serialize(array('schemaname' => NULL, 'tablename' => $arrSelTables[$i]['tablename'], 'fieldname' => $attrs->f['attname']) );
+ }
$attrs->moveNext();
}
- }
+
+ //reset back to our original schema in case we switched from it
+ if ($data->hasSchemas() ) {
+ $data->setSchema($curSchema);
+ }
+ }
asort($arrFields);
echo "<form action=\"$PHP_SELF\" method=\"post\">\n";
echo "<tr><th class=\"data\">{$lang['strcomment']}</th></tr>";
echo "<tr>\n<td class=\"data1\">\n";
// View comments
- echo "<input name=\"formComment\" id=\"formComment\" value=\"", htmlspecialchars($_REQUEST['formComment']), "\" style=\"width: 100%;\" />\n";
+ echo "<textarea name=\"formComment\" rows=\"3\" cols=\"32\" wrap=\"virtual\">",
+ htmlspecialchars($_REQUEST['formComment']), "</textarea>\n";
echo "</td>\n</tr>\n";
echo "</table>\n";
echo "<table>\n";
echo "<tr><th class=\"data\">{$lang['strfields']}</th></tr>";
echo "<tr>\n<td class=\"data1\">\n";
- echo GUI::printCombo($arrFields, 'formFields[]', false, '', true);
+ echo GUI::printCombo($arrFields, 'formFields[]', false, '', true);
echo "</td>\n</tr>\n</table>\n<br />\n";
-
- if ($data->hasForeignKeysInfo()) {
- // Output the Linking keys combo boxes
- echo "<table>\n";
- echo "<tr><th class=\"data\">{$lang['strviewlink']}</th></tr>";
- $rowClass = 'data1';
- for ($i = 0; $i < $linkCount; $i++) {
- // Initialise variables
- if (!isset($formLink[$i]['operator'])) $formLink[$i]['operator'] = 'INNER JOIN';
- echo "<tr>\n<td class=\"$rowClass\">\n";
-
- if (!$rsLinkKeys->EOF) {
- $curLeftLink = htmlspecialchars("\"{$rsLinkKeys->f['p_table']}\".\"{$rsLinkKeys->f['p_field']}\"");
- $curRightLink = htmlspecialchars("\"{$rsLinkKeys->f['f_table']}\".\"{$rsLinkKeys->f['f_field']}\"");
- $rsLinkKeys->moveNext();
- }
- else {
- $curLeftLink = '';
- $curRightLink = '';
- }
-
- echo GUI::printCombo($arrFields, "formLink[$i][leftlink]", true, $curLeftLink, false );
- echo GUI::printCombo($data->joinOps, "formLink[$i][operator]", true, $formLink[$i]['operator']);
- echo GUI::printCombo($arrFields, "formLink[$i][rightlink]", true, $curRightLink, false );
- echo "</td>\n</tr>\n";
- $rowClass = $rowClass == 'data1' ? 'data2' : 'data1';
-
+
+ // Output the Linking keys combo boxes only if we detect linking keys
+ echo "<table>\n";
+ echo "<tr><th class=\"data\">{$lang['strviewlink']}</th></tr>";
+ $rowClass = 'data1';
+ for ($i = 0; $i < $linkCount; $i++) {
+ // Initialise variables
+ if (!isset($formLink[$i]['operator'])) $formLink[$i]['operator'] = 'INNER JOIN';
+ echo "<tr>\n<td class=\"$rowClass\">\n";
+
+ if ($data->hasForeignKeysInfo() && !$rsLinkKeys->EOF) {
+ $curLeftLink = htmlspecialchars(serialize(array('schemaname' => $rsLinkKeys->f['p_schema'], 'tablename' => $rsLinkKeys->f['p_table'], 'fieldname' => $rsLinkKeys->f['p_field']) ) );
+ $curRightLink = htmlspecialchars(serialize(array('schemaname' => $rsLinkKeys->f['f_schema'], 'tablename' => $rsLinkKeys->f['f_table'], 'fieldname' => $rsLinkKeys->f['f_field']) ) );
+ $rsLinkKeys->moveNext();
}
- echo "</table>\n<br />\n";
- }
-
- // Output additional conditions
-
+ else {
+ $curLeftLink = '';
+ $curRightLink = '';
+ }
+
+ echo GUI::printCombo($arrFields, "formLink[$i][leftlink]", true, $curLeftLink, false );
+ echo GUI::printCombo($data->joinOps, "formLink[$i][operator]", true, $formLink[$i]['operator']);
+ echo GUI::printCombo($arrFields, "formLink[$i][rightlink]", true, $curRightLink, false );
+ echo "</td>\n</tr>\n";
+ $rowClass = $rowClass == 'data1' ? 'data2' : 'data1';
+ }
+ echo "</table>\n<br />\n";
+
// Build list of available operators (infix only)
$arrOperators = array();
foreach ($data->selectOps as $k => $v) {
if ($v == 'i') $arrOperators[$k] = $k;
}
+ // Output additional conditions, note that this portion of the wizard treats the right hand side as literal values
+ //(not as database objects) so field names will be treated as strings, use the above linking keys section to perform joins
echo "<table>\n";
echo "<tr><th class=\"data\">{$lang['strviewconditions']}</th></tr>";
$rowClass = 'data1';
- for ($i = 0; $i < 3; $i++) {
+ for ($i = 0; $i < $linkCount; $i++) {
echo "<tr>\n<td class=\"$rowClass\">\n";
echo GUI::printCombo($arrFields, "formCondition[$i][field]");
echo GUI::printCombo($arrOperators, "formCondition[$i][operator]", false, false);
echo "<input type=\"submit\" value=\"{$lang['strnext']}\" />\n";
echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n";
- foreach ($_POST['formTables'] AS $curTable) {
- echo "<input type=\"hidden\" name=\"formTables[]\" id=\"formTables[]\" value=\"" . htmlspecialchars("\"$curTable\"") . "\" />\n";
+ foreach ($arrSelTables AS $curTable) {
+ echo "<input type=\"hidden\" name=\"formTables[]\" id=\"formTables[]\" value=\"" . htmlspecialchars(serialize($curTable) ) . "\" />\n";
}
echo $misc->form;
function doWizardCreate($msg = '') {
global $data, $misc;
global $PHP_SELF, $lang;
- $tables = &$data->getTables();
-
+ $tables = &$data->getTables(true);
echo "<h2>", $misc->printVal($_REQUEST['database']), ": {$lang['strviews']}: {$lang['strcreateviewwiz']}</h2>\n";
$misc->printMsg($msg);
echo "<form action=\"$PHP_SELF\" method=\"post\">\n";
echo "<tr>\n<td class=\"data1\">\n";
$arrTables = array();
- while (!$tables->EOF) {
- $arrTables[$tables->f[$data->tbFields['tbname']]] = $tables->f[$data->tbFields['tbname']];
+ while (!$tables->EOF) {
+ $arrTmp = array();
+ $arrTmp['schemaname'] = $tables->f['schemaname'];
+ $arrTmp['tablename'] = $tables->f['tablename'];
+ if ($data->hasSchemas() ) { //if schemas aren't available don't show them in the interface
+ $arrTables[$tables->f['schemaname'] . '.' . $tables->f['tablename']] = serialize($arrTmp);
+ }
+ else {
+ $arrTables[$tables->f['tablename']] = serialize($arrTmp);
+ }
$tables->moveNext();
}
echo GUI::printCombo($arrTables, 'formTables[]', false, '', true);
if (!strlen($_POST['formView']) ) doSetParamsCreate($lang['strviewneedsname']);
else if (!isset($_POST['formFields']) || !count($_POST['formFields']) ) doSetParamsCreate($lang['strviewneedsfields']);
- else {
- $selTables = implode(', ', $_POST['formTables']);
- $selFields = implode(', ', $_POST['formFields']);
+ else {
+ $selFields = '';
+ foreach ($_POST['formFields'] AS $curField) {
+ $arrTmp = unserialize($curField);
+ if ($data->hasSchemas() ) {
+ $selFields .= strlen($selFields) ? ", \"{$arrTmp['schemaname']}\".\"{$arrTmp['tablename']}\".\"{$arrTmp['fieldname']}\"" : "\"{$arrTmp['schemaname']}\".\"{$arrTmp['tablename']}\".\"{$arrTmp['fieldname']}\"";
+ }
+ else {
+ $selFields .= strlen($selFields) ? ", \"{$arrTmp['tablename']}\".\"{$arrTmp['fieldname']}\"" : "\"{$arrTmp['tablename']}\".\"{$arrTmp['fieldname']}\"";
+ }
+ }
$linkFields = '';
while ($j < $count) {
foreach ($arrLinks AS $curLink) {
- $tbl1 = substr($curLink['leftlink'], 0, strpos($curLink['leftlink'], '.') );
- $tbl2 = substr($curLink['rightlink'], 0, strpos($curLink['rightlink'], '.') );
+ $arrLeftLink = unserialize($curLink['leftlink']);
+ $arrRightLink = unserialize($curLink['rightlink']);
+
+ $tbl1 = $data->hasSchemas() ? "\"{$arrLeftLink['schemaname']}\".\"{$arrLeftLink['tablename']}\"" : $arrLeftLink['tablename'];
+ $tbl2 = $data->hasSchemas() ? "\"{$arrRightLink['schemaname']}\".\"{$arrRightLink['tablename']}\"" : $arrLeftLink['tablename'];
if ( (!in_array($curLink, $arrJoined) && in_array($tbl1, $arrUsedTbls)) || !count($arrJoined) ) {
// Make sure for multi-column foreign keys that we use a table alias tables joined to more than once
// This can (and should be) more optimized for multi-column foreign keys
$adj_tbl2 = in_array($tbl2, $arrUsedTbls) ? "$tbl2 AS alias_ppa_" . mktime() : $tbl2;
+
+ if ($data->hasSchemas() ) {
+ $linkFields .= strlen($linkFields) ? "{$curLink['operator']} $adj_tbl2 ON (\"{$arrLeftLink['schemaname']}\".\"{$arrLeftLink['tablename']}\".\"{$arrLeftLink['fieldname']}\" = \"{$arrRightLink['schemaname']}\".\"{$arrRightLink['tablename']}\".\"{$arrRightLink['fieldname']}\") " : "$tbl1 {$curLink['operator']} $adj_tbl2 ON (\"{$arrLeftLink['schemaname']}\".\"{$arrLeftLink['tablename']}\".\"{$arrLeftLink['fieldname']}\" = \"{$arrRightLink['schemaname']}\".\"{$arrRightLink['tablename']}\".\"{$arrRightLink['fieldname']}\") ";
+ }
+ else {
+ $linkFields .= strlen($linkFields) ? "{$curLink['operator']} $adj_tbl2 ON (\"{$arrLeftLink['tablename']}\".\"{$arrLeftLink['fieldname']}\" = \"{$arrRightLink['tablename']}\".\"{$arrRightLink['fieldname']}\") " : "$tbl1 {$curLink['operator']} $adj_tbl2 ON (\"{$arrLeftLink['tablename']}\".\"{$arrLeftLink['fieldname']}\" = \"{$arrRightLink['tablename']}\".\"{$arrRightLink['fieldname']}\") ";
+ }
- $linkFields .= strlen($linkFields) ? "{$curLink['operator']} $adj_tbl2 ON ({$curLink['leftlink']} = {$curLink['rightlink']}) " : "$tbl1 {$curLink['operator']} $adj_tbl2 ON ({$curLink['leftlink']} = {$curLink['rightlink']}) ";
$arrJoined[] = $curLink;
if (!in_array($tbl1, $arrUsedTbls) ) $arrUsedTbls[] = $tbl1;
if (!in_array($tbl2, $arrUsedTbls) ) $arrUsedTbls[] = $tbl2;
}
$j++;
}
- }
- // Otherwise, just select from all seleted tables - a cartesian join
- else {
- $linkFields = implode(', ', $_POST['formTables']);
- }
- }
- // Otherwise, just select from all seleted tables - a cartesian join
- else {
- $linkFields = implode(', ', $_POST['formTables']);
- }
+ }
+ }
+
+ //if linkfields has no length then either _POST['formLink'] was not set, or there were no join conditions
+ //just select from all seleted tables - a cartesian join do a
+ if (!strlen($linkFields) ) {
+ foreach ($_POST['formTables'] AS $curTable) {
+ $arrTmp = unserialize($curTable);
+ if ($data->hasSchemas() ) {
+ $linkFields .= strlen($linkFields) ? ", \"{$arrTmp['schemaname']}\".\"{$arrTmp['tablename']}\"" : "\"{$arrTmp['schemaname']}\".\"{$arrTmp['tablename']}\"";
+ }
+ else {
+ $linkFields .= strlen($linkFields) ? ", \"{$arrTmp['tablename']}\"" : "\"{$arrTmp['tablename']}\"";
+ }
+ }
+ }
$addConditions = '';
if (is_array($_POST['formCondition']) ) {
foreach ($_POST['formCondition'] AS $curCondition) {
- if (strlen($curCondition['field']) && strlen($curCondition['txt']) ) {
- $addConditions .= strlen($addConditions) ? ' AND ' . "{$curCondition['field']} {$curCondition['operator']} '{$curCondition['txt']}' " : " {$curCondition['field']} {$curCondition['operator']} '{$curCondition['txt']}' ";
+ if (strlen($curCondition['field']) && strlen($curCondition['txt']) ) {
+ $arrTmp = unserialize($curCondition['field']);
+ if ($data->hasSchemas() ) {
+ $addConditions .= strlen($addConditions) ? " AND \"{$arrTmp['schemaname']}\".\"{$arrTmp['tablename']}\".\"{$arrTmp['fieldname']}\" {$curCondition['operator']} '{$curCondition['txt']}' " : " \"{$arrTmp['schemaname']}\".\"{$arrTmp['tablename']}\".\"{$arrTmp['fieldname']}\" {$curCondition['operator']} '{$curCondition['txt']}' ";
+ }
+ else {
+ $addConditions .= strlen($addConditions) ? " AND \"{$arrTmp['tablename']}\".\"{$arrTmp['fieldname']}\" {$curCondition['field']} {$curCondition['operator']} '{$curCondition['txt']}' " : " \"{$arrTmp['tablename']}\".\"{$arrTmp['fieldname']}\" {$curCondition['operator']} '{$curCondition['txt']}' ";
+ }
}
}
}