Merge remote branch 'upstream/master'
This commit is contained in:
commit
023f06a420
@ -27,7 +27,8 @@ namespace Doctrine\Common\Annotations;
|
|||||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
* @link www.doctrine-project.org
|
* @link www.doctrine-project.org
|
||||||
* @since 2.0
|
* @since 2.0
|
||||||
* @version $Revision: 3938 $
|
* @version $Revision$
|
||||||
|
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||||
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||||
* @author Jonathan Wage <jonwage@gmail.com>
|
* @author Jonathan Wage <jonwage@gmail.com>
|
||||||
* @author Roman Borschel <roman@code-factory.org>
|
* @author Roman Borschel <roman@code-factory.org>
|
||||||
@ -53,13 +54,28 @@ class Annotation
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Error handler for unknown property accessor in Annotation class.
|
||||||
|
*
|
||||||
|
* @param string $name Unknown property name
|
||||||
|
*/
|
||||||
public function __get($name)
|
public function __get($name)
|
||||||
{
|
{
|
||||||
throw new \BadMethodCallException("Unknown annotation property '$name' on annotation '".get_class($this)."'.");
|
throw new \BadMethodCallException(
|
||||||
|
sprintf("Unknown property '%s' on annotation '%s'.", $name, get_class($this))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Error handler for unknown property mutator in Annotation class.
|
||||||
|
*
|
||||||
|
* @param string $name Unkown property name
|
||||||
|
* @param mixed $value Property value
|
||||||
|
*/
|
||||||
public function __set($name, $value)
|
public function __set($name, $value)
|
||||||
{
|
{
|
||||||
throw new \BadMethodCallException("Unknown annotation property '$name' on annotation '".get_class($this)."'.");
|
throw new \BadMethodCallException(
|
||||||
|
sprintf("Unknown property '%s' on annotation '%s'.", $name, get_class($this))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -27,19 +27,31 @@ namespace Doctrine\Common\Annotations;
|
|||||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
* @link www.doctrine-project.org
|
* @link www.doctrine-project.org
|
||||||
* @since 2.0
|
* @since 2.0
|
||||||
* @version $Revision: 3938 $
|
* @version $Revision$
|
||||||
|
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||||
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||||
* @author Jonathan Wage <jonwage@gmail.com>
|
* @author Jonathan Wage <jonwage@gmail.com>
|
||||||
* @author Roman Borschel <roman@code-factory.org>
|
* @author Roman Borschel <roman@code-factory.org>
|
||||||
*/
|
*/
|
||||||
class AnnotationException extends \Doctrine\Common\CommonException
|
class AnnotationException extends \Exception
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Creates a new AnnotationException describing a Syntax error.
|
||||||
|
*
|
||||||
|
* @param string $message Exception message
|
||||||
|
* @return AnnotationException
|
||||||
|
*/
|
||||||
public static function syntaxError($message)
|
public static function syntaxError($message)
|
||||||
{
|
{
|
||||||
return new self('[Syntax Error] ' . $message);
|
return new self('[Syntax Error] ' . $message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new AnnotationException describing a Semantical error.
|
||||||
|
*
|
||||||
|
* @param string $message Exception message
|
||||||
|
* @return AnnotationException
|
||||||
|
*/
|
||||||
public static function semanticalError($message)
|
public static function semanticalError($message)
|
||||||
{
|
{
|
||||||
return new self('[Semantical Error] ' . $message);
|
return new self('[Semantical Error] ' . $message);
|
||||||
|
@ -32,7 +32,7 @@ use \ReflectionClass,
|
|||||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
* @link www.doctrine-project.org
|
* @link www.doctrine-project.org
|
||||||
* @since 2.0
|
* @since 2.0
|
||||||
* @version $Revision: 3938 $
|
* @version $Revision$
|
||||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||||
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||||
* @author Jonathan Wage <jonwage@gmail.com>
|
* @author Jonathan Wage <jonwage@gmail.com>
|
||||||
@ -46,7 +46,7 @@ class AnnotationReader
|
|||||||
* @var string
|
* @var string
|
||||||
* @static
|
* @static
|
||||||
*/
|
*/
|
||||||
private static $CACHE_SALT = "@<Annot>";
|
private static $CACHE_SALT = '@<Annot>';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Annotations Parser
|
* Annotations Parser
|
||||||
@ -56,15 +56,14 @@ class AnnotationReader
|
|||||||
private $_parser;
|
private $_parser;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cache machanism to store processed Annotations
|
* Cache mechanism to store processed Annotations
|
||||||
*
|
*
|
||||||
* @var Doctrine\Common\Cache\Cache
|
* @var Doctrine\Common\Cache\Cache
|
||||||
*/
|
*/
|
||||||
private $_cache;
|
private $_cache;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor. Initializes a new AnnotationReader that uses the given
|
* Constructor. Initializes a new AnnotationReader that uses the given Cache provider.
|
||||||
* Cache provider.
|
|
||||||
*
|
*
|
||||||
* @param Cache $cache The cache provider to use. If none is provided, ArrayCache is used.
|
* @param Cache $cache The cache provider to use. If none is provided, ArrayCache is used.
|
||||||
*/
|
*/
|
||||||
@ -112,7 +111,7 @@ class AnnotationReader
|
|||||||
return $data;
|
return $data;
|
||||||
}
|
}
|
||||||
|
|
||||||
$annotations = $this->_parser->parse($class->getDocComment(), "class ".$class->getName());
|
$annotations = $this->_parser->parse($class->getDocComment(), 'class ' . $class->getName());
|
||||||
$this->_cache->save($cacheKey, $annotations, null);
|
$this->_cache->save($cacheKey, $annotations, null);
|
||||||
|
|
||||||
return $annotations;
|
return $annotations;
|
||||||
@ -128,6 +127,7 @@ class AnnotationReader
|
|||||||
public function getClassAnnotation(ReflectionClass $class, $annotation)
|
public function getClassAnnotation(ReflectionClass $class, $annotation)
|
||||||
{
|
{
|
||||||
$annotations = $this->getClassAnnotations($class);
|
$annotations = $this->getClassAnnotations($class);
|
||||||
|
|
||||||
return isset($annotations[$annotation]) ? $annotations[$annotation] : null;
|
return isset($annotations[$annotation]) ? $annotations[$annotation] : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -148,7 +148,7 @@ class AnnotationReader
|
|||||||
return $data;
|
return $data;
|
||||||
}
|
}
|
||||||
|
|
||||||
$context = "property ".$property->getDeclaringClass()->getName()."::\$".$property->getName();
|
$context = 'property ' . $property->getDeclaringClass()->getName() . "::\$" . $property->getName();
|
||||||
$annotations = $this->_parser->parse($property->getDocComment(), $context);
|
$annotations = $this->_parser->parse($property->getDocComment(), $context);
|
||||||
$this->_cache->save($cacheKey, $annotations, null);
|
$this->_cache->save($cacheKey, $annotations, null);
|
||||||
|
|
||||||
@ -165,6 +165,7 @@ class AnnotationReader
|
|||||||
public function getPropertyAnnotation(ReflectionProperty $property, $annotation)
|
public function getPropertyAnnotation(ReflectionProperty $property, $annotation)
|
||||||
{
|
{
|
||||||
$annotations = $this->getPropertyAnnotations($property);
|
$annotations = $this->getPropertyAnnotations($property);
|
||||||
|
|
||||||
return isset($annotations[$annotation]) ? $annotations[$annotation] : null;
|
return isset($annotations[$annotation]) ? $annotations[$annotation] : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -185,7 +186,7 @@ class AnnotationReader
|
|||||||
return $data;
|
return $data;
|
||||||
}
|
}
|
||||||
|
|
||||||
$context = "method ".$method->getDeclaringClass()->getName()."::".$method->getName()."()";
|
$context = 'method ' . $method->getDeclaringClass()->getName() . '::' . $method->getName() . '()';
|
||||||
$annotations = $this->_parser->parse($method->getDocComment(), $context);
|
$annotations = $this->_parser->parse($method->getDocComment(), $context);
|
||||||
$this->_cache->save($cacheKey, $annotations, null);
|
$this->_cache->save($cacheKey, $annotations, null);
|
||||||
|
|
||||||
@ -202,6 +203,7 @@ class AnnotationReader
|
|||||||
public function getMethodAnnotation(ReflectionMethod $method, $annotation)
|
public function getMethodAnnotation(ReflectionMethod $method, $annotation)
|
||||||
{
|
{
|
||||||
$annotations = $this->getMethodAnnotations($method);
|
$annotations = $this->getMethodAnnotations($method);
|
||||||
|
|
||||||
return isset($annotations[$annotation]) ? $annotations[$annotation] : null;
|
return isset($annotations[$annotation]) ? $annotations[$annotation] : null;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -27,7 +27,8 @@ namespace Doctrine\Common\Annotations;
|
|||||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
* @link www.doctrine-project.org
|
* @link www.doctrine-project.org
|
||||||
* @since 2.0
|
* @since 2.0
|
||||||
* @version $Revision: 3938 $
|
* @version $Revision$
|
||||||
|
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||||
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||||
* @author Jonathan Wage <jonwage@gmail.com>
|
* @author Jonathan Wage <jonwage@gmail.com>
|
||||||
* @author Roman Borschel <roman@code-factory.org>
|
* @author Roman Borschel <roman@code-factory.org>
|
||||||
@ -80,7 +81,7 @@ class Lexer extends \Doctrine\Common\Lexer
|
|||||||
$newVal = $this->_getNumeric($value);
|
$newVal = $this->_getNumeric($value);
|
||||||
|
|
||||||
// Checking numeric value
|
// Checking numeric value
|
||||||
if ($newVal !== false){
|
if ($newVal !== false) {
|
||||||
$value = $newVal;
|
$value = $newVal;
|
||||||
|
|
||||||
return (strpos($value, '.') !== false || stripos($value, 'e') !== false)
|
return (strpos($value, '.') !== false || stripos($value, 'e') !== false)
|
||||||
@ -93,16 +94,34 @@ class Lexer extends \Doctrine\Common\Lexer
|
|||||||
return self::T_STRING;
|
return self::T_STRING;
|
||||||
} else {
|
} else {
|
||||||
switch (strtolower($value)) {
|
switch (strtolower($value)) {
|
||||||
case '@': return self::T_AT;
|
case '@':
|
||||||
case ',': return self::T_COMMA;
|
return self::T_AT;
|
||||||
case '(': return self::T_OPEN_PARENTHESIS;
|
|
||||||
case ')': return self::T_CLOSE_PARENTHESIS;
|
case ',':
|
||||||
case '{': return self::T_OPEN_CURLY_BRACES;
|
return self::T_COMMA;
|
||||||
|
|
||||||
|
case '(':
|
||||||
|
return self::T_OPEN_PARENTHESIS;
|
||||||
|
|
||||||
|
case ')':
|
||||||
|
return self::T_CLOSE_PARENTHESIS;
|
||||||
|
|
||||||
|
case '{':
|
||||||
|
return self::T_OPEN_CURLY_BRACES;
|
||||||
|
|
||||||
case '}': return self::T_CLOSE_CURLY_BRACES;
|
case '}': return self::T_CLOSE_CURLY_BRACES;
|
||||||
case '=': return self::T_EQUALS;
|
case '=':
|
||||||
case '\\': return self::T_NAMESPACE_SEPARATOR;
|
return self::T_EQUALS;
|
||||||
case 'true': return self::T_TRUE;
|
|
||||||
case 'false': return self::T_FALSE;
|
case '\\':
|
||||||
|
return self::T_NAMESPACE_SEPARATOR;
|
||||||
|
|
||||||
|
case 'true':
|
||||||
|
return self::T_TRUE;
|
||||||
|
|
||||||
|
case 'false':
|
||||||
|
return self::T_FALSE;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (ctype_alpha($value[0]) || $value[0] === '_') {
|
if (ctype_alpha($value[0]) || $value[0] === '_') {
|
||||||
return self::T_IDENTIFIER;
|
return self::T_IDENTIFIER;
|
||||||
@ -126,6 +145,7 @@ class Lexer extends \Doctrine\Common\Lexer
|
|||||||
if ( ! is_scalar($value)) {
|
if ( ! is_scalar($value)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Checking for valid numeric numbers: 1.234, -1.234e-2
|
// Checking for valid numeric numbers: 1.234, -1.234e-2
|
||||||
if (is_numeric($value)) {
|
if (is_numeric($value)) {
|
||||||
return $value;
|
return $value;
|
||||||
|
@ -27,11 +27,11 @@ namespace Doctrine\Common\Annotations;
|
|||||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
* @link www.doctrine-project.org
|
* @link www.doctrine-project.org
|
||||||
* @since 2.0
|
* @since 2.0
|
||||||
* @version $Revision: 3938 $
|
* @version $Revision$
|
||||||
|
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||||
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||||
* @author Jonathan Wage <jonwage@gmail.com>
|
* @author Jonathan Wage <jonwage@gmail.com>
|
||||||
* @author Roman Borschel <roman@code-factory.org>
|
* @author Roman Borschel <roman@code-factory.org>
|
||||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
|
||||||
*/
|
*/
|
||||||
class Parser
|
class Parser
|
||||||
{
|
{
|
||||||
@ -173,9 +173,10 @@ class Parser
|
|||||||
$message .= "'{$token['value']}' at position {$token['position']}";
|
$message .= "'{$token['value']}' at position {$token['position']}";
|
||||||
}
|
}
|
||||||
|
|
||||||
if(strlen($this->_context)) {
|
if (strlen($this->_context)) {
|
||||||
$message .= ' in '.$this->_context;
|
$message .= ' in ' . $this->_context;
|
||||||
}
|
}
|
||||||
|
|
||||||
$message .= '.';
|
$message .= '.';
|
||||||
|
|
||||||
throw AnnotationException::syntaxError($message);
|
throw AnnotationException::syntaxError($message);
|
||||||
@ -411,6 +412,7 @@ class Parser
|
|||||||
|
|
||||||
foreach ($values as $value) {
|
foreach ($values as $value) {
|
||||||
list ($key, $val) = $value;
|
list ($key, $val) = $value;
|
||||||
|
|
||||||
if ($key !== null) {
|
if ($key !== null) {
|
||||||
$array[$key] = $val;
|
$array[$key] = $val;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
/*
|
/*
|
||||||
* $Id$
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
@ -21,15 +19,12 @@
|
|||||||
|
|
||||||
namespace Doctrine\DBAL;
|
namespace Doctrine\DBAL;
|
||||||
|
|
||||||
use Doctrine\DBAL\Types\Type;
|
use Doctrine\DBAL\Logging\SQLLogger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configuration container for the Doctrine DBAL.
|
* Configuration container for the Doctrine DBAL.
|
||||||
*
|
*
|
||||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
|
||||||
* @link www.doctrine-project.org
|
|
||||||
* @since 2.0
|
* @since 2.0
|
||||||
* @version $Revision: 3938 $
|
|
||||||
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||||
* @author Jonathan Wage <jonwage@gmail.com>
|
* @author Jonathan Wage <jonwage@gmail.com>
|
||||||
* @author Roman Borschel <roman@code-factory.org>
|
* @author Roman Borschel <roman@code-factory.org>
|
||||||
@ -46,22 +41,12 @@ class Configuration
|
|||||||
*/
|
*/
|
||||||
protected $_attributes = array();
|
protected $_attributes = array();
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new DBAL configuration instance.
|
|
||||||
*/
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
$this->_attributes = array(
|
|
||||||
'sqlLogger' => null
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the SQL logger to use. Defaults to NULL which means SQL logging is disabled.
|
* Sets the SQL logger to use. Defaults to NULL which means SQL logging is disabled.
|
||||||
*
|
*
|
||||||
* @param SQLLogger $logger
|
* @param SQLLogger $logger
|
||||||
*/
|
*/
|
||||||
public function setSQLLogger($logger)
|
public function setSQLLogger(SQLLogger $logger)
|
||||||
{
|
{
|
||||||
$this->_attributes['sqlLogger'] = $logger;
|
$this->_attributes['sqlLogger'] = $logger;
|
||||||
}
|
}
|
||||||
@ -73,6 +58,7 @@ class Configuration
|
|||||||
*/
|
*/
|
||||||
public function getSQLLogger()
|
public function getSQLLogger()
|
||||||
{
|
{
|
||||||
return $this->_attributes['sqlLogger'];
|
return isset($this->_attributes['sqlLogger']) ?
|
||||||
|
$this->_attributes['sqlLogger'] : null;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -78,7 +78,7 @@ EOT
|
|||||||
if (preg_match('/^select/i', $sql)) {
|
if (preg_match('/^select/i', $sql)) {
|
||||||
$resultSet = $conn->fetchAll($sql);
|
$resultSet = $conn->fetchAll($sql);
|
||||||
} else {
|
} else {
|
||||||
$resultSet = $em->getConnection()->executeUpdate($sql);
|
$resultSet = $conn->executeUpdate($sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
\Doctrine\Common\Util\Debug::dump($resultSet, (int) $depth);
|
\Doctrine\Common\Util\Debug::dump($resultSet, (int) $depth);
|
||||||
|
@ -27,8 +27,7 @@ use Doctrine\Common\Cache\Cache,
|
|||||||
* It combines all configuration options from DBAL & ORM.
|
* It combines all configuration options from DBAL & ORM.
|
||||||
*
|
*
|
||||||
* @since 2.0
|
* @since 2.0
|
||||||
* @internal When adding a new configuration option just write a getter/setter
|
* @internal When adding a new configuration option just write a getter/setter pair.
|
||||||
* pair and add the option to the _attributes array with a proper default value.
|
|
||||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||||
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||||
* @author Jonathan Wage <jonwage@gmail.com>
|
* @author Jonathan Wage <jonwage@gmail.com>
|
||||||
@ -36,24 +35,6 @@ use Doctrine\Common\Cache\Cache,
|
|||||||
*/
|
*/
|
||||||
class Configuration extends \Doctrine\DBAL\Configuration
|
class Configuration extends \Doctrine\DBAL\Configuration
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* Creates a new configuration that can be used for Doctrine.
|
|
||||||
*/
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
parent::__construct();
|
|
||||||
$this->_attributes = array_merge($this->_attributes, array(
|
|
||||||
'resultCacheImpl' => null,
|
|
||||||
'queryCacheImpl' => null,
|
|
||||||
'metadataCacheImpl' => null,
|
|
||||||
'metadataDriverImpl' => null,
|
|
||||||
'proxyDir' => null,
|
|
||||||
'useCExtension' => false,
|
|
||||||
'autoGenerateProxyClasses' => true,
|
|
||||||
'proxyNamespace' => null
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the directory where Doctrine generates any necessary proxy class files.
|
* Sets the directory where Doctrine generates any necessary proxy class files.
|
||||||
*
|
*
|
||||||
@ -71,7 +52,8 @@ class Configuration extends \Doctrine\DBAL\Configuration
|
|||||||
*/
|
*/
|
||||||
public function getProxyDir()
|
public function getProxyDir()
|
||||||
{
|
{
|
||||||
return $this->_attributes['proxyDir'];
|
return isset($this->_attributes['proxyDir']) ?
|
||||||
|
$this->_attributes['proxyDir'] : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -82,7 +64,8 @@ class Configuration extends \Doctrine\DBAL\Configuration
|
|||||||
*/
|
*/
|
||||||
public function getAutoGenerateProxyClasses()
|
public function getAutoGenerateProxyClasses()
|
||||||
{
|
{
|
||||||
return $this->_attributes['autoGenerateProxyClasses'];
|
return isset($this->_attributes['autoGenerateProxyClasses']) ?
|
||||||
|
$this->_attributes['autoGenerateProxyClasses'] : true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -103,7 +86,8 @@ class Configuration extends \Doctrine\DBAL\Configuration
|
|||||||
*/
|
*/
|
||||||
public function getProxyNamespace()
|
public function getProxyNamespace()
|
||||||
{
|
{
|
||||||
return $this->_attributes['proxyNamespace'];
|
return isset($this->_attributes['proxyNamespace']) ?
|
||||||
|
$this->_attributes['proxyNamespace'] : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -188,7 +172,8 @@ class Configuration extends \Doctrine\DBAL\Configuration
|
|||||||
*/
|
*/
|
||||||
public function getMetadataDriverImpl()
|
public function getMetadataDriverImpl()
|
||||||
{
|
{
|
||||||
return $this->_attributes['metadataDriverImpl'];
|
return isset($this->_attributes['metadataDriverImpl']) ?
|
||||||
|
$this->_attributes['metadataDriverImpl'] : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -198,7 +183,8 @@ class Configuration extends \Doctrine\DBAL\Configuration
|
|||||||
*/
|
*/
|
||||||
public function getResultCacheImpl()
|
public function getResultCacheImpl()
|
||||||
{
|
{
|
||||||
return $this->_attributes['resultCacheImpl'];
|
return isset($this->_attributes['resultCacheImpl']) ?
|
||||||
|
$this->_attributes['resultCacheImpl'] : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -218,7 +204,8 @@ class Configuration extends \Doctrine\DBAL\Configuration
|
|||||||
*/
|
*/
|
||||||
public function getQueryCacheImpl()
|
public function getQueryCacheImpl()
|
||||||
{
|
{
|
||||||
return $this->_attributes['queryCacheImpl'];
|
return isset($this->_attributes['queryCacheImpl']) ?
|
||||||
|
$this->_attributes['queryCacheImpl'] : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -238,7 +225,8 @@ class Configuration extends \Doctrine\DBAL\Configuration
|
|||||||
*/
|
*/
|
||||||
public function getMetadataCacheImpl()
|
public function getMetadataCacheImpl()
|
||||||
{
|
{
|
||||||
return $this->_attributes['metadataCacheImpl'];
|
return isset($this->_attributes['metadataCacheImpl']) ?
|
||||||
|
$this->_attributes['metadataCacheImpl'] : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -259,7 +247,8 @@ class Configuration extends \Doctrine\DBAL\Configuration
|
|||||||
*/
|
*/
|
||||||
public function getUseCExtension()
|
public function getUseCExtension()
|
||||||
{
|
{
|
||||||
return $this->_attributes['useCExtension'];
|
return isset($this->_attributes['useCExtension']) ?
|
||||||
|
$this->_attributes['useCExtension'] : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -350,6 +339,8 @@ class Configuration extends \Doctrine\DBAL\Configuration
|
|||||||
* Such a function can then be used in any DQL statement in any place where string
|
* Such a function can then be used in any DQL statement in any place where string
|
||||||
* functions are allowed.
|
* functions are allowed.
|
||||||
*
|
*
|
||||||
|
* DQL function names are case-insensitive.
|
||||||
|
*
|
||||||
* @param string $name
|
* @param string $name
|
||||||
* @param string $className
|
* @param string $className
|
||||||
*/
|
*/
|
||||||
@ -366,15 +357,33 @@ class Configuration extends \Doctrine\DBAL\Configuration
|
|||||||
*/
|
*/
|
||||||
public function getCustomStringFunction($name)
|
public function getCustomStringFunction($name)
|
||||||
{
|
{
|
||||||
|
$name = strtolower($name);
|
||||||
return isset($this->_attributes['customStringFunctions'][$name]) ?
|
return isset($this->_attributes['customStringFunctions'][$name]) ?
|
||||||
$this->_attributes['customStringFunctions'][$name] : null;
|
$this->_attributes['customStringFunctions'][$name] : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a map of custom DQL string functions.
|
||||||
|
*
|
||||||
|
* Keys must be function names and values the FQCN of the implementing class.
|
||||||
|
* The function names will be case-insensitive in DQL.
|
||||||
|
*
|
||||||
|
* Any previously added string functions are discarded.
|
||||||
|
*
|
||||||
|
* @param array $functions The map of custom DQL string functions.
|
||||||
|
*/
|
||||||
|
public function setCustomStringFunctions(array $functions)
|
||||||
|
{
|
||||||
|
$this->_attributes['customStringFunctions'] = array_change_key_case($functions);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Registers a custom DQL function that produces a numeric value.
|
* Registers a custom DQL function that produces a numeric value.
|
||||||
* Such a function can then be used in any DQL statement in any place where numeric
|
* Such a function can then be used in any DQL statement in any place where numeric
|
||||||
* functions are allowed.
|
* functions are allowed.
|
||||||
*
|
*
|
||||||
|
* DQL function names are case-insensitive.
|
||||||
|
*
|
||||||
* @param string $name
|
* @param string $name
|
||||||
* @param string $className
|
* @param string $className
|
||||||
*/
|
*/
|
||||||
@ -391,15 +400,33 @@ class Configuration extends \Doctrine\DBAL\Configuration
|
|||||||
*/
|
*/
|
||||||
public function getCustomNumericFunction($name)
|
public function getCustomNumericFunction($name)
|
||||||
{
|
{
|
||||||
|
$name = strtolower($name);
|
||||||
return isset($this->_attributes['customNumericFunctions'][$name]) ?
|
return isset($this->_attributes['customNumericFunctions'][$name]) ?
|
||||||
$this->_attributes['customNumericFunctions'][$name] : null;
|
$this->_attributes['customNumericFunctions'][$name] : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a map of custom DQL numeric functions.
|
||||||
|
*
|
||||||
|
* Keys must be function names and values the FQCN of the implementing class.
|
||||||
|
* The function names will be case-insensitive in DQL.
|
||||||
|
*
|
||||||
|
* Any previously added numeric functions are discarded.
|
||||||
|
*
|
||||||
|
* @param array $functions The map of custom DQL numeric functions.
|
||||||
|
*/
|
||||||
|
public function setCustomNumericFunctions(array $functions)
|
||||||
|
{
|
||||||
|
$this->_attributes['customNumericFunctions'] = array_change_key_case($functions);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Registers a custom DQL function that produces a date/time value.
|
* Registers a custom DQL function that produces a date/time value.
|
||||||
* Such a function can then be used in any DQL statement in any place where date/time
|
* Such a function can then be used in any DQL statement in any place where date/time
|
||||||
* functions are allowed.
|
* functions are allowed.
|
||||||
*
|
*
|
||||||
|
* DQL function names are case-insensitive.
|
||||||
|
*
|
||||||
* @param string $name
|
* @param string $name
|
||||||
* @param string $className
|
* @param string $className
|
||||||
*/
|
*/
|
||||||
@ -416,7 +443,23 @@ class Configuration extends \Doctrine\DBAL\Configuration
|
|||||||
*/
|
*/
|
||||||
public function getCustomDatetimeFunction($name)
|
public function getCustomDatetimeFunction($name)
|
||||||
{
|
{
|
||||||
|
$name = strtolower($name);
|
||||||
return isset($this->_attributes['customDatetimeFunctions'][$name]) ?
|
return isset($this->_attributes['customDatetimeFunctions'][$name]) ?
|
||||||
$this->_attributes['customDatetimeFunctions'][$name] : null;
|
$this->_attributes['customDatetimeFunctions'][$name] : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a map of custom DQL date/time functions.
|
||||||
|
*
|
||||||
|
* Keys must be function names and values the FQCN of the implementing class.
|
||||||
|
* The function names will be case-insensitive in DQL.
|
||||||
|
*
|
||||||
|
* Any previously added date/time functions are discarded.
|
||||||
|
*
|
||||||
|
* @param array $functions The map of custom DQL date/time functions.
|
||||||
|
*/
|
||||||
|
public function setCustomDatetimeFunctions(array $functions)
|
||||||
|
{
|
||||||
|
$this->_attributes['customDatetimeFunctions'] = array_change_key_case($functions);
|
||||||
|
}
|
||||||
}
|
}
|
@ -440,7 +440,8 @@ class EntityManager
|
|||||||
*
|
*
|
||||||
* @param object $entity The entity to copy.
|
* @param object $entity The entity to copy.
|
||||||
* @return object The new entity.
|
* @return object The new entity.
|
||||||
* @todo Implementation or remove.
|
* @todo Implementation need. This is necessary since $e2 = clone $e1; throws an E_FATAL when access anything on $e:
|
||||||
|
* Fatal error: Maximum function nesting level of '100' reached, aborting!
|
||||||
*/
|
*/
|
||||||
public function copy($entity, $deep = false)
|
public function copy($entity, $deep = false)
|
||||||
{
|
{
|
||||||
|
@ -43,6 +43,7 @@ class SingleScalarHydrator extends AbstractHydrator
|
|||||||
} else if ($num > 1 || count($result[key($result)]) > 1) {
|
} else if ($num > 1 || count($result[key($result)]) > 1) {
|
||||||
throw new \Doctrine\ORM\NonUniqueResultException;
|
throw new \Doctrine\ORM\NonUniqueResultException;
|
||||||
}
|
}
|
||||||
|
|
||||||
$result = $this->_gatherScalarRowData($result[key($result)], $cache);
|
$result = $this->_gatherScalarRowData($result[key($result)], $cache);
|
||||||
|
|
||||||
return array_shift($result);
|
return array_shift($result);
|
||||||
|
@ -26,7 +26,6 @@ use Doctrine\ORM\Mapping\ClassMetadata;
|
|||||||
* SINGLE_TABLE strategy.
|
* SINGLE_TABLE strategy.
|
||||||
*
|
*
|
||||||
* @author Roman Borschel <roman@code-factory.org>
|
* @author Roman Borschel <roman@code-factory.org>
|
||||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
|
||||||
* @since 2.0
|
* @since 2.0
|
||||||
* @link http://martinfowler.com/eaaCatalog/singleTableInheritance.html
|
* @link http://martinfowler.com/eaaCatalog/singleTableInheritance.html
|
||||||
*/
|
*/
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
/*
|
/*
|
||||||
* $Id$
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
@ -31,10 +29,7 @@ namespace Doctrine\ORM\Query\AST;
|
|||||||
* SimpleStateFieldPathExpression ::= IdentificationVariable "." StateField
|
* SimpleStateFieldPathExpression ::= IdentificationVariable "." StateField
|
||||||
* SimpleStateFieldAssociationPathExpression ::= SingleValuedAssociationPathExpression "." StateField
|
* SimpleStateFieldAssociationPathExpression ::= SingleValuedAssociationPathExpression "." StateField
|
||||||
*
|
*
|
||||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
|
||||||
* @link www.doctrine-project.org
|
|
||||||
* @since 2.0
|
* @since 2.0
|
||||||
* @version $Revision: 3938 $
|
|
||||||
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||||
* @author Jonathan Wage <jonwage@gmail.com>
|
* @author Jonathan Wage <jonwage@gmail.com>
|
||||||
* @author Roman Borschel <roman@code-factory.org>
|
* @author Roman Borschel <roman@code-factory.org>
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
/*
|
/*
|
||||||
* $Id$
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
@ -27,10 +25,7 @@ use Doctrine\ORM\Query;
|
|||||||
* An LL(*) recursive-descent parser for the context-free grammar of the Doctrine Query Language.
|
* An LL(*) recursive-descent parser for the context-free grammar of the Doctrine Query Language.
|
||||||
* Parses a DQL query, reports any errors in it, and generates an AST.
|
* Parses a DQL query, reports any errors in it, and generates an AST.
|
||||||
*
|
*
|
||||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
|
||||||
* @link www.doctrine-project.org
|
|
||||||
* @since 2.0
|
* @since 2.0
|
||||||
* @version $Revision: 3938 $
|
|
||||||
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||||
* @author Jonathan Wage <jonwage@gmail.com>
|
* @author Jonathan Wage <jonwage@gmail.com>
|
||||||
* @author Roman Borschel <roman@code-factory.org>
|
* @author Roman Borschel <roman@code-factory.org>
|
||||||
@ -208,12 +203,15 @@ class Parser
|
|||||||
// Process any deferred validations of some nodes in the AST.
|
// Process any deferred validations of some nodes in the AST.
|
||||||
// This also allows post-processing of the AST for modification purposes.
|
// This also allows post-processing of the AST for modification purposes.
|
||||||
$this->_processDeferredIdentificationVariables();
|
$this->_processDeferredIdentificationVariables();
|
||||||
|
|
||||||
if ($this->_deferredPartialObjectExpressions) {
|
if ($this->_deferredPartialObjectExpressions) {
|
||||||
$this->_processDeferredPartialObjectExpressions();
|
$this->_processDeferredPartialObjectExpressions();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->_deferredPathExpressions) {
|
if ($this->_deferredPathExpressions) {
|
||||||
$this->_processDeferredPathExpressions($AST);
|
$this->_processDeferredPathExpressions($AST);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->_deferredResultVariables) {
|
if ($this->_deferredResultVariables) {
|
||||||
$this->_processDeferredResultVariables();
|
$this->_processDeferredResultVariables();
|
||||||
}
|
}
|
||||||
@ -557,11 +555,16 @@ class Parser
|
|||||||
{
|
{
|
||||||
foreach ($this->_deferredPathExpressions as $deferredItem) {
|
foreach ($this->_deferredPathExpressions as $deferredItem) {
|
||||||
$pathExpression = $deferredItem['expression'];
|
$pathExpression = $deferredItem['expression'];
|
||||||
$parts = $pathExpression->parts;
|
|
||||||
$numParts = count($parts);
|
|
||||||
|
|
||||||
$qComp = $this->_queryComponents[$pathExpression->identificationVariable];
|
$qComp = $this->_queryComponents[$pathExpression->identificationVariable];
|
||||||
|
$numParts = count($pathExpression->parts);
|
||||||
|
|
||||||
|
if ($numParts == 0) {
|
||||||
|
$pathExpression->parts = array($qComp['metadata']->identifier[0]);
|
||||||
|
$numParts++;
|
||||||
|
}
|
||||||
|
|
||||||
|
$parts = $pathExpression->parts;
|
||||||
$aliasIdentificationVariable = $pathExpression->identificationVariable;
|
$aliasIdentificationVariable = $pathExpression->identificationVariable;
|
||||||
$parentField = $pathExpression->identificationVariable;
|
$parentField = $pathExpression->identificationVariable;
|
||||||
$class = $qComp['metadata'];
|
$class = $qComp['metadata'];
|
||||||
@ -625,6 +628,7 @@ class Parser
|
|||||||
),
|
),
|
||||||
null
|
null
|
||||||
);
|
);
|
||||||
|
|
||||||
$AST->fromClause->identificationVariableDeclarations[0]->joinVariableDeclarations[] = $joinVariableDeclaration;
|
$AST->fromClause->identificationVariableDeclarations[0]->joinVariableDeclarations[] = $joinVariableDeclaration;
|
||||||
|
|
||||||
$this->_queryComponents[$aliasIdentificationVariable . '.' . $field] = $joinQueryComponent;
|
$this->_queryComponents[$aliasIdentificationVariable . '.' . $field] = $joinQueryComponent;
|
||||||
@ -915,12 +919,12 @@ class Parser
|
|||||||
$identVariable = $this->IdentificationVariable();
|
$identVariable = $this->IdentificationVariable();
|
||||||
$parts = array();
|
$parts = array();
|
||||||
|
|
||||||
do {
|
while ($this->_lexer->isNextToken(Lexer::T_DOT)) {
|
||||||
$this->match(Lexer::T_DOT);
|
$this->match(Lexer::T_DOT);
|
||||||
$this->match(Lexer::T_IDENTIFIER);
|
$this->match(Lexer::T_IDENTIFIER);
|
||||||
|
|
||||||
$parts[] = $this->_lexer->token['value'];
|
$parts[] = $this->_lexer->token['value'];
|
||||||
} while ($this->_lexer->isNextToken(Lexer::T_DOT));
|
}
|
||||||
|
|
||||||
// Creating AST node
|
// Creating AST node
|
||||||
$pathExpr = new AST\PathExpression($expectedTypes, $identVariable, $parts);
|
$pathExpr = new AST\PathExpression($expectedTypes, $identVariable, $parts);
|
||||||
@ -2168,7 +2172,7 @@ class Parser
|
|||||||
return $this->SingleValuedPathExpression();
|
return $this->SingleValuedPathExpression();
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->IdentificationVariable();
|
return $this->SimpleStateFieldPathExpression();
|
||||||
|
|
||||||
case Lexer::T_INPUT_PARAMETER:
|
case Lexer::T_INPUT_PARAMETER:
|
||||||
return $this->InputParameter();
|
return $this->InputParameter();
|
||||||
@ -2619,9 +2623,10 @@ class Parser
|
|||||||
|
|
||||||
public function CustomFunctionsReturningNumerics()
|
public function CustomFunctionsReturningNumerics()
|
||||||
{
|
{
|
||||||
$funcNameLower = strtolower($this->_lexer->lookahead['value']);
|
$funcName = strtolower($this->_lexer->lookahead['value']);
|
||||||
$funcClass = $this->_em->getConfiguration()->getCustomNumericFunction($funcNameLower);
|
// getCustomNumericFunction is case-insensitive
|
||||||
$function = new $funcClass($funcNameLower);
|
$funcClass = $this->_em->getConfiguration()->getCustomNumericFunction($funcName);
|
||||||
|
$function = new $funcClass($funcName);
|
||||||
$function->parse($this);
|
$function->parse($this);
|
||||||
|
|
||||||
return $function;
|
return $function;
|
||||||
@ -2642,9 +2647,10 @@ class Parser
|
|||||||
|
|
||||||
public function CustomFunctionsReturningDatetime()
|
public function CustomFunctionsReturningDatetime()
|
||||||
{
|
{
|
||||||
$funcNameLower = strtolower($this->_lexer->lookahead['value']);
|
$funcName = $this->_lexer->lookahead['value'];
|
||||||
$funcClass = $this->_em->getConfiguration()->getCustomDatetimeFunction($funcNameLower);
|
// getCustomDatetimeFunction is case-insensitive
|
||||||
$function = new $funcClass($funcNameLower);
|
$funcClass = $this->_em->getConfiguration()->getCustomDatetimeFunction($funcName);
|
||||||
|
$function = new $funcClass($funcName);
|
||||||
$function->parse($this);
|
$function->parse($this);
|
||||||
|
|
||||||
return $function;
|
return $function;
|
||||||
@ -2670,9 +2676,10 @@ class Parser
|
|||||||
|
|
||||||
public function CustomFunctionsReturningStrings()
|
public function CustomFunctionsReturningStrings()
|
||||||
{
|
{
|
||||||
$funcNameLower = strtolower($this->_lexer->lookahead['value']);
|
$funcName = $this->_lexer->lookahead['value'];
|
||||||
$funcClass = $this->_em->getConfiguration()->getCustomStringFunction($funcNameLower);
|
// getCustomStringFunction is case-insensitive
|
||||||
$function = new $funcClass($funcNameLower);
|
$funcClass = $this->_em->getConfiguration()->getCustomStringFunction($funcName);
|
||||||
|
$function = new $funcClass($funcName);
|
||||||
$function->parse($this);
|
$function->parse($this);
|
||||||
|
|
||||||
return $function;
|
return $function;
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
/*
|
/*
|
||||||
* $Id$
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
@ -240,16 +238,17 @@ class SqlWalker implements TreeWalker
|
|||||||
{
|
{
|
||||||
$sql = '';
|
$sql = '';
|
||||||
|
|
||||||
$baseTableAlias = $this->getSqlTableAlias($class->table['name'], $dqlAlias);
|
$baseTableAlias = $this->getSQLTableAlias($class->table['name'], $dqlAlias);
|
||||||
|
|
||||||
// INNER JOIN parent class tables
|
// INNER JOIN parent class tables
|
||||||
foreach ($class->parentClasses as $parentClassName) {
|
foreach ($class->parentClasses as $parentClassName) {
|
||||||
$parentClass = $this->_em->getClassMetadata($parentClassName);
|
$parentClass = $this->_em->getClassMetadata($parentClassName);
|
||||||
$tableAlias = $this->getSqlTableAlias($parentClass->table['name'], $dqlAlias);
|
$tableAlias = $this->getSQLTableAlias($parentClass->table['name'], $dqlAlias);
|
||||||
$sql .= ' INNER JOIN ' . $parentClass->getQuotedTableName($this->_platform)
|
// If this is a joined association we must use left joins to preserve the correct result.
|
||||||
|
$sql .= isset($this->_queryComponents[$dqlAlias]['relation']) ? ' LEFT ' : ' INNER ';
|
||||||
|
$sql .= 'JOIN ' . $parentClass->getQuotedTableName($this->_platform)
|
||||||
. ' ' . $tableAlias . ' ON ';
|
. ' ' . $tableAlias . ' ON ';
|
||||||
$first = true;
|
$first = true;
|
||||||
|
|
||||||
foreach ($class->identifier as $idField) {
|
foreach ($class->identifier as $idField) {
|
||||||
if ($first) $first = false; else $sql .= ' AND ';
|
if ($first) $first = false; else $sql .= ' AND ';
|
||||||
|
|
||||||
@ -260,14 +259,13 @@ class SqlWalker implements TreeWalker
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// LEFT JOIN subclass tables, if partial objects disallowed
|
// LEFT JOIN subclass tables, if partial objects disallowed.
|
||||||
if ( ! $this->_query->getHint(Query::HINT_FORCE_PARTIAL_LOAD)) {
|
if ( ! $this->_query->getHint(Query::HINT_FORCE_PARTIAL_LOAD)) {
|
||||||
foreach ($class->subClasses as $subClassName) {
|
foreach ($class->subClasses as $subClassName) {
|
||||||
$subClass = $this->_em->getClassMetadata($subClassName);
|
$subClass = $this->_em->getClassMetadata($subClassName);
|
||||||
$tableAlias = $this->getSqlTableAlias($subClass->table['name'], $dqlAlias);
|
$tableAlias = $this->getSQLTableAlias($subClass->table['name'], $dqlAlias);
|
||||||
$sql .= ' LEFT JOIN ' . $subClass->getQuotedTableName($this->_platform)
|
$sql .= ' LEFT JOIN ' . $subClass->getQuotedTableName($this->_platform)
|
||||||
. ' ' . $tableAlias . ' ON ';
|
. ' ' . $tableAlias . ' ON ';
|
||||||
|
|
||||||
$first = true;
|
$first = true;
|
||||||
foreach ($class->identifier as $idField) {
|
foreach ($class->identifier as $idField) {
|
||||||
if ($first) $first = false; else $sql .= ' AND ';
|
if ($first) $first = false; else $sql .= ' AND ';
|
||||||
@ -458,6 +456,7 @@ class SqlWalker implements TreeWalker
|
|||||||
|
|
||||||
$sql .= $class->getQuotedColumnName($fieldName, $this->_platform);
|
$sql .= $class->getQuotedColumnName($fieldName, $this->_platform);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AST\PathExpression::TYPE_SINGLE_VALUED_ASSOCIATION:
|
case AST\PathExpression::TYPE_SINGLE_VALUED_ASSOCIATION:
|
||||||
// 1- the owning side:
|
// 1- the owning side:
|
||||||
// Just use the foreign key, i.e. u.group_id
|
// Just use the foreign key, i.e. u.group_id
|
||||||
@ -477,13 +476,18 @@ class SqlWalker implements TreeWalker
|
|||||||
if (count($assoc->sourceToTargetKeyColumns) > 1) {
|
if (count($assoc->sourceToTargetKeyColumns) > 1) {
|
||||||
throw QueryException::associationPathCompositeKeyNotSupported();
|
throw QueryException::associationPathCompositeKeyNotSupported();
|
||||||
}
|
}
|
||||||
$sql .= $this->getSqlTableAlias($class->table['name'], $dqlAlias) . '.'
|
|
||||||
. reset($assoc->targetToSourceKeyColumns);
|
if ($this->_useSqlTableAliases) {
|
||||||
|
$sql .= $this->getSqlTableAlias($class->table['name'], $dqlAlias) . '.';
|
||||||
|
}
|
||||||
|
|
||||||
|
$sql .= reset($assoc->targetToSourceKeyColumns);
|
||||||
} else {
|
} else {
|
||||||
// 2- Inverse side: NOT (YET?) SUPPORTED
|
// 2- Inverse side: NOT (YET?) SUPPORTED
|
||||||
throw QueryException::associationPathInverseSideNotSupported();
|
throw QueryException::associationPathInverseSideNotSupported();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw QueryException::invalidPathExpression($pathExpr);
|
throw QueryException::invalidPathExpression($pathExpr);
|
||||||
}
|
}
|
||||||
|
@ -6,9 +6,9 @@ namespace Doctrine\Tests\Models\Company;
|
|||||||
* @Entity @Table(name="company_events")
|
* @Entity @Table(name="company_events")
|
||||||
* @InheritanceType("JOINED")
|
* @InheritanceType("JOINED")
|
||||||
* @DiscriminatorColumn(name="event_type", type="string")
|
* @DiscriminatorColumn(name="event_type", type="string")
|
||||||
* @DiscriminatorMap({"auction" = "CompanyAuction", "raffle" = "CompanyRaffle"})
|
* @DiscriminatorMap({"auction"="CompanyAuction", "raffle"="CompanyRaffle"})
|
||||||
*/
|
*/
|
||||||
class CompanyEvent {
|
abstract class CompanyEvent {
|
||||||
/**
|
/**
|
||||||
* @Id @Column(type="integer")
|
* @Id @Column(type="integer")
|
||||||
* @GeneratedValue
|
* @GeneratedValue
|
||||||
|
@ -294,5 +294,4 @@ class ClassTableInheritanceTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
|||||||
->getResult()) > 0);
|
->getResult()) > 0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
94
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC512Test.php
Normal file
94
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC512Test.php
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
<?php
|
||||||
|
namespace Doctrine\Tests\ORM\Functional\Ticket;
|
||||||
|
|
||||||
|
require_once __DIR__ . '/../../../TestInit.php';
|
||||||
|
|
||||||
|
class DDC512Test extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||||
|
{
|
||||||
|
protected function setUp()
|
||||||
|
{
|
||||||
|
parent::setUp();
|
||||||
|
$this->_schemaTool->createSchema(array(
|
||||||
|
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC512Customer'),
|
||||||
|
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC512OfferItem'),
|
||||||
|
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC512Item'),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testIssue()
|
||||||
|
{
|
||||||
|
$customer1 = new DDC512Customer();
|
||||||
|
$item = new DDC512OfferItem();
|
||||||
|
$customer1->item = $item;
|
||||||
|
$this->_em->persist($customer1);
|
||||||
|
|
||||||
|
$customer2 = new DDC512Customer();
|
||||||
|
$this->_em->persist($customer2);
|
||||||
|
|
||||||
|
$this->_em->flush();
|
||||||
|
$this->_em->clear();
|
||||||
|
|
||||||
|
$q = $this->_em->createQuery("select u,i from ".__NAMESPACE__."\\DDC512Customer u left join u.item i");
|
||||||
|
$result = $q->getResult();
|
||||||
|
|
||||||
|
$this->assertEquals(2, count($result));
|
||||||
|
$this->assertTrue($result[0] instanceof DDC512Customer);
|
||||||
|
$this->assertTrue($result[1] instanceof DDC512Customer);
|
||||||
|
if ($result[0]->id == $customer1->id) {
|
||||||
|
$this->assertTrue($result[0]->item instanceof DDC512OfferItem);
|
||||||
|
$this->assertEquals($item->id, $result[0]->item->id);
|
||||||
|
$this->assertNull($result[1]->item);
|
||||||
|
} else {
|
||||||
|
$this->assertTrue($result[1]->item instanceof DDC512OfferItem);
|
||||||
|
$this->assertNull($result[0]->item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Entity
|
||||||
|
*/
|
||||||
|
class DDC512Customer {
|
||||||
|
/**
|
||||||
|
* @Id
|
||||||
|
* @Column(type="integer")
|
||||||
|
* @GeneratedValue(strategy="AUTO")
|
||||||
|
*/
|
||||||
|
public $id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* NOTE that we can currently not name the join column the same as the field
|
||||||
|
* (item = item), this currently confuses Doctrine.
|
||||||
|
*
|
||||||
|
* @OneToOne(targetEntity="DDC512OfferItem", cascade={"remove","persist"})
|
||||||
|
* @JoinColumn(name="item_id", referencedColumnName="id")
|
||||||
|
*/
|
||||||
|
public $item;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Entity
|
||||||
|
*/
|
||||||
|
class DDC512OfferItem extends DDC512Item
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Entity
|
||||||
|
* @InheritanceType("JOINED")
|
||||||
|
* @DiscriminatorColumn(name="discr", type="string")
|
||||||
|
* @DiscriminatorMap({"item" = "DDC512Item", "offerItem" = "DDC512OfferItem"})
|
||||||
|
*/
|
||||||
|
class DDC512Item
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @Id
|
||||||
|
* @Column(type="integer")
|
||||||
|
* @GeneratedValue(strategy="AUTO")
|
||||||
|
*/
|
||||||
|
public $id;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -21,6 +21,7 @@ class SelectSqlGenerationTest extends \Doctrine\Tests\OrmTestCase
|
|||||||
$query = $this->_em->createQuery($dqlToBeTested);
|
$query = $this->_em->createQuery($dqlToBeTested);
|
||||||
$query->setHint(Query::HINT_FORCE_PARTIAL_LOAD, true)
|
$query->setHint(Query::HINT_FORCE_PARTIAL_LOAD, true)
|
||||||
->useQueryCache(false);
|
->useQueryCache(false);
|
||||||
|
|
||||||
parent::assertEquals($sqlToBeConfirmed, $query->getSql());
|
parent::assertEquals($sqlToBeConfirmed, $query->getSql());
|
||||||
$query->free();
|
$query->free();
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
@ -385,7 +386,7 @@ class SelectSqlGenerationTest extends \Doctrine\Tests\OrmTestCase
|
|||||||
$this->assertEquals('SELECT d0_.id AS id0 FROM date_time_model d0_ WHERE d0_.col_datetime > CURRENT_TIMESTAMP', $q->getSql());
|
$this->assertEquals('SELECT d0_.id AS id0 FROM date_time_model d0_ WHERE d0_.col_datetime > CURRENT_TIMESTAMP', $q->getSql());
|
||||||
}
|
}
|
||||||
|
|
||||||
/*public function testExistsExpressionInWhereCorrelatedSubqueryAssocCondition()
|
public function testExistsExpressionInWhereCorrelatedSubqueryAssocCondition()
|
||||||
{
|
{
|
||||||
$this->assertSqlGeneration(
|
$this->assertSqlGeneration(
|
||||||
// DQL
|
// DQL
|
||||||
@ -402,7 +403,7 @@ class SelectSqlGenerationTest extends \Doctrine\Tests\OrmTestCase
|
|||||||
. ')'
|
. ')'
|
||||||
|
|
||||||
);
|
);
|
||||||
}*/
|
}
|
||||||
|
|
||||||
public function testLimitFromQueryClass()
|
public function testLimitFromQueryClass()
|
||||||
{
|
{
|
||||||
@ -584,4 +585,62 @@ class SelectSqlGenerationTest extends \Doctrine\Tests\OrmTestCase
|
|||||||
"SELECT c0_.name AS name0, (SELECT COUNT(c1_.phonenumber) AS dctrn__1 FROM cms_phonenumbers c1_ WHERE c1_.phonenumber = 1234) AS sclr1 FROM cms_users c0_ WHERE c0_.name = 'jon'"
|
"SELECT c0_.name AS name0, (SELECT COUNT(c1_.phonenumber) AS dctrn__1 FROM cms_phonenumbers c1_ WHERE c1_.phonenumber = 1234) AS sclr1 FROM cms_users c0_ WHERE c0_.name = 'jon'"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DDC-430
|
||||||
|
*/
|
||||||
|
public function testSupportSelectWithMoreThan10InputParameters()
|
||||||
|
{
|
||||||
|
$this->assertSqlGeneration(
|
||||||
|
"SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = ?1 OR u.id = ?2 OR u.id = ?3 OR u.id = ?4 OR u.id = ?5 OR u.id = ?6 OR u.id = ?7 OR u.id = ?8 OR u.id = ?9 OR u.id = ?10 OR u.id = ?11",
|
||||||
|
"SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3 FROM cms_users c0_ WHERE c0_.id = ? OR c0_.id = ? OR c0_.id = ? OR c0_.id = ? OR c0_.id = ? OR c0_.id = ? OR c0_.id = ? OR c0_.id = ? OR c0_.id = ? OR c0_.id = ? OR c0_.id = ?"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DDC-431
|
||||||
|
*/
|
||||||
|
public function testSupportToCustomDQLFunctions()
|
||||||
|
{
|
||||||
|
$config = $this->_em->getConfiguration();
|
||||||
|
$config->addCustomNumericFunction('MYABS', 'Doctrine\Tests\ORM\Query\MyAbsFunction');
|
||||||
|
|
||||||
|
$this->assertSqlGeneration(
|
||||||
|
'SELECT MYABS(p.phonenumber) FROM Doctrine\Tests\Models\CMS\CmsPhonenumber p',
|
||||||
|
'SELECT ABS(c0_.phonenumber) AS sclr0 FROM cms_phonenumbers c0_'
|
||||||
|
);
|
||||||
|
|
||||||
|
$config->setCustomNumericFunctions(array());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class MyAbsFunction extends \Doctrine\ORM\Query\AST\Functions\FunctionNode
|
||||||
|
{
|
||||||
|
public $simpleArithmeticExpression;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @override
|
||||||
|
*/
|
||||||
|
public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker)
|
||||||
|
{
|
||||||
|
return 'ABS(' . $sqlWalker->walkSimpleArithmeticExpression(
|
||||||
|
$this->simpleArithmeticExpression
|
||||||
|
) . ')';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @override
|
||||||
|
*/
|
||||||
|
public function parse(\Doctrine\ORM\Query\Parser $parser)
|
||||||
|
{
|
||||||
|
$lexer = $parser->getLexer();
|
||||||
|
|
||||||
|
$parser->match(\Doctrine\ORM\Query\Lexer::T_IDENTIFIER);
|
||||||
|
$parser->match(\Doctrine\ORM\Query\Lexer::T_OPEN_PARENTHESIS);
|
||||||
|
|
||||||
|
$this->simpleArithmeticExpression = $parser->SimpleArithmeticExpression();
|
||||||
|
|
||||||
|
$parser->match(\Doctrine\ORM\Query\Lexer::T_CLOSE_PARENTHESIS);
|
||||||
|
}
|
||||||
}
|
}
|
@ -159,4 +159,12 @@ class UpdateSqlGenerationTest extends \Doctrine\Tests\OrmTestCase
|
|||||||
'UPDATE cms_users SET status = ? WHERE id BETWEEN ? AND ?'
|
'UPDATE cms_users SET status = ? WHERE id BETWEEN ? AND ?'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testSingleValuedAssociationFieldInWhere()
|
||||||
|
{
|
||||||
|
$this->assertSqlGeneration(
|
||||||
|
"UPDATE Doctrine\Tests\Models\CMS\CmsPhonenumber p SET p.phonenumber = 1234 WHERE p.user = ?1",
|
||||||
|
"UPDATE cms_phonenumbers SET phonenumber = 1234 WHERE user_id = ?"
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ abstract class OrmFunctionalTestCase extends OrmTestCase
|
|||||||
private static $_queryCacheImpl = null;
|
private static $_queryCacheImpl = null;
|
||||||
|
|
||||||
/* Shared connection when a TestCase is run alone (outside of it's functional suite) */
|
/* Shared connection when a TestCase is run alone (outside of it's functional suite) */
|
||||||
private static $_sharedConn;
|
protected static $_sharedConn;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var \Doctrine\ORM\EntityManager
|
* @var \Doctrine\ORM\EntityManager
|
||||||
@ -33,13 +33,13 @@ abstract class OrmFunctionalTestCase extends OrmTestCase
|
|||||||
protected $_sqlLoggerStack;
|
protected $_sqlLoggerStack;
|
||||||
|
|
||||||
/** The names of the model sets used in this testcase. */
|
/** The names of the model sets used in this testcase. */
|
||||||
private $_usedModelSets = array();
|
protected $_usedModelSets = array();
|
||||||
|
|
||||||
/** Whether the database schema has already been created. */
|
/** Whether the database schema has already been created. */
|
||||||
private static $_tablesCreated = array();
|
protected static $_tablesCreated = array();
|
||||||
|
|
||||||
/** List of model sets and their classes. */
|
/** List of model sets and their classes. */
|
||||||
private static $_modelSets = array(
|
protected static $_modelSets = array(
|
||||||
'cms' => array(
|
'cms' => array(
|
||||||
'Doctrine\Tests\Models\CMS\CmsUser',
|
'Doctrine\Tests\Models\CMS\CmsUser',
|
||||||
'Doctrine\Tests\Models\CMS\CmsPhonenumber',
|
'Doctrine\Tests\Models\CMS\CmsPhonenumber',
|
||||||
@ -170,11 +170,11 @@ abstract class OrmFunctionalTestCase extends OrmTestCase
|
|||||||
$forceCreateTables = false;
|
$forceCreateTables = false;
|
||||||
|
|
||||||
if ( ! isset($this->sharedFixture['conn'])) {
|
if ( ! isset($this->sharedFixture['conn'])) {
|
||||||
if ( ! isset(self::$_sharedConn)) {
|
if ( ! isset(static::$_sharedConn)) {
|
||||||
self::$_sharedConn = TestUtil::getConnection();
|
static::$_sharedConn = TestUtil::getConnection();
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->sharedFixture['conn'] = self::$_sharedConn;
|
$this->sharedFixture['conn'] = static::$_sharedConn;
|
||||||
|
|
||||||
if ($this->sharedFixture['conn']->getDriver() instanceof \Doctrine\DBAL\Driver\PDOSqlite\Driver) {
|
if ($this->sharedFixture['conn']->getDriver() instanceof \Doctrine\DBAL\Driver\PDOSqlite\Driver) {
|
||||||
$forceCreateTables = true;
|
$forceCreateTables = true;
|
||||||
@ -189,12 +189,12 @@ abstract class OrmFunctionalTestCase extends OrmTestCase
|
|||||||
$classes = array();
|
$classes = array();
|
||||||
|
|
||||||
foreach ($this->_usedModelSets as $setName => $bool) {
|
foreach ($this->_usedModelSets as $setName => $bool) {
|
||||||
if ( ! isset(self::$_tablesCreated[$setName])/* || $forceCreateTables*/) {
|
if ( ! isset(static::$_tablesCreated[$setName])/* || $forceCreateTables*/) {
|
||||||
foreach (self::$_modelSets[$setName] as $className) {
|
foreach (static::$_modelSets[$setName] as $className) {
|
||||||
$classes[] = $this->_em->getClassMetadata($className);
|
$classes[] = $this->_em->getClassMetadata($className);
|
||||||
}
|
}
|
||||||
|
|
||||||
self::$_tablesCreated[$setName] = true;
|
static::$_tablesCreated[$setName] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user