[2.0] Continued work on association mappings and class exporting (DDL generation). Fixed #1863.
This commit is contained in:
parent
e202cb1ce1
commit
886c961108
34 changed files with 651 additions and 301 deletions
|
@ -16,7 +16,7 @@
|
|||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information, see
|
||||
* <http://www.phpdoctrine.org>.
|
||||
* <http://www.doctrine-project.org>.
|
||||
*/
|
||||
|
||||
namespace Doctrine\DBAL;
|
||||
|
@ -317,7 +317,6 @@ class Connection
|
|||
|
||||
// column names are specified as array keys
|
||||
$cols = array();
|
||||
// the query VALUES will contain either expressions (eg 'NOW()') or ?
|
||||
$a = array();
|
||||
foreach ($data as $columnName => $value) {
|
||||
$cols[] = $this->quoteIdentifier($columnName);
|
||||
|
|
|
@ -1,7 +1,31 @@
|
|||
<?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\DBAL\Driver\PDOMySql;
|
||||
|
||||
/**
|
||||
* PDO MySql driver.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
class Driver implements \Doctrine\DBAL\Driver
|
||||
{
|
||||
/**
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information, see
|
||||
* <http://www.phpdoctrine.org>.
|
||||
* <http://www.doctrine-project.org>.
|
||||
*/
|
||||
|
||||
namespace Doctrine\DBAL\Platforms;
|
||||
|
@ -1591,7 +1591,7 @@ abstract class AbstractPlatform
|
|||
|
||||
$sql .= implode(', ', array_map(array($this, 'quoteIdentifier'), $definition['local']))
|
||||
. ') REFERENCES '
|
||||
. $this->_conn->quoteIdentifier($definition['foreignTable']) . '('
|
||||
. $this->quoteIdentifier($definition['foreignTable']) . '('
|
||||
. implode(', ', array_map(array($this, 'quoteIdentifier'), $definition['foreign'])) . ')';
|
||||
|
||||
return $sql;
|
||||
|
|
|
@ -431,9 +431,7 @@ class SqlitePlatform extends AbstractPlatform
|
|||
protected function _getCommonIntegerTypeDeclarationSql(array $columnDef)
|
||||
{
|
||||
$autoinc = ! empty($columnDef['autoincrement']) ? 'AUTOINCREMENT' : '';
|
||||
$pk = ! empty($columnDef['primary']) ? 'PRIMARY KEY' : '';
|
||||
|
||||
//$unsigned = (isset($columnDef['unsigned']) && $columnDef['unsigned']) ? ' UNSIGNED' : '';
|
||||
$pk = ! empty($columnDef['primary']) && ! empty($autoinc) ? 'PRIMARY KEY' : '';
|
||||
|
||||
return "INTEGER $pk $autoinc";
|
||||
}
|
||||
|
@ -533,5 +531,18 @@ class SqlitePlatform extends AbstractPlatform
|
|||
return $fixed ? ($length ? 'CHAR(' . $length . ')' : 'CHAR(255)')
|
||||
: ($length ? 'VARCHAR(' . $length . ')' : 'TEXT');
|
||||
}
|
||||
|
||||
/**
|
||||
* SQLite does support foreign key constraints, but only in CREATE TABLE statements...
|
||||
* This really limits their usefulness and requires SQLite specific handling, so
|
||||
* we simply say that SQLite does NOT support foreign keys for now...
|
||||
*
|
||||
* @return boolean
|
||||
* @override
|
||||
*/
|
||||
public function supportsForeignKeyConstraints()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information, see
|
||||
* <http://www.phpdoctrine.org>.
|
||||
* <http://www.doctrine-project.org>.
|
||||
*/
|
||||
|
||||
namespace Doctrine\ORM;
|
||||
|
@ -138,7 +138,9 @@ class EntityManager
|
|||
*/
|
||||
private $_hydrators = array();
|
||||
|
||||
/** Whether the EntityManager is closed or not. */
|
||||
/**
|
||||
* Whether the EntityManager is closed or not.
|
||||
*/
|
||||
private $_closed = false;
|
||||
|
||||
/**
|
||||
|
@ -150,11 +152,7 @@ class EntityManager
|
|||
* @param Doctrine\ORM\Configuration $config
|
||||
* @param Doctrine\Common\EventManager $eventManager
|
||||
*/
|
||||
protected function __construct(
|
||||
Connection $conn,
|
||||
$name,
|
||||
Configuration $config,
|
||||
EventManager $eventManager)
|
||||
protected function __construct(Connection $conn, $name, Configuration $config, EventManager $eventManager)
|
||||
{
|
||||
$this->_conn = $conn;
|
||||
$this->_name = $name;
|
||||
|
@ -207,6 +205,7 @@ class EntityManager
|
|||
|
||||
/**
|
||||
* Commits a running transaction.
|
||||
*
|
||||
* This causes a flush() of the EntityManager if the flush mode is set to
|
||||
* AUTO or COMMIT.
|
||||
*
|
||||
|
@ -245,7 +244,7 @@ class EntityManager
|
|||
}
|
||||
|
||||
/**
|
||||
* Used to lazily create the id generator.
|
||||
* Used to lazily create an ID generator.
|
||||
*
|
||||
* @param string $generatorType
|
||||
* @return object
|
||||
|
@ -281,7 +280,7 @@ class EntityManager
|
|||
/**
|
||||
* Detaches an entity from the manager. It's lifecycle is no longer managed.
|
||||
*
|
||||
* @param Doctrine\ORM\Entity $entity
|
||||
* @param object $entity
|
||||
* @return boolean
|
||||
*/
|
||||
public function detach($entity)
|
||||
|
@ -337,6 +336,7 @@ class EntityManager
|
|||
|
||||
/**
|
||||
* Finds an Entity by its identifier.
|
||||
*
|
||||
* This is just a convenient shortcut for getRepository($entityName)->find($id).
|
||||
*
|
||||
* @param string $entityName
|
||||
|
@ -349,7 +349,7 @@ class EntityManager
|
|||
}
|
||||
|
||||
/**
|
||||
* Sets the flush mode.
|
||||
* Sets the flush mode to use.
|
||||
*
|
||||
* @param string $flushMode
|
||||
*/
|
||||
|
@ -437,21 +437,21 @@ class EntityManager
|
|||
* Refreshes the persistent state of the entity from the database,
|
||||
* overriding any local changes that have not yet been persisted.
|
||||
*
|
||||
* @param Doctrine\ORM\Entity $entity
|
||||
* @param object $entity
|
||||
* @todo FIX Impl
|
||||
*/
|
||||
public function refresh(Doctrine_ORM_Entity $entity)
|
||||
public function refresh($entity)
|
||||
{
|
||||
$this->_mergeData($entity, $entity->getRepository()->find(
|
||||
/*$this->_mergeData($entity, $this->getRepository(get_class($entity))->find(
|
||||
$entity->identifier(), Query::HYDRATE_ARRAY),
|
||||
true);
|
||||
true);*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of the given entity. Can create a shallow or a deep copy.
|
||||
*
|
||||
* @param Doctrine\ORM\Entity $entity The entity to copy.
|
||||
* @return Doctrine\ORM\Entity The new entity.
|
||||
* @param object $entity The entity to copy.
|
||||
* @return object The new entity.
|
||||
*/
|
||||
public function copy($entity, $deep = false)
|
||||
{
|
||||
|
@ -561,16 +561,16 @@ class EntityManager
|
|||
case Query::HYDRATE_OBJECT:
|
||||
$this->_hydrators[$hydrationMode] = new \Doctrine\ORM\Internal\Hydration\ObjectHydrator($this);
|
||||
break;
|
||||
case Doctrine_ORM_Query::HYDRATE_ARRAY:
|
||||
case Query::HYDRATE_ARRAY:
|
||||
$this->_hydrators[$hydrationMode] = new \Doctrine\ORM\Internal\Hydration\ArrayHydrator($this);
|
||||
break;
|
||||
case Doctrine_ORM_Query::HYDRATE_SCALAR:
|
||||
case Query::HYDRATE_SCALAR:
|
||||
$this->_hydrators[$hydrationMode] = new \Doctrine\ORM\Internal\Hydration\ScalarHydrator($this);
|
||||
break;
|
||||
case Doctrine_ORM_Query::HYDRATE_SINGLE_SCALAR:
|
||||
case Query::HYDRATE_SINGLE_SCALAR:
|
||||
$this->_hydrators[$hydrationMode] = new \Doctrine\ORM\Internal\Hydration\SingleScalarHydrator($this);
|
||||
break;
|
||||
case Doctrine_ORM_Query::HYDRATE_NONE:
|
||||
case Query::HYDRATE_NONE:
|
||||
$this->_hydrators[$hydrationMode] = new \Doctrine\ORM\Internal\Hydration\NoneHydrator($this);
|
||||
break;
|
||||
default:
|
||||
|
@ -617,10 +617,7 @@ class EntityManager
|
|||
* @param EventManager $eventManager The EventManager instance to use.
|
||||
* @return EntityManager The created EntityManager.
|
||||
*/
|
||||
public static function create(
|
||||
$conn,
|
||||
$name,
|
||||
Configuration $config = null,
|
||||
public static function create($conn, $name, Configuration $config = null,
|
||||
EventManager $eventManager = null)
|
||||
{
|
||||
if (is_array($conn)) {
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
|
||||
namespace Doctrine\ORM\Export;
|
||||
|
||||
use Doctrine\ORM\EntityManager;
|
||||
|
||||
/**
|
||||
* The ClassExporter can generate database schemas/structures from ClassMetadata
|
||||
* class descriptors.
|
||||
|
@ -41,25 +43,32 @@ class ClassExporter
|
|||
private $_sm;
|
||||
/** The EntityManager */
|
||||
private $_em;
|
||||
/** The DatabasePlatform */
|
||||
private $_platform;
|
||||
|
||||
public function __construct(\Doctrine\ORM\EntityManager $em)
|
||||
/**
|
||||
* 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 entity classes to a schema.
|
||||
*
|
||||
* FIXME: This method is a big huge hack. The sql needs to be executed in the correct order. I have some stupid logic to
|
||||
* make sure they are in the right order.
|
||||
* Exports entity classes to a database, according to the specified mappings.
|
||||
*
|
||||
* @param array $classes
|
||||
* @return void
|
||||
*/
|
||||
public function exportClasses(array $classes)
|
||||
{
|
||||
//TODO: order them
|
||||
$foreignKeyConstraints = array();
|
||||
|
||||
// First we create the tables
|
||||
foreach ($classes as $class) {
|
||||
$columns = array();
|
||||
$options = array();
|
||||
|
@ -70,92 +79,84 @@ class ClassExporter
|
|||
$column['type'] = $mapping['type'];
|
||||
$column['length'] = $mapping['length'];
|
||||
$column['notnull'] = ! $mapping['nullable'];
|
||||
|
||||
if ($class->isIdentifier($fieldName)) {
|
||||
$column['primary'] = true;
|
||||
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()) {
|
||||
foreach ($mapping->getSourceToTargetKeyColumns() as $sourceColumn => $targetColumn) {
|
||||
$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'] = $sourceColumn;
|
||||
$column['type'] = $this->_em->getClassMetadata($mapping->getTargetEntityName())
|
||||
->getTypeOfColumn($targetColumn);
|
||||
$columns[$sourceColumn] = $column;
|
||||
$column['name'] = $joinColumn['name'];
|
||||
$column['type'] = $foreignClass->getTypeOfColumn($joinColumn['referencedColumnName']);
|
||||
$columns[$joinColumn['name']] = $column;
|
||||
$constraint['local'][] = $joinColumn['name'];
|
||||
$constraint['foreign'][] = $joinColumn['referencedColumnName'];
|
||||
}
|
||||
} else if ($mapping->isOneToMany() && $mapping->usesJoinTable()) {
|
||||
$foreignKeyConstraints[] = $constraint;
|
||||
} else if ($mapping->isOneToMany() && $mapping->isOwningSide()) {
|
||||
//... create join table, one-many through join table supported later
|
||||
throw new Doctrine_Exception("Not yet implemented.");
|
||||
throw new DoctrineException("Not yet implemented.");
|
||||
} else if ($mapping->isManyToMany() && $mapping->isOwningSide()) {
|
||||
//... create join table
|
||||
$joinTableColumns = 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;
|
||||
$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;
|
||||
$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;
|
||||
|
||||
$this->_sm->createTable($joinTable['name'], $joinTableColumns, array());
|
||||
}
|
||||
}
|
||||
|
||||
$this->_sm->createTable($class->getTableName(), $columns, $options);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* exportClassesSql
|
||||
* method for exporting entity classes to a schema
|
||||
*
|
||||
* @throws Doctrine_Connection_Exception if some error other than Doctrine::ERR_ALREADY_EXISTS
|
||||
* occurred during the create table operation
|
||||
* @param array $classes
|
||||
* @return void
|
||||
*/
|
||||
public function exportClassesSql(array $classes)
|
||||
{
|
||||
$models = Doctrine::filterInvalidModels($classes);
|
||||
|
||||
$sql = array();
|
||||
$finishedClasses = array();
|
||||
|
||||
foreach ($models as $name) {
|
||||
if (in_array($name, $finishedClasses)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$classMetadata = $this->conn->getClassMetadata($name);
|
||||
|
||||
// In Class Table Inheritance we have to make sure that ALL tables of parent classes
|
||||
// are exported, too as soon as ONE table is exported, because the data of one class is stored
|
||||
// across many tables.
|
||||
if ($classMetadata->getInheritanceType() == Doctrine::INHERITANCE_TYPE_JOINED) {
|
||||
$parents = $classMetadata->getParentClasses();
|
||||
foreach ($parents as $parent) {
|
||||
$data = $classMetadata->getConnection()->getClassMetadata($parent)->getExportableFormat();
|
||||
$query = $this->conn->export->createTableSql($data['tableName'], $data['columns'], $data['options']);
|
||||
$sql = array_merge($sql, (array) $query);
|
||||
$finishedClasses[] = $parent;
|
||||
}
|
||||
}
|
||||
|
||||
$data = $classMetadata->getExportableFormat();
|
||||
$query = $this->conn->export->createTableSql($data['tableName'], $data['columns'], $data['options']);
|
||||
|
||||
if (is_array($query)) {
|
||||
$sql = array_merge($sql, $query);
|
||||
} else {
|
||||
$sql[] = $query;
|
||||
}
|
||||
|
||||
if ($classMetadata->getAttribute(Doctrine::ATTR_EXPORT) & Doctrine::EXPORT_PLUGINS) {
|
||||
$sql = array_merge($sql, $this->exportGeneratorsSql($classMetadata));
|
||||
// Now create the foreign key constraints
|
||||
if ($this->_platform->supportsForeignKeyConstraints()) {
|
||||
foreach ($foreignKeyConstraints as $fkConstraint) {
|
||||
$this->_sm->createForeignKey($fkConstraint['tableName'], $fkConstraint);
|
||||
}
|
||||
}
|
||||
|
||||
$sql = array_unique($sql);
|
||||
|
||||
rsort($sql);
|
||||
|
||||
return $sql;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,23 @@
|
|||
<?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;
|
||||
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
|
||||
namespace Doctrine\ORM\Mapping;
|
||||
|
||||
use Doctrine\ORM\Exceptions\MappingException;
|
||||
|
||||
/**
|
||||
* Base class for association mappings.
|
||||
*
|
||||
|
@ -107,11 +109,11 @@ abstract class AssociationMapping
|
|||
protected $_mappedByFieldName;
|
||||
|
||||
/**
|
||||
* The name of the join table, if any.
|
||||
* The join table definition, if any.
|
||||
*
|
||||
* @var string
|
||||
* @var array
|
||||
*/
|
||||
protected $_joinTable;
|
||||
protected $_joinTable = array();
|
||||
|
||||
/**
|
||||
* Initializes a new instance of a class derived from AssociationMapping.
|
||||
|
@ -132,17 +134,17 @@ abstract class AssociationMapping
|
|||
{
|
||||
// Mandatory attributes for both sides
|
||||
if ( ! isset($mapping['fieldName'])) {
|
||||
throw Doctrine_MappingException::missingFieldName();
|
||||
throw MappingException::missingFieldName();
|
||||
}
|
||||
$this->_sourceFieldName = $mapping['fieldName'];
|
||||
|
||||
if ( ! isset($mapping['sourceEntity'])) {
|
||||
throw Doctrine_MappingException::missingSourceEntity($mapping['fieldName']);
|
||||
throw MappingException::missingSourceEntity($mapping['fieldName']);
|
||||
}
|
||||
$this->_sourceEntityName = $mapping['sourceEntity'];
|
||||
|
||||
if ( ! isset($mapping['targetEntity'])) {
|
||||
throw Doctrine_ORM_Exceptions_MappingException::missingTargetEntity($mapping['fieldName']);
|
||||
throw MappingException::missingTargetEntity($mapping['fieldName']);
|
||||
}
|
||||
$this->_targetEntityName = $mapping['targetEntity'];
|
||||
|
||||
|
@ -287,9 +289,9 @@ abstract class AssociationMapping
|
|||
}
|
||||
|
||||
/**
|
||||
* Gets the name of the join table.
|
||||
* Gets the join table definition, if any.
|
||||
*
|
||||
* @return string
|
||||
* @return array
|
||||
*/
|
||||
public function getJoinTable()
|
||||
{
|
||||
|
@ -316,36 +318,6 @@ abstract class AssociationMapping
|
|||
return $this->_mappedByFieldName;
|
||||
}
|
||||
|
||||
/*public function getInverseSideFieldName()
|
||||
{
|
||||
return $this->_inverseSideFieldName;
|
||||
}*/
|
||||
/**
|
||||
* Marks the association as bidirectional, specifying the field name of
|
||||
* the inverse side.
|
||||
* This is called on the owning side, when an inverse side is discovered.
|
||||
* This does only make sense to call on the owning side.
|
||||
*
|
||||
* @param string $inverseSideFieldName
|
||||
*/
|
||||
/*public function setBidirectional($inverseSideFieldName)
|
||||
{
|
||||
if ( ! $this->_isOwningSide) {
|
||||
return; //TODO: exception?
|
||||
}
|
||||
$this->_inverseSideFieldName = $inverseSideFieldName;
|
||||
}*/
|
||||
|
||||
/**
|
||||
* Whether the association is bidirectional.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
/*public function isBidirectional()
|
||||
{
|
||||
return $this->_mappedByFieldName || $this->_inverseSideFieldName;
|
||||
}*/
|
||||
|
||||
public function isOneToOne()
|
||||
{
|
||||
return false;
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
namespace Doctrine\ORM\Mapping;
|
||||
|
||||
use \ReflectionClass;
|
||||
use Doctrine\Common\DoctrineException;
|
||||
|
||||
/**
|
||||
* A <tt>ClassMetadata</tt> instance holds all the information (metadata) of an entity and
|
||||
|
@ -100,9 +101,18 @@ class ClassMetadata
|
|||
*/
|
||||
const ENTITY_TYPE_MAPPED_SUPERCLASS = 'mappedSuperclass';
|
||||
|
||||
/** The name of the entity class. */
|
||||
/**
|
||||
* The name of the entity class.
|
||||
*/
|
||||
protected $_entityName;
|
||||
|
||||
/**
|
||||
* The namespace the entity class is contained in.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $_namespace;
|
||||
|
||||
/**
|
||||
* The name of the entity class that is at the root of the entity inheritance
|
||||
* hierarchy. If the entity is not part of an inheritance hierarchy this is the same
|
||||
|
@ -268,11 +278,16 @@ class ClassMetadata
|
|||
protected $_discriminatorColumn;
|
||||
|
||||
/**
|
||||
* The name of the primary table.
|
||||
* The primary table definition. The definition is an array with the
|
||||
* following entries:
|
||||
*
|
||||
* @var string
|
||||
* name => <tableName>
|
||||
* schema => <schemaName>
|
||||
* catalog => <catalogName>
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_tableName;
|
||||
protected $_primaryTable;
|
||||
|
||||
/**
|
||||
* The cached lifecycle listeners. There is only one instance of each
|
||||
|
@ -332,15 +347,16 @@ class ClassMetadata
|
|||
protected $_reflectionProperties;
|
||||
|
||||
/**
|
||||
* Initializes a new ClassMetadata instance that will hold the ORM metadata
|
||||
* of the class with the given name.
|
||||
* Initializes a new ClassMetadata instance that will hold the object-relational mapping
|
||||
* metadata of the class with the given name.
|
||||
*
|
||||
* @param string $entityName Name of the entity class the new instance is used for.
|
||||
*/
|
||||
public function __construct($entityName)
|
||||
{
|
||||
$this->_entityName = $entityName;
|
||||
$this->_tableName = $this->_entityName;
|
||||
$this->_namespace = substr($entityName, 0, strrpos($entityName, '\\'));
|
||||
$this->_primaryTable['name'] = str_replace($this->_namespace . '\\', '', $this->_entityName);
|
||||
$this->_rootEntityName = $entityName;
|
||||
$this->_reflectionClass = new ReflectionClass($entityName);
|
||||
}
|
||||
|
@ -383,7 +399,7 @@ class ClassMetadata
|
|||
public function getSingleIdReflectionProperty()
|
||||
{
|
||||
if ($this->_isIdentifierComposite) {
|
||||
throw new Doctrine_Exception("getSingleIdReflectionProperty called on entity with composite key.");
|
||||
throw new DoctrineException("getSingleIdReflectionProperty called on entity with composite key.");
|
||||
}
|
||||
return $this->_reflectionProperties[$this->_identifier[0]];
|
||||
}
|
||||
|
@ -448,7 +464,6 @@ class ClassMetadata
|
|||
if ($mapping !== false) {
|
||||
return isset($mapping['unique']) && $mapping['unique'] == true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -464,7 +479,6 @@ class ClassMetadata
|
|||
if ($mapping !== false) {
|
||||
return isset($mapping['notnull']) && $mapping['notnull'] == true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -520,8 +534,8 @@ class ClassMetadata
|
|||
*/
|
||||
public function getInverseAssociationMapping($mappedByFieldName)
|
||||
{
|
||||
if ( ! isset($this->_associationMappings[$fieldName])) {
|
||||
throw new Doctrine_Exception("Mapping not found: " . $fieldName);
|
||||
if ( ! isset($this->_inverseMappings[$mappedByFieldName])) {
|
||||
throw new DoctrineException("Mapping not found: " . $mappedByFieldName);
|
||||
}
|
||||
return $this->_inverseMappings[$mappedByFieldName];
|
||||
}
|
||||
|
@ -932,13 +946,13 @@ class ClassMetadata
|
|||
}
|
||||
|
||||
/**
|
||||
* getTableName
|
||||
* Gets the name of the primary table.
|
||||
*
|
||||
* @return void
|
||||
* @return string
|
||||
*/
|
||||
public function getTableName()
|
||||
{
|
||||
return $this->_tableName;
|
||||
return $this->_primaryTable['name'];
|
||||
}
|
||||
|
||||
public function getInheritedFields()
|
||||
|
@ -1092,34 +1106,34 @@ class ClassMetadata
|
|||
*/
|
||||
public function setTableName($tableName)
|
||||
{
|
||||
$this->_tableName = $tableName;
|
||||
$this->_primaryTable['name'] = $tableName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Serializes the metadata.
|
||||
* Sets the primary table definition. The provided array must have th
|
||||
* following structure:
|
||||
*
|
||||
* Part of the implementation of the Serializable interface.
|
||||
* name => <tableName>
|
||||
* schema => <schemaName>
|
||||
* catalog => <catalogName>
|
||||
*
|
||||
* @return string The serialized metadata.
|
||||
* @param array $primaryTableDefinition
|
||||
*/
|
||||
/* public function serialize()
|
||||
public function setPrimaryTable(array $primaryTableDefinition)
|
||||
{
|
||||
//$contents = get_object_vars($this);
|
||||
//return serialize($contents);
|
||||
return "";
|
||||
}*/
|
||||
$this->_primaryTable = $primaryTableDefinition;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reconstructs the metadata class from it's serialized representation.
|
||||
* Gets the primary table definition.
|
||||
*
|
||||
* Part of the implementation of the Serializable interface.
|
||||
*
|
||||
* @param string $serialized The serialized metadata class.
|
||||
* @see setPrimaryTable()
|
||||
* @return array
|
||||
*/
|
||||
/*public function unserialize($serialized)
|
||||
public function getPrimaryTable()
|
||||
{
|
||||
return true;
|
||||
}*/
|
||||
return $this->_primaryTable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the given type identifies an entity type.
|
||||
|
@ -1168,12 +1182,14 @@ class ClassMetadata
|
|||
* easier for the user.
|
||||
*
|
||||
* @param array $mapping
|
||||
* @return unknown
|
||||
* @todo Pass param by ref?
|
||||
*/
|
||||
private function _completeAssociationMapping(array $mapping)
|
||||
{
|
||||
$mapping['sourceEntity'] = $this->_entityName;
|
||||
if (isset($mapping['targetEntity']) && strpos($mapping['targetEntity'], '\\') === false) {
|
||||
$mapping['targetEntity'] = $this->_namespace . '\\' . $mapping['targetEntity'];
|
||||
}
|
||||
return $mapping;
|
||||
}
|
||||
|
||||
|
@ -1260,7 +1276,7 @@ class ClassMetadata
|
|||
/**
|
||||
* Stores the association mapping.
|
||||
*
|
||||
* @param Doctrine_Association $assocMapping
|
||||
* @param AssociationMapping $assocMapping
|
||||
*/
|
||||
private function _storeAssociationMapping(AssociationMapping $assocMapping)
|
||||
{
|
||||
|
@ -1278,7 +1294,7 @@ class ClassMetadata
|
|||
}
|
||||
|
||||
/**
|
||||
* Registers a custom mapper for the entity class.
|
||||
* Registers a custom repository class for the entity class.
|
||||
*
|
||||
* @param string $mapperClassName The class name of the custom mapper.
|
||||
*/
|
||||
|
@ -1333,11 +1349,11 @@ class ClassMetadata
|
|||
//Entity::TYPE_ENTITY
|
||||
//Entity::TYPE_MAPPED_SUPERCLASS
|
||||
//Entity::TYPE_TRANSIENT
|
||||
throw new Doctrine_Exception("Not yet implemented.");
|
||||
throw new DoctrineException("Not yet implemented.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatches the lifecycle event of the given Entity to the registered
|
||||
* Dispatches the lifecycle event of the given entity to the registered
|
||||
* lifecycle callbacks and lifecycle listeners.
|
||||
*
|
||||
* @param string $event The lifecycle event.
|
||||
|
@ -1381,7 +1397,7 @@ class ClassMetadata
|
|||
}
|
||||
|
||||
/**
|
||||
* Adds a lifecycle listener for Entities of this class.
|
||||
* Adds a lifecycle listener for entities of this class.
|
||||
*
|
||||
* Note: If the same listener class is registered more than once, the old
|
||||
* one will be overridden.
|
||||
|
|
|
@ -1,14 +1,34 @@
|
|||
<?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\Mapping\Driver;
|
||||
|
||||
use Doctrine\ORM\Mapping\ClassMetadata;
|
||||
use Doctrine\ORM\Exceptions\MappingException;
|
||||
|
||||
/* Addendum annotation reflection extensions */
|
||||
if ( ! class_exists('\Addendum', false)) {
|
||||
require dirname(__FILE__) . '/addendum/annotations.php';
|
||||
require __DIR__ . '/addendum/annotations.php';
|
||||
}
|
||||
require dirname(__FILE__) . '/DoctrineAnnotations.php';
|
||||
require __DIR__ . '/DoctrineAnnotations.php';
|
||||
|
||||
/**
|
||||
* The AnnotationDriver reads the mapping metadata from docblock annotations.
|
||||
|
@ -20,23 +40,31 @@ class AnnotationDriver
|
|||
/**
|
||||
* Loads the metadata for the specified class into the provided container.
|
||||
*/
|
||||
public function loadMetadataForClass($className, \Doctrine\ORM\Mapping\ClassMetadata $metadata)
|
||||
public function loadMetadataForClass($className, ClassMetadata $metadata)
|
||||
{
|
||||
$annotClass = new \Addendum\ReflectionAnnotatedClass($className);
|
||||
|
||||
// Evaluate DoctrineEntity annotation
|
||||
if (($entityAnnot = $annotClass->getAnnotation('DoctrineEntity')) === false) {
|
||||
throw new MappingException("$className is no entity.");
|
||||
}
|
||||
|
||||
if ($entityAnnot->tableName) {
|
||||
$metadata->setTableName($entityAnnot->tableName);
|
||||
}
|
||||
$metadata->setCustomRepositoryClass($entityAnnot->repositoryClass);
|
||||
|
||||
// Evaluate DoctrineTable annotation
|
||||
if ($tableAnnot = $annotClass->getAnnotation('DoctrineTable')) {
|
||||
$metadata->setPrimaryTable(array(
|
||||
'name' => $tableAnnot->name,
|
||||
'schema' => $tableAnnot->schema,
|
||||
'catalog' => $tableAnnot->catalog
|
||||
));
|
||||
}
|
||||
|
||||
// Evaluate DoctrineInheritanceType annotation
|
||||
if ($inheritanceTypeAnnot = $annotClass->getAnnotation('DoctrineInheritanceType')) {
|
||||
$metadata->setInheritanceType($inheritanceTypeAnnot->value);
|
||||
}
|
||||
|
||||
// Evaluate DoctrineDiscriminatorColumn annotation
|
||||
if ($discrColumnAnnot = $annotClass->getAnnotation('DoctrineDiscriminatorColumn')) {
|
||||
$metadata->setDiscriminatorColumn(array(
|
||||
'name' => $discrColumnAnnot->name,
|
||||
|
@ -45,17 +73,38 @@ class AnnotationDriver
|
|||
));
|
||||
}
|
||||
|
||||
// Evaluate DoctrineDiscriminatorMap annotation
|
||||
if ($discrValueAnnot = $annotClass->getAnnotation('DoctrineDiscriminatorMap')) {
|
||||
$metadata->setDiscriminatorMap((array)$discrValueAnnot->value);
|
||||
}
|
||||
|
||||
|
||||
// Evaluate DoctrineSubClasses annotation
|
||||
if ($subClassesAnnot = $annotClass->getAnnotation('DoctrineSubClasses')) {
|
||||
$metadata->setSubclasses($subClassesAnnot->value);
|
||||
}
|
||||
|
||||
// Evaluate annotations on properties/fields
|
||||
foreach ($annotClass->getProperties() as $property) {
|
||||
$mapping = array();
|
||||
$mapping['fieldName'] = $property->getName();
|
||||
|
||||
// Check for DoctrineJoinColummn/DoctrineJoinColumns annotations
|
||||
$joinColumns = array();
|
||||
if ($joinColumnAnnot = $property->getAnnotation('DoctrineJoinColumn')) {
|
||||
$joinColumns[] = array(
|
||||
'name' => $joinColumnAnnot->name,
|
||||
'referencedColumnName' => $joinColumnAnnot->referencedColumnName,
|
||||
'unique' => $joinColumnAnnot->unique,
|
||||
'nullable' => $joinColumnAnnot->nullable,
|
||||
'onDelete' => $joinColumnAnnot->onDelete,
|
||||
'onUpdate' => $joinColumnAnnot->onUpdate
|
||||
);
|
||||
} else if ($joinColumnsAnnot = $property->getAnnotation('DoctrineJoinColumns')) {
|
||||
$joinColumns = $joinColumnsAnnot->value;
|
||||
}
|
||||
|
||||
// Field can only be annotated with one of: DoctrineColumn,
|
||||
// DoctrineOneToOne, DoctrineOneToMany, DoctrineManyToOne, DoctrineManyToMany
|
||||
if ($columnAnnot = $property->getAnnotation('DoctrineColumn')) {
|
||||
if ($columnAnnot->type == null) {
|
||||
throw new MappingException("Missing type on property " . $property->getName());
|
||||
|
@ -72,7 +121,7 @@ class AnnotationDriver
|
|||
$metadata->mapField($mapping);
|
||||
} else if ($oneToOneAnnot = $property->getAnnotation('DoctrineOneToOne')) {
|
||||
$mapping['targetEntity'] = $oneToOneAnnot->targetEntity;
|
||||
$mapping['joinColumns'] = $oneToOneAnnot->joinColumns;
|
||||
$mapping['joinColumns'] = $joinColumns;
|
||||
$mapping['mappedBy'] = $oneToOneAnnot->mappedBy;
|
||||
$mapping['cascade'] = $oneToOneAnnot->cascade;
|
||||
$metadata->mapOneToOne($mapping);
|
||||
|
@ -82,17 +131,26 @@ class AnnotationDriver
|
|||
$mapping['cascade'] = $oneToManyAnnot->cascade;
|
||||
$metadata->mapOneToMany($mapping);
|
||||
} else if ($manyToOneAnnot = $property->getAnnotation('DoctrineManyToOne')) {
|
||||
$mapping['joinColumns'] = $manyToOneAnnot->joinColumns;
|
||||
$mapping['joinColumns'] = $joinColumns;
|
||||
$mapping['targetEntity'] = $manyToOneAnnot->targetEntity;
|
||||
$metadata->mapManyToOne($mapping);
|
||||
} else if ($manyToManyAnnot = $property->getAnnotation('DoctrineManyToMany')) {
|
||||
$joinTable = array();
|
||||
if ($joinTableAnnot = $property->getAnnotation('DoctrineJoinTable')) {
|
||||
$joinTable = array(
|
||||
'name' => $joinTableAnnot->name,
|
||||
'schema' => $joinTableAnnot->schema,
|
||||
'catalog' => $joinTableAnnot->catalog,
|
||||
'joinColumns' => $joinTableAnnot->joinColumns,
|
||||
'inverseJoinColumns' => $joinTableAnnot->inverseJoinColumns
|
||||
);
|
||||
}
|
||||
$mapping['joinTable'] = $joinTable;
|
||||
$mapping['targetEntity'] = $manyToManyAnnot->targetEntity;
|
||||
$mapping['joinColumns'] = $manyToManyAnnot->joinColumns;
|
||||
$mapping['inverseJoinColumns'] = $manyToManyAnnot->inverseJoinColumns;
|
||||
$mapping['joinTable'] = $manyToManyAnnot->joinTable;
|
||||
$mapping['mappedBy'] = $manyToManyAnnot->mappedBy;
|
||||
$metadata->mapManyToMany($mapping);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,15 +1,28 @@
|
|||
<?php
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
/*
|
||||
* $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>.
|
||||
*/
|
||||
|
||||
/* Annotations */
|
||||
|
||||
final class DoctrineEntity extends \Addendum\Annotation {
|
||||
public $tableName;
|
||||
public $repositoryClass;
|
||||
public $inheritanceType;
|
||||
}
|
||||
final class DoctrineInheritanceType extends \Addendum\Annotation {}
|
||||
final class DoctrineDiscriminatorColumn extends \Addendum\Annotation {
|
||||
|
@ -24,11 +37,13 @@ final class DoctrineIdGenerator extends \Addendum\Annotation {}
|
|||
final class DoctrineVersion extends \Addendum\Annotation {}
|
||||
final class DoctrineJoinColumn extends \Addendum\Annotation {
|
||||
public $name;
|
||||
public $type;
|
||||
public $length;
|
||||
public $referencedColumnName;
|
||||
public $unique = false;
|
||||
public $nullable = true;
|
||||
public $onDelete;
|
||||
public $onUpdate;
|
||||
}
|
||||
final class DoctrineJoinColumns extends \Addendum\Annotation {}
|
||||
final class DoctrineColumn extends \Addendum\Annotation {
|
||||
public $type;
|
||||
public $length;
|
||||
|
@ -38,7 +53,6 @@ final class DoctrineColumn extends \Addendum\Annotation {
|
|||
final class DoctrineOneToOne extends \Addendum\Annotation {
|
||||
public $targetEntity;
|
||||
public $mappedBy;
|
||||
public $joinColumns;
|
||||
public $cascade;
|
||||
}
|
||||
final class DoctrineOneToMany extends \Addendum\Annotation {
|
||||
|
@ -48,15 +62,25 @@ final class DoctrineOneToMany extends \Addendum\Annotation {
|
|||
}
|
||||
final class DoctrineManyToOne extends \Addendum\Annotation {
|
||||
public $targetEntity;
|
||||
public $joinColumns;
|
||||
public $cascade;
|
||||
}
|
||||
final class DoctrineManyToMany extends \Addendum\Annotation {
|
||||
public $targetEntity;
|
||||
public $joinColumns;
|
||||
public $inverseJoinColumns;
|
||||
public $joinTable;
|
||||
public $mappedBy;
|
||||
public $cascade;
|
||||
}
|
||||
|
||||
final class DoctrineElementCollection extends \Addendum\Annotation {
|
||||
public $tableName;
|
||||
}
|
||||
final class DoctrineTable extends \Addendum\Annotation {
|
||||
public $name;
|
||||
public $catalog;
|
||||
public $schema;
|
||||
}
|
||||
final class DoctrineJoinTable extends \Addendum\Annotation {
|
||||
public $name;
|
||||
public $catalog;
|
||||
public $schema;
|
||||
public $joinColumns;
|
||||
public $inverseJoinColumns;
|
||||
}
|
||||
|
|
|
@ -1,40 +1,61 @@
|
|||
<?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::Mapping;
|
||||
namespace Doctrine\ORM\Mapping;
|
||||
|
||||
use Doctrine\ORM\Exceptions\MappingException;
|
||||
|
||||
/**
|
||||
* A many-to-many mapping describes the mapping between two collections of
|
||||
* entities.
|
||||
*
|
||||
* @since 2.0
|
||||
* @todo Rename to ManyToManyMapping
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
*/
|
||||
class Doctrine_ORM_Mapping_ManyToManyMapping extends Doctrine_ORM_Mapping_AssociationMapping
|
||||
{
|
||||
class ManyToManyMapping extends AssociationMapping
|
||||
{
|
||||
/**
|
||||
* The name of the association class (if an association class is used).
|
||||
*
|
||||
* @var string
|
||||
* The key columns of the source table.
|
||||
*/
|
||||
private $_associationClass;
|
||||
|
||||
/** The field in the source table that corresponds to the key in the relation table */
|
||||
protected $_sourceKeyColumns;
|
||||
private $_sourceKeyColumns = array();
|
||||
|
||||
/** The field in the target table that corresponds to the key in the relation table */
|
||||
protected $_targetKeyColumns;
|
||||
/**
|
||||
* The key columns of the target table.
|
||||
*/
|
||||
private $_targetKeyColumns = array();
|
||||
|
||||
/** The field in the intermediate table that corresponds to the key in the source table */
|
||||
protected $_sourceRelationKeyColumns;
|
||||
/**
|
||||
* Maps the columns in the source table to the columns in the relation table.
|
||||
*/
|
||||
private $_sourceToRelationKeyColumns = array();
|
||||
|
||||
/** The field in the intermediate table that corresponds to the key in the target table */
|
||||
protected $_targetRelationKeyColumns;
|
||||
/**
|
||||
* Maps the columns in the target table to the columns in the relation table.
|
||||
*/
|
||||
private $_targetToRelationKeyColumns = array();
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* Creates a new ManyToManyMapping.
|
||||
* Initializes a new ManyToManyMapping.
|
||||
*
|
||||
* @param array $mapping The mapping info.
|
||||
* @param array $mapping The mapping information.
|
||||
*/
|
||||
public function __construct(array $mapping)
|
||||
{
|
||||
|
@ -50,38 +71,63 @@ class Doctrine_ORM_Mapping_ManyToManyMapping extends Doctrine_ORM_Mapping_Associ
|
|||
protected function _validateAndCompleteMapping(array $mapping)
|
||||
{
|
||||
parent::_validateAndCompleteMapping($mapping);
|
||||
|
||||
if ($this->isOwningSide()) {
|
||||
// many-many owning MUST have a join table
|
||||
// owning side MUST have a join table
|
||||
if ( ! isset($mapping['joinTable'])) {
|
||||
throw Doctrine_MappingException::joinTableRequired($mapping['fieldName']);
|
||||
throw MappingException::joinTableRequired($mapping['fieldName']);
|
||||
}
|
||||
|
||||
// optional attributes for many-many owning side
|
||||
$this->_associationClass = isset($mapping['associationClass']) ?
|
||||
$mapping['associationClass'] : null;
|
||||
// owning side MUST specify joinColumns
|
||||
if ( ! isset($mapping['joinTable']['joinColumns'])) {
|
||||
throw MappingException::invalidMapping($this->_sourceFieldName);
|
||||
}
|
||||
foreach ($mapping['joinTable']['joinColumns'] as $joinColumn) {
|
||||
$this->_sourceToRelationKeyColumns[$joinColumn['referencedColumnName']] = $joinColumn['name'];
|
||||
}
|
||||
$this->_sourceKeyColumns = array_keys($this->_sourceToRelationKeyColumns);
|
||||
// owning side MUST specify inverseJoinColumns
|
||||
if ( ! isset($mapping['joinTable']['inverseJoinColumns'])) {
|
||||
throw MappingException::invalidMapping($this->_sourceFieldName);
|
||||
}
|
||||
foreach ($mapping['joinTable']['inverseJoinColumns'] as $inverseJoinColumn) {
|
||||
$this->_targetToRelationKeyColumns[$inverseJoinColumn['referencedColumnName']] = $inverseJoinColumn['name'];
|
||||
}
|
||||
$this->_targetKeyColumns = array_keys($this->_targetToRelationKeyColumns);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the mapping uses an association class for the intermediary
|
||||
* table.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function usesAssociationClass()
|
||||
|
||||
public function getSourceToRelationKeyColumns()
|
||||
{
|
||||
return $this->_associationClass !== null;
|
||||
return $this->_sourceToRelationKeyColumns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of the association class.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getAssociationClassName()
|
||||
|
||||
public function getTargetToRelationKeyColumns()
|
||||
{
|
||||
return $this->_associationClass;
|
||||
return $this->_targetToRelationKeyColumns;
|
||||
}
|
||||
|
||||
public function getSourceKeyColumns()
|
||||
{
|
||||
return $this->_sourceKeyColumns;
|
||||
}
|
||||
|
||||
public function getTargetKeyColumns()
|
||||
{
|
||||
return $this->_targetKeyColumns;
|
||||
}
|
||||
|
||||
public function lazyLoadFor($entity, $entityManager)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @override
|
||||
*/
|
||||
public function isManyToMany()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information, see
|
||||
* <http://www.phpdoctrine.org>.
|
||||
* <http://www.doctrine-project.org>.
|
||||
*/
|
||||
|
||||
namespace Doctrine\ORM\Mapping;
|
||||
|
@ -54,10 +54,9 @@ class OneToManyMapping extends AssociationMapping
|
|||
protected $_deleteOrphans = false;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* Creates a new OneToManyMapping.
|
||||
* Initializes a new OneToManyMapping.
|
||||
*
|
||||
* @param array $mapping The mapping info.
|
||||
* @param array $mapping The mapping information.
|
||||
*/
|
||||
public function __construct(array $mapping)
|
||||
{
|
||||
|
|
|
@ -35,21 +35,28 @@ class OneToOneMapping extends AssociationMapping
|
|||
* i.e. source.id (pk) => target.user_id (fk).
|
||||
* Reverse mapping of _targetToSourceKeyColumns.
|
||||
*/
|
||||
protected $_sourceToTargetKeyColumns = array();
|
||||
private $_sourceToTargetKeyColumns = array();
|
||||
|
||||
/**
|
||||
* Maps the target primary/foreign key columns to the source foreign/primary key columns.
|
||||
* i.e. target.user_id (fk) => source.id (pk).
|
||||
* Reverse mapping of _sourceToTargetKeyColumns.
|
||||
*/
|
||||
protected $_targetToSourceKeyColumns = array();
|
||||
private $_targetToSourceKeyColumns = array();
|
||||
|
||||
/**
|
||||
* Whether to delete orphaned elements (when nulled out, i.e. $foo->other = null)
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
protected $_deleteOrphans = false;
|
||||
private $_deleteOrphans = false;
|
||||
|
||||
/**
|
||||
* The join column definitions.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $_joinColumns = array();
|
||||
|
||||
/**
|
||||
* Creates a new OneToOneMapping.
|
||||
|
@ -74,9 +81,12 @@ class OneToOneMapping extends AssociationMapping
|
|||
|
||||
if ($this->isOwningSide()) {
|
||||
if ( ! isset($mapping['joinColumns'])) {
|
||||
throw Doctrine_ORM_Exceptions_MappingException::invalidMapping($this->_sourceFieldName);
|
||||
throw MappingException::invalidMapping($this->_sourceFieldName);
|
||||
}
|
||||
$this->_joinColumns = $mapping['joinColumns'];
|
||||
foreach ($mapping['joinColumns'] as $joinColumn) {
|
||||
$this->_sourceToTargetKeyColumns[$joinColumn['name']] = $joinColumn['referencedColumnName'];
|
||||
}
|
||||
$this->_sourceToTargetKeyColumns = $mapping['joinColumns'];
|
||||
$this->_targetToSourceKeyColumns = array_flip($this->_sourceToTargetKeyColumns);
|
||||
}
|
||||
|
||||
|
@ -85,6 +95,16 @@ class OneToOneMapping extends AssociationMapping
|
|||
|
||||
return $mapping;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the join column definitions for this mapping.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getJoinColumns()
|
||||
{
|
||||
return $this->_joinColumns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the source-to-target key column mapping.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
/*
|
||||
* $Id: Collection.php 4930 2008-09-12 10:40:23Z romanb $
|
||||
* $Id$
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
|
@ -16,7 +16,7 @@
|
|||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information, see
|
||||
* <http://www.phpdoctrine.org>.
|
||||
* <http://www.doctrine-project.org>.
|
||||
*/
|
||||
|
||||
namespace Doctrine\ORM;
|
||||
|
@ -110,6 +110,12 @@ final class PersistentCollection extends \Doctrine\Common\Collections\Collection
|
|||
*/
|
||||
private $_ownerClass;
|
||||
|
||||
/**
|
||||
* Whether the collection is dirty and needs to be synchronized with the database
|
||||
* when the UnitOfWork that manages its persistent state commits.
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
private $_isDirty = false;
|
||||
|
||||
/**
|
||||
|
@ -181,11 +187,21 @@ final class PersistentCollection extends \Doctrine\Common\Collections\Collection
|
|||
*
|
||||
* @return object
|
||||
*/
|
||||
public function _getOwner()
|
||||
public function getOwner()
|
||||
{
|
||||
return $this->_owner;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the class descriptor for the owning entity class.
|
||||
*
|
||||
* @return Doctrine\ORM\Mapping\ClassMetadata
|
||||
*/
|
||||
public function getOwnerClass()
|
||||
{
|
||||
return $this->_ownerClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes an element from the collection.
|
||||
*
|
||||
|
@ -251,8 +267,9 @@ final class PersistentCollection extends \Doctrine\Common\Collections\Collection
|
|||
/**
|
||||
* Adds all entities of the other collection to this collection.
|
||||
*
|
||||
* @param unknown_type $otherCollection
|
||||
* @param object $otherCollection
|
||||
* @todo Impl
|
||||
* @override
|
||||
*/
|
||||
public function addAll($otherCollection)
|
||||
{
|
||||
|
|
|
@ -1,18 +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\Persisters;
|
||||
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use Doctrine\ORM\PersistentCollection;
|
||||
|
||||
/**
|
||||
* Base class for all collection persisters.
|
||||
*
|
||||
* @since 2.0
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
*/
|
||||
abstract class AbstractCollectionPersister
|
||||
{
|
||||
protected $_em;
|
||||
protected $_conn;
|
||||
protected $_uow;
|
||||
|
||||
/**
|
||||
* Initializes a new instance of a class derived from {@link AbstractCollectionPersister}.
|
||||
*
|
||||
* @param Doctrine\ORM\EntityManager $em
|
||||
*/
|
||||
public function __construct(EntityManager $em)
|
||||
{
|
||||
$this->_em = $em;
|
||||
$this->_uow = $em->getUnitOfWork();
|
||||
$this->_conn = $em->getConnection();
|
||||
}
|
||||
|
||||
|
@ -51,7 +83,7 @@ abstract class AbstractCollectionPersister
|
|||
$sql = $this->_getDeleteRowSql($coll);
|
||||
$uow = $this->_em->getUnitOfWork();
|
||||
foreach ($deleteDiff as $element) {
|
||||
$this->_conn->exec($sql, $uow->getEntityIdentifier($element));
|
||||
$this->_conn->exec($sql, $this->_getDeleteRowSqlParameters($element));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -81,6 +113,8 @@ abstract class AbstractCollectionPersister
|
|||
*/
|
||||
abstract protected function _getDeleteRowSql(PersistentCollection $coll);
|
||||
|
||||
abstract protected function _getDeleteRowSqlParameters(PersistentCollection $coll, $element);
|
||||
|
||||
/**
|
||||
* Gets the SQL statement used for updating a row in the collection.
|
||||
*
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information, see
|
||||
* <http://www.phpdoctrine.org>.
|
||||
* <http://www.doctrine-project.org>.
|
||||
*/
|
||||
|
||||
namespace Doctrine\ORM\Persisters;
|
||||
|
|
33
lib/Doctrine/ORM/Persisters/ElementCollectionPersister.php
Normal file
33
lib/Doctrine/ORM/Persisters/ElementCollectionPersister.php
Normal file
|
@ -0,0 +1,33 @@
|
|||
<?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\Persisters;
|
||||
|
||||
/**
|
||||
* Persister for collections of basic elements / value objects.
|
||||
*
|
||||
* @author robo
|
||||
*/
|
||||
class ElementCollectionPersister extends AbstractCollectionPersister
|
||||
{
|
||||
//put your code here
|
||||
}
|
||||
|
|
@ -17,9 +17,28 @@ class ManyToManyPersister extends AbstractCollectionPersister
|
|||
*
|
||||
* @param <type> $coll
|
||||
* @override
|
||||
* @todo Identifier quoting.
|
||||
* @see _getDeleteRowSqlParameters()
|
||||
*/
|
||||
protected function _getDeleteRowSql(PersistentCollection $coll)
|
||||
{
|
||||
$mapping = $coll->getMapping();
|
||||
$joinTable = $mapping->getJoinTable();
|
||||
$columns = array_merge($mapping->getSourceKeyColumns(), $mapping->getTargetKeyColumns());
|
||||
return "DELETE FROM $joinTable WHERE " . implode(' = ?, ', $columns) . ' = ?';
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param <type> $element
|
||||
* @override
|
||||
* @see _getDeleteRowSql()
|
||||
*/
|
||||
protected function _getDeleteRowSqlParameters(PersistentCollection $coll, $element)
|
||||
{
|
||||
$owner = $coll->getOwner();
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,13 @@ use Doctrine\ORM\PersistentCollection;
|
|||
*/
|
||||
class OneToManyPersister extends AbstractCollectionPersister
|
||||
{
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @param <type> $coll
|
||||
* @return <type>
|
||||
* @override
|
||||
*/
|
||||
protected function _getDeleteRowSql(PersistentCollection $coll)
|
||||
{
|
||||
$mapping = $coll->getMapping();
|
||||
|
@ -33,6 +39,18 @@ class OneToManyPersister extends AbstractCollectionPersister
|
|||
return "UPDATE $table SET $setClause WHERE $whereClause";
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @param <type> $element
|
||||
* @return <type>
|
||||
* @override
|
||||
*/
|
||||
protected function _getDeleteRowSqlParameters(PersistentCollection $coll, $element)
|
||||
{
|
||||
return $this->_uow->getEntityIdentifier($element);
|
||||
}
|
||||
|
||||
protected function _getInsertRowSql()
|
||||
{
|
||||
return "UPDATE xxx SET foreign_key = yyy WHERE foreign_key = zzz";
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information, see
|
||||
* <http://www.phpdoctrine.org>.
|
||||
* <http://www.doctrine-project.org>.
|
||||
*/
|
||||
|
||||
namespace Doctrine\ORM;
|
||||
|
@ -584,13 +584,13 @@ class UnitOfWork
|
|||
$oid = spl_object_hash($entity);
|
||||
|
||||
if (isset($this->_dirtyEntities[$oid])) {
|
||||
throw new Doctrine_Exception("Dirty object can't be registered as new.");
|
||||
throw new DoctrineException("Dirty object can't be registered as new.");
|
||||
}
|
||||
if (isset($this->_deletedEntities[$oid])) {
|
||||
throw new Doctrine_Exception("Removed object can't be registered as new.");
|
||||
throw new DoctrineException("Removed object can't be registered as new.");
|
||||
}
|
||||
if (isset($this->_newEntities[$oid])) {
|
||||
throw new Doctrine_Exception("Object already registered as new. Can't register twice.");
|
||||
throw new DoctrineException("Object already registered as new. Can't register twice.");
|
||||
}
|
||||
|
||||
$this->_newEntities[$oid] = $entity;
|
||||
|
@ -968,8 +968,7 @@ class UnitOfWork
|
|||
$this->registerNew($entity);
|
||||
break;
|
||||
case self::STATE_DETACHED:
|
||||
//exception?
|
||||
throw new Doctrine_Exception("Behavior of save() for a detached entity "
|
||||
throw new DoctrineException("Behavior of save() for a detached entity "
|
||||
. "is not yet defined.");
|
||||
case self::STATE_DELETED:
|
||||
// entity becomes managed again
|
||||
|
@ -983,7 +982,7 @@ class UnitOfWork
|
|||
break;
|
||||
default:
|
||||
//TODO: throw UnitOfWorkException::invalidEntityState()
|
||||
throw new Doctrine_Exception("Encountered invalid entity state.");
|
||||
throw new DoctrineException("Encountered invalid entity state.");
|
||||
}
|
||||
$this->_cascadeSave($entity, $visited, $insertNow);
|
||||
}
|
||||
|
|
|
@ -10,7 +10,8 @@ namespace Doctrine\Tests\Models\CMS;
|
|||
* Description of CmsAddress
|
||||
*
|
||||
* @author robo
|
||||
* @DoctrineEntity(tableName="cms_addresses")
|
||||
* @DoctrineEntity
|
||||
* @DoctrineTable(name="cms_addresses")
|
||||
*/
|
||||
class CmsAddress
|
||||
{
|
||||
|
@ -33,9 +34,8 @@ class CmsAddress
|
|||
*/
|
||||
public $city;
|
||||
/**
|
||||
* @DoctrineOneToOne(
|
||||
targetEntity="Doctrine\Tests\Models\CMS\CmsUser",
|
||||
joinColumns={"user_id" = "id"})
|
||||
* @DoctrineOneToOne(targetEntity="CmsUser")
|
||||
* @DoctrineJoinColumn(name="user_id", referencedColumnName="id")
|
||||
*/
|
||||
public $user;
|
||||
}
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
namespace Doctrine\Tests\Models\CMS;
|
||||
|
||||
/**
|
||||
* @DoctrineEntity(tableName="cms_articles")
|
||||
* @DoctrineEntity
|
||||
* @DoctrineTable(name="cms_articles")
|
||||
*/
|
||||
class CmsArticle
|
||||
{
|
||||
|
@ -22,12 +23,12 @@ class CmsArticle
|
|||
*/
|
||||
public $text;
|
||||
/**
|
||||
* @DoctrineManyToOne(targetEntity="Doctrine\Tests\Models\CMS\CmsUser",
|
||||
joinColumns={"user_id" = "id"})
|
||||
* @DoctrineManyToOne(targetEntity="CmsUser")
|
||||
* @DoctrineJoinColumn(name="user_id", referencedColumnName="id")
|
||||
*/
|
||||
public $user;
|
||||
/**
|
||||
* @DoctrineOneToMany(targetEntity="Doctrine\Tests\Models\CMS\CmsComment", mappedBy="article")
|
||||
* @DoctrineOneToMany(targetEntity="CmsComment", mappedBy="article")
|
||||
*/
|
||||
public $comments;
|
||||
}
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
namespace Doctrine\Tests\Models\CMS;
|
||||
|
||||
/**
|
||||
* @DoctrineEntity(tableName="cms_comments")
|
||||
* @DoctrineEntity
|
||||
* @DoctrineTable(name="cms_comments")
|
||||
*/
|
||||
class CmsComment
|
||||
{
|
||||
|
@ -22,8 +23,8 @@ class CmsComment
|
|||
*/
|
||||
public $text;
|
||||
/**
|
||||
* @DoctrineManyToOne(targetEntity="Doctrine\Tests\Models\CMS\CmsArticle",
|
||||
joinColumns={"article_id" = "id"})
|
||||
* @DoctrineManyToOne(targetEntity="CmsArticle")
|
||||
* @DoctrineJoinColumn(name="article_id", referencedColumnName="id")
|
||||
*/
|
||||
public $article;
|
||||
}
|
||||
|
|
33
tests/Doctrine/Tests/Models/CMS/CmsGroup.php
Normal file
33
tests/Doctrine/Tests/Models/CMS/CmsGroup.php
Normal file
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
|
||||
namespace Doctrine\Tests\Models\CMS;
|
||||
|
||||
/**
|
||||
* Description of CmsGroup
|
||||
*
|
||||
* @author robo
|
||||
* @DoctrineEntity
|
||||
* @DoctrineTable(name="cms_groups")
|
||||
*/
|
||||
class CmsGroup
|
||||
{
|
||||
/**
|
||||
* @DoctrineId
|
||||
* @DoctrineColumn(type="integer")
|
||||
* @DoctrineIdGenerator("auto")
|
||||
*/
|
||||
public $id;
|
||||
/**
|
||||
* @DoctrineColumn(type="varchar", length=50)
|
||||
*/
|
||||
public $name;
|
||||
/**
|
||||
* @DoctrineManyToMany(targetEntity="CmsUser", mappedBy="groups")
|
||||
*/
|
||||
public $users;
|
||||
}
|
||||
|
|
@ -3,7 +3,8 @@
|
|||
namespace Doctrine\Tests\Models\CMS;
|
||||
|
||||
/**
|
||||
* @DoctrineEntity(tableName="cms_phonenumbers")
|
||||
* @DoctrineEntity
|
||||
* @DoctrineTable(name="cms_phonenumbers")
|
||||
*/
|
||||
class CmsPhonenumber
|
||||
{
|
||||
|
@ -13,8 +14,8 @@ class CmsPhonenumber
|
|||
*/
|
||||
public $phonenumber;
|
||||
/**
|
||||
* @DoctrineManyToOne(targetEntity="Doctrine\Tests\Models\CMS\CmsUser",
|
||||
joinColumns={"user_id" = "id"})
|
||||
* @DoctrineManyToOne(targetEntity="CmsUser")
|
||||
* @DoctrineJoinColumn(name="user_id", referencedColumnName="id")
|
||||
*/
|
||||
public $user;
|
||||
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
namespace Doctrine\Tests\Models\CMS;
|
||||
|
||||
/**
|
||||
* @DoctrineEntity(tableName="cms_users")
|
||||
* @DoctrineEntity
|
||||
* @DoctrineTable(name="cms_users")
|
||||
*/
|
||||
class CmsUser
|
||||
{
|
||||
|
@ -26,19 +27,24 @@ class CmsUser
|
|||
*/
|
||||
public $name;
|
||||
/**
|
||||
* @DoctrineOneToMany(targetEntity="Doctrine\Tests\Models\CMS\CmsPhonenumber",
|
||||
mappedBy="user", cascade={"save", "delete"})
|
||||
* @DoctrineOneToMany(targetEntity="CmsPhonenumber", mappedBy="user", cascade={"save", "delete"})
|
||||
*/
|
||||
public $phonenumbers;
|
||||
/**
|
||||
* @DoctrineOneToMany(targetEntity="Doctrine\Tests\Models\CMS\CmsArticle", mappedBy="user")
|
||||
* @DoctrineOneToMany(targetEntity="CmsArticle", mappedBy="user")
|
||||
*/
|
||||
public $articles;
|
||||
/**
|
||||
* @DoctrineOneToOne(targetEntity="Doctrine\Tests\Models\CMS\CmsAddress", mappedBy="user",
|
||||
cascade={"save"})
|
||||
* @DoctrineOneToOne(targetEntity="CmsAddress", mappedBy="user", cascade={"save"})
|
||||
*/
|
||||
public $address;
|
||||
/**
|
||||
* @DoctrineManyToMany(targetEntity="CmsGroup")
|
||||
* @DoctrineJoinTable(name="cms_users_groups",
|
||||
joinColumns={{"name"="user_id", "referencedColumnName"="id"}},
|
||||
inverseJoinColumns={{"name"="group_id", "referencedColumnName"="id"}})
|
||||
*/
|
||||
public $groups;
|
||||
|
||||
/**
|
||||
* Adds a phonenumber to the user.
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
namespace Doctrine\Tests\Models\Forum;
|
||||
|
||||
/**
|
||||
* @DoctrineEntity(tableName="forum_avatars")
|
||||
* @DoctrineEntity
|
||||
* @DoctrineTable(name="forum_avatars")
|
||||
*/
|
||||
class ForumAvatar
|
||||
{
|
||||
|
|
|
@ -7,6 +7,7 @@ namespace Doctrine\Tests\Models\Forum;
|
|||
*
|
||||
* @author robo
|
||||
* @DoctrineEntity
|
||||
* @DoctrineTable(name="forum_boards")
|
||||
*/
|
||||
class ForumBoard
|
||||
{
|
||||
|
@ -20,8 +21,8 @@ class ForumBoard
|
|||
*/
|
||||
public $position;
|
||||
/**
|
||||
* @DoctrineManyToOne(targetEntity="Doctrine\Tests\Models\Forum\ForumCategory",
|
||||
joinColumns={"category_id" = "id"})
|
||||
* @DoctrineManyToOne(targetEntity="ForumCategory")
|
||||
* @DoctrineJoinColumn(name="category_id", referencedColumnName="id")
|
||||
*/
|
||||
public $category;
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ namespace Doctrine\Tests\Models\Forum;
|
|||
|
||||
/**
|
||||
* @DoctrineEntity
|
||||
* @DoctrineTable(name="forum_categories")
|
||||
*/
|
||||
class ForumCategory
|
||||
{
|
||||
|
@ -21,7 +22,7 @@ class ForumCategory
|
|||
*/
|
||||
public $name;
|
||||
/**
|
||||
* @DoctrineOneToMany(targetEntity="Doctrine\Tests\Models\Forum\ForumBoard", mappedBy="category")
|
||||
* @DoctrineOneToMany(targetEntity="ForumBoard", mappedBy="category")
|
||||
*/
|
||||
public $boards;
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ namespace Doctrine\Tests\Models\Forum;
|
|||
|
||||
/**
|
||||
* @DoctrineEntity
|
||||
* @DoctrineTable(name="forum_entries")
|
||||
*/
|
||||
class ForumEntry
|
||||
{
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
namespace Doctrine\Tests\Models\Forum;
|
||||
|
||||
/**
|
||||
* @DoctrineEntity(tableName="forum_users")
|
||||
* @DoctrineEntity
|
||||
* @DoctrineTable(name="forum_users")
|
||||
* @DoctrineInheritanceType("joined")
|
||||
* @DoctrineDiscriminatorColumn(name="dtype", type="varchar", length=20)
|
||||
* @DoctrineDiscriminatorMap({
|
||||
|
@ -24,10 +25,8 @@ class ForumUser
|
|||
*/
|
||||
public $username;
|
||||
/**
|
||||
* @DoctrineOneToOne(
|
||||
targetEntity="Doctrine\Tests\Models\Forum\ForumAvatar",
|
||||
joinColumns={"avatar_id" = "id"},
|
||||
cascade={"save"})
|
||||
* @DoctrineOneToOne(targetEntity="ForumAvatar", cascade={"save"})
|
||||
* @DoctrineJoinColumn(name="avatar_id", referencedColumnName="id")
|
||||
*/
|
||||
public $avatar;
|
||||
}
|
|
@ -11,7 +11,7 @@ class OneToOneMappingTest extends \Doctrine\Tests\OrmTestCase
|
|||
$owningSideMapping = array(
|
||||
'fieldName' => 'address',
|
||||
'targetEntity' => 'Address',
|
||||
'joinColumns' => array('address_id' => 'id'),
|
||||
'joinColumns' => array(array('name' => 'address_id', 'referencedColumnName' => 'id')),
|
||||
'sourceEntity' => 'Person', // This is normally filled by ClassMetadata
|
||||
);
|
||||
|
||||
|
|
|
@ -44,7 +44,6 @@ class ClassMetadataTest extends \Doctrine\Tests\OrmTestCase
|
|||
$this->assertEquals(1, count($cm->getAssociationMappings()));
|
||||
$oneOneMapping = $cm->getAssociationMapping('phonenumbers');
|
||||
$this->assertEquals('phonenumbers', $oneOneMapping->getSourceFieldName());
|
||||
$this->assertEquals('Bar', $oneOneMapping->getTargetEntityName());
|
||||
$this->assertEquals('Doctrine\Tests\Models\CMS\Bar', $oneOneMapping->getTargetEntityName());
|
||||
}
|
||||
|
||||
}
|
Loading…
Add table
Reference in a new issue