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; } } ?>