Xataface  2.0alpha2
Xataface Application Framework
 All Data Structures Namespaces Files Functions Variables Groups Pages
ResultReader.php
Go to the documentation of this file.
1 <?php
23 class Dataface_ResultReader implements Iterator {
24 
25  private $sql = null;
26 
31  private $start = null;
32 
38  private $limit = null;
39 
40 
46  private $bufferSize = 30;
47 
52  private $buffer = null;
53 
60  private $bufferStartPos = null;
61 
66  private $currPos = null;
67 
68  private $db = null;
69 
70  private $decorator = null;
71 
79  public function __construct( $sql, $db, $bufferSize=30, $decorator = null){
80  $this->db = $db;
81  $this->start = 0;
82  $this->limit = null;
83  $this->bufferSize = $bufferSize;
84  $this->buffer = null;
85  $this->bufferStartPos = null;
86  $this->currPos = $this->start;
87  $this->sql = $sql;
88  $this->decorator = $decorator;
89 
90  if ( preg_match('/^([\s\S]+)\slimit\s+(\d+)(\s*,\s*(\d+)\s*)?\s*$/i', $this->sql, $matches) ){
91  $this->sql = $matches[1];
92  if ( isset($matches[4]) ){
93  $this->limit = intval($matches[4]);
94  $this->start = intval($matches[2]);
95  } else {
96  $this->start = 0;
97  $this->limit = intval($matches[2]);
98  }
99  }
100  if ( isset($this->limit) and $this->limit < $this->bufferSize ) $this->bufferSize = $this->limit;
101  }
102 
106  public function __destruct(){
107  $this->buffer = null;
108  }
109 
110 
114  public function rewind(){
115  $this->currPos = $this->start;
116 
117  if ( !isset($this->bufferStartPos) ){
118  // The buffer isn't set yet so we are at the beginning
119  return;
120  } else if ( $this->bufferStartPos > $this->start ){
121  // The buffer is beyond the first buffer set
122  // so we reset the buffer now
123  $this->buffer = null;
124  $this->bufferStartPos = null;
125  } else {
126  // The buffer is not beyond the first set
127  // so the buffer is good.
128  }
129 
130  }
131 
132  public function getQuery($start, $limit){
133  return $this->sql.' limit '.$start.', '.$limit;
134  }
135 
139  private function loadBuffer(){
140  if ( $this->currPos >= $this->bufferStartPos + $this->bufferSize ){
141  $this->bufferStartPos += $this->bufferSize;
142  } else if ( !isset($this->bufferStartPos) ){
143  $this->bufferStartPos = $this->start;
144  } else {
145  return;
146  }
147  $q = array();
148  $q['-skip'] = $this->bufferStartPos;
149  $q['-limit'] = $this->bufferSize;
150  if ( isset($this->limit ) ){
151  $q['-limit'] = min($this->bufferSize, $this->start+$this->limit-$this->bufferStartPos);
152  }
153  if ( $q['-limit'] > 0 ){
154  $this->buffer = array();
155  $res = mysql_query($this->getQuery($q['-skip'], $q['-limit']), $this->db);
156  if ( !$res ) throw new Exception(mysql_error($this->db));
157 
158  while ($row = mysql_fetch_object($res) ){
159  if ( isset($this->decorator) and is_callable($this->decorator) ){
160  $row = call_user_func($this->decorator, $row);
161  }
162  $this->buffer[] = $row;
163  }
164  @mysql_free_result($res);
165  } else {
166  $this->buffer = array();
167  }
168 
169  }
170 
175  public function current(){
176  $this->loadBuffer();
177  return $this->buffer[$this->currPos-$this->bufferStartPos];
178  }
179 
184  public function key(){
185  return $this->currPos;
186  }
187 
191  public function next(){
192  ++$this->currPos;
193  }
194 
198  public function valid(){
199  $this->loadBuffer();
200  return isset($this->buffer[$this->currPos-$this->bufferStartPos]);
201  }
202 }