Changeset 34 for trunk/phpgwapi/inc/adodb/drivers/adodb-postgres64.inc.php
- Timestamp:
- 06/29/07 15:17:46 (17 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/phpgwapi/inc/adodb/drivers/adodb-postgres64.inc.php
r2 r34 1 1 <?php 2 2 /* 3 V4. 51 29 July 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.3 V4.94 23 Jan 2007 (c) 2000-2007 John Lim (jlim#natsoft.com.my). All rights reserved. 4 4 Released under both BSD license and Lesser GPL library license. 5 5 Whenever there is any discrepancy between the two licenses, … … 50 50 $len = strlen($s); 51 51 if ($len == 0) return "''"; 52 if (strncmp($s,"'",1) === 0 && substr( s,$len-1) == "'") return $s; // already quoted52 if (strncmp($s,"'",1) === 0 && substr($s,$len-1) == "'") return $s; // already quoted 53 53 54 54 return "'".addslashes($s)."'"; … … 74 74 var $metaColumnsSQL = "SELECT a.attname,t.typname,a.attlen,a.atttypmod,a.attnotnull,a.atthasdef,a.attnum 75 75 FROM pg_class c, pg_attribute a,pg_type t 76 WHERE relkind = 'r'AND (c.relname='%s' or c.relname = lower('%s')) and a.attname not like '....%%'76 WHERE relkind in ('r','v') AND (c.relname='%s' or c.relname = lower('%s')) and a.attname not like '....%%' 77 77 AND a.attnum > 0 AND a.atttypid = t.oid AND a.attrelid = c.oid ORDER BY a.attnum"; 78 78 79 // used when schema defined 79 80 var $metaColumnsSQL1 = "SELECT a.attname, t.typname, a.attlen, a.atttypmod, a.attnotnull, a.atthasdef, a.attnum 80 81 FROM pg_class c, pg_attribute a, pg_type t, pg_namespace n 81 WHERE relkind = 'r'AND (c.relname='%s' or c.relname = lower('%s'))82 WHERE relkind in ('r','v') AND (c.relname='%s' or c.relname = lower('%s')) 82 83 and c.relnamespace=n.oid and n.nspname='%s' 83 84 and a.attname not like '....%%' AND a.attnum > 0 … … 91 92 var $hasLimit = false; // set to true for pgsql 7 only. support pgsql/mysql SELECT * FROM TABLE LIMIT 10 92 93 // below suggested by Freek Dijkstra 93 var $true = ' t'; // string that represents TRUE for a database94 var $false = ' f'; // string that represents FALSE for a database94 var $true = 'TRUE'; // string that represents TRUE for a database 95 var $false = 'FALSE'; // string that represents FALSE for a database 95 96 var $fmtDate = "'Y-m-d'"; // used by DBDate() as the default date format used by the database 96 var $fmtTimeStamp = "'Y-m-d G:i:s'"; // used by DBTimeStamp as the default timestamp fmt.97 var $fmtTimeStamp = "'Y-m-d H:i:s'"; // used by DBTimeStamp as the default timestamp fmt. 97 98 var $hasMoveFirst = true; 98 99 var $hasGenID = true; … … 102 103 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"; 103 104 var $random = 'random()'; /// random function 104 var $autoRollback = true; // apparently pgsql does not autorollback properly before 4.3.4105 var $autoRollback = true; // apparently pgsql does not autorollback properly before php 4.3.4 105 106 // http://bugs.php.net/bug.php?id=25404 106 107 107 108 var $_bindInputArray = false; // requires postgresql 7.3+ and ability to modify database 109 var $disableBlobs = false; // set to true to disable blob checking, resulting in 2-5% improvement in performance. 108 110 109 111 // The last (fmtTimeStamp is not entirely correct: … … 129 131 return $arr; 130 132 } 131 /* 133 132 134 function IfNull( $field, $ifNull ) 133 135 { 134 return " NULLIF($field, $ifNull) "; // if PGSQL135 } 136 */ 136 return " coalesce($field, $ifNull) "; 137 } 138 137 139 // get the last id - never tested 138 140 function pg_insert_id($tablename,$fieldname) … … 151 153 Unless you are very careful, you might end up with a tuple having 152 154 a different OID if a database must be reloaded. */ 153 function _insertid( )155 function _insertid($table,$column) 154 156 { 155 157 if (!is_resource($this->_resultid) || get_resource_type($this->_resultid) !== 'pgsql result') return false; 156 return pg_getlastoid($this->_resultid); 158 $oid = pg_getlastoid($this->_resultid); 159 // to really return the id, we need the table and column-name, else we can only return the oid != id 160 return empty($table) || empty($column) ? $oid : $this->GetOne("SELECT $column FROM $table WHERE oid=".(int)$oid); 157 161 } 158 162 159 163 // I get this error with PHP before 4.0.6 - jlim 160 // Warning: This compilation does not support pg_cmdtuples() in d:/inetpub/wwwroot/php/adodb/adodb-postgres.inc.php on line 44164 // Warning: This compilation does not support pg_cmdtuples() in adodb-postgres.inc.php on line 44 161 165 function _affectedrows() 162 166 { … … 171 175 if ($this->transOff) return true; 172 176 $this->transCnt += 1; 173 return @pg_Exec($this->_connectionID, "begin ");174 } 175 176 function RowLock($tables,$where )177 return @pg_Exec($this->_connectionID, "begin ".$this->_transmode); 178 } 179 180 function RowLock($tables,$where,$flds='1 as ignore') 177 181 { 178 182 if (!$this->transCnt) $this->BeginTrans(); 179 return $this->GetOne("select 1 as ignorefrom $tables where $where for update");183 return $this->GetOne("select $flds from $tables where $where for update"); 180 184 } 181 185 … … 199 203 200 204 function &MetaTables($ttype=false,$showSchema=false,$mask=false) 201 { 205 { 206 $info = $this->ServerInfo(); 207 if ($info['version'] >= 7.3) { 208 $this->metaTablesSQL = "select tablename,'T' from pg_tables where tablename not like 'pg\_%' 209 and schemaname not in ( 'pg_catalog','information_schema') 210 union 211 select viewname,'V' from pg_views where viewname not like 'pg\_%' and schemaname not in ( 'pg_catalog','information_schema') "; 212 } 202 213 if ($mask) { 203 214 $save = $this->metaTablesSQL; 204 215 $mask = $this->qstr(strtolower($mask)); 205 $this->metaTablesSQL = " 206 select tablename,'T' from pg_tables where tablename like $mask union 216 if ($info['version']>=7.3) 217 $this->metaTablesSQL = " 218 select tablename,'T' from pg_tables where tablename like $mask and schemaname not in ( 'pg_catalog','information_schema') 219 union 220 select viewname,'V' from pg_views where viewname like $mask and schemaname not in ( 'pg_catalog','information_schema') "; 221 else 222 $this->metaTablesSQL = " 223 select tablename,'T' from pg_tables where tablename like $mask 224 union 207 225 select viewname,'V' from pg_views where viewname like $mask"; 208 226 } … … 215 233 } 216 234 217 /*235 218 236 // if magic quotes disabled, use pg_escape_string() 219 237 function qstr($s,$magic_quotes=false) 220 238 { 221 239 if (!$magic_quotes) { 222 if (ADODB_PHPVER >= 0x4200) {223 return "'".pg_escape_string($s)."'";224 }225 240 if ($this->replaceQuote[0] == '\\'){ 226 $s = adodb_str_replace(array('\\',"\0"),array('\\\\',"\\\ 0"),$s);241 $s = adodb_str_replace(array('\\',"\0"),array('\\\\',"\\\\000"),$s); 227 242 } 228 243 return "'".str_replace("'",$this->replaceQuote,$s)."'"; … … 233 248 return "'$s'"; 234 249 } 235 */250 236 251 237 252 … … 288 303 break; 289 304 305 case 'w': 306 $s .= 'D'; 307 break; 308 309 case 'l': 310 $s .= 'DAY'; 311 break; 312 313 case 'W': 314 $s .= 'WW'; 315 break; 316 290 317 default: 291 318 // handle escape characters... … … 332 359 } 333 360 361 /* 362 * Deletes/Unlinks a Blob from the database, otherwise it 363 * will be left behind 364 * 365 * Returns TRUE on success or FALSE on failure. 366 * 367 * contributed by Todd Rogers todd#windfox.net 368 */ 369 function BlobDelete( $blob ) 370 { 371 pg_exec ($this->_connectionID, "begin"); 372 $result = @pg_lo_unlink($blob); 373 pg_exec ($this->_connectionID, "commit"); 374 return( $result ); 375 } 376 377 /* 378 Hueristic - not guaranteed to work. 379 */ 380 function GuessOID($oid) 381 { 382 if (strlen($oid)>16) return false; 383 return is_numeric($oid); 384 } 385 334 386 /* 335 387 * If an OID is detected, then we use pg_lo_* to open the oid file and read the … … 340 392 * 341 393 * see http://www.postgresql.org/idocs/index.php?largeobjects.html 394 * 395 * Since adodb 4.54, this returns the blob, instead of sending it to stdout. Also 396 * added maxsize parameter, which defaults to $db->maxblobsize if not defined. 342 397 */ 343 function BlobDecode( $blob)344 { 345 if ( strlen($blob) > 24) return $blob;346 347 @pg_exec($this->_connectionID,"begin");398 function BlobDecode($blob,$maxsize=false,$hastrans=true) 399 { 400 if (!$this->GuessOID($blob)) return $blob; 401 402 if ($hastrans) @pg_exec($this->_connectionID,"begin"); 348 403 $fd = @pg_lo_open($this->_connectionID,$blob,"r"); 349 404 if ($fd === false) { 350 @pg_exec($this->_connectionID,"commit");405 if ($hastrans) @pg_exec($this->_connectionID,"commit"); 351 406 return $blob; 352 407 } 353 $realblob = @pg_loreadall($fd); 408 if (!$maxsize) $maxsize = $this->maxblobsize; 409 $realblob = @pg_loread($fd,$maxsize); 354 410 @pg_loclose($fd); 355 @pg_exec($this->_connectionID,"commit");411 if ($hastrans) @pg_exec($this->_connectionID,"commit"); 356 412 return $realblob; 357 } 413 } 358 414 359 415 /* … … 366 422 function BlobEncode($blob) 367 423 { 368 if (ADODB_PHPVER >= 0x4200 && ADODB_PHPVER < 0x5000) return pg_escape_bytea($blob);369 424 370 425 /*92=backslash, 0=null, 39=single-quote*/ … … 376 431 } 377 432 433 // assumes bytea for blob, and varchar for clob 378 434 function UpdateBlob($table,$column,$val,$where,$blobtype='BLOB') 379 435 { 436 437 if ($blobtype == 'CLOB') { 438 return $this->Execute("UPDATE $table SET $column=" . $this->qstr($val) . " WHERE $where"); 439 } 380 440 // do not use bind params which uses qstr(), as blobencode() already quotes data 381 441 return $this->Execute("UPDATE $table SET $column='".$this->BlobEncode($val)."'::bytea WHERE $where"); … … 385 445 { 386 446 if (!$date) $date = $this->sysDate; 447 else if (strncmp($date,"'",1) == 0) { 448 $len = strlen($date); 449 if (10 <= $len && $len <= 12) $date = 'date '.$date; 450 else $date = 'timestamp '.$date; 451 } 387 452 return "($date+interval'$dayFraction days')"; 388 453 } … … 391 456 // for schema support, pass in the $table param "$schema.$tabname". 392 457 // converts field names to lowercase, $upper is ignored 458 // see http://phplens.com/lens/lensforum/msgs.php?id=14018 for more info 393 459 function &MetaColumns($table,$normalize=true) 394 460 { … … 396 462 397 463 $schema = false; 464 $false = false; 398 465 $this->_findschema($table,$schema); 399 466 … … 409 476 $ADODB_FETCH_MODE = $save; 410 477 411 if ($rs === false) return false; 412 478 if ($rs === false) { 479 return $false; 480 } 413 481 if (!empty($this->metaKeySQL)) { 414 482 // If we want the primary keys, we have to issue a separate query … … 461 529 $fld->type = $rs->fields[1]; 462 530 $fld->max_length = $rs->fields[2]; 531 $fld->attnum = $rs->fields[6]; 532 463 533 if ($fld->max_length <= 0) $fld->max_length = $rs->fields[3]-4; 464 534 if ($fld->max_length <= 0) $fld->max_length = -1; 465 535 if ($fld->type == 'numeric') { 536 $fld->scale = $fld->max_length & 0xFFFF; 537 $fld->max_length >>= 16; 538 } 466 539 // dannym 467 540 // 5 hasdefault; 6 num-of-column … … 472 545 473 546 //Freek 474 if ($rs->fields[4] == $this->true) { 475 $fld->not_null = true; 476 } 547 $fld->not_null = $rs->fields[4] == 't'; 548 477 549 478 550 // Freek 479 551 if (is_array($keys)) { 480 552 foreach($keys as $key) { 481 if ($fld->name == $key['column_name'] AND $key['primary_key'] == $this->true)553 if ($fld->name == $key['column_name'] AND $key['primary_key'] == 't') 482 554 $fld->primary_key = true; 483 if ($fld->name == $key['column_name'] AND $key['unique_key'] == $this->true)555 if ($fld->name == $key['column_name'] AND $key['unique_key'] == 't') 484 556 $fld->unique = true; // What name is more compatible? 485 557 } … … 492 564 } 493 565 $rs->Close(); 494 return $retarr; 566 if (empty($retarr)) 567 return $false; 568 else 569 return $retarr; 495 570 496 571 } … … 510 585 JOIN pg_catalog.pg_class c2 ON c2.oid=i.indrelid 511 586 ,pg_namespace n 512 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';587 WHERE (c2.relname=\'%s\' or c2.relname=lower(\'%s\')) and c.relnamespace=c2.relnamespace and c.relnamespace=n.oid and n.nspname=\'%s\''; 513 588 } else { 514 589 $sql = ' … … 517 592 JOIN pg_catalog.pg_index i ON i.indexrelid=c.oid 518 593 JOIN pg_catalog.pg_class c2 ON c2.oid=i.indrelid 519 WHERE c2.relname=\'%s\' or c2.relname=lower(\'%s\')';594 WHERE (c2.relname=\'%s\' or c2.relname=lower(\'%s\'))'; 520 595 } 521 596 … … 537 612 538 613 if (!is_object($rs)) { 539 return FALSE; 614 $false = false; 615 return $false; 540 616 } 541 617 542 $col_names = $this->MetaColumnNames($table,true); 618 $col_names = $this->MetaColumnNames($table,true,true); 619 //3rd param is use attnum, 620 // see http://sourceforge.net/tracker/index.php?func=detail&aid=1451245&group_id=42718&atid=433976 543 621 $indexes = array(); 544 622 while ($row = $rs->FetchRow()) { 545 623 $columns = array(); 546 624 foreach (explode(' ', $row[2]) as $col) { 547 $columns[] = $col_names[$col - 1];625 $columns[] = $col_names[$col]; 548 626 } 549 627 … … 564 642 { 565 643 566 if (!function_exists('pg_ pconnect')) return null;644 if (!function_exists('pg_connect')) return null; 567 645 568 646 $this->_errorMsg = false; … … 576 654 $host = split(":", $str); 577 655 if ($host[0]) $str = "host=".adodb_addslashes($host[0]); 578 else $str = ' host=localhost';656 else $str = ''; 579 657 if (isset($host[1])) $str .= " port=$host[1]"; 658 else if (!empty($this->port)) $str .= " port=".$this->port; 580 659 } 581 660 if ($user) $str .= " user=".$user; … … 601 680 if ($this->_connectionID === false) return false; 602 681 $this->Execute("set datestyle='ISO'"); 682 683 $info = $this->ServerInfo(); 684 $this->pgVersion = (float) substr($info['version'],0,3); 685 if ($this->pgVersion >= 7.1) { // good till version 999 686 $this->_nestedSQL = true; 687 } 603 688 return true; 604 689 } … … 623 708 function _query($sql,$inputarr) 624 709 { 625 710 $this->_errorMsg = false; 626 711 if ($inputarr) { 627 712 /* … … 652 737 if ($execp) $exsql = "EXECUTE $plan ($execp)"; 653 738 else $exsql = "EXECUTE $plan"; 739 654 740 655 741 $rez = @pg_exec($this->_connectionID,$exsql); … … 677 763 $s = "PREPARE $plan ($params) AS ".substr($sql,0,strlen($sql)-2); 678 764 //adodb_pr($s); 679 pg_exec($this->_connectionID,$s);680 echo $this->ErrorMsg();681 } 682 683 $rez = pg_exec($this->_connectionID,$exsql);765 $rez = pg_exec($this->_connectionID,$s); 766 //echo $this->ErrorMsg(); 767 } 768 if ($rez) 769 $rez = pg_exec($this->_connectionID,$exsql); 684 770 } else { 685 $this->_errorMsg = false;686 771 //adodb_backtrace(); 687 772 $rez = pg_exec($this->_connectionID,$sql); … … 699 784 } 700 785 786 function _errconnect() 787 { 788 if (defined('DB_ERROR_CONNECT_FAILED')) return DB_ERROR_CONNECT_FAILED; 789 else return 'Database connection failed'; 790 } 701 791 702 792 /* Returns: the last error message from previous database operation */ … … 712 802 if (!empty($this->_connectionID)) { 713 803 $this->_errorMsg = @pg_last_error($this->_connectionID); 714 } else $this->_errorMsg = @pg_last_error();804 } else $this->_errorMsg = $this->_errconnect(); 715 805 } else { 716 if (empty($this->_connectionID)) $this->_err orMsg = @pg_errormessage();806 if (empty($this->_connectionID)) $this->_errconnect(); 717 807 else $this->_errorMsg = @pg_errormessage($this->_connectionID); 718 808 } … … 780 870 case ADODB_FETCH_NUM: $this->fetchMode = PGSQL_NUM; break; 781 871 case ADODB_FETCH_ASSOC:$this->fetchMode = PGSQL_ASSOC; break; 782 default:872 783 873 case ADODB_FETCH_DEFAULT: 784 case ADODB_FETCH_BOTH:$this->fetchMode = PGSQL_BOTH; break; 785 } 874 case ADODB_FETCH_BOTH: 875 default: $this->fetchMode = PGSQL_BOTH; break; 876 } 877 $this->adodbFetchMode = $mode; 786 878 $this->ADORecordSet($queryID); 787 879 } … … 802 894 803 895 // cache types for blob decode check 896 // apparently pg_fieldtype actually performs an sql query on the database to get the type. 897 if (empty($this->connection->noBlobs)) 804 898 for ($i=0, $max = $this->_numOfFields; $i < $max; $i++) { 805 899 if (pg_fieldtype($qid,$i) == 'bytea') { … … 886 980 $this->fields = @pg_fetch_array($this->_queryID,$this->_currentRow,$this->fetchMode); 887 981 888 if ($this->fields && isset($this->_blobArr)) $this->_fixblobs();982 if ($this->fields && isset($this->_blobArr)) $this->_fixblobs(); 889 983 890 984 return (is_array($this->fields)); … … 912 1006 case 'BPCHAR': 913 1007 case '_VARCHAR': 1008 case 'INET': 1009 case 'MACADDR': 914 1010 if ($len <= $this->blobSize) return 'C'; 915 1011 … … 931 1027 return 'D'; 932 1028 1029 1030 case 'TIMESTAMP WITHOUT TIME ZONE': 933 1031 case 'TIME': 934 1032 case 'DATETIME':
Note: See TracChangeset
for help on using the changeset viewer.