📄 adodb-postgres64.inc.php
字号:
} // dannym // 5 hasdefault; 6 num-of-column $fld->has_default = ($rs->fields[5] == 't'); if ($fld->has_default) { $fld->default_value = $rsdefa[$rs->fields[6]]; } //Freek if ($rs->fields[4] == $this->true) { $fld->not_null = true; } // Freek if (is_array($keys)) { foreach($keys as $key) { 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 cJOIN pg_catalog.pg_index i ON i.indexrelid=c.oidJOIN pg_catalog.pg_class c2 ON c2.oid=i.indrelid ,pg_namespace nWHERE (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 cJOIN pg_catalog.pg_index i ON i.indexrelid=c.oidJOIN pg_catalog.pg_class c2 ON c2.oid=i.indrelidWHERE 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)) { $false = false; 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->adodbFetchMode = $mode; $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 + -