Skip to content

Commit 23fd927

Browse files
committed
Fixed issue where query would be executed twice if used inside a collection
1 parent bba6bb2 commit 23fd927

File tree

2 files changed

+30
-3
lines changed

2 files changed

+30
-3
lines changed

src/Database/Statement/StatementDecorator.php

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,13 @@ class StatementDecorator implements StatementInterface, \Countable, \IteratorAgg
4646
*/
4747
protected $_driver;
4848

49+
/**
50+
* Whether or not this statement has already been executed
51+
*
52+
* @var bool
53+
*/
54+
protected $_hasExecuted = false;
55+
4956
/**
5057
* Constructor
5158
*
@@ -158,6 +165,7 @@ public function errorInfo()
158165
*/
159166
public function execute($params = null)
160167
{
168+
$this->_hasExecuted = true;
161169
return $this->_statement->execute($params);
162170
}
163171

@@ -228,7 +236,6 @@ public function rowCount()
228236
*
229237
* ```
230238
* $statement = $connection->prepare('SELECT id, title from articles');
231-
* $statement->execute();
232239
* foreach ($statement as $row) {
233240
* //do stuff
234241
* }
@@ -238,7 +245,9 @@ public function rowCount()
238245
*/
239246
public function getIterator()
240247
{
241-
$this->execute();
248+
if (!$this->_hasExecuted) {
249+
$this->execute();
250+
}
242251
return $this->_statement;
243252
}
244253

tests/TestCase/Database/Statement/StatementDecoratorTest.php

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@ public function testLastInsertId()
4444
}
4545

4646
/**
47-
* Tests that calling lastInsertId will get the
47+
* Tests that calling lastInsertId will get the last insert id by
48+
* column name
4849
*
4950
* @return void
5051
*/
@@ -62,4 +63,21 @@ public function testLastInsertIdWithReturning()
6263
$driver->expects($this->never())->method('lastInsertId');
6364
$this->assertEquals(2, $statement->lastInsertId('users', 'id'));
6465
}
66+
67+
/**
68+
* Tests that the statement will not be executed twice if the iterator
69+
* is requested more than once
70+
*
71+
* @return void
72+
*/
73+
public function testNoDoubleExecution() {
74+
$inner = $this->getMock('\PDOStatement');
75+
$driver = $this->getMock('\Cake\Database\Driver');
76+
$statement = new StatementDecorator($inner, $driver);
77+
78+
$inner->expects($this->once())->method('execute');
79+
$this->assertSame($inner, $statement->getIterator());
80+
$this->assertSame($inner, $statement->getIterator());
81+
}
82+
6583
}

0 commit comments

Comments
 (0)