[2.0][DDC-284] Fixed. API polish and some convention over configuration simplifications for join columns and join tables.
This commit is contained in:
parent
da2c329e60
commit
4adc289596
@ -113,11 +113,11 @@
|
||||
<xs:enumeration value="EAGER"/>
|
||||
<xs:enumeration value="LAZY"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
</xs:simpleType>
|
||||
|
||||
<xs:complexType name="field">
|
||||
<xs:attribute name="name" type="xs:NMTOKEN" use="required" />
|
||||
<xs:attribute name="type" type="xs:NMTOKEN" use="required" />
|
||||
<xs:attribute name="type" type="xs:NMTOKEN" default="string" />
|
||||
<xs:attribute name="column" type="xs:NMTOKEN" />
|
||||
<xs:attribute name="length" type="xs:NMTOKEN" />
|
||||
<xs:attribute name="unique" type="xs:boolean" default="false" />
|
||||
@ -167,7 +167,7 @@
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="generator">
|
||||
<xs:attribute name="strategy" type="orm:generator-strategy" use="required" />
|
||||
<xs:attribute name="strategy" type="orm:generator-strategy" use="optional" default="AUTO" />
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="id">
|
||||
@ -187,7 +187,7 @@
|
||||
|
||||
<xs:complexType name="join-column">
|
||||
<xs:attribute name="name" type="xs:NMTOKEN" use="required" />
|
||||
<xs:attribute name="referenced-column-name" type="xs:NMTOKEN" use="required" />
|
||||
<xs:attribute name="referenced-column-name" type="xs:NMTOKEN" use="optional" default="id" />
|
||||
<xs:attribute name="unique" type="xs:boolean" default="false" />
|
||||
<xs:attribute name="nullable" type="xs:boolean" default="true" />
|
||||
<xs:attribute name="on-delete" type="orm:fk-action" />
|
||||
@ -213,7 +213,7 @@
|
||||
<xs:complexType name="many-to-many">
|
||||
<xs:sequence>
|
||||
<xs:element name="cascade" type="orm:cascade-type" minOccurs="0" />
|
||||
<xs:element name="join-table" type="orm:join-table" />
|
||||
<xs:element name="join-table" type="orm:join-table" minOccurs="0" />
|
||||
</xs:sequence>
|
||||
<xs:attribute name="target-entity" type="xs:NMTOKEN" use="required" />
|
||||
<xs:attribute name="field" type="xs:NMTOKEN" use="required" />
|
||||
@ -235,7 +235,7 @@
|
||||
<xs:complexType name="many-to-one">
|
||||
<xs:sequence>
|
||||
<xs:element name="cascade" type="orm:cascade-type" minOccurs="0" />
|
||||
<xs:choice minOccurs="1" maxOccurs="1">
|
||||
<xs:choice minOccurs="0" maxOccurs="1">
|
||||
<xs:element name="join-column" type="orm:join-column"/>
|
||||
<xs:element name="join-columns" type="orm:join-columns"/>
|
||||
</xs:choice>
|
||||
|
@ -52,4 +52,14 @@ class Annotation
|
||||
$this->$key = $value;
|
||||
}
|
||||
}
|
||||
|
||||
public function __get($name)
|
||||
{
|
||||
throw new \BadMethodCallException("Unknown annotation property '$name' on annotation '".get_class($this)."'.");
|
||||
}
|
||||
|
||||
public function __set($name, $value)
|
||||
{
|
||||
throw new \BadMethodCallException("Unknown annotation property '$name' on annotation '".get_class($this)."'.");
|
||||
}
|
||||
}
|
@ -82,7 +82,6 @@ class Configuration
|
||||
*
|
||||
* @param array $types Key-value map of types to include
|
||||
* @param boolean $override Optional flag to support only inclusion or also override
|
||||
* @throws DoctrineException
|
||||
*/
|
||||
public function setCustomTypes(array $types, $override = false)
|
||||
{
|
||||
@ -97,7 +96,6 @@ class Configuration
|
||||
* Overrides existent types in Doctrine
|
||||
*
|
||||
* @param array $types Key-value map of types to override
|
||||
* @throws DoctrineException
|
||||
*/
|
||||
public function setTypeOverrides(array $overrides)
|
||||
{
|
||||
|
@ -22,7 +22,6 @@
|
||||
namespace Doctrine\DBAL;
|
||||
|
||||
use Doctrine\Common\EventManager,
|
||||
Doctrine\Common\DoctrineException,
|
||||
Doctrine\DBAL\DBALException;
|
||||
|
||||
/**
|
||||
|
@ -21,8 +21,6 @@
|
||||
|
||||
namespace Doctrine\DBAL;
|
||||
|
||||
use Doctrine\Common\DoctrineException;
|
||||
|
||||
/**
|
||||
* Doctrine\DBAL\ConnectionException
|
||||
*
|
||||
@ -32,20 +30,15 @@ use Doctrine\Common\DoctrineException;
|
||||
* @version $Revision: 4628 $
|
||||
* @author Jonathan H. Wage <jonwage@gmail.com
|
||||
*/
|
||||
class ConnectionException extends DoctrineException
|
||||
class ConnectionException extends DBALException
|
||||
{
|
||||
public static function invalidPDOInstance()
|
||||
public static function commitFailedRollbackOnly()
|
||||
{
|
||||
return new self("Invalid PDO instance provided on connection creation.");
|
||||
}
|
||||
|
||||
public static function driverRequired()
|
||||
{
|
||||
return new self("Please provide a driver or a driverClass to be able to start a Connection.");
|
||||
return new self("Transaction commit failed because the transaction has been marked for rollback only.");
|
||||
}
|
||||
|
||||
public static function unknownDriver($driver)
|
||||
public static function noActiveTransaction()
|
||||
{
|
||||
return new self("Unknown Connection driver '$driver'.");
|
||||
return new self("There is no active transaction.");
|
||||
}
|
||||
}
|
@ -21,7 +21,6 @@
|
||||
|
||||
namespace Doctrine\DBAL;
|
||||
|
||||
use Doctrine\Common\DoctrineException;
|
||||
use Doctrine\Common\EventManager;
|
||||
|
||||
/**
|
||||
|
@ -147,7 +147,7 @@ abstract class AbstractQuery
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all defined parameters
|
||||
* Get all defined parameters.
|
||||
*
|
||||
* @return array Defined parameters
|
||||
*/
|
||||
|
@ -22,7 +22,6 @@
|
||||
namespace Doctrine\ORM;
|
||||
|
||||
use Doctrine\Common\EventManager,
|
||||
Doctrine\Common\DoctrineException,
|
||||
Doctrine\DBAL\Connection,
|
||||
Doctrine\ORM\Mapping\ClassMetadata,
|
||||
Doctrine\ORM\Mapping\ClassMetadataFactory,
|
||||
@ -96,6 +95,11 @@ class EntityManager
|
||||
* @var Doctrine\ORM\Proxy\ProxyFactory
|
||||
*/
|
||||
private $_proxyFactory;
|
||||
|
||||
/**
|
||||
* @var ExpressionBuilder The expression builder instance used to generate query expressions.
|
||||
*/
|
||||
private $_expressionBuilder;
|
||||
|
||||
/**
|
||||
* Whether the EntityManager is closed or not.
|
||||
@ -144,6 +148,27 @@ class EntityManager
|
||||
return $this->_metadataFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an ExpressionBuilder used for object-oriented construction of query expressions.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* [php]
|
||||
* $qb = $em->createQueryBuilder();
|
||||
* $expr = $em->getExpressionBuilder();
|
||||
* $qb->select('u')->from('User', 'u')
|
||||
* ->where($expr->orX($expr->eq('u.id', 1), $expr->eq('u.id', 2)));
|
||||
*
|
||||
* @return ExpressionBuilder
|
||||
*/
|
||||
public function getExpressionBuilder()
|
||||
{
|
||||
if ($this->_expressionBuilder === null) {
|
||||
$this->_expressionBuilder = new Query\Expr;
|
||||
}
|
||||
return $this->_expressionBuilder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts a transaction on the underlying database connection.
|
||||
*/
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
namespace Doctrine\ORM\Internal\Hydration;
|
||||
|
||||
class HydrationException extends \Doctrine\Common\DoctrineException
|
||||
class HydrationException extends \Doctrine\ORM\ORMException
|
||||
{
|
||||
public static function nonUniqueResult()
|
||||
{
|
||||
|
@ -129,6 +129,7 @@ abstract class AssociationMapping
|
||||
* Validates & completes the mapping. Mapping defaults are applied here.
|
||||
*
|
||||
* @param array $mapping
|
||||
* @throws MappingException If something is wrong with the mapping.
|
||||
*/
|
||||
protected function _validateAndCompleteMapping(array $mapping)
|
||||
{
|
||||
@ -151,7 +152,7 @@ abstract class AssociationMapping
|
||||
// Mandatory and optional attributes for either side
|
||||
if ( ! isset($mapping['mappedBy'])) {
|
||||
// Optional
|
||||
if (isset($mapping['joinTable'])) {
|
||||
if (isset($mapping['joinTable']) && $mapping['joinTable']) {
|
||||
if ($mapping['joinTable']['name'][0] == '`') {
|
||||
$mapping['joinTable']['name'] = trim($mapping['joinTable']['name'], '`');
|
||||
$mapping['joinTable']['quoted'] = true;
|
||||
@ -164,8 +165,7 @@ abstract class AssociationMapping
|
||||
}
|
||||
|
||||
// Optional attributes for both sides
|
||||
$this->fetchMode = isset($mapping['fetch']) ?
|
||||
$mapping['fetch'] : self::FETCH_LAZY;
|
||||
$this->fetchMode = isset($mapping['fetch']) ? $mapping['fetch'] : self::FETCH_LAZY;
|
||||
$cascades = isset($mapping['cascade']) ? $mapping['cascade'] : array();
|
||||
|
||||
if (in_array('all', $cascades)) {
|
||||
@ -178,11 +178,11 @@ abstract class AssociationMapping
|
||||
);
|
||||
}
|
||||
|
||||
$this->isCascadeRemove = in_array('remove', $cascades);
|
||||
$this->isCascadeRemove = in_array('remove', $cascades);
|
||||
$this->isCascadePersist = in_array('persist', $cascades);
|
||||
$this->isCascadeRefresh = in_array('refresh', $cascades);
|
||||
$this->isCascadeMerge = in_array('merge', $cascades);
|
||||
$this->isCascadeDetach = in_array('detach', $cascades);
|
||||
$this->isCascadeMerge = in_array('merge', $cascades);
|
||||
$this->isCascadeDetach = in_array('detach', $cascades);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -254,15 +254,6 @@ class ClassMetadataInfo
|
||||
*/
|
||||
public $columnNames = array();
|
||||
|
||||
/**
|
||||
* Whether to automatically OUTER JOIN subtypes when a basetype is queried.
|
||||
*
|
||||
* <b>This does only apply to the JOINED inheritance mapping strategy.</b>
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
//public $joinSubclasses = true;
|
||||
|
||||
/**
|
||||
* The discriminator value of this class.
|
||||
*
|
||||
@ -270,7 +261,7 @@ class ClassMetadataInfo
|
||||
* where a discriminator column is used.</b>
|
||||
*
|
||||
* @var mixed
|
||||
* @see _discriminatorColumn
|
||||
* @see discriminatorColumn
|
||||
*/
|
||||
public $discriminatorValue;
|
||||
|
||||
@ -281,7 +272,7 @@ class ClassMetadataInfo
|
||||
* where a discriminator column is used.</b>
|
||||
*
|
||||
* @var mixed
|
||||
* @see _discriminatorColumn
|
||||
* @see discriminatorColumn
|
||||
*/
|
||||
public $discriminatorMap = array();
|
||||
|
||||
@ -670,7 +661,8 @@ class ClassMetadataInfo
|
||||
throw MappingException::missingFieldName($this->name, $mapping);
|
||||
}
|
||||
if ( ! isset($mapping['type'])) {
|
||||
throw MappingException::missingType($this->name, $mapping);
|
||||
// Default to string
|
||||
$mapping['type'] = 'string';
|
||||
}
|
||||
|
||||
// Complete fieldName and columnName mapping
|
||||
@ -734,6 +726,7 @@ class ClassMetadataInfo
|
||||
* entity classes that have a single-field pk.
|
||||
*
|
||||
* @return string
|
||||
* @throws MappingException If the class has a composite primary key.
|
||||
*/
|
||||
public function getSingleIdentifierFieldName()
|
||||
{
|
||||
@ -748,6 +741,7 @@ class ClassMetadataInfo
|
||||
* entity classes that have a single-field pk.
|
||||
*
|
||||
* @return string
|
||||
* @throws MappingException If the class has a composite primary key.
|
||||
*/
|
||||
public function getSingleIdentifierColumnName()
|
||||
{
|
||||
@ -776,16 +770,6 @@ class ClassMetadataInfo
|
||||
return isset($this->fieldMappings[$fieldName]);
|
||||
}
|
||||
|
||||
public function hasInheritedMapping($fieldName)
|
||||
{
|
||||
if (isset($this->fieldMappings[$fieldName]) || isset($this->associationMappings[$fieldName]))
|
||||
{
|
||||
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all field mappings.
|
||||
*
|
||||
@ -1008,7 +992,7 @@ class ClassMetadataInfo
|
||||
/**
|
||||
* Sets the mapped subclasses of this class.
|
||||
*
|
||||
* @param array $subclasses The names of all mapped subclasses.
|
||||
* @param array $subclasses The names of all mapped subclasses.
|
||||
*/
|
||||
public function setSubclasses(array $subclasses)
|
||||
{
|
||||
@ -1337,33 +1321,6 @@ class ClassMetadataInfo
|
||||
{
|
||||
return $this->customRepositoryClassName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether sub classes should be automatically OUTER JOINed when a base
|
||||
* class is queried in a class hierarchy that uses the JOINED inheritance mapping
|
||||
* strategy.
|
||||
*
|
||||
* <b>This options does only apply to the JOINED inheritance mapping strategy.</b>
|
||||
*
|
||||
* @param boolean $bool
|
||||
* @see getJoinSubClasses()
|
||||
*/
|
||||
/*public function setJoinSubClasses($bool)
|
||||
{
|
||||
$this->joinSubclasses = (bool)$bool;
|
||||
}*/
|
||||
|
||||
/**
|
||||
* Gets whether the class mapped by this instance should OUTER JOIN sub classes
|
||||
* when a base class is queried.
|
||||
*
|
||||
* @return <type>
|
||||
* @see setJoinSubClasses()
|
||||
*/
|
||||
/*public function getJoinSubClasses()
|
||||
{
|
||||
return $this->joinSubclasses;
|
||||
}*/
|
||||
|
||||
/**
|
||||
* Dispatches the lifecycle event of the given entity to the registered
|
||||
@ -1608,7 +1565,6 @@ class ClassMetadataInfo
|
||||
* value to use depending on the column type
|
||||
*
|
||||
* @param array $mapping The version field mapping array
|
||||
* @return void
|
||||
*/
|
||||
public function setVersionMapping(array &$mapping)
|
||||
{
|
||||
|
@ -40,13 +40,13 @@ final class DiscriminatorMap extends Annotation {}
|
||||
/*final class SubClasses extends Annotation {}*/
|
||||
final class Id extends Annotation {}
|
||||
final class GeneratedValue extends Annotation {
|
||||
public $strategy;
|
||||
public $strategy = 'AUTO';
|
||||
}
|
||||
final class Version extends Annotation {}
|
||||
final class JoinColumn extends Annotation {
|
||||
public $name;
|
||||
public $fieldName; // field name used in non-object hydration (array/scalar)
|
||||
public $referencedColumnName;
|
||||
public $referencedColumnName = 'id';
|
||||
public $unique = false;
|
||||
public $nullable = true;
|
||||
public $onDelete;
|
||||
@ -55,10 +55,12 @@ final class JoinColumn extends Annotation {
|
||||
}
|
||||
final class JoinColumns extends Annotation {}
|
||||
final class Column extends Annotation {
|
||||
public $type;
|
||||
public $type = 'string';
|
||||
public $length;
|
||||
public $precision = 0; // The precision for a decimal (exact numeric) column (Applies only for decimal column)
|
||||
public $scale = 0; // The scale for a decimal (exact numeric) column (Applies only for decimal column)
|
||||
// The precision for a decimal (exact numeric) column (Applies only for decimal column)
|
||||
public $precision = 0;
|
||||
// The scale for a decimal (exact numeric) column (Applies only for decimal column)
|
||||
public $scale = 0;
|
||||
public $unique = false;
|
||||
public $nullable = false;
|
||||
public $name;
|
||||
@ -132,5 +134,3 @@ final class PreRemove extends Annotation {}
|
||||
final class PostRemove extends Annotation {}
|
||||
final class PostLoad extends Annotation {}
|
||||
|
||||
/* Generic annotation for Doctrine extensions */
|
||||
final class DoctrineX extends Annotation {}
|
||||
|
@ -187,8 +187,10 @@ class XmlDriver extends AbstractFileDriver
|
||||
$metadata->mapField($mapping);
|
||||
|
||||
if (isset($idElement->generator)) {
|
||||
$strategy = isset($idElement->generator['strategy']) ?
|
||||
(string)$idElement->generator['strategy'] : 'AUTO';
|
||||
$metadata->setIdGeneratorType(constant('Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_'
|
||||
. strtoupper((string)$idElement->generator['strategy'])));
|
||||
. $strategy));
|
||||
}
|
||||
|
||||
// Check for SequenceGenerator/TableGenerator definition
|
||||
@ -227,8 +229,6 @@ class XmlDriver extends AbstractFileDriver
|
||||
foreach ($oneToOneElement->{'join-columns'}->{'join-column'} as $joinColumnElement) {
|
||||
$joinColumns[] = $this->_getJoinColumnMapping($joinColumnElement);
|
||||
}
|
||||
} else {
|
||||
throw MappingException::invalidMapping($mapping['fieldName']);
|
||||
}
|
||||
|
||||
$mapping['joinColumns'] = $joinColumns;
|
||||
@ -295,8 +295,6 @@ class XmlDriver extends AbstractFileDriver
|
||||
|
||||
$joinColumns[] = $this->_getJoinColumnMapping($joinColumnElement);
|
||||
}
|
||||
} else {
|
||||
throw MappingException::invalidMapping($mapping['fieldName']);
|
||||
}
|
||||
|
||||
$mapping['joinColumns'] = $joinColumns;
|
||||
@ -346,8 +344,6 @@ class XmlDriver extends AbstractFileDriver
|
||||
}
|
||||
|
||||
$mapping['joinTable'] = $joinTable;
|
||||
} else {
|
||||
throw MappingException::invalidMapping($mapping['fieldName']);
|
||||
}
|
||||
|
||||
if (isset($manyToManyElement->cascade)) {
|
||||
|
@ -249,8 +249,6 @@ class YamlDriver extends AbstractFileDriver
|
||||
|
||||
$joinColumns[] = $this->_getJoinColumnMapping($joinColumnElement);
|
||||
}
|
||||
} else {
|
||||
throw MappingException::invalidMapping($mapping['fieldName']);
|
||||
}
|
||||
|
||||
$mapping['joinColumns'] = $joinColumns;
|
||||
@ -309,8 +307,6 @@ class YamlDriver extends AbstractFileDriver
|
||||
|
||||
$joinColumns[] = $this->_getJoinColumnMapping($joinColumnElement);
|
||||
}
|
||||
} else {
|
||||
throw MappingException::invalidMapping($mapping['fieldName']);
|
||||
}
|
||||
|
||||
$mapping['joinColumns'] = $joinColumns;
|
||||
@ -364,8 +360,6 @@ class YamlDriver extends AbstractFileDriver
|
||||
}
|
||||
|
||||
$mapping['joinTable'] = $joinTable;
|
||||
} else {
|
||||
throw MappingException::invalidMapping($mapping['fieldName']);
|
||||
}
|
||||
|
||||
if (isset($manyToManyElement['cascade'])) {
|
||||
|
@ -32,6 +32,9 @@ namespace Doctrine\ORM\Mapping;
|
||||
* 2) To drastically reduce the size of a serialized instance (private/protected members
|
||||
* get the whole class name, namespace inclusive, prepended to every property in
|
||||
* the serialized representation).
|
||||
*
|
||||
* Instances of this class are stored serialized in the metadata cache together with the
|
||||
* owning <tt>ClassMetadata</tt> instance.
|
||||
*
|
||||
* @since 2.0
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
@ -78,18 +81,36 @@ class ManyToManyMapping extends AssociationMapping
|
||||
parent::_validateAndCompleteMapping($mapping);
|
||||
if ($this->isOwningSide) {
|
||||
// owning side MUST have a join table
|
||||
if ( ! isset($mapping['joinTable'])) {
|
||||
throw MappingException::joinTableRequired($mapping['fieldName']);
|
||||
if ( ! isset($mapping['joinTable']) || ! $mapping['joinTable']) {
|
||||
// Apply default join table
|
||||
$sourceShortName = substr($this->sourceEntityName, strrpos($this->sourceEntityName, '\\') + 1);
|
||||
$targetShortName = substr($this->targetEntityName, strrpos($this->targetEntityName, '\\') + 1);
|
||||
$mapping['joinTable'] = array(
|
||||
'name' => $sourceShortName .'_' . $targetShortName,
|
||||
'joinColumns' => array(
|
||||
array(
|
||||
'name' => $sourceShortName . '_id',
|
||||
'referencedColumnName' => 'id'
|
||||
)
|
||||
),
|
||||
'inverseJoinColumns' => array(
|
||||
array(
|
||||
'name' => $targetShortName . '_id',
|
||||
'referencedColumnName' => 'id'
|
||||
)
|
||||
)
|
||||
);
|
||||
$this->joinTable = $mapping['joinTable'];
|
||||
}
|
||||
// owning side MUST specify joinColumns
|
||||
if ( ! isset($mapping['joinTable']['joinColumns'])) {
|
||||
else if ( ! isset($mapping['joinTable']['joinColumns'])) {
|
||||
throw MappingException::missingRequiredOption(
|
||||
$this->sourceFieldName, 'joinColumns',
|
||||
'Did you think of case sensitivity / plural s?'
|
||||
);
|
||||
}
|
||||
// owning side MUST specify inverseJoinColumns
|
||||
if ( ! isset($mapping['joinTable']['inverseJoinColumns'])) {
|
||||
else if ( ! isset($mapping['joinTable']['inverseJoinColumns'])) {
|
||||
throw MappingException::missingRequiredOption(
|
||||
$this->sourceFieldName, 'inverseJoinColumns',
|
||||
'Did you think of case sensitivity / plural s?'
|
||||
@ -151,7 +172,9 @@ class ManyToManyMapping extends AssociationMapping
|
||||
if (isset($sourceClass->fieldNames[$sourceKeyColumn])) {
|
||||
$joinTableConditions[$relationKeyColumn] = $sourceClass->reflFields[$sourceClass->fieldNames[$sourceKeyColumn]]->getValue($sourceEntity);
|
||||
} else {
|
||||
$joinTableConditions[$relationKeyColumn] = $joinColumnValues[$sourceKeyColumn];
|
||||
throw MappingException::joinColumnMustPointToMappedField(
|
||||
$sourceClass->name, $sourceKeyColumn
|
||||
);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -162,7 +185,9 @@ class ManyToManyMapping extends AssociationMapping
|
||||
if (isset($sourceClass->fieldNames[$sourceKeyColumn])) {
|
||||
$joinTableConditions[$relationKeyColumn] = $sourceClass->reflFields[$sourceClass->fieldNames[$sourceKeyColumn]]->getValue($sourceEntity);
|
||||
} else {
|
||||
$joinTableConditions[$relationKeyColumn] = $joinColumnValues[$sourceKeyColumn];
|
||||
throw MappingException::joinColumnMustPointToMappedField(
|
||||
$sourceClass->name, $sourceKeyColumn
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -36,6 +36,9 @@ namespace Doctrine\ORM\Mapping;
|
||||
* 2) To drastically reduce the size of a serialized instance (private/protected members
|
||||
* get the whole class name, namespace inclusive, prepended to every property in
|
||||
* the serialized representation).
|
||||
*
|
||||
* Instances of this class are stored serialized in the metadata cache together with the
|
||||
* owning <tt>ClassMetadata</tt> instance.
|
||||
*
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
* @author Giorgio Sironi <piccoloprincipeazzurro@gmail.com>
|
||||
@ -47,13 +50,6 @@ class OneToManyMapping extends AssociationMapping
|
||||
public $orphanRemoval = false;
|
||||
/** FUTURE: The key column mapping, if any. The key column holds the keys of the Collection. */
|
||||
//public $keyColumn;
|
||||
|
||||
/**
|
||||
* TODO: Allow any combination of source/target columns in lazy loading.
|
||||
* What is supported now is primary key (that can spread on multiple fields)
|
||||
* pointed to foreign keys on the target
|
||||
public $targetColumns;
|
||||
*/
|
||||
|
||||
/**
|
||||
* Initializes a new OneToManyMapping.
|
||||
|
@ -32,6 +32,9 @@ namespace Doctrine\ORM\Mapping;
|
||||
* 2) To drastically reduce the size of a serialized instance (private/protected members
|
||||
* get the whole class name, namespace inclusive, prepended to every property in
|
||||
* the serialized representation).
|
||||
*
|
||||
* Instances of this class are stored serialized in the metadata cache together with the
|
||||
* owning <tt>ClassMetadata</tt> instance.
|
||||
*
|
||||
* @since 2.0
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
@ -109,8 +112,12 @@ class OneToOneMapping extends AssociationMapping
|
||||
}
|
||||
|
||||
if ($this->isOwningSide) {
|
||||
if ( ! isset($mapping['joinColumns'])) {
|
||||
throw MappingException::invalidMapping($this->sourceFieldName);
|
||||
if ( ! isset($mapping['joinColumns']) || ! $mapping['joinColumns']) {
|
||||
// Apply default join column
|
||||
$mapping['joinColumns'] = array(array(
|
||||
'name' => $this->sourceFieldName . '_id',
|
||||
'referencedColumnName' => 'id'
|
||||
));
|
||||
}
|
||||
foreach ($mapping['joinColumns'] as &$joinColumn) {
|
||||
if ($joinColumn['name'][0] == '`') {
|
||||
@ -126,7 +133,7 @@ class OneToOneMapping extends AssociationMapping
|
||||
}
|
||||
|
||||
$this->isOptional = isset($mapping['optional']) ?
|
||||
(bool)$mapping['optional'] : true;
|
||||
(bool) $mapping['optional'] : true;
|
||||
$this->orphanRemoval = isset($mapping['orphanRemoval']) ?
|
||||
(bool) $mapping['orphanRemoval'] : false;
|
||||
|
||||
@ -141,7 +148,6 @@ class OneToOneMapping extends AssociationMapping
|
||||
* Whether the association is optional (0..1), or not (1..1).
|
||||
*
|
||||
* @return boolean TRUE if the association is optional, FALSE otherwise.
|
||||
* @todo Only applicable to OneToOne. Move there.
|
||||
*/
|
||||
public function isOptional()
|
||||
{
|
||||
|
@ -21,8 +21,7 @@
|
||||
|
||||
namespace Doctrine\ORM;
|
||||
|
||||
use Doctrine\Common\DoctrineException,
|
||||
Doctrine\ORM\Mapping\AssociationMapping,
|
||||
use Doctrine\ORM\Mapping\AssociationMapping,
|
||||
\Closure;
|
||||
|
||||
/**
|
||||
|
@ -184,7 +184,7 @@ class StandardEntityPersister
|
||||
$this->_assignDefaultVersionValue($this->_class, $entity, $id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$stmt->closeCursor();
|
||||
$this->_queuedInserts = array();
|
||||
|
||||
@ -462,7 +462,7 @@ class StandardEntityPersister
|
||||
foreach ($this->_class->associationMappings as $field => $assoc) {
|
||||
$value = $this->_class->reflFields[$field]->getValue($entity);
|
||||
if ($assoc->isOneToOne()) {
|
||||
if ($value instanceof Proxy && ! $value->__isInitialized()) {
|
||||
if ($value instanceof Proxy && ! $value->__isInitialized__) {
|
||||
continue; // skip uninitialized proxies
|
||||
}
|
||||
|
||||
|
@ -31,155 +31,77 @@ namespace Doctrine\ORM\Query;
|
||||
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||
* @author Jonathan Wage <jonwage@gmail.com>
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
* @todo Rename: ExpressionBuilder
|
||||
*/
|
||||
class Expr
|
||||
{
|
||||
/**
|
||||
* Creates an instance of Expr\Andx with given arguments.
|
||||
* Each argument is separated by an "AND". Example:
|
||||
* Creates a conjunction of the given boolean expressions.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* [php]
|
||||
* // (u.type = ?1) AND (u.role = ?2)
|
||||
* $q->where($q->expr()->andx('u.type = ?1', 'u.role = ?2'));
|
||||
* $expr->andX('u.type = ?1', 'u.role = ?2'));
|
||||
*
|
||||
* @param mixed $x Optional clause. Defaults = null, but requires
|
||||
* at least one defined when converting to string.
|
||||
* @return Expr\Andx
|
||||
*/
|
||||
public function andx($x = null)
|
||||
public function andX($x = null)
|
||||
{
|
||||
return new Expr\Andx(func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance of Expr\Orx with given arguments.
|
||||
* Each argument is separated by an "OR". Example:
|
||||
* Creates a disjunction of the given boolean expressions.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* [php]
|
||||
* // (u.type = ?1) OR (u.role = ?2)
|
||||
* $q->where($q->expr()->orx('u.type = ?1', 'u.role = ?2'));
|
||||
* $q->where($q->expr()->orX('u.type = ?1', 'u.role = ?2'));
|
||||
*
|
||||
* @param mixed $x Optional clause. Defaults = null, but requires
|
||||
* at least one defined when converting to string.
|
||||
* @return Expr\Orx
|
||||
*/
|
||||
public function orx($x = null)
|
||||
public function orX($x = null)
|
||||
{
|
||||
return new Expr\Orx(func_get_args());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates an instance of Expr\Select with given arguments.
|
||||
* Each argument is separated by a ",". Example:
|
||||
*
|
||||
* [php]
|
||||
* // u.id, u.name, u.surname
|
||||
* $q->select($q->expr()->select('u.id', 'u.name')->add('u.surname'));
|
||||
*
|
||||
* @param mixed $select Optional select. Defaults = null, but requires
|
||||
* at least one defined when converting to string.
|
||||
* @return Expr\Select
|
||||
* Creates an ASCending order expression.
|
||||
*
|
||||
* @param $sort
|
||||
* @return OrderBy
|
||||
*/
|
||||
public function select($select = null)
|
||||
public function asc($expr)
|
||||
{
|
||||
return new Expr\Select(is_array($select) ? $select : func_get_args());
|
||||
return new Expr\OrderBy($expr, 'ASC');
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance of Expr\From with given arguments.
|
||||
*
|
||||
* [php]
|
||||
* // User u
|
||||
* $q->from($q->expr()->from('User', 'u'));
|
||||
*
|
||||
* @param string $from Entity name.
|
||||
* @param string $alias Alias to be used by Entity.
|
||||
* @return Expr\From
|
||||
* Creates a DESCending order expression.
|
||||
*
|
||||
* @param $sort
|
||||
* @return OrderBy
|
||||
*/
|
||||
public function from($from, $alias)
|
||||
public function desc($expr)
|
||||
{
|
||||
return new Expr\From($from, $alias);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance of Expr\Join with given arguments.
|
||||
*
|
||||
* [php]
|
||||
* // LEFT JOIN u.Group g WITH g.name = 'admin'
|
||||
* $q->expr()->leftJoin('u.Group', 'g', 'WITH', "g.name = 'admin'")
|
||||
*
|
||||
* @param string $join Relation join.
|
||||
* @param string $alias Alias to be used by Relation.
|
||||
* @param string $conditionType Optional type of condition appender. Accepts either string or constant.
|
||||
* 'ON' and 'WITH' are supported strings. Expr\Join::ON and Expr\Join::WITH are supported constants.
|
||||
* @param mixed $condition Optional condition to be appended.
|
||||
* @return Expr\Join
|
||||
*/
|
||||
public function leftJoin($join, $alias, $conditionType = null, $condition = null)
|
||||
{
|
||||
return new Expr\Join(Expr\Join::LEFT_JOIN, $join, $alias, $conditionType, $condition);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance of Expr\Join with given arguments.
|
||||
*
|
||||
* [php]
|
||||
* // INNER JOIN u.Group g WITH g.name = 'admin'
|
||||
* $q->expr()->innerJoin('u.Group', 'g', 'WITH', "g.name = 'admin'")
|
||||
*
|
||||
* @param string $join Relation join.
|
||||
* @param string $alias Alias to be used by Relation.
|
||||
* @param string $conditionType Optional type of condition appender. Accepts either string or constant.
|
||||
* 'ON' and 'WITH' are supported strings. Expr\Join::ON and Expr\Join::WITH are supported constants.
|
||||
* @param mixed $condition Optional condition to be appended.
|
||||
* @return Expr\Join
|
||||
*/
|
||||
public function innerJoin($join, $alias, $conditionType = null, $condition = null)
|
||||
{
|
||||
return new Expr\Join(Expr\Join::INNER_JOIN, $join, $alias, $conditionType, $condition);
|
||||
return new Expr\OrderBy($expr, 'DESC');
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance of Expr\OrderBy with given item sort and order.
|
||||
* Each argument is separated by a ",". Example:
|
||||
*
|
||||
* [php]
|
||||
* $q->orderBy($q->expr()->orderBy('u.surname', 'ASC')->add('u.name', 'ASC'));
|
||||
*
|
||||
* @param string $sort Optional item sort.
|
||||
* @param string $order Optional order to be applied in item.
|
||||
* @return Expr\OrderBy
|
||||
*/
|
||||
public function orderBy($sort = null, $order = null)
|
||||
{
|
||||
return new Expr\OrderBy($sort, $order);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance of Expr\GroupBy with given arguments.
|
||||
* Each argument is separated by a ",". Example:
|
||||
*
|
||||
* [php]
|
||||
* // u.id, u.name
|
||||
* $q->select($q->expr()->groupBy('u.id', 'u.name'));
|
||||
*
|
||||
* @param mixed $groupBy Optional group by. Defaults = null, but requires
|
||||
* at least one defined when converting to string.
|
||||
* @return Expr\Select
|
||||
*/
|
||||
public function groupBy($groupBy = null)
|
||||
{
|
||||
return new Expr\GroupBy(func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance of Expr\Comparison, with the given arguments.
|
||||
* Creates an equality comparison expression with the given arguments.
|
||||
*
|
||||
* First argument is considered the left expression and the second is the right expression.
|
||||
* When converted to string, it will generated a <left expr> = <right expr>. Example:
|
||||
*
|
||||
* [php]
|
||||
* // u.id = ?1
|
||||
* $q->where($q->expr()->eq('u.id', '?1'));
|
||||
* $expr->eq('u.id', '?1');
|
||||
*
|
||||
* @param mixed $x Left expression
|
||||
* @param mixed $y Right expression
|
||||
@ -358,7 +280,7 @@ class Expr
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance of SOME() function, with the given DQL Subquery.
|
||||
* Creates a SOME() function expression with the given DQL subquery.
|
||||
*
|
||||
* @param mixed $subquery DQL Subquery to be used in SOME() function.
|
||||
* @return Expr\Func
|
||||
@ -369,7 +291,7 @@ class Expr
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance of ANY() function, with the given DQL subquery.
|
||||
* Creates an ANY() function expression with the given DQL subquery.
|
||||
*
|
||||
* @param mixed $subquery DQL Subquery to be used in ANY() function.
|
||||
* @return Expr\Func
|
||||
@ -380,7 +302,7 @@ class Expr
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance of NOT() function, with the given restriction.
|
||||
* Creates a negation expression of the given restriction.
|
||||
*
|
||||
* @param mixed $restriction Restriction to be used in NOT() function.
|
||||
* @return Expr\Func
|
||||
@ -391,7 +313,7 @@ class Expr
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance of ABS() function, with the given argument.
|
||||
* Creates an ABS() function expression with the given argument.
|
||||
*
|
||||
* @param mixed $x Argument to be used in ABS() function.
|
||||
* @return Expr\Func
|
||||
@ -403,6 +325,7 @@ class Expr
|
||||
|
||||
/**
|
||||
* Creates a product mathematical expression with the given arguments.
|
||||
*
|
||||
* First argument is considered the left expression and the second is the right expression.
|
||||
* When converted to string, it will generated a <left expr> * <right expr>. Example:
|
||||
*
|
||||
@ -461,8 +384,8 @@ class Expr
|
||||
* When converted to string, it will generated a <left expr> / <right expr>. Example:
|
||||
*
|
||||
* [php]
|
||||
* // u.total - u.period
|
||||
* $q->expr()->diff('u.total', 'u.period')
|
||||
* // u.total / u.period
|
||||
* $expr->quot('u.total', 'u.period')
|
||||
*
|
||||
* @param mixed $x Left expression
|
||||
* @param mixed $y Right expression
|
||||
@ -474,7 +397,7 @@ class Expr
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance of SQRT() function, with the given argument.
|
||||
* Creates a SQRT() function expression with the given argument.
|
||||
*
|
||||
* @param mixed $x Argument to be used in SQRT() function.
|
||||
* @return Expr\Func
|
||||
@ -485,7 +408,7 @@ class Expr
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance of field IN() function, with the given arguments.
|
||||
* Creates an IN() expression with the given arguments.
|
||||
*
|
||||
* @param string $x Field in string format to be restricted by IN() function
|
||||
* @param mixed $y Argument to be used in IN() function.
|
||||
@ -493,11 +416,18 @@ class Expr
|
||||
*/
|
||||
public function in($x, $y)
|
||||
{
|
||||
if (is_array($y)) {
|
||||
foreach ($y as &$literal) {
|
||||
if ( ! ($literal instanceof Expr\Literal)) {
|
||||
$literal = $this->_quoteLiteral($literal);
|
||||
}
|
||||
}
|
||||
}
|
||||
return new Expr\Func($x . ' IN', (array) $y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance of field NOT IN() function, with the given arguments.
|
||||
* Creates a NOT IN() expression with the given arguments.
|
||||
*
|
||||
* @param string $x Field in string format to be restricted by NOT IN() function
|
||||
* @param mixed $y Argument to be used in NOT IN() function.
|
||||
@ -509,7 +439,7 @@ class Expr
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance of field LIKE() comparison, with the given arguments.
|
||||
* Creates a LIKE() comparison expression with the given arguments.
|
||||
*
|
||||
* @param string $x Field in string format to be inspected by LIKE() comparison.
|
||||
* @param mixed $y Argument to be used in LIKE() comparison.
|
||||
@ -521,7 +451,7 @@ class Expr
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance of CONCAT() function, with the given argument.
|
||||
* Creates a CONCAT() function expression with the given arguments.
|
||||
*
|
||||
* @param mixed $x First argument to be used in CONCAT() function.
|
||||
* @param mixed $x Second argument to be used in CONCAT() function.
|
||||
@ -533,7 +463,7 @@ class Expr
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance of SUBSTR() function, with the given argument.
|
||||
* Creates a SUBSTR() function expression with the given arguments.
|
||||
*
|
||||
* @param mixed $x Argument to be used as string to be cropped by SUBSTR() function.
|
||||
* @param integer $from Initial offset to start cropping string. May accept negative values.
|
||||
@ -546,10 +476,10 @@ class Expr
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance of LOWER() function, with the given argument.
|
||||
* Creates a LOWER() function expression with the given argument.
|
||||
*
|
||||
* @param mixed $x Argument to be used in LOWER() function.
|
||||
* @return Expr\Func
|
||||
* @return Expr\Func A LOWER function expression.
|
||||
*/
|
||||
public function lower($x)
|
||||
{
|
||||
@ -557,10 +487,10 @@ class Expr
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance of LOWER() function, with the given argument.
|
||||
* Creates an UPPER() function expression with the given argument.
|
||||
*
|
||||
* @param mixed $x Argument to be used in LOWER() function.
|
||||
* @return Expr\Func
|
||||
* @param mixed $x Argument to be used in UPPER() function.
|
||||
* @return Expr\Func An UPPER function expression.
|
||||
*/
|
||||
public function upper($x)
|
||||
{
|
||||
@ -568,10 +498,10 @@ class Expr
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance of LENGTH() function, with the given argument.
|
||||
* Creates a LENGTH() function expression with the given argument.
|
||||
*
|
||||
* @param mixed $x Argument to be used as argument of LENGTH() function.
|
||||
* @return Expr\Func
|
||||
* @return Expr\Func A LENGTH function expression.
|
||||
*/
|
||||
public function length($x)
|
||||
{
|
||||
@ -579,17 +509,28 @@ class Expr
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a literal representation of the given argument.
|
||||
* Creates a literal expression of the given argument.
|
||||
*
|
||||
* @param mixed $literal Argument to be converted to literal.
|
||||
* @return string
|
||||
* @return Expr\Literal
|
||||
*/
|
||||
public function literal($literal)
|
||||
{
|
||||
return new Expr\Literal($this->_quoteLiteral($literal));
|
||||
}
|
||||
|
||||
/**
|
||||
* Quotes a literal value, if necessary, according to the DQL syntax.
|
||||
*
|
||||
* @param mixed $literal The literal value.
|
||||
* @return string
|
||||
*/
|
||||
private function _quoteLiteral($literal)
|
||||
{
|
||||
if (is_numeric($literal)) {
|
||||
return (string) $literal;
|
||||
} else {
|
||||
return "'" . $literal . "'";
|
||||
return "'" . str_replace("'", "''", $literal) . "'";
|
||||
}
|
||||
}
|
||||
|
||||
@ -599,7 +540,7 @@ class Expr
|
||||
* @param mixed $val Valued to be inspected by range values.
|
||||
* @param integer $x Starting range value to be used in BETWEEN() function.
|
||||
* @param integer $y End point value to be used in BETWEEN() function.
|
||||
* @return Expr\Func
|
||||
* @return Expr\Func A BETWEEN expression.
|
||||
*/
|
||||
public function between($val, $x, $y)
|
||||
{
|
||||
@ -610,7 +551,7 @@ class Expr
|
||||
* Creates an instance of TRIM() function, with the given argument.
|
||||
*
|
||||
* @param mixed $x Argument to be used as argument of TRIM() function.
|
||||
* @return Expr\Func
|
||||
* @return Expr\Func a TRIM expression.
|
||||
*/
|
||||
public function trim($x)
|
||||
{
|
||||
|
@ -61,7 +61,7 @@ abstract class Base
|
||||
$class = get_class($arg);
|
||||
|
||||
if ( ! in_array($class, $this->_allowedClasses)) {
|
||||
throw \Doctrine\Common\DoctrineException::classNotAllowed($class, $this);
|
||||
throw new \InvalidArgumentException("Expression of type '$class' not allowed in this context.");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -39,8 +39,8 @@ class Func
|
||||
|
||||
public function __construct($name, $arguments)
|
||||
{
|
||||
$this->_name = $name;
|
||||
$this->_arguments = (array) $arguments;
|
||||
$this->_name = $name;
|
||||
$this->_arguments = (array) $arguments;
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
|
9
lib/Doctrine/ORM/Query/Expr/Literal.php
Normal file
9
lib/Doctrine/ORM/Query/Expr/Literal.php
Normal file
@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\ORM\Query\Expr;
|
||||
|
||||
class Literal extends Base
|
||||
{
|
||||
protected $_preSeparator = '';
|
||||
protected $_postSeparator = '';
|
||||
}
|
@ -21,8 +21,7 @@
|
||||
|
||||
namespace Doctrine\ORM;
|
||||
|
||||
use Doctrine\ORM\Query\Expr,
|
||||
Doctrine\Common\DoctrineException;
|
||||
use Doctrine\ORM\Query\Expr;
|
||||
|
||||
/**
|
||||
* This class is responsible for building DQL query strings via an object oriented
|
||||
@ -46,7 +45,7 @@ class QueryBuilder
|
||||
const STATE_CLEAN = 1;
|
||||
|
||||
/**
|
||||
* @var EntityManager $em Instance of an EntityManager to use for query.
|
||||
* @var EntityManager $em The EntityManager used by this QueryBuilder.
|
||||
*/
|
||||
private $_em;
|
||||
|
||||
@ -78,30 +77,35 @@ class QueryBuilder
|
||||
* @var string The complete DQL string for this query.
|
||||
*/
|
||||
private $_dql;
|
||||
|
||||
|
||||
/**
|
||||
* @var Query The Query instance used for this QueryBuilder.
|
||||
* @var array The query parameters.
|
||||
*/
|
||||
private $_q;
|
||||
|
||||
private $_params = array();
|
||||
|
||||
/**
|
||||
* @var Expr The Expr instance used to generate DQL expressions
|
||||
* @var integer The index of the first result to retrieve.
|
||||
*/
|
||||
private $_expr;
|
||||
private $_firstResult = null;
|
||||
|
||||
/**
|
||||
* @var integer The maximum number of results to retrieve.
|
||||
*/
|
||||
private $_maxResults = null;
|
||||
|
||||
/**
|
||||
* Initializes a new <tt>QueryBuilder</tt> that uses the given <tt>EntityManager</tt>.
|
||||
*
|
||||
* @param EntityManager $entityManager The EntityManager to use.
|
||||
* @param EntityManager $em The EntityManager to use.
|
||||
*/
|
||||
public function __construct(EntityManager $entityManager)
|
||||
public function __construct(EntityManager $em)
|
||||
{
|
||||
$this->_em = $entityManager;
|
||||
$this->_q = $entityManager->createQuery();
|
||||
$this->_em = $em;
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory for instantiating and retrieving the Expr instance when needed
|
||||
* Gets an ExpressionBuilder used for object-oriented construction of query expressions.
|
||||
* Intended for convenient inline usage. Example:
|
||||
*
|
||||
* [php]
|
||||
* $qb = $em->createQueryBuilder()
|
||||
@ -109,36 +113,17 @@ class QueryBuilder
|
||||
* ->from('User', 'u')
|
||||
* ->where($qb->expr()->eq('u.id', 1));
|
||||
*
|
||||
* @return Expr $expr
|
||||
* @return ExpressionBuilder
|
||||
*/
|
||||
public function expr()
|
||||
{
|
||||
if ( ! $this->_expr) {
|
||||
$this->_expr = new Expr;
|
||||
}
|
||||
return $this->_expr;
|
||||
return $this->_em->getExpressionBuilder();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the type of this query instance. Either the constant for SELECT, UPDATE or DELETE
|
||||
* Get the type of the currently built query.
|
||||
*
|
||||
* [php]
|
||||
* switch ($qb->getType())
|
||||
* {
|
||||
* case QueryBuilder::SELECT:
|
||||
* echo 'SELECT';
|
||||
* break;
|
||||
*
|
||||
* case QueryBuilder::DELETE:
|
||||
* echo 'DELETE';
|
||||
* break;
|
||||
*
|
||||
* case QueryBuilder::UPDATE:
|
||||
* echo 'UPDATE';
|
||||
* break;
|
||||
* }
|
||||
*
|
||||
* @return integer $type
|
||||
* @return integer
|
||||
*/
|
||||
public function getType()
|
||||
{
|
||||
@ -146,12 +131,9 @@ class QueryBuilder
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the entity manager instance for this query builder instance
|
||||
* Get the associated EntityManager for this query builder.
|
||||
*
|
||||
* [php]
|
||||
* $em = $qb->getEntityManager();
|
||||
*
|
||||
* @return EntityManager $em
|
||||
* @return EntityManager
|
||||
*/
|
||||
public function getEntityManager()
|
||||
{
|
||||
@ -168,7 +150,7 @@ class QueryBuilder
|
||||
* echo 'Query builder is clean';
|
||||
* }
|
||||
*
|
||||
* @return integer $state
|
||||
* @return integer
|
||||
*/
|
||||
public function getState()
|
||||
{
|
||||
@ -184,7 +166,7 @@ class QueryBuilder
|
||||
* ->from('User', 'u')
|
||||
* echo $qb->getDql(); // SELECT u FROM User u
|
||||
*
|
||||
* @return string $dql The DQL string
|
||||
* @return string The DQL string
|
||||
*/
|
||||
public function getDql()
|
||||
{
|
||||
@ -216,7 +198,7 @@ class QueryBuilder
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Query instance with the DQL string set to it
|
||||
* Constructs a Query instance from the current configuration of the builder.
|
||||
*
|
||||
* [php]
|
||||
* $qb = $em->createQueryBuilder()
|
||||
@ -225,13 +207,14 @@ class QueryBuilder
|
||||
* $q = $qb->getQuery();
|
||||
* $results = $q->execute();
|
||||
*
|
||||
* @return Query $q
|
||||
* @return Query
|
||||
*/
|
||||
public function getQuery()
|
||||
{
|
||||
$this->_q->setDql($this->getDql());
|
||||
|
||||
return $this->_q;
|
||||
return $this->_em->createQuery($this->getDql())
|
||||
->setParameters($this->_params)
|
||||
->setFirstResult($this->_firstResult)
|
||||
->setMaxResults($this->_maxResults);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -264,12 +247,11 @@ class QueryBuilder
|
||||
*
|
||||
* @param string|integer $key The parameter position or name.
|
||||
* @param mixed $value The parameter value.
|
||||
* @return QueryBuilder $qb
|
||||
* @return QueryBuilder This QueryBuilder instance.
|
||||
*/
|
||||
public function setParameter($key, $value)
|
||||
{
|
||||
$this->_q->setParameter($key, $value);
|
||||
|
||||
$this->_params[$key] = $value;
|
||||
return $this;
|
||||
}
|
||||
|
||||
@ -287,12 +269,11 @@ class QueryBuilder
|
||||
* ));
|
||||
*
|
||||
* @param array $params
|
||||
* @return QueryBuilder $qb
|
||||
* @return QueryBuilder This QueryBuilder instance.
|
||||
*/
|
||||
public function setParameters(array $params)
|
||||
{
|
||||
$this->_q->setParameters($params);
|
||||
|
||||
$this->_params = $params;
|
||||
return $this;
|
||||
}
|
||||
|
||||
@ -303,7 +284,7 @@ class QueryBuilder
|
||||
*/
|
||||
public function getParameters($params = array())
|
||||
{
|
||||
return $this->_q->getParameters($params);
|
||||
return $this->_params;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -314,18 +295,18 @@ class QueryBuilder
|
||||
*/
|
||||
public function getParameter($key)
|
||||
{
|
||||
return $this->_q->getParameter($key);
|
||||
return isset($this->_params[$key]) ? $this->_params[$key] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the position of the first result to retrieve (the "offset").
|
||||
*
|
||||
* @param integer $firstResult The first result to return.
|
||||
* @return QueryBuilder This query builder object.
|
||||
* @return QueryBuilder This QueryBuilder instance.
|
||||
*/
|
||||
public function setFirstResult($firstResult)
|
||||
{
|
||||
$this->_q->setFirstResult($firstResult);
|
||||
$this->_firstResult = $firstResult;
|
||||
return $this;
|
||||
}
|
||||
|
||||
@ -337,18 +318,18 @@ class QueryBuilder
|
||||
*/
|
||||
public function getFirstResult()
|
||||
{
|
||||
return $this->_q->getFirstResult();
|
||||
return $this->_firstResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the maximum number of results to retrieve (the "limit").
|
||||
*
|
||||
* @param integer $maxResults
|
||||
* @return QueryBuilder This query builder object.
|
||||
* @return QueryBuilder This QueryBuilder instance.
|
||||
*/
|
||||
public function setMaxResults($maxResults)
|
||||
{
|
||||
$this->_q->setMaxResults($maxResults);
|
||||
$this->_maxResults = $maxResults;
|
||||
return $this;
|
||||
}
|
||||
|
||||
@ -360,7 +341,7 @@ class QueryBuilder
|
||||
*/
|
||||
public function getMaxResults()
|
||||
{
|
||||
return $this->_q->getMaxResults();
|
||||
return $this->_maxResults;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -369,7 +350,7 @@ class QueryBuilder
|
||||
* @param string $dqlPartName
|
||||
* @param string $dqlPart
|
||||
* @param string $append
|
||||
* @return QueryBuilder $qb
|
||||
* @return QueryBuilder This QueryBuilder instance.
|
||||
*/
|
||||
public function add($dqlPartName, $dqlPart, $append = false)
|
||||
{
|
||||
@ -396,7 +377,7 @@ class QueryBuilder
|
||||
* ->leftJoin('u.Phonenumbers', 'p');
|
||||
*
|
||||
* @param mixed $select String SELECT statement or SELECT Expr instance
|
||||
* @return QueryBuilder $qb
|
||||
* @return QueryBuilder This QueryBuilder instance.
|
||||
*/
|
||||
public function select($select = null)
|
||||
{
|
||||
@ -422,7 +403,7 @@ class QueryBuilder
|
||||
* ->leftJoin('u.Phonenumbers', 'p');
|
||||
*
|
||||
* @param mixed $select String SELECT statement or SELECT Expr instance
|
||||
* @return QueryBuilder $qb
|
||||
* @return QueryBuilder This QueryBuilder instance.
|
||||
*/
|
||||
public function addSelect($select = null)
|
||||
{
|
||||
@ -448,7 +429,7 @@ class QueryBuilder
|
||||
*
|
||||
* @param string $delete The model to delete
|
||||
* @param string $alias The alias of the model
|
||||
* @return QueryBuilder $qb
|
||||
* @return QueryBuilder This QueryBuilder instance.
|
||||
*/
|
||||
public function delete($delete = null, $alias = null)
|
||||
{
|
||||
@ -472,7 +453,7 @@ class QueryBuilder
|
||||
*
|
||||
* @param string $update The model to update
|
||||
* @param string $alias The alias of the model
|
||||
* @return QueryBuilder $qb
|
||||
* @return QueryBuilder This QueryBuilder instance.
|
||||
*/
|
||||
public function update($update = null, $alias = null)
|
||||
{
|
||||
@ -493,17 +474,17 @@ class QueryBuilder
|
||||
* ->select('u')
|
||||
* ->from('User', 'u')
|
||||
*
|
||||
* @param string $from The model name
|
||||
* @param string $alias The alias of the model
|
||||
* @return QueryBuilder $qb
|
||||
* @param string $from The class name.
|
||||
* @param string $alias The alias of the class.
|
||||
* @return QueryBuilder This QueryBuilder instance.
|
||||
*/
|
||||
public function from($from, $alias)
|
||||
{
|
||||
return $this->add('from', new Expr\From($from, $alias), true);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add a INNER JOIN
|
||||
* Add a INNER JOIN to an associated class.
|
||||
*
|
||||
* [php]
|
||||
* $qb = $em->createQueryBuilder()
|
||||
@ -515,7 +496,27 @@ class QueryBuilder
|
||||
* @param string $alias The alias of the join
|
||||
* @param string $conditionType The condition type constant. Either ON or WITH.
|
||||
* @param string $condition The condition for the join
|
||||
* @return QueryBuilder $qb
|
||||
* @return QueryBuilder This QueryBuilder instance.
|
||||
*/
|
||||
public function join($join, $alias, $conditionType = null, $condition = null)
|
||||
{
|
||||
return $this->innerJoin($join, $alias, $conditionType, $condition);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an INNER JOIN to an associated class.
|
||||
*
|
||||
* [php]
|
||||
* $qb = $em->createQueryBuilder()
|
||||
* ->select('u')
|
||||
* ->from('User', 'u')
|
||||
* ->innerJoin('u.Phonenumbers', 'p', Expr\Join::WITH, 'p.is_primary = 1');
|
||||
*
|
||||
* @param string $join The relationship to join
|
||||
* @param string $alias The alias of the join
|
||||
* @param string $conditionType The condition type constant. Either ON or WITH.
|
||||
* @param string $condition The condition for the join
|
||||
* @return QueryBuilder This QueryBuilder instance.
|
||||
*/
|
||||
public function innerJoin($join, $alias, $conditionType = null, $condition = null)
|
||||
{
|
||||
@ -756,7 +757,8 @@ class QueryBuilder
|
||||
*/
|
||||
public function orderBy($sort, $order = null)
|
||||
{
|
||||
return $this->add('orderBy', new Expr\OrderBy($sort, $order));
|
||||
return $this->add('orderBy', $sort instanceof Expr\OrderBy ? $sort
|
||||
: new Expr\OrderBy($sort, $order));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -839,8 +841,8 @@ class QueryBuilder
|
||||
return $this->getDql();
|
||||
}
|
||||
|
||||
public function __clone()
|
||||
/*public function __clone()
|
||||
{
|
||||
$this->_q = clone $this->_q;
|
||||
}
|
||||
}*/
|
||||
}
|
@ -40,7 +40,7 @@ class CmsAddress
|
||||
|
||||
/**
|
||||
* @OneToOne(targetEntity="CmsUser")
|
||||
* @JoinColumn(name="user_id", referencedColumnName="id")
|
||||
// * @JoinColumn(name="user_id", referencedColumnName="id")
|
||||
*/
|
||||
public $user;
|
||||
|
||||
|
@ -12,7 +12,7 @@ class CmsUser
|
||||
{
|
||||
/**
|
||||
* @Id @Column(type="integer")
|
||||
* @GeneratedValue(strategy="AUTO")
|
||||
* @GeneratedValue
|
||||
*/
|
||||
public $id;
|
||||
/**
|
||||
|
@ -39,8 +39,8 @@ class ManyToManyBasicAssociationTest extends \Doctrine\Tests\OrmFunctionalTestCa
|
||||
$user->addGroup($group2);
|
||||
|
||||
$this->_em->persist($user); // cascades to groups
|
||||
$this->_em->flush();
|
||||
|
||||
$this->_em->flush();
|
||||
$this->_em->clear();
|
||||
|
||||
$uRep = $this->_em->getRepository(get_class($user));
|
||||
|
@ -25,16 +25,15 @@ class AnnotationDriverTest extends \Doctrine\Tests\OrmTestCase
|
||||
/**
|
||||
* @group DDC-268
|
||||
*/
|
||||
public function testColumnWithMissingTypeThrowsException()
|
||||
public function testColumnWithMissingTypeDefaultsToString()
|
||||
{
|
||||
$cm = new ClassMetadata('Doctrine\Tests\ORM\Mapping\InvalidColumn');
|
||||
$reader = new \Doctrine\Common\Annotations\AnnotationReader(new \Doctrine\Common\Cache\ArrayCache());
|
||||
$reader->setDefaultAnnotationNamespace('Doctrine\ORM\Mapping\\');
|
||||
$annotationDriver = new \Doctrine\ORM\Mapping\Driver\AnnotationDriver($reader);
|
||||
|
||||
$this->setExpectedException('Doctrine\ORM\Mapping\MappingException',
|
||||
"The attribute 'type' is required for the column description of property Doctrine\\Tests\\ORM\\Mapping\\InvalidColumn::\$id");
|
||||
$annotationDriver->loadMetadataForClass('Doctrine\Tests\ORM\Mapping\InvalidColumn', $cm);
|
||||
$this->assertEquals('string', $cm->fieldMappings['id']['type']);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -86,6 +86,24 @@ class ClassMetadataTest extends \Doctrine\Tests\OrmTestCase
|
||||
|
||||
$this->assertEquals("DoctrineGlobal_User", $cm->associationMappings['author']->targetEntityName);
|
||||
}
|
||||
|
||||
public function testMapManyToManyJoinTableDefaults()
|
||||
{
|
||||
$cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
|
||||
$cm->mapManyToMany(
|
||||
array(
|
||||
'fieldName' => 'groups',
|
||||
'targetEntity' => 'CmsGroup'
|
||||
));
|
||||
|
||||
$assoc = $cm->associationMappings['groups'];
|
||||
$this->assertTrue($assoc instanceof \Doctrine\ORM\Mapping\ManyToManyMapping);
|
||||
$this->assertEquals(array(
|
||||
'name' => 'CmsUser_CmsGroup',
|
||||
'joinColumns' => array(array('name' => 'CmsUser_id', 'referencedColumnName' => 'id')),
|
||||
'inverseJoinColumns' => array(array('name' => 'CmsGroup_id', 'referencedColumnName' => 'id'))
|
||||
), $assoc->joinTable);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group DDC-115
|
||||
@ -141,8 +159,8 @@ class ClassMetadataTest extends \Doctrine\Tests\OrmTestCase
|
||||
public function testDuplicateAssociationMappingException()
|
||||
{
|
||||
$cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
|
||||
$a1 = new \Doctrine\ORM\Mapping\OneToOneMapping(array('fieldName' => 'foo', 'sourceEntity' => 'stdClass', 'targetEntity' => 'stdClass', 'joinColumns' => array()));
|
||||
$a2 = new \Doctrine\ORM\Mapping\OneToOneMapping(array('fieldName' => 'foo', 'sourceEntity' => 'stdClass', 'targetEntity' => 'stdClass', 'joinColumns' => array()));
|
||||
$a1 = new \Doctrine\ORM\Mapping\OneToOneMapping(array('fieldName' => 'foo', 'sourceEntity' => 'stdClass', 'targetEntity' => 'stdClass', 'mappedBy' => 'foo'));
|
||||
$a2 = new \Doctrine\ORM\Mapping\OneToOneMapping(array('fieldName' => 'foo', 'sourceEntity' => 'stdClass', 'targetEntity' => 'stdClass', 'mappedBy' => 'foo'));
|
||||
|
||||
$cm->addAssociationMapping($a1);
|
||||
$this->setExpectedException('Doctrine\ORM\Mapping\MappingException');
|
||||
|
@ -20,10 +20,8 @@
|
||||
<field name="email" column="user_email" type="string" column-definition="CHAR(32) NOT NULL" />
|
||||
|
||||
<one-to-one field="address" target-entity="Address">
|
||||
<cascade><cascade-remove /></cascade>
|
||||
<join-column name="address_id" referenced-column-name="id"/>
|
||||
<cascade>
|
||||
<cascade-remove />
|
||||
</cascade>
|
||||
</one-to-one>
|
||||
|
||||
<one-to-many field="phonenumbers" target-entity="Phonenumber" mapped-by="user">
|
||||
@ -33,6 +31,9 @@
|
||||
</one-to-many>
|
||||
|
||||
<many-to-many field="groups" target-entity="Group">
|
||||
<cascade>
|
||||
<cascade-all/>
|
||||
</cascade>
|
||||
<join-table name="cms_users_groups">
|
||||
<join-columns>
|
||||
<join-column name="user_id" referenced-column-name="id" nullable="false" unique="false" />
|
||||
@ -41,9 +42,6 @@
|
||||
<join-column name="group_id" referenced-column-name="id" column-definition="INT NULL" />
|
||||
</inverse-join-columns>
|
||||
</join-table>
|
||||
<cascade>
|
||||
<cascade-all/>
|
||||
</cascade>
|
||||
</many-to-many>
|
||||
|
||||
</entity>
|
||||
|
@ -266,53 +266,29 @@ class ExprTest extends \Doctrine\Tests\OrmTestCase
|
||||
|
||||
$this->assertEquals('(1 = 1) OR (1 < 5)', (string) $orExpr);
|
||||
}
|
||||
|
||||
public function testSelectExpr()
|
||||
{
|
||||
$selectExpr = $this->_expr->select();
|
||||
$selectExpr->add('u.id');
|
||||
$selectExpr->add('u.username');
|
||||
|
||||
$this->assertEquals('u.id, u.username', (string) $selectExpr);
|
||||
}
|
||||
|
||||
public function testFromExpr()
|
||||
{
|
||||
$this->assertEquals('User u', (string) $this->_expr->from('User', 'u'));
|
||||
}
|
||||
|
||||
public function testExprBaseCount()
|
||||
{
|
||||
$selectExpr = $this->_expr->select();
|
||||
$selectExpr->add('u.id');
|
||||
$selectExpr->add('u.username');
|
||||
|
||||
$this->assertEquals($selectExpr->count(), 2);
|
||||
}
|
||||
|
||||
public function testOrderByCountExpr()
|
||||
{
|
||||
$orderByExpr = $this->_expr->orderBy();
|
||||
$orderByExpr->add('u.username', 'DESC');
|
||||
$orderExpr = $this->_expr->desc('u.username');
|
||||
|
||||
$this->assertEquals($orderByExpr->count(), 1);
|
||||
$this->assertEquals('u.username DESC', (string) $orderByExpr);
|
||||
$this->assertEquals($orderExpr->count(), 1);
|
||||
$this->assertEquals('u.username DESC', (string) $orderExpr);
|
||||
}
|
||||
|
||||
public function testOrderByOrder()
|
||||
{
|
||||
$orderByExpr = $this->_expr->orderBy('u.username', 'DESC');
|
||||
$this->assertEquals('u.username DESC', (string) $orderByExpr);
|
||||
$orderExpr = $this->_expr->desc('u.username');
|
||||
$this->assertEquals('u.username DESC', (string) $orderExpr);
|
||||
}
|
||||
|
||||
public function testOrderByDefaultOrderIsAsc()
|
||||
public function testOrderByAsc()
|
||||
{
|
||||
$orderByExpr = $this->_expr->orderBy('u.username');
|
||||
$this->assertEquals('u.username ASC', (string) $orderByExpr);
|
||||
$orderExpr = $this->_expr->asc('u.username');
|
||||
$this->assertEquals('u.username ASC', (string) $orderExpr);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException Doctrine\Common\DoctrineException
|
||||
* @expectedException \InvalidArgumentException
|
||||
*/
|
||||
public function testAddThrowsException()
|
||||
{
|
||||
|
@ -281,6 +281,16 @@ class QueryBuilderTest extends \Doctrine\Tests\OrmTestCase
|
||||
|
||||
$this->assertValidQueryBuilder($qb, 'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u ORDER BY u.username ASC');
|
||||
}
|
||||
|
||||
public function testOrderByWithExpression()
|
||||
{
|
||||
$qb = $this->_em->createQueryBuilder();
|
||||
$qb->select('u')
|
||||
->from('Doctrine\Tests\Models\CMS\CmsUser', 'u')
|
||||
->orderBy($qb->expr()->asc('u.username'));
|
||||
|
||||
$this->assertValidQueryBuilder($qb, 'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u ORDER BY u.username ASC');
|
||||
}
|
||||
|
||||
public function testAddOrderBy()
|
||||
{
|
||||
@ -335,7 +345,7 @@ class QueryBuilderTest extends \Doctrine\Tests\OrmTestCase
|
||||
->where('u.id = :id');
|
||||
|
||||
$qb->setParameters(array('id' => 1));
|
||||
$this->assertEquals(array('id' => 1, 'test' => 1), $qb->getParameters(array('test' => 1)));
|
||||
$this->assertEquals(array('id' => 1), $qb->getParameters());
|
||||
}
|
||||
|
||||
public function testGetParameter()
|
||||
@ -382,7 +392,7 @@ class QueryBuilderTest extends \Doctrine\Tests\OrmTestCase
|
||||
public function testComplexWhere()
|
||||
{
|
||||
$qb = $this->_em->createQueryBuilder();
|
||||
$orExpr = $qb->expr()->orx();
|
||||
$orExpr = $qb->expr()->orX();
|
||||
$orExpr->add($qb->expr()->eq('u.id', ':uid3'));
|
||||
$orExpr->add($qb->expr()->in('u.id', array(1)));
|
||||
|
||||
@ -392,6 +402,90 @@ class QueryBuilderTest extends \Doctrine\Tests\OrmTestCase
|
||||
|
||||
$this->assertValidQueryBuilder($qb, 'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE (u.id = :uid3) OR (u.id IN(1))');
|
||||
}
|
||||
|
||||
public function testWhereInWithStringLiterals()
|
||||
{
|
||||
$qb = $this->_em->createQueryBuilder();
|
||||
$qb->select('u')
|
||||
->from('Doctrine\Tests\Models\CMS\CmsUser', 'u')
|
||||
->where($qb->expr()->in('u.name', array('one', 'two', 'three')));
|
||||
|
||||
$this->assertValidQueryBuilder($qb, "SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.name IN('one', 'two', 'three')");
|
||||
|
||||
$qb->where($qb->expr()->in('u.name', array("O'Reilly", "O'Neil", 'Smith')));
|
||||
|
||||
$this->assertValidQueryBuilder($qb, "SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.name IN('O''Reilly', 'O''Neil', 'Smith')");
|
||||
}
|
||||
|
||||
public function testWhereInWithObjectLiterals()
|
||||
{
|
||||
$qb = $this->_em->createQueryBuilder();
|
||||
$expr = $this->_em->getExpressionBuilder();
|
||||
$qb->select('u')
|
||||
->from('Doctrine\Tests\Models\CMS\CmsUser', 'u')
|
||||
->where($expr->in('u.name', array($expr->literal('one'), $expr->literal('two'), $expr->literal('three'))));
|
||||
|
||||
$this->assertValidQueryBuilder($qb, "SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.name IN('one', 'two', 'three')");
|
||||
|
||||
$qb->where($expr->in('u.name', array($expr->literal("O'Reilly"), $expr->literal("O'Neil"), $expr->literal('Smith'))));
|
||||
|
||||
$this->assertValidQueryBuilder($qb, "SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.name IN('O''Reilly', 'O''Neil', 'Smith')");
|
||||
}
|
||||
|
||||
public function testNegation()
|
||||
{
|
||||
$expr = $this->_em->getExpressionBuilder();
|
||||
$orExpr = $expr->orX();
|
||||
$orExpr->add($expr->eq('u.id', ':uid3'));
|
||||
$orExpr->add($expr->not($expr->in('u.id', array(1))));
|
||||
|
||||
$qb = $this->_em->createQueryBuilder();
|
||||
$qb->select('u')
|
||||
->from('Doctrine\Tests\Models\CMS\CmsUser', 'u')
|
||||
->where($orExpr);
|
||||
|
||||
$this->assertValidQueryBuilder($qb, 'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE (u.id = :uid3) OR (NOT(u.id IN(1)))');
|
||||
}
|
||||
|
||||
public function testSomeAllAny()
|
||||
{
|
||||
$qb = $this->_em->createQueryBuilder();
|
||||
$expr = $this->_em->getExpressionBuilder();
|
||||
|
||||
//$subquery = $qb->subquery('Doctrine\Tests\Models\CMS\CmsArticle', 'a')->select('a.id');
|
||||
|
||||
$qb->select('u')
|
||||
->from('Doctrine\Tests\Models\CMS\CmsUser', 'u')
|
||||
->where($expr->gt('u.id', $expr->all('select a.id from Doctrine\Tests\Models\CMS\CmsArticle a')));
|
||||
|
||||
$this->assertValidQueryBuilder($qb, 'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id > ALL(select a.id from Doctrine\Tests\Models\CMS\CmsArticle a)');
|
||||
|
||||
}
|
||||
|
||||
public function testMultipleIsolatedQueryConstruction()
|
||||
{
|
||||
$qb = $this->_em->createQueryBuilder();
|
||||
$expr = $this->_em->getExpressionBuilder();
|
||||
|
||||
$qb->select('u')->from('Doctrine\Tests\Models\CMS\CmsUser', 'u');
|
||||
$qb->where($expr->eq('u.name', ':name'));
|
||||
$qb->setParameter('name', 'romanb');
|
||||
|
||||
$q1 = $qb->getQuery();
|
||||
$this->assertEquals('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.name = :name', $q1->getDql());
|
||||
$this->assertEquals(1, count($q1->getParameters()));
|
||||
|
||||
// add another condition and construct a second query
|
||||
$qb->andWhere($expr->eq('u.id', ':id'));
|
||||
$qb->setParameter('id', 42);
|
||||
|
||||
$q2 = $qb->getQuery();
|
||||
|
||||
$this->assertEquals('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE (u.name = :name) AND (u.id = :id)', $q2->getDql());
|
||||
$this->assertTrue($q1 !== $q2); // two different, independent queries
|
||||
$this->assertEquals(2, count($q2->getParameters()));
|
||||
$this->assertEquals(1, count($q1->getParameters())); // $q1 unaffected
|
||||
}
|
||||
|
||||
public function testGetEntityManager()
|
||||
{
|
||||
|
@ -128,7 +128,7 @@ abstract class OrmFunctionalTestCase extends OrmTestCase
|
||||
if (isset($this->_usedModelSets['generic'])) {
|
||||
$conn->executeUpdate('DELETE FROM date_time_model');
|
||||
}
|
||||
|
||||
|
||||
$this->_em->clear();
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user