| [ Index ] |
|
Code source de Symfony 1.0.0 |
1 <?php 2 /* 3 * $Id: ODBCCachedResultSet.php,v 1.2 2005/04/01 17:04:00 dlawson_mi Exp $ 4 * 5 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 6 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 7 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 8 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 9 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 10 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 11 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 12 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 13 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 14 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 15 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 16 * 17 * This software consists of voluntary contributions made by many individuals 18 * and is licensed under the LGPL. For more information please see 19 * <http://creole.phpdb.org>. 20 */ 21 22 require_once 'creole/drivers/odbc/ODBCResultSetCommon.php'; 23 require_once 'creole/drivers/odbc/ODBCTypes.php'; 24 25 /** 26 * ODBC implementation of a cached ResultSet. 27 * 28 * In addition to limit/offset emulation, this class implements a resultset 29 * cache. This can be useful as a workaround for some ODBC drivers which lack 30 * support for reverse/absolute cursor scrolling, etc. 31 * 32 * This class will cache rows _on-demand_. So if you only read the first couple 33 * rows of a result, then only those rows will be cached. However, note that if 34 * you call getRecordCount() or last(), the class must read and cache all 35 * available records. 36 * 37 * The offset / limit variables are also taken into account when caching. Any 38 * rows preceding the offset value will be skipped. Caching will stop once the 39 * limit value is reached. 40 * 41 * To use this class, create a derived {@link ODBCAdapter} class which returns 42 * an instance of ODBCCachedResultSet from the {@link ODBCAdapter::createResultSet()} method. 43 * Specify the adapter via the query portion of the Connection URL: 44 * 45 * odbc://localhost/Driver=MySQL ODBC 3.51 Driver;Database=test?adapter=MySQL 46 * 47 * @author Dave Lawson <dlawson@masterytech.com> 48 * @version $Revision: 1.2 $ 49 * @package creole.drivers.odbc 50 */ 51 class ODBCCachedResultSet extends ODBCResultSetCommon implements ResultSet 52 { 53 /** 54 * Record cache 55 * @var array 56 */ 57 protected $recs = array(); 58 59 /** 60 * Tracks the last cursor position of the recordset. 61 * @var integer 62 */ 63 protected $lastPos = -1; 64 65 /** 66 * True if blobs/clobs should also be cached. 67 * @var boolean 68 */ 69 protected $cacheLobs = false; 70 71 /** 72 * @see ResultSet::__construct() 73 */ 74 public function __construct(Connection $conn, $result, $fetchmode = null, $cacheLobs = false) 75 { 76 parent::__construct($conn, $result, $fetchmode); 77 78 $this->cacheLobs = $cacheLobs; 79 } 80 81 /** 82 * @see ODBCResultSetCommon::close() 83 */ 84 function close() 85 { 86 parent::close(); 87 $this->recs = null; 88 $this->lastPos = -1; 89 $this->cacheLobs = false; 90 } 91 92 /** 93 * Caches specified records up to and including the specified 1-based 94 * record position. If -1 is specified, all records will be cached. 95 * @param integer Maximum record position to cache. 96 * @return void 97 * @throws SQLException 98 */ 99 public function loadCache($recPos = -1) 100 { 101 $rid = $this->result->getHandle(); 102 103 $curRecs = count($this->recs); 104 $totRecs = ($curRecs ? $this->offset + $curRecs : 0); 105 106 while (1) 107 { 108 // Is record already cached? 109 if ($this->lastPos != -1 || ($recPos > -1 && $recPos <= $curRecs)) 110 return; 111 112 // Fetch row (no buffers copied yet). 113 $rowNum = ++$totRecs; 114 $result = @odbc_fetch_row($rid, $rowNum); 115 116 // All records cached? 117 if ($result === false || ($this->limit > 0 && $curRecs+1 > $this->limit)) 118 { 119 $this->lastPos = $curRecs; 120 continue; 121 } 122 123 // Ignore offset records. 124 if ($totRecs <= $this->offset) 125 continue; 126 127 // Load row array. 128 $row = array(); 129 for ($i = 0, $n = @odbc_num_fields($rid); $i < $n; $i++) 130 { 131 $fldNum = $i+1; 132 $row[$i] = odbc_result($rid, $fldNum); 133 134 // Cache lobs if necessary 135 if ($this->cacheLobs) 136 { 137 ODBCTypes::loadTypeMap($this->conn); 138 139 $nativeType = @odbc_field_type($rid, $fldNum); 140 $creoleType = ODBCTypes::getType($nativeType); 141 142 $isBlob = ($creoleType == CreoleTypes::BLOB || 143 $creoleType == CreoleTypes::LONGVARBINARY); 144 145 $isClob = ($creoleType == CreoleTypes::CLOB || 146 $creoleType == CreoleTypes::LONGVARCHAR); 147 148 if (($isBlob || $isClob) && $row[$i] !== null) 149 { 150 $binmode = ($isBlob ? ODBC_BINMODE_RETURN : ODBC_BINMODE_CONVERT); 151 $curdata = $row[$i]; 152 $row[$i] = $this->readLobData($fldNum, $binmode, $curdata); 153 } 154 } 155 } 156 157 // Add record to cache. 158 $this->recs[++$curRecs] = $row; 159 } 160 } 161 162 /** 163 * @see ResultSet::seek() 164 */ 165 public function seek($rownum) 166 { 167 $this->loadCache($rownum); 168 169 if ($rownum < 0 || $rownum > count($this->recs)+1) 170 return false; 171 172 $this->cursorPos = $rownum; 173 174 return true; 175 } 176 177 /** 178 * @see ResultSet::next() 179 */ 180 function next() 181 { 182 $this->loadCache(++$this->cursorPos); 183 184 if ($this->isAfterLast()) 185 { 186 $this->afterLast(); 187 return false; 188 } 189 190 $this->fields =& $this->checkFetchMode($this->recs[$this->cursorPos]); 191 192 return true; 193 } 194 195 /** 196 * @see ResultSet::getRecordCount() 197 */ 198 function getRecordCount() 199 { 200 if ($this->lastPos == -1) 201 $this->loadCache(-1); 202 203 return $this->lastPos; 204 } 205 206 /** 207 * @see ResultSet::isAfterLast() 208 */ 209 public function isAfterLast() 210 { 211 // All records cached yet? 212 if ($this->lastPos == -1) 213 return false; 214 215 return ($this->cursorPos > $this->lastPos); 216 } 217 218 }
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
| Généré le : Fri Mar 16 22:42:14 2007 | par Balluche grâce à PHPXref 0.7 |