00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 require_once 'creole/drivers/odbc/ODBCResultSetCommon.php';
00023 require_once 'creole/drivers/odbc/ODBCTypes.php';
00024
00051 class ODBCCachedResultSet extends ODBCResultSetCommon implements ResultSet
00052 {
00057 protected $recs = array();
00058
00063 protected $lastPos = -1;
00064
00069 protected $cacheLobs = false;
00070
00074 public function __construct(Connection $conn, $result, $fetchmode = null, $cacheLobs = false)
00075 {
00076 parent::__construct($conn, $result, $fetchmode);
00077
00078 $this->cacheLobs = $cacheLobs;
00079 }
00080
00084 function close()
00085 {
00086 parent::close();
00087 $this->recs = null;
00088 $this->lastPos = -1;
00089 $this->cacheLobs = false;
00090 }
00091
00099 public function loadCache($recPos = -1)
00100 {
00101 $rid = $this->result->getHandle();
00102
00103 $curRecs = count($this->recs);
00104 $totRecs = ($curRecs ? $this->offset + $curRecs : 0);
00105
00106 while (1)
00107 {
00108
00109 if ($this->lastPos != -1 || ($recPos > -1 && $recPos <= $curRecs))
00110 return;
00111
00112
00113 $rowNum = ++$totRecs;
00114 $result = @odbc_fetch_row($rid, $rowNum);
00115
00116
00117 if ($result === false || ($this->limit > 0 && $curRecs+1 > $this->limit))
00118 {
00119 $this->lastPos = $curRecs;
00120 continue;
00121 }
00122
00123
00124 if ($totRecs <= $this->offset)
00125 continue;
00126
00127
00128 $row = array();
00129 for ($i = 0, $n = @odbc_num_fields($rid); $i < $n; $i++)
00130 {
00131 $fldNum = $i+1;
00132 $row[$i] = odbc_result($rid, $fldNum);
00133
00134
00135 if ($this->cacheLobs)
00136 {
00137 ODBCTypes::loadTypeMap($this->conn);
00138
00139 $nativeType = @odbc_field_type($rid, $fldNum);
00140 $creoleType = ODBCTypes::getType($nativeType);
00141
00142 $isBlob = ($creoleType == CreoleTypes::BLOB ||
00143 $creoleType == CreoleTypes::LONGVARBINARY);
00144
00145 $isClob = ($creoleType == CreoleTypes::CLOB ||
00146 $creoleType == CreoleTypes::LONGVARCHAR);
00147
00148 if (($isBlob || $isClob) && $row[$i] !== null)
00149 {
00150 $binmode = ($isBlob ? ODBC_BINMODE_RETURN : ODBC_BINMODE_CONVERT);
00151 $curdata = $row[$i];
00152 $row[$i] = $this->readLobData($fldNum, $binmode, $curdata);
00153 }
00154 }
00155 }
00156
00157
00158 $this->recs[++$curRecs] = $row;
00159 }
00160 }
00161
00165 public function seek($rownum)
00166 {
00167 $this->loadCache($rownum);
00168
00169 if ($rownum < 0 || $rownum > count($this->recs)+1)
00170 return false;
00171
00172 $this->cursorPos = $rownum;
00173
00174 return true;
00175 }
00176
00180 function next()
00181 {
00182 $this->loadCache(++$this->cursorPos);
00183
00184 if ($this->isAfterLast())
00185 {
00186 $this->afterLast();
00187 return false;
00188 }
00189
00190 $this->fields =& $this->checkFetchMode($this->recs[$this->cursorPos]);
00191
00192 return true;
00193 }
00194
00198 function getRecordCount()
00199 {
00200 if ($this->lastPos == -1)
00201 $this->loadCache(-1);
00202
00203 return $this->lastPos;
00204 }
00205
00209 public function isAfterLast()
00210 {
00211
00212 if ($this->lastPos == -1)
00213 return false;
00214
00215 return ($this->cursorPos > $this->lastPos);
00216 }
00217
00218 }