diff --git a/src/ORM/Connect/MySQLQuery.php b/src/ORM/Connect/MySQLQuery.php index 56b9e0dbc..4f8db6993 100644 --- a/src/ORM/Connect/MySQLQuery.php +++ b/src/ORM/Connect/MySQLQuery.php @@ -63,6 +63,11 @@ class MySQLQuery extends Query } yield $data; } + // Check for the method first since $this->handle is a mixed type + if (method_exists($this->handle, 'data_seek')) { + // Reset so the query can be iterated over again + $this->handle->data_seek(0); + } } } diff --git a/tests/php/ORM/DataListTest.php b/tests/php/ORM/DataListTest.php index dc80aaf40..8ce1de790 100755 --- a/tests/php/ORM/DataListTest.php +++ b/tests/php/ORM/DataListTest.php @@ -42,7 +42,6 @@ class DataListTest extends SapphireTest ); } - public function testFilterDataObjectByCreatedDate() { // create an object to test with diff --git a/tests/php/ORM/DatabaseTest.php b/tests/php/ORM/DatabaseTest.php index 33a45caaf..706d25db3 100644 --- a/tests/php/ORM/DatabaseTest.php +++ b/tests/php/ORM/DatabaseTest.php @@ -7,6 +7,7 @@ use SilverStripe\ORM\Connect\MySQLDatabase; use SilverStripe\MSSQL\MSSQLDatabase; use SilverStripe\Dev\SapphireTest; use Exception; +use SilverStripe\ORM\Queries\SQLSelect; use SilverStripe\ORM\Tests\DatabaseTest\MyObject; /** @@ -293,4 +294,58 @@ class DatabaseTest extends SapphireTest $this->assertEquals($inputData, $query->map()); $this->assertEquals($inputData, $query->map()); } + + /** + * Test that repeated abstracted iteration of a query returns all records. + */ + public function testRepeatedIterationUsingAbstraction() + { + $inputData = ['one', 'two', 'three', 'four']; + + foreach ($inputData as $i => $text) { + $x = new MyObject(); + $x->MyField = $text; + $x->MyInt = $i; + $x->write(); + } + + $select = SQLSelect::create(['"MyInt"', '"MyField"'], '"DatabaseTest_MyObject"', orderby: ['"MyInt"']); + + $this->assertEquals($inputData, $select->execute()->map()); + $this->assertEquals($inputData, $select->execute()->map()); + } + + /** + * Test that stopping iteration part-way through produces predictable results + * on a subsequent iteration. + * This test is here to ensure consistency between implementations (e.g. mysql vs postgres, etc) + */ + public function testRepeatedPartialIteration() + { + $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"'); + + $i = 0; + foreach ($query as $record) { + $this->assertEquals($inputData[$i], $record['MyField']); + $i++; + if ($i > 1) { + break; + } + } + + // Continue from where we left off, since we're using a Generator + foreach ($query as $record) { + $this->assertEquals($inputData[$i], $record['MyField']); + $i++; + } + } }