Merge branch 'master' into bugfix/join-with-condition-placement-fix
This commit is contained in:
commit
324f200f1b
@ -8,9 +8,6 @@ Master: [![Build Status](https://secure.travis-ci.org/doctrine/doctrine2.png?bra
|
|||||||
|
|
||||||
Master: [![Coverage Status](https://coveralls.io/repos/doctrine/doctrine2/badge.png?branch=master)](https://coveralls.io/r/doctrine/doctrine2?branch=master)
|
Master: [![Coverage Status](https://coveralls.io/repos/doctrine/doctrine2/badge.png?branch=master)](https://coveralls.io/r/doctrine/doctrine2?branch=master)
|
||||||
|
|
||||||
[![Latest Stable Version](https://poser.pugx.org/doctrine/orm/v/stable.png)](https://packagist.org/packages/doctrine/orm) [![Total Downloads](https://poser.pugx.org/doctrine/orm/downloads.png)](https://packagist.org/packages/doctrine/orm)
|
|
||||||
|
|
||||||
|
|
||||||
Doctrine 2 is an object-relational mapper (ORM) for PHP 5.3.2+ that provides transparent persistence
|
Doctrine 2 is an object-relational mapper (ORM) for PHP 5.3.2+ that provides transparent persistence
|
||||||
for PHP objects. It sits on top of a powerful database abstraction layer (DBAL). One of its key features
|
for PHP objects. It sits on top of a powerful database abstraction layer (DBAL). One of its key features
|
||||||
is the option to write database queries in a proprietary object oriented SQL dialect called Doctrine Query Language (DQL),
|
is the option to write database queries in a proprietary object oriented SQL dialect called Doctrine Query Language (DQL),
|
||||||
|
@ -509,6 +509,8 @@ And then use the ``NEW`` DQL keyword :
|
|||||||
$query = $em->createQuery('SELECT NEW CustomerDTO(c.name, e.email, a.city, SUM(o.value)) FROM Customer c JOIN c.email e JOIN c.address a JOIN c.orders o GROUP BY c');
|
$query = $em->createQuery('SELECT NEW CustomerDTO(c.name, e.email, a.city, SUM(o.value)) FROM Customer c JOIN c.email e JOIN c.address a JOIN c.orders o GROUP BY c');
|
||||||
$users = $query->getResult(); // array of CustomerDTO
|
$users = $query->getResult(); // array of CustomerDTO
|
||||||
|
|
||||||
|
Note that you can only pass scalar expressions to the constructor.
|
||||||
|
|
||||||
Using INDEX BY
|
Using INDEX BY
|
||||||
~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~
|
||||||
|
|
||||||
@ -929,8 +931,9 @@ the Query class. Here they are:
|
|||||||
result is either a plain collection of objects (pure) or an array
|
result is either a plain collection of objects (pure) or an array
|
||||||
where the objects are nested in the result rows (mixed).
|
where the objects are nested in the result rows (mixed).
|
||||||
- ``Query#getSingleResult()``: Retrieves a single object. If the
|
- ``Query#getSingleResult()``: Retrieves a single object. If the
|
||||||
result contains more than one or no object, an exception is thrown. The
|
result contains more than one object, an ``NonUniqueResultException``
|
||||||
pure/mixed distinction does not apply.
|
is thrown. If the result contains no objects, an ``NoResultException``
|
||||||
|
is thrown. The pure/mixed distinction does not apply.
|
||||||
- ``Query#getOneOrNullResult()``: Retrieve a single object. If no
|
- ``Query#getOneOrNullResult()``: Retrieve a single object. If no
|
||||||
object is found null will be returned.
|
object is found null will be returned.
|
||||||
- ``Query#getArrayResult()``: Retrieves an array graph (a nested
|
- ``Query#getArrayResult()``: Retrieves an array graph (a nested
|
||||||
|
@ -702,3 +702,8 @@ methods:
|
|||||||
* ``notIn($field, array $values)``
|
* ``notIn($field, array $values)``
|
||||||
|
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
There is a limitation on the compatibility of Criteria comparisons.
|
||||||
|
You have to use scalar values only as the value in a comparison or
|
||||||
|
the behaviour between different backends is not the same.
|
||||||
|
@ -408,7 +408,7 @@ class BasicEntityPersister implements EntityPersister
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
$params[] = $value;
|
$params[] = $value;
|
||||||
$set[] = $column . ' = ' . $placeholder;
|
$set[] = $column . ' = ' . $placeholder;
|
||||||
$types[] = $this->columnTypes[$columnName];
|
$types[] = $this->columnTypes[$columnName];
|
||||||
@ -805,7 +805,7 @@ class BasicEntityPersister implements EntityPersister
|
|||||||
$sql = $this->getSelectSQL($id, null, $lockMode);
|
$sql = $this->getSelectSQL($id, null, $lockMode);
|
||||||
list($params, $types) = $this->expandParameters($id);
|
list($params, $types) = $this->expandParameters($id);
|
||||||
$stmt = $this->conn->executeQuery($sql, $params, $types);
|
$stmt = $this->conn->executeQuery($sql, $params, $types);
|
||||||
|
|
||||||
$hydrator = $this->em->newHydrator(Query::HYDRATE_OBJECT);
|
$hydrator = $this->em->newHydrator(Query::HYDRATE_OBJECT);
|
||||||
$hydrator->hydrateAll($stmt, $this->rsm, array(Query::HINT_REFRESH => true));
|
$hydrator->hydrateAll($stmt, $this->rsm, array(Query::HINT_REFRESH => true));
|
||||||
}
|
}
|
||||||
@ -1052,7 +1052,7 @@ class BasicEntityPersister implements EntityPersister
|
|||||||
$tableName = $this->quoteStrategy->getTableName($this->class, $this->platform);
|
$tableName = $this->quoteStrategy->getTableName($this->class, $this->platform);
|
||||||
|
|
||||||
if ('' !== $filterSql) {
|
if ('' !== $filterSql) {
|
||||||
$conditionSql = $conditionSql
|
$conditionSql = $conditionSql
|
||||||
? $conditionSql . ' AND ' . $filterSql
|
? $conditionSql . ' AND ' . $filterSql
|
||||||
: $filterSql;
|
: $filterSql;
|
||||||
}
|
}
|
||||||
@ -1205,7 +1205,7 @@ class BasicEntityPersister implements EntityPersister
|
|||||||
if ($assoc['isOwningSide']) {
|
if ($assoc['isOwningSide']) {
|
||||||
$tableAlias = $this->getSQLTableAlias($association['targetEntity'], $assocAlias);
|
$tableAlias = $this->getSQLTableAlias($association['targetEntity'], $assocAlias);
|
||||||
$this->selectJoinSql .= ' ' . $this->getJoinSQLForJoinColumns($association['joinColumns']);
|
$this->selectJoinSql .= ' ' . $this->getJoinSQLForJoinColumns($association['joinColumns']);
|
||||||
|
|
||||||
foreach ($association['joinColumns'] as $joinColumn) {
|
foreach ($association['joinColumns'] as $joinColumn) {
|
||||||
$sourceCol = $this->quoteStrategy->getJoinColumnName($joinColumn, $this->class, $this->platform);
|
$sourceCol = $this->quoteStrategy->getJoinColumnName($joinColumn, $this->class, $this->platform);
|
||||||
$targetCol = $this->quoteStrategy->getReferencedJoinColumnName($joinColumn, $this->class, $this->platform);
|
$targetCol = $this->quoteStrategy->getReferencedJoinColumnName($joinColumn, $this->class, $this->platform);
|
||||||
@ -1335,7 +1335,7 @@ class BasicEntityPersister implements EntityPersister
|
|||||||
foreach ($columns as $column) {
|
foreach ($columns as $column) {
|
||||||
$placeholder = '?';
|
$placeholder = '?';
|
||||||
|
|
||||||
if (isset($this->class->fieldNames[$column])
|
if (isset($this->class->fieldNames[$column])
|
||||||
&& isset($this->columnTypes[$this->class->fieldNames[$column]])
|
&& isset($this->columnTypes[$this->class->fieldNames[$column]])
|
||||||
&& isset($this->class->fieldMappings[$this->class->fieldNames[$column]]['requireSQLConversion'])) {
|
&& isset($this->class->fieldMappings[$this->class->fieldNames[$column]]['requireSQLConversion'])) {
|
||||||
|
|
||||||
@ -1408,7 +1408,7 @@ class BasicEntityPersister implements EntityPersister
|
|||||||
$columnName = $this->quoteStrategy->getColumnName($field, $class, $this->platform);
|
$columnName = $this->quoteStrategy->getColumnName($field, $class, $this->platform);
|
||||||
$sql = $tableAlias . '.' . $columnName;
|
$sql = $tableAlias . '.' . $columnName;
|
||||||
$columnAlias = $this->getSQLColumnAlias($class->columnNames[$field]);
|
$columnAlias = $this->getSQLColumnAlias($class->columnNames[$field]);
|
||||||
|
|
||||||
$this->rsm->addFieldResult($alias, $columnAlias, $field);
|
$this->rsm->addFieldResult($alias, $columnAlias, $field);
|
||||||
|
|
||||||
if (isset($class->fieldMappings[$field]['requireSQLConversion'])) {
|
if (isset($class->fieldMappings[$field]['requireSQLConversion'])) {
|
||||||
@ -1465,7 +1465,7 @@ class BasicEntityPersister implements EntityPersister
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
$lock = $this->platform->appendLockHint($this->getLockTablesSql(), $lockMode);
|
$lock = $this->getLockTablesSql($lockMode);
|
||||||
$where = ($conditionSql ? ' WHERE ' . $conditionSql : '') . ' ';
|
$where = ($conditionSql ? ' WHERE ' . $conditionSql : '') . ' ';
|
||||||
$sql = 'SELECT 1 '
|
$sql = 'SELECT 1 '
|
||||||
. $lock
|
. $lock
|
||||||
@ -1480,13 +1480,18 @@ class BasicEntityPersister implements EntityPersister
|
|||||||
/**
|
/**
|
||||||
* Gets the FROM and optionally JOIN conditions to lock the entity managed by this persister.
|
* Gets the FROM and optionally JOIN conditions to lock the entity managed by this persister.
|
||||||
*
|
*
|
||||||
|
* @param integer $lockMode One of the Doctrine\DBAL\LockMode::* constants.
|
||||||
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
protected function getLockTablesSql()
|
protected function getLockTablesSql($lockMode)
|
||||||
{
|
{
|
||||||
return 'FROM '
|
return $this->platform->appendLockHint(
|
||||||
. $this->quoteStrategy->getTableName($this->class, $this->platform) . ' '
|
'FROM '
|
||||||
. $this->getSQLTableAlias($this->class->name);
|
. $this->quoteStrategy->getTableName($this->class, $this->platform) . ' '
|
||||||
|
. $this->getSQLTableAlias($this->class->name),
|
||||||
|
$lockMode
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1796,7 +1801,7 @@ class BasicEntityPersister implements EntityPersister
|
|||||||
$alias = $this->getSQLTableAlias($this->class->name);
|
$alias = $this->getSQLTableAlias($this->class->name);
|
||||||
|
|
||||||
$sql = 'SELECT 1 '
|
$sql = 'SELECT 1 '
|
||||||
. $this->getLockTablesSql()
|
. $this->getLockTablesSql(null)
|
||||||
. ' WHERE ' . $this->getSelectConditionSQL($criteria);
|
. ' WHERE ' . $this->getSelectConditionSQL($criteria);
|
||||||
|
|
||||||
if ($filterSql = $this->generateFilterConditionSQL($this->class, $alias)) {
|
if ($filterSql = $this->generateFilterConditionSQL($this->class, $alias)) {
|
||||||
|
@ -74,7 +74,7 @@ interface EntityPersister
|
|||||||
*/
|
*/
|
||||||
public function getSelectSQL($criteria, $assoc = null, $lockMode = 0, $limit = null, $offset = null, array $orderBy = null);
|
public function getSelectSQL($criteria, $assoc = null, $lockMode = 0, $limit = null, $offset = null, array $orderBy = null);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Expands the parameters from the given criteria and use the correct binding types if found.
|
* Expands the parameters from the given criteria and use the correct binding types if found.
|
||||||
*
|
*
|
||||||
* @param $criteria
|
* @param $criteria
|
||||||
@ -269,7 +269,7 @@ interface EntityPersister
|
|||||||
* Locks all rows of this entity matching the given criteria with the specified pessimistic lock mode.
|
* Locks all rows of this entity matching the given criteria with the specified pessimistic lock mode.
|
||||||
*
|
*
|
||||||
* @param array $criteria
|
* @param array $criteria
|
||||||
* @param int $lockMode
|
* @param int $lockMode One of the Doctrine\DBAL\LockMode::* constants.
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
|
@ -288,7 +288,7 @@ class JoinedSubclassPersister extends AbstractEntityInheritancePersister
|
|||||||
foreach ($this->class->parentClasses as $parentClass) {
|
foreach ($this->class->parentClasses as $parentClass) {
|
||||||
$parentMetadata = $this->em->getClassMetadata($parentClass);
|
$parentMetadata = $this->em->getClassMetadata($parentClass);
|
||||||
$parentTable = $this->quoteStrategy->getTableName($parentMetadata, $this->platform);
|
$parentTable = $this->quoteStrategy->getTableName($parentMetadata, $this->platform);
|
||||||
|
|
||||||
$this->conn->delete($parentTable, $id);
|
$this->conn->delete($parentTable, $id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -342,7 +342,7 @@ class JoinedSubclassPersister extends AbstractEntityInheritancePersister
|
|||||||
|
|
||||||
// If the current class in the root entity, add the filters
|
// If the current class in the root entity, add the filters
|
||||||
if ($filterSql = $this->generateFilterConditionSQL($this->em->getClassMetadata($this->class->rootEntityName), $this->getSQLTableAlias($this->class->rootEntityName))) {
|
if ($filterSql = $this->generateFilterConditionSQL($this->em->getClassMetadata($this->class->rootEntityName), $this->getSQLTableAlias($this->class->rootEntityName))) {
|
||||||
$conditionSql .= $conditionSql
|
$conditionSql .= $conditionSql
|
||||||
? ' AND ' . $filterSql
|
? ' AND ' . $filterSql
|
||||||
: $filterSql;
|
: $filterSql;
|
||||||
}
|
}
|
||||||
@ -387,16 +387,13 @@ class JoinedSubclassPersister extends AbstractEntityInheritancePersister
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the FROM and optionally JOIN conditions to lock the entity managed by this persister.
|
* {@inheritdoc}
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public function getLockTablesSql()
|
protected function getLockTablesSql($lockMode)
|
||||||
{
|
{
|
||||||
$joinSql = '';
|
$joinSql = '';
|
||||||
$identifierColumns = $this->class->getIdentifierColumnNames();
|
$identifierColumns = $this->class->getIdentifierColumnNames();
|
||||||
$baseTableAlias = $this->getSQLTableAlias($this->class->name);
|
$baseTableAlias = $this->getSQLTableAlias($this->class->name);
|
||||||
$quotedTableName = $this->quoteStrategy->getTableName($this->class, $this->platform);
|
|
||||||
|
|
||||||
// INNER JOIN parent tables
|
// INNER JOIN parent tables
|
||||||
foreach ($this->class->parentClasses as $parentClassName) {
|
foreach ($this->class->parentClasses as $parentClassName) {
|
||||||
@ -412,7 +409,7 @@ class JoinedSubclassPersister extends AbstractEntityInheritancePersister
|
|||||||
$joinSql .= implode(' AND ', $conditions);
|
$joinSql .= implode(' AND ', $conditions);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 'FROM ' . $quotedTableName . ' ' . $baseTableAlias . $joinSql;
|
return parent::getLockTablesSql($lockMode) . $joinSql;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -488,8 +485,8 @@ class JoinedSubclassPersister extends AbstractEntityInheritancePersister
|
|||||||
|
|
||||||
// Add join columns (foreign keys)
|
// Add join columns (foreign keys)
|
||||||
foreach ($subClass->associationMappings as $mapping) {
|
foreach ($subClass->associationMappings as $mapping) {
|
||||||
if ( ! $mapping['isOwningSide']
|
if ( ! $mapping['isOwningSide']
|
||||||
|| ! ($mapping['type'] & ClassMetadata::TO_ONE)
|
|| ! ($mapping['type'] & ClassMetadata::TO_ONE)
|
||||||
|| isset($mapping['inherited'])) {
|
|| isset($mapping['inherited'])) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -505,17 +502,17 @@ class JoinedSubclassPersister extends AbstractEntityInheritancePersister
|
|||||||
}
|
}
|
||||||
|
|
||||||
$this->selectColumnListSql = implode(', ', $columnList);
|
$this->selectColumnListSql = implode(', ', $columnList);
|
||||||
|
|
||||||
return $this->selectColumnListSql;
|
return $this->selectColumnListSql;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
protected function getInsertColumnList()
|
protected function getInsertColumnList()
|
||||||
{
|
{
|
||||||
// Identifier columns must always come first in the column list of subclasses.
|
// Identifier columns must always come first in the column list of subclasses.
|
||||||
$columns = $this->class->parentClasses
|
$columns = $this->class->parentClasses
|
||||||
? $this->class->getIdentifierColumnNames()
|
? $this->class->getIdentifierColumnNames()
|
||||||
: array();
|
: array();
|
||||||
|
|
||||||
|
@ -457,7 +457,7 @@ class SqlWalker implements TreeWalker
|
|||||||
}
|
}
|
||||||
|
|
||||||
$sqlParts[] = (($this->useSqlTableAliases) ? $this->getSQLTableAlias($class->getTableName(), $dqlAlias) . '.' : '')
|
$sqlParts[] = (($this->useSqlTableAliases) ? $this->getSQLTableAlias($class->getTableName(), $dqlAlias) . '.' : '')
|
||||||
. $class->discriminatorColumn['name'] . ' IN (' . implode(', ', $values) . ')';
|
. $class->discriminatorColumn['name'] . ' IN (' . implode(', ', $values) . ')';
|
||||||
}
|
}
|
||||||
|
|
||||||
$sql = implode(' AND ', $sqlParts);
|
$sql = implode(' AND ', $sqlParts);
|
||||||
@ -497,7 +497,7 @@ class SqlWalker implements TreeWalker
|
|||||||
default:
|
default:
|
||||||
//@todo: throw exception?
|
//@todo: throw exception?
|
||||||
return '';
|
return '';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
$filterClauses = array();
|
$filterClauses = array();
|
||||||
@ -576,7 +576,7 @@ class SqlWalker implements TreeWalker
|
|||||||
$this->rsm->isSelect = false;
|
$this->rsm->isSelect = false;
|
||||||
|
|
||||||
return $this->walkUpdateClause($AST->updateClause)
|
return $this->walkUpdateClause($AST->updateClause)
|
||||||
. $this->walkWhereClause($AST->whereClause);
|
. $this->walkWhereClause($AST->whereClause);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -588,7 +588,7 @@ class SqlWalker implements TreeWalker
|
|||||||
$this->rsm->isSelect = false;
|
$this->rsm->isSelect = false;
|
||||||
|
|
||||||
return $this->walkDeleteClause($AST->deleteClause)
|
return $this->walkDeleteClause($AST->deleteClause)
|
||||||
. $this->walkWhereClause($AST->whereClause);
|
. $this->walkWhereClause($AST->whereClause);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -703,10 +703,10 @@ class SqlWalker implements TreeWalker
|
|||||||
}
|
}
|
||||||
|
|
||||||
$addMetaColumns = ! $this->query->getHint(Query::HINT_FORCE_PARTIAL_LOAD) &&
|
$addMetaColumns = ! $this->query->getHint(Query::HINT_FORCE_PARTIAL_LOAD) &&
|
||||||
$this->query->getHydrationMode() == Query::HYDRATE_OBJECT
|
$this->query->getHydrationMode() == Query::HYDRATE_OBJECT
|
||||||
||
|
||
|
||||||
$this->query->getHydrationMode() != Query::HYDRATE_OBJECT &&
|
$this->query->getHydrationMode() != Query::HYDRATE_OBJECT &&
|
||||||
$this->query->getHint(Query::HINT_INCLUDE_META_COLUMNS);
|
$this->query->getHint(Query::HINT_INCLUDE_META_COLUMNS);
|
||||||
|
|
||||||
foreach ($this->selectedClasses as $selectedClass) {
|
foreach ($this->selectedClasses as $selectedClass) {
|
||||||
$class = $selectedClass['class'];
|
$class = $selectedClass['class'];
|
||||||
@ -804,10 +804,7 @@ class SqlWalker implements TreeWalker
|
|||||||
$sqlParts = array();
|
$sqlParts = array();
|
||||||
|
|
||||||
foreach ($identificationVarDecls as $identificationVariableDecl) {
|
foreach ($identificationVarDecls as $identificationVariableDecl) {
|
||||||
$sql = $this->platform->appendLockHint(
|
$sql = $this->walkRangeVariableDeclaration($identificationVariableDecl->rangeVariableDeclaration);
|
||||||
$this->walkRangeVariableDeclaration($identificationVariableDecl->rangeVariableDeclaration),
|
|
||||||
$this->query->getHint(Query::HINT_LOCK_MODE)
|
|
||||||
);
|
|
||||||
|
|
||||||
foreach ($identificationVariableDecl->joins as $join) {
|
foreach ($identificationVariableDecl->joins as $join) {
|
||||||
$sql .= $this->walkJoin($join);
|
$sql .= $this->walkJoin($join);
|
||||||
@ -849,8 +846,11 @@ class SqlWalker implements TreeWalker
|
|||||||
$this->rootAliases[] = $dqlAlias;
|
$this->rootAliases[] = $dqlAlias;
|
||||||
}
|
}
|
||||||
|
|
||||||
$sql = $this->quoteStrategy->getTableName($class,$this->platform) . ' '
|
$sql = $this->platform->appendLockHint(
|
||||||
. $this->getSQLTableAlias($class->getTableName(), $dqlAlias);
|
$this->quoteStrategy->getTableName($class, $this->platform) . ' ' .
|
||||||
|
$this->getSQLTableAlias($class->getTableName(), $dqlAlias),
|
||||||
|
$this->query->getHint(Query::HINT_LOCK_MODE)
|
||||||
|
);
|
||||||
|
|
||||||
if ($class->isInheritanceTypeJoined()) {
|
if ($class->isInheritanceTypeJoined()) {
|
||||||
$sql .= $this->_generateClassTableInheritanceJoins($class, $dqlAlias);
|
$sql .= $this->_generateClassTableInheritanceJoins($class, $dqlAlias);
|
||||||
@ -904,7 +904,7 @@ class SqlWalker implements TreeWalker
|
|||||||
case ($assoc['type'] & ClassMetadata::TO_ONE):
|
case ($assoc['type'] & ClassMetadata::TO_ONE):
|
||||||
$conditions = array();
|
$conditions = array();
|
||||||
|
|
||||||
foreach ($assoc['joinColumns'] as $joinColumn) {
|
foreach ($assoc['joinColumns'] as $joinColumn) {
|
||||||
$quotedSourceColumn = $this->quoteStrategy->getJoinColumnName($joinColumn, $targetClass, $this->platform);
|
$quotedSourceColumn = $this->quoteStrategy->getJoinColumnName($joinColumn, $targetClass, $this->platform);
|
||||||
$quotedTargetColumn = $this->quoteStrategy->getReferencedJoinColumnName($joinColumn, $targetClass, $this->platform);
|
$quotedTargetColumn = $this->quoteStrategy->getReferencedJoinColumnName($joinColumn, $targetClass, $this->platform);
|
||||||
|
|
||||||
@ -1460,10 +1460,7 @@ class SqlWalker implements TreeWalker
|
|||||||
$sqlParts = array ();
|
$sqlParts = array ();
|
||||||
|
|
||||||
foreach ($identificationVarDecls as $subselectIdVarDecl) {
|
foreach ($identificationVarDecls as $subselectIdVarDecl) {
|
||||||
$sql = $this->platform->appendLockHint(
|
$sql = $this->walkRangeVariableDeclaration($subselectIdVarDecl->rangeVariableDeclaration);
|
||||||
$this->walkRangeVariableDeclaration($subselectIdVarDecl->rangeVariableDeclaration),
|
|
||||||
$this->query->getHint(Query::HINT_LOCK_MODE)
|
|
||||||
);
|
|
||||||
|
|
||||||
foreach ($subselectIdVarDecl->joins as $join) {
|
foreach ($subselectIdVarDecl->joins as $join) {
|
||||||
$sql .= $this->walkJoin($join);
|
$sql .= $this->walkJoin($join);
|
||||||
@ -1481,7 +1478,7 @@ class SqlWalker implements TreeWalker
|
|||||||
public function walkSimpleSelectClause($simpleSelectClause)
|
public function walkSimpleSelectClause($simpleSelectClause)
|
||||||
{
|
{
|
||||||
return 'SELECT' . ($simpleSelectClause->isDistinct ? ' DISTINCT' : '')
|
return 'SELECT' . ($simpleSelectClause->isDistinct ? ' DISTINCT' : '')
|
||||||
. $this->walkSimpleSelectExpression($simpleSelectClause->simpleSelectExpression);
|
. $this->walkSimpleSelectExpression($simpleSelectClause->simpleSelectExpression);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1620,7 +1617,7 @@ class SqlWalker implements TreeWalker
|
|||||||
public function walkAggregateExpression($aggExpression)
|
public function walkAggregateExpression($aggExpression)
|
||||||
{
|
{
|
||||||
return $aggExpression->functionName . '(' . ($aggExpression->isDistinct ? 'DISTINCT ' : '')
|
return $aggExpression->functionName . '(' . ($aggExpression->isDistinct ? 'DISTINCT ' : '')
|
||||||
. $this->walkSimpleArithmeticExpression($aggExpression->pathExpression) . ')';
|
. $this->walkSimpleArithmeticExpression($aggExpression->pathExpression) . ')';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1925,7 +1922,7 @@ class SqlWalker implements TreeWalker
|
|||||||
|
|
||||||
// join to target table
|
// join to target table
|
||||||
$sql .= $this->quoteStrategy->getJoinTableName($owningAssoc, $targetClass, $this->platform) . ' ' . $joinTableAlias
|
$sql .= $this->quoteStrategy->getJoinTableName($owningAssoc, $targetClass, $this->platform) . ' ' . $joinTableAlias
|
||||||
. ' INNER JOIN ' . $this->quoteStrategy->getTableName($targetClass, $this->platform) . ' ' . $targetTableAlias . ' ON ';
|
. ' INNER JOIN ' . $this->quoteStrategy->getTableName($targetClass, $this->platform) . ' ' . $targetTableAlias . ' ON ';
|
||||||
|
|
||||||
// join conditions
|
// join conditions
|
||||||
$joinColumns = $assoc['isOwningSide'] ? $joinTable['inverseJoinColumns'] : $joinTable['joinColumns'];
|
$joinColumns = $assoc['isOwningSide'] ? $joinTable['inverseJoinColumns'] : $joinTable['joinColumns'];
|
||||||
@ -2109,7 +2106,7 @@ class SqlWalker implements TreeWalker
|
|||||||
}
|
}
|
||||||
|
|
||||||
$sql .= ' BETWEEN ' . $this->walkArithmeticExpression($betweenExpr->leftBetweenExpression)
|
$sql .= ' BETWEEN ' . $this->walkArithmeticExpression($betweenExpr->leftBetweenExpression)
|
||||||
. ' AND ' . $this->walkArithmeticExpression($betweenExpr->rightBetweenExpression);
|
. ' AND ' . $this->walkArithmeticExpression($betweenExpr->rightBetweenExpression);
|
||||||
|
|
||||||
return $sql;
|
return $sql;
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,7 @@ namespace Doctrine\ORM\Query;
|
|||||||
* the AST to influence the final output produced by the last walker.
|
* the AST to influence the final output produced by the last walker.
|
||||||
*
|
*
|
||||||
* @author Roman Borschel <roman@code-factory.org>
|
* @author Roman Borschel <roman@code-factory.org>
|
||||||
* @since 2.0
|
* @since 2.0
|
||||||
*/
|
*/
|
||||||
class TreeWalkerChain implements TreeWalker
|
class TreeWalkerChain implements TreeWalker
|
||||||
{
|
{
|
||||||
@ -34,7 +34,7 @@ class TreeWalkerChain implements TreeWalker
|
|||||||
*
|
*
|
||||||
* @var TreeWalker[]
|
* @var TreeWalker[]
|
||||||
*/
|
*/
|
||||||
private $_walkers = array();
|
private $_walkers;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The original Query.
|
* The original Query.
|
||||||
@ -89,6 +89,7 @@ class TreeWalkerChain implements TreeWalker
|
|||||||
$this->_query = $query;
|
$this->_query = $query;
|
||||||
$this->_parserResult = $parserResult;
|
$this->_parserResult = $parserResult;
|
||||||
$this->_queryComponents = $queryComponents;
|
$this->_queryComponents = $queryComponents;
|
||||||
|
$this->_walkers = new TreeWalkerChainIterator($this, $query, $parserResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -100,7 +101,7 @@ class TreeWalkerChain implements TreeWalker
|
|||||||
*/
|
*/
|
||||||
public function addTreeWalker($walkerClass)
|
public function addTreeWalker($walkerClass)
|
||||||
{
|
{
|
||||||
$this->_walkers[] = new $walkerClass($this->_query, $this->_parserResult, $this->_queryComponents);
|
$this->_walkers[] = $walkerClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
126
lib/Doctrine/ORM/Query/TreeWalkerChainIterator.php
Normal file
126
lib/Doctrine/ORM/Query/TreeWalkerChainIterator.php
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* doctrine2
|
||||||
|
* User: shustrik
|
||||||
|
* Date: 2/6/14
|
||||||
|
* Time: 7:03 PM
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Doctrine\ORM\Query;
|
||||||
|
|
||||||
|
|
||||||
|
class TreeWalkerChainIterator implements \Iterator, \ArrayAccess
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var TreeWalker[]
|
||||||
|
*/
|
||||||
|
private $walkers = array();
|
||||||
|
/**
|
||||||
|
* @var TreeWalkerChain
|
||||||
|
*/
|
||||||
|
private $treeWalkerChain;
|
||||||
|
/**
|
||||||
|
* @var
|
||||||
|
*/
|
||||||
|
private $query;
|
||||||
|
/**
|
||||||
|
* @var
|
||||||
|
*/
|
||||||
|
private $parserResult;
|
||||||
|
|
||||||
|
public function __construct(TreeWalkerChain $treeWalkerChain, $query, $parserResult)
|
||||||
|
{
|
||||||
|
$this->treeWalkerChain = $treeWalkerChain;
|
||||||
|
$this->query = $query;
|
||||||
|
$this->parserResult = $parserResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
function rewind()
|
||||||
|
{
|
||||||
|
return reset($this->walkers);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
function current()
|
||||||
|
{
|
||||||
|
return $this->offsetGet(key($this->walkers));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
function key()
|
||||||
|
{
|
||||||
|
return key($this->walkers);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
function next()
|
||||||
|
{
|
||||||
|
next($this->walkers);
|
||||||
|
|
||||||
|
return $this->offsetGet(key($this->walkers));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
function valid()
|
||||||
|
{
|
||||||
|
return key($this->walkers) !== null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function offsetExists($offset)
|
||||||
|
{
|
||||||
|
return isset($this->walkers[$offset]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function offsetGet($offset)
|
||||||
|
{
|
||||||
|
if ($this->offsetExists($offset)) {
|
||||||
|
return new $this->walkers[$offset](
|
||||||
|
$this->query,
|
||||||
|
$this->parserResult,
|
||||||
|
$this->treeWalkerChain->getQueryComponents()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function offsetSet($offset, $value)
|
||||||
|
{
|
||||||
|
if (is_null($offset)) {
|
||||||
|
$this->walkers[] = $value;
|
||||||
|
} else {
|
||||||
|
$this->walkers[$offset] = $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function offsetUnset($offset)
|
||||||
|
{
|
||||||
|
if ($this->offsetExists($offset)) {
|
||||||
|
unset($this->walkers[$offset]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -42,7 +42,7 @@ class CustomTreeWalkersTest extends \Doctrine\Tests\OrmTestCase
|
|||||||
{
|
{
|
||||||
$query = $this->_em->createQuery($dqlToBeTested);
|
$query = $this->_em->createQuery($dqlToBeTested);
|
||||||
$query->setHint(Query::HINT_CUSTOM_TREE_WALKERS, $treeWalkers)
|
$query->setHint(Query::HINT_CUSTOM_TREE_WALKERS, $treeWalkers)
|
||||||
->useQueryCache(false);
|
->useQueryCache(false);
|
||||||
|
|
||||||
if ($outputWalker) {
|
if ($outputWalker) {
|
||||||
$query->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, $outputWalker);
|
$query->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, $outputWalker);
|
||||||
@ -96,6 +96,15 @@ class CustomTreeWalkersTest extends \Doctrine\Tests\OrmTestCase
|
|||||||
__NAMESPACE__ . '\\AddUnknownQueryComponentWalker'
|
__NAMESPACE__ . '\\AddUnknownQueryComponentWalker'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testSupportsSeveralHintsQueries()
|
||||||
|
{
|
||||||
|
$this->assertSqlGeneration(
|
||||||
|
'select u from Doctrine\Tests\Models\CMS\CmsUser u',
|
||||||
|
"SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3, c1_.id AS id4, c1_.country AS country5, c1_.zip AS zip6, c1_.city AS city7, c0_.email_id AS email_id8, c1_.user_id AS user_id9 FROM cms_users c0_ LEFT JOIN cms_addresses c1_ ON c0_.id = c1_.user_id WHERE c0_.id = 1",
|
||||||
|
array('Doctrine\Tests\ORM\Functional\CustomTreeWalkerJoin', 'Doctrine\Tests\ORM\Functional\CustomTreeWalker')
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class AddUnknownQueryComponentWalker extends Query\SqlWalker
|
class AddUnknownQueryComponentWalker extends Query\SqlWalker
|
||||||
@ -183,3 +192,43 @@ class CustomTreeWalker extends Query\TreeWalkerAdapter
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class CustomTreeWalkerJoin extends Query\TreeWalkerAdapter
|
||||||
|
{
|
||||||
|
public function walkSelectStatement(Query\AST\SelectStatement $selectStatement)
|
||||||
|
{
|
||||||
|
foreach ($selectStatement->fromClause->identificationVariableDeclarations as $identificationVariableDeclaration) {
|
||||||
|
if ($identificationVariableDeclaration->rangeVariableDeclaration->abstractSchemaName == 'Doctrine\Tests\Models\CMS\CmsUser') {
|
||||||
|
$identificationVariableDeclaration->joins[] = new Query\AST\Join(
|
||||||
|
Query\AST\Join::JOIN_TYPE_LEFT,
|
||||||
|
new Query\AST\JoinAssociationDeclaration(
|
||||||
|
new Query\AST\JoinAssociationPathExpression(
|
||||||
|
$identificationVariableDeclaration->rangeVariableDeclaration->aliasIdentificationVariable,
|
||||||
|
'address'
|
||||||
|
),
|
||||||
|
$identificationVariableDeclaration->rangeVariableDeclaration->aliasIdentificationVariable . 'a',
|
||||||
|
null
|
||||||
|
)
|
||||||
|
);
|
||||||
|
$selectStatement->selectClause->selectExpressions[] =
|
||||||
|
new Query\AST\SelectExpression(
|
||||||
|
$identificationVariableDeclaration->rangeVariableDeclaration->aliasIdentificationVariable . 'a',
|
||||||
|
null,
|
||||||
|
false
|
||||||
|
);
|
||||||
|
$meta1 = $this->_getQuery()->getEntityManager()->getClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
|
||||||
|
$meta = $this->_getQuery()->getEntityManager()->getClassMetadata('Doctrine\Tests\Models\CMS\CmsAddress');
|
||||||
|
$this->setQueryComponent($identificationVariableDeclaration->rangeVariableDeclaration->aliasIdentificationVariable . 'a',
|
||||||
|
array(
|
||||||
|
'metadata' => $meta,
|
||||||
|
'parent' => $identificationVariableDeclaration->rangeVariableDeclaration->aliasIdentificationVariable,
|
||||||
|
'relation' => $meta1->getAssociationMapping('address'),
|
||||||
|
'map' => null,
|
||||||
|
'nestingLevel' => 0,
|
||||||
|
'token' => null
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -2000,11 +2000,11 @@ class SelectSqlGenerationTest extends \Doctrine\Tests\OrmTestCase
|
|||||||
$connMock->setDatabasePlatform(new \Doctrine\DBAL\Platforms\SQLServerPlatform());
|
$connMock->setDatabasePlatform(new \Doctrine\DBAL\Platforms\SQLServerPlatform());
|
||||||
$this->assertSqlGeneration(
|
$this->assertSqlGeneration(
|
||||||
"SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE CONCAT(u.name, u.status, 's') = ?1",
|
"SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE CONCAT(u.name, u.status, 's') = ?1",
|
||||||
"SELECT c0_.id AS id0 FROM cms_users c0_ WITH (NOLOCK) WHERE (c0_.name + c0_.status + 's') = ?"
|
"SELECT c0_.id AS id0 FROM cms_users c0_ WHERE (c0_.name + c0_.status + 's') = ?"
|
||||||
);
|
);
|
||||||
$this->assertSqlGeneration(
|
$this->assertSqlGeneration(
|
||||||
"SELECT CONCAT(u.id, u.name, u.status) FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = ?1",
|
"SELECT CONCAT(u.id, u.name, u.status) FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = ?1",
|
||||||
"SELECT (c0_.id + c0_.name + c0_.status) AS sclr0 FROM cms_users c0_ WITH (NOLOCK) WHERE c0_.id = ?"
|
"SELECT (c0_.id + c0_.name + c0_.status) AS sclr0 FROM cms_users c0_ WHERE c0_.id = ?"
|
||||||
);
|
);
|
||||||
|
|
||||||
$connMock->setDatabasePlatform($orgPlatform);
|
$connMock->setDatabasePlatform($orgPlatform);
|
||||||
|
@ -1,249 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* Native PHPUnit Task
|
|
||||||
*
|
|
||||||
* LICENSE
|
|
||||||
*
|
|
||||||
* This source file is subject to the new BSD license that is bundled
|
|
||||||
* with this package in the file LICENSE.txt.
|
|
||||||
* If you did not receive a copy of the license and are unable to
|
|
||||||
* obtain it through the world-wide-web, please send an email
|
|
||||||
* to kontakt@beberlei.de so I can send you a copy immediately.
|
|
||||||
*/
|
|
||||||
|
|
||||||
require_once 'PHPUnit/Framework.php';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A more flexible and powerful PHPUnit Task than the native Phing one.
|
|
||||||
*
|
|
||||||
* Plus forward compatibility for PHPUnit 3.5 and later is ensured by using the PHPUnit Test Runner instead of implementing one.
|
|
||||||
*
|
|
||||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
|
||||||
*/
|
|
||||||
class NativePhpunitTask extends Task
|
|
||||||
{
|
|
||||||
private $test;
|
|
||||||
private $testfile;
|
|
||||||
private $testdirectory;
|
|
||||||
private $configuration = null;
|
|
||||||
private $coverageClover = null;
|
|
||||||
private $junitlogfile = null;
|
|
||||||
private $haltonfailure = true;
|
|
||||||
private $haltonerror = true;
|
|
||||||
|
|
||||||
public function setTestdirectory($directory) {
|
|
||||||
$this->testdirectory = $directory;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setTest($test) {
|
|
||||||
$this->test = $test;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setTestfile($testfile) {
|
|
||||||
$this->testfile = $testfile;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setJunitlogfile($junitlogfile) {
|
|
||||||
if (strlen($junitlogfile) == 0) {
|
|
||||||
$junitlogfile = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->junitlogfile = $junitlogfile;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setConfiguration($configuration) {
|
|
||||||
if (strlen($configuration) == 0) {
|
|
||||||
$configuration = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->configuration = $configuration;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setCoverageClover($coverageClover) {
|
|
||||||
if (strlen($coverageClover) == 0) {
|
|
||||||
$coverageClover = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->coverageClover = $coverageClover;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setHaltonfailure($haltonfailures) {
|
|
||||||
$this->haltonfailure = $haltonfailures;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setHaltonerror($haltonerrors) {
|
|
||||||
$this->haltonerror = $haltonerrors;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function init()
|
|
||||||
{
|
|
||||||
require_once "PHPUnit/Runner/Version.php";
|
|
||||||
$version = PHPUnit_Runner_Version::id();
|
|
||||||
|
|
||||||
if (version_compare($version, '3.4.0') < 0)
|
|
||||||
{
|
|
||||||
throw new BuildException("NativePHPUnitTask requires PHPUnit version >= 3.2.0", $this->getLocation());
|
|
||||||
}
|
|
||||||
|
|
||||||
require_once 'PHPUnit/Util/Filter.php';
|
|
||||||
|
|
||||||
// point PHPUnit_MAIN_METHOD define to non-existing method
|
|
||||||
if (!defined('PHPUnit_MAIN_METHOD'))
|
|
||||||
{
|
|
||||||
define('PHPUnit_MAIN_METHOD', 'PHPUnitTask::undefined');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function main()
|
|
||||||
{
|
|
||||||
if (!is_dir(realpath($this->testdirectory))) {
|
|
||||||
throw new BuildException("NativePHPUnitTask requires a Test Directory path given, '".$this->testdirectory."' given.");
|
|
||||||
}
|
|
||||||
set_include_path(realpath($this->testdirectory) . PATH_SEPARATOR . get_include_path());
|
|
||||||
|
|
||||||
$printer = new NativePhpunitPrinter();
|
|
||||||
|
|
||||||
$arguments = array(
|
|
||||||
'configuration' => $this->configuration,
|
|
||||||
'coverageClover' => $this->coverageClover,
|
|
||||||
'junitLogfile' => $this->junitlogfile,
|
|
||||||
'printer' => $printer,
|
|
||||||
);
|
|
||||||
|
|
||||||
require_once "PHPUnit/TextUI/TestRunner.php";
|
|
||||||
$runner = new PHPUnit_TextUI_TestRunner();
|
|
||||||
$suite = $runner->getTest($this->test, $this->testfile, true);
|
|
||||||
|
|
||||||
try {
|
|
||||||
$result = $runner->doRun($suite, $arguments);
|
|
||||||
/* @var $result PHPUnit_Framework_TestResult */
|
|
||||||
|
|
||||||
if ( ($this->haltonfailure && $result->failureCount() > 0) || ($this->haltonerror && $result->errorCount() > 0) ) {
|
|
||||||
throw new BuildException("PHPUnit: ".$result->failureCount()." Failures and ".$result->errorCount()." Errors, ".
|
|
||||||
"last failure message: ".$printer->getMessages());
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->log("PHPUnit Success: ".count($result->passed())." tests passed, no ".
|
|
||||||
"failures (".$result->skippedCount()." skipped, ".$result->notImplementedCount()." not implemented)");
|
|
||||||
|
|
||||||
// Hudson for example doesn't like the backslash in class names
|
|
||||||
if (file_exists($this->coverageClover)) {
|
|
||||||
$this->log("Generated Clover Coverage XML to: ".$this->coverageClover);
|
|
||||||
$content = file_get_contents($this->coverageClover);
|
|
||||||
$content = str_replace("\\", ".", $content);
|
|
||||||
file_put_contents($this->coverageClover, $content);
|
|
||||||
unset($content);
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch(\Exception $e) {
|
|
||||||
throw new BuildException("NativePhpunitTask failed: ".$e->getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class NativePhpunitPrinter extends PHPUnit_Util_Printer implements PHPUnit_Framework_TestListener
|
|
||||||
{
|
|
||||||
private $_messages = array();
|
|
||||||
|
|
||||||
public function write($buffer)
|
|
||||||
{
|
|
||||||
// do nothing
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getMessages()
|
|
||||||
{
|
|
||||||
return $this->_messages;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An error occurred.
|
|
||||||
*
|
|
||||||
* @param PHPUnit_Framework_Test $test
|
|
||||||
* @param Exception $e
|
|
||||||
* @param float $time
|
|
||||||
*/
|
|
||||||
public function addError(PHPUnit_Framework_Test $test, Exception $e, $time)
|
|
||||||
{
|
|
||||||
$this->_messages[] = "Test ERROR: ".$test->getName().": ".$e->getMessage();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A failure occurred.
|
|
||||||
*
|
|
||||||
* @param PHPUnit_Framework_Test $test
|
|
||||||
* @param PHPUnit_Framework_AssertionFailedError $e
|
|
||||||
* @param float $time
|
|
||||||
*/
|
|
||||||
public function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time)
|
|
||||||
{
|
|
||||||
$this->_messages[] = "Test FAILED: ".$test->getName().": ".$e->getMessage();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Incomplete test.
|
|
||||||
*
|
|
||||||
* @param PHPUnit_Framework_Test $test
|
|
||||||
* @param Exception $e
|
|
||||||
* @param float $time
|
|
||||||
*/
|
|
||||||
public function addIncompleteTest(PHPUnit_Framework_Test $test, Exception $e, $time)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Skipped test.
|
|
||||||
*
|
|
||||||
* @param PHPUnit_Framework_Test $test
|
|
||||||
* @param Exception $e
|
|
||||||
* @param float $time
|
|
||||||
* @since Method available since Release 3.0.0
|
|
||||||
*/
|
|
||||||
public function addSkippedTest(PHPUnit_Framework_Test $test, Exception $e, $time)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A test suite started.
|
|
||||||
*
|
|
||||||
* @param PHPUnit_Framework_TestSuite $suite
|
|
||||||
* @since Method available since Release 2.2.0
|
|
||||||
*/
|
|
||||||
public function startTestSuite(PHPUnit_Framework_TestSuite $suite)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A test suite ended.
|
|
||||||
*
|
|
||||||
* @param PHPUnit_Framework_TestSuite $suite
|
|
||||||
* @since Method available since Release 2.2.0
|
|
||||||
*/
|
|
||||||
public function endTestSuite(PHPUnit_Framework_TestSuite $suite)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A test started.
|
|
||||||
*
|
|
||||||
* @param PHPUnit_Framework_Test $test
|
|
||||||
*/
|
|
||||||
public function startTest(PHPUnit_Framework_Test $test)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A test ended.
|
|
||||||
*
|
|
||||||
* @param PHPUnit_Framework_Test $test
|
|
||||||
* @param float $time
|
|
||||||
*/
|
|
||||||
public function endTest(PHPUnit_Framework_Test $test, $time)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user