diff --git a/src/ORM/Connect/MySQLQuery.php b/src/ORM/Connect/MySQLQuery.php index 22f11a3eb..f1dbfefd2 100644 --- a/src/ORM/Connect/MySQLQuery.php +++ b/src/ORM/Connect/MySQLQuery.php @@ -48,8 +48,11 @@ class MySQLQuery extends Query public function seek($row) { if (is_object($this->handle)) { + // Fix for https://github.com/silverstripe/silverstripe-framework/issues/9097 without breaking the seek() API $this->handle->data_seek($row); - return $this->nextRecord(); + $result = $this->nextRecord(); + $this->handle->data_seek($row); + return $result; } return null; } diff --git a/src/ORM/Connect/MySQLStatement.php b/src/ORM/Connect/MySQLStatement.php index 9c7fdce26..ca2cdbd32 100644 --- a/src/ORM/Connect/MySQLStatement.php +++ b/src/ORM/Connect/MySQLStatement.php @@ -105,8 +105,12 @@ class MySQLStatement extends Query public function seek($row) { $this->rowNum = $row - 1; + + // Fix for https://github.com/silverstripe/silverstripe-framework/issues/9097 without breaking the seek() API $this->statement->data_seek($row); - return $this->next(); + $result = $this->next(); + $this->statement->data_seek($row); + return $result; } public function numRecords() @@ -132,9 +136,4 @@ class MySQLStatement extends Query } return $row; } - - public function rewind() - { - return $this->seek(0); - } } diff --git a/src/ORM/Connect/Query.php b/src/ORM/Connect/Query.php index 1f994dd7f..b1c3d4247 100644 --- a/src/ORM/Connect/Query.php +++ b/src/ORM/Connect/Query.php @@ -168,16 +168,15 @@ abstract class Query implements Iterator * 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 + * @return void */ public function rewind() { if ($this->queryHasBegun && $this->numRecords() > 0) { $this->queryHasBegun = false; $this->currentRecord = null; - return $this->seek(0); + $this->seek(0); } - return null; } /** diff --git a/tests/php/ORM/DatabaseTest.php b/tests/php/ORM/DatabaseTest.php index babcdb402..607515613 100644 --- a/tests/php/ORM/DatabaseTest.php +++ b/tests/php/ORM/DatabaseTest.php @@ -272,4 +272,25 @@ class DatabaseTest extends SapphireTest $result = DB::query('SELECT TRUE')->first(); $this->assertInternalType('int', reset($result)); } + + /** + * Test that repeated iteration of a query returns all records. + * See https://github.com/silverstripe/silverstripe-framework/issues/9097 + */ + public function testRepeatedIteration() + { + $inputData = ['one', 'two', 'three', 'four']; + + foreach ($inputData as $i => $text) { + $x = new MyObject(); + $x->MyField = $text; + $x->MyInt = $i; + $x->write(); + } + + $query = DB::query('SELECT "MyInt", "MyField" FROM "DatabaseTest_MyObject" ORDER BY "MyInt"'); + + $this->assertEquals($inputData, $query->map()); + $this->assertEquals($inputData, $query->map()); + } }