commit bryan encina's create view with wizard patch. this still needs a lot more...
authorchriskl <chriskl>
Sun, 9 May 2004 04:31:24 +0000 (04:31 +0000)
committerchriskl <chriskl>
Sun, 9 May 2004 04:31:24 +0000 (04:31 +0000)
BUGS
HISTORY
classes/database/Postgres.php
classes/database/Postgres73.php
lang/english.php
lang/recoded/english.php
views.php

diff --git a/BUGS b/BUGS
index a24525dc95c25e0f7979201d6f6d0c0c1aa4db5a..df3cbfa4c0a797e88551d3dbbe6ba296ab813bc0 100644 (file)
--- a/BUGS
+++ b/BUGS
@@ -28,3 +28,4 @@ NEEDS TESTING
 * Comment stuff
 * Import
 * Script execution
+* Create view wizard looks buggy
\ No newline at end of file
diff --git a/HISTORY b/HISTORY
index 0c083b98677de05d31359ccbbd74cc6717440f87..0accbfe907e6b0c231baaca731f34ecfbb3824aa 100644 (file)
--- a/HISTORY
+++ b/HISTORY
@@ -21,6 +21,7 @@ Features
   (with all options) (Bryan Encina)
 * Fix SQL popup window to reload when the database is changed so
   that the correct page encoding is used.
+* Create view wizard (Bryan Encina)
 
 Bugs
 * Fix pg_dump output for PostgreSQL 7.0.x and 7.1.x
index d413cea1b96fe348b61f8ef82084f11c3ec8006f..fe5be01a27cd9a6cb3975f268cba73458e30c2c7 100755 (executable)
@@ -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.196 2004/05/09 02:00:26 chriskl Exp $
+ * $Id: Postgres.php,v 1.197 2004/05/09 04:31:25 chriskl Exp $
  */
 
 // @@@ THOUGHT: What about inherits? ie. use of ONLY???
@@ -3223,7 +3223,19 @@ class Postgres extends BaseDB {
        }
 
        // Constraint functions
-
+\r
+       /**\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
+        {\r
+               // Pre 7.3 this does nothing\r
+               $recordset = new ADORecordSet;\r
+               return $recordset;\r
+        }\r
+       
        /**
         * A helper function for getConstraints that translates
         * an array of attribute numbers to an array of field names.
index 5961003da172dd611ab21aa9a193b66f08cf0135..a2a232a7998c3f63d9ef3a9ce3e3d738b59593f0 100644 (file)
@@ -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.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???
@@ -346,7 +346,7 @@ class Postgres73 extends Postgres72 {
        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";
@@ -937,6 +937,45 @@ class Postgres73 extends Postgres72 {
        }
 
        // 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
index be9ce7a8ef3f4fe75b73212ba6345def2df47c5d..f2240c757937def828c7aefbd2a3343771df13c4 100755 (executable)
@@ -4,7 +4,7 @@
         * English language file for phpPgAdmin.  Use this as a basis
         * for new translations.
         *
-        * $Id: english.php,v 1.139 2004/04/20 01:34:43 chriskl Exp $
+        * $Id: english.php,v 1.140 2004/05/09 04:31:42 chriskl Exp $
         */
 
        // Language and character set
        $lang['strviewupdatedbad'] = 'View update failed.';
        $lang['strviewlink'] = 'Linking Keys';
        $lang['strviewconditions'] = 'Additional Conditions';
+       $lang['strcreateviewwiz'] = 'Create view with wizard';
 
        // Sequences
        $lang['strsequence'] = 'Sequence';
index 68f585c06ee8c95b03e12a57cb61b5cb57f7789b..a482cb9b240f8364ac4c7406052346906d8acc78 100644 (file)
@@ -4,7 +4,7 @@
         * English language file for phpPgAdmin.  Use this as a basis
         * for new translations.
         *
-        * $Id: english.php,v 1.92 2004/04/20 01:34:43 chriskl Exp $
+        * $Id: english.php,v 1.93 2004/05/09 04:31:42 chriskl Exp $
         */
 
        // Language and character set
        $lang['strviewupdatedbad'] = 'View update failed.';
        $lang['strviewlink'] = 'Linking Keys';
        $lang['strviewconditions'] = 'Additional Conditions';
+       $lang['strcreateviewwiz'] = 'Create view with wizard';
 
        // Sequences
        $lang['strsequence'] = 'Sequence';
index 36a5c644e27de2945285dd70cb4aec1412e0d5e5..e26d3635da8a473555590f6bc2a853fb43c4b8c5 100644 (file)
--- a/views.php
+++ b/views.php
@@ -3,11 +3,12 @@
        /**
         * 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();