Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 62 additions & 0 deletions lib/Doctrine/ORM/QueryBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,13 @@ class QueryBuilder
*/
private $joinRootAliases = [];

/**
* The map of query hints.
*
* @var array
*/
private $_hints = [];

/**
* Whether to use second level cache, if available.
*
Expand Down Expand Up @@ -264,6 +271,55 @@ public function setCacheMode($cacheMode)
return $this;
}

/**
* Sets a query hint.
*
* @param string $name The name of the hint.
* @param mixed $value The value of the hint.
*
* @return self
*/
public function setHint($name, $value)
{
$this->_hints[$name] = $value;

return $this;
}

/**
* Gets the value of a query hint. If the hint name is not recognized, FALSE is returned.
*
* @param string $name The name of the hint.
*
* @return mixed The value of the hint or FALSE, if the hint name is not recognized.
*/
public function getHint($name)
{
return $this->_hints[$name] ?? false;
}

/**
* Check if the query has a hint
*
* @param string $name The name of the hint
*
* @return bool False if the query does not have any hint
*/
public function hasHint($name)
{
return isset($this->_hints[$name]);
}

/**
* Return the key value map of query hints that are currently set.
*
* @return array
*/
public function getHints()
{
return $this->_hints;
}

/**
* Gets the type of the currently built query.
*
Expand Down Expand Up @@ -370,6 +426,12 @@ public function getQuery()
$query->setCacheRegion($this->cacheRegion);
}

if ($this->_hints) {
foreach ($this->_hints as $name => $value) {
$query->setHint($name, $value);
}
}

return $query;
}

Expand Down
41 changes: 41 additions & 0 deletions tests/Doctrine/Tests/ORM/QueryBuilderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1115,6 +1115,47 @@ public function testSecondLevelCacheQueryBuilderOptions()
$this->assertEquals(Cache::MODE_REFRESH, $query->getCacheMode());
}

public function testQueryHints()
{
$defaultQueryBuilder = $this->_em->createQueryBuilder()
->select('s')
->from(State::class, 's');

$this->assertFalse($defaultQueryBuilder->hasHint('foo'));
$this->assertFalse($defaultQueryBuilder->getHint('foo'));
$this->assertEquals([], $defaultQueryBuilder->getHints());

$defaultQuery = $defaultQueryBuilder->getQuery();

$this->assertFalse($defaultQuery->hasHint('foo'));

$builder = $this->_em->createQueryBuilder()
->select('s')
->from(State::class, 's')
->setHint('foo', 'bar')
->setHint('foo_reg', $value = new \stdClass())
;

$this->assertTrue($builder->hasHint('foo'));
$this->assertTrue($builder->hasHint('foo_reg'));
$this->assertFalse($builder->hasHint('fool'));
$this->assertEquals(['foo' => 'bar', 'foo_reg' => $value], $builder->getHints());

$this->assertEquals('bar', $builder->getHint('foo'));
$this->assertEquals($value, $builder->getHint('foo_reg'));
$this->assertFalse($builder->getHint('fool'));

$query = $builder->getQuery();

$this->assertTrue($query->hasHint('foo'));
$this->assertTrue($query->hasHint('foo_reg'));
$this->assertFalse($query->hasHint('fool'));

$this->assertEquals('bar', $query->getHint('foo'));
$this->assertEquals($value, $query->getHint('foo_reg'));
$this->assertFalse($query->getHint('fool'));
}

/**
* @group DDC-2253
*/
Expand Down