00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046 if (!defined('ADODB_DIR')) die();
00047
00048 function adodb_addslashes($s)
00049 {
00050 $len = strlen($s);
00051 if ($len == 0) return "''";
00052 if (strncmp($s,"'",1) === 0 && substr($s,$len-1) == "'") return $s;
00053
00054 return "'".addslashes($s)."'";
00055 }
00056
00057 class ADODB_postgres64 extends ADOConnection{
00058 var $databaseType = 'postgres64';
00059 var $dataProvider = 'postgres';
00060 var $hasInsertID = true;
00061 var $_resultid = false;
00062 var $concat_operator='||';
00063 var $metaDatabasesSQL = "select datname from pg_database where datname not in ('template0','template1') order by 1";
00064 var $metaTablesSQL = "select tablename,'T' from pg_tables where tablename not like 'pg\_%'
00065 and tablename not in ('sql_features', 'sql_implementation_info', 'sql_languages',
00066 'sql_packages', 'sql_sizing', 'sql_sizing_profiles')
00067 union
00068 select viewname,'V' from pg_views where viewname not like 'pg\_%'";
00069
00070 var $isoDates = true;
00071 var $sysDate = "CURRENT_DATE";
00072 var $sysTimeStamp = "CURRENT_TIMESTAMP";
00073 var $blobEncodeType = 'C';
00074 var $metaColumnsSQL = "SELECT a.attname,t.typname,a.attlen,a.atttypmod,a.attnotnull,a.atthasdef,a.attnum
00075 FROM pg_class c, pg_attribute a,pg_type t
00076 WHERE relkind in ('r','v') AND (c.relname='%s' or c.relname = lower('%s')) and a.attname not like '....%%'
00077 AND a.attnum > 0 AND a.atttypid = t.oid AND a.attrelid = c.oid ORDER BY a.attnum";
00078
00079
00080 var $metaColumnsSQL1 = "SELECT a.attname, t.typname, a.attlen, a.atttypmod, a.attnotnull, a.atthasdef, a.attnum
00081 FROM pg_class c, pg_attribute a, pg_type t, pg_namespace n
00082 WHERE relkind in ('r','v') AND (c.relname='%s' or c.relname = lower('%s'))
00083 and c.relnamespace=n.oid and n.nspname='%s'
00084 and a.attname not like '....%%' AND a.attnum > 0
00085 AND a.atttypid = t.oid AND a.attrelid = c.oid ORDER BY a.attnum";
00086
00087
00088 var $metaKeySQL = "SELECT ic.relname AS index_name, a.attname AS column_name,i.indisunique AS unique_key, i.indisprimary AS primary_key
00089 FROM pg_class bc, pg_class ic, pg_index i, pg_attribute a WHERE bc.oid = i.indrelid AND ic.oid = i.indexrelid AND (i.indkey[0] = a.attnum OR i.indkey[1] = a.attnum OR i.indkey[2] = a.attnum OR i.indkey[3] = a.attnum OR i.indkey[4] = a.attnum OR i.indkey[5] = a.attnum OR i.indkey[6] = a.attnum OR i.indkey[7] = a.attnum) AND a.attrelid = bc.oid AND bc.relname = '%s'";
00090
00091 var $hasAffectedRows = true;
00092 var $hasLimit = false;
00093
00094 var $true = 'TRUE';
00095 var $false = 'FALSE';
00096 var $fmtDate = "'Y-m-d'";
00097 var $fmtTimeStamp = "'Y-m-d H:i:s'";
00098 var $hasMoveFirst = true;
00099 var $hasGenID = true;
00100 var $_genIDSQL = "SELECT NEXTVAL('%s')";
00101 var $_genSeqSQL = "CREATE SEQUENCE %s START %s";
00102 var $_dropSeqSQL = "DROP SEQUENCE %s";
00103 var $metaDefaultsSQL = "SELECT d.adnum as num, d.adsrc as def from pg_attrdef d, pg_class c where d.adrelid=c.oid and c.relname='%s' order by d.adnum";
00104 var $random = 'random()';
00105 var $autoRollback = true;
00106
00107
00108 var $_bindInputArray = false;
00109 var $disableBlobs = false;
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119 function ADODB_postgres64()
00120 {
00121
00122 }
00123
00124 function ServerInfo()
00125 {
00126 if (isset($this->version)) return $this->version;
00127
00128 $arr['description'] = $this->GetOne("select version()");
00129 $arr['version'] = ADOConnection::_findvers($arr['description']);
00130 $this->version = $arr;
00131 return $arr;
00132 }
00133
00134 function IfNull( $field, $ifNull )
00135 {
00136 return " coalesce($field, $ifNull) ";
00137 }
00138
00139
00140 function pg_insert_id($tablename,$fieldname)
00141 {
00142 $result=pg_exec($this->_connectionID, "SELECT last_value FROM ${tablename}_${fieldname}_seq");
00143 if ($result) {
00144 $arr = @pg_fetch_row($result,0);
00145 pg_freeresult($result);
00146 if (isset($arr[0])) return $arr[0];
00147 }
00148 return false;
00149 }
00150
00151
00152
00153
00154
00155 function _insertid($table,$column)
00156 {
00157 if (!is_resource($this->_resultid) || get_resource_type($this->_resultid) !== 'pgsql result') return false;
00158 $oid = pg_getlastoid($this->_resultid);
00159
00160 return empty($table) || empty($column) ? $oid : $this->GetOne("SELECT $column FROM $table WHERE oid=".(int)$oid);
00161 }
00162
00163
00164
00165 function _affectedrows()
00166 {
00167 if (!is_resource($this->_resultid) || get_resource_type($this->_resultid) !== 'pgsql result') return false;
00168 return pg_cmdtuples($this->_resultid);
00169 }
00170
00171
00172
00173 function BeginTrans()
00174 {
00175 if ($this->transOff) return true;
00176 $this->transCnt += 1;
00177 return @pg_Exec($this->_connectionID, "begin ".$this->_transmode);
00178 }
00179
00180 function RowLock($tables,$where,$flds='1 as ignore')
00181 {
00182 if (!$this->transCnt) $this->BeginTrans();
00183 return $this->GetOne("select $flds from $tables where $where for update");
00184 }
00185
00186
00187 function CommitTrans($ok=true)
00188 {
00189 if ($this->transOff) return true;
00190 if (!$ok) return $this->RollbackTrans();
00191
00192 $this->transCnt -= 1;
00193 return @pg_Exec($this->_connectionID, "commit");
00194 }
00195
00196
00197 function RollbackTrans()
00198 {
00199 if ($this->transOff) return true;
00200 $this->transCnt -= 1;
00201 return @pg_Exec($this->_connectionID, "rollback");
00202 }
00203
00204 function &MetaTables($ttype=false,$showSchema=false,$mask=false)
00205 {
00206 $info = $this->ServerInfo();
00207 if ($info['version'] >= 7.3) {
00208 $this->metaTablesSQL = "select tablename,'T' from pg_tables where tablename not like 'pg\_%'
00209 and schemaname not in ( 'pg_catalog','information_schema')
00210 union
00211 select viewname,'V' from pg_views where viewname not like 'pg\_%' and schemaname not in ( 'pg_catalog','information_schema') ";
00212 }
00213 if ($mask) {
00214 $save = $this->metaTablesSQL;
00215 $mask = $this->qstr(strtolower($mask));
00216 if ($info['version']>=7.3)
00217 $this->metaTablesSQL = "
00218 select tablename,'T' from pg_tables where tablename like $mask and schemaname not in ( 'pg_catalog','information_schema')
00219 union
00220 select viewname,'V' from pg_views where viewname like $mask and schemaname not in ( 'pg_catalog','information_schema') ";
00221 else
00222 $this->metaTablesSQL = "
00223 select tablename,'T' from pg_tables where tablename like $mask
00224 union
00225 select viewname,'V' from pg_views where viewname like $mask";
00226 }
00227 $ret =& ADOConnection::MetaTables($ttype,$showSchema);
00228
00229 if ($mask) {
00230 $this->metaTablesSQL = $save;
00231 }
00232 return $ret;
00233 }
00234
00235
00236
00237 function qstr($s,$magic_quotes=false)
00238 {
00239 if (!$magic_quotes) {
00240 if (ADODB_PHPVER >= 0x4200) {
00241 return "'".pg_escape_string($s)."'";
00242 }
00243 if ($this->replaceQuote[0] == '\\'){
00244 $s = adodb_str_replace(array('\\',"\0"),array('\\\\',"\\\\000"),$s);
00245 }
00246 return "'".str_replace("'",$this->replaceQuote,$s)."'";
00247 }
00248
00249
00250 $s = str_replace('\\"','"',$s);
00251 return "'$s'";
00252 }
00253
00254
00255
00256
00257 function SQLDate($fmt, $col=false)
00258 {
00259 if (!$col) $col = $this->sysTimeStamp;
00260 $s = 'TO_CHAR('.$col.",'";
00261
00262 $len = strlen($fmt);
00263 for ($i=0; $i < $len; $i++) {
00264 $ch = $fmt[$i];
00265 switch($ch) {
00266 case 'Y':
00267 case 'y':
00268 $s .= 'YYYY';
00269 break;
00270 case 'Q':
00271 case 'q':
00272 $s .= 'Q';
00273 break;
00274
00275 case 'M':
00276 $s .= 'Mon';
00277 break;
00278
00279 case 'm':
00280 $s .= 'MM';
00281 break;
00282 case 'D':
00283 case 'd':
00284 $s .= 'DD';
00285 break;
00286
00287 case 'H':
00288 $s.= 'HH24';
00289 break;
00290
00291 case 'h':
00292 $s .= 'HH';
00293 break;
00294
00295 case 'i':
00296 $s .= 'MI';
00297 break;
00298
00299 case 's':
00300 $s .= 'SS';
00301 break;
00302
00303 case 'a':
00304 case 'A':
00305 $s .= 'AM';
00306 break;
00307
00308 case 'w':
00309 $s .= 'D';
00310 break;
00311
00312 case 'l':
00313 $s .= 'DAY';
00314 break;
00315
00316 case 'W':
00317 $s .= 'WW';
00318 break;
00319
00320 default:
00321
00322 if ($ch == '\\') {
00323 $i++;
00324 $ch = substr($fmt,$i,1);
00325 }
00326 if (strpos('-/.:;, ',$ch) !== false) $s .= $ch;
00327 else $s .= '"'.$ch.'"';
00328
00329 }
00330 }
00331 return $s. "')";
00332 }
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344 function UpdateBlobFile($table,$column,$path,$where,$blobtype='BLOB')
00345 {
00346 pg_exec ($this->_connectionID, "begin");
00347
00348 $fd = fopen($path,'r');
00349 $contents = fread($fd,filesize($path));
00350 fclose($fd);
00351
00352 $oid = pg_lo_create($this->_connectionID);
00353 $handle = pg_lo_open($this->_connectionID, $oid, 'w');
00354 pg_lo_write($handle, $contents);
00355 pg_lo_close($handle);
00356
00357
00358 pg_exec($this->_connectionID, "commit");
00359 $rs = ADOConnection::UpdateBlob($table,$column,$oid,$where,$blobtype);
00360 $rez = !empty($rs);
00361 return $rez;
00362 }
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372 function BlobDelete( $blob )
00373 {
00374 pg_exec ($this->_connectionID, "begin");
00375 $result = @pg_lo_unlink($blob);
00376 pg_exec ($this->_connectionID, "commit");
00377 return( $result );
00378 }
00379
00380
00381
00382
00383 function GuessOID($oid)
00384 {
00385 if (strlen($oid)>16) return false;
00386 return is_numeric($oid);
00387 }
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401 function BlobDecode($blob,$maxsize=false,$hastrans=true)
00402 {
00403 if (!$this->GuessOID($blob)) return $blob;
00404
00405 if ($hastrans) @pg_exec($this->_connectionID,"begin");
00406 $fd = @pg_lo_open($this->_connectionID,$blob,"r");
00407 if ($fd === false) {
00408 if ($hastrans) @pg_exec($this->_connectionID,"commit");
00409 return $blob;
00410 }
00411 if (!$maxsize) $maxsize = $this->maxblobsize;
00412 $realblob = @pg_loread($fd,$maxsize);
00413 @pg_loclose($fd);
00414 if ($hastrans) @pg_exec($this->_connectionID,"commit");
00415 return $realblob;
00416 }
00417
00418
00419
00420
00421
00422
00423
00424
00425 function BlobEncode($blob)
00426 {
00427 if (ADODB_PHPVER >= 0x4200) return pg_escape_bytea($blob);
00428
00429
00430 $badch = array(chr(92),chr(0),chr(39)); # \ null '
00431 $fixch = array('\\\\134','\\\\000','\\\\047');
00432 return adodb_str_replace($badch,$fixch,$blob);
00433
00434
00435 }
00436
00437
00438 function UpdateBlob($table,$column,$val,$where,$blobtype='BLOB')
00439 {
00440
00441 if ($blobtype == 'CLOB') {
00442 return $this->Execute("UPDATE $table SET $column=" . $this->qstr($val) . " WHERE $where");
00443 }
00444
00445 return $this->Execute("UPDATE $table SET $column='".$this->BlobEncode($val)."'::bytea WHERE $where");
00446 }
00447
00448 function OffsetDate($dayFraction,$date=false)
00449 {
00450 if (!$date) $date = $this->sysDate;
00451 else if (strncmp($date,"'",1) == 0) {
00452 $len = strlen($date);
00453 if (10 <= $len && $len <= 12) $date = 'date '.$date;
00454 else $date = 'timestamp '.$date;
00455 }
00456 return "($date+interval'$dayFraction days')";
00457 }
00458
00459
00460
00461
00462
00463 function &MetaColumns($table,$normalize=true)
00464 {
00465 global $ADODB_FETCH_MODE;
00466
00467 $schema = false;
00468 $false = false;
00469 $this->_findschema($table,$schema);
00470
00471 if ($normalize) $table = strtolower($table);
00472
00473 $save = $ADODB_FETCH_MODE;
00474 $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
00475 if ($this->fetchMode !== false) $savem = $this->SetFetchMode(false);
00476
00477 if ($schema) $rs =& $this->Execute(sprintf($this->metaColumnsSQL1,$table,$table,$schema));
00478 else $rs =& $this->Execute(sprintf($this->metaColumnsSQL,$table,$table));
00479 if (isset($savem)) $this->SetFetchMode($savem);
00480 $ADODB_FETCH_MODE = $save;
00481
00482 if ($rs === false) {
00483 return $false;
00484 }
00485 if (!empty($this->metaKeySQL)) {
00486
00487
00488
00489
00490
00491 $ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;
00492
00493 $rskey = $this->Execute(sprintf($this->metaKeySQL,($table)));
00494
00495 $keys =& $rskey->GetArray();
00496 if (isset($savem)) $this->SetFetchMode($savem);
00497 $ADODB_FETCH_MODE = $save;
00498
00499 $rskey->Close();
00500 unset($rskey);
00501 }
00502
00503 $rsdefa = array();
00504 if (!empty($this->metaDefaultsSQL)) {
00505 $ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;
00506 $sql = sprintf($this->metaDefaultsSQL, ($table));
00507 $rsdef = $this->Execute($sql);
00508 if (isset($savem)) $this->SetFetchMode($savem);
00509 $ADODB_FETCH_MODE = $save;
00510
00511 if ($rsdef) {
00512 while (!$rsdef->EOF) {
00513 $num = $rsdef->fields['num'];
00514 $s = $rsdef->fields['def'];
00515 if (strpos($s,'::')===false && substr($s, 0, 1) == "'") {
00516 $s = substr($s, 1);
00517 $s = substr($s, 0, strlen($s) - 1);
00518 }
00519
00520 $rsdefa[$num] = $s;
00521 $rsdef->MoveNext();
00522 }
00523 } else {
00524 ADOConnection::outp( "==> SQL => " . $sql);
00525 }
00526 unset($rsdef);
00527 }
00528
00529 $retarr = array();
00530 while (!$rs->EOF) {
00531 $fld = new ADOFieldObject();
00532 $fld->name = $rs->fields[0];
00533 $fld->type = $rs->fields[1];
00534 $fld->max_length = $rs->fields[2];
00535 $fld->attnum = $rs->fields[6];
00536
00537 if ($fld->max_length <= 0) $fld->max_length = $rs->fields[3]-4;
00538 if ($fld->max_length <= 0) $fld->max_length = -1;
00539 if ($fld->type == 'numeric') {
00540 $fld->scale = $fld->max_length & 0xFFFF;
00541 $fld->max_length >>= 16;
00542 }
00543
00544
00545 $fld->has_default = ($rs->fields[5] == 't');
00546 if ($fld->has_default) {
00547 $fld->default_value = $rsdefa[$rs->fields[6]];
00548 }
00549
00550
00551 $fld->not_null = $rs->fields[4] == 't';
00552
00553
00554
00555 if (is_array($keys)) {
00556 foreach($keys as $key) {
00557 if ($fld->name == $key['column_name'] AND $key['primary_key'] == 't')
00558 $fld->primary_key = true;
00559 if ($fld->name == $key['column_name'] AND $key['unique_key'] == 't')
00560 $fld->unique = true;
00561 }
00562 }
00563
00564 if ($ADODB_FETCH_MODE == ADODB_FETCH_NUM) $retarr[] = $fld;
00565 else $retarr[($normalize) ? strtoupper($fld->name) : $fld->name] = $fld;
00566
00567 $rs->MoveNext();
00568 }
00569 $rs->Close();
00570 if (empty($retarr))
00571 return $false;
00572 else
00573 return $retarr;
00574
00575 }
00576
00577 function &MetaIndexes ($table, $primary = FALSE)
00578 {
00579 global $ADODB_FETCH_MODE;
00580
00581 $schema = false;
00582 $this->_findschema($table,$schema);
00583
00584 if ($schema) {
00585 $sql = '
00586 SELECT c.relname as "Name", i.indisunique as "Unique", i.indkey as "Columns"
00587 FROM pg_catalog.pg_class c
00588 JOIN pg_catalog.pg_index i ON i.indexrelid=c.oid
00589 JOIN pg_catalog.pg_class c2 ON c2.oid=i.indrelid
00590 ,pg_namespace n
00591 WHERE (c2.relname=\'%s\' or c2.relname=lower(\'%s\')) and c.relnamespace=c2.relnamespace and c.relnamespace=n.oid and n.nspname=\'%s\'';
00592 } else {
00593 $sql = '
00594 SELECT c.relname as "Name", i.indisunique as "Unique", i.indkey as "Columns"
00595 FROM pg_catalog.pg_class c
00596 JOIN pg_catalog.pg_index i ON i.indexrelid=c.oid
00597 JOIN pg_catalog.pg_class c2 ON c2.oid=i.indrelid
00598 WHERE (c2.relname=\'%s\' or c2.relname=lower(\'%s\'))';
00599 }
00600
00601 if ($primary == FALSE) {
00602 $sql .= ' AND i.indisprimary=false;';
00603 }
00604
00605 $save = $ADODB_FETCH_MODE;
00606 $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
00607 if ($this->fetchMode !== FALSE) {
00608 $savem = $this->SetFetchMode(FALSE);
00609 }
00610
00611 $rs = $this->Execute(sprintf($sql,$table,$table,$schema));
00612 if (isset($savem)) {
00613 $this->SetFetchMode($savem);
00614 }
00615 $ADODB_FETCH_MODE = $save;
00616
00617 if (!is_object($rs)) {
00618 $false = false;
00619 return $false;
00620 }
00621
00622 $col_names = $this->MetaColumnNames($table,true,true);
00623
00624
00625 $indexes = array();
00626 while ($row = $rs->FetchRow()) {
00627 $columns = array();
00628 foreach (explode(' ', $row[2]) as $col) {
00629 $columns[] = $col_names[$col];
00630 }
00631
00632 $indexes[$row[0]] = array(
00633 'unique' => ($row[1] == 't'),
00634 'columns' => $columns
00635 );
00636 }
00637 return $indexes;
00638 }
00639
00640
00641
00642
00643
00644
00645 function _connect($str,$user='',$pwd='',$db='',$ctype=0)
00646 {
00647
00648 if (!function_exists('pg_connect')) return null;
00649
00650 $this->_errorMsg = false;
00651
00652 if ($user || $pwd || $db) {
00653 $user = adodb_addslashes($user);
00654 $pwd = adodb_addslashes($pwd);
00655 if (strlen($db) == 0) $db = 'template1';
00656 $db = adodb_addslashes($db);
00657 if ($str) {
00658 $host = split(":", $str);
00659 if ($host[0]) $str = "host=".adodb_addslashes($host[0]);
00660 else $str = 'host=localhost';
00661 if (isset($host[1])) $str .= " port=$host[1]";
00662 else if (!empty($this->port)) $str .= " port=".$this->port;
00663 }
00664 if ($user) $str .= " user=".$user;
00665 if ($pwd) $str .= " password=".$pwd;
00666 if ($db) $str .= " dbname=".$db;
00667 }
00668
00669
00670
00671 if ($ctype === 1) {
00672 $this->_connectionID = pg_pconnect($str);
00673 } else {
00674 if ($ctype === -1) {
00675 static $ncnt;
00676
00677 if (empty($ncnt)) $ncnt = 1;
00678 else $ncnt += 1;
00679
00680 $str .= str_repeat(' ',$ncnt);
00681 }
00682 $this->_connectionID = pg_connect($str);
00683 }
00684 if ($this->_connectionID === false) return false;
00685 $this->Execute("set datestyle='ISO'");
00686 return true;
00687 }
00688
00689 function _nconnect($argHostname, $argUsername, $argPassword, $argDatabaseName)
00690 {
00691 return $this->_connect($argHostname, $argUsername, $argPassword, $argDatabaseName,-1);
00692 }
00693
00694
00695
00696
00697
00698
00699 function _pconnect($str,$user='',$pwd='',$db='')
00700 {
00701 return $this->_connect($str,$user,$pwd,$db,1);
00702 }
00703
00704
00705
00706 function _query($sql,$inputarr)
00707 {
00708 $this->_errorMsg = false;
00709 if ($inputarr) {
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723 $plan = 'P'.md5($sql);
00724
00725 $execp = '';
00726 foreach($inputarr as $v) {
00727 if ($execp) $execp .= ',';
00728 if (is_string($v)) {
00729 if (strncmp($v,"'",1) !== 0) $execp .= $this->qstr($v);
00730 } else {
00731 $execp .= $v;
00732 }
00733 }
00734
00735 if ($execp) $exsql = "EXECUTE $plan ($execp)";
00736 else $exsql = "EXECUTE $plan";
00737
00738
00739 $rez = @pg_exec($this->_connectionID,$exsql);
00740 if (!$rez) {
00741 # Perhaps plan does not exist? Prepare/compile plan.
00742 $params = '';
00743 foreach($inputarr as $v) {
00744 if ($params) $params .= ',';
00745 if (is_string($v)) {
00746 $params .= 'VARCHAR';
00747 } else if (is_integer($v)) {
00748 $params .= 'INTEGER';
00749 } else {
00750 $params .= "REAL";
00751 }
00752 }
00753 $sqlarr = explode('?',$sql);
00754
00755 $sql = '';
00756 $i = 1;
00757 foreach($sqlarr as $v) {
00758 $sql .= $v.' $'.$i;
00759 $i++;
00760 }
00761 $s = "PREPARE $plan ($params) AS ".substr($sql,0,strlen($sql)-2);
00762
00763 pg_exec($this->_connectionID,$s);
00764
00765 }
00766
00767 $rez = pg_exec($this->_connectionID,$exsql);
00768 } else {
00769
00770 $rez = pg_exec($this->_connectionID,$sql);
00771 }
00772
00773 if ($rez && pg_numfields($rez) <= 0) {
00774 if (is_resource($this->_resultid) && get_resource_type($this->_resultid) === 'pgsql result') {
00775 pg_freeresult($this->_resultid);
00776 }
00777 $this->_resultid = $rez;
00778 return true;
00779 }
00780
00781 return $rez;
00782 }
00783
00784 function _errconnect()
00785 {
00786 if (defined('DB_ERROR_CONNECT_FAILED')) return DB_ERROR_CONNECT_FAILED;
00787 else return 'Database connection failed';
00788 }
00789
00790
00791 function ErrorMsg()
00792 {
00793 if ($this->_errorMsg !== false) return $this->_errorMsg;
00794 if (ADODB_PHPVER >= 0x4300) {
00795 if (!empty($this->_resultid)) {
00796 $this->_errorMsg = @pg_result_error($this->_resultid);
00797 if ($this->_errorMsg) return $this->_errorMsg;
00798 }
00799
00800 if (!empty($this->_connectionID)) {
00801 $this->_errorMsg = @pg_last_error($this->_connectionID);
00802 } else $this->_errorMsg = $this->_errconnect();
00803 } else {
00804 if (empty($this->_connectionID)) $this->_errconnect();
00805 else $this->_errorMsg = @pg_errormessage($this->_connectionID);
00806 }
00807 return $this->_errorMsg;
00808 }
00809
00810 function ErrorNo()
00811 {
00812 $e = $this->ErrorMsg();
00813 if (strlen($e)) {
00814 return ADOConnection::MetaError($e);
00815 }
00816 return 0;
00817 }
00818
00819
00820 function _close()
00821 {
00822 if ($this->transCnt) $this->RollbackTrans();
00823 if ($this->_resultid) {
00824 @pg_freeresult($this->_resultid);
00825 $this->_resultid = false;
00826 }
00827 @pg_close($this->_connectionID);
00828 $this->_connectionID = false;
00829 return true;
00830 }
00831
00832
00833
00834
00835
00836 function CharMax()
00837 {
00838 return 1000000000;
00839 }
00840
00841
00842
00843
00844 function TextMax()
00845 {
00846 return 1000000000;
00847 }
00848
00849
00850 }
00851
00852
00853
00854
00855
00856 class ADORecordSet_postgres64 extends ADORecordSet{
00857 var $_blobArr;
00858 var $databaseType = "postgres64";
00859 var $canSeek = true;
00860 function ADORecordSet_postgres64($queryID,$mode=false)
00861 {
00862 if ($mode === false) {
00863 global $ADODB_FETCH_MODE;
00864 $mode = $ADODB_FETCH_MODE;
00865 }
00866 switch ($mode)
00867 {
00868 case ADODB_FETCH_NUM: $this->fetchMode = PGSQL_NUM; break;
00869 case ADODB_FETCH_ASSOC:$this->fetchMode = PGSQL_ASSOC; break;
00870
00871 case ADODB_FETCH_DEFAULT:
00872 case ADODB_FETCH_BOTH:
00873 default: $this->fetchMode = PGSQL_BOTH; break;
00874 }
00875 $this->adodbFetchMode = $mode;
00876 $this->ADORecordSet($queryID);
00877 }
00878
00879 function &GetRowAssoc($upper=true)
00880 {
00881 if ($this->fetchMode == PGSQL_ASSOC && !$upper) return $this->fields;
00882 $row =& ADORecordSet::GetRowAssoc($upper);
00883 return $row;
00884 }
00885
00886 function _initrs()
00887 {
00888 global $ADODB_COUNTRECS;
00889 $qid = $this->_queryID;
00890 $this->_numOfRows = ($ADODB_COUNTRECS)? @pg_numrows($qid):-1;
00891 $this->_numOfFields = @pg_numfields($qid);
00892
00893
00894
00895 if (empty($this->connection->noBlobs))
00896 for ($i=0, $max = $this->_numOfFields; $i < $max; $i++) {
00897 if (pg_fieldtype($qid,$i) == 'bytea') {
00898 $this->_blobArr[$i] = pg_fieldname($qid,$i);
00899 }
00900 }
00901 }
00902
00903
00904 function Fields($colname)
00905 {
00906 if ($this->fetchMode != PGSQL_NUM) return @$this->fields[$colname];
00907
00908 if (!$this->bind) {
00909 $this->bind = array();
00910 for ($i=0; $i < $this->_numOfFields; $i++) {
00911 $o = $this->FetchField($i);
00912 $this->bind[strtoupper($o->name)] = $i;
00913 }
00914 }
00915 return $this->fields[$this->bind[strtoupper($colname)]];
00916 }
00917
00918 function &FetchField($off = 0)
00919 {
00920
00921
00922 $o= new ADOFieldObject();
00923 $o->name = @pg_fieldname($this->_queryID,$off);
00924 $o->type = @pg_fieldtype($this->_queryID,$off);
00925 $o->max_length = @pg_fieldsize($this->_queryID,$off);
00926 return $o;
00927 }
00928
00929 function _seek($row)
00930 {
00931 return @pg_fetch_row($this->_queryID,$row);
00932 }
00933
00934 function _decode($blob)
00935 {
00936 eval('$realblob="'.adodb_str_replace(array('"','$'),array('\"','\$'),$blob).'";');
00937 return $realblob;
00938 }
00939
00940 function _fixblobs()
00941 {
00942 if ($this->fetchMode == PGSQL_NUM || $this->fetchMode == PGSQL_BOTH) {
00943 foreach($this->_blobArr as $k => $v) {
00944 $this->fields[$k] = ADORecordSet_postgres64::_decode($this->fields[$k]);
00945 }
00946 }
00947 if ($this->fetchMode == PGSQL_ASSOC || $this->fetchMode == PGSQL_BOTH) {
00948 foreach($this->_blobArr as $k => $v) {
00949 $this->fields[$v] = ADORecordSet_postgres64::_decode($this->fields[$v]);
00950 }
00951 }
00952 }
00953
00954 // 10% speedup to move MoveNext to child class
00955 function MoveNext()
00956 {
00957 if (!$this->EOF) {
00958 $this->_currentRow++;
00959 if ($this->_numOfRows < 0 || $this->_numOfRows > $this->_currentRow) {
00960 $this->fields = @pg_fetch_array($this->_queryID,$this->_currentRow,$this->fetchMode);
00961 if (is_array($this->fields) && $this->fields) {
00962 if (isset($this->_blobArr)) $this->_fixblobs();
00963 return true;
00964 }
00965 }
00966 $this->fields = false;
00967 $this->EOF = true;
00968 }
00969 return false;
00970 }
00971
00972 function _fetch()
00973 {
00974
00975 if ($this->_currentRow >= $this->_numOfRows && $this->_numOfRows >= 0)
00976 return false;
00977
00978 $this->fields = @pg_fetch_array($this->_queryID,$this->_currentRow,$this->fetchMode);
00979
00980 if ($this->fields && isset($this->_blobArr)) $this->_fixblobs();
00981
00982 return (is_array($this->fields));
00983 }
00984
00985 function _close()
00986 {
00987 return @pg_freeresult($this->_queryID);
00988 }
00989
00990 function MetaType($t,$len=-1,$fieldobj=false)
00991 {
00992 if (is_object($t)) {
00993 $fieldobj = $t;
00994 $t = $fieldobj->type;
00995 $len = $fieldobj->max_length;
00996 }
00997 switch (strtoupper($t)) {
00998 case 'MONEY': // stupid, postgres expects money to be a string
00999 case 'INTERVAL':
01000 case 'CHAR':
01001 case 'CHARACTER':
01002 case 'VARCHAR':
01003 case 'NAME':
01004 case 'BPCHAR':
01005 case '_VARCHAR':
01006 case 'INET':
01007 case 'MACADDR':
01008 if ($len <= $this->blobSize) return 'C';
01009
01010 case 'TEXT':
01011 return 'X';
01012
01013 case 'IMAGE': // user defined type
01014 case 'BLOB': // user defined type
01015 case 'BIT': // This is a bit string, not a single bit, so don't return 'L'
01016 case 'VARBIT':
01017 case 'BYTEA':
01018 return 'B';
01019
01020 case 'BOOL':
01021 case 'BOOLEAN':
01022 return 'L';
01023
01024 case 'DATE':
01025 return 'D';
01026
01027
01028 case 'TIMESTAMP WITHOUT TIME ZONE':
01029 case 'TIME':
01030 case 'DATETIME':
01031 case 'TIMESTAMP':
01032 case 'TIMESTAMPTZ':
01033 return 'T';
01034
01035 case 'SMALLINT':
01036 case 'BIGINT':
01037 case 'INTEGER':
01038 case 'INT8':
01039 case 'INT4':
01040 case 'INT2':
01041 if (isset($fieldobj) &&
01042 empty($fieldobj->primary_key) && empty($fieldobj->unique)) return 'I';
01043
01044 case 'OID':
01045 case 'SERIAL':
01046 return 'R';
01047
01048 default:
01049 return 'N';
01050 }
01051 }
01052
01053 }
01054 ?>