diff --git a/model/Database.php b/model/Database.php
index 020564069..024c6cf19 100644
--- a/model/Database.php
+++ b/model/Database.php
@@ -1050,211 +1050,4 @@ abstract class SS_Database {
public function releaseLock($name) {
return false;
}
-}
-
-/**
- * Abstract query-result class.
- * Once again, this should be subclassed by an actual database implementation. It will only
- * ever be constructed by a subclass of SS_Database. The result of a database query - an iteratable object
- * that's returned by DB::SS_Query
- *
- * Primarily, the SS_Query class takes care of the iterator plumbing, letting the subclasses focusing
- * on providing the specific data-access methods that are required: {@link nextRecord()}, {@link numRecords()}
- * and {@link seek()}
- * @package framework
- * @subpackage model
- */
-abstract class SS_Query implements Iterator {
- /**
- * The current record in the interator.
- * @var array
- */
- private $currentRecord = null;
-
- /**
- * The number of the current row in the interator.
- * @var int
- */
- private $rowNum = -1;
-
- /**
- * Flag to keep track of whether iteration has begun, to prevent unnecessary seeks
- */
- private $queryHasBegun = false;
-
- /**
- * Return an array containing all the values from a specific column. If no column is set, then the first will be
- * returned
- *
- * @param string $column
- * @return array
- */
- public function column($column = null) {
- $result = array();
-
- while($record = $this->next()) {
- if($column) $result[] = $record[$column];
- else $result[] = $record[key($record)];
- }
-
- return $result;
- }
-
- /**
- * Return an array containing all values in the leftmost column, where the keys are the
- * same as the values.
- * @return array
- */
- public function keyedColumn() {
- $column = array();
- foreach($this as $record) {
- $val = $record[key($record)];
- $column[$val] = $val;
- }
- return $column;
- }
-
- /**
- * Return a map from the first column to the second column.
- * @return array
- */
- public function map() {
- $column = array();
- foreach($this as $record) {
- $key = reset($record);
- $val = next($record);
- $column[$key] = $val;
- }
- return $column;
- }
-
- /**
- * Returns the next record in the iterator.
- * @return array
- */
- public function record() {
- return $this->next();
- }
-
- /**
- * Returns the first column of the first record.
- * @return string
- */
- public function value() {
- $record = $this->next();
- if($record) return $record[key($record)];
- }
-
- /**
- * Return an HTML table containing the full result-set
- */
- public function table() {
- $first = true;
- $result = "
\n";
-
- foreach($this as $record) {
- if($first) {
- $result .= "";
- foreach($record as $k => $v) {
- $result .= "" . Convert::raw2xml($k) . " | ";
- }
- $result .= "
\n";
- }
-
- $result .= "";
- foreach($record as $k => $v) {
- $result .= "" . Convert::raw2xml($v) . " | ";
- }
- $result .= "
\n";
-
- $first = false;
- }
- $result .= "
\n";
-
- if($first) return "No records found";
- return $result;
- }
-
- /**
- * Iterator function implementation. Rewind the iterator to the first item and return it.
- * Makes use of {@link seek()} and {@link numRecords()}, takes care of the plumbing.
- * @return array
- */
- public function rewind() {
- if($this->queryHasBegun && $this->numRecords() > 0) {
- $this->queryHasBegun = false;
- return $this->seek(0);
- }
- }
-
- /**
- * Iterator function implementation. Return the current item of the iterator.
- * @return array
- */
- public function current() {
- if(!$this->currentRecord) {
- return $this->next();
- } else {
- return $this->currentRecord;
- }
- }
-
- /**
- * Iterator function implementation. Return the first item of this iterator.
- * @return array
- */
- public function first() {
- $this->rewind();
- return $this->current();
- }
-
- /**
- * Iterator function implementation. Return the row number of the current item.
- * @return int
- */
- public function key() {
- return $this->rowNum;
- }
-
- /**
- * Iterator function implementation. Return the next record in the iterator.
- * Makes use of {@link nextRecord()}, takes care of the plumbing.
- * @return array
- */
- public function next() {
- $this->queryHasBegun = true;
- $this->currentRecord = $this->nextRecord();
- $this->rowNum++;
- return $this->currentRecord;
- }
-
- /**
- * Iterator function implementation. Check if the iterator is pointing to a valid item.
- * @return boolean
- */
- public function valid() {
- if(!$this->queryHasBegun) $this->next();
- return $this->currentRecord !== false;
- }
-
- /**
- * Return the next record in the query result.
- * @return array
- */
- abstract public function nextRecord();
-
- /**
- * Return the total number of items in the query result.
- * @return int
- */
- abstract public function numRecords();
-
- /**
- * Go to a specific row number in the query result and return the record.
- * @param int $rowNum Tow number to go to.
- * @return array
- */
- abstract public function seek($rowNum);
-}
-
-
+}
\ No newline at end of file
diff --git a/model/MySQLDatabase.php b/model/MySQLDatabase.php
index 3ed99ec72..e35a92f2b 100644
--- a/model/MySQLDatabase.php
+++ b/model/MySQLDatabase.php
@@ -1209,53 +1209,4 @@ class MySQLDatabase extends SS_Database {
// Prefix with database name
return Convert::raw2sql($this->database . '_' . Convert::raw2sql($name));
}
-}
-
-/**
- * A result-set from a MySQL database.
- * @package framework
- * @subpackage model
- */
-class MySQLQuery extends SS_Query {
- /**
- * The MySQLDatabase object that created this result set.
- * @var MySQLDatabase
- */
- protected $database;
-
- /**
- * The internal MySQL handle that points to the result set.
- * @var resource
- */
- protected $handle;
-
- /**
- * Hook the result-set given into a Query class, suitable for use by SilverStripe.
- * @param database The database object that created this query.
- * @param handle the internal mysql handle that is points to the resultset.
- */
- public function __construct(MySQLDatabase $database, $handle) {
- $this->database = $database;
- $this->handle = $handle;
- }
-
- public function __destruct() {
- if(is_object($this->handle)) $this->handle->free();
- }
-
- public function seek($row) {
- if(is_object($this->handle)) return $this->handle->data_seek($row);
- }
-
- public function numRecords() {
- if(is_object($this->handle)) return $this->handle->num_rows;
- }
-
- public function nextRecord() {
- if(is_object($this->handle) && ($data = $this->handle->fetch_assoc())) {
- return $data;
- } else {
- return false;
- }
- }
-}
+}
\ No newline at end of file
diff --git a/model/MySQLQuery.php b/model/MySQLQuery.php
new file mode 100644
index 000000000..b1366233f
--- /dev/null
+++ b/model/MySQLQuery.php
@@ -0,0 +1,69 @@
+database = $database;
+ $this->handle = $handle;
+ }
+
+ public function __destruct() {
+ if(is_object($this->handle)) {
+ $this->handle->free();
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function seek($row) {
+ if(is_object($this->handle)) {
+ return $this->handle->data_seek($row);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function numRecords() {
+ if(is_object($this->handle)) {
+ return $this->handle->num_rows;
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function nextRecord() {
+ if(is_object($this->handle) && ($data = $this->handle->fetch_assoc())) {
+ return $data;
+ } else {
+ return false;
+ }
+ }
+}
diff --git a/model/Query.php b/model/Query.php
new file mode 100644
index 000000000..e63caa1ca
--- /dev/null
+++ b/model/Query.php
@@ -0,0 +1,252 @@
+next()) {
+ if($column) {
+ $result[] = $record[$column];
+ } else {
+ $result[] = $record[key($record)];
+ }
+ }
+
+ return $result;
+ }
+
+ /**
+ * Return an array containing all values in the leftmost column, where the
+ * keys are the same as the values.
+ *
+ * @return array
+ */
+ public function keyedColumn() {
+ $column = array();
+
+ foreach($this as $record) {
+ $val = $record[key($record)];
+ $column[$val] = $val;
+ }
+
+ return $column;
+ }
+
+ /**
+ * Return a map from the first column to the second column.
+ *
+ * @return array
+ */
+ public function map() {
+ $column = array();
+
+ foreach($this as $record) {
+ $key = reset($record);
+ $val = next($record);
+ $column[$key] = $val;
+ }
+
+ return $column;
+ }
+
+ /**
+ * Returns the next record in the iterator.
+ *
+ * @return array
+ */
+ public function record() {
+ return $this->next();
+ }
+
+ /**
+ * Returns the first column of the first record.
+ *
+ * @return string
+ */
+ public function value() {
+ $record = $this->next();
+
+ if($record) {
+ return $record[key($record)];
+ }
+ }
+
+ /**
+ * Return an HTML table containing the full result-set.
+ */
+ public function table() {
+ $first = true;
+ $result = "\n";
+
+ foreach($this as $record) {
+ if($first) {
+ $result .= "";
+ foreach($record as $k => $v) {
+ $result .= "" . Convert::raw2xml($k) . " | ";
+ }
+ $result .= "
\n";
+ }
+
+ $result .= "";
+ foreach($record as $k => $v) {
+ $result .= "" . Convert::raw2xml($v) . " | ";
+ }
+ $result .= "
\n";
+
+ $first = false;
+ }
+ $result .= "
\n";
+
+ if($first) return "No records found";
+ return $result;
+ }
+
+ /**
+ * Iterator function implementation. Rewind the iterator to the first item
+ * and return it.
+ *
+ * Makes use of {@link seek()} and {@link numRecords()}, takes care of the
+ * plumbing.
+ *
+ * @return array
+ */
+ public function rewind() {
+ if($this->queryHasBegun && $this->numRecords() > 0) {
+ $this->queryHasBegun = false;
+
+ return $this->seek(0);
+ }
+ }
+
+ /**
+ * Iterator function implementation. Return the current item of the
+ * iterator.
+ *
+ * @return array
+ */
+ public function current() {
+ if(!$this->currentRecord) {
+ return $this->next();
+ } else {
+ return $this->currentRecord;
+ }
+ }
+
+ /**
+ * Iterator function implementation. Return the first item of this iterator.
+ * @return array
+ */
+ public function first() {
+ $this->rewind();
+
+ return $this->current();
+ }
+
+ /**
+ * Iterator function implementation. Return the row number of the current
+ * item.
+ *
+ * @return int
+ */
+ public function key() {
+ return $this->rowNum;
+ }
+
+ /**
+ * Iterator function implementation. Return the next record in the iterator.
+ *
+ * Makes use of {@link nextRecord()}, takes care of the plumbing.
+ *
+ * @return array
+ */
+ public function next() {
+ $this->queryHasBegun = true;
+ $this->currentRecord = $this->nextRecord();
+ $this->rowNum++;
+ return $this->currentRecord;
+ }
+
+ /**
+ * Iterator function implementation. Check if the iterator is pointing to a
+ * valid item.
+ *
+ * @return boolean
+ */
+ public function valid() {
+ if(!$this->queryHasBegun) {
+ $this->next();
+ }
+
+ return $this->currentRecord !== false;
+ }
+
+ /**
+ * Return the next record in the query result.
+ *
+ * @return array
+ */
+ abstract public function nextRecord();
+
+ /**
+ * Return the total number of items in the query result.
+ *
+ * @return int
+ */
+ abstract public function numRecords();
+
+ /**
+ * Go to a specific row number in the query result and return the record.
+ *
+ * @param int $rowNum Tow number to go to.
+ *
+ * @return array
+ */
+ abstract public function seek($rowNum);
+}
\ No newline at end of file