Skip to content

Commit e46ec23

Browse files
committed
Add a SingleSelectSqlFinalizer that can take care of adding offset/limit as well as locking mode statements to a given SQL query.
Add a FinalizedSelectExecutor that executes given, finalized SQL statements.
1 parent 94ee5c0 commit e46ec23

File tree

2 files changed

+86
-0
lines changed

2 files changed

+86
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Doctrine\ORM\Query\Exec;
6+
7+
use Doctrine\DBAL\Connection;
8+
use Doctrine\DBAL\Result;
9+
10+
/**
11+
* SQL executor for a given, final, single SELECT SQL query
12+
*/
13+
class FinalizedSelectExecutor extends AbstractSqlExecutor
14+
{
15+
public function __construct(string $sql)
16+
{
17+
parent::__construct();
18+
19+
$this->sqlStatements = $sql;
20+
}
21+
22+
public function execute(Connection $conn, array $params, array $types): Result
23+
{
24+
return $conn->executeQuery($this->getSqlStatements(), $params, $types, $this->queryCacheProfile);
25+
}
26+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Doctrine\ORM\Query\Exec;
6+
7+
use Doctrine\DBAL\LockMode;
8+
use Doctrine\ORM\Query;
9+
use Doctrine\ORM\Query\QueryException;
10+
11+
/**
12+
* SingleSelectSqlFinalizer finalizes a given SQL query by applying
13+
* the query's firstResult/maxResult values as well as extra read lock/write lock
14+
* statements, both through the platform-specific methods.
15+
*
16+
* The resulting, "finalized" SQL is passed to a FinalizedSelectExecutor.
17+
*/
18+
class SingleSelectSqlFinalizer implements SqlFinalizer
19+
{
20+
/** @var string */
21+
private $sql;
22+
23+
public function __construct(string $sql)
24+
{
25+
$this->sql = $sql;
26+
}
27+
28+
/**
29+
* @internal
30+
*
31+
* @psalm-internal Doctrine\ORM
32+
*
33+
* This method exists temporarily to support old SqlWalker interfaces.
34+
*/
35+
public function finalizeSql(Query $query): string
36+
{
37+
$platform = $query->getEntityManager()->getConnection()->getDatabasePlatform();
38+
39+
$sql = $platform->modifyLimitQuery($this->sql, $query->getMaxResults(), $query->getFirstResult());
40+
41+
$lockMode = $query->getHint(Query::HINT_LOCK_MODE) ?: LockMode::NONE;
42+
43+
if ($lockMode !== LockMode::NONE && $lockMode !== LockMode::OPTIMISTIC && $lockMode !== LockMode::PESSIMISTIC_READ && $lockMode !== LockMode::PESSIMISTIC_WRITE) {
44+
throw QueryException::invalidLockMode();
45+
}
46+
47+
if ($lockMode === LockMode::PESSIMISTIC_READ) {
48+
$sql .= ' ' . $platform->getReadLockSQL();
49+
} elseif ($lockMode === LockMode::PESSIMISTIC_WRITE) {
50+
$sql .= ' ' . $platform->getWriteLockSQL();
51+
}
52+
53+
return $sql;
54+
}
55+
56+
public function createExecutor(Query $query): AbstractSqlExecutor
57+
{
58+
return new FinalizedSelectExecutor($this->finalizeSql($query));
59+
}
60+
}

0 commit comments

Comments
 (0)