Skip to content

Commit 1e5eff8

Browse files
committed
Connection and ResultSet refactoring. Some ResultSet rework
Basically, the duplicate code was removed, which was moved to the corresponding base classes. All the result set common code is in ResultSetBase and MultiResultSetBase. The driver-specific (mysqli, PDO) behavior is moved in the appropriate ResultSetAdapter, which is injected into the base classes. Some reworking of the ResultSet in such a way that the behavior of fetch methods has become similar to the behavior of the corresponding mysqli and PDO methods.
1 parent dd8fc03 commit 1e5eff8

17 files changed

+946
-827
lines changed

src/Drivers/ConnectionBase.php

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,13 @@ abstract class ConnectionBase implements ConnectionInterface
1818
*/
1919
protected $connection = null;
2020

21+
/**
22+
* Disables any warning outputs returned on the connection with @ prefix.
23+
*
24+
* @var boolean
25+
*/
26+
protected $silence_connection_warning = false;
27+
2128
/**
2229
* Sets one or more connection parameters.
2330
*
@@ -133,4 +140,30 @@ public function quoteArr(Array $array = array())
133140

134141
return $result;
135142
}
143+
144+
/**
145+
* Establishes a connection if needed
146+
* @throws ConnectionException
147+
*/
148+
protected function ensureConnection()
149+
{
150+
try {
151+
$this->getConnection();
152+
} catch (ConnectionException $e) {
153+
$this->connect();
154+
}
155+
}
156+
157+
/**
158+
* Forces the connection to suppress all errors returned. This should only be used
159+
* when the production server is running with high error reporting settings.
160+
*
161+
* @param boolean $enable True if it should be enabled, false if it should be disabled
162+
* @deprecated
163+
* not good
164+
*/
165+
public function silenceConnectionWarning($enable = true)
166+
{
167+
$this->silence_connection_warning = $enable;
168+
}
136169
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
3+
namespace Foolz\SphinxQL\Drivers;
4+
5+
6+
interface MultiResultSetAdapterInterface
7+
{
8+
public function getNext();
9+
10+
public function current();
11+
12+
public function valid();
13+
}

src/Drivers/MultiResultSetBase.php

Lines changed: 119 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
<?php
22
namespace Foolz\SphinxQL\Drivers;
33

