📄 adodb-postgres64.inc.php
字号:
if ($fld->name == $key['column_name'] AND $key['primary_key'] == $this->true)
$fld->primary_key = true;
if ($fld->name == $key['column_name'] AND $key['unique_key'] == $this->true)
$fld->unique = true; // What name is more compatible?
}
}
if ($ADODB_FETCH_MODE == ADODB_FETCH_NUM) $retarr[] = $fld;
else $retarr[($normalize) ? strtoupper($fld->name) : $fld->name] = $fld;
$rs->MoveNext();
}
$rs->Close();
return $retarr;
}
function &MetaIndexes ($table, $primary = FALSE)
{
global $ADODB_FETCH_MODE;
$schema = false;
$this->_findschema($table,$schema);
if ($schema) { // requires pgsql 7.3+ - pg_namespace used.
$sql = '
SELECT c.relname as "Name", i.indisunique as "Unique", i.indkey as "Columns"
FROM pg_catalog.pg_class c
JOIN pg_catalog.pg_index i ON i.indexrelid=c.oid
JOIN pg_catalog.pg_class c2 ON c2.oid=i.indrelid
,pg_namespace n
WHERE (c2.relname=\'%s\' or c2.relname=lower(\'%s\')) and c.relnamespace=c2.relnamespace and c.relnamespace=n.oid and n.nspname=\'%s\' AND i.indisprimary=false';
} else {
$sql = '
SELECT c.relname as "Name", i.indisunique as "Unique", i.indkey as "Columns"
FROM pg_catalog.pg_class c
JOIN pg_catalog.pg_index i ON i.indexrelid=c.oid
JOIN pg_catalog.pg_class c2 ON c2.oid=i.indrelid
WHERE c2.relname=\'%s\' or c2.relname=lower(\'%s\')';
}
if ($primary == FALSE) {
$sql .= ' AND i.indisprimary=false;';
}
$save = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
if ($this->fetchMode !== FALSE) {
$savem = $this->SetFetchMode(FALSE);
}
$rs = $this->Execute(sprintf($sql,$table,$table,$schema));
if (isset($savem)) {
$this->SetFetchMode($savem);
}
$ADODB_FETCH_MODE = $save;
if (!is_object($rs)) {
return FALSE;
}
$col_names = $this->MetaColumnNames($table,true);
$indexes = array();
while ($row = $rs->FetchRow()) {
$columns = array();
foreach (explode(' ', $row[2]) as $col) {
$columns[] = $col_names[$col - 1];
}
$indexes[$row[0]] = array(
'unique' => ($row[1] == 't'),
'columns' => $columns
);
}
return $indexes;
}
// returns true or false
//
// examples:
// $db->Connect("host=host1 user=user1 password=secret port=4341");
// $db->Connect('host1','user1','secret');
function _connect($str,$user='',$pwd='',$db='',$ctype=0)
{
if (!function_exists('pg_pconnect')) return null;
$this->_errorMsg = false;
if ($user || $pwd || $db) {
$user = adodb_addslashes($user);
$pwd = adodb_addslashes($pwd);
if (strlen($db) == 0) $db = 'template1';
$db = adodb_addslashes($db);
if ($str) {
$host = split(":", $str);
if ($host[0]) $str = "host=".adodb_addslashes($host[0]);
else $str = 'host=localhost';
if (isset($host[1])) $str .= " port=$host[1]";
}
if ($user) $str .= " user=".$user;
if ($pwd) $str .= " password=".$pwd;
if ($db) $str .= " dbname=".$db;
}
//if ($user) $linea = "user=$user host=$linea password=$pwd dbname=$db port=5432";
if ($ctype === 1) { // persistent
$this->_connectionID = pg_pconnect($str);
} else {
if ($ctype === -1) { // nconnect, we trick pgsql ext by changing the connection str
static $ncnt;
if (empty($ncnt)) $ncnt = 1;
else $ncnt += 1;
$str .= str_repeat(' ',$ncnt);
}
$this->_connectionID = pg_connect($str);
}
if ($this->_connectionID === false) return false;
$this->Execute("set datestyle='ISO'");
return true;
}
function _nconnect($argHostname, $argUsername, $argPassword, $argDatabaseName)
{
return $this->_connect($argHostname, $argUsername, $argPassword, $argDatabaseName,-1);
}
// returns true or false
//
// examples:
// $db->PConnect("host=host1 user=user1 password=secret port=4341");
// $db->PConnect('host1','user1','secret');
function _pconnect($str,$user='',$pwd='',$db='')
{
return $this->_connect($str,$user,$pwd,$db,1);
}
// returns queryID or false
function _query($sql,$inputarr)
{
if ($inputarr) {
/*
It appears that PREPARE/EXECUTE is slower for many queries.
For query executed 1000 times:
"select id,firstname,lastname from adoxyz
where firstname not like ? and lastname not like ? and id = ?"
with plan = 1.51861286163 secs
no plan = 1.26903700829 secs
*/
$plan = 'P'.md5($sql);
$execp = '';
foreach($inputarr as $v) {
if ($execp) $execp .= ',';
if (is_string($v)) {
if (strncmp($v,"'",1) !== 0) $execp .= $this->qstr($v);
} else {
$execp .= $v;
}
}
if ($execp) $exsql = "EXECUTE $plan ($execp)";
else $exsql = "EXECUTE $plan";
$rez = @pg_exec($this->_connectionID,$exsql);
if (!$rez) {
# Perhaps plan does not exist? Prepare/compile plan.
$params = '';
foreach($inputarr as $v) {
if ($params) $params .= ',';
if (is_string($v)) {
$params .= 'VARCHAR';
} else if (is_integer($v)) {
$params .= 'INTEGER';
} else {
$params .= "REAL";
}
}
$sqlarr = explode('?',$sql);
//print_r($sqlarr);
$sql = '';
$i = 1;
foreach($sqlarr as $v) {
$sql .= $v.' $'.$i;
$i++;
}
$s = "PREPARE $plan ($params) AS ".substr($sql,0,strlen($sql)-2);
//adodb_pr($s);
pg_exec($this->_connectionID,$s);
echo $this->ErrorMsg();
}
$rez = pg_exec($this->_connectionID,$exsql);
} else {
$this->_errorMsg = false;
//adodb_backtrace();
$rez = pg_exec($this->_connectionID,$sql);
}
// check if no data returned, then no need to create real recordset
if ($rez && pg_numfields($rez) <= 0) {
if (is_resource($this->_resultid) && get_resource_type($this->_resultid) === 'pgsql result') {
pg_freeresult($this->_resultid);
}
$this->_resultid = $rez;
return true;
}
return $rez;
}
/* Returns: the last error message from previous database operation */
function ErrorMsg()
{
if ($this->_errorMsg !== false) return $this->_errorMsg;
if (ADODB_PHPVER >= 0x4300) {
if (!empty($this->_resultid)) {
$this->_errorMsg = @pg_result_error($this->_resultid);
if ($this->_errorMsg) return $this->_errorMsg;
}
if (!empty($this->_connectionID)) {
$this->_errorMsg = @pg_last_error($this->_connectionID);
} else $this->_errorMsg = @pg_last_error();
} else {
if (empty($this->_connectionID)) $this->_errorMsg = @pg_errormessage();
else $this->_errorMsg = @pg_errormessage($this->_connectionID);
}
return $this->_errorMsg;
}
function ErrorNo()
{
$e = $this->ErrorMsg();
if (strlen($e)) {
return ADOConnection::MetaError($e);
}
return 0;
}
// returns true or false
function _close()
{
if ($this->transCnt) $this->RollbackTrans();
if ($this->_resultid) {
@pg_freeresult($this->_resultid);
$this->_resultid = false;
}
@pg_close($this->_connectionID);
$this->_connectionID = false;
return true;
}
/*
* Maximum size of C field
*/
function CharMax()
{
return 1000000000; // should be 1 Gb?
}
/*
* Maximum size of X field
*/
function TextMax()
{
return 1000000000; // should be 1 Gb?
}
}
/*--------------------------------------------------------------------------------------
Class Name: Recordset
--------------------------------------------------------------------------------------*/
class ADORecordSet_postgres64 extends ADORecordSet{
var $_blobArr;
var $databaseType = "postgres64";
var $canSeek = true;
function ADORecordSet_postgres64($queryID,$mode=false)
{
if ($mode === false) {
global $ADODB_FETCH_MODE;
$mode = $ADODB_FETCH_MODE;
}
switch ($mode)
{
case ADODB_FETCH_NUM: $this->fetchMode = PGSQL_NUM; break;
case ADODB_FETCH_ASSOC:$this->fetchMode = PGSQL_ASSOC; break;
default:
case ADODB_FETCH_DEFAULT:
case ADODB_FETCH_BOTH:$this->fetchMode = PGSQL_BOTH; break;
}
$this->ADORecordSet($queryID);
}
function &GetRowAssoc($upper=true)
{
if ($this->fetchMode == PGSQL_ASSOC && !$upper) return $this->fields;
$row =& ADORecordSet::GetRowAssoc($upper);
return $row;
}
function _initrs()
{
global $ADODB_COUNTRECS;
$qid = $this->_queryID;
$this->_numOfRows = ($ADODB_COUNTRECS)? @pg_numrows($qid):-1;
$this->_numOfFields = @pg_numfields($qid);
// cache types for blob decode check
for ($i=0, $max = $this->_numOfFields; $i < $max; $i++) {
if (pg_fieldtype($qid,$i) == 'bytea') {
$this->_blobArr[$i] = pg_fieldname($qid,$i);
}
}
}
/* Use associative array to get fields array */
function Fields($colname)
{
if ($this->fetchMode != PGSQL_NUM) return @$this->fields[$colname];
if (!$this->bind) {
$this->bind = array();
for ($i=0; $i < $this->_numOfFields; $i++) {
$o = $this->FetchField($i);
$this->bind[strtoupper($o->name)] = $i;
}
}
return $this->fields[$this->bind[strtoupper($colname)]];
}
function &FetchField($off = 0)
{
// offsets begin at 0
$o= new ADOFieldObject();
$o->name = @pg_fieldname($this->_queryID,$off);
$o->type = @pg_fieldtype($this->_queryID,$off);
$o->max_length = @pg_fieldsize($this->_queryID,$off);
return $o;
}
function _seek($row)
{
return @pg_fetch_row($this->_queryID,$row);
}
function _decode($blob)
{
eval('$realblob="'.adodb_str_replace(array('"','$'),array('\"','\$'),$blob).'";');
return $realblob;
}
function _fixblobs()
{
if ($this->fetchMode == PGSQL_NUM || $this->fetchMode == PGSQL_BOTH) {
foreach($this->_blobArr as $k => $v) {
$this->fields[$k] = ADORecordSet_postgres64::_decode($this->fields[$k]);
}
}
if ($this->fetchMode == PGSQL_ASSOC || $this->fetchMode == PGSQL_BOTH) {
foreach($this->_blobArr as $k => $v) {
$this->fields[$v] = ADORecordSet_postgres64::_decode($this->fields[$v]);
}
}
}
// 10% speedup to move MoveNext to child class
function MoveNext()
{
if (!$this->EOF) {
$this->_currentRow++;
if ($this->_numOfRows < 0 || $this->_numOfRows > $this->_currentRow) {
$this->fields = @pg_fetch_array($this->_queryID,$this->_currentRow,$this->fetchMode);
if (is_array($this->fields) && $this->fields) {
if (isset($this->_blobArr)) $this->_fixblobs();
return true;
}
}
$this->fields = false;
$this->EOF = true;
}
return false;
}
function _fetch()
{
if ($this->_currentRow >= $this->_numOfRows && $this->_numOfRows >= 0)
return false;
$this->fields = @pg_fetch_array($this->_queryID,$this->_currentRow,$this->fetchMode);
if ($this->fields && isset($this->_blobArr)) $this->_fixblobs();
return (is_array($this->fields));
}
function _close()
{
return @pg_freeresult($this->_queryID);
}
function MetaType($t,$len=-1,$fieldobj=false)
{
if (is_object($t)) {
$fieldobj = $t;
$t = $fieldobj->type;
$len = $fieldobj->max_length;
}
switch (strtoupper($t)) {
case 'MONEY': // stupid, postgres expects money to be a string
case 'INTERVAL':
case 'CHAR':
case 'CHARACTER':
case 'VARCHAR':
case 'NAME':
case 'BPCHAR':
case '_VARCHAR':
if ($len <= $this->blobSize) return 'C';
case 'TEXT':
return 'X';
case 'IMAGE': // user defined type
case 'BLOB': // user defined type
case 'BIT': // This is a bit string, not a single bit, so don't return 'L'
case 'VARBIT':
case 'BYTEA':
return 'B';
case 'BOOL':
case 'BOOLEAN':
return 'L';
case 'DATE':
return 'D';
case 'TIME':
case 'DATETIME':
case 'TIMESTAMP':
case 'TIMESTAMPTZ':
return 'T';
case 'SMALLINT':
case 'BIGINT':
case 'INTEGER':
case 'INT8':
case 'INT4':
case 'INT2':
if (isset($fieldobj) &&
empty($fieldobj->primary_key) && empty($fieldobj->unique)) return 'I';
case 'OID':
case 'SERIAL':
return 'R';
default:
return 'N';
}
}
}
?>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -