[2.0] Work on ID generators, functional tests and more.
This commit is contained in:
parent
2812318254
commit
f9a222817c
@ -25,13 +25,16 @@ class DoctrineException extends \Exception
|
||||
|
||||
public static function __callStatic($method, $arguments)
|
||||
{
|
||||
$class = get_called_class();
|
||||
$messageKey = substr($class, strrpos($class, '\\') + 1) . "#$method";
|
||||
|
||||
$end = end($arguments);
|
||||
if ($end instanceof Exception) {
|
||||
$this->_innerException = $end;
|
||||
unset($arguments[count($arguments) - 1]);
|
||||
}
|
||||
|
||||
if ($message = self::getExceptionMessage($method)) {
|
||||
if ($message = self::getExceptionMessage($messageKey)) {
|
||||
$message = sprintf($message, $arguments);
|
||||
} else {
|
||||
$message = strtolower(preg_replace('~(?<=\\w)([A-Z])~', '_$1', $method));
|
||||
@ -42,22 +45,25 @@ class DoctrineException extends \Exception
|
||||
}
|
||||
$message .= ' (' . implode(', ', $args) . ')';
|
||||
}
|
||||
$class = get_called_class();
|
||||
|
||||
return new $class($message);
|
||||
}
|
||||
|
||||
public static function getExceptionMessage($method)
|
||||
public static function getExceptionMessage($messageKey)
|
||||
{
|
||||
if ( ! self::$_messages) {
|
||||
// Lazy-init messages
|
||||
self::$_messages = array(
|
||||
'partialObjectsAreDangerous' =>
|
||||
'DoctrineException#partialObjectsAreDangerous' =>
|
||||
"Loading partial objects is dangerous. Fetch full objects or consider " .
|
||||
"using a different fetch mode. If you really want partial objects, " .
|
||||
"set the doctrine.forcePartialLoad query hint to TRUE."
|
||||
"set the doctrine.forcePartialLoad query hint to TRUE.",
|
||||
'QueryException#nonUniqueResult' =>
|
||||
"The query contains more than one result."
|
||||
);
|
||||
}
|
||||
if (isset(self::$_messages[$method])) {
|
||||
return self::$_messages[$method];
|
||||
if (isset(self::$_messages[$messageKey])) {
|
||||
return self::$_messages[$messageKey];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -515,7 +515,7 @@ class Connection
|
||||
{
|
||||
$this->connect();
|
||||
try {
|
||||
echo $query . PHP_EOL;
|
||||
echo "DBAL:" . $query . PHP_EOL;
|
||||
if ( ! empty($params)) {
|
||||
$stmt = $this->prepare($query);
|
||||
$stmt->execute($params);
|
||||
@ -756,6 +756,7 @@ class Connection
|
||||
*/
|
||||
public function getWrappedConnection()
|
||||
{
|
||||
$this->connect();
|
||||
return $this->_conn;
|
||||
}
|
||||
|
||||
|
@ -28,7 +28,18 @@ class Driver implements \Doctrine\DBAL\Driver
|
||||
*/
|
||||
private function _constructPdoDsn(array $params)
|
||||
{
|
||||
//TODO
|
||||
$dsn = 'pgsql:';
|
||||
if (isset($params['host'])) {
|
||||
$dsn .= 'host=' . $params['host'] . ' ';
|
||||
}
|
||||
if (isset($params['port'])) {
|
||||
$dsn .= 'port=' . $params['port'] . ' ';
|
||||
}
|
||||
if (isset($params['dbname'])) {
|
||||
$dsn .= 'dbname=' . $params['dbname'] . ' ';
|
||||
}
|
||||
|
||||
return $dsn;
|
||||
}
|
||||
|
||||
public function getDatabasePlatform()
|
||||
|
@ -108,13 +108,6 @@ class EntityManager
|
||||
*/
|
||||
private $_eventManager;
|
||||
|
||||
/**
|
||||
* The maintained (cached) Id generators.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $_idGenerators = array();
|
||||
|
||||
/**
|
||||
* The maintained (cached) hydrators. One instance per type.
|
||||
*
|
||||
@ -202,38 +195,6 @@ class EntityManager
|
||||
{
|
||||
return $this->_metadataFactory->getMetadataFor($className);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an IdGenerator that can be used to generate identifiers for the specified
|
||||
* class.
|
||||
*/
|
||||
public function getIdGenerator($className)
|
||||
{
|
||||
if (!isset($this->_idGenerators[$className])) {
|
||||
$this->_idGenerators[$className] = $this->_createIdGenerator(
|
||||
$this->getClassMetadata($className)->getIdGeneratorType());
|
||||
}
|
||||
return $this->_idGenerators[$className];
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to lazily create an ID generator.
|
||||
*
|
||||
* @param string $generatorType
|
||||
* @return object
|
||||
*/
|
||||
protected function _createIdGenerator($generatorType)
|
||||
{
|
||||
if ($generatorType == ClassMetadata::GENERATOR_TYPE_IDENTITY) {
|
||||
return new \Doctrine\ORM\Id\IdentityGenerator($this);
|
||||
} else if ($generatorType == ClassMetadata::GENERATOR_TYPE_SEQUENCE) {
|
||||
return new \Doctrine\ORM\Id\SequenceGenerator($this);
|
||||
} else if ($generatorType == ClassMetadata::GENERATOR_TYPE_TABLE) {
|
||||
return new \Doctrine\ORM\Id\TableGenerator($this);
|
||||
} else {
|
||||
return new \Doctrine\ORM\Id\Assigned($this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new Query object.
|
||||
@ -265,7 +226,7 @@ class EntityManager
|
||||
* Creates a query with the specified name.
|
||||
*
|
||||
* @todo Implementation.
|
||||
* @throws SomeException If there is no query registered with the given name.
|
||||
* @throws DoctrineException If there is no query registered with the given name.
|
||||
*/
|
||||
public function createNamedQuery($name)
|
||||
{
|
||||
|
@ -1,182 +0,0 @@
|
||||
<?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
|
||||
* 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\Export;
|
||||
|
||||
use Doctrine\ORM\EntityManager;
|
||||
|
||||
/**
|
||||
* The ClassExporter can generate database schemas/structures from ClassMetadata
|
||||
* class descriptors.
|
||||
*
|
||||
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
|
||||
* @author Lukas Smith <smith@pooteeweet.org> (PEAR MDB2 library)
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.doctrine-project.org
|
||||
* @since 2.0
|
||||
* @version $Revision: 4805 $
|
||||
*/
|
||||
class ClassExporter
|
||||
{
|
||||
/** The SchemaManager */
|
||||
private $_sm;
|
||||
/** The EntityManager */
|
||||
private $_em;
|
||||
/** The DatabasePlatform */
|
||||
private $_platform;
|
||||
|
||||
/**
|
||||
* Initializes a new ClassExporter instance that uses the connection of the
|
||||
* provided EntityManager.
|
||||
*
|
||||
* @param Doctrine\ORM\EntityManager $em
|
||||
*/
|
||||
public function __construct(EntityManager $em)
|
||||
{
|
||||
$this->_em = $em;
|
||||
$this->_sm = $em->getConnection()->getSchemaManager();
|
||||
$this->_platform = $em->getConnection()->getDatabasePlatform();
|
||||
}
|
||||
|
||||
/**
|
||||
* Exports an array of class meta data instances to your database
|
||||
*
|
||||
* @param array $classes
|
||||
*/
|
||||
public function exportClasses(array $classes)
|
||||
{
|
||||
$exportClassesSql = $this->getExportClassesSql($classes);
|
||||
foreach ($exportClassesSql as $sql) {
|
||||
$this->_em->getConnection()->execute($sql);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an array of sql statements for the specified array of class meta data instances
|
||||
*
|
||||
* @param array $classes
|
||||
* @return array $sql
|
||||
*/
|
||||
public function getExportClassesSql(array $classes)
|
||||
{
|
||||
$sql = array();
|
||||
$foreignKeyConstraints = array();
|
||||
|
||||
// First we create the tables
|
||||
foreach ($classes as $class) {
|
||||
$columns = array();
|
||||
$options = array();
|
||||
|
||||
foreach ($class->getFieldMappings() as $fieldName => $mapping) {
|
||||
$column = array();
|
||||
$column['name'] = $mapping['columnName'];
|
||||
$column['type'] = $mapping['type'];
|
||||
$column['length'] = $mapping['length'];
|
||||
$column['notnull'] = ! $mapping['nullable'];
|
||||
if ($class->isIdentifier($fieldName)) {
|
||||
$column['primary'] = true;
|
||||
$options['primary'][] = $mapping['columnName'];
|
||||
if ($class->isIdGeneratorIdentity()) {
|
||||
$column['autoincrement'] = true;
|
||||
}
|
||||
}
|
||||
$columns[$mapping['columnName']] = $column;
|
||||
}
|
||||
|
||||
foreach ($class->getAssociationMappings() as $mapping) {
|
||||
$foreignClass = $this->_em->getClassMetadata($mapping->getTargetEntityName());
|
||||
if ($mapping->isOneToOne() && $mapping->isOwningSide()) {
|
||||
$constraint = array();
|
||||
$constraint['tableName'] = $class->getTableName();
|
||||
$constraint['foreignTable'] = $foreignClass->getTableName();
|
||||
$constraint['local'] = array();
|
||||
$constraint['foreign'] = array();
|
||||
foreach ($mapping->getJoinColumns() as $joinColumn) {
|
||||
$column = array();
|
||||
$column['name'] = $joinColumn['name'];
|
||||
$column['type'] = $foreignClass->getTypeOfColumn($joinColumn['referencedColumnName']);
|
||||
$columns[$joinColumn['name']] = $column;
|
||||
$constraint['local'][] = $joinColumn['name'];
|
||||
$constraint['foreign'][] = $joinColumn['referencedColumnName'];
|
||||
}
|
||||
$foreignKeyConstraints[] = $constraint;
|
||||
} else if ($mapping->isOneToMany() && $mapping->isOwningSide()) {
|
||||
//... create join table, one-many through join table supported later
|
||||
\Doctrine\Common\DoctrineException::updateMe("Not yet implemented.");
|
||||
} else if ($mapping->isManyToMany() && $mapping->isOwningSide()) {
|
||||
//... create join table
|
||||
$joinTableColumns = array();
|
||||
$joinTableOptions = array();
|
||||
$joinTable = $mapping->getJoinTable();
|
||||
$constraint1 = array();
|
||||
$constraint1['tableName'] = $joinTable['name'];
|
||||
$constraint1['foreignTable'] = $class->getTableName();
|
||||
$constraint1['local'] = array();
|
||||
$constraint1['foreign'] = array();
|
||||
foreach ($joinTable['joinColumns'] as $joinColumn) {
|
||||
$column = array();
|
||||
$column['primary'] = true;
|
||||
$joinTableOptions['primary'][] = $joinColumn['name'];
|
||||
$column['name'] = $joinColumn['name'];
|
||||
$column['type'] = $class->getTypeOfColumn($joinColumn['referencedColumnName']);
|
||||
$joinTableColumns[$joinColumn['name']] = $column;
|
||||
$constraint1['local'][] = $joinColumn['name'];
|
||||
$constraint1['foreign'][] = $joinColumn['referencedColumnName'];
|
||||
}
|
||||
$foreignKeyConstraints[] = $constraint1;
|
||||
|
||||
$constraint2 = array();
|
||||
$constraint2['tableName'] = $joinTable['name'];
|
||||
$constraint2['foreignTable'] = $foreignClass->getTableName();
|
||||
$constraint2['local'] = array();
|
||||
$constraint2['foreign'] = array();
|
||||
foreach ($joinTable['inverseJoinColumns'] as $inverseJoinColumn) {
|
||||
$column = array();
|
||||
$column['primary'] = true;
|
||||
$joinTableOptions['primary'][] = $inverseJoinColumn['name'];
|
||||
$column['name'] = $inverseJoinColumn['name'];
|
||||
$column['type'] = $this->_em->getClassMetadata($mapping->getTargetEntityName())
|
||||
->getTypeOfColumn($inverseJoinColumn['referencedColumnName']);
|
||||
$joinTableColumns[$inverseJoinColumn['name']] = $column;
|
||||
$constraint2['local'][] = $inverseJoinColumn['name'];
|
||||
$constraint2['foreign'][] = $inverseJoinColumn['referencedColumnName'];
|
||||
}
|
||||
$foreignKeyConstraints[] = $constraint2;
|
||||
|
||||
$sql = array_merge($sql, $this->_platform->getCreateTableSql(
|
||||
$joinTable['name'], $joinTableColumns, $joinTableOptions));
|
||||
}
|
||||
}
|
||||
|
||||
$sql = array_merge($sql, $this->_platform->getCreateTableSql($class->getTableName(), $columns, $options));
|
||||
}
|
||||
|
||||
// Now create the foreign key constraints
|
||||
if ($this->_platform->supportsForeignKeyConstraints()) {
|
||||
foreach ($foreignKeyConstraints as $fkConstraint) {
|
||||
$sql = array_merge($sql, (array)$this->_platform->getCreateForeignKeySql($fkConstraint['tableName'], $fkConstraint));
|
||||
}
|
||||
}
|
||||
|
||||
return $sql;
|
||||
}
|
||||
}
|
@ -8,21 +8,14 @@ use Doctrine\ORM\EntityManager;
|
||||
* Enter description here...
|
||||
*/
|
||||
abstract class AbstractIdGenerator
|
||||
{
|
||||
protected $_em;
|
||||
|
||||
public function __construct(EntityManager $em)
|
||||
{
|
||||
$this->_em = $em;
|
||||
}
|
||||
|
||||
{
|
||||
/**
|
||||
* Generates an identifier for an entity.
|
||||
*
|
||||
* @param Doctrine\ORM\Entity $entity
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function generate($entity);
|
||||
abstract public function generate(EntityManager $em, $entity);
|
||||
|
||||
/**
|
||||
* Gets whether this generator is a post-insert generator which means that
|
||||
|
@ -21,6 +21,7 @@
|
||||
|
||||
namespace Doctrine\ORM\Id;
|
||||
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use Doctrine\Common\DoctrineException;
|
||||
|
||||
/**
|
||||
@ -38,9 +39,9 @@ class Assigned extends AbstractIdGenerator
|
||||
* @return mixed
|
||||
* @override
|
||||
*/
|
||||
public function generate($entity)
|
||||
public function generate(EntityManager $em, $entity)
|
||||
{
|
||||
$class = $this->_em->getClassMetadata(get_class($entity));
|
||||
$class = $em->getClassMetadata(get_class($entity));
|
||||
$identifier = null;
|
||||
if ($class->isIdentifierComposite()) {
|
||||
$identifier = array();
|
||||
@ -61,7 +62,7 @@ class Assigned extends AbstractIdGenerator
|
||||
}
|
||||
|
||||
if ( ! $identifier) {
|
||||
\Doctrine\Common\DoctrineException::updateMe("Entity of type '" . get_class($entity) . "' is missing an assigned ID.");
|
||||
throw DoctrineException::updateMe("Entity of type '" . get_class($entity) . "' is missing an assigned ID.");
|
||||
}
|
||||
|
||||
return $identifier;
|
||||
|
@ -2,18 +2,20 @@
|
||||
|
||||
namespace Doctrine\ORM\Id;
|
||||
|
||||
use Doctrine\ORM\EntityManager;
|
||||
|
||||
class IdentityGenerator extends AbstractIdGenerator
|
||||
{
|
||||
/**
|
||||
* Enter description here...
|
||||
* Generates an ID for the given entity.
|
||||
*
|
||||
* @param Doctrine_ORM_Entity $entity
|
||||
* @return unknown
|
||||
* @param object $entity
|
||||
* @return integer|float
|
||||
* @override
|
||||
*/
|
||||
public function generate($entity)
|
||||
public function generate(EntityManager $em, $entity)
|
||||
{
|
||||
return $this->_em->getConnection()->lastInsertId();
|
||||
return $em->getConnection()->lastInsertId();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,19 +1,50 @@
|
||||
<?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
|
||||
* 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 SequenceGenerator extends AbstractIdGenerator
|
||||
/**
|
||||
* Represents an ID generator that uses a database sequence.
|
||||
*
|
||||
* @since 2.0
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
*/
|
||||
class SequenceGenerator extends AbstractIdGenerator implements \Serializable
|
||||
{
|
||||
private $_allocationSize;
|
||||
private $_sequenceName;
|
||||
private $_nextValue = 0;
|
||||
private $_maxValue = null;
|
||||
|
||||
public function __construct(EntityManager $em, $sequenceName, $allocationSize = 20)
|
||||
|
||||
/**
|
||||
* Initializes a new sequence generator.
|
||||
*
|
||||
* @param Doctrine\ORM\EntityManager $em The EntityManager to use.
|
||||
* @param string $sequenceName The name of the sequence.
|
||||
* @param integer $allocationSize The allocation size of the sequence.
|
||||
*/
|
||||
public function __construct($sequenceName, $allocationSize)
|
||||
{
|
||||
parent::__construct($em);
|
||||
$this->_sequenceName = $sequenceName;
|
||||
$this->_allocationSize = $allocationSize;
|
||||
}
|
||||
@ -25,11 +56,11 @@ class SequenceGenerator extends AbstractIdGenerator
|
||||
* @return integer|float The generated value.
|
||||
* @override
|
||||
*/
|
||||
public function generate($entity)
|
||||
public function generate(EntityManager $em, $entity)
|
||||
{
|
||||
if ($this->_maxValue === null || $this->_nextValue == $this->_maxValue) {
|
||||
// Allocate new values
|
||||
$conn = $this->_em->getConnection();
|
||||
$conn = $em->getConnection();
|
||||
$sql = $conn->getDatabasePlatform()->getSequenceNextValSql($this->_sequenceName);
|
||||
$this->_maxValue = $conn->fetchOne($sql);
|
||||
$this->_nextValue = $this->_maxValue - $this->_allocationSize;
|
||||
@ -37,13 +68,38 @@ class SequenceGenerator extends AbstractIdGenerator
|
||||
return $this->_nextValue++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the maximum value of the currently allocated bag of values.
|
||||
*
|
||||
* @return integer|float
|
||||
*/
|
||||
public function getCurrentMaxValue()
|
||||
{
|
||||
return $this->_maxValue;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the next value that will be returned by generate().
|
||||
*
|
||||
* @return integer|float
|
||||
*/
|
||||
public function getNextValue()
|
||||
{
|
||||
return $this->_nextValue;
|
||||
}
|
||||
|
||||
public function serialize()
|
||||
{
|
||||
return serialize(array(
|
||||
'allocationSize' => $this->_allocationSize,
|
||||
'sequenceName' => $this->_sequenceName
|
||||
));
|
||||
}
|
||||
|
||||
public function unserialize($serialized)
|
||||
{
|
||||
$array = unserialize($serialized);
|
||||
$this->_sequenceName = $array['sequenceName'];
|
||||
$this->_allocationSize = $array['allocationSize'];
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,8 @@
|
||||
|
||||
namespace Doctrine\ORM\Id;
|
||||
|
||||
use Doctrine\ORM\EntityManager;
|
||||
|
||||
class SequenceIdentityGenerator extends IdentityGenerator
|
||||
{
|
||||
private $_sequenceName;
|
||||
@ -10,15 +12,18 @@ class SequenceIdentityGenerator extends IdentityGenerator
|
||||
{
|
||||
$this->_sequenceName = $sequenceName;
|
||||
}
|
||||
|
||||
public function generate(EntityManager $em, $entity)
|
||||
{
|
||||
return $em->getConnection()->lastInsertId($this->_sequenceName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enter description here...
|
||||
*
|
||||
* @param Doctrine_Connection $conn
|
||||
* @return boolean
|
||||
* @override
|
||||
*/
|
||||
public function getPostInsertId()
|
||||
public function isPostInsertGenerator()
|
||||
{
|
||||
return $this->_em->getConnection()->lastInsertId($this->_sequenceName);
|
||||
return true;
|
||||
}
|
||||
}
|
@ -2,6 +2,8 @@
|
||||
|
||||
namespace Doctrine\ORM\Id;
|
||||
|
||||
use Doctrine\ORM\EntityManager;
|
||||
|
||||
/**
|
||||
* Id generator that uses a single-row database table and a hi/lo algorithm.
|
||||
*
|
||||
@ -9,7 +11,7 @@ namespace Doctrine\ORM\Id;
|
||||
*/
|
||||
class TableGenerator extends AbstractIdGenerator
|
||||
{
|
||||
public function generate($entity)
|
||||
public function generate(EntityManager $em, $entity)
|
||||
{
|
||||
throw \Doctrine\Common\DoctrineException::updateMe("Not implemented");
|
||||
}
|
||||
|
@ -333,6 +333,36 @@ final class ClassMetadata
|
||||
private $_reflectionProperties;
|
||||
|
||||
//private $_insertSql;
|
||||
/**
|
||||
* The name of the ID generator used for this class. Only used for SEQUENCE
|
||||
* and TABLE generation strategies.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
//private $_idGeneratorName;
|
||||
|
||||
/**
|
||||
* The ID generator used for generating IDs for this class.
|
||||
*
|
||||
* @var AbstractIdGenerator
|
||||
*/
|
||||
private $_idGenerator;
|
||||
|
||||
/**
|
||||
* The definition of the sequence generator of this class. Only used for the
|
||||
* SEQUENCE generation strategy.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $_sequenceGeneratorDefinition;
|
||||
|
||||
/**
|
||||
* The definition of the table generator of this class. Only used for the
|
||||
* TABLE generation strategy.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
//private $_tableGeneratorDefinition;
|
||||
|
||||
/**
|
||||
* Initializes a new ClassMetadata instance that will hold the object-relational mapping
|
||||
@ -389,7 +419,7 @@ final class ClassMetadata
|
||||
public function getSingleIdReflectionProperty()
|
||||
{
|
||||
if ($this->_isIdentifierComposite) {
|
||||
\Doctrine\Common\DoctrineException::updateMe("getSingleIdReflectionProperty called on entity with composite key.");
|
||||
throw DoctrineException::updateMe("getSingleIdReflectionProperty called on entity with composite key.");
|
||||
}
|
||||
return $this->_reflectionProperties[$this->_identifier[0]];
|
||||
}
|
||||
@ -635,17 +665,6 @@ final class ClassMetadata
|
||||
if ( ! in_array($mapping['fieldName'], $this->_identifier)) {
|
||||
$this->_identifier[] = $mapping['fieldName'];
|
||||
}
|
||||
if (isset($mapping['idGenerator'])) {
|
||||
if ( ! $this->_isIdGeneratorType($mapping['idGenerator'])) {
|
||||
//TODO: check if the idGenerator specifies an existing generator by name
|
||||
throw MappingException::invalidGeneratorType($mapping['idGenerator']);
|
||||
} else if (count($this->_identifier) > 1) {
|
||||
throw MappingException::generatorNotAllowedWithCompositeId();
|
||||
}
|
||||
$this->_generatorType = $mapping['idGenerator'];
|
||||
}
|
||||
// TODO: validate/complete 'tableGenerator' and 'sequenceGenerator' mappings
|
||||
|
||||
// Check for composite key
|
||||
if ( ! $this->_isIdentifierComposite && count($this->_identifier) > 1) {
|
||||
$this->_isIdentifierComposite = true;
|
||||
@ -719,12 +738,23 @@ final class ClassMetadata
|
||||
public function getSingleIdentifierFieldName()
|
||||
{
|
||||
if ($this->_isIdentifierComposite) {
|
||||
throw \Doctrine\Common\DoctrineException::updateMe("Calling getSingleIdentifierFieldName "
|
||||
throw DoctrineException::updateMe("Calling getSingleIdentifierFieldName "
|
||||
. "on a class that uses a composite identifier is not allowed.");
|
||||
}
|
||||
return $this->_identifier[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the column name of the single id column. Note that this only works on
|
||||
* entity classes that have a single-field pk.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getSingleIdentifierColumnName()
|
||||
{
|
||||
return $this->getColumnName($this->getSingleIdentifierFieldName());
|
||||
}
|
||||
|
||||
public function setIdentifier(array $identifier)
|
||||
{
|
||||
$this->_identifier = $identifier;
|
||||
@ -1067,7 +1097,7 @@ final class ClassMetadata
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the primary table definition. The provided array must have th
|
||||
* Sets the primary table definition. The provided array must have the
|
||||
* following structure:
|
||||
*
|
||||
* name => <tableName>
|
||||
@ -1471,7 +1501,82 @@ final class ClassMetadata
|
||||
! $this->_associationMappings[$fieldName]->isOneToOne();
|
||||
}
|
||||
|
||||
/** Creates a string representation of the instance. */
|
||||
/**
|
||||
* Gets the name of the ID generator used for this class.
|
||||
* Only classes that use a SEQUENCE or TABLE ID generation strategy have a generator name.
|
||||
*
|
||||
* @return string|null The name of the ID generator or NULL if this class does not
|
||||
* use a named ID generator.
|
||||
*/
|
||||
/*public function getIdGeneratorName()
|
||||
{
|
||||
return $this->_idGeneratorName;
|
||||
}*/
|
||||
|
||||
/**
|
||||
* Sets the ID generator used to generate IDs for instances of this class.
|
||||
*
|
||||
* @param AbstractIdGenerator $generator
|
||||
*/
|
||||
public function setIdGenerator($generator)
|
||||
{
|
||||
$this->_idGenerator = $generator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the ID generator used to generate IDs for instances of this class.
|
||||
*
|
||||
* @return AbstractIdGenerator
|
||||
*/
|
||||
public function getIdGenerator()
|
||||
{
|
||||
return $this->_idGenerator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the definition of the sequence ID generator for this class.
|
||||
*
|
||||
* The definition has the following structure:
|
||||
* <code>
|
||||
* array(
|
||||
* 'sequenceName' => 'name',
|
||||
* 'allocationSize' => 20,
|
||||
* 'initialValue' => 1
|
||||
* )
|
||||
* </code>
|
||||
*
|
||||
* @return array|null An array with the generator definition or NULL if this class
|
||||
* has no sequence generator definition.
|
||||
*/
|
||||
public function getSequenceGeneratorDefinition()
|
||||
{
|
||||
return $this->_sequenceGeneratorDefinition;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the definition of the sequence ID generator for this class.
|
||||
*
|
||||
* The definition must have the following structure:
|
||||
* <code>
|
||||
* array(
|
||||
* 'sequenceName' => 'name',
|
||||
* 'allocationSize' => 20,
|
||||
* 'initialValue' => 1
|
||||
* )
|
||||
* </code>
|
||||
*
|
||||
* @param array $definition
|
||||
*/
|
||||
public function setSequenceGeneratorDefinition(array $definition)
|
||||
{
|
||||
$this->_sequenceGeneratorDefinition = $definition;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a string representation of this instance.
|
||||
*
|
||||
* @return string The string representation of this instance.
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return __CLASS__ . '@' . spl_object_hash($this);
|
||||
|
@ -21,6 +21,7 @@
|
||||
|
||||
namespace Doctrine\ORM\Mapping;
|
||||
|
||||
use Doctrine\Common\DoctrineException;
|
||||
use Doctrine\DBAL\Platforms\AbstractPlatform;
|
||||
|
||||
/**
|
||||
@ -134,6 +135,11 @@ class ClassMetadataFactory
|
||||
|
||||
// Invoke driver
|
||||
$this->_driver->loadMetadataForClass($className, $class);
|
||||
|
||||
// Verify & complete identifier mapping
|
||||
if ( ! $class->getIdentifier()) {
|
||||
throw MappingException::identifierRequired($className);
|
||||
}
|
||||
$this->_completeIdGeneratorMapping($class);
|
||||
|
||||
if ($parent && $parent->isInheritanceTypeSingleTable()) {
|
||||
@ -195,7 +201,8 @@ class ClassMetadataFactory
|
||||
*/
|
||||
private function _completeIdGeneratorMapping(ClassMetadata $class)
|
||||
{
|
||||
if ($class->getIdGeneratorType() == ClassMetadata::GENERATOR_TYPE_AUTO) {
|
||||
$idGenType = $class->getIdGeneratorType();
|
||||
if ($idGenType == ClassMetadata::GENERATOR_TYPE_AUTO) {
|
||||
if ($this->_targetPlatform->prefersSequences()) {
|
||||
$class->setIdGeneratorType(ClassMetadata::GENERATOR_TYPE_SEQUENCE);
|
||||
} else if ($this->_targetPlatform->prefersIdentityColumns()) {
|
||||
@ -204,5 +211,35 @@ class ClassMetadataFactory
|
||||
$class->setIdGeneratorType(ClassMetadata::GENERATOR_TYPE_TABLE);
|
||||
}
|
||||
}
|
||||
|
||||
// Create & assign an appropriate ID generator instance
|
||||
switch ($class->getIdGeneratorType()) {
|
||||
case ClassMetadata::GENERATOR_TYPE_IDENTITY:
|
||||
$class->setIdGenerator(new \Doctrine\ORM\Id\IdentityGenerator());
|
||||
break;
|
||||
case ClassMetadata::GENERATOR_TYPE_SEQUENCE:
|
||||
// If there is no sequence definition yet, create a default definition
|
||||
$definition = $class->getSequenceGeneratorDefinition();
|
||||
if ( ! $definition) {
|
||||
$definition['sequenceName'] = $class->getTableName() . '_' . $class->getSingleIdentifierColumnName() . '_seq';
|
||||
$definition['allocationSize'] = 20;
|
||||
$definition['initialValue'] = 1;
|
||||
$class->setSequenceGeneratorDefinition($definition);
|
||||
}
|
||||
$sequenceGenerator = new \Doctrine\ORM\Id\SequenceGenerator(
|
||||
$definition['sequenceName'],
|
||||
$definition['allocationSize']
|
||||
);
|
||||
$class->setIdGenerator($sequenceGenerator);
|
||||
break;
|
||||
case ClassMetadata::GENERATOR_TYPE_NONE:
|
||||
$class->setIdGenerator(new \Doctrine\ORM\Id\Assigned());
|
||||
break;
|
||||
case ClassMetadata::GENERATOR_TYPE_TABLE:
|
||||
throw new DoctrineException("DoctrineTableGenerator not yet implemented.");
|
||||
break;
|
||||
default:
|
||||
throw new DoctrineException("Unexhaustive match.");
|
||||
}
|
||||
}
|
||||
}
|
@ -21,6 +21,7 @@
|
||||
|
||||
namespace Doctrine\ORM\Mapping\Driver;
|
||||
|
||||
use Doctrine\Common\DoctrineException;
|
||||
use Doctrine\ORM\Mapping\ClassMetadata;
|
||||
use Doctrine\ORM\Mapping\MappingException;
|
||||
|
||||
@ -48,7 +49,7 @@ class AnnotationDriver
|
||||
|
||||
// Evaluate DoctrineEntity annotation
|
||||
if (($entityAnnot = $annotClass->getAnnotation('DoctrineEntity')) === false) {
|
||||
throw \Doctrine\Common\DoctrineException::updateMe("$className is no entity.");
|
||||
throw DoctrineException::updateMe("$className is no entity.");
|
||||
}
|
||||
$metadata->setCustomRepositoryClass($entityAnnot->repositoryClass);
|
||||
|
||||
@ -109,7 +110,7 @@ class AnnotationDriver
|
||||
// DoctrineOneToOne, DoctrineOneToMany, DoctrineManyToOne, DoctrineManyToMany
|
||||
if ($columnAnnot = $property->getAnnotation('DoctrineColumn')) {
|
||||
if ($columnAnnot->type == null) {
|
||||
throw \Doctrine\Common\DoctrineException::updateMe("Missing type on property " . $property->getName());
|
||||
throw DoctrineException::updateMe("Missing type on property " . $property->getName());
|
||||
}
|
||||
$mapping['type'] = $columnAnnot->type;
|
||||
$mapping['length'] = $columnAnnot->length;
|
||||
@ -117,10 +118,22 @@ class AnnotationDriver
|
||||
if ($idAnnot = $property->getAnnotation('DoctrineId')) {
|
||||
$mapping['id'] = true;
|
||||
}
|
||||
if ($idGeneratorAnnot = $property->getAnnotation('DoctrineIdGenerator')) {
|
||||
$mapping['idGenerator'] = $idGeneratorAnnot->value;
|
||||
if ($generatedValueAnnot = $property->getAnnotation('DoctrineGeneratedValue')) {
|
||||
$metadata->setIdGeneratorType($generatedValueAnnot->strategy);
|
||||
}
|
||||
$metadata->mapField($mapping);
|
||||
|
||||
// Check for SequenceGenerator/TableGenerator definition
|
||||
if ($seqGeneratorAnnot = $property->getAnnotation('DoctrineSequenceGenerator')) {
|
||||
$metadata->setSequenceGeneratorDefinition(array(
|
||||
'sequenceName' => $seqGeneratorAnnot->sequenceName,
|
||||
'allocationSize' => $seqGeneratorAnnot->allocationSize,
|
||||
'initialValue' => $seqGeneratorAnnot->initialValue
|
||||
));
|
||||
} else if ($tblGeneratorAnnot = $property->getAnnotation('DoctrineTableGenerator')) {
|
||||
throw new DoctrineException("DoctrineTableGenerator not yet implemented.");
|
||||
}
|
||||
|
||||
} else if ($oneToOneAnnot = $property->getAnnotation('DoctrineOneToOne')) {
|
||||
$mapping['targetEntity'] = $oneToOneAnnot->targetEntity;
|
||||
$mapping['joinColumns'] = $joinColumns;
|
||||
|
@ -33,7 +33,10 @@ final class DoctrineDiscriminatorColumn extends \Addendum\Annotation {
|
||||
final class DoctrineDiscriminatorMap extends \Addendum\Annotation {}
|
||||
final class DoctrineSubClasses extends \Addendum\Annotation {}
|
||||
final class DoctrineId extends \Addendum\Annotation {}
|
||||
final class DoctrineIdGenerator extends \Addendum\Annotation {}
|
||||
final class DoctrineGeneratedValue extends \Addendum\Annotation {
|
||||
public $strategy;
|
||||
//public $generator;
|
||||
}
|
||||
final class DoctrineVersion extends \Addendum\Annotation {}
|
||||
final class DoctrineJoinColumn extends \Addendum\Annotation {
|
||||
public $name;
|
||||
@ -85,7 +88,10 @@ final class DoctrineJoinTable extends \Addendum\Annotation {
|
||||
public $inverseJoinColumns;
|
||||
}
|
||||
final class DoctrineSequenceGenerator extends \Addendum\Annotation {
|
||||
public $name;
|
||||
//public $name;
|
||||
public $sequenceName;
|
||||
public $allocationSize = 20;
|
||||
public $initialValue;
|
||||
public $initialValue = 1;
|
||||
/** The name of the class that defines the generator. */
|
||||
//public $definingClass;
|
||||
}
|
||||
|
@ -94,9 +94,9 @@ abstract class AbstractEntityPersister
|
||||
$insertData = array();
|
||||
$this->_prepareData($entity, $insertData, true);
|
||||
$this->_conn->insert($this->_classMetadata->getTableName(), $insertData);
|
||||
$idGen = $this->_em->getIdGenerator($this->_classMetadata->getClassName());
|
||||
$idGen = $this->_classMetadata->getIdGenerator();
|
||||
if ($idGen->isPostInsertGenerator()) {
|
||||
return $idGen->generate($entity);
|
||||
return $idGen->generate($this->_em, $entity);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@ -21,6 +21,7 @@
|
||||
|
||||
namespace Doctrine\ORM;
|
||||
|
||||
use Doctrine\ORM\Query\CacheHandler;
|
||||
use Doctrine\ORM\Query\Parser;
|
||||
use Doctrine\ORM\Query\QueryException;
|
||||
|
||||
@ -129,7 +130,7 @@ class Query extends AbstractQuery
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the assocated EntityManager to this Query instance.
|
||||
* Retrieves the associated EntityManager of this Query instance.
|
||||
*
|
||||
* @return Doctrine\ORM\EntityManager
|
||||
*/
|
||||
@ -243,13 +244,13 @@ class Query extends AbstractQuery
|
||||
if ($cached === false) {
|
||||
// Cache does not exist, we have to create it.
|
||||
$result = $this->_execute($params, self::HYDRATE_ARRAY);
|
||||
$queryResult = \Doctrine\ORM\Query\CacheHandler::fromResultSet($this, $result);
|
||||
$queryResult = CacheHandler::fromResultSet($this, $result);
|
||||
$cacheDriver->save($hash, $queryResult->toCachedForm(), $this->_resultCacheTTL);
|
||||
|
||||
return $result;
|
||||
} else {
|
||||
// Cache exists, recover it and return the results.
|
||||
$queryResult = \Doctrine\ORM\Query\CacheHandler::fromCachedResult($this, $cached);
|
||||
$queryResult = CacheHandler::fromCachedResult($this, $cached);
|
||||
|
||||
return $queryResult->getResultSet();
|
||||
}
|
||||
@ -288,7 +289,7 @@ class Query extends AbstractQuery
|
||||
$cacheDriver->save($hash, $this->_parserResult->toCachedForm(), $this->_queryCacheTTL);
|
||||
} else {
|
||||
// Cache exists, recover it and return the results.
|
||||
$this->_parserResult = Doctrine\ORM\Query\CacheHandler::fromCachedQuery($this, $cached);
|
||||
$this->_parserResult = CacheHandler::fromCachedQuery($this, $cached);
|
||||
|
||||
$executor = $this->_parserResult->getSqlExecutor();
|
||||
}
|
||||
@ -327,7 +328,7 @@ class Query extends AbstractQuery
|
||||
public function setResultCache($resultCache)
|
||||
{
|
||||
if ($resultCache !== null && ! ($resultCache instanceof \Doctrine\ORM\Cache\Cache)) {
|
||||
\Doctrine\Common\DoctrineException::updateMe(
|
||||
throw DoctrineException::updateMe(
|
||||
'Method setResultCache() accepts only an instance of Doctrine_Cache_Interface or null.'
|
||||
);
|
||||
}
|
||||
@ -409,7 +410,7 @@ class Query extends AbstractQuery
|
||||
public function setQueryCache($queryCache)
|
||||
{
|
||||
if ($queryCache !== null && ! ($queryCache instanceof \Doctrine\ORM\Cache\Cache)) {
|
||||
\Doctrine\Common\DoctrineException::updateMe(
|
||||
throw DoctrineException::updateMe(
|
||||
'Method setResultCache() accepts only an instance of Doctrine_ORM_Cache_Interface or null.'
|
||||
);
|
||||
}
|
||||
@ -510,7 +511,6 @@ class Query extends AbstractQuery
|
||||
|
||||
/**
|
||||
* Gets the array of results for the query.
|
||||
* Object graphs are represented as nested array structures.
|
||||
*
|
||||
* Alias for execute(array(), HYDRATE_ARRAY).
|
||||
*
|
||||
@ -575,9 +575,11 @@ class Query extends AbstractQuery
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the query and returns an IterableResult that can be iterated over.
|
||||
* Objects in the result are initialized on-demand.
|
||||
* Executes the query and returns an IterableResult that can be used to incrementally
|
||||
* iterated over the result.
|
||||
*
|
||||
* @param array $params The query parameters.
|
||||
* @param integer $hydrationMode The hydratio mode to use.
|
||||
* @return IterableResult
|
||||
*/
|
||||
public function iterate(array $params = array(), $hydrationMode = self::HYDRATE_OBJECT)
|
||||
|
@ -32,6 +32,7 @@ use Doctrine\Common\DoctrineException;
|
||||
* @version $Revision: 1393 $
|
||||
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
*/
|
||||
abstract class AbstractResult
|
||||
{
|
||||
|
@ -11,10 +11,4 @@ namespace Doctrine\ORM\Query;
|
||||
*
|
||||
* @author robo
|
||||
*/
|
||||
class QueryException extends \Doctrine\Common\DoctrineException
|
||||
{
|
||||
public static function nonUniqueResult()
|
||||
{
|
||||
return new self("The query contains more than one result.");
|
||||
}
|
||||
}
|
||||
class QueryException extends \Doctrine\Common\DoctrineException {}
|
@ -28,7 +28,6 @@ use Doctrine\ORM\PersistentCollection;
|
||||
use Doctrine\ORM\Mapping;
|
||||
use Doctrine\ORM\Persisters;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use Doctrine\ORM\Exceptions\UnitOfWorkException;
|
||||
|
||||
/**
|
||||
* The UnitOfWork is responsible for tracking changes to objects during an
|
||||
@ -440,9 +439,9 @@ class UnitOfWork
|
||||
$oid = spl_object_hash($entry);
|
||||
if ($state == self::STATE_NEW) {
|
||||
// Get identifier, if possible (not post-insert)
|
||||
$idGen = $this->_em->getIdGenerator($targetClass->getClassName());
|
||||
$idGen = $targetClass->getIdGenerator();
|
||||
if ( ! $idGen->isPostInsertGenerator()) {
|
||||
$idValue = $idGen->generate($entry);
|
||||
$idValue = $idGen->generate($this->_em, $entry);
|
||||
$this->_entityStates[$oid] = self::STATE_MANAGED;
|
||||
if ( ! $idGen instanceof \Doctrine\ORM\Id\Assigned) {
|
||||
$this->_entityIdentifiers[$oid] = array($idValue);
|
||||
@ -828,7 +827,7 @@ class UnitOfWork
|
||||
$classMetadata = $this->_em->getClassMetadata(get_class($entity));
|
||||
$idHash = $this->getIdentifierHash($this->_entityIdentifiers[$oid]);
|
||||
if ($idHash === '') {
|
||||
\Doctrine\Common\DoctrineException::updateMe("Entity with oid '" . spl_object_hash($entity)
|
||||
throw DoctrineException::updateMe("Entity with oid '" . spl_object_hash($entity)
|
||||
. "' has no identity and therefore can't be removed from the identity map.");
|
||||
}
|
||||
$className = $classMetadata->getRootClassName();
|
||||
@ -974,11 +973,11 @@ class UnitOfWork
|
||||
}
|
||||
break;
|
||||
case self::STATE_NEW:
|
||||
$idGen = $this->_em->getIdGenerator($class->getClassName());
|
||||
$idGen = $class->getIdGenerator();
|
||||
if ($idGen->isPostInsertGenerator()) {
|
||||
$insertNow[$oid] = $entity;
|
||||
} else {
|
||||
$idValue = $idGen->generate($entity);
|
||||
$idValue = $idGen->generate($this->_em, $entity);
|
||||
$this->_entityStates[$oid] = self::STATE_MANAGED;
|
||||
if ( ! $idGen instanceof \Doctrine\ORM\Id\Assigned) {
|
||||
$this->_entityIdentifiers[$oid] = array($idValue);
|
||||
@ -990,7 +989,7 @@ class UnitOfWork
|
||||
$this->registerNew($entity);
|
||||
break;
|
||||
case self::STATE_DETACHED:
|
||||
\Doctrine\Common\DoctrineException::updateMe("Behavior of save() for a detached entity "
|
||||
throw DoctrineException::updateMe("Behavior of save() for a detached entity "
|
||||
. "is not yet defined.");
|
||||
case self::STATE_DELETED:
|
||||
// entity becomes managed again
|
||||
@ -1004,7 +1003,7 @@ class UnitOfWork
|
||||
break;
|
||||
default:
|
||||
//TODO: throw UnitOfWorkException::invalidEntityState()
|
||||
\Doctrine\Common\DoctrineException::updateMe("Encountered invalid entity state.");
|
||||
throw DoctrineException::updateMe("Encountered invalid entity state.");
|
||||
}
|
||||
$this->_cascadeSave($entity, $visited, $insertNow);
|
||||
}
|
||||
@ -1046,9 +1045,9 @@ class UnitOfWork
|
||||
$this->registerDeleted($entity);
|
||||
break;
|
||||
case self::STATE_DETACHED:
|
||||
\Doctrine\Common\DoctrineException::updateMe("A detached entity can't be deleted.");
|
||||
throw DoctrineException::updateMe("A detached entity can't be deleted.");
|
||||
default:
|
||||
\Doctrine\Common\DoctrineException::updateMe("Encountered invalid entity state.");
|
||||
throw DoctrineException::updateMe("Encountered invalid entity state.");
|
||||
}
|
||||
$this->_cascadeDelete($entity, $visited);
|
||||
}
|
||||
@ -1298,7 +1297,7 @@ class UnitOfWork
|
||||
/**
|
||||
* Gets the identifier of an entity.
|
||||
* The returned value is always an array of identifier values. If the entity
|
||||
* has a composite primary key then the identifier values are in the same
|
||||
* has a composite identifier then the identifier values are in the same
|
||||
* order as the identifier field names as returned by ClassMetadata#getIdentifierFieldNames().
|
||||
*
|
||||
* @param object $entity
|
||||
@ -1343,8 +1342,6 @@ class UnitOfWork
|
||||
/**
|
||||
* Gets the EntityPersister for an Entity.
|
||||
*
|
||||
* This is usually not of interest for users, mainly for internal use.
|
||||
*
|
||||
* @param string $entityName The name of the Entity.
|
||||
* @return Doctrine\ORM\Persister\AbstractEntityPersister
|
||||
*/
|
||||
|
@ -5,7 +5,8 @@ namespace Doctrine\Tests\Mocks;
|
||||
class DatabasePlatformMock extends \Doctrine\DBAL\Platforms\AbstractPlatform
|
||||
{
|
||||
private $_sequenceNextValSql = "";
|
||||
private $_prefersIdentityColumns = false;
|
||||
private $_prefersIdentityColumns = true;
|
||||
private $_prefersSequences = false;
|
||||
|
||||
/**
|
||||
* @override
|
||||
@ -25,6 +26,14 @@ class DatabasePlatformMock extends \Doctrine\DBAL\Platforms\AbstractPlatform
|
||||
return $this->_prefersIdentityColumns;
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public function prefersSequences()
|
||||
{
|
||||
return $this->_prefersSequences;
|
||||
}
|
||||
|
||||
/** @override */
|
||||
public function getSequenceNextValSql($sequenceName)
|
||||
{
|
||||
@ -37,15 +46,9 @@ class DatabasePlatformMock extends \Doctrine\DBAL\Platforms\AbstractPlatform
|
||||
/** @override */
|
||||
public function getBigIntTypeDeclarationSql(array $field) {}
|
||||
|
||||
/** @override */
|
||||
public function getTinyIntTypeDeclarationSql(array $field) {}
|
||||
|
||||
/** @override */
|
||||
public function getSmallIntTypeDeclarationSql(array $field) {}
|
||||
|
||||
/** @override */
|
||||
public function getMediumIntTypeDeclarationSql(array $field) {}
|
||||
|
||||
/** @override */
|
||||
protected function _getCommonIntegerTypeDeclarationSql(array $columnDef) {}
|
||||
|
||||
@ -56,7 +59,12 @@ class DatabasePlatformMock extends \Doctrine\DBAL\Platforms\AbstractPlatform
|
||||
|
||||
public function setPrefersIdentityColumns($bool)
|
||||
{
|
||||
$this->_prefersIdentityColumns = (bool)$bool;
|
||||
$this->_prefersIdentityColumns = $bool;
|
||||
}
|
||||
|
||||
public function setPrefersSequences($bool)
|
||||
{
|
||||
$this->_prefersSequences = $bool;
|
||||
}
|
||||
|
||||
public function setSequenceNextValSql($sql)
|
||||
|
@ -70,14 +70,14 @@ class EntityManagerMock extends \Doctrine\ORM\EntityManager
|
||||
|
||||
return new EntityManagerMock($conn, $config, $eventManager);
|
||||
}
|
||||
|
||||
/*
|
||||
public function setIdGenerator($className, $generator)
|
||||
{
|
||||
$this->_idGenerators[$className] = $generator;
|
||||
}
|
||||
|
||||
*/
|
||||
/** @override */
|
||||
public function getIdGenerator($className)
|
||||
/* public function getIdGenerator($className)
|
||||
{
|
||||
|
||||
if (isset($this->_idGenerators[$className])) {
|
||||
@ -86,4 +86,5 @@ class EntityManagerMock extends \Doctrine\ORM\EntityManager
|
||||
|
||||
return parent::getIdGenerator($className);
|
||||
}
|
||||
*/
|
||||
}
|
@ -2,6 +2,8 @@
|
||||
|
||||
namespace Doctrine\Tests\Mocks;
|
||||
|
||||
use Doctrine\ORM\EntityManager;
|
||||
|
||||
class SequenceMock extends \Doctrine\ORM\Id\SequenceGenerator
|
||||
{
|
||||
private $_sequenceNumber = 0;
|
||||
@ -9,10 +11,10 @@ class SequenceMock extends \Doctrine\ORM\Id\SequenceGenerator
|
||||
/**
|
||||
* Enter description here...
|
||||
*
|
||||
* @param Doctrine_Entity $entity
|
||||
* @param object $entity
|
||||
* @override
|
||||
*/
|
||||
public function generate($entity)
|
||||
public function generate(EntityManager $em, $entity)
|
||||
{
|
||||
return $this->_sequenceNumber++;
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ class CmsAddress
|
||||
/**
|
||||
* @DoctrineColumn(type="integer")
|
||||
* @DoctrineId
|
||||
* @DoctrineIdGenerator("auto")
|
||||
* @DoctrineGeneratedValue(strategy="auto")
|
||||
*/
|
||||
public $id;
|
||||
|
||||
|
@ -11,7 +11,7 @@ class CmsArticle
|
||||
/**
|
||||
* @DoctrineId
|
||||
* @DoctrineColumn(type="integer")
|
||||
* @DoctrineIdGenerator("auto")
|
||||
* @DoctrineGeneratedValue(strategy="auto")
|
||||
*/
|
||||
public $id;
|
||||
/**
|
||||
|
@ -11,7 +11,7 @@ class CmsComment
|
||||
/**
|
||||
* @DoctrineColumn(type="integer")
|
||||
* @DoctrineId
|
||||
* @DoctrineIdGenerator("auto")
|
||||
* @DoctrineGeneratedValue(strategy="auto")
|
||||
*/
|
||||
public $id;
|
||||
/**
|
||||
|
@ -18,7 +18,7 @@ class CmsGroup
|
||||
/**
|
||||
* @DoctrineId
|
||||
* @DoctrineColumn(type="integer")
|
||||
* @DoctrineIdGenerator("auto")
|
||||
* @DoctrineGeneratedValue(strategy="auto")
|
||||
*/
|
||||
public $id;
|
||||
/**
|
||||
|
@ -11,7 +11,7 @@ class CmsUser
|
||||
/**
|
||||
* @DoctrineId
|
||||
* @DoctrineColumn(type="integer")
|
||||
* @DoctrineIdGenerator("auto")
|
||||
* @DoctrineGeneratedValue(strategy="auto")
|
||||
*/
|
||||
public $id;
|
||||
/**
|
||||
|
@ -17,7 +17,7 @@ class CompanyEmployee
|
||||
/**
|
||||
* @DoctrineId
|
||||
* @DoctrineColumn(type="integer")
|
||||
* @DoctrineIdGenerator("auto")
|
||||
* @DoctrineGeneratedValue(strategy="auto")
|
||||
*/
|
||||
public $id;
|
||||
|
||||
|
@ -11,7 +11,7 @@ class ForumAvatar
|
||||
/**
|
||||
* @DoctrineId
|
||||
* @DoctrineColumn(type="integer")
|
||||
* @DoctrineIdGenerator("auto")
|
||||
* @DoctrineGeneratedValue(strategy="auto")
|
||||
*/
|
||||
public $id;
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ class ForumEntry
|
||||
/**
|
||||
* @DoctrineId
|
||||
* @DoctrineColumn(type="integer")
|
||||
* @DoctrineIdGenerator("auto")
|
||||
* @DoctrineGeneratedValue(strategy="auto")
|
||||
*/
|
||||
public $id;
|
||||
/**
|
||||
|
@ -17,7 +17,7 @@ class ForumUser
|
||||
/**
|
||||
* @DoctrineColumn(type="integer")
|
||||
* @DoctrineId
|
||||
* @DoctrineIdGenerator("auto")
|
||||
* @DoctrineGeneratedValue(strategy="auto")
|
||||
*/
|
||||
public $id;
|
||||
/**
|
||||
|
@ -36,7 +36,7 @@ class AllTests
|
||||
$suite->addTest(Query\AllTests::suite());
|
||||
$suite->addTest(Hydration\AllTests::suite());
|
||||
$suite->addTest(Entity\AllTests::suite());
|
||||
$suite->addTest(Export\AllTests::suite());
|
||||
$suite->addTest(Tools\AllTests::suite());
|
||||
$suite->addTest(Associations\AllTests::suite());
|
||||
$suite->addTest(Mapping\AllTests::suite());
|
||||
$suite->addTest(Functional\AllTests::suite());
|
||||
|
@ -26,8 +26,8 @@ class EntityPersisterTest extends \Doctrine\Tests\OrmTestCase
|
||||
$this->_emMock = EntityManagerMock::create($this->_connMock);
|
||||
$this->_uowMock = new UnitOfWorkMock($this->_emMock);
|
||||
$this->_emMock->setUnitOfWork($this->_uowMock);
|
||||
$this->_idGenMock = new SequenceMock($this->_emMock, 'seq');
|
||||
$this->_emMock->setIdGenerator('Doctrine\Tests\Models\Forum\ForumUser', $this->_idGenMock);
|
||||
$this->_idGenMock = new SequenceMock($this->_emMock, 'seq', 20);
|
||||
//$this->_emMock->setIdGenerator('Doctrine\Tests\Models\Forum\ForumUser', $this->_idGenMock);
|
||||
}
|
||||
|
||||
public function testSimpleInsert()
|
||||
|
@ -1,29 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\ORM\Export;
|
||||
|
||||
use Doctrine\ORM\Export\ClassExporter;
|
||||
|
||||
require_once __DIR__ . '/../../TestInit.php';
|
||||
|
||||
class ClassExporterTest extends \Doctrine\Tests\OrmTestCase
|
||||
{
|
||||
public function testGetExportClassesSql()
|
||||
{
|
||||
$driver = new \Doctrine\Tests\Mocks\DriverMock;
|
||||
$conn = new \Doctrine\Tests\Mocks\ConnectionMock(array(), $driver);
|
||||
$conn->setDatabasePlatform(new \Doctrine\DBAL\Platforms\MySqlPlatform());
|
||||
|
||||
$em = $this->_getTestEntityManager($conn);
|
||||
|
||||
$classes = array(
|
||||
$em->getClassMetadata('Doctrine\Tests\Models\CMS\CmsAddress'),
|
||||
$em->getClassMetadata('Doctrine\Tests\Models\CMS\CmsUser'),
|
||||
$em->getClassMetadata('Doctrine\Tests\Models\CMS\CmsPhonenumber'),
|
||||
);
|
||||
|
||||
$exporter = new ClassExporter($em);
|
||||
$sql = $exporter->getExportClassesSql($classes);
|
||||
$this->assertEquals(count($sql), 8);
|
||||
}
|
||||
}
|
@ -19,7 +19,7 @@ class AllTests
|
||||
{
|
||||
$suite = new \Doctrine\Tests\OrmFunctionalTestSuite('Doctrine Orm Functional');
|
||||
|
||||
$suite->addTestSuite('Doctrine\Tests\ORM\Functional\BasicCRUDTest');
|
||||
$suite->addTestSuite('Doctrine\Tests\ORM\Functional\BasicFunctionalTest');
|
||||
|
||||
return $suite;
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
namespace Doctrine\Tests\ORM\Functional;
|
||||
|
||||
use Doctrine\ORM\Export\ClassExporter;
|
||||
use Doctrine\ORM\Tools\SchemaTool;
|
||||
use Doctrine\Tests\Models\CMS\CmsUser;
|
||||
use Doctrine\Tests\Models\CMS\CmsPhonenumber;
|
||||
use Doctrine\Tests\Models\CMS\CmsAddress;
|
||||
@ -10,27 +10,16 @@ use Doctrine\Tests\Models\CMS\CmsGroup;
|
||||
|
||||
require_once __DIR__ . '/../../TestInit.php';
|
||||
|
||||
class BasicCRUDTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
class BasicFunctionalTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
{
|
||||
protected function tearDown()
|
||||
protected function setUp()
|
||||
{
|
||||
$conn = $this->_em->getConnection();
|
||||
$conn->exec('DELETE FROM cms_users_groups');
|
||||
$conn->exec('DELETE FROM cms_groups');
|
||||
$conn->exec('DELETE FROM cms_addresses');
|
||||
$conn->exec('DELETE FROM cms_phonenumbers');
|
||||
$conn->exec('DELETE FROM cms_users');
|
||||
$this->useModelSet('cms');
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
public function testBasicUnitsOfWorkWithOneToManyAssociation()
|
||||
{
|
||||
$this->_exporter->exportClasses(array(
|
||||
$this->_em->getClassMetadata('Doctrine\Tests\Models\CMS\CmsUser'),
|
||||
$this->_em->getClassMetadata('Doctrine\Tests\Models\CMS\CmsPhonenumber'),
|
||||
$this->_em->getClassMetadata('Doctrine\Tests\Models\CMS\CmsAddress'),
|
||||
$this->_em->getClassMetadata('Doctrine\Tests\Models\CMS\CmsGroup')
|
||||
));
|
||||
|
||||
// Create
|
||||
$user = new CmsUser;
|
||||
$user->name = 'Roman';
|
||||
@ -175,7 +164,7 @@ class BasicCRUDTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
$group->users[] = $user;
|
||||
}
|
||||
|
||||
$this->_em->save($user); // Saves the user, cause of post-insert ID
|
||||
$this->_em->save($user); // Saves the user, 'cause of post-insert ID
|
||||
|
||||
$this->_em->flush();
|
||||
|
||||
@ -215,6 +204,22 @@ class BasicCRUDTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
$this->assertEquals('developer', $users[0]->status);
|
||||
$this->assertNull($users[0]->phonenumbers);
|
||||
$this->assertNull($users[0]->articles);
|
||||
|
||||
$usersArray = $query->getResultArray();
|
||||
|
||||
$this->assertTrue(is_array($usersArray));
|
||||
$this->assertEquals(1, count($usersArray));
|
||||
$this->assertEquals('Guilherme', $usersArray[0]['name']);
|
||||
$this->assertEquals('gblanco', $usersArray[0]['username']);
|
||||
$this->assertEquals('developer', $usersArray[0]['status']);
|
||||
|
||||
$usersScalar = $query->getScalarResult();
|
||||
|
||||
$this->assertTrue(is_array($usersScalar));
|
||||
$this->assertEquals(1, count($usersScalar));
|
||||
$this->assertEquals('Guilherme', $usersScalar[0]['u_name']);
|
||||
$this->assertEquals('gblanco', $usersScalar[0]['u_username']);
|
||||
$this->assertEquals('developer', $usersScalar[0]['u_status']);
|
||||
}
|
||||
|
||||
public function testBasicInnerJoin()
|
@ -1,11 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\ORM\Export;
|
||||
|
||||
|
||||
namespace Doctrine\Tests\ORM\Id;
|
||||
|
||||
if (!defined('PHPUnit_MAIN_METHOD')) {
|
||||
define('PHPUnit_MAIN_METHOD', 'Orm_Export_AllTests::main');
|
||||
define('PHPUnit_MAIN_METHOD', 'Orm_Id_AllTests::main');
|
||||
}
|
||||
|
||||
require_once __DIR__ . '/../../TestInit.php';
|
||||
@ -19,14 +17,14 @@ class AllTests
|
||||
|
||||
public static function suite()
|
||||
{
|
||||
$suite = new \Doctrine\Tests\DoctrineTestSuite('Doctrine Orm Export');
|
||||
$suite = new \Doctrine\Tests\DoctrineTestSuite('Doctrine Orm Id');
|
||||
|
||||
$suite->addTestSuite('Doctrine\Tests\ORM\Export\ClassExporterTest');
|
||||
$suite->addTestSuite('Doctrine\Tests\ORM\Id\SequenceGeneratorTest');
|
||||
|
||||
return $suite;
|
||||
}
|
||||
}
|
||||
|
||||
if (PHPUnit_MAIN_METHOD == 'Orm_Export_AllTests::main') {
|
||||
if (PHPUnit_MAIN_METHOD == 'Orm_Id_AllTests::main') {
|
||||
AllTests::main();
|
||||
}
|
40
tests/Doctrine/Tests/ORM/Id/SequenceGeneratorTest.php
Normal file
40
tests/Doctrine/Tests/ORM/Id/SequenceGeneratorTest.php
Normal file
@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\ORM\Id;
|
||||
|
||||
use Doctrine\ORM\Id\SequenceGenerator;
|
||||
|
||||
require_once __DIR__ . '/../../TestInit.php';
|
||||
|
||||
/**
|
||||
* Description of SequenceGeneratorTest
|
||||
*
|
||||
* @author robo
|
||||
*/
|
||||
class SequenceGeneratorTest extends \Doctrine\Tests\OrmTestCase
|
||||
{
|
||||
private $_em;
|
||||
private $_seqGen;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->_em = $this->_getTestEntityManager();
|
||||
$this->_seqGen = new SequenceGenerator('seq', 10);
|
||||
}
|
||||
|
||||
public function testGeneration()
|
||||
{
|
||||
for ($i=0; $i < 42; ++$i) {
|
||||
if ($i % 10 == 0) {
|
||||
$this->_em->getConnection()->setFetchOneResult((int)($i / 10) * 10 + 10);
|
||||
}
|
||||
$id = $this->_seqGen->generate($this->_em, null);
|
||||
$this->assertEquals($i, $id);
|
||||
$this->assertEquals((int)($i / 10) * 10 + 10, $this->_seqGen->getCurrentMaxValue());
|
||||
$this->assertEquals($i + 1, $this->_seqGen->getNextValue());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -15,11 +15,15 @@ class ClassMetadataFactoryTest extends \Doctrine\Tests\OrmTestCase
|
||||
{
|
||||
$mockPlatform = new DatabasePlatformMock();
|
||||
$mockDriver = new MetadataDriverMock();
|
||||
$mockPlatform->setPrefersSequences(true);
|
||||
$mockPlatform->setPrefersIdentityColumns(false);
|
||||
|
||||
// Self-made metadata
|
||||
$cm1 = new ClassMetadata('Doctrine\Tests\ORM\Mapping\TestEntity1');
|
||||
// Add a mapped field
|
||||
$cm1->mapField(array('fieldName' => 'name', 'type' => 'varchar'));
|
||||
// Add a mapped field
|
||||
$cm1->mapField(array('fieldName' => 'id', 'type' => 'integer', 'id' => true));
|
||||
// and a mapped association
|
||||
$cm1->mapOneToOne(array('fieldName' => 'other', 'targetEntity' => 'Other', 'mappedBy' => 'this'));
|
||||
// and an id generator type
|
||||
@ -41,8 +45,7 @@ class ClassMetadataFactoryTest extends \Doctrine\Tests\OrmTestCase
|
||||
|
||||
$this->assertEquals(array(), $cm1->getParentClasses());
|
||||
$this->assertTrue($cm1->hasField('name'));
|
||||
// The default fallback for id generation is the table strategy
|
||||
$this->assertEquals('table', $cm1->getIdGeneratorType());
|
||||
$this->assertEquals('sequence', $cm1->getIdGeneratorType());
|
||||
}
|
||||
|
||||
public function testGetMetadataForClassInHierarchy()
|
||||
@ -56,6 +59,8 @@ class ClassMetadataFactoryTest extends \Doctrine\Tests\OrmTestCase
|
||||
$cm1->setInheritanceType('singleTable');
|
||||
// Add a mapped field
|
||||
$cm1->mapField(array('fieldName' => 'name', 'type' => 'varchar'));
|
||||
// Add a mapped field
|
||||
$cm1->mapField(array('fieldName' => 'id', 'type' => 'integer', 'id' => true));
|
||||
// and a mapped association
|
||||
$cm1->mapOneToOne(array('fieldName' => 'other', 'targetEntity' => 'Other', 'mappedBy' => 'this'));
|
||||
// and an id generator type
|
||||
@ -144,6 +149,7 @@ class ClassMetadataFactoryTestSubject extends \Doctrine\ORM\Mapping\ClassMetadat
|
||||
|
||||
class TestEntity1
|
||||
{
|
||||
protected $id;
|
||||
protected $name;
|
||||
protected $other;
|
||||
}
|
||||
|
30
tests/Doctrine/Tests/ORM/Tools/AllTests.php
Normal file
30
tests/Doctrine/Tests/ORM/Tools/AllTests.php
Normal file
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\ORM\Tools;
|
||||
|
||||
if (!defined('PHPUnit_MAIN_METHOD')) {
|
||||
define('PHPUnit_MAIN_METHOD', 'Orm_Tools_AllTests::main');
|
||||
}
|
||||
|
||||
require_once __DIR__ . '/../../TestInit.php';
|
||||
|
||||
class AllTests
|
||||
{
|
||||
public static function main()
|
||||
{
|
||||
\PHPUnit_TextUI_TestRunner::run(self::suite());
|
||||
}
|
||||
|
||||
public static function suite()
|
||||
{
|
||||
$suite = new \Doctrine\Tests\DoctrineTestSuite('Doctrine Orm Tools');
|
||||
|
||||
$suite->addTestSuite('Doctrine\Tests\ORM\Tools\SchemaToolTest');
|
||||
|
||||
return $suite;
|
||||
}
|
||||
}
|
||||
|
||||
if (PHPUnit_MAIN_METHOD == 'Orm_Tools_AllTests::main') {
|
||||
AllTests::main();
|
||||
}
|
@ -54,8 +54,8 @@ class UnitOfWorkTest extends \Doctrine\Tests\OrmTestCase
|
||||
// Setup fake persister and id generator for identity generation
|
||||
$userPersister = new EntityPersisterMock($this->_emMock, $this->_emMock->getClassMetadata("Doctrine\Tests\Models\Forum\ForumUser"));
|
||||
$this->_unitOfWork->setEntityPersister('Doctrine\Tests\Models\Forum\ForumUser', $userPersister);
|
||||
$idGeneratorMock = new IdentityIdGeneratorMock($this->_emMock);
|
||||
$this->_emMock->setIdGenerator('Doctrine\Tests\Models\Forum\ForumUser', $idGeneratorMock);
|
||||
//$idGeneratorMock = new IdentityIdGeneratorMock($this->_emMock);
|
||||
//$this->_emMock->setIdGenerator('Doctrine\Tests\Models\Forum\ForumUser', $idGeneratorMock);
|
||||
$userPersister->setMockIdGeneratorType(\Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_IDENTITY);
|
||||
|
||||
// Test
|
||||
@ -95,14 +95,14 @@ class UnitOfWorkTest extends \Doctrine\Tests\OrmTestCase
|
||||
//ForumUser
|
||||
$userPersister = new EntityPersisterMock($this->_emMock, $this->_emMock->getClassMetadata("Doctrine\Tests\Models\Forum\ForumUser"));
|
||||
$this->_unitOfWork->setEntityPersister('Doctrine\Tests\Models\Forum\ForumUser', $userPersister);
|
||||
$userIdGeneratorMock = new IdentityIdGeneratorMock($this->_emMock);
|
||||
$this->_emMock->setIdGenerator('Doctrine\Tests\Models\Forum\ForumUser', $userIdGeneratorMock);
|
||||
//$userIdGeneratorMock = new IdentityIdGeneratorMock($this->_emMock);
|
||||
//$this->_emMock->setIdGenerator('Doctrine\Tests\Models\Forum\ForumUser', $userIdGeneratorMock);
|
||||
$userPersister->setMockIdGeneratorType(\Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_IDENTITY);
|
||||
// ForumAvatar
|
||||
$avatarPersister = new EntityPersisterMock($this->_emMock, $this->_emMock->getClassMetadata("Doctrine\Tests\Models\Forum\ForumAvatar"));
|
||||
$this->_unitOfWork->setEntityPersister('Doctrine\Tests\Models\Forum\ForumAvatar', $avatarPersister);
|
||||
$avatarIdGeneratorMock = new IdentityIdGeneratorMock($this->_emMock);
|
||||
$this->_emMock->setIdGenerator('Doctrine\Tests\Models\Forum\ForumAvatar', $avatarIdGeneratorMock);
|
||||
//$avatarIdGeneratorMock = new IdentityIdGeneratorMock($this->_emMock);
|
||||
//$this->_emMock->setIdGenerator('Doctrine\Tests\Models\Forum\ForumAvatar', $avatarIdGeneratorMock);
|
||||
$avatarPersister->setMockIdGeneratorType(\Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_IDENTITY);
|
||||
|
||||
// Test
|
||||
|
@ -3,7 +3,7 @@
|
||||
namespace Doctrine\Tests;
|
||||
|
||||
/**
|
||||
* Base testcase class for all orm testcases.
|
||||
* Base testcase class for all functional ORM testcases.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
@ -15,119 +15,88 @@ class OrmFunctionalTestCase extends OrmTestCase
|
||||
/** The EntityManager for this testcase. */
|
||||
protected $_em;
|
||||
|
||||
/** The ClassExporter for this testcase. */
|
||||
protected $_exporter;
|
||||
/** The SchemaTool. */
|
||||
protected $_schemaTool;
|
||||
|
||||
/**
|
||||
* The currently loaded model names of the fixtures for the testcase.
|
||||
*/
|
||||
private $_loadedFixtures = array();
|
||||
|
||||
/**
|
||||
* All loaded fixtures during test execution. Common fixture cache.
|
||||
*/
|
||||
private static $_fixtures = array();
|
||||
|
||||
/**
|
||||
* The names of all tables that were already exported. Each table is exported
|
||||
* only once. Then it's just filled & erased for each testmethod in a testcase
|
||||
* that uses one or more fixtures.
|
||||
*/
|
||||
private static $_exportedTables = array();
|
||||
|
||||
/**
|
||||
* Loads a data fixture into the database. This method must only be called
|
||||
* from within the setUp() method of testcases. The database will then be
|
||||
* populated with fresh data of all loaded fixtures for each test method.
|
||||
*
|
||||
* WARNING: A single testcase should never load fixtures from different scenarios of
|
||||
* the same package as the concistency and uniqueness of keys is not guaranteed.
|
||||
*
|
||||
* @param string $package The package name. Must be one of Doctrine's test model packages
|
||||
* (forum, cms or ecommerce).
|
||||
* @param string $scenario The fixture scenario. A model package can have many fixture
|
||||
* scenarios. Within a scenario all primary keys and foreign keys
|
||||
* of fixtures are consistent and unique.
|
||||
* @param string $name The name of the fixture to load from the specified package.
|
||||
*/
|
||||
protected function loadFixture($package, $scenario, $name)
|
||||
/** The names of the model sets used in this testcase. */
|
||||
private $_usedModelSets = array();
|
||||
|
||||
/** Whether the database schema has already been created. */
|
||||
private static $_tablesCreated = array();
|
||||
|
||||
/** List of model sets and their classes. */
|
||||
private static $_modelSets = array(
|
||||
'cms' => array(
|
||||
'Doctrine\Tests\Models\CMS\CmsUser',
|
||||
'Doctrine\Tests\Models\CMS\CmsPhonenumber',
|
||||
'Doctrine\Tests\Models\CMS\CmsAddress',
|
||||
'Doctrine\Tests\Models\CMS\CmsGroup'
|
||||
),
|
||||
'forum' => array(),
|
||||
'company' => array(),
|
||||
'ecommerce' => array()
|
||||
);
|
||||
|
||||
protected function useModelSet($setName)
|
||||
{
|
||||
$uniqueName = $package . '/' . $scenario . '/' . $name;
|
||||
|
||||
if ( ! isset(self::$_fixtures[$uniqueName])) {
|
||||
// load fixture file
|
||||
$fixtureFile = 'fixtures'
|
||||
. DIRECTORY_SEPARATOR . $package
|
||||
. DIRECTORY_SEPARATOR . $scenario
|
||||
. DIRECTORY_SEPARATOR . $name
|
||||
. '.php';
|
||||
require $fixtureFile;
|
||||
self::$_fixtures[$uniqueName] = $fixture;
|
||||
}
|
||||
|
||||
$fixture = self::$_fixtures[$uniqueName];
|
||||
$this->_loadedFixtures[] = $fixture['table'];
|
||||
|
||||
$conn = $this->sharedFixture['conn'];
|
||||
$tableName = $fixture['table'];
|
||||
|
||||
if ( ! in_array($tableName, self::$_exportedTables)) {
|
||||
$conn->getSchemaManager()->exportClasses(array($fixture['model']));
|
||||
self::$_exportedTables[] = $tableName;
|
||||
}
|
||||
|
||||
foreach ($fixture['rows'] as $row) {
|
||||
$conn->insert($tableName, $row);
|
||||
}
|
||||
$this->_usedModelSets[] = $setName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads multiple fixtures of the same package and scenario.
|
||||
* This method must only be called from within the setUp() method of testcases.
|
||||
* The database will then be populated with fresh data of all loaded fixtures for each
|
||||
* test method.
|
||||
*
|
||||
* WARNING: A single testcase should never load fixtures from different scenarios of
|
||||
* the same package as the concistency and uniqueness of keys is not guaranteed.
|
||||
*
|
||||
* @param string $package The package name. Must be one of Doctrine's test model packages
|
||||
* (forum, cms or ecommerce).
|
||||
* @param string $scenario The fixture scenario. A model package can have many fixture
|
||||
* scenarios. Within a scenario all primary keys and foreign keys
|
||||
* of fixtures are consistent and unique.
|
||||
* @param array $names The names of the fixtures to load from the specified package.
|
||||
*/
|
||||
protected function loadFixtures($package, $scenario, array $names)
|
||||
{
|
||||
foreach ($names as $name) {
|
||||
$this->loadFixture($package, $scenario, $name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sweeps the database tables of all used fixtures and clears the EntityManager.
|
||||
* Sweeps the database tables and clears the EntityManager.
|
||||
*/
|
||||
protected function tearDown()
|
||||
{
|
||||
$conn = $this->sharedFixture['conn'];
|
||||
foreach (array_reverse($this->_loadedFixtures) as $table) {
|
||||
$conn->exec("DELETE FROM " . $table);
|
||||
if (in_array('cms', $this->_usedModelSets)) {
|
||||
$conn->exec('DELETE FROM cms_users_groups');
|
||||
$conn->exec('DELETE FROM cms_groups');
|
||||
$conn->exec('DELETE FROM cms_addresses');
|
||||
$conn->exec('DELETE FROM cms_phonenumbers');
|
||||
$conn->exec('DELETE FROM cms_users');
|
||||
}
|
||||
$this->_em->clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a connection to the test database, if there is none yet, and
|
||||
* creates the necessary tables.
|
||||
*/
|
||||
protected function setUp()
|
||||
{
|
||||
$forceCreateTables = false;
|
||||
if ( ! isset($this->sharedFixture['conn'])) {
|
||||
echo PHP_EOL . " --- CREATE CONNECTION ----" . PHP_EOL;
|
||||
$this->sharedFixture['conn'] = TestUtil::getConnection();
|
||||
if ($this->sharedFixture['conn']->getDriver() instanceof \Doctrine\DBAL\Driver\PDOSqlite\Driver) {
|
||||
$forceCreateTables = true;
|
||||
}
|
||||
}
|
||||
if ( ! $this->_em) {
|
||||
$this->_em = $this->_getEntityManager();
|
||||
$this->_exporter = new \Doctrine\ORM\Export\ClassExporter($this->_em);
|
||||
$this->_schemaTool = new \Doctrine\ORM\Tools\SchemaTool($this->_em);
|
||||
}
|
||||
|
||||
$classes = array();
|
||||
foreach ($this->_usedModelSets as $setName) {
|
||||
if ( ! isset(self::$_tablesCreated[$setName]) || $forceCreateTables) {
|
||||
foreach (self::$_modelSets[$setName] as $className) {
|
||||
$classes[] = $this->_em->getClassMetadata($className);
|
||||
}
|
||||
self::$_tablesCreated[$setName] = true;
|
||||
}
|
||||
}
|
||||
if ($classes) {
|
||||
$this->_schemaTool->createSchema($classes);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an EntityManager for testing purposes.
|
||||
*
|
||||
* @param Configuration $config The Configuration to pass to the EntityManager.
|
||||
* @param EventManager $eventManager The EventManager to pass to the EntityManager.
|
||||
* @return EntityManager
|
||||
*/
|
||||
protected function _getEntityManager($config = null, $eventManager = null) {
|
||||
// NOTE: Functional tests use their own shared metadata cache, because
|
||||
// the actual database platform used during execution has effect on some
|
||||
|
10
tests/fixtures/forum/common/admins.php
vendored
10
tests/fixtures/forum/common/admins.php
vendored
@ -1,10 +0,0 @@
|
||||
<?php
|
||||
$fixture = array(
|
||||
'model' => 'ForumAdministrator',
|
||||
'rows' => array(
|
||||
array(
|
||||
'id' => 1,
|
||||
'access_level' => 4
|
||||
)
|
||||
)
|
||||
);
|
16
tests/fixtures/forum/common/users.php
vendored
16
tests/fixtures/forum/common/users.php
vendored
@ -1,16 +0,0 @@
|
||||
<?php
|
||||
$fixture = array(
|
||||
'model' => 'ForumUser',
|
||||
'rows' => array(
|
||||
array(
|
||||
'id' => 1,
|
||||
'username' => 'romanb',
|
||||
'dtype' => 'admin'
|
||||
),
|
||||
array(
|
||||
'id' => 2,
|
||||
'username' => 'jwage',
|
||||
'dtype' => 'user'
|
||||
)
|
||||
)
|
||||
);
|
Loading…
x
Reference in New Issue
Block a user