refactorings. made basic one-one, one-many joins work.
This commit is contained in:
parent
efca79412d
commit
0f8e9e0ba9
@ -159,6 +159,7 @@ class Doctrine_Association implements Serializable
|
||||
$this->_customAccessor = isset($mapping['accessor']) ? $mapping['accessor'] : null;
|
||||
$this->_customMutator = isset($mapping['mutator']) ? $mapping['mutator'] : null;
|
||||
$this->_isOptional = isset($mapping['isOptional']) ? (bool)$mapping['isOptional'] : true;
|
||||
$this->_cascades = isset($mapping['cascade']) ? (array)$mapping['cascade'] : array();
|
||||
|
||||
return $mapping;
|
||||
}
|
||||
|
@ -1,28 +1,94 @@
|
||||
<?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.phpdoctrine.org>.
|
||||
*/
|
||||
|
||||
#namespace Doctrine::ORM::Mappings;
|
||||
|
||||
/**
|
||||
* Represents a one-to-many mapping.
|
||||
*
|
||||
* NOTE: One-to-many mappings can currently not be uni-directional (one -> many).
|
||||
* They must either be bidirectional (one <-> many) or unidirectional (many -> one).
|
||||
* In other words, the many-side MUST be the owning side and the one-side MUST be
|
||||
* the inverse side.
|
||||
*
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
* @since 2.0
|
||||
* @todo Rename to OneToManyMapping
|
||||
*/
|
||||
class Doctrine_Association_OneToMany extends Doctrine_Association
|
||||
{
|
||||
/** The target foreign key columns that reference the sourceKeyColumns. */
|
||||
protected $_targetForeignKeyColumns;
|
||||
/* NOTE: Currently not used because uni-directional one-many not supported atm. */
|
||||
//protected $_targetForeignKeyColumns;
|
||||
|
||||
/** The (typically primary) source key columns that are referenced by the targetForeignKeyColumns. */
|
||||
protected $_sourceKeyColumns;
|
||||
/* NOTE: Currently not used because uni-directional one-many not supported atm. */
|
||||
//protected $_sourceKeyColumns;
|
||||
|
||||
/** This maps the target foreign key columns to the corresponding (primary) source key columns. */
|
||||
protected $_targetForeignKeysToSourceKeys;
|
||||
/* NOTE: Currently not used because uni-directional one-many not supported atm. */
|
||||
//protected $_targetForeignKeysToSourceKeys;
|
||||
|
||||
/** This maps the (primary) source key columns to the corresponding target foreign key columns. */
|
||||
protected $_sourceKeysToTargetForeignKeys;
|
||||
/* NOTE: Currently not used because uni-directional one-many not supported atm. */
|
||||
//protected $_sourceKeysToTargetForeignKeys;
|
||||
|
||||
/** Whether to delete orphaned elements (removed from the collection) */
|
||||
protected $_deleteOrphans = false;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* Creates a new OneToManyMapping.
|
||||
*
|
||||
* @param array $mapping The mapping info.
|
||||
*/
|
||||
public function __construct(array $mapping)
|
||||
{
|
||||
parent::__construct($mapping);
|
||||
// one side in one-many can currently never be owning side, we may support that later
|
||||
$this->_isOwningSide = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether orphaned elements (removed from the collection) should be deleted.
|
||||
*
|
||||
* @return boolean TRUE if orphaned elements should be deleted, FALSE otherwise.
|
||||
*/
|
||||
public function shouldDeleteOrphans()
|
||||
{
|
||||
return $this->_deleteOrphans;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the association is one-to-many.
|
||||
*
|
||||
* @return boolean TRUE if the association is one-to-many, FALSE otherwise.
|
||||
* @override
|
||||
*/
|
||||
public function isOneToMany()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
?>
|
@ -83,9 +83,7 @@ class Doctrine_Cache_Apc extends Doctrine_Cache_Driver
|
||||
*/
|
||||
public function save($id, $data, $lifeTime = false)
|
||||
{
|
||||
$lifeTime = $this->getLifeTime($lifeTime);
|
||||
|
||||
return (bool) apc_store($id, array($data, time()), $lifeTime);
|
||||
return (bool) apc_store($id, $data, $lifeTime);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -18,7 +18,7 @@
|
||||
* and is licensed under the LGPL. For more information, see
|
||||
* <http://www.phpdoctrine.org>.
|
||||
*/
|
||||
Doctrine::autoload('Doctrine_Cache_Driver');
|
||||
|
||||
/**
|
||||
* Doctrine_Cache_Memcache
|
||||
*
|
||||
@ -80,15 +80,7 @@ class Doctrine_Cache_Memcache extends Doctrine_Cache_Driver
|
||||
*/
|
||||
public function fetch($id, $testCacheValidity = true)
|
||||
{
|
||||
$tmp = $this->_memcache->get($id);
|
||||
|
||||
if (is_array($tmp)) {
|
||||
return $tmp[0];
|
||||
} else if (is_string($tmp)) {
|
||||
return $tmp;
|
||||
}
|
||||
|
||||
return false;
|
||||
return $this->_memcache->get($id);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -18,7 +18,7 @@
|
||||
* and is licensed under the LGPL. For more information, see
|
||||
* <http://www.phpdoctrine.org>.
|
||||
*/
|
||||
Doctrine::autoload('Doctrine_Cache_Driver');
|
||||
|
||||
/**
|
||||
* Doctrine_Cache_Xcache
|
||||
*
|
||||
|
@ -25,26 +25,65 @@
|
||||
|
||||
/**
|
||||
* A <tt>ClassMetadata</tt> instance holds all the information (metadata) of an entity and
|
||||
* it's associations and how they're mapped to the relational database.
|
||||
* it's associations and how they're mapped to a relational database.
|
||||
* It is the backbone of Doctrine's metadata mapping.
|
||||
*
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
* @since 2.0
|
||||
* @todo Rename to ClassDescriptor?
|
||||
* @todo Rename to ClassDescriptor.
|
||||
*/
|
||||
class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable
|
||||
{
|
||||
/* The inheritance mapping types */
|
||||
/**
|
||||
* NONE means the class does not participate in an inheritance hierarchy
|
||||
* and therefore does not need an inheritance mapping type.
|
||||
*/
|
||||
const INHERITANCE_TYPE_NONE = 'none';
|
||||
/**
|
||||
* JOINED means the class will be persisted according to the rules of
|
||||
* <tt>Class Table Inheritance</tt>.
|
||||
*/
|
||||
const INHERITANCE_TYPE_JOINED = 'joined';
|
||||
/**
|
||||
* SINGLE_TABLE means the class will be persisted according to the rules of
|
||||
* <tt>Single Table Inheritance</tt>.
|
||||
*/
|
||||
const INHERITANCE_TYPE_SINGLE_TABLE = 'singleTable';
|
||||
/**
|
||||
* TABLE_PER_CLASS means the class will be persisted according to the rules
|
||||
* of <tt>Concrete Table Inheritance</tt>.
|
||||
*/
|
||||
const INHERITANCE_TYPE_TABLE_PER_CLASS = 'tablePerClass';
|
||||
|
||||
/* The Id generator types. TODO: belongs more in a DBAL class */
|
||||
/* The Id generator types. */
|
||||
/**
|
||||
* AUTO means the generator type will depend on what the used platform prefers.
|
||||
* Offers full portability.
|
||||
*/
|
||||
const GENERATOR_TYPE_AUTO = 'auto';
|
||||
/**
|
||||
* SEQUENCE means a separate sequence object will be used. Platforms that do
|
||||
* not have native sequence support may emulate it. Full portability is currently
|
||||
* not guaranteed.
|
||||
*/
|
||||
const GENERATOR_TYPE_SEQUENCE = 'sequence';
|
||||
/**
|
||||
* TABLE means a separate table is used for id generation.
|
||||
* Offers full portability.
|
||||
*/
|
||||
const GENERATOR_TYPE_TABLE = 'table';
|
||||
/**
|
||||
* IDENTITY means an identity column is used for id generation. The database
|
||||
* will fill in the id column on insertion. Platforms that do not support
|
||||
* native identity columns may emulate them. Full portability is currently
|
||||
* not guaranteed.
|
||||
*/
|
||||
const GENERATOR_TYPE_IDENTITY = 'identity';
|
||||
/**
|
||||
* NONE means the class does not have a generated id. That means the class
|
||||
* must have a natural id.
|
||||
*/
|
||||
const GENERATOR_TYPE_NONE = 'none';
|
||||
|
||||
/* The Entity types */
|
||||
@ -53,7 +92,7 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable
|
||||
*/
|
||||
const ENTITY_TYPE_REGULAR = 'regular';
|
||||
/**
|
||||
* A transient entity is ignored by Doctrine.
|
||||
* A transient entity is ignored by Doctrine (so ... it's not an entity really).
|
||||
*/
|
||||
const ENTITY_TYPE_TRANSIENT = 'transient';
|
||||
/**
|
||||
@ -216,14 +255,6 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable
|
||||
*/
|
||||
protected $_lcColumnToFieldNames = array();
|
||||
|
||||
/**
|
||||
* Relation parser object. Manages the relations for the class.
|
||||
*
|
||||
* @var Doctrine_Relation_Parser $_parser
|
||||
* @todo Remove.
|
||||
*/
|
||||
protected $_parser;
|
||||
|
||||
/**
|
||||
* Inheritance options.
|
||||
*/
|
||||
@ -315,8 +346,6 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable
|
||||
$this->_entityName = $entityName;
|
||||
$this->_rootEntityName = $entityName;
|
||||
$this->_em = $em;
|
||||
|
||||
$this->_parser = new Doctrine_Relation_Parser($this);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -503,6 +532,11 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable
|
||||
return $this->_fieldMappings[$fieldName];
|
||||
}
|
||||
|
||||
public function addFieldMapping($fieldName, array $mapping)
|
||||
{
|
||||
$this->_fieldMappings[$fieldName] = $mapping;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the mapping of an association.
|
||||
*
|
||||
@ -519,6 +553,11 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable
|
||||
return $this->_associationMappings[$fieldName];
|
||||
}
|
||||
|
||||
public function addAssociationMapping($fieldName, Doctrine_Association $assoc)
|
||||
{
|
||||
$this->_associationMappings[$fieldName] = $assoc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all association mappings of the class.
|
||||
*
|
||||
@ -879,6 +918,21 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable
|
||||
return $this->_generatorType != self::GENERATOR_TYPE_NONE;
|
||||
}
|
||||
|
||||
public function isInheritanceTypeJoined()
|
||||
{
|
||||
return $this->_inheritanceType == self::INHERITANCE_TYPE_JOINED;
|
||||
}
|
||||
|
||||
public function isInheritanceTypeSingleTable()
|
||||
{
|
||||
return $this->_inheritanceType == self::INHERITANCE_TYPE_SINGLE_TABLE;
|
||||
}
|
||||
|
||||
public function isInheritanceTypeTablePerClass()
|
||||
{
|
||||
return $this->_inheritanceType == self::INHERITANCE_TYPE_TABLE_PER_CLASS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the class uses an identity column for the Id generation.
|
||||
*
|
||||
@ -1008,6 +1062,29 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable
|
||||
{
|
||||
return $this->_subClasses;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of the class in the entity hierarchy that owns the field with
|
||||
* the given name. The owning class is the one that defines the field.
|
||||
*
|
||||
* @param string $fieldName
|
||||
* @return string
|
||||
* @todo Consider using 'inherited' => 'ClassName' to make the lookup simpler.
|
||||
*/
|
||||
public function getOwningClass($fieldName)
|
||||
{
|
||||
if ($this->_inheritanceType == self::INHERITANCE_TYPE_NONE) {
|
||||
return $this;
|
||||
} else {
|
||||
foreach ($this->_parentClasses as $parentClass) {
|
||||
if ( ! $this->_em->getClassMetadata($parentClass)->isInheritedField($fieldName)) {
|
||||
return $parentClass;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
throw new Doctrine_ClassMetadata_Exception("Unable to find defining class of field '$fieldName'.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the class has any persistent subclasses.
|
||||
@ -1408,9 +1485,9 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a one-to-one association mapping.
|
||||
* Adds a one-to-one mapping.
|
||||
*
|
||||
* @todo Implementation.
|
||||
* @param array $mapping The mapping.
|
||||
*/
|
||||
public function mapOneToOne(array $mapping)
|
||||
{
|
||||
@ -1425,7 +1502,9 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo Implementation.
|
||||
* Adds a one-to-many mapping.
|
||||
*
|
||||
* @param array $mapping The mapping.
|
||||
*/
|
||||
public function mapOneToMany(array $mapping)
|
||||
{
|
||||
@ -1440,11 +1519,14 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo Implementation.
|
||||
* Adds a many-to-one mapping.
|
||||
*
|
||||
* @param array $mapping The mapping.
|
||||
*/
|
||||
public function mapManyToOne(array $mapping)
|
||||
{
|
||||
|
||||
// A many-to-one mapping is simply a one-one backreference
|
||||
$this->mapOneToOne($mapping);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1585,6 +1667,8 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable
|
||||
/**
|
||||
* Completes the identifier mapping of the class.
|
||||
* NOTE: Should only be called by the ClassMetadataFactory!
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function completeIdentifierMapping()
|
||||
{
|
||||
@ -1603,7 +1687,7 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable
|
||||
/**
|
||||
* @todo Implementation. Immutable entities can not be updated or deleted once
|
||||
* they are created. This means the entity can only be modified as long as it's
|
||||
* in transient state (TCLEAN, TDIRTY).
|
||||
* new (STATE_NEW).
|
||||
*/
|
||||
public function isImmutable()
|
||||
{
|
||||
@ -1634,121 +1718,11 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable
|
||||
}
|
||||
}
|
||||
|
||||
/* The following stuff needs to be touched for the association mapping rewrite */
|
||||
|
||||
/**
|
||||
* hasOne
|
||||
* binds One-to-One aggregate relation
|
||||
*
|
||||
* @param string $componentName the name of the related component
|
||||
* @param string $options relation options
|
||||
* @see Doctrine_Relation::_$definition
|
||||
* @return Doctrine_Entity this object
|
||||
* @deprecated
|
||||
*/
|
||||
public function hasOne()
|
||||
{
|
||||
$this->bind(func_get_args(), Doctrine_Relation::ONE_AGGREGATE);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* hasMany
|
||||
* binds One-to-Many / Many-to-Many aggregate relation
|
||||
*
|
||||
* @param string $componentName the name of the related component
|
||||
* @param string $options relation options
|
||||
* @see Doctrine_Relation::_$definition
|
||||
* @return Doctrine_Entity this object
|
||||
* @deprecated
|
||||
*/
|
||||
public function hasMany()
|
||||
{
|
||||
$this->bind(func_get_args(), Doctrine_Relation::MANY_AGGREGATE);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
public function bindRelation($args, $type)
|
||||
{
|
||||
return $this->bind($args, $type);
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo Relation mapping rewrite.
|
||||
* @deprecated
|
||||
*/
|
||||
public function bind($args, $type)
|
||||
{
|
||||
$options = array();
|
||||
$options['type'] = $type;
|
||||
|
||||
if ( ! isset($args[1])) {
|
||||
$args[1] = array();
|
||||
}
|
||||
if ( ! is_array($args[1])) {
|
||||
try {
|
||||
throw new Exception();
|
||||
} catch (Exception $e) {
|
||||
echo $e->getTraceAsString();
|
||||
}
|
||||
}
|
||||
$options = array_merge($args[1], $options);
|
||||
$this->_parser->bind($args[0], $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* hasRelation
|
||||
*
|
||||
* @param string $alias the relation to check if exists
|
||||
* @return boolean true if the relation exists otherwise false
|
||||
* @deprecated
|
||||
*/
|
||||
public function hasRelation($alias)
|
||||
{
|
||||
return $this->_parser->hasRelation($alias);
|
||||
}
|
||||
|
||||
public function hasAssociation($fieldName)
|
||||
{
|
||||
return isset($this->_associationMappings[$fieldName]);
|
||||
}
|
||||
|
||||
/**
|
||||
* getRelation
|
||||
*
|
||||
* @param string $alias relation alias
|
||||
* @deprecated
|
||||
*/
|
||||
public function getRelation($alias, $recursive = true)
|
||||
{
|
||||
return $this->_parser->getRelation($alias, $recursive);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
public function getRelationParser()
|
||||
{
|
||||
return $this->_parser;
|
||||
}
|
||||
|
||||
/**
|
||||
* getRelations
|
||||
* returns an array containing all relation objects
|
||||
*
|
||||
* @return array an array of Doctrine_Relation objects
|
||||
* @deprecated
|
||||
*/
|
||||
public function getRelations()
|
||||
{
|
||||
return $this->_parser->getRelations();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
@ -31,7 +31,7 @@
|
||||
* @version $Revision$
|
||||
* @link www.phpdoctrine.org
|
||||
* @since 2.0
|
||||
* @todo Rename to ClassMetadataFactory.
|
||||
* @todo Rename to ClassDescriptorFactory.
|
||||
*/
|
||||
class Doctrine_ClassMetadata_Factory
|
||||
{
|
||||
@ -114,6 +114,7 @@ class Doctrine_ClassMetadata_Factory
|
||||
// load metadata of subclasses
|
||||
// -> child1 -> child2 -> $name
|
||||
|
||||
// Move down the hierarchy of parent classes, starting from the topmost class
|
||||
$parent = $class;
|
||||
foreach ($parentClasses as $subclassName) {
|
||||
$subClass = new Doctrine_ClassMetadata($subclassName, $this->_em);
|
||||
@ -121,7 +122,7 @@ class Doctrine_ClassMetadata_Factory
|
||||
$this->_addInheritedFields($subClass, $parent);
|
||||
$this->_addInheritedRelations($subClass, $parent);
|
||||
$this->_loadMetadata($subClass, $subclassName);
|
||||
if ($parent->getInheritanceType() == Doctrine::INHERITANCE_TYPE_SINGLE_TABLE) {
|
||||
if ($parent->isInheritanceTypeSingleTable()) {
|
||||
$subClass->setTableName($parent->getTableName());
|
||||
}
|
||||
$classes[$subclassName] = $subClass;
|
||||
@ -132,15 +133,17 @@ class Doctrine_ClassMetadata_Factory
|
||||
/**
|
||||
* Adds inherited fields to the subclass mapping.
|
||||
*
|
||||
* @param unknown_type $subClass
|
||||
* @param unknown_type $parentClass
|
||||
* @param Doctrine::ORM::Mapping::ClassMetadata $subClass
|
||||
* @param Doctrine::ORM::Mapping::ClassMetadata $parentClass
|
||||
* @return void
|
||||
*/
|
||||
protected function _addInheritedFields($subClass, $parentClass)
|
||||
{
|
||||
foreach ($parentClass->getFieldMappings() as $fieldName => $mapping) {
|
||||
$fullName = "$name as " . $parentClass->getFieldName($name);
|
||||
$mapping['inherited'] = true;
|
||||
$subClass->mapField($mapping);
|
||||
if ( ! isset($mapping['inherited'])) {
|
||||
$mapping['inherited'] = $parentClass->getClassName();
|
||||
}
|
||||
$subClass->addFieldMapping($fieldName, $mapping);
|
||||
}
|
||||
}
|
||||
|
||||
@ -152,8 +155,8 @@ class Doctrine_ClassMetadata_Factory
|
||||
*/
|
||||
protected function _addInheritedRelations($subClass, $parentClass)
|
||||
{
|
||||
foreach ($parentClass->getRelationParser()->getRelationDefinitions() as $name => $definition) {
|
||||
$subClass->getRelationParser()->addRelationDefinition($name, $definition);
|
||||
foreach ($parentClass->getAssociationMappings() as $fieldName => $mapping) {
|
||||
$subClass->addAssociationMapping($name, $mapping);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -83,7 +83,7 @@ class Doctrine_Collection implements Countable, IteratorAggregate, Serializable,
|
||||
*
|
||||
* @var Doctrine::ORM::Mapping::AssociationMapping
|
||||
*/
|
||||
protected $_associationMapping;
|
||||
protected $_association;
|
||||
|
||||
/**
|
||||
* The name of the column that is used for collection key mapping.
|
||||
@ -99,8 +99,6 @@ class Doctrine_Collection implements Countable, IteratorAggregate, Serializable,
|
||||
*/
|
||||
//protected static $null;
|
||||
|
||||
protected $_mapping;
|
||||
|
||||
/**
|
||||
* The EntityManager.
|
||||
*
|
||||
@ -261,10 +259,10 @@ class Doctrine_Collection implements Countable, IteratorAggregate, Serializable,
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setReference(Doctrine_Entity $entity, $relation)
|
||||
public function setReference(Doctrine_Entity $entity, Doctrine_Association $relation)
|
||||
{
|
||||
$this->_owner = $entity;
|
||||
//$this->relation = $relation;
|
||||
$this->_association = $relation;
|
||||
|
||||
/*if ($relation instanceof Doctrine_Relation_ForeignKey ||
|
||||
$relation instanceof Doctrine_Relation_LocalKey) {
|
||||
@ -304,6 +302,12 @@ class Doctrine_Collection implements Countable, IteratorAggregate, Serializable,
|
||||
$removed = $this->_data[$key];
|
||||
unset($this->_data[$key]);
|
||||
//TODO: Register collection as dirty with the UoW if necessary
|
||||
//$this->_em->getUnitOfWork()->scheduleCollectionUpdate($this);
|
||||
//TODO: delete entity if shouldDeleteOrphans
|
||||
/*if ($this->_association->isOneToMany() && $this->_association->shouldDeleteOrphans()) {
|
||||
$this->_em->delete($removed);
|
||||
}*/
|
||||
|
||||
return $removed;
|
||||
}
|
||||
|
||||
@ -323,7 +327,7 @@ class Doctrine_Collection implements Countable, IteratorAggregate, Serializable,
|
||||
*
|
||||
* @param string $name
|
||||
* @since 1.0
|
||||
* @return void
|
||||
* @return mixed
|
||||
*/
|
||||
public function __unset($key)
|
||||
{
|
||||
@ -508,7 +512,7 @@ class Doctrine_Collection implements Countable, IteratorAggregate, Serializable,
|
||||
throw new Doctrine_Record_Exception('Value variable in set is not an instance of Doctrine_Entity.');
|
||||
}
|
||||
|
||||
// Neither Maps nor Lists allow duplicates, both are Sets
|
||||
// TODO: Really prohibit duplicates?
|
||||
if (in_array($value, $this->_data, true)) {
|
||||
return false;
|
||||
}
|
||||
@ -956,7 +960,7 @@ class Doctrine_Collection implements Countable, IteratorAggregate, Serializable,
|
||||
public function mapElements($lambda) {
|
||||
$result = array();
|
||||
foreach ($this->_data as $key => $entity) {
|
||||
list($key, $value) = $lambda($key, $entity);
|
||||
list($key, $value) = each($lambda($key, $entity));
|
||||
$result[$key] = $value;
|
||||
}
|
||||
return $result;
|
||||
@ -969,14 +973,20 @@ class Doctrine_Collection implements Countable, IteratorAggregate, Serializable,
|
||||
*/
|
||||
public function clear()
|
||||
{
|
||||
$this->_data = array();
|
||||
//TODO: Register collection as dirty with the UoW if necessary
|
||||
//TODO: If oneToMany() && shouldDeleteOrphan() delete entities
|
||||
/*if ($this->_association->isOneToMany() && $this->_association->shouldDeleteOrphans()) {
|
||||
foreach ($this->_data as $entity) {
|
||||
$this->_em->delete($entity);
|
||||
}
|
||||
}*/
|
||||
$this->_data = array();
|
||||
}
|
||||
|
||||
private function _changed()
|
||||
{
|
||||
/*if ( ! $this->_em->getUnitOfWork()->isCollectionScheduledForUpdate($this)) {
|
||||
$this->_em->getUnitOfWork()->scheduleCollectionUpdate($this);
|
||||
}*/
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
@ -932,7 +932,7 @@ abstract class Doctrine_Connection
|
||||
*/
|
||||
public function lastInsertId($table = null, $field = null)
|
||||
{
|
||||
return $this->sequence->lastInsertId($table, $field);
|
||||
return $this->getSequenceManager()->lastInsertId($table, $field);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -160,6 +160,8 @@ class Doctrine_Connection_UnitOfWork
|
||||
|
||||
foreach ($commitOrder as $class) {
|
||||
$this->_executeInserts($class);
|
||||
}
|
||||
foreach ($commitOrder as $class) {
|
||||
$this->_executeUpdates($class);
|
||||
}
|
||||
|
||||
@ -268,7 +270,7 @@ class Doctrine_Connection_UnitOfWork
|
||||
}
|
||||
// add dependency
|
||||
$otherNode = $this->_commitOrderCalculator->getNodeForKey($targetClassName);
|
||||
$node->before($otherNode);
|
||||
$otherNode->before($node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -27,7 +27,8 @@
|
||||
* @author Lukas Smith <smith@pooteeweet.org> (PEAR MDB2 library)
|
||||
* @version $Revision$
|
||||
* @link www.phpdoctrine.org
|
||||
* @since 1.0
|
||||
* @since 1.0
|
||||
* @todo Remove.
|
||||
*/
|
||||
class Doctrine_DataDict_Informix extends Doctrine_DataDict
|
||||
{
|
||||
|
@ -227,6 +227,26 @@ class Doctrine_DatabasePlatform_MySqlPlatform extends Doctrine_DatabasePlatform
|
||||
return 'CONCAT(' . join(', ', (array) $args) . ')';
|
||||
}
|
||||
|
||||
/**
|
||||
* @TEST
|
||||
*/
|
||||
public function getVarcharDeclaration(array $field)
|
||||
{
|
||||
if ( ! isset($field['length'])) {
|
||||
if (array_key_exists('default', $field)) {
|
||||
$field['length'] = $this->getVarcharMaxLength();
|
||||
} else {
|
||||
$field['length'] = false;
|
||||
}
|
||||
}
|
||||
|
||||
$length = ($field['length'] <= $this->getVarcharMaxLength()) ? $field['length'] : false;
|
||||
$fixed = (isset($field['fixed'])) ? $field['fixed'] : false;
|
||||
|
||||
return $fixed ? ($length ? 'CHAR(' . $length . ')' : 'CHAR(255)')
|
||||
: ($length ? 'VARCHAR(' . $length . ')' : 'TEXT');
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare an text type
|
||||
* field to be used in statements like CREATE TABLE.
|
||||
|
@ -143,6 +143,14 @@ abstract class Doctrine_Entity implements ArrayAccess, Serializable
|
||||
* @var integer
|
||||
*/
|
||||
private $_state;
|
||||
|
||||
/**
|
||||
* Name => Value map of join columns.
|
||||
*
|
||||
* @var array
|
||||
* @todo Not yet clear if needed.
|
||||
*/
|
||||
//private $_joinColumns = array();
|
||||
|
||||
/**
|
||||
* The changes that happened to fields of the entity.
|
||||
@ -189,14 +197,6 @@ abstract class Doctrine_Entity implements ArrayAccess, Serializable
|
||||
*/
|
||||
private $_oid;
|
||||
|
||||
/**
|
||||
* Flag that indicates whether the entity is dirty.
|
||||
* (which means it has local changes)
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
//private $_isDirty = false;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* Creates a new Entity instance.
|
||||
@ -444,6 +444,7 @@ abstract class Doctrine_Entity implements ArrayAccess, Serializable
|
||||
$this->_internalSetReference($fieldName, $value);
|
||||
$this->_referenceChangeSet[$fieldName] = array($old => $value);
|
||||
$this->_registerDirty();
|
||||
//TODO: Allow arrays in $value. Wrap them in a collection transparently.
|
||||
if ($old instanceof Doctrine_Collection) {
|
||||
$this->_em->getUnitOfWork()->scheduleCollectionDeletion($old);
|
||||
}
|
||||
@ -524,67 +525,6 @@ abstract class Doctrine_Entity implements ArrayAccess, Serializable
|
||||
*
|
||||
* @param string $fieldName
|
||||
* @param mixed $value
|
||||
* @todo Refactor.
|
||||
*/
|
||||
final public function _internalSetReference_OLD($name, $value)
|
||||
{
|
||||
if ($value === Doctrine_Null::$INSTANCE) {
|
||||
$this->_references[$name] = $value;
|
||||
return;
|
||||
}
|
||||
|
||||
$rel = $this->_class->getRelation($name);
|
||||
|
||||
// one-to-many or one-to-one relation
|
||||
if ($rel instanceof Doctrine_Relation_ForeignKey ||
|
||||
$rel instanceof Doctrine_Relation_LocalKey) {
|
||||
if ( ! $rel->isOneToOne()) {
|
||||
// one-to-many relation
|
||||
if ( ! $value instanceof Doctrine_Collection) {
|
||||
throw Doctrine_Entity_Exception::invalidValueForOneToManyReference();
|
||||
}
|
||||
if (isset($this->_references[$name])) {
|
||||
$this->_references[$name]->setData($value->getData());
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
$relatedTable = $value->getTable();
|
||||
$foreignFieldName = $rel->getForeignFieldName();
|
||||
$localFieldName = $rel->getLocalFieldName();
|
||||
|
||||
// one-to-one relation found
|
||||
if ( ! ($value instanceof Doctrine_Entity)) {
|
||||
throw Doctrine_Entity_Exception::invalidValueForOneToOneReference();
|
||||
}
|
||||
if ($rel instanceof Doctrine_Relation_LocalKey) {
|
||||
$idFieldNames = $value->getTable()->getIdentifier();
|
||||
if ( ! empty($foreignFieldName) && $foreignFieldName != $idFieldNames[0]) {
|
||||
$this->set($localFieldName, $value->_get($foreignFieldName));
|
||||
} else {
|
||||
$this->set($localFieldName, $value);
|
||||
}
|
||||
} else {
|
||||
$value->set($foreignFieldName, $this);
|
||||
}
|
||||
}
|
||||
} else if ($rel instanceof Doctrine_Relation_Association) {
|
||||
if ( ! ($value instanceof Doctrine_Collection)) {
|
||||
throw Doctrine_Entity_Exception::invalidValueForManyToManyReference();
|
||||
}
|
||||
}
|
||||
|
||||
$this->_references[$name] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* INTERNAL:
|
||||
* Sets a reference to another entity or a collection of entities.
|
||||
*
|
||||
* NOTE: Use of this method in userland code is strongly discouraged.
|
||||
*
|
||||
* @param string $fieldName
|
||||
* @param mixed $value
|
||||
* @todo Refactor.
|
||||
*/
|
||||
final public function _internalSetReference($name, $value)
|
||||
{
|
||||
@ -595,31 +535,14 @@ abstract class Doctrine_Entity implements ArrayAccess, Serializable
|
||||
|
||||
$rel = $this->_class->getAssociationMapping($name);
|
||||
|
||||
// one-to-many or one-to-one relation
|
||||
if ($rel->isOneToOne() || $rel->isOneToMany()) {
|
||||
if ( ! $rel->isOneToOne()) {
|
||||
// one-to-many relation
|
||||
if ( ! $value instanceof Doctrine_Collection) {
|
||||
throw Doctrine_Entity_Exception::invalidValueForOneToManyReference();
|
||||
}
|
||||
if (isset($this->_references[$name])) {
|
||||
$this->_references[$name]->setData($value->getData());
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
$relatedClass = $value->getClass();
|
||||
//$foreignFieldName = $rel->getForeignFieldName();
|
||||
//$localFieldName = $rel->getLocalFieldName();
|
||||
|
||||
// one-to-one relation found
|
||||
if ( ! ($value instanceof Doctrine_Entity)) {
|
||||
throw Doctrine_Entity_Exception::invalidValueForOneToOneReference();
|
||||
}
|
||||
}
|
||||
} else if ($rel instanceof Doctrine_Relation_Association) {
|
||||
if ( ! ($value instanceof Doctrine_Collection)) {
|
||||
throw Doctrine_Entity_Exception::invalidValueForManyToManyReference();
|
||||
}
|
||||
if ($rel->isOneToOne() && ! $value instanceof Doctrine_Entity) {
|
||||
throw Doctrine_Entity_Exception::invalidValueForOneToOneReference();
|
||||
}
|
||||
if ($rel->isOneToMany() && ! $value instanceof Doctrine_Collection) {
|
||||
throw Doctrine_Entity_Exception::invalidValueForOneToManyReference();
|
||||
}
|
||||
if ($rel->isManyToMany() && ! $value instanceof Doctrine_Collection) {
|
||||
throw Doctrine_Entity_Exception::invalidValueForManyToManyReference();
|
||||
}
|
||||
|
||||
$this->_references[$name] = $value;
|
||||
@ -734,7 +657,7 @@ abstract class Doctrine_Entity implements ArrayAccess, Serializable
|
||||
* @param string $name
|
||||
* @return boolean
|
||||
*/
|
||||
final public function contains($fieldName)
|
||||
private function _contains($fieldName)
|
||||
{
|
||||
if (isset($this->_data[$fieldName])) {
|
||||
if ($this->_data[$fieldName] === Doctrine_Null::$INSTANCE) {
|
||||
@ -755,28 +678,29 @@ abstract class Doctrine_Entity implements ArrayAccess, Serializable
|
||||
/**
|
||||
* Clears the value of a field.
|
||||
*
|
||||
* Invoked by Doctrine::ORM::Access#__unset().
|
||||
*
|
||||
* @param string $name
|
||||
* @return void
|
||||
*/
|
||||
final public function remove($fieldName)
|
||||
private function _unset($fieldName)
|
||||
{
|
||||
if (isset($this->_data[$fieldName])) {
|
||||
$this->_data[$fieldName] = array();
|
||||
$this->_data[$fieldName] = null;
|
||||
} else if (isset($this->_references[$fieldName])) {
|
||||
if ($this->_references[$fieldName] instanceof Doctrine_Entity) {
|
||||
// todo: delete related record when saving $this (ONLY WITH deleteOrphans!)
|
||||
$this->_references[$fieldName] = Doctrine_Null::$INSTANCE;
|
||||
} else if ($this->_references[$fieldName] instanceof Doctrine_Collection) {
|
||||
$this->_references[$fieldName]->setData(array());
|
||||
$assoc = $this->_class->getAssociationMapping($fieldName);
|
||||
if ($assoc->isOneToOne() && $assoc->shouldDeleteOrphans()) {
|
||||
$this->_em->delete($this->_references[$fieldName]);
|
||||
} else if ($assoc->isOneToMany() && $assoc->shouldDeleteOrphans()) {
|
||||
foreach ($this->_references[$fieldName] as $entity) {
|
||||
$this->_em->delete($entity);
|
||||
}
|
||||
}
|
||||
$this->_references[$fieldName] = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* INTERNAL:
|
||||
* Gets the changeset of the entities persistent state.
|
||||
* Gets the changeset of the entities data.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
@ -785,6 +709,12 @@ abstract class Doctrine_Entity implements ArrayAccess, Serializable
|
||||
return $this->_dataChangeSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* INTERNAL:
|
||||
* Gets the changeset of the entities references to other entities.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
final public function _getReferenceChangeSet()
|
||||
{
|
||||
return $this->_referenceChangeSet;
|
||||
@ -831,11 +761,28 @@ abstract class Doctrine_Entity implements ArrayAccess, Serializable
|
||||
$this->_data[$name] = $id;
|
||||
}
|
||||
$this->_dataChangeSet = array();
|
||||
$this->_referenceChangeSet = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo Not yet clear if needed.
|
||||
*/
|
||||
/*final public function _setJoinColumn($columnName, $value)
|
||||
{
|
||||
$this->_joinColumns[$columnName] = $value;
|
||||
}*/
|
||||
|
||||
/**
|
||||
* @todo Not yet clear if needed.
|
||||
*/
|
||||
/*final public function _getJoinColumn($columnName)
|
||||
{
|
||||
return $this->_joinColumns[$columnName];
|
||||
}*/
|
||||
|
||||
/**
|
||||
* INTERNAL:
|
||||
* Returns the primary keys of the entity (key => value pairs).
|
||||
* Returns the primary keys of the entity (field => value pairs).
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
@ -844,32 +791,6 @@ abstract class Doctrine_Entity implements ArrayAccess, Serializable
|
||||
return $this->_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* hasRefence
|
||||
* @param string $name
|
||||
* @return boolean
|
||||
* @todo Better name? hasAssociation() ? Remove?
|
||||
*/
|
||||
final public function hasReference($name)
|
||||
{
|
||||
return isset($this->_references[$name]);
|
||||
}
|
||||
|
||||
/**
|
||||
* obtainReference
|
||||
*
|
||||
* @param string $name
|
||||
* @throws Doctrine_Record_Exception if trying to get an unknown related component
|
||||
* @todo Better name? Remove?
|
||||
*/
|
||||
final public function obtainReference($name)
|
||||
{
|
||||
if (isset($this->_references[$name])) {
|
||||
return $this->_references[$name];
|
||||
}
|
||||
throw new Doctrine_Record_Exception("Unknown reference $name.");
|
||||
}
|
||||
|
||||
/**
|
||||
* INTERNAL:
|
||||
*
|
||||
@ -881,19 +802,6 @@ abstract class Doctrine_Entity implements ArrayAccess, Serializable
|
||||
return $this->_references;
|
||||
}
|
||||
|
||||
/**
|
||||
* INTERNAL:
|
||||
* setRelated
|
||||
*
|
||||
* @param string $alias
|
||||
* @param Doctrine_Access $coll
|
||||
* @todo Name? Remove?
|
||||
*/
|
||||
final public function _setRelated($alias, Doctrine_Access $coll)
|
||||
{
|
||||
$this->_references[$alias] = $coll;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the ClassMetadata object that describes the entity class.
|
||||
*
|
||||
@ -925,23 +833,6 @@ abstract class Doctrine_Entity implements ArrayAccess, Serializable
|
||||
return $this->_em->getRepository($this->_entityName);
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo Why toString() and __toString() ?
|
||||
*/
|
||||
public function toString()
|
||||
{
|
||||
return Doctrine::dump(get_object_vars($this));
|
||||
}
|
||||
|
||||
/**
|
||||
* returns a string representation of this object
|
||||
* @todo Why toString() and __toString() ?
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return (string)$this->_oid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helps freeing the memory occupied by the entity.
|
||||
* Cuts all references the entity has to other entities and removes the entity
|
||||
@ -980,7 +871,7 @@ abstract class Doctrine_Entity implements ArrayAccess, Serializable
|
||||
*/
|
||||
public function offsetExists($offset)
|
||||
{
|
||||
return $this->contains($offset);
|
||||
return $this->_contains($offset);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1020,7 +911,7 @@ abstract class Doctrine_Entity implements ArrayAccess, Serializable
|
||||
*/
|
||||
public function offsetUnset($offset)
|
||||
{
|
||||
return $this->remove($offset);
|
||||
return $this->_unset($offset);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1058,7 +949,7 @@ abstract class Doctrine_Entity implements ArrayAccess, Serializable
|
||||
*/
|
||||
public function __isset($name)
|
||||
{
|
||||
return $this->contains($name);
|
||||
return $this->_contains($name);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1070,6 +961,14 @@ abstract class Doctrine_Entity implements ArrayAccess, Serializable
|
||||
*/
|
||||
public function __unset($name)
|
||||
{
|
||||
return $this->remove($name);
|
||||
return $this->_unset($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* returns a string representation of this object
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return (string)$this->_oid;
|
||||
}
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ class Doctrine_EntityManager
|
||||
* IMMEDIATE: Flush occurs automatically after each operation that issues database
|
||||
* queries. No operations are queued.
|
||||
*/
|
||||
const FLUSHMODE_IMMEDIATE = 'immediated';
|
||||
const FLUSHMODE_IMMEDIATE = 'immediate';
|
||||
/**
|
||||
* AUTO: Flush occurs automatically in the following situations:
|
||||
* - Before any query executions (to prevent getting stale data)
|
||||
@ -86,7 +86,7 @@ class Doctrine_EntityManager
|
||||
/**
|
||||
* The metadata factory, used to retrieve the metadata of entity classes.
|
||||
*
|
||||
* @var Doctrine_ClassMetadata_Factory
|
||||
* @var Doctrine::ORM::Mapping::ClassMetadataFactory
|
||||
*/
|
||||
private $_metadataFactory;
|
||||
|
||||
@ -539,7 +539,8 @@ class Doctrine_EntityManager
|
||||
}
|
||||
} else {
|
||||
foreach ($data as $field => $value) {
|
||||
if ( ! $entity->contains($field) || $entity->_internalGetField($field) === null) {
|
||||
$currentValue = $entity->get($field);
|
||||
if ( ! isset($currentValue) || $entity->_internalGetField($field) === null) {
|
||||
$entity->_internalSetField($field, $value);
|
||||
}
|
||||
}
|
||||
|
@ -72,7 +72,7 @@ abstract class Doctrine_EntityPersister_Abstract
|
||||
private $_nullObject;
|
||||
|
||||
/**
|
||||
* Constructs a new persister.
|
||||
* Constructs a new EntityPersister.
|
||||
*/
|
||||
public function __construct(Doctrine_EntityManager $em, Doctrine_ClassMetadata $classMetadata)
|
||||
{
|
||||
@ -83,37 +83,78 @@ abstract class Doctrine_EntityPersister_Abstract
|
||||
$this->_nullObject = Doctrine_Null::$INSTANCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts an entity.
|
||||
*
|
||||
* @param Doctrine::ORM::Entity $entity The entity to insert.
|
||||
* @return void
|
||||
*/
|
||||
public function insert(Doctrine_Entity $entity)
|
||||
{
|
||||
$insertData = array();
|
||||
$dataChangeSet = $entity->_getDataChangeSet();
|
||||
$class = $entity->getClass();
|
||||
|
||||
$referenceChangeSet = $entity->_getReferenceChangeSet();
|
||||
|
||||
foreach ($referenceChangeSet as $field => $change) {
|
||||
list($old, $new) = each($change);
|
||||
$assocMapping = $entity->getClass()->getAssociationMapping($field);
|
||||
if ($assocMapping->isOneToOne()) {
|
||||
if ($assocMapping->isInverseSide()) {
|
||||
//echo "INVERSE!";
|
||||
continue; // ignore inverse side
|
||||
}
|
||||
foreach ($assocMapping->getSourceToTargetKeyColumns() as $localColumn => $foreignColumn) {
|
||||
//echo "$localColumn -- $foreignColumn<br/>";
|
||||
//$insertData[$localColumn] = 1; //FIX
|
||||
}
|
||||
// ... set the foreign key column to the id of the related entity ($new)
|
||||
$assocMapping = $class->getAssociationMapping($field);
|
||||
if ( ! $assocMapping->isOneToOne() || $assocMapping->isInverseSide()) {
|
||||
//echo "NOT TO-ONE OR INVERSE!";
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ($assocMapping->getSourceToTargetKeyColumns() as $sourceColumn => $targetColumn) {
|
||||
//TODO: What if both join columns (local/foreign) are just db-only
|
||||
// columns (no fields in models) ? Currently we assume the foreign column
|
||||
// is mapped to a field in the foreign entity.
|
||||
$insertData[$sourceColumn] = $new->_internalGetField(
|
||||
$new->getClass()->getFieldName($targetColumn)
|
||||
);
|
||||
}
|
||||
//...
|
||||
}
|
||||
|
||||
foreach ($dataChangeSet as $field => $change) {
|
||||
$insertData[$entity->getClass()->getColumnName($field)] = current($change);
|
||||
}
|
||||
$this->_prepareData($entity, $insertData, true);
|
||||
|
||||
//TODO: perform insert
|
||||
$this->_conn->insert($entity->getClass()->getTableName(), $insertData);
|
||||
$this->_conn->insert($class->getTableName(), $insertData);
|
||||
|
||||
//TODO: if IDENTITY pk, assign it
|
||||
if ($class->isIdGeneratorIdentity()) {
|
||||
//TODO: Postgres IDENTITY columns (SERIAL) use a sequence, so we need to pass the
|
||||
// sequence name to lastInsertId().
|
||||
$entity->_assignIdentifier($this->_conn->lastInsertId());
|
||||
}
|
||||
}
|
||||
|
||||
/*protected function _fillJoinColumns($entity, array &$data)
|
||||
{
|
||||
$referenceChangeSet = $entity->_getReferenceChangeSet();
|
||||
foreach ($referenceChangeSet as $field => $change) {
|
||||
list($old, $new) = each($change);
|
||||
$assocMapping = $entity->getClass()->getAssociationMapping($field);
|
||||
if ( ! $assocMapping->isOneToOne() || $assocMapping->isInverseSide()) {
|
||||
//echo "NOT TO-ONE OR INVERSE!";
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ($assocMapping->getSourceToTargetKeyColumns() as $sourceColumn => $targetColumn) {
|
||||
//TODO: What if both join columns (local/foreign) are just db-only
|
||||
// columns (no fields in models) ? Currently we assume the foreign column
|
||||
// is mapped to a field in the foreign entity.
|
||||
$insertData[$sourceColumn] = $new->_internalGetField(
|
||||
$new->getClass()->getFieldName($targetColumn)
|
||||
);
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
/**
|
||||
* Updates an entity.
|
||||
*
|
||||
* @param Doctrine::ORM::Entity $entity The entity to update.
|
||||
* @return void
|
||||
*/
|
||||
public function update(Doctrine_Entity $entity)
|
||||
{
|
||||
$dataChangeSet = $entity->_getDataChangeSet();
|
||||
@ -134,6 +175,12 @@ abstract class Doctrine_EntityPersister_Abstract
|
||||
//TODO: perform update
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes an entity.
|
||||
*
|
||||
* @param Doctrine::ORM::Entity $entity The entity to delete.
|
||||
* @return void
|
||||
*/
|
||||
public function delete(Doctrine_Entity $entity)
|
||||
{
|
||||
//TODO: perform delete
|
||||
@ -177,6 +224,9 @@ abstract class Doctrine_EntityPersister_Abstract
|
||||
return $this->_classMetadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo Move to ClassMetadata?
|
||||
*/
|
||||
public function getFieldNames()
|
||||
{
|
||||
if ($this->_fieldNames) {
|
||||
@ -186,6 +236,9 @@ abstract class Doctrine_EntityPersister_Abstract
|
||||
return $this->_fieldNames;
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo Move to ClassMetadata?
|
||||
*/
|
||||
public function getOwningClass($fieldName)
|
||||
{
|
||||
return $this->_classMetadata;
|
||||
@ -193,6 +246,7 @@ abstract class Doctrine_EntityPersister_Abstract
|
||||
|
||||
/**
|
||||
* Callback that is invoked during the SQL construction process.
|
||||
* @todo Move to ClassMetadata?
|
||||
*/
|
||||
public function getCustomJoins()
|
||||
{
|
||||
@ -201,6 +255,7 @@ abstract class Doctrine_EntityPersister_Abstract
|
||||
|
||||
/**
|
||||
* Callback that is invoked during the SQL construction process.
|
||||
* @todo Move to ClassMetadata?
|
||||
*/
|
||||
public function getCustomFields()
|
||||
{
|
||||
@ -213,7 +268,7 @@ abstract class Doctrine_EntityPersister_Abstract
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function _convertFieldToColumnNames(array $fields, Doctrine_ClassMetadata $class)
|
||||
/*protected function _convertFieldToColumnNames(array $fields, Doctrine_ClassMetadata $class)
|
||||
{
|
||||
$converted = array();
|
||||
foreach ($fields as $fieldName => $value) {
|
||||
@ -221,65 +276,52 @@ abstract class Doctrine_EntityPersister_Abstract
|
||||
}
|
||||
|
||||
return $converted;
|
||||
}
|
||||
}*/
|
||||
|
||||
/**
|
||||
* Returns an array of modified fields and values with data preparation
|
||||
* adds column aggregation inheritance and converts Records into primary key values
|
||||
*
|
||||
* @param array $array
|
||||
* @return array
|
||||
* @return void
|
||||
* @todo Move to EntityPersister. There call _getChangeSet() and apply this logic.
|
||||
*/
|
||||
public function prepareData(array $data = array())
|
||||
protected function _prepareData($entity, array &$result, $isInsert = false)
|
||||
{
|
||||
$dataSet = array();
|
||||
foreach ($entity->_getDataChangeSet() as $field => $change) {
|
||||
list ($oldVal, $newVal) = each($change);
|
||||
$type = $entity->getClass()->getTypeOfField($field);
|
||||
$columnName = $entity->getClass()->getColumnName($field);
|
||||
|
||||
$modifiedFields = $fields;
|
||||
|
||||
foreach ($data as $field => $value) {
|
||||
$type = $this->_classMetadata->getTypeOfField($field);
|
||||
|
||||
if ($value === Doctrine_Null::$INSTANCE) {
|
||||
$dataSet[$field] = null;
|
||||
if ($newVal === Doctrine_Null::$INSTANCE) {
|
||||
$result[$columnName] = null;
|
||||
continue;
|
||||
}
|
||||
|
||||
switch ($type) {
|
||||
case 'array':
|
||||
case 'object':
|
||||
$dataSet[$field] = serialize($value);
|
||||
$result[$columnName] = serialize($newVal);
|
||||
break;
|
||||
case 'gzip':
|
||||
$dataSet[$field] = gzcompress($value, 5);
|
||||
$result[$columnName] = gzcompress($newVal, 5);
|
||||
break;
|
||||
case 'boolean':
|
||||
$dataSet[$field] = $this->_em->getConnection()
|
||||
->convertBooleans($value);
|
||||
$result[$columnName] = $this->_em->getConnection()->convertBooleans($newVal);
|
||||
break;
|
||||
case 'enum':
|
||||
$dataSet[$field] = $this->_class->enumIndex($field, $value);
|
||||
break;
|
||||
default:
|
||||
$dataSet[$field] = $value;
|
||||
$result[$columnName] = $newVal;
|
||||
}
|
||||
}
|
||||
|
||||
// @todo cleanup
|
||||
// populates the discriminator field in Single & Class Table Inheritance
|
||||
if ($this->_classMetadata->getInheritanceType() == Doctrine_ClassMetadata::INHERITANCE_TYPE_JOINED ||
|
||||
$this->_class->getInheritanceType() == Doctrine_ClassMetadata::INHERITANCE_TYPE_SINGLE_TABLE) {
|
||||
$discCol = $this->_classMetadata->getInheritanceOption('discriminatorColumn');
|
||||
$discMap = $this->_classMetadata->getInheritanceOption('discriminatorMap');
|
||||
$old = $this->get($discCol, false);
|
||||
$discValue = array_search($this->_entityName, $discMap);
|
||||
if ((string) $old !== (string) $discValue || $old === null) {
|
||||
$dataSet[$discCol] = $discValue;
|
||||
//$this->_data[$discCol] = $discValue;
|
||||
}
|
||||
// @todo Cleanup
|
||||
// populates the discriminator column on insert in Single & Class Table Inheritance
|
||||
if ($isInsert && ($entity->getClass()->isInheritanceTypeJoined() ||
|
||||
$entity->getClass()->isInheritanceTypeSingleTable())) {
|
||||
$discColumn = $entity->getClass()->getInheritanceOption('discriminatorColumn');
|
||||
$discMap = $entity->getClass()->getInheritanceOption('discriminatorMap');
|
||||
$result[$discColumn] = array_search($this->_entityName, $discMap);
|
||||
}
|
||||
|
||||
return $dataSet;
|
||||
}
|
||||
|
||||
|
||||
|
@ -30,58 +30,53 @@
|
||||
* @since 2.0
|
||||
*/
|
||||
class Doctrine_EntityPersister_JoinedSubclass extends Doctrine_EntityPersister_Abstract
|
||||
{
|
||||
//protected $_columnNameFieldNameMap = array();
|
||||
|
||||
{
|
||||
/**
|
||||
* Inserts an entity that is part of a Class Table Inheritance hierarchy.
|
||||
*
|
||||
* @param Doctrine_Entity $record record to be inserted
|
||||
* @return boolean
|
||||
* @override
|
||||
*/
|
||||
protected function _doInsert(Doctrine_Entity $record)
|
||||
public function insert(Doctrine_Entity $entity)
|
||||
{
|
||||
$class = $this->_classMetadata;
|
||||
$conn = $this->_conn;
|
||||
|
||||
$dataSet = $this->_groupFieldsByDefiningClass($record);
|
||||
$class = $entity->getClass();
|
||||
|
||||
$dataSet = array();
|
||||
|
||||
$this->_prepareData($entity, $dataSet, true);
|
||||
|
||||
$dataSet = $this->_groupFieldsByDefiningClass($class, $dataSet);
|
||||
|
||||
$component = $class->getClassName();
|
||||
$classes = $class->getParentClasses();
|
||||
array_unshift($classes, $component);
|
||||
|
||||
try {
|
||||
$conn->beginInternalTransaction();
|
||||
$identifier = null;
|
||||
foreach (array_reverse($classes) as $k => $parent) {
|
||||
$parentClass = $conn->getClassMetadata($parent);
|
||||
if ($k == 0) {
|
||||
$identifierType = $parentClass->getIdentifierType();
|
||||
if ($identifierType == Doctrine::IDENTIFIER_AUTOINC) {
|
||||
$this->_insertRow($parentClass->getTableName(), $dataSet[$parent]);
|
||||
$identifier = $conn->sequence->lastInsertId();
|
||||
} else if ($identifierType == Doctrine::IDENTIFIER_SEQUENCE) {
|
||||
$seq = $record->getClassMetadata()->getTableOption('sequenceName');
|
||||
if ( ! empty($seq)) {
|
||||
$id = $conn->sequence->nextId($seq);
|
||||
$identifierFields = (array)$parentClass->getIdentifier();
|
||||
$dataSet[$parent][$identifierFields[0]] = $id;
|
||||
$this->_insertRow($parentClass->getTableName(), $dataSet[$parent]);
|
||||
}
|
||||
} else {
|
||||
throw new Doctrine_Mapper_Exception("Unsupported identifier type '$identifierType'.");
|
||||
}
|
||||
$record->assignIdentifier($identifier);
|
||||
} else {
|
||||
foreach ((array) $record->identifier() as $id => $value) {
|
||||
$dataSet[$parent][$parentClass->getColumnName($id)] = $value;
|
||||
}
|
||||
$identifier = null;
|
||||
foreach (array_reverse($classes) as $k => $parent) {
|
||||
$parentClass = $this->_em->getClassMetadata($parent);
|
||||
if ($k == 0) {
|
||||
if ($parentClass->isIdGeneratorIdentity()) {
|
||||
$this->_insertRow($parentClass->getTableName(), $dataSet[$parent]);
|
||||
$identifier = $this->_conn->lastInsertId();
|
||||
} else if ($parentClass->isIdGeneratorSequence()) {
|
||||
$seq = $entity->getClassMetadata()->getTableOption('sequenceName');
|
||||
if ( ! empty($seq)) {
|
||||
$id = $this->_conn->getSequenceManager()->nextId($seq);
|
||||
$identifierFields = $parentClass->getIdentifier();
|
||||
$dataSet[$parent][$identifierFields[0]] = $id;
|
||||
$this->_insertRow($parentClass->getTableName(), $dataSet[$parent]);
|
||||
}
|
||||
} else {
|
||||
throw new Doctrine_Mapper_Exception("Unsupported identifier type '$identifierType'.");
|
||||
}
|
||||
$entity->_assignIdentifier($identifier);
|
||||
} else {
|
||||
foreach ($entity->_identifier() as $id => $value) {
|
||||
$dataSet[$parent][$parentClass->getColumnName($id)] = $value;
|
||||
}
|
||||
$this->_insertRow($parentClass->getTableName(), $dataSet[$parent]);
|
||||
}
|
||||
$conn->commit();
|
||||
} catch (Exception $e) {
|
||||
$conn->rollback();
|
||||
throw $e;
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -255,29 +250,26 @@ class Doctrine_EntityPersister_JoinedSubclass extends Doctrine_EntityPersister_A
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function _groupFieldsByDefiningClass(Doctrine_Entity $record)
|
||||
protected function _groupFieldsByDefiningClass(Doctrine_ClassMetadata $class, array $fields)
|
||||
{
|
||||
$conn = $this->_conn;
|
||||
$classMetadata = $this->_classMetadata;
|
||||
$dataSet = array();
|
||||
$component = $classMetadata->getClassName();
|
||||
$array = $record->getPrepared();
|
||||
$component = $class->getClassName();
|
||||
|
||||
$classes = array_merge(array($component), $classMetadata->getParentClasses());
|
||||
$classes = array_merge(array($component), $class->getParentClasses());
|
||||
|
||||
foreach ($classes as $class) {
|
||||
$dataSet[$class] = array();
|
||||
$parentClassMetadata = $conn->getClassMetadata($class);
|
||||
foreach ($parentClassMetadata->getColumns() as $columnName => $definition) {
|
||||
if ((isset($definition['primary']) && $definition['primary'] === true) ||
|
||||
(isset($definition['inherited']) && $definition['inherited'] === true)) {
|
||||
$parentClassMetadata = $this->_em->getClassMetadata($class);
|
||||
foreach ($parentClassMetadata->getFieldMappings() as $fieldName => $mapping) {
|
||||
if ((isset($mapping['id']) && $mapping['id'] === true) ||
|
||||
(isset($mapping['inherited']) && $mapping['inherited'] === true)) {
|
||||
continue;
|
||||
}
|
||||
$fieldName = $classMetadata->getFieldName($columnName);
|
||||
if ( ! array_key_exists($fieldName, $array)) {
|
||||
if ( ! array_key_exists($fieldName, $fields)) {
|
||||
continue;
|
||||
}
|
||||
$dataSet[$class][$columnName] = $array[$fieldName];
|
||||
$columnName = $parentClassMetadata->getColumnName($fieldName);
|
||||
$dataSet[$class][$columnName] = $fields[$fieldName];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -18,7 +18,7 @@
|
||||
* and is licensed under the LGPL. For more information, see
|
||||
* <http://www.phpdoctrine.org>.
|
||||
*/
|
||||
Doctrine::autoload('Doctrine_Hook_Parser');
|
||||
|
||||
/**
|
||||
* Doctrine_Hook_Equal
|
||||
*
|
||||
@ -28,7 +28,9 @@ Doctrine::autoload('Doctrine_Hook_Parser');
|
||||
* @link www.phpdoctrine.org
|
||||
* @since 1.0
|
||||
* @version $Revision$
|
||||
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
|
||||
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
|
||||
* @todo Can be removed?
|
||||
* @deprecated
|
||||
*/
|
||||
class Doctrine_Hook_Equal extends Doctrine_Hook_Parser
|
||||
{
|
||||
|
@ -18,7 +18,7 @@
|
||||
* and is licensed under the LGPL. For more information, see
|
||||
* <http://www.phpdoctrine.org>.
|
||||
*/
|
||||
Doctrine::autoload('Doctrine_Hook_Parser_Complex');
|
||||
|
||||
/**
|
||||
* Doctrine_Hook_Integer
|
||||
*
|
||||
@ -28,7 +28,9 @@ Doctrine::autoload('Doctrine_Hook_Parser_Complex');
|
||||
* @link www.phpdoctrine.org
|
||||
* @since 1.0
|
||||
* @version $Revision$
|
||||
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
|
||||
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
|
||||
* @todo Can be removed?
|
||||
* @deprecated
|
||||
*/
|
||||
class Doctrine_Hook_Integer extends Doctrine_Hook_Parser_Complex
|
||||
{
|
||||
|
@ -28,7 +28,9 @@
|
||||
* @link www.phpdoctrine.org
|
||||
* @since 1.0
|
||||
* @version $Revision$
|
||||
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
|
||||
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
|
||||
* @todo Can be removed?
|
||||
* @deprecated
|
||||
*/
|
||||
abstract class Doctrine_Hook_Parser
|
||||
{
|
||||
|
@ -18,7 +18,7 @@
|
||||
* and is licensed under the LGPL. For more information, see
|
||||
* <http://www.phpdoctrine.org>.
|
||||
*/
|
||||
Doctrine::autoload('Doctrine_Hook_Parser');
|
||||
|
||||
/**
|
||||
* Doctrine_Hook_Parser_Complex
|
||||
*
|
||||
@ -28,7 +28,9 @@ Doctrine::autoload('Doctrine_Hook_Parser');
|
||||
* @link www.phpdoctrine.org
|
||||
* @since 1.0
|
||||
* @version $Revision$
|
||||
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
|
||||
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
|
||||
* @todo Can be removed?
|
||||
* @deprecated
|
||||
*/
|
||||
abstract class Doctrine_Hook_Parser_Complex extends Doctrine_Hook_Parser
|
||||
{
|
||||
|
@ -18,7 +18,7 @@
|
||||
* and is licensed under the LGPL. For more information, see
|
||||
* <http://www.phpdoctrine.org>.
|
||||
*/
|
||||
Doctrine::autoload('Doctrine_Hook_Parser');
|
||||
|
||||
/**
|
||||
* Doctrine_Hook_WordLike
|
||||
*
|
||||
@ -28,7 +28,9 @@ Doctrine::autoload('Doctrine_Hook_Parser');
|
||||
* @link www.phpdoctrine.org
|
||||
* @since 1.0
|
||||
* @version $Revision$
|
||||
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
|
||||
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
|
||||
* @deprecated
|
||||
* @todo Can be removed?
|
||||
*/
|
||||
class Doctrine_Hook_WordLike extends Doctrine_Hook_Parser_Complex
|
||||
{
|
||||
|
@ -88,33 +88,51 @@ class Doctrine_Query_Production_Join extends Doctrine_Query_Production
|
||||
return $sql . ' ON ' . $conditionExpression;
|
||||
}
|
||||
|
||||
// We need to build the relationship conditions. Retrieving AssociationMapping
|
||||
$queryComponent = $this->_rangeVariableDeclaration->getQueryComponent();
|
||||
$relationColumns = $queryComponent['relation']->getSourceToTargetKeyColumns();
|
||||
$relationConditionExpression = '';
|
||||
// We need to build the join conditions. Retrieving AssociationMapping
|
||||
$queryComponent = $this->_rangeVariableDeclaration->getQueryComponent();
|
||||
$association = $queryComponent['relation'];
|
||||
$joinColumns = array();
|
||||
|
||||
if ($association->isOneToMany() || $association->isOneToOne()) {
|
||||
if ($association->isInverseSide()) {
|
||||
// joinColumns are found on the other (owning) side
|
||||
$targetClass = $this->_em->getClassMetadata($association->getTargetEntityName());
|
||||
$joinColumns = $targetClass->getAssociationMapping($association->getMappedByFieldName())
|
||||
->getTargetToSourceKeyColumns();
|
||||
} else {
|
||||
$joinColumns = $association->getSourceToTargetKeyColumns();
|
||||
}
|
||||
} else {
|
||||
//TODO: many-many
|
||||
}
|
||||
|
||||
$relationConditionExpression = '';
|
||||
|
||||
// We have an array('localColumn' => 'foreignColumn', ...) here
|
||||
foreach ($relationColumns as $localColumn => $foreignColumn) {
|
||||
// leftExpression = rightExpression
|
||||
// We have an array('localColumn' => 'foreignColumn', ...) here
|
||||
foreach ($joinColumns as $localColumn => $foreignColumn) {
|
||||
// leftExpression = rightExpression
|
||||
|
||||
// Defining leftExpression
|
||||
$leftExpression = $conn->quoteIdentifier(
|
||||
$parserResult->getTableAliasFromComponentAlias($queryComponent['parent']) . '.' . $localColumn
|
||||
);
|
||||
// Defining leftExpression
|
||||
$leftExpression = $conn->quoteIdentifier(
|
||||
$parserResult->getTableAliasFromComponentAlias($queryComponent['parent']) . '.' . $localColumn
|
||||
);
|
||||
|
||||
// Defining rightExpression
|
||||
$rightExpression = $conn->quoteIdentifier(
|
||||
$parserResult->getTableAliasFromComponentAlias(
|
||||
$this->_rangeVariableDeclaration->getIdentificationVariable()
|
||||
) . '.' . $foreignColumn
|
||||
);
|
||||
// Defining rightExpression
|
||||
$rightExpression = $conn->quoteIdentifier(
|
||||
$parserResult->getTableAliasFromComponentAlias(
|
||||
$this->_rangeVariableDeclaration->getIdentificationVariable()
|
||||
) . '.' . $foreignColumn
|
||||
);
|
||||
|
||||
// Building the relation
|
||||
$relationConditionExpression .= (($relationConditionExpression != '') ? ' AND ' : '')
|
||||
. $leftExpression . ' = ' . $rightExpression;
|
||||
}
|
||||
// Building the relation
|
||||
$relationConditionExpression .= (($relationConditionExpression != '') ? ' AND ' : '')
|
||||
. $leftExpression . ' = ' . $rightExpression;
|
||||
}
|
||||
|
||||
$sql .= ' ON ' . $relationConditionExpression;
|
||||
$sql .= empty($conditionExpression) ? '' : ' AND (' . $conditionExpression . ')';
|
||||
|
||||
return $sql . ' ON ' . $relationConditionExpression . ' AND (' . $conditionExpression . ')';
|
||||
return $sql;
|
||||
}
|
||||
|
||||
|
||||
|
@ -52,7 +52,7 @@ class Doctrine_Query_Production_JoinVariableDeclaration extends Doctrine_Query_P
|
||||
|
||||
public function buildSql()
|
||||
{
|
||||
return $this->_join->buildSql() . ' ' . (isset($this->_indexby) ? $this->_indexby->buildSql() . ' ' : '');
|
||||
return $this->_join->buildSql() . (isset($this->_indexby) ? $this->_indexby->buildSql() . ' ' : '');
|
||||
}
|
||||
|
||||
|
||||
|
@ -18,7 +18,9 @@
|
||||
* and is licensed under the LGPL. For more information, see
|
||||
* <http://www.phpdoctrine.org>.
|
||||
*/
|
||||
Doctrine::autoload('Doctrine_Exception');
|
||||
|
||||
#namespace Doctrine::ORM::Exceptions;
|
||||
|
||||
/**
|
||||
* Doctrine_RawSql_Exception
|
||||
*
|
||||
@ -28,7 +30,8 @@ Doctrine::autoload('Doctrine_Exception');
|
||||
* @link www.phpdoctrine.org
|
||||
* @since 1.0
|
||||
* @version $Revision$
|
||||
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
|
||||
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
|
||||
* @todo Rename to NativeSqlException or maybe remove.
|
||||
*/
|
||||
class Doctrine_RawSql_Exception extends Doctrine_Exception
|
||||
{ }
|
@ -18,7 +18,7 @@
|
||||
* and is licensed under the LGPL. For more information, see
|
||||
* <http://www.phpdoctrine.org>.
|
||||
*/
|
||||
Doctrine::autoload('Doctrine_Exception');
|
||||
|
||||
/**
|
||||
* Doctrine_Exception
|
||||
*
|
||||
@ -28,7 +28,8 @@ Doctrine::autoload('Doctrine_Exception');
|
||||
* @link www.phpdoctrine.org
|
||||
* @since 1.0
|
||||
* @version $Revision$
|
||||
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
|
||||
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
|
||||
* @deprecated Remove.
|
||||
*/
|
||||
class Doctrine_Record_Exception extends Doctrine_Exception
|
||||
{ }
|
@ -29,7 +29,8 @@
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.phpdoctrine.org
|
||||
* @since 1.0
|
||||
* @version $Revision: 1298 $
|
||||
* @version $Revision: 1298 $
|
||||
* @deprecated Remove.
|
||||
*/
|
||||
abstract class Doctrine_Record_Filter
|
||||
{
|
||||
|
@ -28,7 +28,9 @@
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.phpdoctrine.org
|
||||
* @since 1.0
|
||||
* @version $Revision: 1298 $
|
||||
* @version $Revision: 1298 $
|
||||
* @todo Remove.
|
||||
* @deprecated
|
||||
*/
|
||||
class Doctrine_Record_Filter_Compound extends Doctrine_Record_Filter
|
||||
{
|
||||
|
@ -29,7 +29,8 @@
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.phpdoctrine.org
|
||||
* @since 1.0
|
||||
* @version $Revision: 1298 $
|
||||
* @version $Revision: 1298 $
|
||||
* @deprecated Remove.
|
||||
*/
|
||||
class Doctrine_Record_Filter_Standard extends Doctrine_Record_Filter
|
||||
{
|
||||
|
@ -28,7 +28,8 @@
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @version $Revision$
|
||||
* @link www.phpdoctrine.org
|
||||
* @since 1.0
|
||||
* @since 1.0
|
||||
* @todo Rename. Move. Reimpl?
|
||||
*/
|
||||
abstract class Doctrine_Record_Generator
|
||||
{
|
||||
|
@ -28,7 +28,8 @@
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.phpdoctrine.org
|
||||
* @since 1.0
|
||||
* @version $Revision$
|
||||
* @version $Revision$
|
||||
* @deprecated Remove.
|
||||
*/
|
||||
class Doctrine_Record_Iterator extends ArrayIterator
|
||||
{
|
||||
|
@ -28,7 +28,8 @@
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.phpdoctrine.org
|
||||
* @since 1.0
|
||||
* @version $Revision$
|
||||
* @version $Revision$
|
||||
* @deprecated Remove.
|
||||
*/
|
||||
class Doctrine_Record_Listener implements Doctrine_Record_Listener_Interface
|
||||
{
|
||||
|
@ -18,7 +18,6 @@
|
||||
* and is licensed under the LGPL. For more information, see
|
||||
* <http://www.phpdoctrine.org>.
|
||||
*/
|
||||
Doctrine::autoload('Doctrine_Access');
|
||||
|
||||
/**
|
||||
* Doctrine_Record_Listener_Chain
|
||||
@ -31,7 +30,9 @@ Doctrine::autoload('Doctrine_Access');
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.phpdoctrine.org
|
||||
* @since 1.0
|
||||
* @version $Revision$
|
||||
* @version $Revision$
|
||||
* @deprecated
|
||||
* @todo Remove
|
||||
*/
|
||||
class Doctrine_Record_Listener_Chain extends Doctrine_Access implements Doctrine_Record_Listener_Interface
|
||||
{
|
||||
|
@ -28,7 +28,8 @@
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.phpdoctrine.org
|
||||
* @since 1.0
|
||||
* @version $Revision$
|
||||
* @version $Revision$
|
||||
* @deprecated Remove.
|
||||
*/
|
||||
interface Doctrine_Record_Listener_Interface
|
||||
{
|
||||
|
@ -18,7 +18,7 @@
|
||||
* and is licensed under the LGPL. For more information, see
|
||||
* <http://www.phpdoctrine.org>.
|
||||
*/
|
||||
Doctrine::autoload('Doctrine_Record_Exception');
|
||||
|
||||
/**
|
||||
* Doctrine_Exception
|
||||
*
|
||||
@ -28,7 +28,8 @@ Doctrine::autoload('Doctrine_Record_Exception');
|
||||
* @link www.phpdoctrine.org
|
||||
* @since 1.0
|
||||
* @version $Revision$
|
||||
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
|
||||
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
|
||||
* @todo Deprecated. Remove
|
||||
*/
|
||||
class Doctrine_Record_State_Exception extends Doctrine_Record_Exception
|
||||
{ }
|
@ -29,7 +29,8 @@
|
||||
* @link www.phpdoctrine.org
|
||||
* @since 1.0
|
||||
* @version $Revision$
|
||||
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
|
||||
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
|
||||
* @deprecated
|
||||
*/
|
||||
abstract class Doctrine_Relation implements ArrayAccess
|
||||
{
|
||||
|
@ -18,7 +18,7 @@
|
||||
* and is licensed under the LGPL. For more information, see
|
||||
* <http://www.phpdoctrine.org>.
|
||||
*/
|
||||
Doctrine::autoload('Doctrine_Relation');
|
||||
|
||||
/**
|
||||
* Doctrine_Relation_Association
|
||||
*
|
||||
@ -30,7 +30,8 @@ Doctrine::autoload('Doctrine_Relation');
|
||||
* @link www.phpdoctrine.org
|
||||
* @since 1.0
|
||||
* @version $Revision$
|
||||
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
|
||||
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
|
||||
* @deprecated
|
||||
*/
|
||||
class Doctrine_Relation_Association extends Doctrine_Relation
|
||||
{
|
||||
|
@ -28,7 +28,8 @@
|
||||
* @link www.phpdoctrine.org
|
||||
* @since 1.0
|
||||
* @version $Revision$
|
||||
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
|
||||
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
|
||||
* @deprecated
|
||||
*/
|
||||
class Doctrine_Relation_Association_Self extends Doctrine_Relation_Association
|
||||
{
|
||||
|
@ -29,7 +29,8 @@
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.phpdoctrine.org
|
||||
* @since 1.0
|
||||
* @version $Revision$
|
||||
* @version $Revision$
|
||||
* @deprecated
|
||||
*/
|
||||
class Doctrine_Relation_ForeignKey extends Doctrine_Relation
|
||||
{
|
||||
|
@ -29,7 +29,8 @@
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.phpdoctrine.org
|
||||
* @since 1.0
|
||||
* @version $Revision$
|
||||
* @version $Revision$
|
||||
* @deprecated
|
||||
*/
|
||||
class Doctrine_Relation_LocalKey extends Doctrine_Relation
|
||||
{
|
||||
|
@ -18,7 +18,7 @@
|
||||
* and is licensed under the LGPL. For more information, see
|
||||
* <http://www.phpdoctrine.org>.
|
||||
*/
|
||||
Doctrine::autoload('Doctrine_Relation_Association');
|
||||
|
||||
/**
|
||||
* Doctrine_Relation_Association_Self
|
||||
*
|
||||
@ -28,7 +28,8 @@ Doctrine::autoload('Doctrine_Relation_Association');
|
||||
* @link www.phpdoctrine.org
|
||||
* @since 1.0
|
||||
* @version $Revision: 1434 $
|
||||
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
|
||||
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
|
||||
* @deprecated
|
||||
*/
|
||||
class Doctrine_Relation_Nest extends Doctrine_Relation_Association
|
||||
{
|
||||
|
@ -30,7 +30,8 @@
|
||||
* @link www.phpdoctrine.org
|
||||
* @since 1.0
|
||||
* @todo Composite key support?
|
||||
* @todo Remove. Association mapping needs a reimplementation.
|
||||
* @todo Remove. Association mapping is being reimplemented.
|
||||
* @deprecated
|
||||
*/
|
||||
class Doctrine_Relation_Parser
|
||||
{
|
||||
|
@ -18,7 +18,7 @@
|
||||
* and is licensed under the LGPL. For more information, see
|
||||
* <http://www.phpdoctrine.org>.
|
||||
*/
|
||||
Doctrine::autoload('Doctrine_Relation_Exception');
|
||||
|
||||
/**
|
||||
* Doctrine_Relation_Parser_Exception
|
||||
*
|
||||
@ -28,7 +28,8 @@ Doctrine::autoload('Doctrine_Relation_Exception');
|
||||
* @link www.phpdoctrine.org
|
||||
* @since 1.0
|
||||
* @version $Revision$
|
||||
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
|
||||
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
|
||||
* @deprecated Remove.
|
||||
*/
|
||||
class Doctrine_Relation_Parser_Exception extends Doctrine_Relation_Exception
|
||||
{ }
|
@ -83,7 +83,7 @@ class Doctrine_Sequence_Mysql extends Doctrine_Sequence
|
||||
*/
|
||||
public function lastInsertId($table = null, $field = null)
|
||||
{
|
||||
return $this->conn->getDbh()->lastInsertId();
|
||||
return $this->conn->getPdo()->lastInsertId();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -84,7 +84,7 @@ class Doctrine_Sequence_Sqlite extends Doctrine_Sequence
|
||||
*/
|
||||
public function lastInsertId($table = null, $field = null)
|
||||
{
|
||||
return $this->conn->getDbh()->lastInsertId();
|
||||
return $this->conn->getPdo()->lastInsertId();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -11,32 +11,54 @@ class Orm_EntityPersisterTest extends Doctrine_OrmTestCase
|
||||
private $_persister; // SUT
|
||||
private $_connMock;
|
||||
private $_emMock;
|
||||
private $_seqManagerMock;
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->_connMock = new Doctrine_ConnectionMock(array());
|
||||
$this->_emMock = new Doctrine_EntityManagerMock($this->_connMock);
|
||||
$this->_seqManagerMock = new Doctrine_SequenceMock($this->_connMock);
|
||||
|
||||
$this->_connMock->setDatabasePlatform(new Doctrine_DatabasePlatformMock());
|
||||
$this->_connMock->setSequenceManager($this->_seqManagerMock);
|
||||
|
||||
$this->_persister = new Doctrine_EntityPersister_Standard(
|
||||
$this->_emMock, $this->_emMock->getClassMetadata("ForumUser"));
|
||||
}
|
||||
|
||||
public function testTest() {
|
||||
public function testInsert() {
|
||||
$user = new ForumUser();
|
||||
$user->username = "romanb";
|
||||
|
||||
$user->avatar = new ForumAvatar();
|
||||
|
||||
$this->_persister->insert($user);
|
||||
|
||||
$this->_seqManagerMock->autoinc(); //fake identity column autoinc
|
||||
$this->_persister->insert($user->avatar);
|
||||
$inserts = $this->_connMock->getInserts();
|
||||
//var_dump($inserts);
|
||||
//check
|
||||
$this->assertEquals(1, count($inserts));
|
||||
$this->assertEquals(0, $user->avatar->id);
|
||||
$this->assertTrue(isset($inserts['forum_avatar']));
|
||||
$this->assertEquals(1, count($inserts['forum_avatar']));
|
||||
$this->assertTrue(empty($inserts['forum_avatar'][0]));
|
||||
|
||||
$this->_seqManagerMock->autoinc(); //fake identity column autoinc
|
||||
$this->_persister->insert($user);
|
||||
$inserts = $this->_connMock->getInserts();
|
||||
//check
|
||||
$this->assertEquals(2, count($inserts));
|
||||
$this->assertEquals(1, $user->id);
|
||||
$this->assertTrue(isset($inserts['forum_user']));
|
||||
$this->assertEquals(1, count($inserts['forum_user']));
|
||||
$this->assertEquals(1, count($inserts['forum_user'][0]));
|
||||
$this->assertEquals(3, count($inserts['forum_user'][0]));
|
||||
//username column
|
||||
$this->assertTrue(isset($inserts['forum_user'][0]['username']));
|
||||
$this->assertEquals('romanb', $inserts['forum_user'][0]['username']);
|
||||
//avatar_id join column
|
||||
$this->assertTrue(isset($inserts['forum_user'][0]['avatar_id']));
|
||||
$this->assertEquals(0, $inserts['forum_user'][0]['avatar_id']);
|
||||
//dtype discriminator column
|
||||
$this->assertTrue(isset($inserts['forum_user'][0]['dtype']));
|
||||
$this->assertEquals('user', $inserts['forum_user'][0]['dtype']);
|
||||
}
|
||||
|
||||
}
|
@ -172,7 +172,7 @@ class Orm_Query_SelectSqlGenerationTest extends Doctrine_OrmTestCase
|
||||
{
|
||||
$this->assertSqlGeneration(
|
||||
'SELECT u.id, a.id FROM CmsUser u LEFT JOIN u.articles a',
|
||||
'SELECT cu.id AS cu__id, ca.id AS ca__id FROM cms_user cu LEFT JOIN cms_article ca ON ca.user_id = cu.id WHERE 1 = 1'
|
||||
'SELECT cu.id AS cu__id, ca.id AS ca__id FROM cms_user cu LEFT JOIN cms_article ca ON cu.id = ca.user_id WHERE 1 = 1'
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -126,6 +126,23 @@ class Orm_UnitOfWorkTest extends Doctrine_OrmTestCase
|
||||
$this->assertEquals(0, count($this->_persisterMock->getDeletes()));
|
||||
}
|
||||
|
||||
public function testCommitOrder()
|
||||
{
|
||||
$avatar = new ForumAvatar();
|
||||
$this->_user->avatar = $avatar;
|
||||
$this->_unitOfWork->save($this->_user); // save cascaded to avatar
|
||||
|
||||
$this->assertEquals(2, count($this->_persisterMock->getInserts())); // insert forced
|
||||
$this->assertEquals(0, count($this->_persisterMock->getUpdates()));
|
||||
$this->assertEquals(0, count($this->_persisterMock->getDeletes()));
|
||||
// verify order of inserts()s
|
||||
$inserts = $this->_persisterMock->getInserts();
|
||||
$this->assertSame($avatar, $inserts[0]);
|
||||
$this->assertSame($this->_user, $inserts[1]);
|
||||
|
||||
//...
|
||||
}
|
||||
|
||||
public function testSavingSingleEntityWithSequenceIdGeneratorSchedulesInsert()
|
||||
{
|
||||
//...
|
||||
|
@ -34,6 +34,11 @@ class Doctrine_SequenceMock extends Doctrine_Sequence
|
||||
{
|
||||
$this->_sequenceNumber = 0;
|
||||
}
|
||||
|
||||
public function autoinc()
|
||||
{
|
||||
$this->_sequenceNumber++;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
@ -35,17 +35,16 @@ class CmsArticle extends Doctrine_Entity
|
||||
'length' => 4
|
||||
));
|
||||
|
||||
/*$mapping->hasMany('CmsComment as comments', array(
|
||||
'local' => 'id', 'foreign' => 'article_id'));*/
|
||||
|
||||
$mapping->mapOneToMany(array(
|
||||
'fieldName' => 'comments',
|
||||
'targetEntity' => 'CmsComment',
|
||||
));
|
||||
|
||||
/*$mapping->mapManyToOne(array(
|
||||
'fieldName' => 'author',
|
||||
$mapping->mapManyToOne(array(
|
||||
'fieldName' => 'user',
|
||||
'targetEntity' => 'CmsUser',
|
||||
'joinColumns' => array('user_id' => 'id')
|
||||
));*/
|
||||
));
|
||||
}
|
||||
}
|
||||
|
@ -17,5 +17,11 @@ class CmsPhonenumber extends Doctrine_Entity
|
||||
'length' => 50,
|
||||
'id' => true
|
||||
));
|
||||
|
||||
$mapping->mapManyToOne(array(
|
||||
'fieldName' => 'user',
|
||||
'targetEntity' => 'CmsUser',
|
||||
'joinColumns' => array('user_id' => 'id')
|
||||
));
|
||||
}
|
||||
}
|
||||
|
@ -35,21 +35,17 @@ class CmsUser extends Doctrine_Entity
|
||||
'type' => 'string',
|
||||
'length' => 255
|
||||
));
|
||||
|
||||
/*$mapping->hasMany('CmsPhonenumber as phonenumbers', array(
|
||||
'local' => 'id', 'foreign' => 'user_id'));
|
||||
$mapping->hasMany('CmsArticle as articles', array(
|
||||
'local' => 'id', 'foreign' => 'user_id'));*/
|
||||
|
||||
$mapping->mapOneToMany(array(
|
||||
'fieldName' => 'phonenumbers',
|
||||
'targetEntity' => 'CmsPhonenumber',
|
||||
|
||||
'mappedBy' => 'user'
|
||||
));
|
||||
|
||||
$mapping->mapOneToMany(array(
|
||||
'fieldName' => 'articles',
|
||||
'targetEntity' => 'CmsArticle',
|
||||
'mappedBy' => 'user'
|
||||
));
|
||||
|
||||
}
|
||||
|
@ -21,12 +21,6 @@ class ForumUser extends Doctrine_Entity
|
||||
));
|
||||
// register subclasses
|
||||
$mapping->setSubclasses(array('ForumAdministrator'));
|
||||
// the discriminator column
|
||||
$mapping->mapField(array(
|
||||
'fieldName' => 'dtype',
|
||||
'type' => 'string',
|
||||
'length' => 50
|
||||
));
|
||||
|
||||
// column-to-field mapping
|
||||
$mapping->mapField(array(
|
||||
@ -46,6 +40,7 @@ class ForumUser extends Doctrine_Entity
|
||||
'fieldName' => 'avatar',
|
||||
'targetEntity' => 'ForumAvatar',
|
||||
'joinColumns' => array('avatar_id' => 'id'),
|
||||
'cascade' => array('save')
|
||||
));
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user