Skip to content

Commit

Permalink
[DDC-551] Initial support for filters in the JoinedSubclassPersister
Browse files Browse the repository at this point in the history
Still some things to do.
  • Loading branch information
asm89 committed Nov 30, 2011
1 parent 4c94a7c commit f6d5f04
Show file tree
Hide file tree
Showing 4 changed files with 125 additions and 7 deletions.
2 changes: 1 addition & 1 deletion lib/Doctrine/ORM/Persisters/BasicEntityPersister.php
Expand Up @@ -1584,7 +1584,7 @@ public function getSQLColumnAlias($columnName)
);
}

private function generateFilterConditionSQL(ClassMetadata $targetEntity, $targetTableAlias)
private function generateFilterConditionSQL(ClassMetadata $targetEntity, $targetTableAlias, $targetTable = '')
{
$filterSql = '';

Expand Down
31 changes: 31 additions & 0 deletions lib/Doctrine/ORM/Persisters/JoinedSubclassPersister.php
Expand Up @@ -328,8 +328,17 @@ protected function _getSelectEntitiesSQL(array $criteria, $assoc = null, $lockMo

$joinSql .= $baseTableAlias . '.' . $idColumn . ' = ' . $tableAlias . '.' . $idColumn;
}

// Filters for each parent table
$filterSql = $this->generateFilterConditionSQL($parentClass, $tableAlias, $parentClass->table['name']);
if('' !== $filterSql) {
if (!$first) $joinSql .= ' AND ';
$joinSql .= $filterSql;
}
}

//@todo: filters for the sub tables of childs

// OUTER JOIN sub tables
foreach ($this->_class->subClasses as $subClassName) {
$subClass = $this->_em->getClassMetadata($subClassName);
Expand Down Expand Up @@ -389,6 +398,13 @@ protected function _getSelectEntitiesSQL(array $criteria, $assoc = null, $lockMo
$lockSql = ' ' . $this->_platform->getWriteLockSql();
}

// Filters for the base table
$filterSql = $this->generateFilterConditionSQL($this->_class, $baseTableAlias, $this->_class->table['name']);
if('' !== $filterSql) {
if($conditionSql) $conditionSql .= ' AND ';
$conditionSql .= $filterSql;
}

return $this->_platform->modifyLimitQuery('SELECT ' . $this->_selectColumnListSql
. ' FROM ' . $this->_class->getQuotedTableName($this->_platform) . ' ' . $baseTableAlias
. $joinSql
Expand Down Expand Up @@ -473,4 +489,19 @@ protected function assignDefaultVersionValue($entity, $id)
$value = $this->fetchVersionValue($this->_getVersionedClassMetadata(), $id);
$this->_class->setFieldValue($entity, $this->_class->versionField, $value);
}

private function generateFilterConditionSQL(ClassMetadata $targetEntity, $targetTableAlias, $targetTable = '')
{
$filterSql = '';

$first = true;
foreach($this->_em->getFilters()->getEnabledFilters() as $filter) {
if("" !== $filterExpr = $filter->addFilterConstraint($targetEntity, $targetTableAlias, $targetTable)) {
if ( ! $first) $filterSql .= ' AND '; else $first = false;
$filterSql .= '(' . $filterExpr . ')';
}
}

return $filterSql;
}
}
2 changes: 1 addition & 1 deletion lib/Doctrine/ORM/Query/Filter/SQLFilter.php
Expand Up @@ -73,5 +73,5 @@ final public function __toString()
/**
* @return string The constraint if there is one, empty string otherwise
*/
abstract public function addFilterConstraint(ClassMetadata $targetEntity, $targetTableAlias);
abstract public function addFilterConstraint(ClassMetadata $targetEntity, $targetTableAlias, $targetTable = '');
}
97 changes: 92 additions & 5 deletions tests/Doctrine/Tests/ORM/Functional/SQLFilterTest.php
Expand Up @@ -15,6 +15,10 @@
use Doctrine\Tests\Models\CMS\CmsArticle;
use Doctrine\Tests\Models\CMS\CmsComment;

use Doctrine\Tests\Models\Company\CompanyPerson;
use Doctrine\Tests\Models\Company\CompanyManager;
use Doctrine\Tests\Models\Company\CompanyEmployee;

require_once __DIR__ . '/../../TestInit.php';

