Add ability to create and drop custom aggregates, view aggregate details, and alter...
authorxzilla <xzilla>
Wed, 9 Aug 2006 21:19:44 +0000 (21:19 +0000)
committerxzilla <xzilla>
Wed, 9 Aug 2006 21:19:44 +0000 (21:19 +0000)
Patch from Javier Carlos with a little refactoring from me.

aggregates.php
classes/Misc.php
classes/database/Postgres.php
classes/database/Postgres73.php
classes/database/Postgres74.php
lang/english.php
lang/recoded/english.php

index 700debc9a44e5473dc3a1f6a1d48fca12978b07a..9cba3694bda425050c2bf392e89de8724ae31a94 100644 (file)
@@ -3,7 +3,7 @@
        /**
         * Manage aggregates in a database
         *
-        * $Id: aggregates.php,v 1.13 2005/11/25 08:49:08 jollytoad Exp $
+        * $Id: aggregates.php,v 1.14 2006/08/09 21:19:44 xzilla Exp $
         */
 
        // Include application functions
        
        $action = (isset($_REQUEST['action'])) ? $_REQUEST['action'] : '';
        if (!isset($msg)) $msg = '';
+       $PHP_SELF = $_SERVER['PHP_SELF'];
 
        /**
-        * Show default list of aggregates in the database
+        * Actually creates the new aggregate in the database
+        */
+       function doSaveCreate() {
+               global $data, $lang, $_reload_browser;
+
+               // Check inputs
+               if (trim($_REQUEST['name']) == '') {
+                       doCreate($lang['straggrneedsname']);
+                       return;
+               }
+               else if (trim($_REQUEST['basetype']) == '') {
+                       doCreate($lang['straggrneedsbasetype']);
+                       return;
+               }
+               else if (trim($_REQUEST['sfunc']) == '') {
+                       doCreate($lang['straggrneedssfunc']);
+                       return;
+               }
+               else if (trim($_REQUEST['stype']) == '') {
+                       doCreate($lang['straggrneedsstype']);
+                       return;
+               }
+
+               $status = $data->createAggregate($_REQUEST['name'], $_REQUEST['basetype'], $_REQUEST['sfunc'], $_REQUEST['stype'], 
+               $_REQUEST['ffunc'], $_REQUEST['initcond'], $_REQUEST['sortop'], $_REQUEST['aggrcomment']);
+                       
+               if ($status == 0) {
+                       $_reload_browser = true;
+                       doDefault($lang['straggrcreated']);
+               }
+               else {
+                       doCreate($lang['straggrcreatedbad']);
+               }
+       }       
+
+       /**
+        * Displays a screen for create a new aggregate function
+        */
+       function doCreate($msg = '') {
+               global $data, $misc;
+               global $PHP_SELF, $lang;
+
+               if (!isset($_REQUEST['name'])) $_REQUEST['name'] = '';
+               if (!isset($_REQUEST['basetype'])) $_REQUEST['basetype'] = '';
+               if (!isset($_REQUEST['sfunc'])) $_REQUEST['sfunc'] = '';
+               if (!isset($_REQUEST['stype'])) $_REQUEST['stype'] = '';
+               if (!isset($_REQUEST['ffunc'])) $_REQUEST['ffunc'] = '';
+               if (!isset($_REQUEST['initcond'])) $_REQUEST['initcond'] = '';
+               if (!isset($_REQUEST['sortop'])) $_REQUEST['sortop'] = '';
+               if (!isset($_REQUEST['aggrcomment'])) $_REQUEST['aggrcomment'] = '';
+
+               $misc->printTrail('schema');
+               $misc->printTitle($lang['strcreateaggregate'], 'pg.aggregate.create');
+               $misc->printMsg($msg);
+                               
+               echo "<form action=\"$PHP_SELF\" method=\"post\">\n";
+               echo "<table>\n";
+               echo "\t<tr>\n\t\t<th class=\"data left required\">{$lang['strname']}</th>\n";
+               echo "\t\t<td class=\"data\"><input name=\"name\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"", 
+                       htmlspecialchars($_REQUEST['name']), "\" /></td>\n\t</tr>\n";
+               echo "\t<tr>\n\t\t<th class=\"data left required\">{$lang['straggrbasetype']}</th>\n";
+               echo "\t\t<td class=\"data\"><input name=\"basetype\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"", 
+                       htmlspecialchars($_REQUEST['basetype']), "\" /></td>\n\t</tr>\n";
+               echo "\t<tr>\n\t\t<th class=\"data left required\">{$lang['straggrsfunc']}</th>\n";
+               echo "\t\t<td class=\"data\"><input name=\"sfunc\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"", 
+                       htmlspecialchars($_REQUEST['sfunc']), "\" /></td>\n\t</tr>\n";
+               echo "\t<tr>\n\t\t<th class=\"data left required\">{$lang['straggrstype']}</th>\n";
+               echo "\t\t<td class=\"data\"><input name=\"stype\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"", 
+                       htmlspecialchars($_REQUEST['stype']), "\" /></td>\n\t</tr>\n";
+               echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['straggrffunc']}</th>\n";
+               echo "\t\t<td class=\"data\"><input name=\"ffunc\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"", 
+                       htmlspecialchars($_REQUEST['ffunc']), "\" /></td>\n\t</tr>\n";
+               echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['straggrinitcond']}</th>\n";
+               echo "\t\t<td class=\"data\"><input name=\"initcond\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"", 
+                       htmlspecialchars($_REQUEST['initcond']), "\" /></td>\n\t</tr>\n";
+               echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['straggrsortop']}</th>\n";
+               echo "\t\t<td class=\"data\"><input name=\"sortop\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"", 
+                       htmlspecialchars($_REQUEST['sortop']), "\" /></td>\n\t</tr>\n";
+               echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['strcomment']}</th>\n";
+               echo "\t\t<td><textarea name=\"aggrcomment\" rows=\"3\" cols=\"32\" wrap=\"virtual\">", 
+                       htmlspecialchars($_REQUEST['aggrcomment']), "</textarea></td>\n\t</tr>\n";
+
+               echo "</table>\n";
+               echo "<p><input type=\"hidden\" name=\"action\" value=\"save_create\" />\n";
+               echo $misc->form;
+               echo "<input type=\"submit\" value=\"{$lang['strcreate']}\" />\n";
+               echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n";
+               echo "</form>\n";
+       }
+
+       /** 
+        * Function to save after altering an aggregate 
+        */
+       function doSaveAlter() {
+               global $data, $lang;
+
+               // Check inputs
+               if (trim($_REQUEST['aggrname']) == '') {
+                       doAlter($lang['straggrneedsname']);
+                       return;
+               }
+               $status = $data->alterAggregate($_REQUEST['aggrname'], $_REQUEST['aggrtype'], $_REQUEST['aggrowner'], 
+                       $_REQUEST['aggrschema'], $_REQUEST['aggrcomment'], $_REQUEST['newaggrname'], $_REQUEST['newaggrowner'], 
+                       $_REQUEST['newaggrschema'], $_REQUEST['newaggrcomment']);
+               if ($status == 0)
+                       doDefault($lang['straggraltered']);
+               else {
+                       doAlter($lang['straggralteredbad']);
+                       return;
+               }
+       }
+
+
+       /**
+        * Function to allow editing an aggregate function
+        */
+       function doAlter($msg = '') {
+               global $data, $misc;
+               global $PHP_SELF, $lang;
+
+               $misc->printTrail('aggregate');
+               $misc->printTitle($lang['stralteraggregate'], 'pg.aggregate.alter');
+               $misc->printMsg($msg);
+
+               echo "<form action=\"$PHP_SELF\" method=\"post\">\n";
+               $aggrdata = $data->getAggregate($_REQUEST['aggrname'], $_REQUEST['aggrtype']);
+               if($aggrdata->recordCount() > 0 ) {
+                       // Output table header
+                       echo "<table>\n";
+                       echo "\t<tr>\n\t\t<th class=\"data required\">{$lang['strname']}</th>";
+                       echo "<th class=\"data required\">{$lang['strowner']}</th>";
+                       echo "<th class=\"data required\">{$lang['strschema']}</th>\n\t</tr>\n";
+
+                       // Display aggregate's name, owner and schema
+                       echo "\t<tr>\n\t\t<td><input name=\"newaggrname\" size=\"32\" maxlength=\"32\" value=\"", htmlspecialchars($_REQUEST['aggrname']), "\" /></td>";
+                       echo "<td><input name=\"newaggrowner\" size=\"32\" maxlength=\"32\" value=\"", htmlspecialchars($aggrdata->f['usename']), "\" /></td>";
+                       echo "<td><input name=\"newaggrschema\" size=\"32\" maxlength=\"32\" value=\"", htmlspecialchars($_REQUEST['schema']), "\" /></td>\n\t</tr>\n";
+                       echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['strcomment']}</th>\n";
+                       echo "\t\t<td><textarea name=\"newaggrcomment\" rows=\"3\" cols=\"32\" wrap=\"virtual\">", 
+                               htmlspecialchars($aggrdata->f['aggrcomment']), "</textarea></td>\n\t</tr>\n";
+                       echo "</table>\n";
+                       echo "<p><input type=\"hidden\" name=\"action\" value=\"save_alter\" />\n";
+                       echo $misc->form;
+                       echo "<input type=\"hidden\" name=\"aggrname\" value=\"", htmlspecialchars($_REQUEST['aggrname']), "\" />\n";
+                       echo "<input type=\"hidden\" name=\"aggrtype\" value=\"", htmlspecialchars($_REQUEST['aggrtype']), "\" />\n";
+                       echo "<input type=\"hidden\" name=\"aggrowner\" value=\"", htmlspecialchars($aggrdata->f['usename']), "\" />\n";
+                       echo "<input type=\"hidden\" name=\"aggrschema\" value=\"", htmlspecialchars($_REQUEST['schema']), "\" />\n";
+                       echo "<input type=\"hidden\" name=\"aggrcomment\" value=\"", htmlspecialchars($aggrdata->f['aggrcomment']), "\" />\n";
+                       echo "<input type=\"submit\" name=\"alter\" value=\"{$lang['stralter']}\" />\n";
+                       echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n";
+               } else {
+                       echo "<p>{$lang['strnodata']}</p>\n";
+                       echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strback']}\" /></p>\n";
+               }       
+               echo "</form>\n";                                               
+       }
+
+       /**
+        * Show confirmation of drop and perform actual drop of the aggregate function selected
+        */
+       function doDrop($confirm) {
+               global $data, $misc;
+               global $lang, $_reload_browser;
+               global $PHP_SELF;
+
+               if ($confirm) {
+                       $misc->printTrail('aggregate');
+                       $misc->printTitle($lang['strdrop'], 'pg.aggregate.drop');
+
+                       echo "<p>", sprintf($lang['strconfdropaggregate'], htmlspecialchars($_REQUEST['aggrname'])), "</p>\n";
+
+                       echo "<form action=\"$PHP_SELF\" method=\"post\">\n";
+                       echo "<input type=\"hidden\" name=\"action\" value=\"drop\" />\n";
+                       echo "<input type=\"hidden\" name=\"aggrname\" value=\"", htmlspecialchars($_REQUEST['aggrname']), "\" />\n";
+                       echo "<input type=\"hidden\" name=\"aggrtype\" value=\"", htmlspecialchars($_REQUEST['aggrtype']), "\" />\n";
+                       echo $misc->form;
+                       // Show cascade drop option if supportd
+                       if ($data->hasDropBehavior()) {
+                               echo "<p><input type=\"checkbox\" id=\"cascade\" name=\"cascade\" /> <label for=\"cascade\">{$lang['strcascade']}</label></p>\n";
+                       }
+                       echo "<input type=\"submit\" name=\"drop\" value=\"{$lang['strdrop']}\" />\n";
+                       echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" />\n";
+                       echo "</form>\n";
+               }
+               else {
+                       $status = $data->dropAggregate($_POST['aggrname'], $_POST['aggrtype'], isset($_POST['cascade']));
+                       if ($status == 0) {
+                               $_reload_browser = true;
+                               doDefault($lang['straggregatedropped']);
+                       }
+                       else
+                               doDefault($lang['straggregatedroppedbad']);
+               }
+       }
+
+       /**
+        * Show the properties of an aggregate
+        */
+       function doProperties($msg = '') {
+               global $data, $misc;
+               global $PHP_SELF, $lang;
+
+               $misc->printTrail('aggregate');
+               $misc->printTitle($lang['strproperties'],'pg.aggregate');
+               $misc->printMsg($msg);
+
+               $aggrdata = $data->getAggregate($_REQUEST['aggrname'], $_REQUEST['aggrtype']);
+
+               if($aggrdata->recordCount() > 0 ) {
+                       // Display aggregate's info
+                       echo "<table>\n";
+                       echo "<tr>\n\t<th class=\"data\">Description</th>\n\t<th class=\"data\">Value</th>\n</tr>\n";
+                       echo "<tr>\n\t<td class=\"data1\" width=\"160\">{$lang['strname']}</td>\n";
+                       echo "\t<td class=\"data1\" width=\"120\">", htmlspecialchars($_REQUEST['aggrname']), "</td>\n</tr>\n";
+                       echo "<tr>\n\t<td class=\"data2\">{$lang['straggrbasetype']}</td>\n";
+                       echo "\t<td class=\"data2\">", htmlspecialchars($_REQUEST['aggrtype']), "</td>\n</tr>\n";
+                       echo "<tr>\n\t<td class=\"data1\">{$lang['straggrsfunc']}</td>\n";
+                       echo "\t<td class=\"data1\">", htmlspecialchars($aggrdata->f['aggtransfn']), "</td>\n</tr>\n";
+                       echo "<tr>\n\t<td class=\"data2\">{$lang['straggrstype']}</td>\n";
+                       echo "\t<td class=\"data2\">", htmlspecialchars($aggrdata->f['aggstype']), "</td>\n</tr>\n";
+                       echo "<tr>\n\t<td class=\"data1\">{$lang['straggrffunc']}</td>\n";
+                       echo "\t<td class=\"data1\">", htmlspecialchars($aggrdata->f['aggfinalfn']), "</td>\n</tr>\n";
+                       echo "<tr>\n\t<td class=\"data2\">{$lang['straggrinitcond']}</td>\n";
+                       echo "\t<td class=\"data2\">", htmlspecialchars($aggrdata->f['agginitval']), "</td>\n</tr>\n";
+                       echo "<tr>\n\t<td class=\"data1\">{$lang['straggrsortop']}</td>\n";
+                       echo "\t<td class=\"data1\">", htmlspecialchars($aggrdata->f['aggsortop']), "</td>\n</tr>\n";
+                       echo "<tr>\n\t<td class=\"data2\">{$lang['strowner']}</td>\n";
+                       echo "\t<td class=\"data2\">", htmlspecialchars($aggrdata->f['usename']), "</td>\n</tr>\n";
+                       echo "<tr>\n\t<td class=\"data1\">{$lang['strcomment']}</td>\n";
+                       echo "\t<td class=\"data1\">", $misc->printVal($aggrdata->f['aggrcomment']), "</td>\n</tr>\n";
+                       echo "</table>\n";
+               }
+               else echo "<p>{$lang['strnodata']}</p>\n";
+
+               echo "<p><a class=\"navlink\" href=\"$PHP_SELF?{$misc->href}\">{$lang['straggrshowall']}</a> |\n";
+               if ($data->hasAlterAggregate()) {
+               echo "<a class=\"navlink\" href=\"$PHP_SELF?action=alter&amp;{$misc->href}&amp;aggrname=", 
+                       urlencode($_REQUEST['aggrname']), "&amp;aggrtype=", urlencode($_REQUEST['aggrtype']), "\">{$lang['stralter']}</a> |\n";
+               }
+               echo "<a class=\"navlink\" href=\"$PHP_SELF?action=confirm_drop&amp;{$misc->href}&amp;aggrname=",
+                       urlencode($_REQUEST['aggrname']), "&amp;aggrtype=", urlencode($_REQUEST['aggrtype']), "\">{$lang['strdrop']}</a>\n";
+       }
+
+
+       /**
+        * Show default list of aggregate functions in the database
         */
        function doDefault($msg = '') {
-               global $data, $conf, $misc;
-               global $lang;
+               global $data, $conf, $misc;     
+               global $PHP_SELF, $lang;
 
                $misc->printTrail('schema');
                $misc->printTabs('schema', 'aggregates');
                $aggregates = $data->getAggregates();
 
                $columns = array(
-                       'aggregate' => array(
+                       'aggrname' => array(
                                'title' => $lang['strname'],
                                'field' => 'proname',
                        ),
-                       'type' => array(
+                       'aggrtype' => array(
                                'title' => $lang['strtype'],
                                'field' => 'proargtypes',
-                               'params'=> array('null' => $lang['stralltypes']),
                        ),
+                       'aggrtransfn' => array(
+                               'title' => $lang['straggrtransfn'],
+                               'field' => 'aggtransfn',
+                       ),                      
+                       'owner' => array(
+                               'title' => $lang['strowner'],
+                               'field' => 'usename',
+                       ),                      
+                       'actions' => array(
+                               'title' => $lang['stractions'],
+                       ),                      
                        'comment' => array(
                                'title' => $lang['strcomment'],
-                               'field' => 'aggcomment',
+                               'field' => 'aggrcomment',
                        ),
                );
                
-               $actions = array();
-               
+               $actions = array(
+                       'properties' => array(
+                               'title' => $lang['strproperties'],
+                               'url'   => "redirect.php?subject=aggregate&amp;action=properties&amp;{$misc->href}&amp;",
+                               'vars'  => array('aggrname' => 'proname', 'aggrtype' => 'proargtypes'),
+                       ),              
+                       'alter' => array(
+                               'title' => $lang['stralter'],
+                               'url'   => "{$PHP_SELF}?action=alter&amp;{$misc->href}&amp;",
+                               'vars'  => array('aggrname' => 'proname', 'aggrtype' => 'proargtypes'),
+                       ),
+                       'drop' => array(
+                               'title' => $lang['strdrop'],
+                               'url'   => "{$PHP_SELF}?action=confirm_drop&amp;{$misc->href}&amp;",
+                               'vars'  => array('aggrname' => 'proname', 'aggrtype' => 'proargtypes'),
+                       )
+               );
+
+               if (!$data->hasAlterAggregate()) unset($actions['alter']);
                $misc->printTable($aggregates, $columns, $actions, $lang['strnoaggregates']);
+               
+               echo "<p><a class=\"navlink\" href=\"$PHP_SELF?action=create&amp;{$misc->href}\">{$lang['strcreateaggregate']}</a></p>\n";
        }
 
        /**
        $misc->printBody();
 
        switch ($action) {
+               case 'create':
+                       doCreate();
+                       break;
+               case 'save_create':
+                       if (isset($_POST['cancel'])) doDefault();
+                       else doSaveCreate();
+                       break;
+               case 'alter':
+                       doAlter();
+                       break;
+               case 'save_alter':
+                       if (isset($_POST['alter'])) doSaveAlter();
+                       else doProperties();
+                       break;
+               case 'drop':
+                       if (isset($_POST['drop'])) doDrop(false);
+                       else doDefault();
+                       break;
+               case 'confirm_drop':
+                       doDrop(true);
+                       break;
                default:
                        doDefault();
                        break;
-       }       
+               case 'properties':
+                       doProperties();
+                       break;
+       }
 
        $misc->printFooter();
 
index b96a4e35cb0f4768d27d7a1cc99a77a32f42598b..62c52641dcbf6acbcecff057a376c919bbbfb7ff 100644 (file)
@@ -2,7 +2,7 @@
        /**
         * Class to hold various commonly used functions
         *
-        * $Id: Misc.php,v 1.132 2006/08/03 19:03:33 xzilla Exp $
+        * $Id: Misc.php,v 1.133 2006/08/09 21:19:44 xzilla Exp $
         */
         
        class Misc {
                                                        'help'  => 'pg.locks',
                                                        'tree'  => false,
                                                        'icon'  => 'Key',
-                  ),
+                                               ),
                                                'admin' => array (
                                                        'title' => $lang['stradmin'],
                                                        'url'   => 'database.php',
                                                ),
                                        );
                                        return $tabs;
