Merge pull request #13777 from owncloud/close-cursor

Close cursor for appframework and manipulation queries if applicable
This commit is contained in:
Lukas Reschke 2015-02-20 20:15:22 +01:00
commit fcc5f5a4f4
4 changed files with 51 additions and 37 deletions

View File

@ -69,6 +69,7 @@ class OC_DB_StatementWrapper {
return false; return false;
} }
if ($this->isManipulation) { if ($this->isManipulation) {
$this->statement->closeCursor();
return $this->statement->rowCount(); return $this->statement->rowCount();
} else { } else {
return $this; return $this;

View File

@ -70,10 +70,12 @@ abstract class Mapper {
/** /**
* Deletes an entity from the table * Deletes an entity from the table
* @param Entity $entity the entity that should be deleted * @param Entity $entity the entity that should be deleted
* @return Entity the deleted entity
*/ */
public function delete(Entity $entity){ public function delete(Entity $entity){
$sql = 'DELETE FROM `' . $this->tableName . '` WHERE `id` = ?'; $sql = 'DELETE FROM `' . $this->tableName . '` WHERE `id` = ?';
$this->execute($sql, array($entity->getId())); $this->execute($sql, [$entity->getId()]);
return $entity;
} }
@ -88,7 +90,7 @@ abstract class Mapper {
$properties = $entity->getUpdatedFields(); $properties = $entity->getUpdatedFields();
$values = ''; $values = '';
$columns = ''; $columns = '';
$params = array(); $params = [];
// build the fields // build the fields
$i = 0; $i = 0;
@ -116,6 +118,7 @@ abstract class Mapper {
$this->execute($sql, $params); $this->execute($sql, $params);
$entity->setId((int) $this->db->getInsertId($this->tableName)); $entity->setId((int) $this->db->getInsertId($this->tableName));
return $entity; return $entity;
} }
@ -147,7 +150,7 @@ abstract class Mapper {
unset($properties['id']); unset($properties['id']);
$columns = ''; $columns = '';
$params = array(); $params = [];
// build the fields // build the fields
$i = 0; $i = 0;
@ -185,7 +188,7 @@ abstract class Mapper {
* @param int $offset from which row we want to start * @param int $offset from which row we want to start
* @return \PDOStatement the database query result * @return \PDOStatement the database query result
*/ */
protected function execute($sql, array $params=array(), $limit=null, $offset=null){ protected function execute($sql, array $params=[], $limit=null, $offset=null){
$query = $this->db->prepareQuery($sql, $limit, $offset); $query = $this->db->prepareQuery($sql, $limit, $offset);
$index = 1; // bindParam is 1 indexed $index = 1; // bindParam is 1 indexed
@ -226,14 +229,16 @@ abstract class Mapper {
* @throws MultipleObjectsReturnedException if more than one item exist * @throws MultipleObjectsReturnedException if more than one item exist
* @return array the result as row * @return array the result as row
*/ */
protected function findOneQuery($sql, array $params=array(), $limit=null, $offset=null){ protected function findOneQuery($sql, array $params=[], $limit=null, $offset=null){
$result = $this->execute($sql, $params, $limit, $offset); $stmt = $this->execute($sql, $params, $limit, $offset);
$row = $result->fetch(); $row = $stmt->fetch();
if($row === false || $row === null){ if($row === false || $row === null){
$stmt->closeCursor();
throw new DoesNotExistException('No matching entry found'); throw new DoesNotExistException('No matching entry found');
} }
$row2 = $result->fetch(); $row2 = $stmt->fetch();
$stmt->closeCursor();
//MDB2 returns null, PDO and doctrine false when no row is available //MDB2 returns null, PDO and doctrine false when no row is available
if( ! ($row2 === false || $row2 === null )) { if( ! ($row2 === false || $row2 === null )) {
throw new MultipleObjectsReturnedException('More than one result'); throw new MultipleObjectsReturnedException('More than one result');
@ -262,15 +267,17 @@ abstract class Mapper {
* @param int $offset from which row we want to start * @param int $offset from which row we want to start
* @return array all fetched entities * @return array all fetched entities
*/ */
protected function findEntities($sql, array $params=array(), $limit=null, $offset=null) { protected function findEntities($sql, array $params=[], $limit=null, $offset=null) {
$result = $this->execute($sql, $params, $limit, $offset); $stmt = $this->execute($sql, $params, $limit, $offset);
$entities = array(); $entities = [];
while($row = $result->fetch()){ while($row = $stmt->fetch()){
$entities[] = $this->mapRowToEntity($row); $entities[] = $this->mapRowToEntity($row);
} }
$stmt->closeCursor();
return $entities; return $entities;
} }
@ -286,7 +293,7 @@ abstract class Mapper {
* @throws MultipleObjectsReturnedException if more than one item exist * @throws MultipleObjectsReturnedException if more than one item exist
* @return Entity the entity * @return Entity the entity
*/ */
protected function findEntity($sql, array $params=array(), $limit=null, $offset=null){ protected function findEntity($sql, array $params=[], $limit=null, $offset=null){
return $this->mapRowToEntity($this->findOneQuery($sql, $params, $limit, $offset)); return $this->mapRowToEntity($this->findOneQuery($sql, $params, $limit, $offset));
} }

View File

@ -84,7 +84,7 @@ class MapperTest extends MapperTestUtility {
$rows = array( $rows = array(
array('pre_name' => 'hi') array('pre_name' => 'hi')
); );
$this->setMapperResult($sql, $params, $rows); $this->setMapperResult($sql, $params, $rows, null, null, true);
$this->mapper->findOneEntity($sql, $params); $this->mapper->findOneEntity($sql, $params);
} }
@ -102,7 +102,7 @@ class MapperTest extends MapperTestUtility {
$sql = 'hi'; $sql = 'hi';
$params = array('jo'); $params = array('jo');
$rows = array(); $rows = array();
$this->setMapperResult($sql, $params, $rows); $this->setMapperResult($sql, $params, $rows, null, null, true);
$this->setExpectedException( $this->setExpectedException(
'\OCP\AppFramework\Db\DoesNotExistException'); '\OCP\AppFramework\Db\DoesNotExistException');
$this->mapper->findOneEntity($sql, $params); $this->mapper->findOneEntity($sql, $params);
@ -114,7 +114,7 @@ class MapperTest extends MapperTestUtility {
$rows = array( $rows = array(
array('jo'), array('ho') array('jo'), array('ho')
); );
$this->setMapperResult($sql, $params, $rows); $this->setMapperResult($sql, $params, $rows, null, null, true);
$this->setExpectedException( $this->setExpectedException(
'\OCP\AppFramework\Db\MultipleObjectsReturnedException'); '\OCP\AppFramework\Db\MultipleObjectsReturnedException');
$this->mapper->find($sql, $params); $this->mapper->find($sql, $params);
@ -126,7 +126,7 @@ class MapperTest extends MapperTestUtility {
$rows = array( $rows = array(
array('jo'), array('ho') array('jo'), array('ho')
); );
$this->setMapperResult($sql, $params, $rows); $this->setMapperResult($sql, $params, $rows, null, null, true);
$this->setExpectedException( $this->setExpectedException(
'\OCP\AppFramework\Db\MultipleObjectsReturnedException'); '\OCP\AppFramework\Db\MultipleObjectsReturnedException');
$this->mapper->findOneEntity($sql, $params); $this->mapper->findOneEntity($sql, $params);
@ -249,7 +249,7 @@ class MapperTest extends MapperTestUtility {
$entity = new Example(); $entity = new Example();
$entity->setPreName('hi'); $entity->setPreName('hi');
$entity->resetUpdatedFields(); $entity->resetUpdatedFields();
$this->setMapperResult($sql, array(), $rows); $this->setMapperResult($sql, array(), $rows, null, null, true);
$result = $this->mapper->findAllEntities($sql); $result = $this->mapper->findAllEntities($sql);
$this->assertEquals(array($entity), $result); $this->assertEquals(array($entity), $result);
} }

View File

@ -51,7 +51,7 @@ abstract class MapperTestUtility extends \Test\TestCase {
->getMock(); ->getMock();
$this->query = $this->getMock('Query', array('execute', 'bindValue')); $this->query = $this->getMock('Query', array('execute', 'bindValue'));
$this->pdoResult = $this->getMock('Result', array('fetch')); $this->pdoResult = $this->getMock('Result', array('fetch', 'closeCursor'));
$this->queryAt = 0; $this->queryAt = 0;
$this->prepareAt = 0; $this->prepareAt = 0;
$this->iterators = array(); $this->iterators = array();
@ -69,7 +69,7 @@ abstract class MapperTestUtility extends \Test\TestCase {
* will be called on the result * will be called on the result
*/ */
protected function setMapperResult($sql, $arguments=array(), $returnRows=array(), protected function setMapperResult($sql, $arguments=array(), $returnRows=array(),
$limit=null, $offset=null){ $limit=null, $offset=null, $expectClose=false){
$this->iterators[] = new ArgumentIterator($returnRows); $this->iterators[] = new ArgumentIterator($returnRows);
@ -88,8 +88,14 @@ abstract class MapperTestUtility extends \Test\TestCase {
} }
return $result; return $result;
} }
)); ));
if ($expectClose) {
$closing = $this->once();
} else {
$closing = $this->any();
}
$this->pdoResult->expects($closing)->method('closeCursor');
$index = 1; $index = 1;
foreach($arguments as $argument) { foreach($arguments as $argument) {