mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-11-30 20:04:30 +01:00
273 lines
7.7 KiB
PHP
273 lines
7.7 KiB
PHP
<?php
|
|
/**************************************************************************\
|
|
* phpGroupWare - Setup *
|
|
* http://www.phpgroupware.org *
|
|
* -------------------------------------------- *
|
|
* This program is free software; you can redistribute it and/or modify it *
|
|
* under the terms of the GNU General Public License as published by the *
|
|
* Free Software Foundation; either version 2 of the License, or (at your *
|
|
* option) any later version. *
|
|
\**************************************************************************/
|
|
|
|
/* $Id$ */
|
|
|
|
class phpgw_schema_proc_pgsql
|
|
{
|
|
var $m_sStatementTerminator;
|
|
|
|
function phpgw_schema_proc_pgsql()
|
|
{
|
|
$this->m_sStatementTerminator = ";";
|
|
}
|
|
|
|
// Return a type suitable for DDL
|
|
function TranslateType($sType, $iPrecision = 0, $iScale = 0, &$sTranslated)
|
|
{
|
|
switch($sType)
|
|
{
|
|
case "auto":
|
|
$sTranslated = "int4";
|
|
break;
|
|
case "blob":
|
|
$sTranslated = "text";
|
|
break;
|
|
case "char":
|
|
if ($iPrecision > 0 && $iPrecision < 256)
|
|
$sTranslated = sprintf("char(%d)", $iPrecision);
|
|
|
|
if ($iPrecision > 255)
|
|
$sTranslated = "text";
|
|
|
|
break;
|
|
case "date":
|
|
$sTranslated = "date";
|
|
break;
|
|
case "decimal":
|
|
$sTranslated = sprintf("decimal(%d,%d)", $iPrecision, $iScale);
|
|
break;
|
|
case "float":
|
|
if ($iPrecision == 4 || $iPrecision == 8)
|
|
$sTranslated = sprintf("float%d", $iPrecision);
|
|
|
|
break;
|
|
case "int":
|
|
if ($iPrecision == 2 || $iPrecision == 4 || $iPrecision == 8)
|
|
$sTranslated = sprintf("int%d", $iPrecision);
|
|
|
|
break;
|
|
case "text":
|
|
$sTranslated = "text";
|
|
break;
|
|
case "timestamp":
|
|
$sTranslated = "timestamp";
|
|
break;
|
|
case "varchar":
|
|
if ($iPrecision > 0 && $iPrecision < 256)
|
|
$sTranslated = sprintf("varchar(%d)", $iPrecision);
|
|
|
|
if ($iPrecision > 255)
|
|
$sTranslated = "text";
|
|
|
|
break;
|
|
}
|
|
|
|
return (strlen($sTranslated) > 0);
|
|
}
|
|
|
|
function TranslateDefault($sDefault)
|
|
{
|
|
switch ($sDefault)
|
|
{
|
|
case "current_date":
|
|
case "current_timestamp":
|
|
return "now";
|
|
}
|
|
|
|
return $sDefault;
|
|
}
|
|
|
|
function GetPKSQL($sFields)
|
|
{
|
|
return "PRIMARY KEY($sFields)";
|
|
}
|
|
|
|
function GetUCSQL($sFields)
|
|
{
|
|
return "UNIQUE($sFields)";
|
|
}
|
|
|
|
function _GetColumns($oProc, $sTableName, &$sColumns, $sDropColumn = '', $sAlteredColumn = '', $sAlteredColumnType = '')
|
|
{
|
|
$sColumns = '';
|
|
$query = "SELECT a.attname FROM pg_attribute a,pg_class b WHERE ";
|
|
$query .= "b.oid=a.attrelid AND a.attnum>0 and b.relname='$sTableName'";
|
|
if ($sDropColumn != "")
|
|
$query .= " AND a.attname != '$sDropColumn'";
|
|
$query .= " ORDER BY a.attnum";
|
|
|
|
$oProc->m_odb->query($query);
|
|
while ($oProc->m_odb->next_record())
|
|
{
|
|
if ($sColumns != "")
|
|
$sColumns .= ",";
|
|
|
|
$sFieldName = $oProc->m_odb->f(0);
|
|
$sColumns .= $sFieldName;
|
|
if ($sAlteredColumn == $sFieldName && $sAlteredColumnType != '')
|
|
$sColumns .= '::' . $sAlteredColumnType;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
function _CopyAlteredTable($oProc, &$aTables, $sSource, $sDest)
|
|
{
|
|
$oDB = $oProc->m_odb;
|
|
$oProc->m_odb->query("select * from $sSource");
|
|
while ($oProc->m_odb->next_record())
|
|
{
|
|
$sSQL = "insert into $sDest (";
|
|
for ($i = 0; $i < count($aTables[$sDest]); $i++)
|
|
{
|
|
if ($i > 0)
|
|
$sSQL .= ',';
|
|
|
|
$sSQL .= $aTables[$sDest]['fd'][$i];
|
|
}
|
|
|
|
$sSQL .= ') values (';
|
|
for ($i = 0; $i < $oProc->m_odb->num_fields(); $i++)
|
|
{
|
|
if ($i > 0)
|
|
$sSQL .= ',';
|
|
|
|
if ($oProc->m_odb->f($i) != null)
|
|
{
|
|
switch ($aTables[$sDest]['fd'][$i])
|
|
{
|
|
case "blob":
|
|
case "char":
|
|
case "date":
|
|
case "text":
|
|
case "timestamp":
|
|
case "varchar":
|
|
$sSQL .= "'" . $oProc->m_odb->f($i) . "'";
|
|
break;
|
|
default:
|
|
$sSQL .= $oProc->m_odb->f($i);
|
|
}
|
|
}
|
|
else
|
|
$sSQL .= 'null';
|
|
}
|
|
$sSQL .= ')';
|
|
|
|
$oDB->query($sSQL);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
function DropTable($oProc, &$aTables, $sTableName)
|
|
{
|
|
return !!($oProc->m_odb->query("DROP TABLE " . $sTableName));
|
|
}
|
|
|
|
function DropColumn($oProc, &$aTables, $sTableName, $aNewTableDef, $sColumnName, $bCopyData = true)
|
|
{
|
|
if ($bCopyData)
|
|
$oProc->m_odb->query("SELECT * INTO $sTableName" . "_tmp FROM $sTableName");
|
|
|
|
$this->DropTable($oProc, $aTables, $sTableName);
|
|
|
|
$oProc->_GetTableSQL($sTableName, $aNewTableDef, $sTableSQL);
|
|
$query = "CREATE TABLE $sTableName ($sTableSQL)";
|
|
if (!$bCopyData)
|
|
return !!($oProc->m_odb->query($query));
|
|
|
|
$oProc->m_odb->query($query);
|
|
$this->_GetColumns($oProc, $sTableName . "_tmp", $sColumns, $sColumnName);
|
|
$query = "INSERT INTO $sTableName SELECT $sColumns FROM $sTableName" . "_tmp";
|
|
$bRet = !!($oProc->m_odb->query($query));
|
|
return ($bRet && $this->DropTable($oProc, $aTables, $sTableName . "_tmp"));
|
|
}
|
|
|
|
function RenameTable($oProc, &$aTables, $sOldTableName, $sNewTableName)
|
|
{
|
|
return !!($oProc->m_odb->query("ALTER TABLE $sOldTableName RENAME TO $sNewTableName"));
|
|
}
|
|
|
|
function RenameColumn($oProc, &$aTables, $sTableName, $sOldColumnName, $sNewColumnName, $bCopyData = true)
|
|
{
|
|
// This really needs testing - it can affect primary keys, and other table-related objects
|
|
// like sequences and such
|
|
if ($bCopyData)
|
|
$oProc->m_odb->query("SELECT * INTO $sTableName" . "_tmp FROM $sTableName");
|
|
|
|
$this->DropTable($oProc, $aTables, $sTableName);
|
|
|
|
if (!$bCopyData)
|
|
return $this->CreateTable($oProc, $aTables, $sTableName, $oProc->m_aTables[$sTableName], false);
|
|
|
|
$this->CreateTable($oProc, $aTables, $sTableName, $aTables[$sTableName], false);
|
|
$this->_GetColumns($oProc, $sTableName . "_tmp", $sColumns);
|
|
$query = "INSERT INTO $sTableName SELECT $sColumns FROM $sTableName" . "_tmp";
|
|
|
|
$bRet = !!($oProc->m_odb->query($query));
|
|
return ($bRet && $this->DropTable($oProc, $aTables, $sTableName . "_tmp"));
|
|
}
|
|
|
|
function AlterColumn($oProc, &$aTables, $sTableName, $sColumnName, &$aColumnDef, $bCopyData = true)
|
|
{
|
|
if ($bCopyData)
|
|
$oProc->m_odb->query("SELECT * INTO $sTableName" . "_tmp FROM $sTableName");
|
|
|
|
$this->DropTable($oProc, $aTables, $sTableName);
|
|
|
|
if (!$bCopyData)
|
|
return $this->CreateTable($oProc, $aTables, $sTableName, $aTables[$sTableName], false);
|
|
|
|
$this->CreateTable($oProc, $aTables, $sTableName, $aTables[$sTableName], false);
|
|
$this->_GetColumns($oProc, $sTableName . "_tmp", $sColumns, '', $sColumnName, $aColumnDef['type'] == 'auto' ? 'int4' : $aColumnDef['type']);
|
|
|
|
// TODO: analyze the type of change and determine if this is used or _CopyAlteredTable
|
|
//$query = "INSERT INTO $sTableName SELECT $sColumns FROM $sTableName" . "_tmp";
|
|
//$bRet = !!($oProc->m_odb->query($query));
|
|
|
|
$bRet = $this->_CopyAlteredTable($oProc, $aTables, $sTableName . '_tmp', $sTableName);
|
|
|
|
return ($bRet && $this->DropTable($oProc, $aTables, $sTableName . "_tmp"));
|
|
}
|
|
|
|
function AddColumn($oProc, &$aTables, $sTableName, $sColumnName, &$aColumnDef)
|
|
{
|
|
$oProc->_GetFieldSQL($aColumnDef, $sFieldSQL);
|
|
$query = "ALTER TABLE $sTableName ADD COLUMN $sColumnName $sFieldSQL";
|
|
|
|
return !!($oProc->m_odb->query($query));
|
|
}
|
|
|
|
function GetSequenceSQL($sTableName, $sFieldName, &$sSequenceSQL)
|
|
{
|
|
$sSequenceSQL = sprintf("CREATE SEQUENCE %s_%s_seq", $sTableName, $sFieldName);
|
|
return true;
|
|
}
|
|
|
|
function CreateTable($oProc, $aTables, $sTableName, $aTableDef, $bCreateSequence = true)
|
|
{
|
|
if ($oProc->_GetTableSQL($sTableName, $aTableDef, $sTableSQL, $sSequenceSQL))
|
|
{
|
|
// create sequence first since it will be needed for default
|
|
if ($bCreateSequence && $sSequenceSQL != "")
|
|
$oProc->m_odb->query($sSequenceSQL);
|
|
|
|
$query = "CREATE TABLE $sTableName ($sTableSQL)";
|
|
|
|
return !!($oProc->m_odb->query($query));
|
|
}
|
|
|
|
return false;
|
|
}
|
|
}
|
|
?>
|