-
Notifications
You must be signed in to change notification settings - Fork 2.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[DDC-551] Add SQLFilter functionality #210
Changes from 32 commits
a85902b
b867744
277fc75
d1908f7
4cf63a4
4266ab7
afd7a54
6163d9d
e3dcfa8
6cf7bdc
3b1ddb0
2653d73
3800581
ed0fb4e
63a3fb5
097d573
58b381b
07ce409
9ccce8e
53055f1
68027e1
be48821
4c94a7c
f6d5f04
bf1cc29
e98c775
752b502
4c84297
3b7d16c
04635ad
e8d3006
f4663f4
efe7a01
5e91f0c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -27,7 +27,8 @@ | |
Doctrine\ORM\Mapping\ClassMetadata, | ||
Doctrine\ORM\Mapping\ClassMetadataFactory, | ||
Doctrine\ORM\Query\ResultSetMapping, | ||
Doctrine\ORM\Proxy\ProxyFactory; | ||
Doctrine\ORM\Proxy\ProxyFactory, | ||
Doctrine\ORM\Query\FilterCollection; | ||
|
||
/** | ||
* The EntityManager is the central access point to ORM functionality. | ||
|
@@ -110,6 +111,13 @@ class EntityManager implements ObjectManager | |
*/ | ||
private $closed = false; | ||
|
||
/** | ||
* Collection of query filters. | ||
* | ||
* @var Doctrine\ORM\Query\FilterCollection | ||
*/ | ||
private $filterCollection; | ||
|
||
/** | ||
* Creates a new EntityManager that operates on the given database connection | ||
* and uses the given Configuration and EventManager implementations. | ||
|
@@ -788,4 +796,39 @@ public static function create($conn, Configuration $config, EventManager $eventM | |
|
||
return new EntityManager($conn, $config, $conn->getEventManager()); | ||
} | ||
|
||
/** | ||
* Gets the enabled filters. | ||
* | ||
* @return FilterCollection The active filter collection. | ||
*/ | ||
public function getFilters() | ||
{ | ||
if(null === $this->filterCollection) { | ||
$this->filterCollection = new FilterCollection($this); | ||
} | ||
|
||
return $this->filterCollection; | ||
} | ||
|
||
/** | ||
* Checks whether the state of the filter collection is clean. | ||
* | ||
* @return boolean True, iff the filter collection is clean. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. typo here |
||
*/ | ||
public function isFiltersStateClean() | ||
{ | ||
return null === $this->filterCollection | ||
|| $this->filterCollection->isClean(); | ||
} | ||
|
||
/** | ||
* Checks whether the Entity Manager has filters. | ||
* | ||
* @return True, iff the EM has a filter collection. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same here |
||
*/ | ||
public function hasFilters() | ||
{ | ||
return null !== $this->filterCollection; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -72,6 +72,7 @@ | |
* @author Roman Borschel <roman@code-factory.org> | ||
* @author Giorgio Sironi <piccoloprincipeazzurro@gmail.com> | ||
* @author Benjamin Eberlei <kontakt@beberlei.de> | ||
* @author Alexander <iam.asm89@gmail.com> | ||
* @since 2.0 | ||
*/ | ||
class BasicEntityPersister | ||
|
@@ -900,9 +901,16 @@ protected function _getSelectEntitiesSQL(array $criteria, $assoc = null, $lockMo | |
$lockSql = ' ' . $this->_platform->getWriteLockSql(); | ||
} | ||
|
||
$alias = $this->_getSQLTableAlias($this->_class->name); | ||
|
||
if('' !== $filterSql = $this->generateFilterConditionSQL($this->_class, $alias)) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. space needed here and next line There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. they are missing in many other places |
||
if($conditionSql) $conditionSql .= ' AND '; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you should always use braces for if statements, even when there is only one line |
||
$conditionSql .= $filterSql; | ||
} | ||
|
||
return $this->_platform->modifyLimitQuery('SELECT ' . $this->_getSelectColumnListSQL() | ||
. $this->_platform->appendLockHint(' FROM ' . $this->_class->getQuotedTableName($this->_platform) . ' ' | ||
. $this->_getSQLTableAlias($this->_class->name), $lockMode) | ||
. $alias, $lockMode) | ||
. $this->_selectJoinSql . $joinSql | ||
. ($conditionSql ? ' WHERE ' . $conditionSql : '') | ||
. $orderBySql, $limit, $offset) | ||
|
@@ -1018,10 +1026,16 @@ protected function _getSelectColumnListSQL() | |
if ( ! $first) { | ||
$this->_selectJoinSql .= ' AND '; | ||
} | ||
$tableAlias = $this->_getSQLTableAlias($assoc['targetEntity'], $assocAlias); | ||
$this->_selectJoinSql .= $this->_getSQLTableAlias($assoc['sourceEntity']) . '.' . $sourceCol . ' = ' | ||
. $this->_getSQLTableAlias($assoc['targetEntity'], $assocAlias) . '.' . $targetCol; | ||
. $tableAlias . '.' . $targetCol; | ||
$first = false; | ||
} | ||
|
||
// Add filter SQL | ||
if('' !== $filterSql = $this->generateFilterConditionSQL($eagerEntity, $tableAlias)) { | ||
$this->_selectJoinSql .= ' AND ' . $filterSql; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
} | ||
} else { | ||
$eagerEntity = $this->_em->getClassMetadata($assoc['targetEntity']); | ||
$owningAssoc = $eagerEntity->getAssociationMapping($assoc['mappedBy']); | ||
|
@@ -1267,10 +1281,10 @@ public function lock(array $criteria, $lockMode) | |
* | ||
* @return string | ||
*/ | ||
protected function getLockTablesSql() | ||
protected function getLockTablesSql($alias = null) | ||
{ | ||
return 'FROM ' . $this->_class->getQuotedTableName($this->_platform) . ' ' | ||
. $this->_getSQLTableAlias($this->_class->name); | ||
. (null !== $alias ? $alias : $this->_getSQLTableAlias($this->_class->name)); | ||
} | ||
|
||
/** | ||
|
@@ -1521,10 +1535,16 @@ public function exists($entity, array $extraConditions = array()) | |
$criteria = array_merge($criteria, $extraConditions); | ||
} | ||
|
||
$alias = $this->_getSQLTableAlias($this->_class->name); | ||
|
||
$sql = 'SELECT 1 ' | ||
. $this->getLockTablesSql() | ||
. $this->getLockTablesSql($alias) | ||
. ' WHERE ' . $this->_getSelectConditionSQL($criteria); | ||
|
||
if('' !== $filterSql = $this->generateFilterConditionSQL($this->_class, $alias)) { | ||
$sql .= ' AND ' . $filterSql; | ||
} | ||
|
||
list($params, $types) = $this->expandParameters($criteria); | ||
|
||
return (bool) $this->_conn->fetchColumn($sql, $params); | ||
|
@@ -1562,4 +1582,25 @@ public function getSQLColumnAlias($columnName) | |
substr($columnName . $this->_sqlAliasCounter++, -$this->_platform->getMaxIdentifierLength()) | ||
); | ||
} | ||
|
||
/** | ||
* Generates the filter SQL for a given entity and table alias. | ||
* | ||
* @param ClassMetadata $targetEntity Metadata of the target entity. | ||
* @param string $targetTableAlias The table alias of the joined/selected table. | ||
* | ||
* @return string The SQL query part to add to a query. | ||
*/ | ||
protected function generateFilterConditionSQL(ClassMetadata $targetEntity, $targetTableAlias) | ||
{ | ||
$filterClauses = array(); | ||
|
||
foreach($this->_em->getFilters()->getEnabledFilters() as $filter) { | ||
if('' !== $filterExpr = $filter->addFilterConstraint($targetEntity, $targetTableAlias)) { | ||
$filterClauses[] = '(' . $filterExpr . ')'; | ||
} | ||
} | ||
|
||
return implode(' AND ', $filterClauses); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -31,6 +31,7 @@ | |
* | ||
* @author Roman Borschel <roman@code-factory.org> | ||
* @author Benjamin Eberlei <kontakt@beberlei.de> | ||
* @author Alexander <iam.asm89@gmail.com> | ||
* @since 2.0 | ||
* @see http://martinfowler.com/eaaCatalog/classTableInheritance.html | ||
*/ | ||
|
@@ -327,6 +328,13 @@ protected function _getSelectEntitiesSQL(array $criteria, $assoc = null, $lockMo | |
if ($first) $first = false; else $joinSql .= ' AND '; | ||
|
||
$joinSql .= $baseTableAlias . '.' . $idColumn . ' = ' . $tableAlias . '.' . $idColumn; | ||
|
||
if($parentClass->name === $this->_class->rootEntityName) { | ||
// Add filters on the root class | ||
if('' !== $filterSql = $this->generateFilterConditionSQL($parentClass, $tableAlias)) { | ||
$joinSql .= ' AND ' . $filterSql; | ||
} | ||
} | ||
} | ||
} | ||
|
||
|
@@ -374,6 +382,14 @@ protected function _getSelectEntitiesSQL(array $criteria, $assoc = null, $lockMo | |
|
||
$conditionSql = $this->_getSelectConditionSQL($criteria, $assoc); | ||
|
||
// If the current class in the root entity, add the filters | ||
if($this->_class->name === $this->_class->rootEntityName) { | ||
if('' !== $filterSql = $this->generateFilterConditionSQL($this->_class, $baseTableAlias)) { | ||
if($conditionSql) $conditionSql .= ' AND '; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. curly braces are needed here too |
||
$conditionSql .= $filterSql; | ||
} | ||
} | ||
|
||
$orderBy = ($assoc !== null && isset($assoc['orderBy'])) ? $assoc['orderBy'] : $orderBy; | ||
$orderBySql = $orderBy ? $this->_getOrderBySQL($orderBy, $baseTableAlias) : ''; | ||
|
||
|
@@ -401,10 +417,10 @@ protected function _getSelectEntitiesSQL(array $criteria, $assoc = null, $lockMo | |
* | ||
* @return string | ||
*/ | ||
public function getLockTablesSql() | ||
public function getLockTablesSql($alias = null) | ||
{ | ||
$idColumns = $this->_class->getIdentifierColumnNames(); | ||
$baseTableAlias = $this->_getSQLTableAlias($this->_class->name); | ||
$baseTableAlias = null !== $alias ? $alias : $this->_getSQLTableAlias($this->_class->name); | ||
|
||
// INNER JOIN parent tables | ||
$joinSql = ''; | ||
|
@@ -473,4 +489,5 @@ protected function assignDefaultVersionValue($entity, $id) | |
$value = $this->fetchVersionValue($this->_getVersionedClassMetadata(), $id); | ||
$this->_class->setFieldValue($entity, $this->_class->versionField, $value); | ||
} | ||
|
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you should add a space after the
if