Skip to content

Commit

Permalink
Helping PDO figure out what statements are not used anymore, this
Browse files Browse the repository at this point in the history
prevents SQlite tests from failing
  • Loading branch information
lorenzo committed Nov 1, 2013
1 parent fb55f89 commit a37455b
Show file tree
Hide file tree
Showing 12 changed files with 92 additions and 27 deletions.
13 changes: 11 additions & 2 deletions Cake/Database/Query.php
Expand Up @@ -1639,12 +1639,21 @@ protected function _transformQuery() {
if (!empty($this->_transformedQuery) && !$this->_dirty) {
return $this->_transformedQuery;
}

if ($this->_transformedQuery === false) {
return $this;
}

$translator = $this->connection()->driver()->queryTranslator($this->_type);
$transformed = $this->_transformedQuery = $translator($this);
$transformed->_transformedQuery = $transformed->_dirty = false;
$transformed = $translator($this);
$transformed->_dirty = false;
$transformed->_transformedQuery = false;

if ($transformed !== $this) {
$this->_transformedQuery = $transformed;

}

return $transformed;
}

Expand Down
5 changes: 5 additions & 0 deletions Cake/Database/Schema/Collection.php
Expand Up @@ -64,6 +64,7 @@ public function listTables() {
while ($row = $statement->fetch()) {
$result[] = $row[0];
}
$statement->closeCursor();
return $result;
}

Expand All @@ -82,23 +83,27 @@ public function describe($name) {
if (count($statement) === 0) {
throw new Exception(__d('cake_dev', 'Cannot describe %s. It has 0 columns.', $name));
}
$statement->closeCursor();

$table = new Table($name);
foreach ($statement->fetchAll('assoc') as $row) {
$this->_dialect->convertFieldDescription($table, $row);
}
$statement->closeCursor();

list($sql, $params) = $this->_dialect->describeIndexSql($name, $config);
$statement = $this->_executeSql($sql, $params);
foreach ($statement->fetchAll('assoc') as $row) {
$this->_dialect->convertIndexDescription($table, $row);
}
$statement->closeCursor();

list($sql, $params) = $this->_dialect->describeForeignKeySql($name, $config);
$statement = $this->_executeSql($sql, $params);
foreach ($statement->fetchAll('assoc') as $row) {
$this->_dialect->convertForeignKeyDescription($table, $row);
}
$statement->closeCursor();
return $table;
}

