333 lines
11 KiB
PHP
333 lines
11 KiB
PHP
<?php
|
|
|
|
/**
|
|
* PostgreSQL 8.3 support
|
|
*
|
|
* $Id: Postgres82.php,v 1.10 2007/12/28 16:21:25 ioguix Exp $
|
|
*/
|
|
|
|
include_once('./classes/database/Postgres84.php');
|
|
|
|
class Postgres83 extends Postgres84 {
|
|
|
|
var $major_version = 8.3;
|
|
|
|
// List of all legal privileges that can be applied to different types
|
|
// of objects.
|
|
var $privlist = array(
|
|
'table' => array('SELECT', 'INSERT', 'UPDATE', 'DELETE', 'REFERENCES', 'TRIGGER', 'ALL PRIVILEGES'),
|
|
'view' => array('SELECT', 'INSERT', 'UPDATE', 'DELETE', 'REFERENCES', 'TRIGGER', 'ALL PRIVILEGES'),
|
|
'sequence' => array('SELECT', 'UPDATE', 'ALL PRIVILEGES'),
|
|
'database' => array('CREATE', 'TEMPORARY', 'CONNECT', 'ALL PRIVILEGES'),
|
|
'function' => array('EXECUTE', 'ALL PRIVILEGES'),
|
|
'language' => array('USAGE', 'ALL PRIVILEGES'),
|
|
'schema' => array('CREATE', 'USAGE', 'ALL PRIVILEGES'),
|
|
'tablespace' => array('CREATE', 'ALL PRIVILEGES')
|
|
);
|
|
// List of characters in acl lists and the privileges they
|
|
// refer to.
|
|
var $privmap = array(
|
|
'r' => 'SELECT',
|
|
'w' => 'UPDATE',
|
|
'a' => 'INSERT',
|
|
'd' => 'DELETE',
|
|
'R' => 'RULE',
|
|
'x' => 'REFERENCES',
|
|
't' => 'TRIGGER',
|
|
'X' => 'EXECUTE',
|
|
'U' => 'USAGE',
|
|
'C' => 'CREATE',
|
|
'T' => 'TEMPORARY',
|
|
'c' => 'CONNECT'
|
|
);
|
|
|
|
/**
|
|
* Constructor
|
|
* @param $conn The database connection
|
|
*/
|
|
function Postgres83($conn) {
|
|
$this->Postgres($conn);
|
|
}
|
|
|
|
// Help functions
|
|
|
|
function getHelpPages() {
|
|
include_once('./help/PostgresDoc83.php');
|
|
return $this->help_page;
|
|
}
|
|
|
|
// Databse functions
|
|
|
|
/**
|
|
* Return all database available on the server
|
|
* @param $currentdatabase database name that should be on top of the resultset
|
|
*
|
|
* @return A list of databases, sorted alphabetically
|
|
*/
|
|
function getDatabases($currentdatabase = NULL) {
|
|
global $conf, $misc;
|
|
|
|
$server_info = $misc->getServerInfo();
|
|
|
|
if (isset($conf['owned_only']) && $conf['owned_only'] && !$this->isSuperUser($server_info['username'])) {
|
|
$username = $server_info['username'];
|
|
$this->clean($username);
|
|
$clause = " AND pr.rolname='{$username}'";
|
|
}
|
|
else $clause = '';
|
|
|
|
if ($currentdatabase != NULL) {
|
|
$this->clean($currentdatabase);
|
|
$orderby = "ORDER BY pdb.datname = '{$currentdatabase}' DESC, pdb.datname";
|
|
}
|
|
else
|
|
$orderby = "ORDER BY pdb.datname";
|
|
|
|
if (!$conf['show_system'])
|
|
$where = ' AND NOT pdb.datistemplate';
|
|
else
|
|
$where = ' AND pdb.datallowconn';
|
|
|
|
$sql = "
|
|
SELECT pdb.datname AS datname, pr.rolname AS datowner, pg_encoding_to_char(encoding) AS datencoding,
|
|
(SELECT description FROM pg_catalog.pg_shdescription pd WHERE pdb.oid=pd.objoid) AS datcomment,
|
|
(SELECT spcname FROM pg_catalog.pg_tablespace pt WHERE pt.oid=pdb.dattablespace) AS tablespace,
|
|
pg_catalog.pg_database_size(pdb.oid) as dbsize
|
|
FROM pg_catalog.pg_database pdb LEFT JOIN pg_catalog.pg_roles pr ON (pdb.datdba = pr.oid)
|
|
WHERE true
|
|
{$where}
|
|
{$clause}
|
|
{$orderby}";
|
|
|
|
return $this->selectSet($sql);
|
|
}
|
|
|
|
// Administration functions
|
|
|
|
/**
|
|
* Returns all available autovacuum per table information.
|
|
* @return A recordset
|
|
*/
|
|
function getTableAutovacuum($table='') {
|
|
$sql = '';
|
|
|
|
if ($table !== '') {
|
|
$this->clean($table);
|
|
$c_schema = $this->_schema;
|
|
$this->clean($c_schema);
|
|
|
|
$sql = "
|
|
SELECT vacrelid, nspname, relname,
|
|
CASE enabled
|
|
WHEN 't' THEN 'on'
|
|
ELSE 'off'
|
|
END AS autovacuum_enabled, vac_base_thresh AS autovacuum_vacuum_threshold,
|
|
vac_scale_factor AS autovacuum_vacuum_scale_factor, anl_base_thresh AS autovacuum_analyze_threshold,
|
|
anl_scale_factor AS autovacuum_analyze_scale_factor, vac_cost_delay AS autovacuum_vacuum_cost_delay,
|
|
vac_cost_limit AS autovacuum_vacuum_cost_limit
|
|
FROM pg_autovacuum AS a
|
|
join pg_class AS c on (c.oid=a.vacrelid)
|
|
join pg_namespace AS n on (n.oid=c.relnamespace)
|
|
WHERE c.relname = '{$table}' AND n.nspname = '{$c_schema}'
|
|
ORDER BY nspname, relname
|
|
";
|
|
}
|
|
else {
|
|
$sql = "
|
|
SELECT vacrelid, nspname, relname,
|
|
CASE enabled
|
|
WHEN 't' THEN 'on'
|
|
ELSE 'off'
|
|
END AS autovacuum_enabled, vac_base_thresh AS autovacuum_vacuum_threshold,
|
|
vac_scale_factor AS autovacuum_vacuum_scale_factor, anl_base_thresh AS autovacuum_analyze_threshold,
|
|
anl_scale_factor AS autovacuum_analyze_scale_factor, vac_cost_delay AS autovacuum_vacuum_cost_delay,
|
|
vac_cost_limit AS autovacuum_vacuum_cost_limit
|
|
FROM pg_autovacuum AS a
|
|
join pg_class AS c on (c.oid=a.vacrelid)
|
|
join pg_namespace AS n on (n.oid=c.relnamespace)
|
|
ORDER BY nspname, relname
|
|
";
|
|
}
|
|
|
|
return $this->selectSet($sql);
|
|
}
|
|
|
|
function saveAutovacuum($table, $vacenabled, $vacthreshold, $vacscalefactor, $anathresold,
|
|
$anascalefactor, $vaccostdelay, $vaccostlimit)
|
|
{
|
|
$defaults = $this->getAutovacuum();
|
|
$c_schema = $this->_schema;
|
|
$this->clean($c_schema);
|
|
$this->clean($table);
|
|
|
|
$rs = $this->selectSet("
|
|
SELECT c.oid
|
|
FROM pg_catalog.pg_class AS c
|
|
LEFT JOIN pg_catalog.pg_namespace AS n ON (n.oid=c.relnamespace)
|
|
WHERE
|
|
c.relname = '{$table}' AND n.nspname = '{$c_schema}'
|
|
");
|
|
|
|
if ($rs->EOF)
|
|
return -1;
|
|
|
|
$toid = $rs->fields('oid');
|
|
unset ($rs);
|
|
|
|
if (empty($_POST['autovacuum_vacuum_threshold']))
|
|
$_POST['autovacuum_vacuum_threshold'] = $defaults['autovacuum_vacuum_threshold'];
|
|
|
|
if (empty($_POST['autovacuum_vacuum_scale_factor']))
|
|
$_POST['autovacuum_vacuum_scale_factor'] = $defaults['autovacuum_vacuum_scale_factor'];
|
|
|
|
if (empty($_POST['autovacuum_analyze_threshold']))
|
|
$_POST['autovacuum_analyze_threshold'] = $defaults['autovacuum_analyze_threshold'];
|
|
|
|
if (empty($_POST['autovacuum_analyze_scale_factor']))
|
|
$_POST['autovacuum_analyze_scale_factor'] = $defaults['autovacuum_analyze_scale_factor'];
|
|
|
|
if (empty($_POST['autovacuum_vacuum_cost_delay']))
|
|
$_POST['autovacuum_vacuum_cost_delay'] = $defaults['autovacuum_vacuum_cost_delay'];
|
|
|
|
if (empty($_POST['autovacuum_vacuum_cost_limit']))
|
|
$_POST['autovacuum_vacuum_cost_limit'] = $defaults['autovacuum_vacuum_cost_limit'];
|
|
|
|
if (empty($_POST['vacuum_freeze_min_age']))
|
|
$_POST['vacuum_freeze_min_age'] = $defaults['vacuum_freeze_min_age'];
|
|
|
|
if (empty($_POST['autovacuum_freeze_max_age']))
|
|
$_POST['autovacuum_freeze_max_age'] = $defaults['autovacuum_freeze_max_age'];
|
|
|
|
|
|
$rs = $this->selectSet("SELECT vacrelid
|
|
FROM \"pg_catalog\".\"pg_autovacuum\"
|
|
WHERE vacrelid = {$toid};");
|
|
|
|
$status = -1; // ini
|
|
if (isset($rs->fields['vacrelid']) and ($rs->fields['vacrelid'] == $toid)) {
|
|
// table exists in pg_autovacuum, UPDATE
|
|
$sql = sprintf("UPDATE \"pg_catalog\".\"pg_autovacuum\" SET
|
|
enabled = '%s',
|
|
vac_base_thresh = %s,
|
|
vac_scale_factor = %s,
|
|
anl_base_thresh = %s,
|
|
anl_scale_factor = %s,
|
|
vac_cost_delay = %s,
|
|
vac_cost_limit = %s,
|
|
freeze_min_age = %s,
|
|
freeze_max_age = %s
|
|
WHERE vacrelid = {$toid};
|
|
",
|
|
($_POST['autovacuum_enabled'] == 'on')? 't':'f',
|
|
$_POST['autovacuum_vacuum_threshold'],
|
|
$_POST['autovacuum_vacuum_scale_factor'],
|
|
$_POST['autovacuum_analyze_threshold'],
|
|
$_POST['autovacuum_analyze_scale_factor'],
|
|
$_POST['autovacuum_vacuum_cost_delay'],
|
|
$_POST['autovacuum_vacuum_cost_limit'],
|
|
$_POST['vacuum_freeze_min_age'],
|
|
$_POST['autovacuum_freeze_max_age']
|
|
);
|
|
$status = $this->execute($sql);
|
|
}
|
|
else {
|
|
// table doesn't exists in pg_autovacuum, INSERT
|
|
$sql = sprintf("INSERT INTO \"pg_catalog\".\"pg_autovacuum\"
|
|
VALUES (%s, '%s', %s, %s, %s, %s, %s, %s, %s, %s )
|
|
WHERE
|
|
c.relname = '{$table}' AND n.nspname = '{$c_schema}';",
|
|
$toid,
|
|
($_POST['autovacuum_enabled'] == 'on')? 't':'f',
|
|
$_POST['autovacuum_vacuum_threshold'],
|
|
$_POST['autovacuum_vacuum_scale_factor'],
|
|
$_POST['autovacuum_analyze_threshold'],
|
|
$_POST['autovacuum_analyze_scale_factor'],
|
|
$_POST['autovacuum_vacuum_cost_delay'],
|
|
$_POST['autovacuum_vacuum_cost_limit'],
|
|
$_POST['vacuum_freeze_min_age'],
|
|
$_POST['autovacuum_freeze_max_age']
|
|
);
|
|
$status = $this->execute($sql);
|
|
}
|
|
|
|
return $status;
|
|
}
|
|
|
|
function dropAutovacuum($table) {
|
|
$c_schema = $this->_schema;
|
|
$this->clean($c_schema);
|
|
$this->clean($table);
|
|
|
|
$rs = $this->selectSet("
|
|
SELECT c.oid
|
|
FROM pg_catalog.pg_class AS c
|
|
LEFT JOIN pg_catalog.pg_namespace AS n ON (n.oid=c.relnamespace)
|
|
WHERE
|
|
c.relname = '{$table}' AND n.nspname = '{$c_schema}'
|
|
");
|
|
|
|
return $this->deleteRow('pg_autovacuum', array('vacrelid' => $rs->fields['oid']), 'pg_catalog');
|
|
}
|
|
|
|
// Sequence functions
|
|
|
|
/**
|
|
* Alter a sequence's properties
|
|
* @param $seqrs The sequence RecordSet returned by getSequence()
|
|
* @param $increment The sequence incremental value
|
|
* @param $minvalue The sequence minimum value
|
|
* @param $maxvalue The sequence maximum value
|
|
* @param $restartvalue The sequence current value
|
|
* @param $cachevalue The sequence cache value
|
|
* @param $cycledvalue Sequence can cycle ?
|
|
* @param $startvalue The sequence start value when issueing a restart (ignored)
|
|
* @return 0 success
|
|
*/
|
|
function alterSequenceProps($seqrs, $increment, $minvalue, $maxvalue,
|
|
$restartvalue, $cachevalue, $cycledvalue, $startvalue) {
|
|
|
|
$sql = '';
|
|
/* vars are cleaned in _alterSequence */
|
|
if (!empty($increment) && ($increment != $seqrs->fields['increment_by'])) $sql .= " INCREMENT {$increment}";
|
|
if (!empty($minvalue) && ($minvalue != $seqrs->fields['min_value'])) $sql .= " MINVALUE {$minvalue}";
|
|
if (!empty($maxvalue) && ($maxvalue != $seqrs->fields['max_value'])) $sql .= " MAXVALUE {$maxvalue}";
|
|
if (!empty($restartvalue) && ($restartvalue != $seqrs->fields['last_value'])) $sql .= " RESTART {$restartvalue}";
|
|
if (!empty($cachevalue) && ($cachevalue != $seqrs->fields['cache_value'])) $sql .= " CACHE {$cachevalue}";
|
|
// toggle cycle yes/no
|
|
if (!is_null($cycledvalue)) $sql .= (!$cycledvalue ? ' NO ' : '') . " CYCLE";
|
|
if ($sql != '') {
|
|
$f_schema = $this->_schema;
|
|
$this->fieldClean($f_schema);
|
|
$sql = "ALTER SEQUENCE \"{$f_schema}\".\"{$seqrs->fields['seqname']}\" {$sql}";
|
|
return $this->execute($sql);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* Alter a sequence's owner
|
|
* @param $seqrs The sequence RecordSet returned by getSequence()
|
|
* @param $name The new owner for the sequence
|
|
* @return 0 success
|
|
*/
|
|
function alterSequenceOwner($seqrs, $owner) {
|
|
// If owner has been changed, then do the alteration. We are
|
|
// careful to avoid this generally as changing owner is a
|
|
// superuser only function.
|
|
/* vars are cleaned in _alterSequence */
|
|
if (!empty($owner) && ($seqrs->fields['seqowner'] != $owner)) {
|
|
$f_schema = $this->_schema;
|
|
$this->fieldClean($f_schema);
|
|
$sql = "ALTER TABLE \"{$f_schema}\".\"{$seqrs->fields['seqname']}\" OWNER TO \"{$owner}\"";
|
|
return $this->execute($sql);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
function hasQueryKill() { return false; }
|
|
function hasDatabaseCollation() { return false; }
|
|
function hasAlterSequenceStart() { return false; }
|
|
}
|
|
|
|
?>
|