4+
use Foolz\SphinxQL\Exception\DatabaseException;
5+
46
abstract class MultiResultSetBase implements MultiResultSetInterface
57
{
68
/**
@@ -11,7 +13,27 @@ abstract class MultiResultSetBase implements MultiResultSetInterface
1113
/**
1214
* @var int
1315
*/
14-
public $cursor = null;
16+
public $cursor = 0;
17+
18+
/**
19+
* @var int
20+
*/
21+
protected $next_cursor = 0;
22+
23+
/**
24+
* @var \Foolz\SphinxQL\Drivers\ResultSetInterface|null
25+
*/
26+
protected $rowSet = null;
27+
28+
/**
29+
* @var \Foolz\SphinxQL\Drivers\MultiResultSetAdapterInterface|null
30+
*/
31+
protected $adapter = null;
32+
33+
/**
34+
* @var bool
35+
*/
36+
protected $valid = true;
1537

1638
public function getStored()
1739
{
@@ -34,7 +56,7 @@ public function getStored()
3456
public function offsetExists($offset)
3557
{
3658
$this->store();
37-
return $offset >= 0 && $offset < count($this->stored);
59+
return $this->storedValid($offset);
3860
}
3961

4062
/**
@@ -95,11 +117,7 @@ public function offsetUnset($offset)
95117
*/
96118
public function next()
97119
{
98-
if ($this->cursor === null) {
99-
$this->cursor = 0;
100-
} else {
101-
$this->cursor++;
102-
}
120+
$this->rowSet = $this->getNext();
103121
}
104122

105123
/**
@@ -122,7 +140,9 @@ public function key()
122140
public function rewind()
123141
{
124142
// we actually can't roll this back unless it was stored first
125-
$this->cursor = null;
143+
$this->cursor = 0;
144+
$this->next_cursor = 0;
145+
$this->rowSet = $this->getNext();
126146
}
127147

128148
/**
@@ -139,4 +159,95 @@ public function count()
139159
$this->store();
140160
return count($this->stored);
141161
}
162+
163+
/**
164+
* (PHP 5 &gt;= 5.0.0)<br/>
165+
* Checks if current position is valid
166+
* @link http://php.net/manual/en/iterator.valid.php
167+
* @return boolean The return value will be casted to boolean and then evaluated.
168+
* Returns true on success or false on failure.
169+
*/
170+
public function valid()
171+
{
172+
if ($this->stored !== null) {
173+
return $this->storedValid();
174+
}
175+
176+
return $this->adapter->valid();
177+
}
178+
179+
/**
180+
* (PHP 5 &gt;= 5.0.0)<br/>
181+
* Return the current element
182+
* @link http://php.net/manual/en/iterator.current.php
183+
* @return mixed Can return any type.
184+
*/
185+
public function current()
186+
{
187+
$rowSet = $this->rowSet;
188+
unset($this->rowSet);
189+
return $rowSet;
190+
}
191+
192+
/**
193+
* @param null|int $cursor
194+
* @return bool
195+
*/
196+
protected function storedValid($cursor = null)
197+
{
198+
$cursor = (!is_null($cursor) ? $cursor : $this->cursor);
199+
return $cursor >= 0 && $cursor < count($this->stored);
200+
}
201+
202+
/*
203+
* @return \Foolz\SphinxQL\Drivers\ResultSetInterface|false
204+
*/
205+
public function getNext()
206+
{
207+
$this->cursor = $this->next_cursor;
208+
209+
if ($this->stored !== null) {
210+
$resultSet = !$this->storedValid() ? false : $this->stored[$this->cursor];
211+
} else {
212+
if ($this->next_cursor > 0) {
213+
$this->adapter->getNext();
214+
}
215+
216+
$resultSet = !$this->adapter->valid() ? false : $this->adapter->current();
217+
}
218+
219+
$this->next_cursor++;
220+
221+
return $resultSet;
222+
}
223+
224+
/**
225+
* @return $this
226+
* @throws DatabaseException
227+
*/
228+
public function store()
229+
{
230+
if ($this->stored !== null) {
231+
return $this;
232+
}
233+
234+
// don't let users mix storage and driver cursors
235+
if ($this->next_cursor > 0) {
236+
throw new DatabaseException('The MultiResultSet is using the driver cursors, store() can\'t fetch all the data');
237+
}
238+
239+
$store = array();
240+
while ($set = $this->getNext()) {
241+
// this relies on stored being null!
242+
$store[] = $set->store();
243+
}
244+
245+
$this->cursor = 0;
246+
$this->next_cursor = 0;
247+
248+
// if we write the array straight to $this->stored it won't be null anymore and functions relying on null will break
249+
$this->stored = $store;
250+
251+
return $this;
252+
}
142253
}

src/Drivers/Mysqli/Connection.php

Lines changed: 7 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@
77
use Foolz\SphinxQL\Exception\SphinxQLException;
88
use Foolz\SphinxQL\Drivers\ConnectionBase;
99

10+
/**
11+
* SphinxQL connection class utilizing the MySQLi extension.
12+
* It also contains escaping and quoting functions.
13+
* @package Foolz\SphinxQL
14+
*/
1015
class Connection extends ConnectionBase
1116
{
1217
/**
@@ -16,24 +21,6 @@ class Connection extends ConnectionBase
1621
*/
1722
protected $internal_encoding = null;
1823

19-
/**
20-
* Disables any warning outputs returned on the \MySQLi connection with @ prefix.
21-
*
22-
* @var boolean
23-
*/
24-
protected $silence_connection_warning = false;
25-
26-
/**
27-
* Forces the \MySQLi connection to suppress all errors returned. This should only be used
28-
* when the production server is running with high error reporting settings.
29-
*
30-
* @param boolean $enable True if it should be enabled, false if it should be disabled
31-
*/
32-
public function silenceConnectionWarning($enable = true)
33-
{
34-
$this->silence_connection_warning = $enable;
35-
}
36-
3724
/**
3825
* Returns the internal encoding.
3926
*
@@ -92,19 +79,6 @@ public function ping()
9279
return $this->getConnection()->ping();
9380
}
9481

95-
/**
96-
* Establishes a connection if needed
97-
* @throws ConnectionException
98-
*/
99-
private function ensureConnection()
100-
{
101-
try {
102-
$this->getConnection();
103-
} catch (ConnectionException $e) {
104-
$this->connect();
105-
}
106-
}
107-
10882
/**
10983
* Closes and unset the connection to the Sphinx server.
11084
*/
@@ -134,7 +108,7 @@ public function query($query)
134108
$this->getConnection()->error.' [ '.$query.']');
135109
}
136110

137-
return new ResultSet($this, $resource);
111+
return ResultSet::make($this, $resource);
138112
}
139113

140114
/**
@@ -162,7 +136,7 @@ public function multiQuery(Array $queue)
162136
$this->getConnection()->error.' [ '.implode(';', $queue).']');
163137
};
164138

165-
return new MultiResultSet($this, $count);
139+
return MultiResultSet::make($this);
166140
}
167141

168142
/**

0 commit comments

Comments
 (0)