Patch from Javier Carlos with a little refactoring from me.
/**
* 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&{$misc->href}&aggrname=",
+ urlencode($_REQUEST['aggrname']), "&aggrtype=", urlencode($_REQUEST['aggrtype']), "\">{$lang['stralter']}</a> |\n";
+ }
+ echo "<a class=\"navlink\" href=\"$PHP_SELF?action=confirm_drop&{$misc->href}&aggrname=",
+ urlencode($_REQUEST['aggrname']), "&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&action=properties&{$misc->href}&",
+ 'vars' => array('aggrname' => 'proname', 'aggrtype' => 'proargtypes'),
+ ),
+ 'alter' => array(
+ 'title' => $lang['stralter'],
+ 'url' => "{$PHP_SELF}?action=alter&{$misc->href}&",
+ 'vars' => array('aggrname' => 'proname', 'aggrtype' => 'proargtypes'),
+ ),
+ 'drop' => array(
+ 'title' => $lang['strdrop'],
+ 'url' => "{$PHP_SELF}?action=confirm_drop&{$misc->href}&",
+ '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&{$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();
/**
* 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(
* 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???
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
/**
/**
* 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) {
case 'FUNCTION':
$sql .= "{$obj_name} IS ";
break;
+ case 'AGGREGATE':
+ $sql .= "\"{$obj_name}\" (\"{$basetype}\") IS ";
+ break;
default:
// Unknown object type
return -1;
function hasAlterSequence() { return false; }
function hasLocksView() { return false; }
function hasPreparedXacts() { return false; }
+ function hasAlterAggregate() { return false; }
}
* 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???
}
// 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
/**
* 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');
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; }
function hasRecluster() { return true; }
function hasReadOnlyQueries() { return true; }
function hasAlterSequence() { return true; }
+ function hasAlterAggregate() { return true; }
}
?>
* 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';
* 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 "%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';