Expand Down
1 change: 1 addition & 0 deletions Cake/Database/Schema/SqliteSchema.php
Expand Up @@ -150,6 +150,7 @@ public function convertIndexDescription(Table $table, $row) {
foreach ($statement->fetchAll('assoc') as $column) {
$columns[] = $column['name'];
}
$statement->closeCursor();
if ($row['unique']) {
$table->addConstraint($row['name'], [
'type' => Table::CONSTRAINT_UNIQUE,
Expand Down
2 changes: 2 additions & 0 deletions Cake/Database/Statement/BufferedStatement.php
Expand Up @@ -55,6 +55,7 @@ public function fetch($type = 'num') {
if ($record === false) {
$this->_allFetched = true;
$this->_counter = $this->_count + 1;
$this->_statement->closeCursor();
return false;
}

Expand All @@ -70,6 +71,7 @@ public function fetchAll($type = 'num') {
$this->_records = parent::fetchAll($type);
$this->_count = count($this->_records);
$this->_allFetched = true;
$this->_statement->closeCursor();
return $this->_records;
}

Expand Down
4 changes: 3 additions & 1 deletion Cake/Database/Statement/SqliteStatement.php
Expand Up @@ -31,7 +31,9 @@ public function rowCount() {
if (preg_match('/^(?:DELETE|UPDATE|INSERT)/i', $this->_statement->queryString)) {
$changes = $this->_driver->prepare('SELECT CHANGES()');
$changes->execute();
return $changes->fetch()[0];
$count = $changes->fetch()[0];
$changes->closeCursor();
return $count;
}
return parent::rowCount();
}
Expand Down
7 changes: 2 additions & 5 deletions Cake/ORM/Query.php
Expand Up @@ -613,11 +613,8 @@ public function first() {
}
$this->bufferResults();
$this->_results = $this->execute();
// Calls foreach so we cursor is rewound automatically
foreach ($this->_results as $row) {
// Just get the first result from the iterator
return $row;
}
return $this->_results->one();

}

public function hydrate($enable = null) {
Expand Down
24 changes: 23 additions & 1 deletion Cake/ORM/ResultSet.php
Expand Up @@ -181,7 +181,29 @@ public function rewind() {
*/
public function valid() {
$this->_current = $this->_fetchResult();
return $this->_current !== false;
$valid = $this->_current !== false;

if (!$valid && $this->_statement) {
$this->_statement->closeCursor();
}

return $valid;
}

/**
* Returns the first result in this set and blocks the set so that no other
* results can be fetched
*
* @return array|object
*/
public function one() {
if ($this->valid()) {
if ($this->_statement) {
$this->_statement->closeCursor();
}
return $this->_current;
}
return null;
}

/**
Expand Down
12 changes: 9 additions & 3 deletions Cake/ORM/Table.php
Expand Up @@ -697,7 +697,9 @@ public function updateAll($fields, $conditions) {
->set($fields)
->where($conditions);
$statement = $query->executeStatement();
return $statement->rowCount() > 0;
$success = $statement->rowCount() > 0;
$statement->closeCursor();
return $success;
}

/**
Expand All @@ -720,7 +722,9 @@ public function deleteAll($conditions) {
$query->delete($this->table())
->where($conditions);
$statement = $query->executeStatement();
return $statement->rowCount() > 0;
$success = $statement->rowCount() > 0;
$statement->closeCursor();
return $success;
}

/**
Expand Down Expand Up @@ -785,7 +789,7 @@ public function save(Entity $entity, array $options = []) {
return $this->_processSave($entity, $options);
});
} else {
$success = $this->_processSave($entity, $data, $options);
$success = $this->_processSave($entity, $options);
}

return $success;
Expand Down Expand Up @@ -855,6 +859,7 @@ protected function _insert($entity, $data) {
$entity->clean();
$success = $entity;
}
$statement->closeCursor();
return $success;
}

Expand Down Expand Up @@ -890,6 +895,7 @@ protected function _update($entity, $data) {
$entity->clean();
$success = $entity;
}
$statement->closeCursor();
return $success;
}

Expand Down
3 changes: 2 additions & 1 deletion Cake/Test/TestCase/ORM/QueryTest.php
Expand Up @@ -829,6 +829,7 @@ public function testBufferResults() {
$this->assertSame($query, $result, 'Query should be the same');
$result = $query->execute();
$this->assertInstanceOf('Cake\ORM\BufferedResultSet', $result);
$result->toArray();
}

/**
Expand Down Expand Up @@ -992,7 +993,7 @@ public function testResultsAreWrappedInMapReduce() {
$params = [$this->connection, $this->table];
$query = $this->getMock('\Cake\ORM\Query', ['executeStatement'], $params);

$statement = $this->getMock('\Database\StatementInterface', ['fetch']);
$statement = $this->getMock('\Database\StatementInterface', ['fetch', 'closeCursor']);
$statement->expects($this->exactly(3))
->method('fetch')
->will($this->onConsecutiveCalls(['a' => 1], ['a' => 2], false));
Expand Down
24 changes: 21 additions & 3 deletions Cake/Test/TestCase/ORM/TableTest.php
Expand Up @@ -1017,6 +1017,7 @@ public function testCallBehaviorFinder() {
/**
* Tests that it is possible to insert a new row using the save method
*
* @group save
* @return void
*/
public function testSaveNewEntity() {
Expand All @@ -1038,6 +1039,7 @@ public function testSaveNewEntity() {
* Tests that saving an entity will filter out properties that
* are not present in the table schema when saving
*
* @group save
* @return void
*/
public function testSaveEntityOnlySchemaFields() {
Expand All @@ -1061,6 +1063,7 @@ public function testSaveEntityOnlySchemaFields() {
* Tests saving only a few fields in an entity when an fieldList
* is passed to save
*
* @group save
* @return void
*/
public function testSaveWithFieldList() {
Expand All @@ -1083,6 +1086,7 @@ public function testSaveWithFieldList() {
/**
* Tests that it is possible to modify data from the beforeSave callback
*
* @group save
* @return void
*/
public function testBeforeSaveModifyData() {
Expand All @@ -1106,6 +1110,7 @@ public function testBeforeSaveModifyData() {
/**
* Tests that it is possible to modify the options array in beforeSave
*
* @group save
* @return void
*/
public function testBeforeSaveModifyOptions() {
Expand Down Expand Up @@ -1137,6 +1142,7 @@ public function testBeforeSaveModifyOptions() {
* Tests that it is possible to stop the saving altogether, without implying
* the save operation failed
*
* @group save
* @return void
*/
public function testBeforeSaveStopEvent() {
Expand All @@ -1160,6 +1166,7 @@ public function testBeforeSaveStopEvent() {
/**
* Asserts that afterSave callback is called on successful save
*
* @group save
* @return void
*/
public function testAfterSave() {
Expand All @@ -1184,10 +1191,10 @@ public function testAfterSave() {
/**
* Asserts that afterSave callback not is called on unsuccessful save
*
* @group save
* @return void
*/
public function testAfterSaveNotCalled() {
$this->markTestIncomplete('This test causes errors with Sqlite');
$table = $this->getMock(
'\Cake\ORM\Table',
['_buildQuery', 'exists'],
Expand All @@ -1213,7 +1220,8 @@ public function testAfterSaveNotCalled() {
$query->expects($this->once())->method('executeStatement')
->will($this->returnValue($statement));

$statement->expects($this->once())->method('rowCount')->will($this->returnValue(0));
$statement->expects($this->once())->method('rowCount')
->will($this->returnValue(0));

$called = false;
$listener = function($e, $entity, $options) use ($data, &$called) {
Expand All @@ -1227,6 +1235,7 @@ public function testAfterSaveNotCalled() {
/**
* Tests that save is wrapped around a transaction
*
* @group save
* @return void
*/
public function testAtomicSave() {
Expand Down Expand Up @@ -1256,6 +1265,7 @@ public function testAtomicSave() {
/**
* Tests that save will rollback the transaction in the case of an exception
*
* @group save
* @expectedException \PDOException
* @return void
*/
Expand Down Expand Up @@ -1302,6 +1312,7 @@ public function testAtomicSaveRollback() {
/**
* Tests that save will rollback the transaction in the case of an exception
*
* @group save
* @return void
*/
public function testAtomicSaveRollbackOnFailure() {
Expand Down Expand Up @@ -1351,6 +1362,7 @@ public function testAtomicSaveRollbackOnFailure() {
* Tests that only the properties marked as dirty are actually saved
* to the database
*
* @group save
* @return void
*/
public function testSaveOnlyDirtyProperties() {
Expand All @@ -1377,6 +1389,7 @@ public function testSaveOnlyDirtyProperties() {
/**
* Tests that a recently saved entity is marked as clean
*
* @group save
* @return void
*/
public function testsASavedEntityIsClean() {
Expand All @@ -1397,6 +1410,7 @@ public function testsASavedEntityIsClean() {
/**
* Tests that a recently saved entity is marked as not new
*
* @group save
* @return void
*/
public function testsASavedEntityIsNotNew() {
Expand All @@ -1415,6 +1429,7 @@ public function testsASavedEntityIsNotNew() {
* Tests that save can detect automatically if it needs to insert
* or update a row
*
* @group save
* @return void
*/
public function testSaveUpdateAuto() {
Expand All @@ -1440,6 +1455,7 @@ public function testSaveUpdateAuto() {
* Tests that marking an entity as already persisted will prevent the save
* method from trying to infer the entity's actual status.
*
* @group save
* @return void
*/
public function testSaveUpdateWithHint() {
Expand All @@ -1461,6 +1477,7 @@ public function testSaveUpdateWithHint() {
* Tests that when updating the primary key is not passed to the list of
* attributes to change
*
* @group save
* @return void
*/
public function testSaveUpdatePrimaryKeyNotModified() {
Expand Down Expand Up @@ -1501,6 +1518,7 @@ public function testSaveUpdatePrimaryKeyNotModified() {
* Tests that passing only the primary key to save will not execute any queries
* but still return success
*
* @group save
* @return void
*/
public function testUpdateNoChange() {
Expand All @@ -1519,11 +1537,11 @@ public function testUpdateNoChange() {
/**
* Tests that failing to pass a primary key to save will result in exception
*
* @group save
* @expectedException \InvalidArgumentException
* @return void
*/
public function testUpdateNoPrimaryButOtherKeys() {
$this->markTestIncomplete('This test causes errors with Sqlite');
$table = $this->getMock(
'\Cake\ORM\Table',
['_buildQuery'],
Expand Down

0 comments on commit a37455b

Please sign in to comment.