/**
Expand All @@ -30,6 +34,7 @@ class SQLFilterTest extends \Doctrine\Tests\OrmFunctionalTestCase
public function setUp()
{
$this->useModelSet('cms');
$this->useModelSet('company');
parent::setUp();
}

Expand Down Expand Up @@ -444,6 +449,44 @@ public function testManyToMany_ExtraLazySliceWithFilter()
$this->assertEquals(1, count($user->groups->slice(0,10)));
}

public function testJoinSubclassPersister_FilterOnBaseTable()
{
$this->loadCompanyFixtureData();
$this->assertEquals(2, count($this->_em->getRepository('Doctrine\Tests\Models\Company\CompanyManager')->findAll()));

// Enable the filter
$conf = $this->_em->getConfiguration();
$conf->addFilter("manager_title", "\Doctrine\Tests\ORM\Functional\CompanyManagerTitleFilter");
$this->_em->getFilters()
->enable("manager_title")
->setParameter("title", "devlead", \Doctrine\DBAL\Types\Type::getType(\Doctrine\DBAL\Types\Type::STRING)->getBindingType());

$this->_em->getConnection()->getConfiguration()->setSQLLogger(new \Doctrine\DBAL\Logging\EchoSQLLogger);

$managers = $this->_em->getRepository('Doctrine\Tests\Models\Company\CompanyManager')->findAll();
$this->assertEquals(1, count($managers));
$this->assertEquals("Guilherme", $managers[0]->getName());
}

public function testJoinSubclassPersister_FilterOnParentTable()
{
$this->loadCompanyFixtureData();
$this->assertEquals(2, count($this->_em->getRepository('Doctrine\Tests\Models\Company\CompanyManager')->findAll()));

// Enable the filter
$conf = $this->_em->getConfiguration();
$conf->addFilter("employee_department", "\Doctrine\Tests\ORM\Functional\CompanyEmployeeDepartmentFilter");
$this->_em->getFilters()
->enable("employee_department")
->setParameter("department", "parsers", \Doctrine\DBAL\Types\Type::getType(\Doctrine\DBAL\Types\Type::STRING)->getBindingType());

$this->_em->getConnection()->getConfiguration()->setSQLLogger(new \Doctrine\DBAL\Logging\EchoSQLLogger);

$managers = $this->_em->getRepository('Doctrine\Tests\Models\Company\CompanyManager')->findAll();
$this->assertEquals(1, count($managers));
$this->assertEquals("Guilherme", $managers[0]->getName());
}

private function loadFixtureData()
{
$user = new CmsUser;
Expand Down Expand Up @@ -507,11 +550,31 @@ private function loadFixtureData()
$this->groupId = $group->id;
$this->groupId2 = $group2->id;
}

private function loadCompanyFixtureData()
{
$manager = new CompanyManager;
$manager->setName('Roman');
$manager->setTitle('testlead');
$manager->setSalary(42);
$manager->setDepartment('persisters');

$manager2 = new CompanyManager;
$manager2->setName('Guilherme');
$manager2->setTitle('devlead');
$manager2->setSalary(42);
$manager2->setDepartment('parsers');

$this->_em->persist($manager);
$this->_em->persist($manager2);
$this->_em->flush();
$this->_em->clear();
}
}

class MySoftDeleteFilter extends SQLFilter
{
public function addFilterConstraint(ClassMetadata $targetEntity, $targetTableAlias)
public function addFilterConstraint(ClassMetadata $targetEntity, $targetTableAlias, $targetTable = '')
{
if ($targetEntity->name != "MyEntity\SoftDeleteNewsItem") {
return "";
Expand All @@ -523,7 +586,7 @@ public function addFilterConstraint(ClassMetadata $targetEntity, $targetTableAli

class MyLocaleFilter extends SQLFilter
{
public function addFilterConstraint(ClassMetadata $targetEntity, $targetTableAlias)
public function addFilterConstraint(ClassMetadata $targetEntity, $targetTableAlias, $targetTable = '')
{
if (!in_array("LocaleAware", $targetEntity->reflClass->getInterfaceNames())) {
return "";
Expand All @@ -535,7 +598,7 @@ public function addFilterConstraint(ClassMetadata $targetEntity, $targetTableAli

class CMSCountryFilter extends SQLFilter
{
public function addFilterConstraint(ClassMetadata $targetEntity, $targetTableAlias)
public function addFilterConstraint(ClassMetadata $targetEntity, $targetTableAlias, $targetTable = '')
{
if ($targetEntity->name != "Doctrine\Tests\Models\CMS\CmsAddress") {
return "";
Expand All @@ -547,7 +610,7 @@ public function addFilterConstraint(ClassMetadata $targetEntity, $targetTableAli

class CMSGroupPrefixFilter extends SQLFilter
{
public function addFilterConstraint(ClassMetadata $targetEntity, $targetTableAlias)
public function addFilterConstraint(ClassMetadata $targetEntity, $targetTableAlias, $targetTable = '')
{
if ($targetEntity->name != "Doctrine\Tests\Models\CMS\CmsGroup") {
return "";
Expand All @@ -558,7 +621,7 @@ public function addFilterConstraint(ClassMetadata $targetEntity, $targetTableAli
}
class CMSArticleTopicFilter extends SQLFilter
{
public function addFilterConstraint(ClassMetadata $targetEntity, $targetTableAlias)
public function addFilterConstraint(ClassMetadata $targetEntity, $targetTableAlias, $targetTable = '')
{
if ($targetEntity->name != "Doctrine\Tests\Models\CMS\CmsArticle") {
return "";
Expand All @@ -567,3 +630,27 @@ public function addFilterConstraint(ClassMetadata $targetEntity, $targetTableAli
return $targetTableAlias.'.topic = ' . $this->getParameter('topic'); // getParam uses connection to quote the value.
}
}

class CompanyManagerTitleFilter extends SQLFilter
{
public function addFilterConstraint(ClassMetadata $targetEntity, $targetTableAlias, $targetTable = '')
{
if ($targetEntity->name != "Doctrine\Tests\Models\Company\CompanyManager") {
return "";
}

return $targetTableAlias.'.title = ' . $this->getParameter('title'); // getParam uses connection to quote the value.
}
}

class CompanyEmployeeDepartmentFilter extends SQLFilter
{
public function addFilterConstraint(ClassMetadata $targetEntity, $targetTableAlias, $targetTable = '')
{
if ($targetEntity->name != "Doctrine\Tests\Models\Company\CompanyEmployee") {
return "";
}

return $targetTableAlias.'.department = ' . $this->getParameter('department'); // getParam uses connection to quote the value.
}
}

0 comments on commit f6d5f04

Please sign in to comment.