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 ...@@ -38,6 +38,7 @@ class Configuration extends \Doctrine\DBAL\Configuration
public function __construct() public function __construct()
{ {
parent::__construct(); parent::__construct();
$this->_attributes = array_merge($this->_attributes, array( $this->_attributes = array_merge($this->_attributes, array(
'resultCacheImpl' => null, 'resultCacheImpl' => null,
'queryCacheImpl' => null, 'queryCacheImpl' => null,
...@@ -46,7 +47,7 @@ class Configuration extends \Doctrine\DBAL\Configuration ...@@ -46,7 +47,7 @@ class Configuration extends \Doctrine\DBAL\Configuration
'cacheDir' => null, 'cacheDir' => null,
'allowPartialObjects' => true, 'allowPartialObjects' => true,
'useCExtension' => false 'useCExtension' => false
)); ));
//TODO: Move this to client code to avoid unnecessary work when a different metadata //TODO: Move this to client code to avoid unnecessary work when a different metadata
// driver is used. // driver is used.
......
...@@ -117,6 +117,11 @@ class Parser ...@@ -117,6 +117,11 @@ class Parser
*/ */
private $_queryComponents = array(); private $_queryComponents = array();
/**
* Sql tree walker
*
* @var SqlTreeWalker
*/
private $_sqlTreeWalker; private $_sqlTreeWalker;
/** /**
...@@ -195,7 +200,9 @@ class Parser ...@@ -195,7 +200,9 @@ class Parser
} }
// Create SqlWalker who creates the SQL from the AST // 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 // Assign an SQL executor to the parser result
$this->_parserResult->setSqlExecutor(Exec\AbstractExecutor::create($AST, $sqlWalker)); $this->_parserResult->setSqlExecutor(Exec\AbstractExecutor::create($AST, $sqlWalker));
...@@ -261,10 +268,18 @@ class Parser ...@@ -261,10 +268,18 @@ class Parser
public function semanticalError($message = '', $token = null) public function semanticalError($message = '', $token = null)
{ {
if ($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); throw DoctrineException::updateMe($message);
} }
...@@ -337,7 +352,6 @@ class Parser ...@@ -337,7 +352,6 @@ class Parser
default: default:
$this->syntaxError('SELECT, UPDATE or DELETE'); $this->syntaxError('SELECT, UPDATE or DELETE');
break;
} }
} }
...@@ -497,6 +511,7 @@ class Parser ...@@ -497,6 +511,7 @@ class Parser
/** /**
* NewValue ::= SimpleArithmeticExpression | StringPrimary | DatetimePrimary | BooleanPrimary | * NewValue ::= SimpleArithmeticExpression | StringPrimary | DatetimePrimary | BooleanPrimary |
* EnumPrimary | SimpleEntityExpression | "NULL" * EnumPrimary | SimpleEntityExpression | "NULL"
*
* @todo Implementation still incomplete. * @todo Implementation still incomplete.
*/ */
public function NewValue() public function NewValue()
...@@ -641,8 +656,13 @@ class Parser ...@@ -641,8 +656,13 @@ class Parser
$fieldIdentificationVariable = $this->_lexer->token['value']; $fieldIdentificationVariable = $this->_lexer->token['value'];
} }
} else { } else {
//TODO: If hydration mode is OBJECT throw an exception ("partial object dangerous...") if (
// unless the doctrine.forcePartialLoad query hint is set $this->_query->getHydrationMode() == Query::HYDRATE_OBJECT &&
! $this->_em->getConfiguration()->getAllowPartialObjects()
) {
$this->semanticalError('Cannot select partial object when using object hydration');
}
$expression = $this->StateFieldPathExpression(); $expression = $this->StateFieldPathExpression();
} }
......
...@@ -15,10 +15,7 @@ class LanguageRecognitionTest extends \Doctrine\Tests\OrmTestCase ...@@ -15,10 +15,7 @@ class LanguageRecognitionTest extends \Doctrine\Tests\OrmTestCase
public function assertValidDql($dql, $debug = false) public function assertValidDql($dql, $debug = false)
{ {
try { try {
$query = $this->_em->createQuery($dql); $parserResult = $this->parseDql($dql);
$parser = new \Doctrine\ORM\Query\Parser($query);
$parser->setSqlTreeWalker(new \Doctrine\Tests\Mocks\MockTreeWalker);
$parserResult = $parser->parse();
} catch (\Exception $e) { } catch (\Exception $e) {
if ($debug) { if ($debug) {
echo $e->getTraceAsString() . PHP_EOL; echo $e->getTraceAsString() . PHP_EOL;
...@@ -30,11 +27,7 @@ class LanguageRecognitionTest extends \Doctrine\Tests\OrmTestCase ...@@ -30,11 +27,7 @@ class LanguageRecognitionTest extends \Doctrine\Tests\OrmTestCase
public function assertInvalidDql($dql, $debug = false) public function assertInvalidDql($dql, $debug = false)
{ {
try { try {
$query = $this->_em->createQuery($dql); $parserResult = $this->parseDql($dql);
$query->setDql($dql);
$parser = new \Doctrine\ORM\Query\Parser($query);
$parser->setSqlTreeWalker(new \Doctrine\Tests\Mocks\MockTreeWalker);
$parserResult = $parser->parse();
$this->fail('No syntax errors were detected, when syntax errors were expected'); $this->fail('No syntax errors were detected, when syntax errors were expected');
} catch (\Exception $e) { } catch (\Exception $e) {
if ($debug) { if ($debug) {
...@@ -43,6 +36,16 @@ class LanguageRecognitionTest extends \Doctrine\Tests\OrmTestCase ...@@ -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() public function testEmptyQueryString()
{ {
...@@ -326,4 +329,19 @@ class LanguageRecognitionTest extends \Doctrine\Tests\OrmTestCase ...@@ -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->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