+
                                case 'schema':
                                        return array (
                                                'tables' => array (
                                                        'icon'  => 'Privileges',
                                                ),
                                        );
-                               
+                                       
+                               case 'aggregate':
+                                       return array (
+                                               'definition' => array (
+                                                       'title' => $lang['strdefinition'],
+                                                       'url'   => 'aggregates.php',
+                                                       'urlvars' => array(
+                                                                       'subject' => 'aggregate',
+                                                                       'aggrname' => field('aggrname'),
+                                                                       'aggrtype' => field('aggrtype'),
+                                                                       'action' => 'properties',
+                                                               ),
+                                                       'icon'  => 'Definition',
+                                               ),
+                                       );
+                       
                                case 'popup':
                                        return array (
                                                'sql' => array (
                 */
                function getTrail($subject = null) {
                        global $lang, $conf, $data, $appName;
-                       
+
                        $trail = array();
                        $vars = '';
                        $done = false;
                                                        'icon'  => 'Function'
                                                );
                                                break;
+                                       case 'aggregate':
+                                               $vars .= "subject=aggregate&action=properties&aggrname=".urlencode($_REQUEST['aggrname']);
+                                               $vars .= "&aggrtype=".urlencode($_REQUEST['aggrtype']); 
+                                               $trail[$subject] = array(
+                                                       'title' => $lang['straggregate'],
+                                                       'text'  => $_REQUEST['aggrname'],
+                                                       'url'   => "redirect.php?{$vars}",
+                                                       'help'  => 'pg.aggregate',
+                                                       'icon'  => 'Aggregate'
+                                               );
+                                               break;
                                        case 'slony_node':
                                                $vars .= 'no_id='.urlencode($_REQUEST['no_id']).'&no_name='.urlencode($_REQUEST['no_name']);
                                                $trail[$subject] = array(
index b58a850ddbe6e9c73d2d831d9285ad185509ba7b..7283576f8c433d3532f97c27784d4acec9c33902 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.287 2006/08/04 20:42:24 xzilla Exp $
+ * $Id: Postgres.php,v 1.288 2006/08/09 21:19:44 xzilla Exp $
  */
 
 // @@@ THOUGHT: What about inherits? ie. use of ONLY???
@@ -3720,6 +3720,74 @@ class Postgres extends ADODB_base {
                return $this->selectSet($sql);
        }
 
+       /**
+        * Creates a new aggregate in the database
+        * @param $name The name of the aggregate
+        * @param $basetype The input data type of the aggregate
+        * @param $sfunc The name of the state transition function for the aggregate
+        * @param $stype The data type for the aggregate's state value
+        * @param $ffunc The name of the final function for the aggregate
+        * @param $initcond The initial setting for the state value
+        * @param $sortop The sort operator for the aggregate
+        * @param $comment Aggregate comment
+        * @return 0 success
+        * @return -1 error
+        */
+       function createAggregate($name, $basetype, $sfunc, $stype, $ffunc, $initcond, $sortop, $comment) {
+               $this->fieldClean($name);
+               $this->fieldClean($basetype);
+               $this->fieldClean($sfunc);
+               $this->fieldClean($stype);
+               $this->fieldClean($ffunc);
+               $this->fieldClean($initcond);
+               $this->fieldClean($sortop);
+               $this->clean($comment);
+
+               $this->beginTransaction();
+               
+               $sql = "CREATE AGGREGATE \"{$name}\" (BASETYPE = \"{$basetype}\", SFUNC = \"{$sfunc}\", STYPE = \"{$stype}\"";
+               if(trim($ffunc) != '') $sql .= ", FINALFUNC = \"{$ffunc}\"";
+               if(trim($initcond) != '') $sql .= ", INITCOND = \"{$initcond}\"";
+               if(trim($sortop) != '') $sql .= ", SORTOP = \"{$sortop}\"";
+               $sql .= ")";
+
+               $status = $this->execute($sql);
+               if ($status) {
+                       $this->rollbackTransaction();
+                       return -1;
+               }
+
+               if (trim($comment) != '') {
+                       $status = $this->setComment('AGGREGATE', $name, '', $comment, $basetype);
+                       if ($status) {
+                               $this->rollbackTransaction();
+                               return -1;
+                       }
+               }
+
+               return $this->endTransaction();
+       }       
+
+       /**
+        * Removes an aggregate function from the database
+        * @param $aggrname The name of the aggregate
+        * @param $aggrtype The input data type of the aggregate
+        * @param $cascade True to cascade drop, false to restrict
+        * @return 0 success
+        */
+       function dropAggregate($aggrname, $aggrtype, $cascade) {
+               $this->fieldClean($aggrname);
+               $this->fieldClean($aggrtype);
+
+               $sql = "DROP AGGREGATE \"{$aggrname}\" (\"{$aggrtype}\")";
+               if ($cascade) $sql .= " CASCADE";
+
+               return $this->execute($sql);
+       }
+
+
+
+
        // Operator Class functions
        
        /**
@@ -3780,13 +3848,13 @@ class Postgres extends ADODB_base {
        /**
         * Sets the comment for an object in the database
         * @pre All parameters must already be cleaned
-        * @param $obj_type One of 'TABLE' | 'COLUMN' | 'VIEW' | 'SCHEMA' | 'SEQUENCE' | 'TYPE' | 'FUNCTION'
+        * @param $obj_type One of 'TABLE' | 'COLUMN' | 'VIEW' | 'SCHEMA' | 'SEQUENCE' | 'TYPE' | 'FUNCTION' | 'AGGREGATE'
         * @param $obj_name The name of the object for which to attach a comment.
         * @param $table Name of table that $obj_name belongs to.  Ignored unless $obj_type is 'TABLE' or 'COLUMN'.
         * @param $comment The comment to add.
         * @return 0 success
         */
-       function setComment($obj_type, $obj_name, $table, $comment) {
+       function setComment($obj_type, $obj_name, $table, $comment, $basetype = NULL) {
                $sql = "COMMENT ON {$obj_type} " ;
 
                switch ($obj_type) {
@@ -3805,6 +3873,9 @@ class Postgres extends ADODB_base {
                        case 'FUNCTION':                                
                                $sql .= "{$obj_name} IS ";
                                break;
+                       case 'AGGREGATE':
+                               $sql .= "\"{$obj_name}\" (\"{$basetype}\") IS ";
+                               break;
                        default:
                                // Unknown object type
                                return -1;
@@ -4562,6 +4633,7 @@ class Postgres extends ADODB_base {
        function hasAlterSequence() { return false; }
        function hasLocksView() { return false; }
        function hasPreparedXacts() { return false; }
+       function hasAlterAggregate() { return false; }
 
 }
 
index e9e6053878e8cb489ea00acb654deb403dc07254..44e8a8a16b842e5a11b419101d885570040149c6 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.157 2006/05/24 04:53:40 chriskl Exp $
+ * $Id: Postgres73.php,v 1.158 2006/08/09 21:19:44 xzilla Exp $
  */
 
 // @@@ THOUGHT: What about inherits? ie. use of ONLY???
@@ -1849,32 +1849,45 @@ class Postgres73 extends Postgres72 {
        }
 
        // Aggregate functions
+
+       /**
+        * Gets all information for an aggregate
+        * @param $name The name of the aggregate
+        * @param $basetype The input data type of the aggregate
+        * @return A recordset
+        */
+       function getAggregate($name, $basetype) {
+               $this->fieldclean($name);
+               $this->fieldclean($basetype);
        
+               $sql = "SELECT p.proname, CASE p.proargtypes[0] WHEN 'pg_catalog.\"any\"'::pg_catalog.regtype THEN NULL ELSE
+                          pg_catalog.format_type(p.proargtypes[0], NULL) END AS proargtypes, a.aggtransfn, 
+                          format_type(a.aggtranstype, NULL) AS aggstype, a.aggfinalfn, a.agginitval, a.aggsortop, u.usename, 
+                          pg_catalog.obj_description(p.oid, 'pg_proc') AS aggrcomment
+                          FROM pg_catalog.pg_proc p, pg_catalog.pg_namespace n, pg_catalog.pg_user u, pg_catalog.pg_aggregate a 
+                          WHERE n.oid = p.pronamespace AND p.proowner=u.usesysid AND p.oid=a.aggfnoid 
+                          AND p.proisagg AND n.nspname='{$this->_schema}' 
+                          AND p.proname='" . $name . "' AND CASE p.proargtypes[0] WHEN 'pg_catalog.\"any\"'::pg_catalog.regtype 
+                          THEN NULL ELSE pg_catalog.format_type(p.proargtypes[0], NULL) END ='" . $basetype . "'";
+
+               return $this->selectSet($sql);
+       }
+
        /**
         * Gets all aggregates
         * @return A recordset
         */
        function getAggregates() {
-               $sql = "
-                       SELECT
-                               p.proname,
-                               CASE p.proargtypes[0]
-                                       WHEN 'pg_catalog.\"any\"'::pg_catalog.regtype
-                                       THEN NULL
-                                       ELSE pg_catalog.format_type(p.proargtypes[0], NULL)
-                               END AS proargtypes,
-                               pg_catalog.obj_description(p.oid, 'pg_proc') AS aggcomment
-                       FROM pg_catalog.pg_proc p
-                               LEFT JOIN pg_catalog.pg_namespace n ON n.oid = p.pronamespace
-                       WHERE
-                               p.proisagg
-                               AND n.nspname='{$this->_schema}'
-                       ORDER BY 1, 2
-               ";
+               $sql = "SELECT p.proname, CASE p.proargtypes[0] WHEN 'pg_catalog.\"any\"'::pg_catalog.regtype THEN NULL ELSE
+                          pg_catalog.format_type(p.proargtypes[0], NULL) END AS proargtypes, a.aggtransfn, u.usename, 
+                          pg_catalog.obj_description(p.oid, 'pg_proc') AS aggrcomment
+                          FROM pg_catalog.pg_proc p, pg_catalog.pg_namespace n, pg_catalog.pg_user u, pg_catalog.pg_aggregate a 
+                          WHERE n.oid = p.pronamespace AND p.proowner=u.usesysid AND p.oid=a.aggfnoid 
+                          AND p.proisagg AND n.nspname='{$this->_schema}' ORDER BY 1, 2";
 
                return $this->selectSet($sql);
        }
-       
+
        // Operator Class functions
        
        /**
index a3da26ab296f491ac9ad01b1c2ef787cfac5994b..72427c32d5195b9dd9aa871cd79e56ed357487ea 100644 (file)
@@ -4,7 +4,7 @@
  * A class that implements the DB interface for Postgres
  * Note: This class uses ADODB and returns RecordSets.
  *
- * $Id: Postgres74.php,v 1.52 2006/07/03 01:20:28 xzilla Exp $
+ * $Id: Postgres74.php,v 1.53 2006/08/09 21:19:44 xzilla Exp $
  */
 
 include_once('./classes/database/Postgres73.php');
@@ -585,7 +585,115 @@ class Postgres74 extends Postgres73 {
                
                return $this->execute($sql);
        }       
-       
+
+       // Aggregates
+
+       /**
+        * Alters an aggregate
+        * @param $aggrname The actual name of the aggregate
+        * @param $aggrtype The actual input data type of the aggregate
+        * @param $aggrowner The actual owner of the aggregate
+        * @param $aggrschema The actual schema the aggregate belongs to
+        * @param $aggrcomment The actual comment for the aggregate
+        * @param $newaggrname The new name of the aggregate
+        * @param $newaggrowner The new owner of the aggregate
+        * @param $newaggrschema The new schema where the aggregate will belong to
+        * @param $newaggrcomment The new comment for the aggregate
+        * @return 0 success
+        * @return -1 change owner error
+        * @return -2 change comment error
+        * @return -3 change schema error
+        * @return -4 change name error
+        */
+       function alterAggregate($aggrname, $aggrtype, $aggrowner, $aggrschema, $aggrcomment, $newaggrname, $newaggrowner, $newaggrschema, $newaggrcomment) {
+               // Clean fields
+               $this->fieldClean($aggrname);
+               $this->fieldClean($aggrtype);
+               $this->fieldClean($aggrowner);
+               $this->fieldClean($aggrschema);
+               $this->clean($aggrcomment);
+               $this->fieldClean($newaggrname);
+               $this->fieldClean($newaggrowner);
+               $this->fieldClean($newaggrschema);
+               $this->clean($newaggrcomment);
+               
+               $this->beginTransaction();
+
+               // Change the owner, if it has changed
+               if($aggrowner != $newaggrowner) {
+                       $status = $this->changeAggregateOwner($aggrname, $aggrtype, $newaggrowner);
+                       if($status != 0) {
+                               $this->rollbackTransaction();
+                               return -1;
+                       }
+               }
+
+               // Set the comment, if it has changed
+               if($aggrcomment != $newaggrcomment) {
+                       $status = $this->setComment('AGGREGATE', $aggrname, '', $newaggrcomment, $aggrtype);
+                       if ($status) {
+                               $this->rollbackTransaction();
+                               return -2;
+                       }
+               }
+
+               // Change the schema, if it has changed
+               if($aggrschema != $newaggrschema) {
+                       $status = $this->changeAggregateSchema($aggrname, $aggrtype, $newaggrschema);
+                       if($status != 0) {
+                               $this->rollbackTransaction();
+                               return -3;
+                       }
+               }
+
+               // Rename the aggregate, if it has changed
+               if($aggrname != $newaggrname) {
+                       $status = $this->renameAggregate($newaggrschema, $aggrname, $aggrtype, $newaggrname);
+                       if($status != 0) {
+                               $this->rollbackTransaction();
+                               return -4;
+                       }
+               }
+
+               return $this->endTransaction();
+       }       
+
+       /**
+        * Changes the owner of an aggregate function
+        * @param $aggrname The name of the aggregate
+        * @param $aggrtype The input data type of the aggregate
+        * @param $newaggrowner The new owner of the aggregate
+        * @return 0 success
+        */
+       function changeAggregateOwner($aggrname, $aggrtype, $newaggrowner) {
+               $sql = "ALTER AGGREGATE \"{$aggrname}\" (\"{$aggrtype}\") OWNER TO \"{$newaggrowner}\"";
+               return $this->execute($sql);
+       }
+
+       /**
+        * Changes the schema of an aggregate function
+        * @param $aggrname The name of the aggregate
+        * @param $aggrtype The input data type of the aggregate
+        * @param $newaggrschema The new schema for the aggregate
+        * @return 0 success
+        */
+       function changeAggregateSchema($aggrname, $aggrtype, $newaggrschema) {
+               $sql = "ALTER AGGREGATE \"{$aggrname}\" (\"{$aggrtype}\") SET SCHEMA  \"{$newaggrschema}\"";
+               return $this->execute($sql);
+       }
+
+       /**
+        * Renames an aggregate function
+        * @param $aggrname The actual name of the aggregate
+        * @param $aggrtype The actual input data type of the aggregate
+        * @param $newaggrname The new name of the aggregate
+        * @return 0 success
+        */
+       function renameAggregate($aggrschema, $aggrname, $aggrtype, $newaggrname) {
+               $sql = "ALTER AGGREGATE \"{$aggrschema}\"" . '.' . "\"{$aggrname}\" (\"{$aggrtype}\") RENAME TO \"{$newaggrname}\"";
+               return $this->execute($sql);
+       }
+
        // Capabilities
        function hasAlterDatabaseRename() { return true; }
        function hasGrantOption() { return true; }
@@ -594,6 +702,7 @@ class Postgres74 extends Postgres73 {
        function hasRecluster() { return true; }
        function hasReadOnlyQueries() { return true; }  
        function hasAlterSequence() { return true; }
+       function hasAlterAggregate() { return true; }
 }
 
 ?>
index 41892843d318f77e01db4002686dc4b68b12c427..2d75121e5eaa960f19a968401edf04e5a7741561 100755 (executable)
@@ -4,7 +4,7 @@
         * English language file for phpPgAdmin.  Use this as a basis
         * for new translations.
         *
-        * $Id: english.php,v 1.193 2006/08/04 20:42:24 xzilla Exp $
+        * $Id: english.php,v 1.194 2006/08/09 21:19:44 xzilla Exp $
         */
 
        // Language and character set
        $lang['strreferringtables'] = 'Referring tables';
        $lang['strparenttables'] = 'Parent tables';
        $lang['strchildtables'] = 'Child tables';
-       
+
        // Aggregates
+       $lang['straggregate'] = 'Aggregate';
        $lang['straggregates'] = 'Aggregates';
        $lang['strnoaggregates'] = 'No aggregates found.';
        $lang['stralltypes'] = '(All types)';
+       $lang['straggrtransfn'] = 'Transition function';
+       $lang['strcreateaggregate'] = 'Create aggregate';
+       $lang['straggrbasetype'] = 'Input data type';
+       $lang['straggrsfunc'] = 'State transition function';
+       $lang['straggrstype'] = 'State data type';
+       $lang['straggrffunc'] = 'Final function';
+       $lang['straggrinitcond'] = 'Initial condition';
+       $lang['straggrsortop'] = 'Sort operator';
+       $lang['strconfdropaggregate'] = 'Are you sure you want to drop the aggregate "%s"?';
+       $lang['straggregatedropped'] = 'Aggregate dropped.';
+       $lang['straggregatedroppedbad'] = 'Aggregate drop failed.';
+       $lang['stralteraggregate'] = 'Alter aggregate';
+       $lang['straggraltered'] = 'Aggregate altered.';
+       $lang['straggralteredbad'] = 'Aggregate alteration failed.';
+       $lang['straggrneedsname'] = 'You must specify a name for the aggregate';
+       $lang['straggrneedsbasetype'] = 'You must specify the input data type for the aggregate';
+       $lang['straggrneedssfunc'] = 'You must specify the name of the state transition function for the aggregate';
+       $lang['straggrneedsstype'] = 'You must specify the data type for the aggregate\'s state value';
+       $lang['straggrcreated'] = 'Aggregate created.';
+       $lang['straggrcreatedbad'] = 'Aggregate creation failed.';
+       $lang['straggrshowall'] = 'Show all aggregates';
 
        // Operator Classes
        $lang['stropclasses'] = 'Op Classes';
index 56678c46cdd37ef50abdf9a322b873baba20a83b..cf917482d5a4a69cbd6cc9e39397bb9e39d6546f 100644 (file)
@@ -4,7 +4,7 @@
         * English language file for phpPgAdmin.  Use this as a basis
         * for new translations.
         *
-        * $Id: english.php,v 1.146 2006/08/04 20:42:24 xzilla Exp $
+        * $Id: english.php,v 1.147 2006/08/09 21:19:44 xzilla Exp $
         */
 
        // Language and character set
        $lang['strreferringtables'] = 'Referring tables';
        $lang['strparenttables'] = 'Parent tables';
        $lang['strchildtables'] = 'Child tables';
-       
+
        // Aggregates
+       $lang['straggregate'] = 'Aggregate';
        $lang['straggregates'] = 'Aggregates';
        $lang['strnoaggregates'] = 'No aggregates found.';
        $lang['stralltypes'] = '(All types)';
+       $lang['straggrtransfn'] = 'Transition function';
+       $lang['strcreateaggregate'] = 'Create aggregate';
+       $lang['straggrbasetype'] = 'Input data type';
+       $lang['straggrsfunc'] = 'State transition function';
+       $lang['straggrstype'] = 'State data type';
+       $lang['straggrffunc'] = 'Final function';
+       $lang['straggrinitcond'] = 'Initial condition';
+       $lang['straggrsortop'] = 'Sort operator';
+       $lang['strconfdropaggregate'] = 'Are you sure you want to drop the aggregate &quot;%s&quot;?';
+       $lang['straggregatedropped'] = 'Aggregate dropped.';
+       $lang['straggregatedroppedbad'] = 'Aggregate drop failed.';
+       $lang['stralteraggregate'] = 'Alter aggregate';
+       $lang['straggraltered'] = 'Aggregate altered.';
+       $lang['straggralteredbad'] = 'Aggregate alteration failed.';
+       $lang['straggrneedsname'] = 'You must specify a name for the aggregate';
+       $lang['straggrneedsbasetype'] = 'You must specify the input data type for the aggregate';
+       $lang['straggrneedssfunc'] = 'You must specify the name of the state transition function for the aggregate';
+       $lang['straggrneedsstype'] = 'You must specify the data type for the aggregate\'s state value';
+       $lang['straggrcreated'] = 'Aggregate created.';
+       $lang['straggrcreatedbad'] = 'Aggregate creation failed.';
+       $lang['straggrshowall'] = 'Show all aggregates';
 
        // Operator Classes
        $lang['stropclasses'] = 'Op Classes';