Commit 55651ec9 authored by guilhermeblanco's avatar guilhermeblanco

[2.0] Updated semantical error to display token and text close to the found...

[2.0] Updated semantical error to display token and text close to the found error. Some cosmetics applied.
parent c48648aa
......@@ -38,6 +38,7 @@ class Configuration extends \Doctrine\DBAL\Configuration
public function __construct()
{
parent::__construct();
$this->_attributes = array_merge($this->_attributes, array(
'resultCacheImpl' => null,
'queryCacheImpl' => null,
......@@ -46,7 +47,7 @@ class Configuration extends \Doctrine\DBAL\Configuration
'cacheDir' => null,
'allowPartialObjects' => true,
'useCExtension' => false
));
));
//TODO: Move this to client code to avoid unnecessary work when a different metadata
// driver is used.
......
......@@ -117,6 +117,11 @@ class Parser
*/
private $_queryComponents = array();
/**
* Sql tree walker
*
* @var SqlTreeWalker
*/
private $_sqlTreeWalker;
/**
......@@ -195,7 +200,9 @@ class Parser
}
// Create SqlWalker who creates the SQL from the AST
$sqlWalker = $this->_sqlTreeWalker ?: new SqlWalker($this->_query, $this->_parserResult, $this->_queryComponents);
$sqlWalker = $this->_sqlTreeWalker ?: new SqlWalker(
$this->_query, $this->_parserResult, $this->_queryComponents
);
// Assign an SQL executor to the parser result
$this->_parserResult->setSqlExecutor(Exec\AbstractExecutor::create($AST, $sqlWalker));
......@@ -261,10 +268,18 @@ class Parser
public function semanticalError($message = '', $token = null)
{
if ($token === null) {
$token = $this->_lexer->token;
$token = $this->_lexer->lookahead;
}
// Find a position of a final word to display in error string
$dql = $this->_query->getDql();
$pos = strpos($dql, ' ', $token['position'] + 10);
$length = ($pos !== false) ? $pos - $token['position'] : 10;
// Building informative message
$message = 'line 0, col ' . (isset($token['position']) ? $token['position'] : '-1')
. " near '" . substr($dql, $token['position'], $length) . "'): Error: " . $message;
//TODO: Include $token in $message
throw DoctrineException::updateMe($message);
}
......@@ -337,7 +352,6 @@ class Parser
default:
$this->syntaxError('SELECT, UPDATE or DELETE');
break;
}
}
......@@ -497,6 +511,7 @@ class Parser
/**
* NewValue ::= SimpleArithmeticExpression | StringPrimary | DatetimePrimary | BooleanPrimary |
* EnumPrimary | SimpleEntityExpression | "NULL"
*
* @todo Implementation still incomplete.
*/
public function NewValue()
......@@ -641,8 +656,13 @@ class Parser
$fieldIdentificationVariable = $this->_lexer->token['value'];
}
} else {
//TODO: If hydration mode is OBJECT throw an exception ("partial object dangerous...")
// unless the doctrine.forcePartialLoad query hint is set
if (
$this->_query->getHydrationMode() == Query::HYDRATE_OBJECT &&
! $this->_em->getConfiguration()->getAllowPartialObjects()
) {
$this->semanticalError('Cannot select partial object when using object hydration');
}
$expression = $this->StateFieldPathExpression();
}
......
......@@ -15,10 +15,7 @@ class LanguageRecognitionTest extends \Doctrine\Tests\OrmTestCase
public function assertValidDql($dql, $debug = false)
{
try {
$query = $this->_em->createQuery($dql);
$parser = new \Doctrine\ORM\Query\Parser($query);
$parser->setSqlTreeWalker(new \Doctrine\Tests\Mocks\MockTreeWalker);
$parserResult = $parser->parse();
$parserResult = $this->parseDql($dql);
} catch (\Exception $e) {
if ($debug) {
echo $e->getTraceAsString() . PHP_EOL;
......@@ -30,11 +27,7 @@ class LanguageRecognitionTest extends \Doctrine\Tests\OrmTestCase
public function assertInvalidDql($dql, $debug = false)
{
try {
$query = $this->_em->createQuery($dql);
$query->setDql($dql);
$parser = new \Doctrine\ORM\Query\Parser($query);
$parser->setSqlTreeWalker(new \Doctrine\Tests\Mocks\MockTreeWalker);
$parserResult = $parser->parse();
$parserResult = $this->parseDql($dql);
$this->fail('No syntax errors were detected, when syntax errors were expected');
} catch (\Exception $e) {
if ($debug) {
......@@ -43,6 +36,16 @@ class LanguageRecognitionTest extends \Doctrine\Tests\OrmTestCase
}
}
}
public function parseDql($dql)
{
$query = $this->_em->createQuery($dql);
$query->setDql($dql);
$parser = new \Doctrine\ORM\Query\Parser($query);
$parser->setSqlTreeWalker(new \Doctrine\Tests\Mocks\MockTreeWalker);
return $parser->parse();
}
public function testEmptyQueryString()
{
......@@ -326,4 +329,19 @@ class LanguageRecognitionTest extends \Doctrine\Tests\OrmTestCase
{
$this->assertValidDql('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE :param MEMBER OF u.phonenumbers');
}
/**
* This checks for invalid attempt to hydrate a proxy. It should throw an exception
*
* @expectedException \Doctrine\Common\DoctrineException
*/
public function testPartialObjectLoad()
{
$oldValue = $this->_em->getConfiguration()->getAllowPartialObjects();
$this->_em->getConfiguration()->setAllowPartialObjects(false);
$this->parseDql('SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u');
$this->_em->getConfiguration()->setAllowPartialObjects($oldValue);
}
}
\ No newline at end of file
Markdown is supported
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