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 include_once 'jargon/Record.php';
00026 require_once 'jargon/DataSetException.php';
00027
00050 abstract class DataSet implements IteratorAggregate {
00051
00053 const ALL_RECORDS = 0;
00054
00056 protected $records;
00057
00059 protected $conn;
00060
00062 protected $allRecordsRetrieved = false;
00063
00065 protected $recordRetrievedCount = 0;
00066
00068 protected $lastFetchSize = 0;
00069
00071 protected $totalFetchCount = 0;
00072
00074 protected $columns;
00075
00077 protected $selectSql;
00078
00080 protected $keyDef;
00081
00083 protected $resultSet;
00084
00086 protected $stmt;
00087
00098 public function getIterator()
00099 {
00100 $it = new DataSetIterator($this);
00101 return $it;
00102 }
00103
00110 public function resultSet()
00111 {
00112 if ($this->resultSet === null) {
00113 throw new DataSetException ("ResultSet is null.");
00114 }
00115 return $this->resultSet;
00116 }
00117
00123 public function allRecordsRetrieved()
00124 {
00125 return $this->allRecordsRetrieved;
00126 }
00127
00133 function setAllRecordsRetrieved($set)
00134 {
00135 $this->allRecordsRetrieved = $set;
00136 }
00137
00144 public function removeRecord(Record $rec)
00145 {
00146 $loc = array_search($rec, $this->records, true);
00147 $removeRec = array_splice($this->records, $loc, 1);
00148 return $removeRec;
00149 }
00150
00157 public function clearRecords()
00158 {
00159 $this->records = null;
00160 return $this;
00161 }
00162
00168 public function releaseRecords()
00169 {
00170 $this->records = null;
00171 $this->recordRetrievedCount = 0;
00172 $this->lastFetchSize = 0;
00173 $this->setAllRecordsRetrieved(false);
00174 return $this;
00175 }
00176
00183 public function close()
00184 {
00185 $this->releaseRecords();
00186 $this->schema = null;
00187
00188 if ($this->resultSet !== null && !$this instanceof QueryDataSet) {
00189 $this->resultSet->close();
00190 }
00191
00192 $this->resultSet = null;
00193
00194 if ( $this->stmt !== null ) {
00195 $this->stmt->close();
00196 }
00197
00198 $this->conn = null;
00199 }
00200
00208 public function reset()
00209 {
00210 if (! ($this->resultSet !== null && ($this instanceof QueryDataSet))) {
00211 return $this->releaseRecords();
00212 } else {
00213 throw new DataSetException("You cannot call reset() on a QueryDataSet.");
00214 }
00215 }
00216
00222 public function connection()
00223 {
00224 return $this->conn;
00225 }
00226
00232 public function schema()
00233 {
00234 return $this->schema;
00235 }
00236
00244 public function getRecord($pos)
00245 {
00246 if ($this->containsRecord($pos)) {
00247 $rec = $this->records[$pos];
00248 if ($this instanceof TableDataSet) {
00249 $rec->markForUpdate();
00250 }
00251 $this->recordRetrievedCount++;
00252 return $rec;
00253 }
00254 throw new DataSetException ("Record not found at index: " . $pos);
00255 }
00256
00265 public function findRecord($pos)
00266 {
00267 if ($this->containsRecord($pos)) {
00268 return $this->records[$pos];
00269 }
00270 throw new DataSetException ("Record not found at index: " . $pos);
00271 }
00272
00279 public function containsRecord($pos)
00280 {
00281 return (isset($this->records[$pos]));
00282 }
00283
00298 public function fetchRecords($p1 = 0, $p2 = null)
00299 {
00300 if ($p2 !== null) {
00301 $start = $p1;
00302 $max = $p2;
00303 } else {
00304 $start = 0;
00305 $max = $p1;
00306 }
00307
00308 if ($this->lastFetchSize() > 0 && $this->records !== null) {
00309 throw new DataSetException("You must call DataSet::clearRecords() before executing DataSet::fetchRecords() again!");
00310 }
00311
00312 try {
00313
00314 if ($this->stmt === null && $this->resultSet === null) {
00315 $this->stmt = $this->conn->createStatement();
00316 $this->stmt->setOffset($start);
00317 $this->stmt->setLimit($max);
00318
00319 $start = 0;
00320 $max = 0;
00321 $this->resultSet = $this->stmt->executeQuery($this->selectSql);
00322 }
00323
00324 if ($this->resultSet !== null) {
00325
00326 $this->records = array();
00327
00328 $startCounter = 0;
00329 $fetchCount = 0;
00330 while (! $this->allRecordsRetrieved() ) {
00331 if ($this->resultSet->next()) {
00332 if ($startCounter >= $start) {
00333 $this->records[] = new Record($this);
00334 $fetchCount++;
00335 if ($fetchCount === $max) {
00336 break;
00337 }
00338 } else {
00339 $startCounter++;
00340 }
00341 } else {
00342 $this->setAllRecordsRetrieved(true);
00343 break;
00344 }
00345 }
00346 $this->lastFetchSize = $fetchCount;
00347 }
00348 } catch (SQLException $e) {
00349 if ($this->stmt) $this->stmt->close();
00350 throw $e;
00351 }
00352
00353 return $this;
00354 }
00355
00361 public function lastFetchSize()
00362 {
00363 return $this->lastFetchSize;
00364 }
00365
00371 public function keydef()
00372 {
00373 return $this->keyDef;
00374 }
00375
00379 public function __toString()
00380 {
00381 $sb = "";
00382 for ($i = 0, $size = $this->size(); $i < $size; $i++) {
00383 $sb .= $this->getRecord($i);
00384 }
00385 return $sb;
00386 }
00387
00394 public abstract function getSelectSql();
00395
00401 public function getColumns()
00402 {
00403 return $this->columns;
00404 }
00405
00411 public function size()
00412 {
00413 if ( $this->records === null )
00414 return 0;
00415 return count($this->records);
00416 }
00417 }
00418
00419
00434 class DataSetIterator implements Iterator {
00435
00436 private $ds;
00437 private $size;
00438 private $pos;
00439
00440 function __construct(DataSet $ds) {
00441 $this->ds = $ds;
00442 $this->size = $ds->size();
00443 }
00444
00445 function rewind() {
00446 $this->pos = 0;
00447 }
00448
00449 function valid() {
00450 return $this->pos < $this->size;
00451 }
00452
00453 function key() {
00454 return $this->pos;
00455 }
00456
00457 function current() {
00458 return $this->ds->getRecord($this->pos);
00459 }
00460
00461 function next() {
00462 $this->pos++;
00463 }
00464 }