Merged with upstream/master
This commit is contained in:
commit
d0325d7048
22 changed files with 391 additions and 284 deletions
|
@ -1,7 +1,5 @@
|
|||
<?php
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
<?php
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
|
@ -21,17 +19,17 @@
|
|||
|
||||
namespace Doctrine\DBAL\Driver\PDOMsSql;
|
||||
|
||||
use PDO, Doctrine\DBAL\Driver\Connection as DriverConnection;
|
||||
|
||||
/**
|
||||
* MsSql Connection implementation.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
class Connection extends \Doctrine\DBAL\Driver\PDOConnection
|
||||
class Connection extends PDO implements DriverConnection
|
||||
{
|
||||
/**
|
||||
* Performs the rollback.
|
||||
*
|
||||
* @override
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function rollback()
|
||||
{
|
||||
|
@ -39,9 +37,7 @@ class Connection extends \Doctrine\DBAL\Driver\PDOConnection
|
|||
}
|
||||
|
||||
/**
|
||||
* Performs the commit.
|
||||
*
|
||||
* @override
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function commit()
|
||||
{
|
||||
|
@ -49,12 +45,21 @@ class Connection extends \Doctrine\DBAL\Driver\PDOConnection
|
|||
}
|
||||
|
||||
/**
|
||||
* Begins a database transaction.
|
||||
*
|
||||
* @override
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function beginTransaction()
|
||||
{
|
||||
$this->exec('BEGIN TRANSACTION');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function lastInsertId($name = null)
|
||||
{
|
||||
$stmt = $this->query('SELECT SCOPE_IDENTITY()');
|
||||
$id = $stmt->fetchColumn();
|
||||
$stmt->closeCursor();
|
||||
return $id;
|
||||
}
|
||||
}
|
|
@ -25,7 +25,7 @@ use Doctrine\DBAL\Platforms\AbstractPlatform;
|
|||
|
||||
/**
|
||||
* Type that maps an SQL INT to a PHP integer.
|
||||
*
|
||||
*
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
* @since 2.0
|
||||
*/
|
||||
|
@ -43,9 +43,9 @@ class IntegerType extends Type
|
|||
|
||||
public function convertToPHPValue($value, AbstractPlatform $platform)
|
||||
{
|
||||
return (int) $value;
|
||||
return (null === $value) ? null : (int) $value;
|
||||
}
|
||||
|
||||
|
||||
public function getBindingType()
|
||||
{
|
||||
return \PDO::PARAM_INT;
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
<?php
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
|
@ -30,10 +28,7 @@ use Doctrine\Common\EventManager,
|
|||
/**
|
||||
* The EntityManager is the central access point to ORM functionality.
|
||||
*
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.doctrine-project.org
|
||||
* @since 2.0
|
||||
* @version $Revision$
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||
* @author Jonathan Wage <jonwage@gmail.com>
|
||||
|
|
|
@ -21,23 +21,36 @@ namespace Doctrine\ORM\Id;
|
|||
|
||||
use Doctrine\ORM\EntityManager;
|
||||
|
||||
/**
|
||||
* Id generator that obtains IDs from special "identity" columns. These are columns
|
||||
* that automatically get a database-generated, auto-incremented identifier on INSERT.
|
||||
* This generator obtains the last insert id after such an insert.
|
||||
*/
|
||||
class IdentityGenerator extends AbstractIdGenerator
|
||||
{
|
||||
/** @var string The name of the sequence to pass to lastInsertId(), if any. */
|
||||
private $_seqName;
|
||||
|
||||
/**
|
||||
* Generates an ID for the given entity.
|
||||
*
|
||||
* @param object $entity
|
||||
* @return integer|float
|
||||
* @override
|
||||
* @param string $seqName The name of the sequence to pass to lastInsertId()
|
||||
* to obtain the last generated identifier within the current
|
||||
* database session/connection, if any.
|
||||
*/
|
||||
public function generate(EntityManager $em, $entity)
|
||||
public function __construct($seqName = null)
|
||||
{
|
||||
return $em->getConnection()->lastInsertId();
|
||||
$this->_seqName = $seqName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return boolean
|
||||
* @override
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function generate(EntityManager $em, $entity)
|
||||
{
|
||||
return $em->getConnection()->lastInsertId($this->_seqName);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isPostInsertGenerator()
|
||||
{
|
||||
|
|
|
@ -1,46 +0,0 @@
|
|||
<?php
|
||||
/*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information, see
|
||||
* <http://www.doctrine-project.org>.
|
||||
*/
|
||||
|
||||
namespace Doctrine\ORM\Id;
|
||||
|
||||
use Doctrine\ORM\EntityManager;
|
||||
|
||||
class SequenceIdentityGenerator extends IdentityGenerator
|
||||
{
|
||||
private $_sequenceName;
|
||||
|
||||
public function __construct($sequenceName)
|
||||
{
|
||||
$this->_sequenceName = $sequenceName;
|
||||
}
|
||||
|
||||
public function generate(EntityManager $em, $entity)
|
||||
{
|
||||
return $em->getConnection()->lastInsertId($this->_sequenceName);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return boolean
|
||||
* @override
|
||||
*/
|
||||
public function isPostInsertGenerator()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -19,8 +19,10 @@
|
|||
|
||||
namespace Doctrine\ORM\Mapping;
|
||||
|
||||
use Doctrine\ORM\ORMException,
|
||||
Doctrine\DBAL\Platforms\AbstractPlatform,
|
||||
use ReflectionException,
|
||||
Doctrine\ORM\ORMException,
|
||||
Doctrine\ORM\EntityManager,
|
||||
Doctrine\DBAL\Platforms,
|
||||
Doctrine\ORM\Events;
|
||||
|
||||
/**
|
||||
|
@ -53,7 +55,7 @@ class ClassMetadataFactory
|
|||
*
|
||||
* @param $driver The metadata driver to use.
|
||||
*/
|
||||
public function __construct(\Doctrine\ORM\EntityManager $em)
|
||||
public function __construct(EntityManager $em)
|
||||
{
|
||||
$this->_em = $em;
|
||||
}
|
||||
|
@ -94,15 +96,15 @@ class ClassMetadataFactory
|
|||
if ( ! $this->_initialized) {
|
||||
$this->_initialize();
|
||||
}
|
||||
|
||||
|
||||
$metadata = array();
|
||||
foreach ($this->_driver->getAllClassNames() as $className) {
|
||||
$metadata[] = $this->getMetadataFor($className);
|
||||
}
|
||||
|
||||
|
||||
return $metadata;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Lazy initialization of this stuff, especially the metadata driver,
|
||||
* since these are not needed at all when a metadata cache is active.
|
||||
|
@ -252,7 +254,7 @@ class ClassMetadataFactory
|
|||
// Invoke driver
|
||||
try {
|
||||
$this->_driver->loadMetadataForClass($className, $class);
|
||||
} catch(\ReflectionException $e) {
|
||||
} catch(ReflectionException $e) {
|
||||
throw MappingException::reflectionFailure($className, $e);
|
||||
}
|
||||
|
||||
|
@ -275,9 +277,9 @@ class ClassMetadataFactory
|
|||
} else {
|
||||
$this->_completeIdGeneratorMapping($class);
|
||||
}
|
||||
|
||||
|
||||
if ($parent && $parent->isInheritanceTypeSingleTable()) {
|
||||
$class->setTableName($parent->getTableName());
|
||||
$class->setPrimaryTable($parent->table);
|
||||
}
|
||||
|
||||
$class->setParentClasses($visited);
|
||||
|
@ -376,7 +378,13 @@ class ClassMetadataFactory
|
|||
// Create & assign an appropriate ID generator instance
|
||||
switch ($class->generatorType) {
|
||||
case ClassMetadata::GENERATOR_TYPE_IDENTITY:
|
||||
$class->setIdGenerator(new \Doctrine\ORM\Id\IdentityGenerator());
|
||||
// For PostgreSQL IDENTITY (SERIAL) we need a sequence name. It defaults to
|
||||
// <table>_<column>_seq in PostgreSQL for SERIAL columns.
|
||||
// Not pretty but necessary and the simplest solution that currently works.
|
||||
$seqName = $this->_targetPlatform instanceof Platforms\PostgreSQLPlatform ?
|
||||
$class->table['name'] . '_' . $class->columnNames[$class->identifier[0]] . '_seq' :
|
||||
null;
|
||||
$class->setIdGenerator(new \Doctrine\ORM\Id\IdentityGenerator($seqName));
|
||||
break;
|
||||
case ClassMetadata::GENERATOR_TYPE_SEQUENCE:
|
||||
// If there is no sequence definition yet, create a default definition
|
||||
|
|
|
@ -317,7 +317,7 @@ class ClassMetadataInfo
|
|||
* READ-ONLY: The ID generator used for generating IDs for this class.
|
||||
*
|
||||
* @var AbstractIdGenerator
|
||||
* @todo Remove
|
||||
* @todo Remove!
|
||||
*/
|
||||
public $idGenerator;
|
||||
|
||||
|
@ -335,6 +335,7 @@ class ClassMetadataInfo
|
|||
* </code>
|
||||
*
|
||||
* @var array
|
||||
* @todo Merge with tableGeneratorDefinition into generic generatorDefinition
|
||||
*/
|
||||
public $sequenceGeneratorDefinition;
|
||||
|
||||
|
@ -343,6 +344,7 @@ class ClassMetadataInfo
|
|||
* TABLE generation strategy.
|
||||
*
|
||||
* @var array
|
||||
* @todo Merge with tableGeneratorDefinition into generic generatorDefinition
|
||||
*/
|
||||
public $tableGeneratorDefinition;
|
||||
|
||||
|
@ -395,7 +397,7 @@ class ClassMetadataInfo
|
|||
public function getReflectionClass()
|
||||
{
|
||||
if ( ! $this->reflClass) {
|
||||
$this->reflClass = new ReflectionClass($entityName);
|
||||
$this->reflClass = new ReflectionClass($this->name);
|
||||
}
|
||||
return $this->reflClass;
|
||||
}
|
||||
|
@ -901,8 +903,8 @@ class ClassMetadataInfo
|
|||
/**
|
||||
* Sets the name of the primary table the class is mapped to.
|
||||
*
|
||||
* @param string $tableName The table name.
|
||||
* @deprecated
|
||||
* @param string $tableName The table name.
|
||||
* @deprecated Use {@link setPrimaryTable}.
|
||||
*/
|
||||
public function setTableName($tableName)
|
||||
{
|
||||
|
@ -910,18 +912,22 @@ class ClassMetadataInfo
|
|||
}
|
||||
|
||||
/**
|
||||
* Sets the primary table definition. The provided array must have the
|
||||
* Sets the primary table definition. The provided array supports the
|
||||
* following structure:
|
||||
*
|
||||
* name => <tableName>
|
||||
* schema => <schemaName>
|
||||
* catalog => <catalogName>
|
||||
* name => <tableName> (optional, defaults to class name)
|
||||
* indexes => array of indexes (optional)
|
||||
* uniqueConstraints => array of constraints (optional)
|
||||
*
|
||||
* @param array $primaryTableDefinition
|
||||
* @param array $table
|
||||
*/
|
||||
public function setPrimaryTable(array $primaryTableDefinition)
|
||||
public function setPrimaryTable(array $table)
|
||||
{
|
||||
$this->table = $primaryTableDefinition;
|
||||
if (isset($table['name']) && $table['name'][0] == '`') {
|
||||
$table['name'] = trim($table['name'], '`');
|
||||
$table['quoted'] = true;
|
||||
}
|
||||
$this->table = $table;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
<?php
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
|
@ -31,14 +29,11 @@ require __DIR__ . '/DoctrineAnnotations.php';
|
|||
/**
|
||||
* The AnnotationDriver reads the mapping metadata from docblock annotations.
|
||||
*
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.doctrine-project.org
|
||||
* @since 2.0
|
||||
* @version $Revision$
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||
* @author Jonathan H. Wage <jonwage@gmail.com>
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
* @since 2.0
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||
* @author Jonathan H. Wage <jonwage@gmail.com>
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
*/
|
||||
class AnnotationDriver implements Driver
|
||||
{
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
<?php
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
|
|
|
@ -62,13 +62,16 @@ class XmlDriver extends AbstractFileDriver
|
|||
}
|
||||
|
||||
// Evaluate <entity...> attributes
|
||||
$table = array();
|
||||
if (isset($xmlRoot['table'])) {
|
||||
$metadata->table['name'] = (string)$xmlRoot['table'];
|
||||
$table['name'] = (string)$xmlRoot['table'];
|
||||
}
|
||||
|
||||
$metadata->setPrimaryTable($table);
|
||||
|
||||
/* not implemented specially anyway. use table = schema.table
|
||||
if (isset($xmlRoot['schema'])) {
|
||||
$metadata->table['schema'] = (string)$xmlRoot['schema'];
|
||||
}
|
||||
}*/
|
||||
|
||||
if (isset($xmlRoot['inheritance-type'])) {
|
||||
$inheritanceType = (string)$xmlRoot['inheritance-type'];
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
<?php
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
|
@ -27,14 +25,11 @@ use Doctrine\ORM\Mapping\ClassMetadataInfo,
|
|||
/**
|
||||
* The YamlDriver reads the mapping metadata from yaml schema files.
|
||||
*
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.doctrine-project.org
|
||||
* @since 2.0
|
||||
* @version $Revision$
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||
* @author Jonathan H. Wage <jonwage@gmail.com>
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
* @since 2.0
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||
* @author Jonathan H. Wage <jonwage@gmail.com>
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
*/
|
||||
class YamlDriver extends AbstractFileDriver
|
||||
{
|
||||
|
@ -61,13 +56,16 @@ class YamlDriver extends AbstractFileDriver
|
|||
}
|
||||
|
||||
// Evaluate root level properties
|
||||
$table = array();
|
||||
if (isset($element['table'])) {
|
||||
$metadata->table['name'] = $element['table'];
|
||||
$table['name'] = $element['table'];
|
||||
}
|
||||
$metadata->setPrimaryTable($table);
|
||||
|
||||
/* not implemented specially anyway. use table = schema.table
|
||||
if (isset($element['schema'])) {
|
||||
$metadata->table['schema'] = $element['schema'];
|
||||
}
|
||||
}*/
|
||||
|
||||
if (isset($element['inheritanceType'])) {
|
||||
$metadata->setInheritanceType(constant('Doctrine\ORM\Mapping\ClassMetadata::INHERITANCE_TYPE_' . strtoupper($element['inheritanceType'])));
|
||||
|
|
|
@ -36,7 +36,7 @@ class ManyToManyPersister extends AbstractCollectionPersister
|
|||
*
|
||||
* @override
|
||||
*/
|
||||
protected function _getDeleteRowSql(PersistentCollection $coll)
|
||||
protected function _getDeleteRowSQL(PersistentCollection $coll)
|
||||
{
|
||||
$mapping = $coll->getMapping();
|
||||
$joinTable = $mapping->joinTable;
|
||||
|
@ -51,7 +51,7 @@ class ManyToManyPersister extends AbstractCollectionPersister
|
|||
* @internal Order of the parameters must be the same as the order of the columns in
|
||||
* _getDeleteRowSql.
|
||||
*/
|
||||
protected function _getDeleteRowSqlParameters(PersistentCollection $coll, $element)
|
||||
protected function _getDeleteRowSQLParameters(PersistentCollection $coll, $element)
|
||||
{
|
||||
return $this->_collectJoinTableColumnParameters($coll, $element);
|
||||
}
|
||||
|
@ -61,7 +61,7 @@ class ManyToManyPersister extends AbstractCollectionPersister
|
|||
*
|
||||
* @override
|
||||
*/
|
||||
protected function _getUpdateRowSql(PersistentCollection $coll)
|
||||
protected function _getUpdateRowSQL(PersistentCollection $coll)
|
||||
{}
|
||||
|
||||
/**
|
||||
|
@ -71,7 +71,7 @@ class ManyToManyPersister extends AbstractCollectionPersister
|
|||
* @internal Order of the parameters must be the same as the order of the columns in
|
||||
* _getInsertRowSql.
|
||||
*/
|
||||
protected function _getInsertRowSql(PersistentCollection $coll)
|
||||
protected function _getInsertRowSQL(PersistentCollection $coll)
|
||||
{
|
||||
$mapping = $coll->getMapping();
|
||||
$joinTable = $mapping->joinTable;
|
||||
|
@ -87,11 +87,11 @@ class ManyToManyPersister extends AbstractCollectionPersister
|
|||
* @internal Order of the parameters must be the same as the order of the columns in
|
||||
* _getInsertRowSql.
|
||||
*/
|
||||
protected function _getInsertRowSqlParameters(PersistentCollection $coll, $element)
|
||||
protected function _getInsertRowSQLParameters(PersistentCollection $coll, $element)
|
||||
{
|
||||
return $this->_collectJoinTableColumnParameters($coll, $element);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Collects the parameters for inserting/deleting on the join table in the order
|
||||
* of the join table columns as specified in ManyToManyMapping#joinTableColumns.
|
||||
|
@ -105,15 +105,15 @@ class ManyToManyPersister extends AbstractCollectionPersister
|
|||
$params = array();
|
||||
$mapping = $coll->getMapping();
|
||||
$isComposite = count($mapping->joinTableColumns) > 2;
|
||||
|
||||
|
||||
$identifier1 = $this->_uow->getEntityIdentifier($coll->getOwner());
|
||||
$identifier2 = $this->_uow->getEntityIdentifier($element);
|
||||
|
||||
|
||||
if ($isComposite) {
|
||||
$class1 = $this->_em->getClassMetadata(get_class($coll->getOwner()));
|
||||
$class2 = $coll->getTypeClass();
|
||||
}
|
||||
|
||||
|
||||
foreach ($mapping->joinTableColumns as $joinTableColumn) {
|
||||
if (isset($mapping->relationToSourceKeyColumns[$joinTableColumn])) {
|
||||
if ($isComposite) {
|
||||
|
@ -138,7 +138,7 @@ class ManyToManyPersister extends AbstractCollectionPersister
|
|||
*
|
||||
* @override
|
||||
*/
|
||||
protected function _getDeleteSql(PersistentCollection $coll)
|
||||
protected function _getDeleteSQL(PersistentCollection $coll)
|
||||
{
|
||||
$mapping = $coll->getMapping();
|
||||
$joinTable = $mapping->joinTable;
|
||||
|
@ -157,7 +157,7 @@ class ManyToManyPersister extends AbstractCollectionPersister
|
|||
* @internal Order of the parameters must be the same as the order of the columns in
|
||||
* _getDeleteSql.
|
||||
*/
|
||||
protected function _getDeleteSqlParameters(PersistentCollection $coll)
|
||||
protected function _getDeleteSQLParameters(PersistentCollection $coll)
|
||||
{
|
||||
$params = array();
|
||||
$mapping = $coll->getMapping();
|
||||
|
@ -170,7 +170,7 @@ class ManyToManyPersister extends AbstractCollectionPersister
|
|||
} else {
|
||||
$params[] = array_pop($identifier);
|
||||
}
|
||||
|
||||
|
||||
return $params;
|
||||
}
|
||||
}
|
|
@ -25,7 +25,7 @@ use Doctrine\ORM\PersistentCollection;
|
|||
|
||||
/**
|
||||
* Persister for one-to-many collections.
|
||||
*
|
||||
*
|
||||
* IMPORTANT:
|
||||
* This persister is only used for uni-directional one-to-many mappings on a foreign key
|
||||
* (which are not yet supported). So currently this persister is not used.
|
||||
|
@ -44,7 +44,7 @@ class OneToManyPersister extends AbstractCollectionPersister
|
|||
* @return string
|
||||
* @override
|
||||
*/
|
||||
protected function _getDeleteRowSql(PersistentCollection $coll)
|
||||
protected function _getDeleteRowSQL(PersistentCollection $coll)
|
||||
{
|
||||
$mapping = $coll->getMapping();
|
||||
$targetClass = $this->_em->getClassMetadata($mapping->getTargetEntityName());
|
||||
|
@ -67,36 +67,36 @@ class OneToManyPersister extends AbstractCollectionPersister
|
|||
return array("UPDATE $table SET $setClause WHERE $whereClause", $this->_uow->getEntityIdentifier($element));
|
||||
}
|
||||
|
||||
protected function _getInsertRowSql(PersistentCollection $coll)
|
||||
protected function _getInsertRowSQL(PersistentCollection $coll)
|
||||
{
|
||||
return "UPDATE xxx SET foreign_key = yyy WHERE foreign_key = zzz";
|
||||
}
|
||||
|
||||
/* Not used for OneToManyPersister */
|
||||
protected function _getUpdateRowSql(PersistentCollection $coll)
|
||||
protected function _getUpdateRowSQL(PersistentCollection $coll)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Generates the SQL UPDATE that updates all the foreign keys to null.
|
||||
*
|
||||
* @param PersistentCollection $coll
|
||||
*/
|
||||
protected function _getDeleteSql(PersistentCollection $coll)
|
||||
protected function _getDeleteSQL(PersistentCollection $coll)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the SQL parameters for the corresponding SQL statement to delete
|
||||
* the given collection.
|
||||
*
|
||||
* @param PersistentCollection $coll
|
||||
*/
|
||||
protected function _getDeleteSqlParameters(PersistentCollection $coll)
|
||||
protected function _getDeleteSQLParameters(PersistentCollection $coll)
|
||||
{}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the SQL parameters for the corresponding SQL statement to insert the given
|
||||
* element of the given collection into the database.
|
||||
|
@ -104,9 +104,9 @@ class OneToManyPersister extends AbstractCollectionPersister
|
|||
* @param PersistentCollection $coll
|
||||
* @param mixed $element
|
||||
*/
|
||||
protected function _getInsertRowSqlParameters(PersistentCollection $coll, $element)
|
||||
protected function _getInsertRowSQLParameters(PersistentCollection $coll, $element)
|
||||
{}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the SQL parameters for the corresponding SQL statement to delete the given
|
||||
* element from the given collection.
|
||||
|
@ -114,6 +114,6 @@ class OneToManyPersister extends AbstractCollectionPersister
|
|||
* @param PersistentCollection $coll
|
||||
* @param mixed $element
|
||||
*/
|
||||
protected function _getDeleteRowSqlParameters(PersistentCollection $coll, $element)
|
||||
protected function _getDeleteRowSQLParameters(PersistentCollection $coll, $element)
|
||||
{}
|
||||
}
|
|
@ -1,7 +1,5 @@
|
|||
<?php
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
|
@ -27,30 +25,29 @@ use Doctrine\ORM\Query\Expr;
|
|||
* This class is responsible for building DQL query strings via an object oriented
|
||||
* PHP interface.
|
||||
*
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.doctrine-project.org
|
||||
* @since 2.0
|
||||
* @version $Revision$
|
||||
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||
* @author Jonathan Wage <jonwage@gmail.com>
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
* @since 2.0
|
||||
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||
* @author Jonathan Wage <jonwage@gmail.com>
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
*/
|
||||
class QueryBuilder
|
||||
{
|
||||
/* The query types. */
|
||||
const SELECT = 0;
|
||||
const DELETE = 1;
|
||||
const UPDATE = 2;
|
||||
|
||||
/** The builder states. */
|
||||
const STATE_DIRTY = 0;
|
||||
const STATE_CLEAN = 1;
|
||||
|
||||
/**
|
||||
* @var EntityManager $em The EntityManager used by this QueryBuilder.
|
||||
* @var EntityManager The EntityManager used by this QueryBuilder.
|
||||
*/
|
||||
private $_em;
|
||||
|
||||
/**
|
||||
* @var array $dqlParts The array of DQL parts collected.
|
||||
* @var array The array of DQL parts collected.
|
||||
*/
|
||||
private $_dqlParts = array(
|
||||
'select' => array(),
|
||||
|
@ -105,13 +102,17 @@ class QueryBuilder
|
|||
|
||||
/**
|
||||
* Gets an ExpressionBuilder used for object-oriented construction of query expressions.
|
||||
* Intended for convenient inline usage. Example:
|
||||
* This producer method is intended for convenient inline usage. Example:
|
||||
*
|
||||
* [php]
|
||||
* <code>
|
||||
* $qb = $em->createQueryBuilder()
|
||||
* ->select('u')
|
||||
* ->from('User', 'u')
|
||||
* ->where($qb->expr()->eq('u.id', 1));
|
||||
* </code>
|
||||
*
|
||||
* For more complex expression construction, consider storing the expression
|
||||
* builder object in a local variable.
|
||||
*
|
||||
* @return Expr
|
||||
*/
|
||||
|
@ -141,16 +142,9 @@ class QueryBuilder
|
|||
}
|
||||
|
||||
/**
|
||||
* Get the state of this query builder instance
|
||||
* Get the state of this query builder instance.
|
||||
*
|
||||
* [php]
|
||||
* if ($qb->getState() == QueryBuilder::STATE_DIRTY) {
|
||||
* echo 'Query builder is dirty';
|
||||
* } else {
|
||||
* echo 'Query builder is clean';
|
||||
* }
|
||||
*
|
||||
* @return integer
|
||||
* @return integer Either QueryBuilder::STATE_DIRTY or QueryBuilder::STATE_CLEAN.
|
||||
*/
|
||||
public function getState()
|
||||
{
|
||||
|
@ -158,15 +152,16 @@ class QueryBuilder
|
|||
}
|
||||
|
||||
/**
|
||||
* Get the complete DQL string for this query builder instance
|
||||
* Get the complete DQL string formed by the current specifications of this QueryBuilder.
|
||||
*
|
||||
* [php]
|
||||
* <code>
|
||||
* $qb = $em->createQueryBuilder()
|
||||
* ->select('u')
|
||||
* ->from('User', 'u')
|
||||
* echo $qb->getDql(); // SELECT u FROM User u
|
||||
* </code>
|
||||
*
|
||||
* @return string The DQL string
|
||||
* @return string The DQL query string.
|
||||
*/
|
||||
public function getDQL()
|
||||
{
|
||||
|
@ -198,14 +193,15 @@ class QueryBuilder
|
|||
}
|
||||
|
||||
/**
|
||||
* Constructs a Query instance from the current configuration of the builder.
|
||||
* Constructs a Query instance from the current specifications of the builder.
|
||||
*
|
||||
* [php]
|
||||
* <code>
|
||||
* $qb = $em->createQueryBuilder()
|
||||
* ->select('u')
|
||||
* ->from('User', 'u');
|
||||
* $q = $qb->getQuery();
|
||||
* $results = $q->execute();
|
||||
* </code>
|
||||
*
|
||||
* @return Query
|
||||
*/
|
||||
|
@ -218,17 +214,19 @@ class QueryBuilder
|
|||
}
|
||||
|
||||
/**
|
||||
* Get the root alias for the query. This is the first entity alias involved
|
||||
* in the construction of the query
|
||||
* Gets the root alias of the query. This is the first entity alias involved
|
||||
* in the construction of the query.
|
||||
*
|
||||
* [php]
|
||||
* <code>
|
||||
* $qb = $em->createQueryBuilder()
|
||||
* ->select('u')
|
||||
* ->from('User', 'u');
|
||||
*
|
||||
* echo $qb->getRootAlias(); // u
|
||||
* </code>
|
||||
*
|
||||
* @return string $rootAlias
|
||||
* @todo Rename/Refactor: getRootAliases(), there can be multiple roots!
|
||||
*/
|
||||
public function getRootAlias()
|
||||
{
|
||||
|
@ -236,14 +234,15 @@ class QueryBuilder
|
|||
}
|
||||
|
||||
/**
|
||||
* Sets a query parameter.
|
||||
* Sets a query parameter for the query being constructed.
|
||||
*
|
||||
* [php]
|
||||
* <code>
|
||||
* $qb = $em->createQueryBuilder()
|
||||
* ->select('u')
|
||||
* ->from('User', 'u')
|
||||
* ->where('u.id = :user_id')
|
||||
* ->setParameter(':user_id', 1);
|
||||
* </code>
|
||||
*
|
||||
* @param string|integer $key The parameter position or name.
|
||||
* @param mixed $value The parameter value.
|
||||
|
@ -256,9 +255,9 @@ class QueryBuilder
|
|||
}
|
||||
|
||||
/**
|
||||
* Sets a collection of query parameters.
|
||||
* Sets a collection of query parameters for the query being constructed.
|
||||
*
|
||||
* [php]
|
||||
* <code>
|
||||
* $qb = $em->createQueryBuilder()
|
||||
* ->select('u')
|
||||
* ->from('User', 'u')
|
||||
|
@ -267,8 +266,9 @@ class QueryBuilder
|
|||
* ':user_id1' => 1,
|
||||
* ':user_id2' => 2
|
||||
* ));
|
||||
* </code>
|
||||
*
|
||||
* @param array $params
|
||||
* @param array $params The query parameters to set.
|
||||
* @return QueryBuilder This QueryBuilder instance.
|
||||
*/
|
||||
public function setParameters(array $params)
|
||||
|
@ -278,17 +278,17 @@ class QueryBuilder
|
|||
}
|
||||
|
||||
/**
|
||||
* Get all defined parameters
|
||||
* Gets all defined query parameters for the query being constructed.
|
||||
*
|
||||
* @return array Defined parameters
|
||||
* @return array The currently defined query parameters.
|
||||
*/
|
||||
public function getParameters($params = array())
|
||||
public function getParameters()
|
||||
{
|
||||
return $this->_params;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets a query parameter.
|
||||
* Gets a (previously set) query parameter of the query being constructed.
|
||||
*
|
||||
* @param mixed $key The key (index or name) of the bound parameter.
|
||||
* @return mixed The value of the bound parameter.
|
||||
|
@ -297,7 +297,7 @@ class QueryBuilder
|
|||
{
|
||||
return isset($this->_params[$key]) ? $this->_params[$key] : null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the position of the first result to retrieve (the "offset").
|
||||
*
|
||||
|
@ -309,10 +309,10 @@ class QueryBuilder
|
|||
$this->_firstResult = $firstResult;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the position of the first result the query object was set to retrieve (the "offset").
|
||||
* Returns NULL if {@link setFirstResult} was not applied to this query builder.
|
||||
* Returns NULL if {@link setFirstResult} was not applied to this QueryBuilder.
|
||||
*
|
||||
* @return integer The position of the first result.
|
||||
*/
|
||||
|
@ -324,7 +324,7 @@ class QueryBuilder
|
|||
/**
|
||||
* Sets the maximum number of results to retrieve (the "limit").
|
||||
*
|
||||
* @param integer $maxResults
|
||||
* @param integer $maxResults The maximum number of results to retrieve.
|
||||
* @return QueryBuilder This QueryBuilder instance.
|
||||
*/
|
||||
public function setMaxResults($maxResults)
|
||||
|
@ -345,7 +345,10 @@ class QueryBuilder
|
|||
}
|
||||
|
||||
/**
|
||||
* Add a single DQL query part to the array of parts
|
||||
* Either appends to or replaces a single, generic query part.
|
||||
*
|
||||
* The available parts are: 'select', 'from', 'join', 'set', 'where',
|
||||
* 'groupBy', 'having' and 'orderBy'.
|
||||
*
|
||||
* @param string $dqlPartName
|
||||
* @param string $dqlPart
|
||||
|
@ -368,15 +371,17 @@ class QueryBuilder
|
|||
}
|
||||
|
||||
/**
|
||||
* Set the SELECT statement
|
||||
* Specifies an item that is to be returned in the query result.
|
||||
* Replaces any previously specified selections, if any.
|
||||
*
|
||||
* [php]
|
||||
* <code>
|
||||
* $qb = $em->createQueryBuilder()
|
||||
* ->select('u', 'p')
|
||||
* ->from('User', 'u')
|
||||
* ->leftJoin('u.Phonenumbers', 'p');
|
||||
* </code>
|
||||
*
|
||||
* @param mixed $select String SELECT statement or SELECT Expr instance
|
||||
* @param mixed $select The selection expressions.
|
||||
* @return QueryBuilder This QueryBuilder instance.
|
||||
*/
|
||||
public function select($select = null)
|
||||
|
@ -393,16 +398,17 @@ class QueryBuilder
|
|||
}
|
||||
|
||||
/**
|
||||
* Add to the SELECT statement
|
||||
* Adds an item that is to be returned in the query result.
|
||||
*
|
||||
* [php]
|
||||
* <code>
|
||||
* $qb = $em->createQueryBuilder()
|
||||
* ->select('u')
|
||||
* ->addSelect('p')
|
||||
* ->from('User', 'u')
|
||||
* ->leftJoin('u.Phonenumbers', 'p');
|
||||
* </code>
|
||||
*
|
||||
* @param mixed $select String SELECT statement or SELECT Expr instance
|
||||
* @param mixed $select The selection expression.
|
||||
* @return QueryBuilder This QueryBuilder instance.
|
||||
*/
|
||||
public function addSelect($select = null)
|
||||
|
@ -419,16 +425,18 @@ class QueryBuilder
|
|||
}
|
||||
|
||||
/**
|
||||
* Construct a DQL DELETE query
|
||||
* Turns the query being built into a bulk delete query that ranges over
|
||||
* a certain entity type.
|
||||
*
|
||||
* [php]
|
||||
* <code>
|
||||
* $qb = $em->createQueryBuilder()
|
||||
* ->delete('User', 'u')
|
||||
* ->where('u.id = :user_id');
|
||||
* ->setParameter(':user_id', 1);
|
||||
* </code>
|
||||
*
|
||||
* @param string $delete The model to delete
|
||||
* @param string $alias The alias of the model
|
||||
* @param string $delete The class/type whose instances are subject to the deletion.
|
||||
* @param string $alias The class/type alias used in the constructed query.
|
||||
* @return QueryBuilder This QueryBuilder instance.
|
||||
*/
|
||||
public function delete($delete = null, $alias = null)
|
||||
|
@ -443,16 +451,18 @@ class QueryBuilder
|
|||
}
|
||||
|
||||
/**
|
||||
* Construct a DQL UPDATE query
|
||||
* Turns the query being built into a bulk update query that ranges over
|
||||
* a certain entity type.
|
||||
*
|
||||
* [php]
|
||||
* <code>
|
||||
* $qb = $em->createQueryBuilder()
|
||||
* ->update('User', 'u')
|
||||
* ->set('u.password', md5('password'))
|
||||
* ->where('u.id = ?');
|
||||
* </code>
|
||||
*
|
||||
* @param string $update The model to update
|
||||
* @param string $alias The alias of the model
|
||||
* @param string $update The class/type whose instances are subject to the update.
|
||||
* @param string $alias The class/type alias used in the constructed query.
|
||||
* @return QueryBuilder This QueryBuilder instance.
|
||||
*/
|
||||
public function update($update = null, $alias = null)
|
||||
|
@ -467,12 +477,14 @@ class QueryBuilder
|
|||
}
|
||||
|
||||
/**
|
||||
* Specify the FROM part when constructing a SELECT DQL query
|
||||
* Create and add a query root corresponding to the entity identified by the given alias,
|
||||
* forming a cartesian product with any existing query roots.
|
||||
*
|
||||
* [php]
|
||||
* <code>
|
||||
* $qb = $em->createQueryBuilder()
|
||||
* ->select('u')
|
||||
* ->from('User', 'u')
|
||||
* </code>
|
||||
*
|
||||
* @param string $from The class name.
|
||||
* @param string $alias The alias of the class.
|
||||
|
@ -482,20 +494,25 @@ class QueryBuilder
|
|||
{
|
||||
return $this->add('from', new Expr\From($from, $alias), true);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add a INNER JOIN to an associated class.
|
||||
* Creates and adds a join over an entity association to the query.
|
||||
*
|
||||
* [php]
|
||||
* The entities in the joined association will be fetched as part of the query
|
||||
* result if the alias used for the joined association is placed in the select
|
||||
* expressions.
|
||||
*
|
||||
* <code>
|
||||
* $qb = $em->createQueryBuilder()
|
||||
* ->select('u')
|
||||
* ->from('User', 'u')
|
||||
* ->innerJoin('u.Phonenumbers', 'p', Expr\Join::WITH, 'p.is_primary = 1');
|
||||
* ->join('u.Phonenumbers', 'p', Expr\Join::WITH, 'p.is_primary = 1');
|
||||
* </code>
|
||||
*
|
||||
* @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
|
||||
* @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 join($join, $alias, $conditionType = null, $condition = null)
|
||||
|
@ -504,7 +521,11 @@ class QueryBuilder
|
|||
}
|
||||
|
||||
/**
|
||||
* Add an INNER JOIN to an associated class.
|
||||
* Creates and adds a join over an entity association to the query.
|
||||
*
|
||||
* The entities in the joined association will be fetched as part of the query
|
||||
* result if the alias used for the joined association is placed in the select
|
||||
* expressions.
|
||||
*
|
||||
* [php]
|
||||
* $qb = $em->createQueryBuilder()
|
||||
|
@ -512,10 +533,10 @@ class QueryBuilder
|
|||
* ->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
|
||||
* @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)
|
||||
|
@ -526,19 +547,24 @@ class QueryBuilder
|
|||
}
|
||||
|
||||
/**
|
||||
* Add a LEFT JOIN
|
||||
* Creates and adds a left join over an entity association to the query.
|
||||
*
|
||||
* [php]
|
||||
* The entities in the joined association will be fetched as part of the query
|
||||
* result if the alias used for the joined association is placed in the select
|
||||
* expressions.
|
||||
*
|
||||
* <code>
|
||||
* $qb = $em->createQueryBuilder()
|
||||
* ->select('u')
|
||||
* ->from('User', 'u')
|
||||
* ->leftJoin('u.Phonenumbers', 'p', Expr\Join::WITH, 'p.is_primary = 1');
|
||||
* </code>
|
||||
*
|
||||
* @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 $qb
|
||||
* @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 leftJoin($join, $alias, $conditionType = null, $condition = null)
|
||||
{
|
||||
|
@ -548,17 +574,18 @@ class QueryBuilder
|
|||
}
|
||||
|
||||
/**
|
||||
* Add a SET statement for a DQL UPDATE query
|
||||
* Sets a new value for a field in a bulk update query.
|
||||
*
|
||||
* [php]
|
||||
* <code>
|
||||
* $qb = $em->createQueryBuilder()
|
||||
* ->update('User', 'u')
|
||||
* ->set('u.password', md5('password'))
|
||||
* ->where('u.id = ?');
|
||||
* </code>
|
||||
*
|
||||
* @param string $key The key/field to set
|
||||
* @param string $value The value, expression, placeholder, etc. to use in the SET
|
||||
* @return QueryBuilder $qb
|
||||
* @param string $key The key/field to set.
|
||||
* @param string $value The value, expression, placeholder, etc.
|
||||
* @return QueryBuilder This QueryBuilder instance.
|
||||
*/
|
||||
public function set($key, $value)
|
||||
{
|
||||
|
@ -566,9 +593,10 @@ class QueryBuilder
|
|||
}
|
||||
|
||||
/**
|
||||
* Set and override any existing WHERE statements
|
||||
* Specifies one or more restrictions to the query result.
|
||||
* Replaces any previously specified restrictions, if any.
|
||||
*
|
||||
* [php]
|
||||
* <code>
|
||||
* $qb = $em->createQueryBuilder()
|
||||
* ->select('u')
|
||||
* ->from('User', 'u')
|
||||
|
@ -584,9 +612,10 @@ class QueryBuilder
|
|||
* $qb->update('User', 'u')
|
||||
* ->set('u.password', md5('password'))
|
||||
* ->where($or);
|
||||
* </code>
|
||||
*
|
||||
* @param mixed $predicates The predicates.
|
||||
* @return QueryBuilder
|
||||
* @param mixed $predicates The restriction predicates.
|
||||
* @return QueryBuilder This QueryBuilder instance.
|
||||
*/
|
||||
public function where($predicates)
|
||||
{
|
||||
|
@ -598,17 +627,19 @@ class QueryBuilder
|
|||
}
|
||||
|
||||
/**
|
||||
* Add a new WHERE statement with an AND
|
||||
* Adds one or more restrictions to the query results, forming a logical
|
||||
* conjunction with any previously specified restrictions.
|
||||
*
|
||||
* [php]
|
||||
* <code>
|
||||
* $qb = $em->createQueryBuilder()
|
||||
* ->select('u')
|
||||
* ->from('User', 'u')
|
||||
* ->where('u.username LIKE ?')
|
||||
* ->andWhere('u.is_active = 1');
|
||||
* </code>
|
||||
*
|
||||
* @param mixed $where The WHERE statement
|
||||
* @return QueryBuilder $qb
|
||||
* @param mixed $where The query restrictions.
|
||||
* @return QueryBuilder This QueryBuilder instance.
|
||||
* @see where()
|
||||
*/
|
||||
public function andWhere($where)
|
||||
|
@ -627,14 +658,16 @@ class QueryBuilder
|
|||
}
|
||||
|
||||
/**
|
||||
* Add a new WHERE statement with an OR
|
||||
* Adds one or more restrictions to the query results, forming a logical
|
||||
* disjunction with any previously specified restrictions.
|
||||
*
|
||||
* [php]
|
||||
* <code>
|
||||
* $qb = $em->createQueryBuilder()
|
||||
* ->select('u')
|
||||
* ->from('User', 'u')
|
||||
* ->where('u.id = 1')
|
||||
* ->orWhere('u.id = 2');
|
||||
* </code>
|
||||
*
|
||||
* @param mixed $where The WHERE statement
|
||||
* @return QueryBuilder $qb
|
||||
|
@ -656,16 +689,18 @@ class QueryBuilder
|
|||
}
|
||||
|
||||
/**
|
||||
* Set the GROUP BY clause
|
||||
* Specifies a grouping over the results of the query.
|
||||
* Replaces any previously specified groupings, if any.
|
||||
*
|
||||
* [php]
|
||||
* <code>
|
||||
* $qb = $em->createQueryBuilder()
|
||||
* ->select('u')
|
||||
* ->from('User', 'u')
|
||||
* ->groupBy('u.id');
|
||||
* </code>
|
||||
*
|
||||
* @param string $groupBy The GROUP BY clause
|
||||
* @return QueryBuilder $qb
|
||||
* @param string $groupBy The grouping expression.
|
||||
* @return QueryBuilder This QueryBuilder instance.
|
||||
*/
|
||||
public function groupBy($groupBy)
|
||||
{
|
||||
|
@ -674,17 +709,18 @@ class QueryBuilder
|
|||
|
||||
|
||||
/**
|
||||
* Add to the existing GROUP BY clause
|
||||
* Adds a grouping expression to the query.
|
||||
*
|
||||
* [php]
|
||||
* <code>
|
||||
* $qb = $em->createQueryBuilder()
|
||||
* ->select('u')
|
||||
* ->from('User', 'u')
|
||||
* ->groupBy('u.last_login');
|
||||
* ->addGroupBy('u.created_at')
|
||||
* ->groupBy('u.lastLogin');
|
||||
* ->addGroupBy('u.createdAt')
|
||||
* </code>
|
||||
*
|
||||
* @param string $groupBy The GROUP BY clause
|
||||
* @return QueryBuilder $qb
|
||||
* @param string $groupBy The grouping expression.
|
||||
* @return QueryBuilder This QueryBuilder instance.
|
||||
*/
|
||||
public function addGroupBy($groupBy)
|
||||
{
|
||||
|
@ -692,10 +728,11 @@ class QueryBuilder
|
|||
}
|
||||
|
||||
/**
|
||||
* Set the HAVING clause
|
||||
* Specifies a restriction over the groups of the query.
|
||||
* Replaces any previous having restrictions, if any.
|
||||
*
|
||||
* @param mixed $having
|
||||
* @return QueryBuilder $qb
|
||||
* @param mixed $having The restriction over the groups.
|
||||
* @return QueryBuilder This QueryBuilder instance.
|
||||
*/
|
||||
public function having($having)
|
||||
{
|
||||
|
@ -707,10 +744,11 @@ class QueryBuilder
|
|||
}
|
||||
|
||||
/**
|
||||
* Add to the existing HAVING clause with an AND
|
||||
* Adds a restriction over the groups of the query, forming a logical
|
||||
* conjunction with any existing having restrictions.
|
||||
*
|
||||
* @param mixed $having
|
||||
* @return QueryBuilder $qb
|
||||
* @param mixed $having The restriction to append.
|
||||
* @return QueryBuilder This QueryBuilder instance.
|
||||
*/
|
||||
public function andHaving($having)
|
||||
{
|
||||
|
@ -728,10 +766,11 @@ class QueryBuilder
|
|||
}
|
||||
|
||||
/**
|
||||
* Add to the existing HAVING clause with an OR
|
||||
* Adds a restriction over the groups of the query, forming a logical
|
||||
* disjunction with any existing having restrictions.
|
||||
*
|
||||
* @param mixed $having
|
||||
* @return QueryBuilder $qb
|
||||
* @param mixed $having The restriction to add.
|
||||
* @return QueryBuilder This QueryBuilder instance.
|
||||
*/
|
||||
public function orHaving($having)
|
||||
{
|
||||
|
@ -749,11 +788,12 @@ class QueryBuilder
|
|||
}
|
||||
|
||||
/**
|
||||
* Set the ORDER BY clause
|
||||
* Specifies an ordering for the query results.
|
||||
* Replaces any previously specified orderings, if any.
|
||||
*
|
||||
* @param string $sort What to sort on
|
||||
* @param string $order Optional: The order to sort the results.
|
||||
* @return QueryBuilder $qb
|
||||
* @param string $sort The ordering expression.
|
||||
* @param string $order The ordering direction.
|
||||
* @return QueryBuilder This QueryBuilder instance.
|
||||
*/
|
||||
public function orderBy($sort, $order = null)
|
||||
{
|
||||
|
@ -762,11 +802,11 @@ class QueryBuilder
|
|||
}
|
||||
|
||||
/**
|
||||
* Add to the existing ORDER BY clause
|
||||
* Adds an ordering to the query results.
|
||||
*
|
||||
* @param string $sort What to sort on
|
||||
* @param string $order Optional: The order to sort the results.
|
||||
* @return QueryBuilder $qb
|
||||
* @param string $sort The ordering expression.
|
||||
* @param string $order The ordering direction.
|
||||
* @return QueryBuilder This QueryBuilder instance.
|
||||
*/
|
||||
public function addOrderBy($sort, $order = null)
|
||||
{
|
||||
|
@ -774,10 +814,11 @@ class QueryBuilder
|
|||
}
|
||||
|
||||
/**
|
||||
* Get a DQL part or parts by the part name
|
||||
* Get a query part by its name.
|
||||
*
|
||||
* @param string $queryPartName
|
||||
* @return mixed $queryPart
|
||||
* @todo Rename: getQueryPart (or remove?)
|
||||
*/
|
||||
public function getDQLPart($queryPartName)
|
||||
{
|
||||
|
@ -785,9 +826,10 @@ class QueryBuilder
|
|||
}
|
||||
|
||||
/**
|
||||
* Get the full DQL parts array
|
||||
* Get all query parts.
|
||||
*
|
||||
* @return array $dqlParts
|
||||
* @todo Rename: getQueryParts (or remove?)
|
||||
*/
|
||||
public function getDQLParts()
|
||||
{
|
||||
|
@ -836,6 +878,12 @@ class QueryBuilder
|
|||
. (isset($options['post']) ? $options['post'] : '');
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a string representation of this QueryBuilder which corresponds to
|
||||
* the final DQL query being constructed.
|
||||
*
|
||||
* @return string The string representation of this QueryBuilder.
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return $this->getDQL();
|
||||
|
|
|
@ -486,7 +486,7 @@ class UnitOfWork implements PropertyChangedListener
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Look for changes in associations of the entity
|
||||
foreach ($class->associationMappings as $assoc) {
|
||||
$val = $class->reflFields[$assoc->sourceFieldName]->getValue($entity);
|
||||
|
@ -2043,9 +2043,15 @@ class UnitOfWork implements PropertyChangedListener
|
|||
$oid = spl_object_hash($entity);
|
||||
$class = $this->_em->getClassMetadata(get_class($entity));
|
||||
|
||||
$isAssocField = isset($class->associationMappings[$propertyName]);
|
||||
|
||||
if ( ! $isAssocField && ! isset($class->fieldMappings[$propertyName])) {
|
||||
return; // ignore non-persistent fields
|
||||
}
|
||||
|
||||
$this->_entityChangeSets[$oid][$propertyName] = array($oldValue, $newValue);
|
||||
|
||||
if (isset($class->associationMappings[$propertyName])) {
|
||||
if ($isAssocField) {
|
||||
$assoc = $class->associationMappings[$propertyName];
|
||||
if ($assoc->isOneToOne() && $assoc->isOwningSide) {
|
||||
$this->_entityUpdates[$oid] = $entity;
|
||||
|
|
|
@ -6,7 +6,7 @@ use Doctrine\DBAL\Types\Type;
|
|||
use Doctrine\Tests\DBAL\Mocks;
|
||||
|
||||
require_once __DIR__ . '/../../TestInit.php';
|
||||
|
||||
|
||||
class IntegerTest extends \Doctrine\Tests\DbalTestCase
|
||||
{
|
||||
protected
|
||||
|
@ -19,10 +19,14 @@ class IntegerTest extends \Doctrine\Tests\DbalTestCase
|
|||
$this->_type = Type::getType('integer');
|
||||
}
|
||||
|
||||
public function testDecimalConvertsToPHPValue()
|
||||
public function testIntegerConvertsToPHPValue()
|
||||
{
|
||||
$this->assertTrue(
|
||||
is_integer($this->_type->convertToPHPValue('1', $this->_platform))
|
||||
);
|
||||
|
||||
$this->assertTrue(
|
||||
is_null($this->_type->convertToPHPValue(null, $this->_platform))
|
||||
);
|
||||
}
|
||||
}
|
|
@ -54,6 +54,7 @@ class AllTests
|
|||
$suite->addTestSuite('Doctrine\Tests\ORM\Functional\EntityRepositoryTest');
|
||||
$suite->addTestSuite('Doctrine\Tests\ORM\Functional\IdentityMapTest');
|
||||
$suite->addTestSuite('Doctrine\Tests\ORM\Functional\DatabaseDriverTest');
|
||||
$suite->addTestSuite('Doctrine\Tests\ORM\Functional\PostgreSQLIdentityStrategyTest');
|
||||
|
||||
$suite->addTest(Locking\AllTests::suite());
|
||||
$suite->addTest(SchemaTool\AllTests::suite());
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
<?php
|
||||
|
||||
namespace Doctrine\Tests\ORM\Functional;
|
||||
|
||||
use Doctrine\ORM\Event\PreUpdateEventArgs;
|
||||
|
||||
require_once __DIR__ . '/../../TestInit.php';
|
||||
|
||||
class PostgreSQLIdentityStrategyTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
{
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
if ($this->_em->getConnection()->getDatabasePlatform()->getName() != 'postgresql') {
|
||||
$this->markTestSkipped('This test is special to the PostgreSQL IDENTITY key generation strategy.');
|
||||
} else {
|
||||
try {
|
||||
$this->_schemaTool->createSchema(array(
|
||||
$this->_em->getClassMetadata('Doctrine\Tests\ORM\Functional\PostgreSQLIdentityEntity'),
|
||||
));
|
||||
} catch (\Exception $e) {
|
||||
// Swallow all exceptions. We do not test the schema tool here.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function tearDown() {
|
||||
parent::tearDown();
|
||||
// drop sequence manually due to dependency
|
||||
$this->_em->getConnection()->exec('DROP SEQUENCE postgresqlidentityentity_id_seq CASCADE');
|
||||
}
|
||||
|
||||
public function testPreSavePostSaveCallbacksAreInvoked()
|
||||
{
|
||||
$entity = new PostgreSQLIdentityEntity();
|
||||
$entity->setValue('hello');
|
||||
$this->_em->persist($entity);
|
||||
$this->_em->flush();
|
||||
$this->assertTrue(is_numeric($entity->getId()));
|
||||
$this->assertTrue($entity->getId() > 0);
|
||||
$this->assertTrue($this->_em->contains($entity));
|
||||
}
|
||||
}
|
||||
|
||||
/** @Entity */
|
||||
class PostgreSQLIdentityEntity {
|
||||
/** @Id @Column(type="integer") @GeneratedValue(strategy="IDENTITY") */
|
||||
private $id;
|
||||
/** @Column(type="string") */
|
||||
private $value;
|
||||
public function getId() {return $this->id;}
|
||||
public function getValue() {return $this->value;}
|
||||
public function setValue($value) {$this->value = $value;}
|
||||
}
|
|
@ -26,6 +26,7 @@ class ClassMetadataFactoryTest extends \Doctrine\Tests\OrmTestCase
|
|||
|
||||
// Self-made metadata
|
||||
$cm1 = new ClassMetadata('Doctrine\Tests\ORM\Mapping\TestEntity1');
|
||||
$cm1->setPrimaryTable(array('name' => '`group`'));
|
||||
// Add a mapped field
|
||||
$cm1->mapField(array('fieldName' => 'name', 'type' => 'varchar'));
|
||||
// Add a mapped field
|
||||
|
@ -54,6 +55,8 @@ class ClassMetadataFactoryTest extends \Doctrine\Tests\OrmTestCase
|
|||
// Go
|
||||
$cm1 = $cmf->getMetadataFor('Doctrine\Tests\ORM\Mapping\TestEntity1');
|
||||
|
||||
$this->assertEquals('group', $cm1->table['name']);
|
||||
$this->assertTrue($cm1->table['quoted']);
|
||||
$this->assertEquals(array(), $cm1->parentClasses);
|
||||
$this->assertTrue($cm1->hasField('name'));
|
||||
$this->assertEquals(ClassMetadata::GENERATOR_TYPE_SEQUENCE, $cm1->generatorType);
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
<?php
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
|
@ -32,10 +30,7 @@ require_once __DIR__ . '/../TestInit.php';
|
|||
*
|
||||
* @author Jonathan H. Wage <jonwage@gmail.com>
|
||||
* @author Roman Borschel <roman@code-factory.org
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link http://www.phpdoctrine.org
|
||||
* @since 2.0
|
||||
* @version $Revision$
|
||||
*/
|
||||
class QueryBuilderTest extends \Doctrine\Tests\OrmTestCase
|
||||
{
|
||||
|
@ -181,6 +176,20 @@ class QueryBuilderTest extends \Doctrine\Tests\OrmTestCase
|
|||
$this->assertValidQueryBuilder($qb, 'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE (u.id = :uid) OR (u.id = :uid2)');
|
||||
}
|
||||
|
||||
public function testComplexAndWhereOrWhereNesting()
|
||||
{
|
||||
$qb = $this->_em->createQueryBuilder();
|
||||
$qb->select('u')
|
||||
->from('Doctrine\Tests\Models\CMS\CmsUser', 'u')
|
||||
->where('u.id = :uid')
|
||||
->orWhere('u.id = :uid2')
|
||||
->andWhere('u.id = :uid3')
|
||||
->orWhere('u.name = :name1', 'u.name = :name2')
|
||||
->andWhere('u.name <> :noname');
|
||||
|
||||
$this->assertValidQueryBuilder($qb, 'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE ((((u.id = :uid) OR (u.id = :uid2)) AND (u.id = :uid3)) OR (u.name = :name1) OR (u.name = :name2)) AND (u.name <> :noname)');
|
||||
}
|
||||
|
||||
public function testAndWhereIn()
|
||||
{
|
||||
$qb = $this->_em->createQueryBuilder();
|
||||
|
|
|
@ -140,6 +140,7 @@ class UnitOfWorkTest extends \Doctrine\Tests\OrmTestCase
|
|||
$this->assertTrue($this->_unitOfWork->isInIdentityMap($entity));
|
||||
|
||||
$entity->setData('newdata');
|
||||
$entity->setTransient('newtransientvalue');
|
||||
|
||||
$this->assertTrue($this->_unitOfWork->isScheduledForUpdate($entity));
|
||||
|
||||
|
@ -206,10 +207,19 @@ class NotifyChangedEntity implements \Doctrine\Common\NotifyPropertyChanged
|
|||
*/
|
||||
private $data;
|
||||
|
||||
private $transient; // not persisted
|
||||
|
||||
public function getId() {
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function setTransient($value) {
|
||||
if ($value != $this->transient) {
|
||||
$this->_onPropertyChanged('transient', $this->transient, $value);
|
||||
$this->transient = $value;
|
||||
}
|
||||
}
|
||||
|
||||
public function getData() {
|
||||
return $this->data;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue