Commit a9f7ec32 authored by Tymoteusz Motylewski's avatar Tymoteusz Motylewski Committed by Christian Kuhn
Browse files

[BUGFIX] Make Extbase pagination work with QueryBuilder queries

Now you can pass a query built by QueryBuilder to $query->statement(),
and use the QueryResult for pagination.

So inside repository you can create custom query like:

$queryBuilder->select('*')->...
$query = $this->createQuery();
$query->statement($queryBuilder);
return $query->execute();

and pass the result to paginate ViewHelper.

Resolves: #81887
Releases: master, 8.7
Change-Id: Ia00f673039362afaa8ef7232ba4bc89c520d5a46
Reviewed-on: https://review.typo3.org/53409

Reviewed-by: Anja Leichsenring's avatarAnja Leichsenring <aleichsenring@ab-softlab.de>
Tested-by: default avatarTYPO3com <no-reply@typo3.com>
Reviewed-by: Andreas Fernandez's avatarAndreas Fernandez <typo3@scripting-base.de>
Tested-by: Joerg Kummer's avatarJoerg Kummer <typo3@enobe.de>
Reviewed-by: default avatarStefan Neufeind <typo3.neufeind@speedpartner.de>
Reviewed-by: Wouter Wolters's avatarWouter Wolters <typo3@wouterwolters.nl>
Tested-by: Anja Leichsenring's avatarAnja Leichsenring <aleichsenring@ab-softlab.de>
Reviewed-by: Christian Kuhn's avatarChristian Kuhn <lolli@schwarzbu.ch>
Tested-by: Christian Kuhn's avatarChristian Kuhn <lolli@schwarzbu.ch>
parent d34522e5
...@@ -353,12 +353,19 @@ class Typo3DbBackend implements BackendInterface, SingletonInterface ...@@ -353,12 +353,19 @@ class Typo3DbBackend implements BackendInterface, SingletonInterface
public function getObjectDataByQuery(QueryInterface $query) public function getObjectDataByQuery(QueryInterface $query)
{ {
$statement = $query->getStatement(); $statement = $query->getStatement();
if ($statement instanceof Qom\Statement) { if ($statement instanceof Qom\Statement
&& !$statement->getStatement() instanceof QueryBuilder
) {
$rows = $this->getObjectDataByRawQuery($statement); $rows = $this->getObjectDataByRawQuery($statement);
} else { } else {
$queryParser = $this->objectManager->get(Typo3DbQueryParser::class); $queryParser = $this->objectManager->get(Typo3DbQueryParser::class);
$queryBuilder = $queryParser if ($statement instanceof Qom\Statement
->convertQueryToDoctrineQueryBuilder($query); && $statement->getStatement() instanceof QueryBuilder
) {
$queryBuilder = $statement->getStatement();
} else {
$queryBuilder = $queryParser->convertQueryToDoctrineQueryBuilder($query);
}
$selectParts = $queryBuilder->getQueryPart('select'); $selectParts = $queryBuilder->getQueryPart('select');
if ($queryParser->isDistinctQuerySuggested() && !empty($selectParts)) { if ($queryParser->isDistinctQuerySuggested() && !empty($selectParts)) {
$selectParts[0] = 'DISTINCT ' . $selectParts[0]; $selectParts[0] = 'DISTINCT ' . $selectParts[0];
......
...@@ -138,6 +138,11 @@ class Typo3DbQueryParser ...@@ -138,6 +138,11 @@ class Typo3DbQueryParser
$this->tableAliasMap = []; $this->tableAliasMap = [];
$this->unionTableAliasCache = []; $this->unionTableAliasCache = [];
$this->tableName = ''; $this->tableName = '';
if ($query->getStatement() && $query->getStatement()->getStatement() instanceof QueryBuilder) {
$this->queryBuilder = clone $query->getStatement()->getStatement();
return $this->queryBuilder;
}
// Find the right table name // Find the right table name
$source = $query->getSource(); $source = $query->getSource();
$this->initializeQueryBuilder($source); $this->initializeQueryBuilder($source);
......
...@@ -76,6 +76,7 @@ class Typo3DbQueryParserTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestC ...@@ -76,6 +76,7 @@ class Typo3DbQueryParserTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestC
$sourceProphecy = $this->prophesize(SourceInterface::class); $sourceProphecy = $this->prophesize(SourceInterface::class);
$queryProphecy->getSource()->willReturn($sourceProphecy->reveal()); $queryProphecy->getSource()->willReturn($sourceProphecy->reveal());
$queryProphecy->getOrderings()->willReturn([]); $queryProphecy->getOrderings()->willReturn([]);
$queryProphecy->getStatement()->willReturn(null);
// Test part: getConstraint returns no constraint object, andWhere() should not be called // Test part: getConstraint returns no constraint object, andWhere() should not be called
$queryProphecy->getConstraint()->willReturn(null); $queryProphecy->getConstraint()->willReturn(null);
...@@ -102,6 +103,7 @@ class Typo3DbQueryParserTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestC ...@@ -102,6 +103,7 @@ class Typo3DbQueryParserTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestC
$sourceProphecy = $this->prophesize(SourceInterface::class); $sourceProphecy = $this->prophesize(SourceInterface::class);
$queryProphecy->getSource()->willReturn($sourceProphecy->reveal()); $queryProphecy->getSource()->willReturn($sourceProphecy->reveal());
$queryProphecy->getOrderings()->willReturn([]); $queryProphecy->getOrderings()->willReturn([]);
$queryProphecy->getStatement()->willReturn(null);
// Test part: getConstraint returns not implemented object // Test part: getConstraint returns not implemented object
$constraintProphecy = $this->prophesize(ConstraintInterface::class); $constraintProphecy = $this->prophesize(ConstraintInterface::class);
...@@ -130,6 +132,7 @@ class Typo3DbQueryParserTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestC ...@@ -130,6 +132,7 @@ class Typo3DbQueryParserTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestC
$sourceProphecy = $this->prophesize(SourceInterface::class); $sourceProphecy = $this->prophesize(SourceInterface::class);
$queryProphecy->getSource()->willReturn($sourceProphecy->reveal()); $queryProphecy->getSource()->willReturn($sourceProphecy->reveal());
$queryProphecy->getOrderings()->willReturn([]); $queryProphecy->getOrderings()->willReturn([]);
$queryProphecy->getStatement()->willReturn(null);
// Test part: getConstraint returns simple constraint, and should push to andWhere() // Test part: getConstraint returns simple constraint, and should push to andWhere()
$constraintProphecy = $this->prophesize(ComparisonInterface::class); $constraintProphecy = $this->prophesize(ComparisonInterface::class);
...@@ -158,6 +161,7 @@ class Typo3DbQueryParserTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestC ...@@ -158,6 +161,7 @@ class Typo3DbQueryParserTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestC
$sourceProphecy = $this->prophesize(SourceInterface::class); $sourceProphecy = $this->prophesize(SourceInterface::class);
$queryProphecy->getSource()->willReturn($sourceProphecy->reveal()); $queryProphecy->getSource()->willReturn($sourceProphecy->reveal());
$queryProphecy->getOrderings()->willReturn([]); $queryProphecy->getOrderings()->willReturn([]);
$queryProphecy->getStatement()->willReturn(null);
$constraintProphecy = $this->prophesize(NotInterface::class); $constraintProphecy = $this->prophesize(NotInterface::class);
$subConstraintProphecy = $this->prophesize(ComparisonInterface::class); $subConstraintProphecy = $this->prophesize(ComparisonInterface::class);
...@@ -187,6 +191,7 @@ class Typo3DbQueryParserTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestC ...@@ -187,6 +191,7 @@ class Typo3DbQueryParserTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestC
$sourceProphecy = $this->prophesize(SourceInterface::class); $sourceProphecy = $this->prophesize(SourceInterface::class);
$queryProphecy->getSource()->willReturn($sourceProphecy->reveal()); $queryProphecy->getSource()->willReturn($sourceProphecy->reveal());
$queryProphecy->getOrderings()->willReturn([]); $queryProphecy->getOrderings()->willReturn([]);
$queryProphecy->getStatement()->willReturn(null);
$constraintProphecy = $this->prophesize(AndInterface::class); $constraintProphecy = $this->prophesize(AndInterface::class);
$queryProphecy->getConstraint()->willReturn($constraintProphecy->reveal()); $queryProphecy->getConstraint()->willReturn($constraintProphecy->reveal());
...@@ -224,6 +229,7 @@ class Typo3DbQueryParserTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestC ...@@ -224,6 +229,7 @@ class Typo3DbQueryParserTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestC
$sourceProphecy = $this->prophesize(SourceInterface::class); $sourceProphecy = $this->prophesize(SourceInterface::class);
$queryProphecy->getSource()->willReturn($sourceProphecy->reveal()); $queryProphecy->getSource()->willReturn($sourceProphecy->reveal());
$queryProphecy->getOrderings()->willReturn([]); $queryProphecy->getOrderings()->willReturn([]);
$queryProphecy->getStatement()->willReturn(null);
$constraintProphecy = $this->prophesize(AndInterface::class); $constraintProphecy = $this->prophesize(AndInterface::class);
$queryProphecy->getConstraint()->willReturn($constraintProphecy->reveal()); $queryProphecy->getConstraint()->willReturn($constraintProphecy->reveal());
...@@ -256,6 +262,7 @@ class Typo3DbQueryParserTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestC ...@@ -256,6 +262,7 @@ class Typo3DbQueryParserTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestC
$sourceProphecy = $this->prophesize(SourceInterface::class); $sourceProphecy = $this->prophesize(SourceInterface::class);
$queryProphecy->getSource()->willReturn($sourceProphecy->reveal()); $queryProphecy->getSource()->willReturn($sourceProphecy->reveal());
$queryProphecy->getOrderings()->willReturn([]); $queryProphecy->getOrderings()->willReturn([]);
$queryProphecy->getStatement()->willReturn(null);
$constraintProphecy = $this->prophesize(OrInterface::class); $constraintProphecy = $this->prophesize(OrInterface::class);
$queryProphecy->getConstraint()->willReturn($constraintProphecy->reveal()); $queryProphecy->getConstraint()->willReturn($constraintProphecy->reveal());
...@@ -293,6 +300,7 @@ class Typo3DbQueryParserTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestC ...@@ -293,6 +300,7 @@ class Typo3DbQueryParserTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestC
$sourceProphecy = $this->prophesize(SourceInterface::class); $sourceProphecy = $this->prophesize(SourceInterface::class);
$queryProphecy->getSource()->willReturn($sourceProphecy->reveal()); $queryProphecy->getSource()->willReturn($sourceProphecy->reveal());
$queryProphecy->getOrderings()->willReturn([]); $queryProphecy->getOrderings()->willReturn([]);
$queryProphecy->getStatement()->willReturn(null);
$constraintProphecy = $this->prophesize(OrInterface::class); $constraintProphecy = $this->prophesize(OrInterface::class);
$queryProphecy->getConstraint()->willReturn($constraintProphecy->reveal()); $queryProphecy->getConstraint()->willReturn($constraintProphecy->reveal());
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment