Commit d0325d70 authored by Guilherme Blanco's avatar Guilherme Blanco

Merged with upstream/master

parents 65fbb9f7 59d4e0c8
<?php <?php
/* /*
* $Id$
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
......
<?php <?php
/* /*
* $Id$
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
...@@ -21,17 +19,17 @@ ...@@ -21,17 +19,17 @@
namespace Doctrine\DBAL\Driver\PDOMsSql; namespace Doctrine\DBAL\Driver\PDOMsSql;
use PDO, Doctrine\DBAL\Driver\Connection as DriverConnection;
/** /**
* MsSql Connection implementation. * MsSql Connection implementation.
* *
* @since 2.0 * @since 2.0
*/ */
class Connection extends \Doctrine\DBAL\Driver\PDOConnection class Connection extends PDO implements DriverConnection
{ {
/** /**
* Performs the rollback. * {@inheritdoc}
*
* @override
*/ */
public function rollback() public function rollback()
{ {
...@@ -39,9 +37,7 @@ class Connection extends \Doctrine\DBAL\Driver\PDOConnection ...@@ -39,9 +37,7 @@ class Connection extends \Doctrine\DBAL\Driver\PDOConnection
} }
/** /**
* Performs the commit. * {@inheritdoc}
*
* @override
*/ */
public function commit() public function commit()
{ {
...@@ -49,12 +45,21 @@ class Connection extends \Doctrine\DBAL\Driver\PDOConnection ...@@ -49,12 +45,21 @@ class Connection extends \Doctrine\DBAL\Driver\PDOConnection
} }
/** /**
* Begins a database transaction. * {@inheritdoc}
*
* @override
*/ */
public function beginTransaction() public function beginTransaction()
{ {
$this->exec('BEGIN TRANSACTION'); $this->exec('BEGIN TRANSACTION');
} }
/**
* {@inheritdoc}
*/
public function lastInsertId($name = null)
{
$stmt = $this->query('SELECT SCOPE_IDENTITY()');
$id = $stmt->fetchColumn();
$stmt->closeCursor();
return $id;
}
} }
\ No newline at end of file
...@@ -25,7 +25,7 @@ use Doctrine\DBAL\Platforms\AbstractPlatform; ...@@ -25,7 +25,7 @@ use Doctrine\DBAL\Platforms\AbstractPlatform;
/** /**
* Type that maps an SQL INT to a PHP integer. * Type that maps an SQL INT to a PHP integer.
* *
* @author Roman Borschel <roman@code-factory.org> * @author Roman Borschel <roman@code-factory.org>
* @since 2.0 * @since 2.0
*/ */
...@@ -43,9 +43,9 @@ class IntegerType extends Type ...@@ -43,9 +43,9 @@ class IntegerType extends Type
public function convertToPHPValue($value, AbstractPlatform $platform) public function convertToPHPValue($value, AbstractPlatform $platform)
{ {
return (int) $value; return (null === $value) ? null : (int) $value;
} }
public function getBindingType() public function getBindingType()
{ {
return \PDO::PARAM_INT; return \PDO::PARAM_INT;
......
<?php <?php
/* /*
* $Id$
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
...@@ -30,10 +28,7 @@ use Doctrine\Common\EventManager, ...@@ -30,10 +28,7 @@ use Doctrine\Common\EventManager,
/** /**
* The EntityManager is the central access point to ORM functionality. * 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 * @since 2.0
* @version $Revision$
* @author Benjamin Eberlei <kontakt@beberlei.de> * @author Benjamin Eberlei <kontakt@beberlei.de>
* @author Guilherme Blanco <guilhermeblanco@hotmail.com> * @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @author Jonathan Wage <jonwage@gmail.com> * @author Jonathan Wage <jonwage@gmail.com>
......
...@@ -21,23 +21,36 @@ namespace Doctrine\ORM\Id; ...@@ -21,23 +21,36 @@ namespace Doctrine\ORM\Id;
use Doctrine\ORM\EntityManager; 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 class IdentityGenerator extends AbstractIdGenerator
{ {
/** @var string The name of the sequence to pass to lastInsertId(), if any. */
private $_seqName;
/**
* @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 __construct($seqName = null)
{
$this->_seqName = $seqName;
}
/** /**
* Generates an ID for the given entity. * {@inheritdoc}
*
* @param object $entity
* @return integer|float
* @override
*/ */
public function generate(EntityManager $em, $entity) public function generate(EntityManager $em, $entity)
{ {
return $em->getConnection()->lastInsertId(); return $em->getConnection()->lastInsertId($this->_seqName);
} }
/** /**
* @return boolean * {@inheritdoc}
* @override
*/ */
public function isPostInsertGenerator() public function isPostInsertGenerator()
{ {
......
<?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;
}
}
\ No newline at end of file
...@@ -19,8 +19,10 @@ ...@@ -19,8 +19,10 @@
namespace Doctrine\ORM\Mapping; namespace Doctrine\ORM\Mapping;
use Doctrine\ORM\ORMException, use ReflectionException,
Doctrine\DBAL\Platforms\AbstractPlatform, Doctrine\ORM\ORMException,
Doctrine\ORM\EntityManager,
Doctrine\DBAL\Platforms,
Doctrine\ORM\Events; Doctrine\ORM\Events;
/** /**
...@@ -53,7 +55,7 @@ class ClassMetadataFactory ...@@ -53,7 +55,7 @@ class ClassMetadataFactory
* *
* @param $driver The metadata driver to use. * @param $driver The metadata driver to use.
*/ */
public function __construct(\Doctrine\ORM\EntityManager $em) public function __construct(EntityManager $em)
{ {
$this->_em = $em; $this->_em = $em;
} }
...@@ -94,15 +96,15 @@ class ClassMetadataFactory ...@@ -94,15 +96,15 @@ class ClassMetadataFactory
if ( ! $this->_initialized) { if ( ! $this->_initialized) {
$this->_initialize(); $this->_initialize();
} }
$metadata = array(); $metadata = array();
foreach ($this->_driver->getAllClassNames() as $className) { foreach ($this->_driver->getAllClassNames() as $className) {
$metadata[] = $this->getMetadataFor($className); $metadata[] = $this->getMetadataFor($className);
} }
return $metadata; return $metadata;
} }
/** /**
* Lazy initialization of this stuff, especially the metadata driver, * Lazy initialization of this stuff, especially the metadata driver,
* since these are not needed at all when a metadata cache is active. * since these are not needed at all when a metadata cache is active.
...@@ -252,7 +254,7 @@ class ClassMetadataFactory ...@@ -252,7 +254,7 @@ class ClassMetadataFactory
// Invoke driver // Invoke driver
try { try {
$this->_driver->loadMetadataForClass($className, $class); $this->_driver->loadMetadataForClass($className, $class);
} catch(\ReflectionException $e) { } catch(ReflectionException $e) {
throw MappingException::reflectionFailure($className, $e); throw MappingException::reflectionFailure($className, $e);
} }
...@@ -275,9 +277,9 @@ class ClassMetadataFactory ...@@ -275,9 +277,9 @@ class ClassMetadataFactory
} else { } else {
$this->_completeIdGeneratorMapping($class); $this->_completeIdGeneratorMapping($class);
} }
if ($parent && $parent->isInheritanceTypeSingleTable()) { if ($parent && $parent->isInheritanceTypeSingleTable()) {
$class->setTableName($parent->getTableName()); $class->setPrimaryTable($parent->table);
} }
$class->setParentClasses($visited); $class->setParentClasses($visited);
...@@ -376,7 +378,13 @@ class ClassMetadataFactory ...@@ -376,7 +378,13 @@ class ClassMetadataFactory
// Create & assign an appropriate ID generator instance // Create & assign an appropriate ID generator instance
switch ($class->generatorType) { switch ($class->generatorType) {
case ClassMetadata::GENERATOR_TYPE_IDENTITY: 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; break;
case ClassMetadata::GENERATOR_TYPE_SEQUENCE: case ClassMetadata::GENERATOR_TYPE_SEQUENCE:
// If there is no sequence definition yet, create a default definition // If there is no sequence definition yet, create a default definition
......
...@@ -317,7 +317,7 @@ class ClassMetadataInfo ...@@ -317,7 +317,7 @@ class ClassMetadataInfo
* READ-ONLY: The ID generator used for generating IDs for this class. * READ-ONLY: The ID generator used for generating IDs for this class.
* *
* @var AbstractIdGenerator * @var AbstractIdGenerator
* @todo Remove * @todo Remove!
*/ */
public $idGenerator; public $idGenerator;
...@@ -335,6 +335,7 @@ class ClassMetadataInfo ...@@ -335,6 +335,7 @@ class ClassMetadataInfo
* </code> * </code>
* *
* @var array * @var array
* @todo Merge with tableGeneratorDefinition into generic generatorDefinition
*/ */
public $sequenceGeneratorDefinition; public $sequenceGeneratorDefinition;
...@@ -343,6 +344,7 @@ class ClassMetadataInfo ...@@ -343,6 +344,7 @@ class ClassMetadataInfo
* TABLE generation strategy. * TABLE generation strategy.
* *
* @var array * @var array
* @todo Merge with tableGeneratorDefinition into generic generatorDefinition
*/ */
public $tableGeneratorDefinition; public $tableGeneratorDefinition;
...@@ -395,7 +397,7 @@ class ClassMetadataInfo ...@@ -395,7 +397,7 @@ class ClassMetadataInfo
public function getReflectionClass() public function getReflectionClass()
{ {
if ( ! $this->reflClass) { if ( ! $this->reflClass) {
$this->reflClass = new ReflectionClass($entityName); $this->reflClass = new ReflectionClass($this->name);
} }
return $this->reflClass; return $this->reflClass;
} }
...@@ -901,8 +903,8 @@ class ClassMetadataInfo ...@@ -901,8 +903,8 @@ class ClassMetadataInfo
/** /**
* Sets the name of the primary table the class is mapped to. * Sets the name of the primary table the class is mapped to.
* *
* @param string $tableName The table name. * @param string $tableName The table name.
* @deprecated * @deprecated Use {@link setPrimaryTable}.
*/ */
public function setTableName($tableName) public function setTableName($tableName)
{ {
...@@ -910,18 +912,22 @@ class ClassMetadataInfo ...@@ -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: * following structure:
* *
* name => <tableName> * name => <tableName> (optional, defaults to class name)
* schema => <schemaName> * indexes => array of indexes (optional)
* catalog => <catalogName> * 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;
} }
/** /**
......
<?php <?php
/* /*
* $Id$
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
...@@ -31,14 +29,11 @@ require __DIR__ . '/DoctrineAnnotations.php'; ...@@ -31,14 +29,11 @@ require __DIR__ . '/DoctrineAnnotations.php';
/** /**
* The AnnotationDriver reads the mapping metadata from docblock annotations. * The AnnotationDriver reads the mapping metadata from docblock annotations.
* *
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL * @since 2.0
* @link www.doctrine-project.org * @author Benjamin Eberlei <kontakt@beberlei.de>
* @since 2.0 * @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @version $Revision$ * @author Jonathan H. Wage <jonwage@gmail.com>
* @author Benjamin Eberlei <kontakt@beberlei.de> * @author Roman Borschel <roman@code-factory.org>
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @author Jonathan H. Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
*/ */
class AnnotationDriver implements Driver class AnnotationDriver implements Driver
{ {
......
<?php <?php
/* /*
* $Id$
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
......
...@@ -62,13 +62,16 @@ class XmlDriver extends AbstractFileDriver ...@@ -62,13 +62,16 @@ class XmlDriver extends AbstractFileDriver
} }
// Evaluate <entity...> attributes // Evaluate <entity...> attributes
$table = array();
if (isset($xmlRoot['table'])) { 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'])) { if (isset($xmlRoot['schema'])) {
$metadata->table['schema'] = (string)$xmlRoot['schema']; $metadata->table['schema'] = (string)$xmlRoot['schema'];
} }*/
if (isset($xmlRoot['inheritance-type'])) { if (isset($xmlRoot['inheritance-type'])) {
$inheritanceType = (string)$xmlRoot['inheritance-type']; $inheritanceType = (string)$xmlRoot['inheritance-type'];
......
<?php <?php
/* /*
* $Id$
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
...@@ -27,14 +25,11 @@ use Doctrine\ORM\Mapping\ClassMetadataInfo, ...@@ -27,14 +25,11 @@ use Doctrine\ORM\Mapping\ClassMetadataInfo,
/** /**
* The YamlDriver reads the mapping metadata from yaml schema files. * The YamlDriver reads the mapping metadata from yaml schema files.
* *
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL * @since 2.0
* @link www.doctrine-project.org * @author Benjamin Eberlei <kontakt@beberlei.de>
* @since 2.0 * @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @version $Revision$ * @author Jonathan H. Wage <jonwage@gmail.com>
* @author Benjamin Eberlei <kontakt@beberlei.de> * @author Roman Borschel <roman@code-factory.org>
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @author Jonathan H. Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
*/ */
class YamlDriver extends AbstractFileDriver class YamlDriver extends AbstractFileDriver
{ {
...@@ -61,13 +56,16 @@ class YamlDriver extends AbstractFileDriver ...@@ -61,13 +56,16 @@ class YamlDriver extends AbstractFileDriver
} }
// Evaluate root level properties // Evaluate root level properties
$table = array();
if (isset($element['table'])) { 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'])) { if (isset($element['schema'])) {
$metadata->table['schema'] = $element['schema']; $metadata->table['schema'] = $element['schema'];
} }*/
if (isset($element['inheritanceType'])) { if (isset($element['inheritanceType'])) {
$metadata->setInheritanceType(constant('Doctrine\ORM\Mapping\ClassMetadata::INHERITANCE_TYPE_' . strtoupper($element['inheritanceType']))); $metadata->setInheritanceType(constant('Doctrine\ORM\Mapping\ClassMetadata::INHERITANCE_TYPE_' . strtoupper($element['inheritanceType'])));
......
...@@ -36,7 +36,7 @@ class ManyToManyPersister extends AbstractCollectionPersister ...@@ -36,7 +36,7 @@ class ManyToManyPersister extends AbstractCollectionPersister
* *
* @override * @override
*/ */
protected function _getDeleteRowSql(PersistentCollection $coll) protected function _getDeleteRowSQL(PersistentCollection $coll)
{ {
$mapping = $coll->getMapping(); $mapping = $coll->getMapping();
$joinTable = $mapping->joinTable; $joinTable = $mapping->joinTable;
...@@ -51,7 +51,7 @@ class ManyToManyPersister extends AbstractCollectionPersister ...@@ -51,7 +51,7 @@ class ManyToManyPersister extends AbstractCollectionPersister
* @internal Order of the parameters must be the same as the order of the columns in * @internal Order of the parameters must be the same as the order of the columns in
* _getDeleteRowSql. * _getDeleteRowSql.
*/ */
protected function _getDeleteRowSqlParameters(PersistentCollection $coll, $element) protected function _getDeleteRowSQLParameters(PersistentCollection $coll, $element)
{ {
return $this->_collectJoinTableColumnParameters($coll, $element); return $this->_collectJoinTableColumnParameters($coll, $element);
} }
...@@ -61,7 +61,7 @@ class ManyToManyPersister extends AbstractCollectionPersister ...@@ -61,7 +61,7 @@ class ManyToManyPersister extends AbstractCollectionPersister
* *
* @override * @override
*/ */
protected function _getUpdateRowSql(PersistentCollection $coll) protected function _getUpdateRowSQL(PersistentCollection $coll)
{} {}
/** /**
...@@ -71,7 +71,7 @@ class ManyToManyPersister extends AbstractCollectionPersister ...@@ -71,7 +71,7 @@ class ManyToManyPersister extends AbstractCollectionPersister
* @internal Order of the parameters must be the same as the order of the columns in * @internal Order of the parameters must be the same as the order of the columns in
* _getInsertRowSql. * _getInsertRowSql.
*/ */
protected function _getInsertRowSql(PersistentCollection $coll) protected function _getInsertRowSQL(PersistentCollection $coll)
{ {
$mapping = $coll->getMapping(); $mapping = $coll->getMapping();
$joinTable = $mapping->joinTable; $joinTable = $mapping->joinTable;
...@@ -87,11 +87,11 @@ class ManyToManyPersister extends AbstractCollectionPersister ...@@ -87,11 +87,11 @@ class ManyToManyPersister extends AbstractCollectionPersister
* @internal Order of the parameters must be the same as the order of the columns in * @internal Order of the parameters must be the same as the order of the columns in
* _getInsertRowSql. * _getInsertRowSql.
*/ */
protected function _getInsertRowSqlParameters(PersistentCollection $coll, $element) protected function _getInsertRowSQLParameters(PersistentCollection $coll, $element)
{ {
return $this->_collectJoinTableColumnParameters($coll, $element); return $this->_collectJoinTableColumnParameters($coll, $element);
} }
/** /**
* Collects the parameters for inserting/deleting on the join table in the order * Collects the parameters for inserting/deleting on the join table in the order
* of the join table columns as specified in ManyToManyMapping#joinTableColumns. * of the join table columns as specified in ManyToManyMapping#joinTableColumns.
...@@ -105,15 +105,15 @@ class ManyToManyPersister extends AbstractCollectionPersister ...@@ -105,15 +105,15 @@ class ManyToManyPersister extends AbstractCollectionPersister
$params = array(); $params = array();
$mapping = $coll->getMapping(); $mapping = $coll->getMapping();
$isComposite = count($mapping->joinTableColumns) > 2; $isComposite = count($mapping->joinTableColumns) > 2;
$identifier1 = $this->_uow->getEntityIdentifier($coll->getOwner()); $identifier1 = $this->_uow->getEntityIdentifier($coll->getOwner());
$identifier2 = $this->_uow->getEntityIdentifier($element); $identifier2 = $this->_uow->getEntityIdentifier($element);
if ($isComposite) { if ($isComposite) {
$class1 = $this->_em->getClassMetadata(get_class($coll->getOwner())); $class1 = $this->_em->getClassMetadata(get_class($coll->getOwner()));
$class2 = $coll->getTypeClass(); $class2 = $coll->getTypeClass();
} }
foreach ($mapping->joinTableColumns as $joinTableColumn) { foreach ($mapping->joinTableColumns as $joinTableColumn) {
if (isset($mapping->relationToSourceKeyColumns[$joinTableColumn])) { if (isset($mapping->relationToSourceKeyColumns[$joinTableColumn])) {
if ($isComposite) { if ($isComposite) {
...@@ -138,7 +138,7 @@ class ManyToManyPersister extends AbstractCollectionPersister ...@@ -138,7 +138,7 @@ class ManyToManyPersister extends AbstractCollectionPersister
* *
* @override * @override
*/ */
protected function _getDeleteSql(PersistentCollection $coll) protected function _getDeleteSQL(PersistentCollection $coll)
{ {
$mapping = $coll->getMapping(); $mapping = $coll->getMapping();
$joinTable = $mapping->joinTable; $joinTable = $mapping->joinTable;
...@@ -157,7 +157,7 @@ class ManyToManyPersister extends AbstractCollectionPersister ...@@ -157,7 +157,7 @@ class ManyToManyPersister extends AbstractCollectionPersister
* @internal Order of the parameters must be the same as the order of the columns in * @internal Order of the parameters must be the same as the order of the columns in
* _getDeleteSql. * _getDeleteSql.
*/ */
protected function _getDeleteSqlParameters(PersistentCollection $coll) protected function _getDeleteSQLParameters(PersistentCollection $coll)
{ {
$params = array(); $params = array();
$mapping = $coll->getMapping(); $mapping = $coll->getMapping();
...@@ -170,7 +170,7 @@ class ManyToManyPersister extends AbstractCollectionPersister ...@@ -170,7 +170,7 @@ class ManyToManyPersister extends AbstractCollectionPersister
} else { } else {
$params[] = array_pop($identifier); $params[] = array_pop($identifier);
} }
return $params; return $params;
} }
} }
\ No newline at end of file
...@@ -25,7 +25,7 @@ use Doctrine\ORM\PersistentCollection; ...@@ -25,7 +25,7 @@ use Doctrine\ORM\PersistentCollection;
/** /**
* Persister for one-to-many collections. * Persister for one-to-many collections.
* *
* IMPORTANT: * IMPORTANT:
* This persister is only used for uni-directional one-to-many mappings on a foreign key * 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. * (which are not yet supported). So currently this persister is not used.
...@@ -44,7 +44,7 @@ class OneToManyPersister extends AbstractCollectionPersister ...@@ -44,7 +44,7 @@ class OneToManyPersister extends AbstractCollectionPersister
* @return string * @return string
* @override * @override
*/ */
protected function _getDeleteRowSql(PersistentCollection $coll) protected function _getDeleteRowSQL(PersistentCollection $coll)
{ {
$mapping = $coll->getMapping(); $mapping = $coll->getMapping();
$targetClass = $this->_em->getClassMetadata($mapping->getTargetEntityName()); $targetClass = $this->_em->getClassMetadata($mapping->getTargetEntityName());
...@@ -67,36 +67,36 @@ class OneToManyPersister extends AbstractCollectionPersister ...@@ -67,36 +67,36 @@ class OneToManyPersister extends AbstractCollectionPersister
return array("UPDATE $table SET $setClause WHERE $whereClause", $this->_uow->getEntityIdentifier($element)); 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"; return "UPDATE xxx SET foreign_key = yyy WHERE foreign_key = zzz";
} }
/* Not used for OneToManyPersister */ /* Not used for OneToManyPersister */
protected function _getUpdateRowSql(PersistentCollection $coll) protected function _getUpdateRowSQL(PersistentCollection $coll)
{ {
return; return;
} }
/** /**
* Generates the SQL UPDATE that updates all the foreign keys to null. * Generates the SQL UPDATE that updates all the foreign keys to null.
* *
* @param PersistentCollection $coll * @param PersistentCollection $coll
*/ */
protected function _getDeleteSql(PersistentCollection $coll) protected function _getDeleteSQL(PersistentCollection $coll)
{ {
} }
/** /**
* Gets the SQL parameters for the corresponding SQL statement to delete * Gets the SQL parameters for the corresponding SQL statement to delete
* the given collection. * the given collection.
* *
* @param PersistentCollection $coll * @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 * Gets the SQL parameters for the corresponding SQL statement to insert the given
* element of the given collection into the database. * element of the given collection into the database.
...@@ -104,9 +104,9 @@ class OneToManyPersister extends AbstractCollectionPersister ...@@ -104,9 +104,9 @@ class OneToManyPersister extends AbstractCollectionPersister
* @param PersistentCollection $coll * @param PersistentCollection $coll
* @param mixed $element * @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 * Gets the SQL parameters for the corresponding SQL statement to delete the given
* element from the given collection. * element from the given collection.
...@@ -114,6 +114,6 @@ class OneToManyPersister extends AbstractCollectionPersister ...@@ -114,6 +114,6 @@ class OneToManyPersister extends AbstractCollectionPersister
* @param PersistentCollection $coll * @param PersistentCollection $coll
* @param mixed $element * @param mixed $element
*/ */
protected function _getDeleteRowSqlParameters(PersistentCollection $coll, $element) protected function _getDeleteRowSQLParameters(PersistentCollection $coll, $element)
{} {}
} }
\ No newline at end of file
This diff is collapsed.
...@@ -486,7 +486,7 @@ class UnitOfWork implements PropertyChangedListener ...@@ -486,7 +486,7 @@ class UnitOfWork implements PropertyChangedListener
} }
} }
} }
// Look for changes in associations of the entity // Look for changes in associations of the entity
foreach ($class->associationMappings as $assoc) { foreach ($class->associationMappings as $assoc) {
$val = $class->reflFields[$assoc->sourceFieldName]->getValue($entity); $val = $class->reflFields[$assoc->sourceFieldName]->getValue($entity);
...@@ -2043,9 +2043,15 @@ class UnitOfWork implements PropertyChangedListener ...@@ -2043,9 +2043,15 @@ class UnitOfWork implements PropertyChangedListener
$oid = spl_object_hash($entity); $oid = spl_object_hash($entity);
$class = $this->_em->getClassMetadata(get_class($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); $this->_entityChangeSets[$oid][$propertyName] = array($oldValue, $newValue);
if (isset($class->associationMappings[$propertyName])) { if ($isAssocField) {
$assoc = $class->associationMappings[$propertyName]; $assoc = $class->associationMappings[$propertyName];
if ($assoc->isOneToOne() && $assoc->isOwningSide) { if ($assoc->isOneToOne() && $assoc->isOwningSide) {
$this->_entityUpdates[$oid] = $entity; $this->_entityUpdates[$oid] = $entity;
......
...@@ -6,7 +6,7 @@ use Doctrine\DBAL\Types\Type; ...@@ -6,7 +6,7 @@ use Doctrine\DBAL\Types\Type;
use Doctrine\Tests\DBAL\Mocks; use Doctrine\Tests\DBAL\Mocks;
require_once __DIR__ . '/../../TestInit.php'; require_once __DIR__ . '/../../TestInit.php';
class IntegerTest extends \Doctrine\Tests\DbalTestCase class IntegerTest extends \Doctrine\Tests\DbalTestCase
{ {
protected protected
...@@ -19,10 +19,14 @@ class IntegerTest extends \Doctrine\Tests\DbalTestCase ...@@ -19,10 +19,14 @@ class IntegerTest extends \Doctrine\Tests\DbalTestCase
$this->_type = Type::getType('integer'); $this->_type = Type::getType('integer');
} }
public function testDecimalConvertsToPHPValue() public function testIntegerConvertsToPHPValue()
{ {
$this->assertTrue( $this->assertTrue(
is_integer($this->_type->convertToPHPValue('1', $this->_platform)) is_integer($this->_type->convertToPHPValue('1', $this->_platform))
); );
$this->assertTrue(
is_null($this->_type->convertToPHPValue(null, $this->_platform))
);
} }
} }
\ No newline at end of file
...@@ -54,6 +54,7 @@ class AllTests ...@@ -54,6 +54,7 @@ class AllTests
$suite->addTestSuite('Doctrine\Tests\ORM\Functional\EntityRepositoryTest'); $suite->addTestSuite('Doctrine\Tests\ORM\Functional\EntityRepositoryTest');
$suite->addTestSuite('Doctrine\Tests\ORM\Functional\IdentityMapTest'); $suite->addTestSuite('Doctrine\Tests\ORM\Functional\IdentityMapTest');
$suite->addTestSuite('Doctrine\Tests\ORM\Functional\DatabaseDriverTest'); $suite->addTestSuite('Doctrine\Tests\ORM\Functional\DatabaseDriverTest');
$suite->addTestSuite('Doctrine\Tests\ORM\Functional\PostgreSQLIdentityStrategyTest');
$suite->addTest(Locking\AllTests::suite()); $suite->addTest(Locking\AllTests::suite());
$suite->addTest(SchemaTool\AllTests::suite()); $suite->addTest(SchemaTool\AllTests::suite());
......
<?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 ...@@ -26,6 +26,7 @@ class ClassMetadataFactoryTest extends \Doctrine\Tests\OrmTestCase
// Self-made metadata // Self-made metadata
$cm1 = new ClassMetadata('Doctrine\Tests\ORM\Mapping\TestEntity1'); $cm1 = new ClassMetadata('Doctrine\Tests\ORM\Mapping\TestEntity1');
$cm1->setPrimaryTable(array('name' => '`group`'));
// Add a mapped field // Add a mapped field
$cm1->mapField(array('fieldName' => 'name', 'type' => 'varchar')); $cm1->mapField(array('fieldName' => 'name', 'type' => 'varchar'));
// Add a mapped field // Add a mapped field
...@@ -54,6 +55,8 @@ class ClassMetadataFactoryTest extends \Doctrine\Tests\OrmTestCase ...@@ -54,6 +55,8 @@ class ClassMetadataFactoryTest extends \Doctrine\Tests\OrmTestCase
// Go // Go
$cm1 = $cmf->getMetadataFor('Doctrine\Tests\ORM\Mapping\TestEntity1'); $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->assertEquals(array(), $cm1->parentClasses);
$this->assertTrue($cm1->hasField('name')); $this->assertTrue($cm1->hasField('name'));
$this->assertEquals(ClassMetadata::GENERATOR_TYPE_SEQUENCE, $cm1->generatorType); $this->assertEquals(ClassMetadata::GENERATOR_TYPE_SEQUENCE, $cm1->generatorType);
......
<?php <?php
/* /*
* $Id$
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
...@@ -32,10 +30,7 @@ require_once __DIR__ . '/../TestInit.php'; ...@@ -32,10 +30,7 @@ require_once __DIR__ . '/../TestInit.php';
* *
* @author Jonathan H. Wage <jonwage@gmail.com> * @author Jonathan H. Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org * @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 * @since 2.0
* @version $Revision$
*/ */
class QueryBuilderTest extends \Doctrine\Tests\OrmTestCase class QueryBuilderTest extends \Doctrine\Tests\OrmTestCase
{ {
...@@ -181,6 +176,20 @@ 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)'); $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() public function testAndWhereIn()
{ {
$qb = $this->_em->createQueryBuilder(); $qb = $this->_em->createQueryBuilder();
......
...@@ -140,6 +140,7 @@ class UnitOfWorkTest extends \Doctrine\Tests\OrmTestCase ...@@ -140,6 +140,7 @@ class UnitOfWorkTest extends \Doctrine\Tests\OrmTestCase
$this->assertTrue($this->_unitOfWork->isInIdentityMap($entity)); $this->assertTrue($this->_unitOfWork->isInIdentityMap($entity));
$entity->setData('newdata'); $entity->setData('newdata');
$entity->setTransient('newtransientvalue');
$this->assertTrue($this->_unitOfWork->isScheduledForUpdate($entity)); $this->assertTrue($this->_unitOfWork->isScheduledForUpdate($entity));
...@@ -206,10 +207,19 @@ class NotifyChangedEntity implements \Doctrine\Common\NotifyPropertyChanged ...@@ -206,10 +207,19 @@ class NotifyChangedEntity implements \Doctrine\Common\NotifyPropertyChanged
*/ */
private $data; private $data;
private $transient; // not persisted
public function getId() { public function getId() {
return $this->id; return $this->id;
} }
public function setTransient($value) {
if ($value != $this->transient) {
$this->_onPropertyChanged('transient', $this->transient, $value);
$this->transient = $value;
}
}
public function getData() { public function getData() {
return $this->data; return $this->data;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment