started refactoring to final mapper structure for 1.0. different mapping strategies are factored out as separate strategy classes instead of inheritance.
This commit is contained in:
parent
dcc2a54e63
commit
eb02b4d002
@ -77,22 +77,6 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
|
||||
*/
|
||||
protected $_inheritanceType = Doctrine::INHERITANCETYPE_TABLE_PER_CLASS;
|
||||
|
||||
/**
|
||||
* The name of the column that acts as a discriminator to identify the type of an
|
||||
* object. Used in Single Table Inheritance and Class Table Inheritance.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $_discriminatorColumn;
|
||||
|
||||
/**
|
||||
* The discriminator map contains the mapping of discriminator values (keys)
|
||||
* to class names (values).
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_discriminatorMap;
|
||||
|
||||
/**
|
||||
* An array containing all templates attached to the class.
|
||||
*
|
||||
@ -120,10 +104,10 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
|
||||
protected $_filters = array();
|
||||
|
||||
/**
|
||||
* An array of column definitions,
|
||||
* keys are column names and values are column definitions
|
||||
* The mapped columns and their mapping definitions.
|
||||
* Keys are column names and values are definitions.
|
||||
*
|
||||
* the definition array has atleast the following values:
|
||||
* The definition array has atleast the following values:
|
||||
*
|
||||
* -- type the column type, eg. 'integer'
|
||||
* -- length the column length, eg. 11
|
||||
@ -156,6 +140,12 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
|
||||
*/
|
||||
protected $_columnNames = array();
|
||||
|
||||
/**
|
||||
* Caches enum value mappings. Keys are field names and values arrays with the
|
||||
* mapping.
|
||||
*/
|
||||
protected $_enumValues = array();
|
||||
|
||||
/**
|
||||
* @todo Implementation.
|
||||
*/
|
||||
@ -164,7 +154,8 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
|
||||
/**
|
||||
* Tree object associated with the class.
|
||||
*
|
||||
* @var Doctrine_Tree
|
||||
* @var Doctrine_Tree
|
||||
* @todo Belongs to the NestedSet Behavior plugin.
|
||||
*/
|
||||
protected $_tree;
|
||||
|
||||
@ -692,18 +683,25 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
|
||||
* @return mixed
|
||||
*/
|
||||
public function enumValue($fieldName, $index)
|
||||
{
|
||||
{
|
||||
if ($index instanceof Doctrine_Null) {
|
||||
return $index;
|
||||
}
|
||||
|
||||
if (isset($this->_enumValues[$fieldName][$index])) {
|
||||
return $this->_enumValues[$fieldName][$index];
|
||||
}
|
||||
|
||||
$columnName = $this->getColumnName($fieldName);
|
||||
if ( ! $this->_conn->getAttribute(Doctrine::ATTR_USE_NATIVE_ENUM) &&
|
||||
isset($this->_columns[$columnName]['values'][$index])) {
|
||||
return $this->_columns[$columnName]['values'][$index];
|
||||
$enumValue = $this->_columns[$columnName]['values'][$index];
|
||||
} else {
|
||||
$enumValue = $index;
|
||||
}
|
||||
|
||||
return $index;
|
||||
$this->_enumValues[$fieldName][$index] = $enumValue;
|
||||
|
||||
return $enumValue;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -13,6 +13,10 @@ class Doctrine_ClassMetadata_CodeDriver
|
||||
*/
|
||||
public function loadMetadataForClass($className, Doctrine_ClassMetadata $metadata)
|
||||
{
|
||||
if ( ! method_exists($className, 'initMetadata')) {
|
||||
throw new Doctrine_ClassMetadata_Exception("Unable to load metadata for class"
|
||||
. " '$className'. Callback method 'initMetadata' not found.");
|
||||
}
|
||||
call_user_func_array(array($className, 'initMetadata'), array($metadata));
|
||||
}
|
||||
}
|
@ -165,6 +165,11 @@ class Doctrine_ClassMetadata_Factory
|
||||
} while ($className = get_parent_class($className));
|
||||
|
||||
if ($className === false) {
|
||||
try {
|
||||
throw new Exception();
|
||||
} catch (Exception $e) {
|
||||
echo $e->getTraceAsString() . "<br />";
|
||||
}
|
||||
throw new Doctrine_ClassMetadata_Factory_Exception("Unknown component '$className'.");
|
||||
}
|
||||
|
||||
|
@ -109,7 +109,7 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
|
||||
$this->_mapper = $mapper;
|
||||
|
||||
if ($keyColumn === null) {
|
||||
$keyColumn = $mapper->getBoundQueryPart('indexBy');
|
||||
$keyColumn = $mapper->getClassMetadata()->getBoundQueryPart('indexBy');
|
||||
}
|
||||
|
||||
if ($keyColumn === null) {
|
||||
@ -214,7 +214,7 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
|
||||
|
||||
$keyColumn = isset($array['keyColumn']) ? $array['keyColumn'] : null;
|
||||
if ($keyColumn === null) {
|
||||
$keyColumn = $this->_mapper->getBoundQueryPart('indexBy');
|
||||
$keyColumn = $this->_mapper->getClassMetadata()->getBoundQueryPart('indexBy');
|
||||
}
|
||||
|
||||
if ($keyColumn !== null) {
|
||||
|
@ -1128,31 +1128,57 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
|
||||
* @return Doctrine_Mapper The mapper object.
|
||||
* @todo package:orm
|
||||
*/
|
||||
public function getMapper($entityClassName)
|
||||
/*public function getMapper($entityName)
|
||||
{
|
||||
if (isset($this->_mappers[$entityClassName])) {
|
||||
return $this->_mappers[$entityClassName];
|
||||
if (isset($this->_mappers[$entityName])) {
|
||||
return $this->_mappers[$entityName];
|
||||
}
|
||||
|
||||
$metadata = $this->getClassMetadata($entityClassName);
|
||||
$metadata = $this->getClassMetadata($entityName);
|
||||
$customMapperClassName = $metadata->getCustomMapperClass();
|
||||
if ($customMapperClassName !== null) {
|
||||
$mapper = new $customMapperClassName($entityClassName, $metadata);
|
||||
$mapper = new $customMapperClassName($entityName, $metadata);
|
||||
} else {
|
||||
// instantiate correct mapper type
|
||||
$inheritanceType = $metadata->getInheritanceType();
|
||||
if ($inheritanceType == Doctrine::INHERITANCETYPE_JOINED) {
|
||||
$mapper = new Doctrine_Mapper_Joined($entityClassName, $metadata);
|
||||
$mapper = new Doctrine_Mapper_Joined($entityName, $metadata);
|
||||
} else if ($inheritanceType == Doctrine::INHERITANCETYPE_SINGLE_TABLE) {
|
||||
$mapper = new Doctrine_Mapper_SingleTable($entityClassName, $metadata);
|
||||
$mapper = new Doctrine_Mapper_SingleTable($entityName, $metadata);
|
||||
} else if ($inheritanceType == Doctrine::INHERITANCETYPE_TABLE_PER_CLASS) {
|
||||
$mapper = new Doctrine_Mapper_TablePerClass($entityClassName, $metadata);
|
||||
$mapper = new Doctrine_Mapper_TablePerClass($entityName, $metadata);
|
||||
} else {
|
||||
throw new Doctrine_Connection_Exception("Unknown inheritance type '$inheritanceType'. Can't create mapper.");
|
||||
}
|
||||
}
|
||||
|
||||
$this->_mappers[$entityClassName] = $mapper;
|
||||
$this->_mappers[$entityName] = $mapper;
|
||||
|
||||
return $mapper;
|
||||
}*/
|
||||
|
||||
/**
|
||||
* Gets a mapper for the specified domain class that is used to map instances of
|
||||
* the class between the relational database and their object representation.
|
||||
*
|
||||
* @param string $entityClassName The name of the entity class.
|
||||
* @return Doctrine_Mapper The mapper object.
|
||||
* @todo package:orm
|
||||
*/
|
||||
public function getMapper($entityName)
|
||||
{
|
||||
if (isset($this->_mappers[$entityName])) {
|
||||
return $this->_mappers[$entityName];
|
||||
}
|
||||
|
||||
$metadata = $this->getClassMetadata($entityName);
|
||||
$customMapperClassName = $metadata->getCustomMapperClass();
|
||||
if ($customMapperClassName !== null) {
|
||||
$mapper = new $customMapperClassName($entityName, $metadata);
|
||||
} else {
|
||||
$mapper = new Doctrine_Mapper($entityName, $metadata);
|
||||
}
|
||||
$this->_mappers[$entityName] = $mapper;
|
||||
|
||||
return $mapper;
|
||||
}
|
||||
|
@ -92,7 +92,7 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module
|
||||
{
|
||||
$tree = array();
|
||||
foreach ($mappers as $k => $mapper) {
|
||||
if ( ! ($mapper instanceof Doctrine_Mapper_Abstract)) {
|
||||
if ( ! ($mapper instanceof Doctrine_Mapper)) {
|
||||
$mapper = $this->conn->getMapper($mapper);
|
||||
}
|
||||
$nm = $mapper->getComponentName();
|
||||
|
@ -1159,7 +1159,6 @@ class Doctrine_Export extends Doctrine_Connection_Module
|
||||
// as soon as ONE table is exported, because the data of one class is stored
|
||||
// across many tables.
|
||||
if ($classMetadata->getInheritanceType() == Doctrine::INHERITANCETYPE_JOINED) {
|
||||
//echo "joined.<br />";
|
||||
$parents = $classMetadata->getOption('parents');
|
||||
foreach ($parents as $parent) {
|
||||
$data = $classMetadata->getConnection()->getClassMetadata($parent)->getExportableFormat();
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: Hydrate.php 3192 2007-11-19 17:55:23Z romanb $
|
||||
* $Id$
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
@ -20,9 +20,8 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* Doctrine_Hydrate is a base class for Doctrine_RawSql and Doctrine_Query.
|
||||
* Its purpose is to populate object graphs.
|
||||
*
|
||||
* The hydrator has the tedious task to construct object or array graphs out of
|
||||
* a database result set.
|
||||
*
|
||||
* @package Doctrine
|
||||
* @subpackage Hydrate
|
||||
@ -31,6 +30,7 @@
|
||||
* @since 1.0
|
||||
* @version $Revision: 3192 $
|
||||
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
*/
|
||||
class Doctrine_Hydrator extends Doctrine_Hydrator_Abstract
|
||||
{
|
||||
@ -56,7 +56,7 @@ class Doctrine_Hydrator extends Doctrine_Hydrator_Abstract
|
||||
* 'map' => Custom index to use as the key in the result (if any)
|
||||
* )
|
||||
* )
|
||||
* @return array
|
||||
* @return mixed The created object/array graph.
|
||||
*/
|
||||
public function hydrateResultSet($stmt, $tableAliases, $hydrationMode = null)
|
||||
{
|
||||
@ -224,7 +224,7 @@ class Doctrine_Hydrator extends Doctrine_Hydrator_Abstract
|
||||
}
|
||||
$id[$rootAlias] = '';
|
||||
}
|
||||
|
||||
|
||||
$stmt->closeCursor();
|
||||
|
||||
$driver->flush();
|
||||
@ -294,6 +294,7 @@ class Doctrine_Hydrator extends Doctrine_Hydrator_Abstract
|
||||
foreach ($data as $key => $value) {
|
||||
// Parse each column name only once. Cache the results.
|
||||
if ( ! isset($cache[$key])) {
|
||||
// cache general information like the column name <-> field name mapping
|
||||
$e = explode('__', $key);
|
||||
$last = strtolower(array_pop($e));
|
||||
$cache[$key]['dqlAlias'] = $this->_tableAliases[strtolower(implode('__', $e))];
|
||||
@ -301,15 +302,20 @@ class Doctrine_Hydrator extends Doctrine_Hydrator_Abstract
|
||||
$table = $mapper->getTable();
|
||||
$fieldName = $mapper->getFieldName($last);
|
||||
$cache[$key]['fieldName'] = $fieldName;
|
||||
|
||||
// cache identifier information
|
||||
if ($table->isIdentifier($fieldName)) {
|
||||
$cache[$key]['isIdentifier'] = true;
|
||||
} else {
|
||||
$cache[$key]['isIdentifier'] = false;
|
||||
}
|
||||
|
||||
// cache type information
|
||||
$type = $table->getTypeOfColumn($last);
|
||||
if ($type == 'integer' || $type == 'string') {
|
||||
$cache[$key]['isSimpleType'] = true;
|
||||
} else {
|
||||
$cache[$key]['type'] = $type;
|
||||
$cache[$key]['isSimpleType'] = false;
|
||||
}
|
||||
}
|
||||
@ -329,7 +335,8 @@ class Doctrine_Hydrator extends Doctrine_Hydrator_Abstract
|
||||
if ($cache[$key]['isSimpleType']) {
|
||||
$rowData[$dqlAlias][$fieldName] = $value;
|
||||
} else {
|
||||
$rowData[$dqlAlias][$fieldName] = $mapper->prepareValue($fieldName, $value);
|
||||
$rowData[$dqlAlias][$fieldName] = $mapper->prepareValue(
|
||||
$fieldName, $value, $cache[$key]['type']);
|
||||
}
|
||||
|
||||
if ( ! isset($nonemptyComponents[$dqlAlias]) && $value !== null) {
|
||||
|
@ -31,7 +31,7 @@
|
||||
* @link www.phpdoctrine.org
|
||||
* @since 1.0
|
||||
*/
|
||||
abstract class Doctrine_Mapper_Abstract extends Doctrine_Configurable implements Countable
|
||||
class Doctrine_Mapper extends Doctrine_Configurable implements Countable
|
||||
{
|
||||
/**
|
||||
* @var Doctrine_Table Metadata container that represents the database table this
|
||||
@ -43,11 +43,6 @@ abstract class Doctrine_Mapper_Abstract extends Doctrine_Configurable implements
|
||||
* The name of the domain class this mapper is used for.
|
||||
*/
|
||||
protected $_domainClassName;
|
||||
|
||||
/**
|
||||
* The names of all the fields that are available on entities created by this mapper.
|
||||
*/
|
||||
protected $_fieldNames = array();
|
||||
|
||||
/**
|
||||
* The Doctrine_Connection object that the database connection of this mapper.
|
||||
@ -55,6 +50,11 @@ abstract class Doctrine_Mapper_Abstract extends Doctrine_Configurable implements
|
||||
* @var Doctrine_Connection $conn
|
||||
*/
|
||||
protected $_conn;
|
||||
|
||||
/**
|
||||
* The concrete mapping strategy that is used.
|
||||
*/
|
||||
protected $_mappingStrategy;
|
||||
|
||||
/**
|
||||
* @var array $identityMap first level cache
|
||||
@ -81,13 +81,18 @@ abstract class Doctrine_Mapper_Abstract extends Doctrine_Configurable implements
|
||||
* @param Doctrine_Table $table The table object used for the mapping procedure.
|
||||
* @throws Doctrine_Connection_Exception if there are no opened connections
|
||||
*/
|
||||
public function __construct($name, Doctrine_ClassMetadata $metadata)
|
||||
public function __construct($name, Doctrine_ClassMetadata $classMetadata)
|
||||
{
|
||||
$this->_domainClassName = $name;
|
||||
$this->_conn = $metadata->getConnection();
|
||||
$this->_classMetadata = $metadata;
|
||||
$this->_conn = $classMetadata->getConnection();
|
||||
$this->_classMetadata = $classMetadata;
|
||||
$this->setParent($this->_conn);
|
||||
$this->_repository = new Doctrine_Table_Repository($this);
|
||||
$this->_repository = new Doctrine_Table_Repository($this);
|
||||
if ($classMetadata->getInheritanceType() == Doctrine::INHERITANCETYPE_JOINED) {
|
||||
$this->_mappingStrategy = new Doctrine_Mapper_JoinedStrategy($this);
|
||||
} else {
|
||||
$this->_mappingStrategy = new Doctrine_Mapper_DefaultStrategy($this);
|
||||
}
|
||||
}
|
||||
|
||||
public function getMethodOwner($method)
|
||||
@ -150,6 +155,7 @@ abstract class Doctrine_Mapper_Abstract extends Doctrine_Configurable implements
|
||||
* getRepository
|
||||
*
|
||||
* @return Doctrine_Table_Repository
|
||||
* @todo refactor
|
||||
*/
|
||||
public function getRepository()
|
||||
{
|
||||
@ -161,6 +167,7 @@ abstract class Doctrine_Mapper_Abstract extends Doctrine_Configurable implements
|
||||
*
|
||||
* @params Doctrine_Connection a connection object
|
||||
* @return Doctrine_Table this object
|
||||
* @todo refactor
|
||||
*/
|
||||
public function setConnection(Doctrine_Connection $conn)
|
||||
{
|
||||
@ -195,7 +202,7 @@ abstract class Doctrine_Mapper_Abstract extends Doctrine_Configurable implements
|
||||
}
|
||||
|
||||
/**
|
||||
* finds a record by its identifier
|
||||
* Finds an entity by its primary key.
|
||||
*
|
||||
* @param $id database row id
|
||||
* @param int $hydrationMode Doctrine::HYDRATE_ARRAY or Doctrine::HYDRATE_RECORD
|
||||
@ -215,10 +222,10 @@ abstract class Doctrine_Mapper_Abstract extends Doctrine_Configurable implements
|
||||
}
|
||||
|
||||
/**
|
||||
* findAll
|
||||
* returns a collection of records
|
||||
* Finds all entities of the mapper's class.
|
||||
* Use with care.
|
||||
*
|
||||
* @param int $hydrationMode Doctrine::FETCH_ARRAY or Doctrine::FETCH_RECORD
|
||||
* @param int $hydrationMode Doctrine::HYDRATE_ARRAY or Doctrine::HYDRATE_RECORD
|
||||
* @return Doctrine_Collection
|
||||
*/
|
||||
public function findAll($hydrationMode = null)
|
||||
@ -262,50 +269,20 @@ abstract class Doctrine_Mapper_Abstract extends Doctrine_Configurable implements
|
||||
|
||||
return $query->query($dql, $params, $hydrationMode);
|
||||
}
|
||||
|
||||
/**
|
||||
* execute
|
||||
* fetches data using the provided queryKey and
|
||||
* the associated query in the query registry
|
||||
*
|
||||
* if no query for given queryKey is being found a
|
||||
* Doctrine_Query_Registry exception is being thrown
|
||||
*
|
||||
* @param string $queryKey the query key
|
||||
* @param array $params prepared statement params (if any)
|
||||
* @return mixed the fetched data
|
||||
*/
|
||||
public function execute($queryKey, $params = array(), $hydrationMode = Doctrine::HYDRATE_RECORD)
|
||||
{
|
||||
return Doctrine_Manager::getInstance()
|
||||
->getQueryRegistry()
|
||||
->get($queryKey, $this->getComponentName())
|
||||
->execute($params, $hydrationMode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes a named query.
|
||||
*
|
||||
* @param string $queryName The name that was used when storing the query.
|
||||
* @param array $params The query parameters.
|
||||
* @return mixed The result.
|
||||
* @deprecated
|
||||
*/
|
||||
public function executeNamedQuery($queryName, $params = array(), $hydrationMode = Doctrine::HYDRATE_RECORD)
|
||||
{
|
||||
return $this->execute($queryName, $params, $hydrationMode);
|
||||
}
|
||||
|
||||
/**
|
||||
* executeOne
|
||||
* fetches data using the provided queryKey and
|
||||
* the associated query in the query registry
|
||||
*
|
||||
* if no query for given queryKey is being found a
|
||||
* Doctrine_Query_Registry exception is being thrown
|
||||
*
|
||||
* @param string $queryKey the query key
|
||||
* @param array $params prepared statement params (if any)
|
||||
* @return mixed the fetched data
|
||||
*/
|
||||
public function executeOne($queryKey, $params = array(), $hydrationMode = Doctrine::HYDRATE_RECORD)
|
||||
{
|
||||
return Doctrine_Manager::getInstance()
|
||||
->getQueryRegistry()
|
||||
->get($queryKey, $this->getComponentName())
|
||||
->fetchOne($params, $hydrationMode);
|
||||
->createNamedQuery($queryName)
|
||||
->execute($params, $hydrationMode);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -364,8 +341,8 @@ abstract class Doctrine_Mapper_Abstract extends Doctrine_Configurable implements
|
||||
|
||||
/**
|
||||
* getRecord
|
||||
* first checks if record exists in identityMap, if not
|
||||
* returns a new record
|
||||
* First checks if record exists in identityMap, if not
|
||||
* returns a new record.
|
||||
*
|
||||
* @return Doctrine_Record
|
||||
*/
|
||||
@ -414,7 +391,6 @@ abstract class Doctrine_Mapper_Abstract extends Doctrine_Configurable implements
|
||||
|
||||
/**
|
||||
* @param $id database row id
|
||||
* @throws Doctrine_Find_Exception
|
||||
*/
|
||||
final public function getProxy($id = null)
|
||||
{
|
||||
@ -470,20 +446,11 @@ abstract class Doctrine_Mapper_Abstract extends Doctrine_Configurable implements
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
$a = $this->_conn->execute('SELECT COUNT(1) FROM ' . $this->_classMetadata->getOption('tableName'))->fetch(Doctrine::FETCH_NUM);
|
||||
$a = $this->_conn->execute('SELECT COUNT(1) FROM ' . $this->_classMetadata->getTableName())
|
||||
->fetch(Doctrine::FETCH_NUM);
|
||||
return current($a);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Doctrine_Query a Doctrine_Query object
|
||||
*/
|
||||
public function getQueryObject()
|
||||
{
|
||||
$graph = new Doctrine_Query($this->getConnection());
|
||||
$graph->load($this->getComponentName());
|
||||
return $graph;
|
||||
}
|
||||
|
||||
/**
|
||||
* prepareValue
|
||||
* this method performs special data preparation depending on
|
||||
@ -505,17 +472,19 @@ abstract class Doctrine_Mapper_Abstract extends Doctrine_Configurable implements
|
||||
* @throws Doctrine_Table_Exception if uncompression of gzip typed column fails *
|
||||
* @param string $field the name of the field
|
||||
* @param string $value field value
|
||||
* @param string $typeHint A hint on the type of the value. If provided, the type lookup
|
||||
* for the field can be skipped. Used i.e. during hydration to
|
||||
* improve performance on large and/or complex results.
|
||||
* @return mixed prepared value
|
||||
*/
|
||||
public function prepareValue($fieldName, $value)
|
||||
public function prepareValue($fieldName, $value, $typeHint = null)
|
||||
{
|
||||
if ($value === self::$_null) {
|
||||
return self::$_null;
|
||||
} else if ($value === null) {
|
||||
return null;
|
||||
} else {
|
||||
$type = $this->_classMetadata->getTypeOf($fieldName);
|
||||
|
||||
$type = is_null($typeHint) ? $this->_classMetadata->getTypeOf($fieldName) : $typeHint;
|
||||
switch ($type) {
|
||||
case 'integer':
|
||||
case 'string';
|
||||
@ -548,6 +517,17 @@ abstract class Doctrine_Mapper_Abstract extends Doctrine_Configurable implements
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hydrates the given data into the entity.
|
||||
*
|
||||
*/
|
||||
public function hydrate(Doctrine_Record $entity, array $data)
|
||||
{
|
||||
$this->_values = array_merge($this->_values, $this->cleanData($data));
|
||||
$this->_data = array_merge($this->_data, $data);
|
||||
$this->_extractIdentifier(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* getTree
|
||||
@ -579,11 +559,20 @@ abstract class Doctrine_Mapper_Abstract extends Doctrine_Configurable implements
|
||||
* getComponentName
|
||||
*
|
||||
* @return void
|
||||
* @deprecated Use getMappedClassName()
|
||||
*/
|
||||
public function getComponentName()
|
||||
{
|
||||
return $this->_domainClassName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of the class the mapper is used for.
|
||||
*/
|
||||
public function getMappedClassName()
|
||||
{
|
||||
return $this->_domainClassName;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns a string representation of this object
|
||||
@ -620,7 +609,7 @@ abstract class Doctrine_Mapper_Abstract extends Doctrine_Configurable implements
|
||||
{
|
||||
$results = $this->createQuery()->where($fieldName . ' = ?')->limit(1)->execute(
|
||||
array($value), $hydrationMode);
|
||||
return $hydrationMode === Doctrine::HYDRATE_ARRAY ? $results[0] : $results->getFirst();
|
||||
return $hydrationMode === Doctrine::HYDRATE_ARRAY ? array_shift($results) : $results->getFirst();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -631,6 +620,9 @@ abstract class Doctrine_Mapper_Abstract extends Doctrine_Configurable implements
|
||||
* findById, findByContactId, etc.
|
||||
*
|
||||
* @return void
|
||||
* @throws Doctrine_Mapper_Exception If the method called is an invalid find* method
|
||||
* or no find* method at all and therefore an invalid
|
||||
* method call.
|
||||
*/
|
||||
public function __call($method, $arguments)
|
||||
{
|
||||
@ -640,13 +632,13 @@ abstract class Doctrine_Mapper_Abstract extends Doctrine_Configurable implements
|
||||
} else if (substr($method, 0, 9) == 'findOneBy') {
|
||||
$by = substr($method, 9, strlen($method));
|
||||
$method = 'findOneBy';
|
||||
}/* else {
|
||||
throw new Doctrine_Mapper_Exception("Unknown method '$method'.");
|
||||
}*/
|
||||
} else {
|
||||
throw new Doctrine_Mapper_Exception("Undefined method '$method'.");
|
||||
}
|
||||
|
||||
if (isset($by)) {
|
||||
if ( ! isset($arguments[0])) {
|
||||
throw new Doctrine_Mapper_Exception('You must specify the value to findBy');
|
||||
throw new Doctrine_Mapper_Exception('You must specify the value to findBy.');
|
||||
}
|
||||
|
||||
$fieldName = Doctrine::tableize($by);
|
||||
@ -656,11 +648,9 @@ abstract class Doctrine_Mapper_Abstract extends Doctrine_Configurable implements
|
||||
return $this->$method($fieldName, $arguments[0], $hydrationMode);
|
||||
} else if ($this->_classMetadata->hasRelation($by)) {
|
||||
$relation = $this->_classMetadata->getRelation($by);
|
||||
|
||||
if ($relation['type'] === Doctrine_Relation::MANY) {
|
||||
throw new Doctrine_Table_Exception('Cannot findBy many relationship.');
|
||||
throw new Doctrine_Mapper_Exception('Cannot findBy many relationship.');
|
||||
}
|
||||
|
||||
return $this->$method($relation['local'], $arguments[0], $hydrationMode);
|
||||
} else {
|
||||
throw new Doctrine_Mapper_Exception('Cannot find by: ' . $by . '. Invalid field or relationship alias.');
|
||||
@ -674,7 +664,7 @@ abstract class Doctrine_Mapper_Abstract extends Doctrine_Configurable implements
|
||||
* @param Doctrine_Record $record The entity to save.
|
||||
* @param Doctrine_Connection $conn The connection to use. Will default to the mapper's
|
||||
* connection.
|
||||
* @throws Doctrine_Mapper_Exception If the mapper is unable to save the given record.
|
||||
* @throws Doctrine_Mapper_Exception If the mapper is unable to save the given entity.
|
||||
*/
|
||||
public function save(Doctrine_Record $record, Doctrine_Connection $conn = null)
|
||||
{
|
||||
@ -697,34 +687,11 @@ abstract class Doctrine_Mapper_Abstract extends Doctrine_Configurable implements
|
||||
try {
|
||||
$conn->beginInternalTransaction();
|
||||
$saveLater = $this->_saveRelated($record);
|
||||
//echo "num savelater:" . count($saveLater) . "<br />";
|
||||
|
||||
$record->state($state);
|
||||
|
||||
if ($record->isValid()) {
|
||||
$event = new Doctrine_Event($record, Doctrine_Event::RECORD_SAVE);
|
||||
$record->preSave($event);
|
||||
$this->getRecordListener()->preSave($event);
|
||||
|
||||
$state = $record->state();
|
||||
|
||||
if ( ! $event->skipOperation) {
|
||||
switch ($state) {
|
||||
case Doctrine_Record::STATE_TDIRTY:
|
||||
$this->insert($record);
|
||||
break;
|
||||
case Doctrine_Record::STATE_DIRTY:
|
||||
case Doctrine_Record::STATE_PROXY:
|
||||
$this->update($record);
|
||||
break;
|
||||
case Doctrine_Record::STATE_CLEAN:
|
||||
case Doctrine_Record::STATE_TCLEAN:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$this->getRecordListener()->postSave($event);
|
||||
$record->postSave($event);
|
||||
$this->_insertOrUpdate($record);
|
||||
} else {
|
||||
$conn->transaction->addInvalid($record);
|
||||
}
|
||||
@ -757,57 +724,34 @@ abstract class Doctrine_Mapper_Abstract extends Doctrine_Configurable implements
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts a single entity into the database, without any related entities.
|
||||
* Inserts or updates an entity, depending on it's state.
|
||||
*
|
||||
* @param Doctrine_Record $record The entity to insert.
|
||||
* @param Doctrine_Record $record The entity to insert/update.
|
||||
*/
|
||||
protected function insertSingleRecord(Doctrine_Record $record)
|
||||
protected function _insertOrUpdate(Doctrine_Record $record)
|
||||
{
|
||||
$fields = $record->getPrepared();
|
||||
if (empty($fields)) {
|
||||
return false;
|
||||
}
|
||||
$event = new Doctrine_Event($record, Doctrine_Event::RECORD_SAVE);
|
||||
$record->preSave($event);
|
||||
$this->getRecordListener()->preSave($event);
|
||||
|
||||
$class = $record->getClassMetadata();
|
||||
$identifier = (array) $class->getIdentifier();
|
||||
$fields = $this->_convertFieldToColumnNames($fields, $class);
|
||||
|
||||
$seq = $class->getTableOption('sequenceName');
|
||||
if ( ! empty($seq)) {
|
||||
$id = $this->_conn->sequence->nextId($seq);
|
||||
$seqName = $class->getIdentifier();
|
||||
$fields[$seqName] = $id;
|
||||
$record->assignIdentifier($id);
|
||||
}
|
||||
|
||||
$this->_conn->insert($class->getTableName(), $fields);
|
||||
|
||||
if (empty($seq) && count($identifier) == 1 && $identifier[0] == $class->getIdentifier() &&
|
||||
$class->getIdentifierType() != Doctrine::IDENTIFIER_NATURAL) {
|
||||
if (strtolower($this->_conn->getName()) == 'pgsql') {
|
||||
$seq = $class->getTableName() . '_' . $identifier[0];
|
||||
if ( ! $event->skipOperation) {
|
||||
switch ($record->state()) {
|
||||
case Doctrine_Record::STATE_TDIRTY:
|
||||
$this->_insert($record);
|
||||
break;
|
||||
case Doctrine_Record::STATE_DIRTY:
|
||||
case Doctrine_Record::STATE_PROXY:
|
||||
$this->_update($record);
|
||||
break;
|
||||
case Doctrine_Record::STATE_CLEAN:
|
||||
case Doctrine_Record::STATE_TCLEAN:
|
||||
// do nothing
|
||||
break;
|
||||
}
|
||||
|
||||
$id = $this->_conn->sequence->lastInsertId($seq);
|
||||
|
||||
if ( ! $id) {
|
||||
throw new Doctrine_Connection_Exception("Couldn't get last insert identifier.");
|
||||
}
|
||||
|
||||
$record->assignIdentifier($id);
|
||||
} else {
|
||||
$record->assignIdentifier(true);
|
||||
}
|
||||
}
|
||||
|
||||
protected function _convertFieldToColumnNames(array $fields, Doctrine_ClassMetadata $class)
|
||||
{
|
||||
$converted = array();
|
||||
foreach ($fields as $fieldName => $value) {
|
||||
$converted[$class->getColumnName($fieldName)] = $value;
|
||||
}
|
||||
|
||||
return $converted;
|
||||
|
||||
$this->getRecordListener()->postSave($event);
|
||||
$record->postSave($event);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -818,28 +762,7 @@ abstract class Doctrine_Mapper_Abstract extends Doctrine_Configurable implements
|
||||
*/
|
||||
public function saveSingleRecord(Doctrine_Record $record)
|
||||
{
|
||||
$event = new Doctrine_Event($record, Doctrine_Event::RECORD_SAVE);
|
||||
$record->preSave($event);
|
||||
$this->getRecordListener()->preSave($event);
|
||||
|
||||
if ( ! $event->skipOperation) {
|
||||
switch ($record->state()) {
|
||||
case Doctrine_Record::STATE_TDIRTY:
|
||||
$this->insert($record);
|
||||
break;
|
||||
case Doctrine_Record::STATE_DIRTY:
|
||||
case Doctrine_Record::STATE_PROXY:
|
||||
$this->update($record);
|
||||
break;
|
||||
case Doctrine_Record::STATE_CLEAN:
|
||||
case Doctrine_Record::STATE_TCLEAN:
|
||||
// do nothing
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$this->getRecordListener()->postSave($event);
|
||||
$record->postSave($event);
|
||||
$this->_insertOrUpdate($record);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -913,13 +836,14 @@ abstract class Doctrine_Mapper_Abstract extends Doctrine_Configurable implements
|
||||
. ' AND ' . $rel->getLocal() . ' = ?';
|
||||
$this->_conn->execute($query, array($r->getIncremented(), $record->getIncremented()));
|
||||
}
|
||||
|
||||
foreach ($relatedObject->getInsertDiff() as $r) {
|
||||
$assocRecord = $this->_conn->getMapper($assocTable->getComponentName())->create();
|
||||
|
||||
$assocMapper = $this->_conn->getMapper($assocTable->getComponentName());
|
||||
foreach ($relatedObject->getInsertDiff() as $r) {
|
||||
$assocRecord = $assocMapper->create();
|
||||
$assocRecord->set($assocTable->getFieldName($rel->getForeign()), $r);
|
||||
$assocRecord->set($assocTable->getFieldName($rel->getLocal()), $record);
|
||||
|
||||
$this->saveSingleRecord($assocRecord);
|
||||
$assocMapper->save($assocRecord);
|
||||
//$this->saveSingleRecord($assocRecord);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -932,7 +856,7 @@ abstract class Doctrine_Mapper_Abstract extends Doctrine_Configurable implements
|
||||
* @return boolean whether or not the update was successful
|
||||
* @todo Move to Doctrine_Table (which will become Doctrine_Mapper).
|
||||
*/
|
||||
protected function update(Doctrine_Record $record)
|
||||
protected function _update(Doctrine_Record $record)
|
||||
{
|
||||
$event = new Doctrine_Event($record, Doctrine_Event::RECORD_UPDATE);
|
||||
$record->preUpdate($event);
|
||||
@ -940,7 +864,7 @@ abstract class Doctrine_Mapper_Abstract extends Doctrine_Configurable implements
|
||||
$this->getRecordListener()->preUpdate($event);
|
||||
|
||||
if ( ! $event->skipOperation) {
|
||||
$this->_doUpdate($record);
|
||||
$this->_mappingStrategy->doUpdate($record);
|
||||
}
|
||||
|
||||
$this->getRecordListener()->postUpdate($event);
|
||||
@ -952,13 +876,13 @@ abstract class Doctrine_Mapper_Abstract extends Doctrine_Configurable implements
|
||||
/**
|
||||
* Updates an entity.
|
||||
*/
|
||||
protected function _doUpdate(Doctrine_Record $record)
|
||||
/*protected function _doUpdate(Doctrine_Record $record)
|
||||
{
|
||||
$identifier = $this->_convertFieldToColumnNames($record->identifier(), $this->_classMetadata);
|
||||
$data = $this->_convertFieldToColumnNames($record->getPrepared(), $this->_classMetadata);
|
||||
$this->_conn->update($this->_classMetadata->getTableName(), $data, $identifier);
|
||||
$record->assignIdentifier(true);
|
||||
}
|
||||
}*/
|
||||
|
||||
/**
|
||||
* Inserts an entity.
|
||||
@ -966,7 +890,7 @@ abstract class Doctrine_Mapper_Abstract extends Doctrine_Configurable implements
|
||||
* @param Doctrine_Record $record record to be inserted
|
||||
* @return boolean
|
||||
*/
|
||||
protected function insert(Doctrine_Record $record)
|
||||
protected function _insert(Doctrine_Record $record)
|
||||
{
|
||||
// trigger event
|
||||
$event = new Doctrine_Event($record, Doctrine_Event::RECORD_INSERT);
|
||||
@ -974,7 +898,7 @@ abstract class Doctrine_Mapper_Abstract extends Doctrine_Configurable implements
|
||||
$this->getRecordListener()->preInsert($event);
|
||||
|
||||
if ( ! $event->skipOperation) {
|
||||
$this->_doInsert($record);
|
||||
$this->_mappingStrategy->doInsert($record);
|
||||
}
|
||||
|
||||
// trigger event
|
||||
@ -986,21 +910,66 @@ abstract class Doctrine_Mapper_Abstract extends Doctrine_Configurable implements
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts an entity.
|
||||
* Inserts a single entity into the database, without any related entities.
|
||||
*
|
||||
* @param Doctrine_Record $record The entity to insert.
|
||||
*/
|
||||
protected function _doInsert(Doctrine_Record $record)
|
||||
/*protected function _doInsert(Doctrine_Record $record)
|
||||
{
|
||||
$this->insertSingleRecord($record);
|
||||
}
|
||||
$fields = $record->getPrepared();
|
||||
if (empty($fields)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($record->getClassMetadata() !== $this->_classMetadata) {
|
||||
echo $record->getClassMetadata()->getClassname() . ' != ' . $this->_classMetadata->getClassName() . "<br /><br />";
|
||||
try {
|
||||
throw new Exception();
|
||||
} catch (Exception $e) {
|
||||
echo $e->getTraceAsString() . "<br /><br />";
|
||||
}
|
||||
}
|
||||
|
||||
//$class = $record->getClassMetadata();
|
||||
$class = $this->_classMetadata;
|
||||
$identifier = (array) $class->getIdentifier();
|
||||
$fields = $this->_convertFieldToColumnNames($fields, $class);
|
||||
|
||||
$seq = $class->getTableOption('sequenceName');
|
||||
if ( ! empty($seq)) {
|
||||
$id = $this->_conn->sequence->nextId($seq);
|
||||
$seqName = $class->getIdentifier();
|
||||
$fields[$seqName] = $id;
|
||||
$record->assignIdentifier($id);
|
||||
}
|
||||
|
||||
$this->_conn->insert($class->getTableName(), $fields);
|
||||
|
||||
if (empty($seq) && count($identifier) == 1 && $identifier[0] == $class->getIdentifier() &&
|
||||
$class->getIdentifierType() != Doctrine::IDENTIFIER_NATURAL) {
|
||||
if (strtolower($this->_conn->getName()) == 'pgsql') {
|
||||
$seq = $class->getTableName() . '_' . $identifier[0];
|
||||
}
|
||||
|
||||
$id = $this->_conn->sequence->lastInsertId($seq);
|
||||
|
||||
if ( ! $id) {
|
||||
throw new Doctrine_Mapper_Exception("Couldn't get last insert identifier.");
|
||||
}
|
||||
|
||||
$record->assignIdentifier($id);
|
||||
} else {
|
||||
$record->assignIdentifier(true);
|
||||
}
|
||||
}*/
|
||||
|
||||
/**
|
||||
* deletes given record and all the related composites
|
||||
* this operation is isolated by a transaction
|
||||
* Deletes given entity and all it's related entities.
|
||||
*
|
||||
* this event can be listened by the onPreDelete and onDelete listeners
|
||||
* Triggered Events: onPreDelete, onDelete.
|
||||
*
|
||||
* @return boolean true on success, false on failure
|
||||
* @todo Move to Doctrine_Table (which will become Doctrine_Mapper).
|
||||
* @throws Doctrine_Mapper_Exception
|
||||
*/
|
||||
public function delete(Doctrine_Record $record, Doctrine_Connection $conn = null)
|
||||
{
|
||||
@ -1027,7 +996,7 @@ abstract class Doctrine_Mapper_Abstract extends Doctrine_Configurable implements
|
||||
$record->state(Doctrine_Record::STATE_LOCKED);
|
||||
|
||||
if ( ! $event->skipOperation) {
|
||||
$this->_doDelete($record, $conn);
|
||||
$this->_mappingStrategy->doDelete($record);
|
||||
} else {
|
||||
// return to original state
|
||||
$record->state($state);
|
||||
@ -1042,26 +1011,26 @@ abstract class Doctrine_Mapper_Abstract extends Doctrine_Configurable implements
|
||||
/**
|
||||
* Deletes an entity.
|
||||
*/
|
||||
protected function _doDelete(Doctrine_Record $record, Doctrine_Connection $conn)
|
||||
/*protected function _doDelete(Doctrine_Record $record)
|
||||
{
|
||||
try {
|
||||
$conn->beginInternalTransaction();
|
||||
$this->_conn->beginInternalTransaction();
|
||||
$this->_deleteComposites($record);
|
||||
|
||||
$record->state(Doctrine_Record::STATE_TDIRTY);
|
||||
|
||||
$identifier = $this->_convertFieldToColumnNames($record->identifier(), $this->_classMetadata);
|
||||
$conn->delete($this->_classMetadata->getTableName(), $identifier);
|
||||
$this->_conn->delete($this->_classMetadata->getTableName(), $identifier);
|
||||
$record->state(Doctrine_Record::STATE_TCLEAN);
|
||||
|
||||
$this->removeRecord($record);
|
||||
$conn->commit();
|
||||
$this->_conn->commit();
|
||||
} catch (Exception $e) {
|
||||
$conn->rollback();
|
||||
$this->_conn->rollback();
|
||||
throw $e;
|
||||
}
|
||||
|
||||
}
|
||||
}*/
|
||||
|
||||
/**
|
||||
* deletes all related composites
|
||||
@ -1070,7 +1039,7 @@ abstract class Doctrine_Mapper_Abstract extends Doctrine_Configurable implements
|
||||
* @throws PDOException if something went wrong at database level
|
||||
* @return void
|
||||
*/
|
||||
protected function _deleteComposites(Doctrine_Record $record)
|
||||
/*protected function _deleteComposites(Doctrine_Record $record)
|
||||
{
|
||||
foreach ($this->_classMetadata->getRelations() as $fk) {
|
||||
if ($fk->isComposite()) {
|
||||
@ -1081,7 +1050,7 @@ abstract class Doctrine_Mapper_Abstract extends Doctrine_Configurable implements
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
public function executeQuery(Doctrine_Query $query)
|
||||
{
|
||||
@ -1092,22 +1061,8 @@ abstract class Doctrine_Mapper_Abstract extends Doctrine_Configurable implements
|
||||
{
|
||||
return $this->_classMetadata;
|
||||
}
|
||||
|
||||
public function getFieldName($columnName)
|
||||
{
|
||||
return $this->_classMetadata->getFieldName($columnName);
|
||||
}
|
||||
|
||||
public function getFieldNames()
|
||||
{
|
||||
if ($this->_fieldNames) {
|
||||
return $this->_fieldNames;
|
||||
}
|
||||
$this->_fieldNames = $this->_classMetadata->getFieldNames();
|
||||
return $this->_fieldNames;
|
||||
}
|
||||
|
||||
public function getOwningTable($fieldName)
|
||||
public function getClassMetadata()
|
||||
{
|
||||
return $this->_classMetadata;
|
||||
}
|
||||
@ -1122,6 +1077,10 @@ abstract class Doctrine_Mapper_Abstract extends Doctrine_Configurable implements
|
||||
var_dump($this->_invokedMethods);
|
||||
}
|
||||
|
||||
public function free()
|
||||
{
|
||||
$this->_mappingStrategy = null;
|
||||
}
|
||||
|
||||
/*public function addToWhere($componentAlias, array &$sqlWhereParts, Doctrine_Query $query)
|
||||
{
|
||||
@ -1133,6 +1092,21 @@ abstract class Doctrine_Mapper_Abstract extends Doctrine_Configurable implements
|
||||
|
||||
}*/
|
||||
|
||||
public function getFieldName($columnName)
|
||||
{
|
||||
return $this->_mappingStrategy->getFieldName($columnName);
|
||||
}
|
||||
|
||||
public function getFieldNames()
|
||||
{
|
||||
return $this->_mappingStrategy->getFieldNames();
|
||||
}
|
||||
|
||||
public function getOwningTable($fieldName)
|
||||
{
|
||||
return $this->_mappingStrategy->getOwningTable($fieldName);
|
||||
}
|
||||
|
||||
/* Hooks used during SQL query construction to manipulate the query. */
|
||||
|
||||
/**
|
||||
@ -1140,7 +1114,7 @@ abstract class Doctrine_Mapper_Abstract extends Doctrine_Configurable implements
|
||||
*/
|
||||
public function getCustomJoins()
|
||||
{
|
||||
return array();
|
||||
return $this->_mappingStrategy->getCustomJoins();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1148,6 +1122,6 @@ abstract class Doctrine_Mapper_Abstract extends Doctrine_Configurable implements
|
||||
*/
|
||||
public function getCustomFields()
|
||||
{
|
||||
return array();
|
||||
return $this->_mappingStrategy->getCustomFields();
|
||||
}
|
||||
}
|
117
lib/Doctrine/Mapper/DefaultStrategy.php
Normal file
117
lib/Doctrine/Mapper/DefaultStrategy.php
Normal file
@ -0,0 +1,117 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* The default strategy maps a single instance to a single database table, as is
|
||||
* the case in Single Table Inheritance & Concrete Table Inheritance.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
class Doctrine_Mapper_DefaultStrategy extends Doctrine_Mapper_Strategy
|
||||
{
|
||||
|
||||
/**
|
||||
* Deletes an entity.
|
||||
*/
|
||||
public function doDelete(Doctrine_Record $record)
|
||||
{
|
||||
$conn = $this->_mapper->getConnection();
|
||||
$metadata = $this->_mapper->getClassMetadata();
|
||||
try {
|
||||
$conn->beginInternalTransaction();
|
||||
$this->_deleteComposites($record);
|
||||
|
||||
$record->state(Doctrine_Record::STATE_TDIRTY);
|
||||
|
||||
$identifier = $this->_convertFieldToColumnNames($record->identifier(), $metadata);
|
||||
$this->_deleteRow($metadata->getTableName(), $identifier);
|
||||
$record->state(Doctrine_Record::STATE_TCLEAN);
|
||||
|
||||
$this->_mapper->removeRecord($record);
|
||||
$conn->commit();
|
||||
} catch (Exception $e) {
|
||||
$conn->rollback();
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* deletes all related composites
|
||||
* this method is always called internally when a record is deleted
|
||||
*
|
||||
* @throws PDOException if something went wrong at database level
|
||||
* @return void
|
||||
*/
|
||||
protected function _deleteComposites(Doctrine_Record $record)
|
||||
{
|
||||
$classMetadata = $this->_mapper->getClassMetadata();
|
||||
foreach ($classMetadata->getRelations() as $fk) {
|
||||
if ($fk->isComposite()) {
|
||||
$obj = $record->get($fk->getAlias());
|
||||
if ($obj instanceof Doctrine_Record &&
|
||||
$obj->state() != Doctrine_Record::STATE_LOCKED) {
|
||||
$obj->delete($this->_mapper->getConnection());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts a single entity into the database, without any related entities.
|
||||
*
|
||||
* @param Doctrine_Record $record The entity to insert.
|
||||
*/
|
||||
public function doInsert(Doctrine_Record $record)
|
||||
{
|
||||
$conn = $this->_mapper->getConnection();
|
||||
|
||||
$fields = $record->getPrepared();
|
||||
if (empty($fields)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//$class = $record->getClassMetadata();
|
||||
$class = $this->_mapper->getClassMetadata();
|
||||
$identifier = (array) $class->getIdentifier();
|
||||
$fields = $this->_convertFieldToColumnNames($fields, $class);
|
||||
|
||||
$seq = $class->getTableOption('sequenceName');
|
||||
if ( ! empty($seq)) {
|
||||
$id = $conn->sequence->nextId($seq);
|
||||
$seqName = $class->getIdentifier();
|
||||
$fields[$seqName] = $id;
|
||||
$record->assignIdentifier($id);
|
||||
}
|
||||
|
||||
$this->_insertRow($class->getTableName(), $fields);
|
||||
|
||||
if (empty($seq) && count($identifier) == 1 && $identifier[0] == $class->getIdentifier() &&
|
||||
$class->getIdentifierType() != Doctrine::IDENTIFIER_NATURAL) {
|
||||
if (strtolower($conn->getName()) == 'pgsql') {
|
||||
$seq = $class->getTableName() . '_' . $identifier[0];
|
||||
}
|
||||
|
||||
$id = $conn->sequence->lastInsertId($seq);
|
||||
|
||||
if ( ! $id) {
|
||||
throw new Doctrine_Mapper_Exception("Couldn't get last insert identifier.");
|
||||
}
|
||||
|
||||
$record->assignIdentifier($id);
|
||||
} else {
|
||||
$record->assignIdentifier(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates an entity.
|
||||
*/
|
||||
public function doUpdate(Doctrine_Record $record)
|
||||
{
|
||||
$conn = $this->_mapper->getConnection();
|
||||
$classMetadata = $this->_mapper->getClassMetadata();
|
||||
$identifier = $this->_convertFieldToColumnNames($record->identifier(), $classMetadata);
|
||||
$data = $this->_convertFieldToColumnNames($record->getPrepared(), $classMetadata);
|
||||
$this->_updateRow($classMetadata->getTableName(), $data, $identifier);
|
||||
$record->assignIdentifier(true);
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
class Doctrine_Mapper_Joined extends Doctrine_Mapper_Abstract
|
||||
class Doctrine_Mapper_JoinedStrategy extends Doctrine_Mapper_Strategy
|
||||
{
|
||||
protected $_columnNameFieldNameMap = array();
|
||||
|
||||
@ -10,31 +10,32 @@ class Doctrine_Mapper_Joined extends Doctrine_Mapper_Abstract
|
||||
* @param Doctrine_Record $record record to be inserted
|
||||
* @return boolean
|
||||
*/
|
||||
protected function _doInsert(Doctrine_Record $record)
|
||||
public function doInsert(Doctrine_Record $record)
|
||||
{
|
||||
$class = $this->_classMetadata;
|
||||
$class = $this->_mapper->getClassMetadata();
|
||||
$conn = $this->_mapper->getConnection();
|
||||
|
||||
$dataSet = $this->_formatDataSet($record);
|
||||
$dataSet = $this->_groupFieldsByDefiningClass($record);
|
||||
$component = $class->getClassName();
|
||||
$classes = $class->getParentClasses();
|
||||
array_unshift($classes, $component);
|
||||
|
||||
try {
|
||||
$this->_conn->beginInternalTransaction();
|
||||
$conn->beginInternalTransaction();
|
||||
$identifier = null;
|
||||
foreach (array_reverse($classes) as $k => $parent) {
|
||||
$parentClass = $this->_conn->getClassMetadata($parent);
|
||||
$parentClass = $conn->getClassMetadata($parent);
|
||||
if ($k == 0) {
|
||||
$identifierType = $parentClass->getIdentifierType();
|
||||
if ($identifierType == Doctrine::IDENTIFIER_AUTOINC) {
|
||||
$this->_conn->insert($parentClass->getTableName(), $dataSet[$parent]);
|
||||
$identifier = $this->_conn->sequence->lastInsertId();
|
||||
$this->_insertRow($parentClass->getTableName(), $dataSet[$parent]);
|
||||
$identifier = $conn->sequence->lastInsertId();
|
||||
} else if ($identifierType == Doctrine::IDENTIFIER_SEQUENCE) {
|
||||
$seq = $record->getClassMetadata()->getTableOption('sequenceName');
|
||||
if ( ! empty($seq)) {
|
||||
$identifier = $this->_conn->sequence->nextId($seq);
|
||||
$identifier = $conn->sequence->nextId($seq);
|
||||
$dataSet[$parent][$parentClass->getIdentifier()] = $identifier;
|
||||
$this->_conn->insert($parentClass->getTableName(), $dataSet[$parent]);
|
||||
$this->_insertRow($parentClass->getTableName(), $dataSet[$parent]);
|
||||
}
|
||||
} else {
|
||||
throw new Doctrine_Mapper_Exception("Unsupported identifier type '$identifierType'.");
|
||||
@ -44,12 +45,12 @@ class Doctrine_Mapper_Joined extends Doctrine_Mapper_Abstract
|
||||
foreach ((array) $record->identifier() as $id => $value) {
|
||||
$dataSet[$parent][$parentClass->getColumnName($id)] = $value;
|
||||
}
|
||||
$this->_conn->insert($parentClass->getTableName(), $dataSet[$parent]);
|
||||
$this->_insertRow($parentClass->getTableName(), $dataSet[$parent]);
|
||||
}
|
||||
}
|
||||
$this->_conn->commit();
|
||||
$conn->commit();
|
||||
} catch (Exception $e) {
|
||||
$this->_conn->rollback();
|
||||
$conn->rollback();
|
||||
throw $e;
|
||||
}
|
||||
|
||||
@ -63,13 +64,14 @@ class Doctrine_Mapper_Joined extends Doctrine_Mapper_Abstract
|
||||
* @return boolean whether or not the update was successful
|
||||
* @todo Move to Doctrine_Table (which will become Doctrine_Mapper).
|
||||
*/
|
||||
protected function _doUpdate(Doctrine_Record $record)
|
||||
public function doUpdate(Doctrine_Record $record)
|
||||
{
|
||||
$table = $this->_classMetadata;
|
||||
$identifier = $this->_convertFieldToColumnNames($record->identifier(), $this->_classMetadata);
|
||||
$dataSet = $this->_formatDataSet($record);
|
||||
$component = $table->getClassName();
|
||||
$classes = $table->getParentClasses();
|
||||
$conn = $this->_mapper->getConnection();
|
||||
$classMetadata = $this->_mapper->getClassMetadata();
|
||||
$identifier = $this->_convertFieldToColumnNames($record->identifier(), $classMetadata);
|
||||
$dataSet = $this->_groupFieldsByDefiningClass($record);
|
||||
$component = $classMetadata->getClassName();
|
||||
$classes = $classMetadata->getParentClasses();
|
||||
array_unshift($classes, $component);
|
||||
|
||||
foreach ($record as $field => $value) {
|
||||
@ -82,8 +84,8 @@ class Doctrine_Mapper_Joined extends Doctrine_Mapper_Abstract
|
||||
}
|
||||
|
||||
foreach (array_reverse($classes) as $class) {
|
||||
$parentTable = $this->_conn->getClassMetadata($class);
|
||||
$this->_conn->update($parentTable->getTableName(), $dataSet[$class], $identifier);
|
||||
$parentTable = $conn->getClassMetadata($class);
|
||||
$this->_updateRow($parentTable->getTableName(), $dataSet[$class], $identifier);
|
||||
}
|
||||
|
||||
$record->assignIdentifier(true);
|
||||
@ -95,10 +97,11 @@ class Doctrine_Mapper_Joined extends Doctrine_Mapper_Abstract
|
||||
* Deletes an entity that is part of a Class Table Inheritance hierarchy.
|
||||
*
|
||||
*/
|
||||
protected function _doDelete(Doctrine_Record $record, Doctrine_Connection $conn)
|
||||
public function doDelete(Doctrine_Record $record)
|
||||
{
|
||||
$conn = $this->_mapper->getConnection();
|
||||
try {
|
||||
$class = $this->_classMetadata;
|
||||
$class = $this->_mapper->getClassMetadata();
|
||||
$conn->beginInternalTransaction();
|
||||
$this->deleteComposites($record);
|
||||
|
||||
@ -108,13 +111,13 @@ class Doctrine_Mapper_Joined extends Doctrine_Mapper_Abstract
|
||||
|
||||
foreach ($class->getParentClasses() as $parent) {
|
||||
$parentClass = $conn->getClassMetadata($parent);
|
||||
$conn->delete($parentClass->getTableName(), $identifier);
|
||||
$this->_deleteRow($parentClass->getTableName(), $identifier);
|
||||
}
|
||||
|
||||
$conn->delete($class->getTableName(), $identifier);
|
||||
$record->state(Doctrine_Record::STATE_TCLEAN);
|
||||
|
||||
$this->removeRecord($record);
|
||||
$this->_mapper->removeRecord($record);
|
||||
$conn->commit();
|
||||
} catch (Exception $e) {
|
||||
$conn->rollback();
|
||||
@ -135,11 +138,12 @@ class Doctrine_Mapper_Joined extends Doctrine_Mapper_Abstract
|
||||
public function getCustomJoins()
|
||||
{
|
||||
$customJoins = array();
|
||||
foreach ($this->_classMetadata->getParentClasses() as $parentClass) {
|
||||
$classMetadata = $this->_mapper->getClassMetadata();
|
||||
foreach ($classMetadata->getParentClasses() as $parentClass) {
|
||||
$customJoins[$parentClass] = 'INNER';
|
||||
}
|
||||
foreach ((array)$this->_classMetadata->getSubclasses() as $subClass) {
|
||||
if ($subClass != $this->_domainClassName) {
|
||||
foreach ((array)$classMetadata->getSubclasses() as $subClass) {
|
||||
if ($subClass != $this->_mapper->getComponentName()) {
|
||||
$customJoins[$subClass] = 'LEFT';
|
||||
}
|
||||
}
|
||||
@ -158,10 +162,12 @@ class Doctrine_Mapper_Joined extends Doctrine_Mapper_Abstract
|
||||
*/
|
||||
public function getCustomFields()
|
||||
{
|
||||
$fields = array($this->_classMetadata->getInheritanceOption('discriminatorColumn'));
|
||||
if ($this->_classMetadata->getSubclasses()) {
|
||||
foreach ($this->_classMetadata->getSubclasses() as $subClass) {
|
||||
$fields = array_merge($this->_conn->getMetadata($subClass)->getFieldNames(), $fields);
|
||||
$classMetadata = $this->_mapper->getClassMetadata();
|
||||
$conn = $this->_mapper->getConnection();
|
||||
$fields = array($classMetadata->getInheritanceOption('discriminatorColumn'));
|
||||
if ($classMetadata->getSubclasses()) {
|
||||
foreach ($classMetadata->getSubclasses() as $subClass) {
|
||||
$fields = array_merge($conn->getMetadata($subClass)->getFieldNames(), $fields);
|
||||
}
|
||||
}
|
||||
|
||||
@ -177,7 +183,7 @@ class Doctrine_Mapper_Joined extends Doctrine_Mapper_Abstract
|
||||
return $this->_fieldNames;
|
||||
}
|
||||
|
||||
$fieldNames = $this->_classMetadata->getFieldNames();
|
||||
$fieldNames = $this->_mapper->getClassMetadata()->getFieldNames();
|
||||
$this->_fieldNames = array_unique($fieldNames);
|
||||
|
||||
return $fieldNames;
|
||||
@ -192,21 +198,24 @@ class Doctrine_Mapper_Joined extends Doctrine_Mapper_Abstract
|
||||
return $this->_columnNameFieldNameMap[$columnName];
|
||||
}
|
||||
|
||||
if ($this->_classMetadata->hasColumn($columnName)) {
|
||||
$this->_columnNameFieldNameMap[$columnName] = $this->_classMetadata->getFieldName($columnName);
|
||||
$classMetadata = $this->_mapper->getClassMetadata();
|
||||
$conn = $this->_mapper->getConnection();
|
||||
|
||||
if ($classMetadata->hasColumn($columnName)) {
|
||||
$this->_columnNameFieldNameMap[$columnName] = $classMetadata->getFieldName($columnName);
|
||||
return $this->_columnNameFieldNameMap[$columnName];
|
||||
}
|
||||
|
||||
foreach ($this->_classMetadata->getParentClasses() as $parentClass) {
|
||||
$parentTable = $this->_conn->getMetadata($parentClass);
|
||||
foreach ($classMetadata->getParentClasses() as $parentClass) {
|
||||
$parentTable = $conn->getClassMetadata($parentClass);
|
||||
if ($parentTable->hasColumn($columnName)) {
|
||||
$this->_columnNameFieldNameMap[$columnName] = $parentTable->getFieldName($columnName);
|
||||
return $this->_columnNameFieldNameMap[$columnName];
|
||||
}
|
||||
}
|
||||
|
||||
foreach ((array)$this->_classMetadata->getSubclasses() as $subClass) {
|
||||
$subTable = $this->_conn->getMetadata($subClass);
|
||||
foreach ((array)$classMetadata->getSubclasses() as $subClass) {
|
||||
$subTable = $conn->getClassMetadata($subClass);
|
||||
if ($subTable->hasColumn($columnName)) {
|
||||
$this->_columnNameFieldNameMap[$columnName] = $subTable->getFieldName($columnName);
|
||||
return $this->_columnNameFieldNameMap[$columnName];
|
||||
@ -221,20 +230,22 @@ class Doctrine_Mapper_Joined extends Doctrine_Mapper_Abstract
|
||||
* @todo Looks like this better belongs into the ClassMetadata class.
|
||||
*/
|
||||
public function getOwningTable($fieldName)
|
||||
{
|
||||
if ($this->_classMetadata->hasField($fieldName) && ! $this->_classMetadata->isInheritedField($fieldName)) {
|
||||
return $this->_classMetadata;
|
||||
{
|
||||
$conn = $this->_mapper->getConnection();
|
||||
$classMetadata = $this->_mapper->getClassMetadata();
|
||||
if ($classMetadata->hasField($fieldName) && ! $classMetadata->isInheritedField($fieldName)) {
|
||||
return $classMetadata;
|
||||
}
|
||||
|
||||
foreach ($this->_classMetadata->getParentClasses() as $parentClass) {
|
||||
$parentTable = $this->_conn->getMetadata($parentClass);
|
||||
foreach ($classMetadata->getParentClasses() as $parentClass) {
|
||||
$parentTable = $conn->getClassMetadata($parentClass);
|
||||
if ($parentTable->hasField($fieldName) && ! $parentTable->isInheritedField($fieldName)) {
|
||||
return $parentTable;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ((array)$this->_classMetadata->getSubclasses() as $subClass) {
|
||||
$subTable = $this->_conn->getMetadata($subClass);
|
||||
foreach ((array)$classMetadata->getSubclasses() as $subClass) {
|
||||
$subTable = $conn->getClassMetadata($subClass);
|
||||
if ($subTable->hasField($fieldName) && ! $subTable->isInheritedField($fieldName)) {
|
||||
return $subTable;
|
||||
}
|
||||
@ -248,24 +259,25 @@ class Doctrine_Mapper_Joined extends Doctrine_Mapper_Abstract
|
||||
* are grouped by the class names they belong to.
|
||||
*
|
||||
*/
|
||||
protected function _formatDataSet(Doctrine_Record $record)
|
||||
protected function _groupFieldsByDefiningClass(Doctrine_Record $record)
|
||||
{
|
||||
$table = $this->_classMetadata;
|
||||
$conn = $this->_mapper->getConnection();
|
||||
$classMetadata = $this->_mapper->getClassMetadata();
|
||||
$dataSet = array();
|
||||
$component = $table->getClassName();
|
||||
$component = $classMetadata->getClassName();
|
||||
$array = $record->getPrepared();
|
||||
|
||||
$classes = array_merge(array($component), $this->_classMetadata->getParentClasses());
|
||||
$classes = array_merge(array($component), $classMetadata->getParentClasses());
|
||||
|
||||
foreach ($classes as $class) {
|
||||
$dataSet[$class] = array();
|
||||
$metadata = $this->_conn->getMetadata($class);
|
||||
foreach ($metadata->getColumns() as $columnName => $definition) {
|
||||
$parentClassMetadata = $conn->getClassMetadata($class);
|
||||
foreach ($parentClassMetadata->getColumns() as $columnName => $definition) {
|
||||
if ((isset($definition['primary']) && $definition['primary'] === true) ||
|
||||
(isset($definition['inherited']) && $definition['inherited'] === true)) {
|
||||
continue;
|
||||
}
|
||||
$fieldName = $table->getFieldName($columnName);
|
||||
$fieldName = $classMetadata->getFieldName($columnName);
|
||||
if ( ! array_key_exists($fieldName, $array)) {
|
||||
continue;
|
||||
}
|
@ -1,57 +0,0 @@
|
||||
<?php
|
||||
|
||||
class Doctrine_Mapper_SingleTable extends Doctrine_Mapper_Abstract
|
||||
{
|
||||
|
||||
/*public function addToWhere($componentAlias, array &$sqlWhereParts, Doctrine_Query $query)
|
||||
{
|
||||
$array = array();
|
||||
$componentParts = $query->getQueryComponent($componentAlias);
|
||||
$sqlTableAlias = $query->getSqlTableAlias($componentAlias);
|
||||
$array[$sqlTableAlias][] = $this->getDiscriminatorColumn();
|
||||
|
||||
// apply inheritance maps
|
||||
$str = '';
|
||||
$c = array();
|
||||
|
||||
$index = 0;
|
||||
foreach ($array as $tableAlias => $maps) {
|
||||
$a = array();
|
||||
|
||||
// don't use table aliases if the query isn't a select query
|
||||
if ($query->getType() !== Doctrine_Query::SELECT) {
|
||||
$tableAlias = '';
|
||||
} else {
|
||||
$tableAlias .= '.';
|
||||
}
|
||||
|
||||
foreach ($maps as $map) {
|
||||
$b = array();
|
||||
foreach ($map as $field => $value) {
|
||||
$identifier = $this->_conn->quoteIdentifier($tableAlias . $field);
|
||||
|
||||
if ($index > 0) {
|
||||
$b[] = '(' . $identifier . ' = ' . $this->_conn->quote($value)
|
||||
. ' OR ' . $identifier . ' IS NULL)';
|
||||
} else {
|
||||
$b[] = $identifier . ' = ' . $this->_conn->quote($value);
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! empty($b)) {
|
||||
$a[] = implode(' AND ', $b);
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! empty($a)) {
|
||||
$c[] = implode(' AND ', $a);
|
||||
}
|
||||
$index++;
|
||||
}
|
||||
|
||||
$str .= implode(' AND ', $c);
|
||||
|
||||
return $str;
|
||||
}*/
|
||||
}
|
||||
|
105
lib/Doctrine/Mapper/Strategy.php
Normal file
105
lib/Doctrine/Mapper/Strategy.php
Normal file
@ -0,0 +1,105 @@
|
||||
<?php
|
||||
|
||||
abstract class Doctrine_Mapper_Strategy
|
||||
{
|
||||
protected $_mapper;
|
||||
|
||||
/**
|
||||
* The names of all the fields that are available on entities created by this mapper.
|
||||
*/
|
||||
protected $_fieldNames = array();
|
||||
|
||||
public function __construct(Doctrine_Mapper $mapper)
|
||||
{
|
||||
$this->_mapper = $mapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assumes that the keys of the given field array are field names and converts
|
||||
* them to column names.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function _convertFieldToColumnNames(array $fields, Doctrine_ClassMetadata $class)
|
||||
{
|
||||
$converted = array();
|
||||
foreach ($fields as $fieldName => $value) {
|
||||
$converted[$class->getColumnName($fieldName)] = $value;
|
||||
}
|
||||
|
||||
return $converted;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback that is invoked during the SQL construction process.
|
||||
*/
|
||||
public function getCustomJoins()
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback that is invoked during the SQL construction process.
|
||||
*/
|
||||
public function getCustomFields()
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
public function getFieldName($columnName)
|
||||
{
|
||||
return $this->_mapper->getClassMetadata()->getFieldName($columnName);
|
||||
}
|
||||
|
||||
public function getFieldNames()
|
||||
{
|
||||
if ($this->_fieldNames) {
|
||||
return $this->_fieldNames;
|
||||
}
|
||||
$this->_fieldNames = $this->_mapper->getClassMetadata()->getFieldNames();
|
||||
return $this->_fieldNames;
|
||||
}
|
||||
|
||||
public function getOwningTable($fieldName)
|
||||
{
|
||||
return $this->_mapper->getClassMetadata();
|
||||
}
|
||||
|
||||
abstract public function doDelete(Doctrine_Record $record);
|
||||
abstract public function doInsert(Doctrine_Record $record);
|
||||
abstract public function doUpdate(Doctrine_Record $record);
|
||||
|
||||
/**
|
||||
* Inserts a row into a table.
|
||||
*
|
||||
* @todo This method could be used to allow mapping to secondary table(s).
|
||||
* @see http://www.oracle.com/technology/products/ias/toplink/jpa/resources/toplink-jpa-annotations.html#SecondaryTable
|
||||
*/
|
||||
protected function _insertRow($tableName, array $data)
|
||||
{
|
||||
$this->_mapper->getConnection()->insert($tableName, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes rows of a table.
|
||||
*
|
||||
* @todo This method could be used to allow mapping to secondary table(s).
|
||||
* @see http://www.oracle.com/technology/products/ias/toplink/jpa/resources/toplink-jpa-annotations.html#SecondaryTable
|
||||
*/
|
||||
protected function _deleteRow($tableName, array $identifierToMatch)
|
||||
{
|
||||
$this->_mapper->getConnection()->delete($tableName, $identifierToMatch);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes rows of a table.
|
||||
*
|
||||
* @todo This method could be used to allow mapping to secondary table(s).
|
||||
* @see http://www.oracle.com/technology/products/ias/toplink/jpa/resources/toplink-jpa-annotations.html#SecondaryTable
|
||||
*/
|
||||
protected function _updateRow($tableName, array $data, array $identifierToMatch)
|
||||
{
|
||||
$this->_mapper->getConnection()->update($tableName, $data, $identifierToMatch);
|
||||
}
|
||||
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
<?php
|
||||
|
||||
class Doctrine_Mapper_TablePerClass extends Doctrine_Mapper_Abstract
|
||||
{
|
||||
|
||||
|
||||
|
||||
}
|
@ -562,7 +562,7 @@ abstract class Doctrine_Query_Abstract
|
||||
$array = array();
|
||||
foreach ($this->_queryComponents as $componentAlias => $data) {
|
||||
$sqlTableAlias = $this->getSqlTableAlias($componentAlias);
|
||||
if ( ! $data['mapper'] instanceof Doctrine_Mapper_SingleTable) {
|
||||
if ($data['table']->getInheritanceType() != Doctrine::INHERITANCETYPE_SINGLE_TABLE) {
|
||||
$array[$sqlTableAlias][] = array();
|
||||
} else {
|
||||
$discCol = $data['table']->getInheritanceOption('discriminatorColumn');
|
||||
|
@ -56,6 +56,11 @@ class Doctrine_Query_Registry
|
||||
$query = $this->_queries[$namespace][$key];
|
||||
} else {
|
||||
if ( ! isset($this->_queries[$key])) {
|
||||
try {
|
||||
throw new Exception();
|
||||
} catch (Exception $e) {
|
||||
echo $e->getTraceAsString() ."<br /><br />";
|
||||
}
|
||||
throw new Doctrine_Query_Registry_Exception('A query with the name ' . $key . ' does not exist.');
|
||||
}
|
||||
$query = $this->_queries[$key];
|
||||
|
@ -31,6 +31,8 @@ Doctrine::autoload('Doctrine_Record_Abstract');
|
||||
* @link www.phpdoctrine.com
|
||||
* @since 1.0
|
||||
* @version $Revision$
|
||||
* @todo Remove the depdency on the ClassMetadata. All operations that involve the metadata
|
||||
* should be left to the mapper.
|
||||
*/
|
||||
abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Countable, IteratorAggregate, Serializable
|
||||
{
|
||||
@ -169,14 +171,14 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
|
||||
*/
|
||||
public function __construct($mapper = null, $isNewEntry = false, array $data = array())
|
||||
{
|
||||
if (isset($mapper) && $mapper instanceof Doctrine_Mapper_Abstract) {
|
||||
if (isset($mapper) && $mapper instanceof Doctrine_Mapper) {
|
||||
$class = get_class($this);
|
||||
$this->_mapper = Doctrine_Manager::getInstance()->getMapper($class);
|
||||
$this->_table = $this->_mapper->getTable();
|
||||
$this->_table = $this->_mapper->getClassMetadata();
|
||||
$exists = ! $isNewEntry;
|
||||
} else {
|
||||
$this->_mapper = Doctrine_Manager::getInstance()->getMapper(get_class($this));
|
||||
$this->_table = $this->_mapper->getTable();
|
||||
$this->_table = $this->_mapper->getClassMetadata();
|
||||
$exists = false;
|
||||
}
|
||||
|
||||
@ -193,7 +195,7 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
|
||||
|
||||
$this->_values = $this->cleanData($this->_data);
|
||||
|
||||
$this->prepareIdentifiers($exists);
|
||||
$this->_extractIdentifier($exists);
|
||||
|
||||
if ( ! $exists) {
|
||||
if ($count > count($this->_values)) {
|
||||
@ -212,7 +214,6 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
|
||||
}
|
||||
}
|
||||
|
||||
$this->_errorStack = new Doctrine_Validator_ErrorStack(get_class($this));
|
||||
$repository = $this->_mapper->getRepository();
|
||||
$repository->add($this);
|
||||
|
||||
@ -270,8 +271,9 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
|
||||
if ( ! $this->_mapper->getAttribute(Doctrine::ATTR_VALIDATE)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Clear the stack from any previous errors.
|
||||
$this->_errorStack->clear();
|
||||
$this->getErrorStack()->clear();
|
||||
|
||||
// Run validation process
|
||||
$validator = new Doctrine_Validator();
|
||||
@ -283,7 +285,7 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
|
||||
$this->validateOnUpdate();
|
||||
}
|
||||
|
||||
return $this->_errorStack->count() == 0 ? true : false;
|
||||
return $this->getErrorStack()->count() == 0 ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -405,6 +407,9 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
|
||||
*/
|
||||
public function getErrorStack()
|
||||
{
|
||||
if (is_null($this->_errorStack)) {
|
||||
$this->_errorStack = new Doctrine_Validator_ErrorStack();
|
||||
}
|
||||
return $this->_errorStack;
|
||||
}
|
||||
|
||||
@ -423,7 +428,7 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
|
||||
}
|
||||
$this->_errorStack = $stack;
|
||||
} else {
|
||||
return $this->_errorStack;
|
||||
return $this->getErrorStack();
|
||||
}
|
||||
}
|
||||
|
||||
@ -496,7 +501,7 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
|
||||
{
|
||||
$this->_values = array_merge($this->_values, $this->cleanData($data));
|
||||
$this->_data = array_merge($this->_data, $data);
|
||||
$this->prepareIdentifiers(true);
|
||||
$this->_extractIdentifier(true);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -507,7 +512,7 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
|
||||
* @return void
|
||||
* @todo Maybe better placed in the Mapper?
|
||||
*/
|
||||
private function prepareIdentifiers($exists = true)
|
||||
private function _extractIdentifier($exists = true)
|
||||
{
|
||||
switch ($this->_table->getIdentifierType()) {
|
||||
case Doctrine::IDENTIFIER_AUTOINC:
|
||||
@ -637,7 +642,7 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
|
||||
|
||||
$this->_mapper->getRepository()->add($this);
|
||||
$this->cleanData($this->_data);
|
||||
$this->prepareIdentifiers($this->exists());
|
||||
$this->_extractIdentifier($this->exists());
|
||||
|
||||
$this->postUnserialize($event);
|
||||
}
|
||||
@ -730,7 +735,7 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
|
||||
|
||||
$this->_modified = array();
|
||||
|
||||
$this->prepareIdentifiers();
|
||||
$this->_extractIdentifier();
|
||||
|
||||
$this->_state = Doctrine_Record::STATE_CLEAN;
|
||||
|
||||
@ -1485,7 +1490,7 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
|
||||
$this->_state = Doctrine_Record::STATE_TCLEAN;
|
||||
$this->_modified = array();
|
||||
} else if ($id === true) {
|
||||
$this->prepareIdentifiers(true);
|
||||
$this->_extractIdentifier(true);
|
||||
$this->_state = Doctrine_Record::STATE_CLEAN;
|
||||
$this->_modified = array();
|
||||
} else {
|
||||
|
@ -5,6 +5,7 @@
|
||||
*
|
||||
* @todo Support different drivers for loading the meta data from different sources.
|
||||
* @package Doctrine
|
||||
* @deprecated
|
||||
*/
|
||||
class Doctrine_Table_Factory
|
||||
{
|
||||
|
@ -51,7 +51,7 @@ class Doctrine_Table_Repository implements Countable, IteratorAggregate
|
||||
*
|
||||
* @param Doctrine_Table $table
|
||||
*/
|
||||
public function __construct(Doctrine_Mapper_Abstract $mapper)
|
||||
public function __construct($mapper)
|
||||
{
|
||||
$this->table = $mapper;
|
||||
}
|
||||
|
@ -54,14 +54,14 @@ class Doctrine_Query_Registry_TestCase extends Doctrine_UnitTestCase
|
||||
{
|
||||
$registry = new Doctrine_Query_Registry();
|
||||
|
||||
$registry->add('User/all', 'SELECT u.* FROM User u');
|
||||
$registry->add('User.all', 'SELECT u.* FROM User u');
|
||||
|
||||
$this->assertEqual($registry->get('all', 'User')->getDql(), 'SELECT u.* FROM User u');
|
||||
$this->assertEqual($registry->get('User.all')->getDql(), 'SELECT u.* FROM User u');
|
||||
|
||||
$this->manager->setQueryRegistry($registry);
|
||||
|
||||
$user = new User();
|
||||
|
||||
$user->getMapper()->execute('all');
|
||||
$user->getMapper()->executeNamedQuery('User.all');
|
||||
}
|
||||
}
|
||||
|
@ -391,15 +391,12 @@ class Doctrine_Record_TestCase extends Doctrine_UnitTestCase
|
||||
$this->assertEqual($user->name, "Jack Daniels");
|
||||
$this->assertEqual($user->created, null);
|
||||
$this->assertEqual($user->updated, null);
|
||||
$this->assertEqual($user->getMapper()->getData(), array());
|
||||
|
||||
}
|
||||
|
||||
public function testNewOperator()
|
||||
{
|
||||
$table = $this->connection->getClassMetadata("User");
|
||||
|
||||
$this->assertEqual($this->connection->getMapper("User")->getData(), array());
|
||||
$user = new User();
|
||||
$this->assertEqual(Doctrine_Lib::getRecordStateAsString($user->state()), Doctrine_Lib::getRecordStateAsString(Doctrine_Record::STATE_TCLEAN));
|
||||
$user->name = "John Locke";
|
||||
|
@ -78,6 +78,7 @@ class Doctrine_Relation_ManyToMany2_TestCase extends Doctrine_UnitTestCase
|
||||
->from('TestMovie d, d.MovieBookmarks i, i.UserVotes u, u.User c')
|
||||
->execute()
|
||||
->getFirst();
|
||||
|
||||
$newdata['MovieBookmarks'][0]['UserVotes'][0]['User']['name'] = 'user2';
|
||||
try {
|
||||
$newdata->save();
|
||||
|
@ -137,11 +137,6 @@ class Doctrine_Table_TestCase extends Doctrine_UnitTestCase
|
||||
$this->assertTrue($this->objTable->getConnection() instanceof Doctrine_Connection);
|
||||
}
|
||||
|
||||
public function testGetData()
|
||||
{
|
||||
$this->assertTrue($this->objTable->getData() == array());
|
||||
}
|
||||
|
||||
public function testSetSequenceName()
|
||||
{
|
||||
$this->objTable->sequenceName = 'test-seq';
|
||||
|
@ -1,5 +1,5 @@
|
||||
<?php
|
||||
class PluginSymfonyRecordTable extends Doctrine_Mapper_TablePerClass
|
||||
class PluginSymfonyRecordTable extends Doctrine_Mapper
|
||||
{
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user