[2.0][DDC-202][DDC-132][DDC-185] Fixed.
This commit is contained in:
parent
a26464da4c
commit
909e98c6f2
15 changed files with 194 additions and 264 deletions
|
@ -292,7 +292,8 @@ class Connection
|
|||
/**
|
||||
* Establishes the connection with the database.
|
||||
*
|
||||
* @return boolean
|
||||
* @return boolean TRUE if the connection was successfully established, FALSE if
|
||||
* the connection is already open.
|
||||
*/
|
||||
public function connect()
|
||||
{
|
||||
|
@ -311,11 +312,13 @@ class Connection
|
|||
}
|
||||
|
||||
/**
|
||||
* Convenience method for PDO::query("...") followed by $stmt->fetch(PDO::FETCH_ASSOC).
|
||||
*
|
||||
* Prepares and executes an SQL query and returns the first row of the result
|
||||
* as an associative array.
|
||||
*
|
||||
* @param string $statement The SQL query.
|
||||
* @param array $params The query parameters.
|
||||
* @return array
|
||||
* @todo Rename: fetchAssoc
|
||||
*/
|
||||
public function fetchRow($statement, array $params = array())
|
||||
{
|
||||
|
@ -323,7 +326,8 @@ class Connection
|
|||
}
|
||||
|
||||
/**
|
||||
* Convenience method for PDO::query("...") followed by $stmt->fetch(PDO::FETCH_NUM).
|
||||
* Prepares and executes an SQL query and returns the first row of the result
|
||||
* as a numerically indexed array.
|
||||
*
|
||||
* @param string $statement sql query to be executed
|
||||
* @param array $params prepared statement params
|
||||
|
@ -335,12 +339,13 @@ class Connection
|
|||
}
|
||||
|
||||
/**
|
||||
* Convenience method for PDO::query("...") followed by $stmt->fetchColumn(...).
|
||||
*
|
||||
* Prepares and executes an SQL query and returns the value of a single column
|
||||
* of the first row of the result.
|
||||
*
|
||||
* @param string $statement sql query to be executed
|
||||
* @param array $params prepared statement params
|
||||
* @param int $colnum 0-indexed column number to retrieve
|
||||
* @return array
|
||||
* @return mixed
|
||||
*/
|
||||
public function fetchColumn($statement, array $params = array(), $colnum = 0)
|
||||
{
|
||||
|
@ -357,22 +362,10 @@ class Connection
|
|||
return $this->_isConnected;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method for PDO::query("...") followed by $stmt->fetchAll(PDO::FETCH_BOTH).
|
||||
*
|
||||
* @param string $statement sql query to be executed
|
||||
* @param array $params prepared statement params
|
||||
* @return array
|
||||
*/
|
||||
public function fetchBoth($statement, array $params = array())
|
||||
{
|
||||
return $this->execute($statement, $params)->fetchAll(Connection::FETCH_BOTH);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes table row(s) matching the specified identifier.
|
||||
*
|
||||
* @param string $table The table to delete data from
|
||||
* @param string $table The table to delete data from.
|
||||
* @param array $identifier An associateve array containing identifier fieldname-value pairs.
|
||||
* @return integer The number of affected rows
|
||||
*/
|
||||
|
@ -532,7 +525,7 @@ class Connection
|
|||
}
|
||||
|
||||
/**
|
||||
* Convenience method for PDO::query("...") followed by $stmt->fetchAll(PDO::FETCH_ASSOC).
|
||||
* Prepares and executes an SQL query and returns the result as an associative array.
|
||||
*
|
||||
* @param string $sql The SQL query.
|
||||
* @param array $params The query parameters.
|
||||
|
@ -546,8 +539,8 @@ class Connection
|
|||
/**
|
||||
* Prepares an SQL statement.
|
||||
*
|
||||
* @param string $statement
|
||||
* @return Statement
|
||||
* @param string $statement The SQL statement to prepare.
|
||||
* @return Statement The prepared statement.
|
||||
*/
|
||||
public function prepare($statement)
|
||||
{
|
||||
|
@ -557,29 +550,11 @@ class Connection
|
|||
}
|
||||
|
||||
/**
|
||||
* Queries the database with limit and offset added to the query and returns
|
||||
* a Statement object.
|
||||
* Prepares and executes an SQL query.
|
||||
*
|
||||
* @param string $query
|
||||
* @param integer $limit
|
||||
* @param integer $offset
|
||||
* @return Statement
|
||||
*/
|
||||
public function select($query, $limit = 0, $offset = 0)
|
||||
{
|
||||
if ($limit > 0 || $offset > 0) {
|
||||
$query = $this->_platform->modifyLimitQuery($query, $limit, $offset);
|
||||
}
|
||||
|
||||
return $this->execute($query);
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes an SQL SELECT query with the given parameters.
|
||||
*
|
||||
* @param string $query sql query
|
||||
* @param array $params query parameters
|
||||
* @return PDOStatement
|
||||
* @param string $query The SQL query to prepare and execute.
|
||||
* @param array $params The parameters, if any.
|
||||
* @return Statement The prepared and executed statement.
|
||||
*/
|
||||
public function execute($query, array $params = array())
|
||||
{
|
||||
|
@ -598,6 +573,35 @@ class Connection
|
|||
|
||||
return $stmt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares and executes an SQL query and returns the result, optionally applying a
|
||||
* transformation on the rows of the result.
|
||||
*
|
||||
* @param string $query The SQL query to execute.
|
||||
* @param array $params The parameters, if any.
|
||||
* @param Closure $mapper The transformation function that is applied on each row.
|
||||
* The function receives a single paramater, an array, that
|
||||
* represents a row of the result set.
|
||||
* @return mixed The (possibly transformed) result of the query.
|
||||
*/
|
||||
public function query($query, array $params = array(), \Closure $mapper = null)
|
||||
{
|
||||
$result = array();
|
||||
$stmt = $this->execute($query, $params);
|
||||
|
||||
while ($row = $stmt->fetch()) {
|
||||
if ($mapper === null) {
|
||||
$result[] = $row;
|
||||
} else {
|
||||
$result[] = $mapper($row);
|
||||
}
|
||||
}
|
||||
|
||||
$stmt->closeCursor();
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes an SQL INSERT/UPDATE/DELETE query with the given parameters.
|
||||
|
@ -726,7 +730,7 @@ class Connection
|
|||
* this method can be listened with onPreTransactionRollback and onTransactionRollback
|
||||
* eventlistener methods
|
||||
*
|
||||
* @throws ConnectionException If the rollback operation fails at database level.
|
||||
* @throws ConnectionException If the rollback operation failed.
|
||||
*/
|
||||
public function rollback()
|
||||
{
|
||||
|
|
|
@ -143,7 +143,7 @@ class OCI8Statement implements \Doctrine\DBAL\Driver\Statement
|
|||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fetch($fetchStyle = Connection::FETCH_BOTH, $cursorOrientation = \PDO::FETCH_ORI_NEXT, $cursorOffset = 0)
|
||||
public function fetch($fetchStyle = Connection::FETCH_BOTH)
|
||||
{
|
||||
if ( ! isset(self::$fetchStyleMap[$fetchStyle])) {
|
||||
throw new \InvalidArgumentException("Invalid fetch style: " . $fetchStyle);
|
||||
|
@ -176,60 +176,11 @@ class OCI8Statement implements \Doctrine\DBAL\Driver\Statement
|
|||
return $row[$columnIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fetchObject($className = 'stdClass', $args = array())
|
||||
{
|
||||
throw new \Exception(__METHOD__ . " not supported.");
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getAttribute($attribute)
|
||||
{
|
||||
throw new \Exception(__METHOD__ . " not supported.");
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getColumnMeta($column)
|
||||
{
|
||||
throw new \Exception(__METHOD__ . " not supported.");
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function nextRowset()
|
||||
{
|
||||
throw new \Exception(__METHOD__ . " not supported.");
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function rowCount()
|
||||
{
|
||||
return oci_num_rows($this->_sth);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setAttribute($attribute, $value)
|
||||
{
|
||||
throw new \Exception(__METHOD__ . " not supported.");
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setFetchMode($mode, $arg1)
|
||||
{
|
||||
throw new \Exception(__METHOD__ . " not supported.");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -36,6 +36,5 @@ class PDOConnection extends PDO implements Connection
|
|||
parent::__construct($dsn, $user, $password, $options);
|
||||
$this->setAttribute(PDO::ATTR_STATEMENT_CLASS, array('Doctrine\DBAL\Driver\PDOStatement', array()));
|
||||
$this->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||
//$this->setAttribute(PDO::ATTR_CASE, PDO::CASE_LOWER);
|
||||
}
|
||||
}
|
|
@ -21,11 +21,13 @@
|
|||
|
||||
namespace Doctrine\DBAL\Driver;
|
||||
|
||||
use Doctrine\DBAL\Connection as DBALConnection;
|
||||
|
||||
/**
|
||||
* Statement interface.
|
||||
* Drivers must implement this interface.
|
||||
*
|
||||
* This resembles the PDOStatement interface.
|
||||
* This resembles (a subset of) the PDOStatement interface.
|
||||
*
|
||||
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
|
@ -35,7 +37,7 @@ namespace Doctrine\DBAL\Driver;
|
|||
* @version $Revision$
|
||||
*/
|
||||
interface Statement
|
||||
{
|
||||
{
|
||||
/**
|
||||
* Bind a column to a PHP variable
|
||||
*
|
||||
|
@ -92,7 +94,6 @@ interface Statement
|
|||
function bindParam($column, &$variable, $type = null, $length = null, $driverOptions = array());
|
||||
|
||||
/**
|
||||
* closeCursor
|
||||
* Closes the cursor, enabling the statement to be executed again.
|
||||
*
|
||||
* @return boolean Returns TRUE on success or FALSE on failure.
|
||||
|
@ -170,12 +171,9 @@ interface Statement
|
|||
*
|
||||
* @return mixed
|
||||
*/
|
||||
function fetch($fetchStyle = Query::HYDRATE_BOTH,
|
||||
$cursorOrientation = Query::HYDRATE_ORI_NEXT,
|
||||
$cursorOffset = null);
|
||||
function fetch($fetchStyle = DBALConnection::FETCH_BOTH);
|
||||
|
||||
/**
|
||||
* fetchAll
|
||||
* Returns an array containing all of the result set rows
|
||||
*
|
||||
* @param integer $fetchStyle Controls how the next row will be returned to the caller.
|
||||
|
@ -187,7 +185,7 @@ interface Statement
|
|||
*
|
||||
* @return array
|
||||
*/
|
||||
function fetchAll($fetchStyle = Query::HYDRATE_BOTH);
|
||||
function fetchAll($fetchStyle = DBALConnection::FETCH_BOTH);
|
||||
|
||||
/**
|
||||
* fetchColumn
|
||||
|
@ -202,62 +200,6 @@ interface Statement
|
|||
*/
|
||||
function fetchColumn($columnIndex = 0);
|
||||
|
||||
/**
|
||||
* fetchObject
|
||||
* Fetches the next row and returns it as an object.
|
||||
*
|
||||
* Fetches the next row and returns it as an object. This function is an alternative to
|
||||
* PDOStatement->fetch() with Query::HYDRATE_CLASS or Query::HYDRATE_OBJ style.
|
||||
*
|
||||
* @param string $className Name of the created class, defaults to stdClass.
|
||||
* @param array $args Elements of this array are passed to the constructor.
|
||||
*
|
||||
* @return mixed an instance of the required class with property names that correspond
|
||||
* to the column names or FALSE in case of an error.
|
||||
*/
|
||||
function fetchObject($className = 'stdClass', $args = array());
|
||||
|
||||
/**
|
||||
* getAttribute
|
||||
* Retrieve a statement attribute
|
||||
*
|
||||
* @param integer $attribute
|
||||
* @see Doctrine::ATTR_* constants
|
||||
* @return mixed the attribute value
|
||||
*/
|
||||
function getAttribute($attribute);
|
||||
|
||||
/**
|
||||
* getColumnMeta
|
||||
* Returns metadata for a column in a result set
|
||||
*
|
||||
* @param integer $column The 0-indexed column in the result set.
|
||||
*
|
||||
* @return array Associative meta data array with the following structure:
|
||||
*
|
||||
* native_type The PHP native type used to represent the column value.
|
||||
* driver:decl_ type The SQL type used to represent the column value in the database. If the column in the result set is the result of a function, this value is not returned by PDOStatement->getColumnMeta().
|
||||
* flags Any flags set for this column.
|
||||
* name The name of this column as returned by the database.
|
||||
* len The length of this column. Normally -1 for types other than floating point decimals.
|
||||
* precision The numeric precision of this column. Normally 0 for types other than floating point decimals.
|
||||
* pdo_type The type of this column as represented by the PDO::PARAM_* constants.
|
||||
*/
|
||||
function getColumnMeta($column);
|
||||
|
||||
/**
|
||||
* nextRowset
|
||||
* Advances to the next rowset in a multi-rowset statement handle
|
||||
*
|
||||
* Some database servers support stored procedures that return more than one rowset
|
||||
* (also known as a result set). The nextRowset() method enables you to access the second
|
||||
* and subsequent rowsets associated with a PDOStatement object. Each rowset can have a
|
||||
* different set of columns from the preceding rowset.
|
||||
*
|
||||
* @return boolean Returns TRUE on success or FALSE on failure.
|
||||
*/
|
||||
function nextRowset();
|
||||
|
||||
/**
|
||||
* rowCount
|
||||
* rowCount() returns the number of rows affected by the last DELETE, INSERT, or UPDATE statement
|
||||
|
@ -271,23 +213,4 @@ interface Statement
|
|||
* @return integer Returns the number of rows.
|
||||
*/
|
||||
function rowCount();
|
||||
|
||||
/**
|
||||
* setAttribute
|
||||
* Set a statement attribute
|
||||
*
|
||||
* @param integer $attribute
|
||||
* @param mixed $value the value of given attribute
|
||||
* @return boolean Returns TRUE on success or FALSE on failure.
|
||||
*/
|
||||
function setAttribute($attribute, $value);
|
||||
|
||||
/**
|
||||
* setFetchMode
|
||||
* Set the default fetch mode for this statement
|
||||
*
|
||||
* @param integer $mode The fetch mode must be one of the Query::HYDRATE_* constants.
|
||||
* @return boolean Returns 1 on success or FALSE on failure.
|
||||
*/
|
||||
function setFetchMode($mode, $arg1);
|
||||
}
|
|
@ -62,7 +62,7 @@ class ObjectHydrator extends AbstractHydrator
|
|||
|
||||
foreach ($this->_rsm->aliasMap as $dqlAlias => $className) {
|
||||
$this->_identifierMap[$dqlAlias] = array();
|
||||
$this->_resultPointers[$dqlAlias] = array();
|
||||
//$this->_resultPointers[$dqlAlias] = array();
|
||||
$this->_idTemplate[$dqlAlias] = '';
|
||||
$class = $this->_em->getClassMetadata($className);
|
||||
|
||||
|
|
|
@ -334,7 +334,7 @@ final class ClassMetadata extends ClassMetadataInfo
|
|||
'inheritanceType',
|
||||
'inheritedAssociationFields',
|
||||
'insertSql',
|
||||
'inverseMappings',
|
||||
'inverseMappings', //TODO: Remove!
|
||||
'isIdentifierComposite',
|
||||
'isMappedSuperclass',
|
||||
'isVersioned',
|
||||
|
@ -343,7 +343,6 @@ final class ClassMetadata extends ClassMetadataInfo
|
|||
'namespace',
|
||||
'parentClasses',
|
||||
'primaryTable',
|
||||
'resultColumnNames',
|
||||
'rootEntityName',
|
||||
'sequenceGeneratorDefinition',
|
||||
'subClasses',
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
|
||||
namespace Doctrine\ORM\Mapping;
|
||||
|
||||
use Doctrine\Common\DoctrineException,
|
||||
use Doctrine\ORM\ORMException,
|
||||
Doctrine\DBAL\Platforms\AbstractPlatform,
|
||||
Doctrine\ORM\Events;
|
||||
|
||||
|
@ -189,7 +189,6 @@ class ClassMetadataFactory
|
|||
$class->setVersioned($parent->isVersioned);
|
||||
$class->setVersionField($parent->versionField);
|
||||
$class->setDiscriminatorMap($parent->discriminatorMap);
|
||||
$class->setResultColumnNames($parent->resultColumnNames);
|
||||
}
|
||||
|
||||
// Invoke driver
|
||||
|
@ -230,13 +229,6 @@ class ClassMetadataFactory
|
|||
$this->_generateStaticSql($class);
|
||||
}
|
||||
|
||||
if ($parent) {
|
||||
foreach ($visited as $parentClassName) {
|
||||
$parentClass = $this->_loadedMetadata[$parentClassName];
|
||||
$parentClass->setResultColumnNames(array_merge($parentClass->resultColumnNames, $class->resultColumnNames));
|
||||
}
|
||||
}
|
||||
|
||||
$this->_loadedMetadata[$className] = $class;
|
||||
|
||||
$parent = $class;
|
||||
|
@ -321,11 +313,6 @@ class ClassMetadataFactory
|
|||
if (isset($class->fieldMappings[$name]['inherited']) && ! isset($class->fieldMappings[$name]['id'])
|
||||
|| isset($class->inheritedAssociationFields[$name])
|
||||
|| ($versioned && $versionField == $name)) {
|
||||
if (isset($class->columnNames[$name])) {
|
||||
// Add column mapping for SQL result sets
|
||||
$columnName = $class->columnNames[$name];
|
||||
$class->resultColumnNames[$this->_targetPlatform->getSqlResultCasing($columnName)] = $columnName;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -334,19 +321,10 @@ class ClassMetadataFactory
|
|||
if ($assoc->isOneToOne() && $assoc->isOwningSide) {
|
||||
foreach ($assoc->targetToSourceKeyColumns as $sourceCol) {
|
||||
$columns[] = $assoc->getQuotedJoinColumnName($sourceCol, $this->_targetPlatform);
|
||||
// Add column mapping for SQL result sets
|
||||
$class->resultColumnNames[$this->_targetPlatform->getSqlResultCasing($sourceCol)] = $sourceCol;
|
||||
}
|
||||
}
|
||||
} else if ($class->name != $class->rootEntityName || ! $class->isIdGeneratorIdentity() || $class->identifier[0] != $name) {
|
||||
$columns[] = $class->getQuotedColumnName($name, $this->_targetPlatform);
|
||||
// Add column mapping for SQL result sets
|
||||
$columnName = $class->columnNames[$name];
|
||||
$class->resultColumnNames[$this->_targetPlatform->getSqlResultCasing($columnName)] = $columnName;
|
||||
} else {
|
||||
// Add column mapping for SQL result sets
|
||||
$columnName = $class->columnNames[$name];
|
||||
$class->resultColumnNames[$this->_targetPlatform->getSqlResultCasing($columnName)] = $columnName;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -360,19 +338,10 @@ class ClassMetadataFactory
|
|||
if ($assoc->isOwningSide && $assoc->isOneToOne()) {
|
||||
foreach ($assoc->targetToSourceKeyColumns as $sourceCol) {
|
||||
$columns[] = $assoc->getQuotedJoinColumnName($sourceCol, $this->_targetPlatform);
|
||||
// Add column mapping for SQL result sets
|
||||
$class->resultColumnNames[$this->_targetPlatform->getSqlResultCasing($sourceCol)] = $sourceCol;
|
||||
}
|
||||
}
|
||||
} else if ($class->generatorType != ClassMetadata::GENERATOR_TYPE_IDENTITY || $class->identifier[0] != $name) {
|
||||
$columns[] = $class->getQuotedColumnName($name, $this->_targetPlatform);
|
||||
// Add column mapping for SQL result sets
|
||||
$columnName = $class->columnNames[$name];
|
||||
$class->resultColumnNames[$this->_targetPlatform->getSqlResultCasing($columnName)] = $columnName;
|
||||
} else {
|
||||
// Add column mapping for SQL result sets
|
||||
$columnName = $class->columnNames[$name];
|
||||
$class->resultColumnNames[$this->_targetPlatform->getSqlResultCasing($columnName)] = $columnName;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -383,9 +352,6 @@ class ClassMetadataFactory
|
|||
&& $class->name == $class->rootEntityName) {
|
||||
$columns[] = $class->getQuotedDiscriminatorColumnName($this->_targetPlatform);
|
||||
}
|
||||
// Add column mapping for SQL result sets
|
||||
$columnName = $class->discriminatorColumn['name'];
|
||||
$class->resultColumnNames[$this->_targetPlatform->getSqlResultCasing($columnName)] = $columnName;
|
||||
}
|
||||
|
||||
if (empty($columns)) {
|
||||
|
@ -448,10 +414,10 @@ class ClassMetadataFactory
|
|||
$class->setIdGenerator(new \Doctrine\ORM\Id\Assigned());
|
||||
break;
|
||||
case ClassMetadata::GENERATOR_TYPE_TABLE:
|
||||
throw new DoctrineException("DoctrineTableGenerator not yet implemented.");
|
||||
throw new ORMException("TableGenerator not yet implemented.");
|
||||
break;
|
||||
default:
|
||||
throw new DoctrineException("Unexhaustive match.");
|
||||
throw new ORMException("Unknown generator type: " . $class->generatorType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -257,18 +257,6 @@ class ClassMetadataInfo
|
|||
* @var array
|
||||
*/
|
||||
public $columnNames = array();
|
||||
|
||||
/**
|
||||
* A map of column names as they appear in an SQL result set to column names as they
|
||||
* are defined in the mapping. This includes the columns of all mapped fields as well
|
||||
* as any join columns and discriminator columns.
|
||||
*
|
||||
* @var array
|
||||
* @todo Remove. Or at least remove from serialization/unserialization and instead
|
||||
* populate them during runtime.
|
||||
* See http://www.doctrine-project.org/jira/browse/DDC-132.
|
||||
*/
|
||||
public $resultColumnNames = array();
|
||||
|
||||
/**
|
||||
* Whether to automatically OUTER JOIN subtypes when a basetype is queried.
|
||||
|
@ -340,6 +328,7 @@ class ClassMetadataInfo
|
|||
* List of inverse association mappings, indexed by mappedBy field name.
|
||||
*
|
||||
* @var array
|
||||
* @todo Remove! See http://www.doctrine-project.org/jira/browse/DDC-193
|
||||
*/
|
||||
public $inverseMappings = array();
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
|
||||
namespace Doctrine\ORM\Persisters;
|
||||
|
||||
use Doctrine\Common\DoctrineException;
|
||||
use Doctrine\ORM\ORMException;
|
||||
|
||||
/**
|
||||
* The joined subclass persister maps a single entity instance to several tables in the
|
||||
|
@ -52,8 +52,7 @@ class JoinedSubclassPersister extends StandardEntityPersister
|
|||
if ($isInsert) {
|
||||
$discColumn = $this->_class->discriminatorColumn;
|
||||
$rootClass = $this->_em->getClassMetadata($this->_class->rootEntityName);
|
||||
$result[$rootClass->primaryTable['name']][$discColumn['name']] =
|
||||
$this->_class->discriminatorValue;
|
||||
$result[$rootClass->primaryTable['name']][$discColumn['name']] = $this->_class->discriminatorValue;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -61,7 +60,7 @@ class JoinedSubclassPersister extends StandardEntityPersister
|
|||
* This function finds the ClassMetadata instance in a inheritance hierarchy
|
||||
* that is responsible for enabling versioning.
|
||||
*
|
||||
* @return mixed $versionedClass ClassMetadata instance or false if versioning is not enabled
|
||||
* @return mixed $versionedClass ClassMetadata instance or false if versioning is not enabled
|
||||
*/
|
||||
private function _getVersionedClassMetadata()
|
||||
{
|
||||
|
@ -280,6 +279,7 @@ class JoinedSubclassPersister extends StandardEntityPersister
|
|||
$aliasIndex = 1;
|
||||
$idColumns = $this->_class->getIdentifierColumnNames();
|
||||
$baseTableAlias = 't0';
|
||||
$setResultColumnNames = empty($this->_resultColumnNames);
|
||||
|
||||
foreach (array_merge($this->_class->subClasses, $this->_class->parentClasses) as $className) {
|
||||
$tableAliases[$className] = 't' . $aliasIndex++;
|
||||
|
@ -292,6 +292,11 @@ class JoinedSubclassPersister extends StandardEntityPersister
|
|||
$tableAliases[$mapping['inherited']] : $baseTableAlias;
|
||||
if ($columnList != '') $columnList .= ', ';
|
||||
$columnList .= $tableAlias . '.' . $this->_class->getQuotedColumnName($fieldName, $this->_platform);
|
||||
|
||||
if ($setResultColumnNames) {
|
||||
$resultColumnName = $this->_platform->getSqlResultCasing($mapping['columnName']);
|
||||
$this->_resultColumnNames[$resultColumnName] = $mapping['columnName'];
|
||||
}
|
||||
}
|
||||
|
||||
// Add foreign key columns
|
||||
|
@ -299,6 +304,11 @@ class JoinedSubclassPersister extends StandardEntityPersister
|
|||
if ($assoc2->isOwningSide && $assoc2->isOneToOne()) {
|
||||
foreach ($assoc2->targetToSourceKeyColumns as $srcColumn) {
|
||||
$columnList .= ', ' . $assoc2->getQuotedJoinColumnName($srcColumn, $this->_platform);
|
||||
|
||||
if ($setResultColumnNames) {
|
||||
$resultColumnName = $this->_platform->getSqlResultCasing($srcColumn);
|
||||
$this->_resultColumnNames[$resultColumnName] = $srcColumn;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -311,6 +321,11 @@ class JoinedSubclassPersister extends StandardEntityPersister
|
|||
$columnList .= ', ' . $tableAliases[$this->_class->rootEntityName] . '.' .
|
||||
$this->_class->getQuotedDiscriminatorColumnName($this->_platform);
|
||||
}
|
||||
|
||||
if ($setResultColumnNames) {
|
||||
$resultColumnName = $this->_platform->getSqlResultCasing($this->_class->discriminatorColumn['name']);
|
||||
$this->_resultColumnNames[$resultColumnName] = $this->_class->discriminatorColumn['name'];
|
||||
}
|
||||
|
||||
// INNER JOIN parent tables
|
||||
$joinSql = '';
|
||||
|
@ -336,6 +351,11 @@ class JoinedSubclassPersister extends StandardEntityPersister
|
|||
continue;
|
||||
}
|
||||
$columnList .= ', ' . $tableAlias . '.' . $subClass->getQuotedColumnName($fieldName, $this->_platform);
|
||||
|
||||
if ($setResultColumnNames) {
|
||||
$resultColumnName = $this->_platform->getSqlResultCasing($mapping['columnName']);
|
||||
$this->_resultColumnNames[$resultColumnName] = $mapping['columnName'];
|
||||
}
|
||||
}
|
||||
|
||||
// Add join columns (foreign keys)
|
||||
|
@ -343,6 +363,11 @@ class JoinedSubclassPersister extends StandardEntityPersister
|
|||
if ($assoc2->isOwningSide && $assoc2->isOneToOne() && ! isset($subClass->inheritedAssociationFields[$assoc2->sourceFieldName])) {
|
||||
foreach ($assoc2->targetToSourceKeyColumns as $srcColumn) {
|
||||
$columnList .= ', ' . $tableAlias . '.' . $assoc2->getQuotedJoinColumnName($srcColumn, $this->_platform);
|
||||
|
||||
if ($setResultColumnNames) {
|
||||
$resultColumnName = $this->_platform->getSqlResultCasing($srcColumn);
|
||||
$this->_resultColumnNames[$resultColumnName] = $srcColumn;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -365,7 +390,7 @@ class JoinedSubclassPersister extends StandardEntityPersister
|
|||
} else if ($assoc !== null) {
|
||||
$conditionSql .= $assoc->getQuotedJoinColumnName($field, $this->_platform);
|
||||
} else {
|
||||
throw DoctrineException::unrecognizedField($field);
|
||||
throw ORMException::unrecognizedField($field);
|
||||
}
|
||||
$conditionSql .= ' = ?';
|
||||
}
|
||||
|
|
|
@ -50,9 +50,16 @@ class SingleTablePersister extends StandardEntityPersister
|
|||
/** @override */
|
||||
protected function _getSelectColumnList()
|
||||
{
|
||||
$setResultColumnNames = empty($this->_resultColumnNames);
|
||||
$columnList = parent::_getSelectColumnList();
|
||||
// Append discriminator column
|
||||
$columnList .= ', ' . $this->_class->getQuotedDiscriminatorColumnName($this->_platform);
|
||||
|
||||
if ($setResultColumnNames) {
|
||||
$resultColumnName = $this->_platform->getSqlResultCasing($this->_class->discriminatorColumn['name']);
|
||||
$this->_resultColumnNames[$resultColumnName] = $this->_class->discriminatorColumn['name'];
|
||||
}
|
||||
|
||||
///$tableAlias = $this->_class->getQuotedTableName($this->_platform);
|
||||
foreach ($this->_class->subClasses as $subClassName) {
|
||||
$subClass = $this->_em->getClassMetadata($subClassName);
|
||||
|
@ -60,6 +67,10 @@ class SingleTablePersister extends StandardEntityPersister
|
|||
foreach ($subClass->fieldMappings as $fieldName => $mapping) {
|
||||
if ( ! isset($mapping['inherited'])) {
|
||||
$columnList .= ', ' . $subClass->getQuotedColumnName($fieldName, $this->_platform);
|
||||
if ($setResultColumnNames) {
|
||||
$resultColumnName = $this->_platform->getSqlResultCasing($mapping['columnName']);
|
||||
$this->_resultColumnNames[$resultColumnName] = $mapping['columnName'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -68,6 +79,10 @@ class SingleTablePersister extends StandardEntityPersister
|
|||
if ($assoc->isOwningSide && $assoc->isOneToOne() && ! isset($subClass->inheritedAssociationFields[$assoc->sourceFieldName])) {
|
||||
foreach ($assoc->targetToSourceKeyColumns as $srcColumn) {
|
||||
$columnList .= ', ' /*. $tableAlias . '.'*/ . $assoc->getQuotedJoinColumnName($srcColumn, $this->_platform);
|
||||
if ($setResultColumnNames) {
|
||||
$resultColumnName = $this->_platform->getSqlResultCasing($srcColumn);
|
||||
$this->_resultColumnNames[$resultColumnName] = $srcColumn;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -86,6 +86,8 @@ class StandardEntityPersister
|
|||
* @var array
|
||||
*/
|
||||
protected $_queuedInserts = array();
|
||||
|
||||
protected $_resultColumnNames = array();
|
||||
|
||||
/**
|
||||
* Initializes a new instance of a class derived from AbstractEntityPersister
|
||||
|
@ -189,8 +191,8 @@ class StandardEntityPersister
|
|||
$identifier = $this->_class->getIdentifierColumnNames();
|
||||
$versionFieldColumnName = $this->_class->getColumnName($versionField);
|
||||
//FIXME: Order with composite keys might not be correct
|
||||
$sql = "SELECT " . $versionFieldColumnName . " FROM " . $class->getQuotedTableName($this->_platform) .
|
||||
" WHERE " . implode(' = ? AND ', $identifier) . " = ?";
|
||||
$sql = "SELECT " . $versionFieldColumnName . " FROM " . $class->getQuotedTableName($this->_platform)
|
||||
. " WHERE " . implode(' = ? AND ', $identifier) . " = ?";
|
||||
$value = $this->_conn->fetchColumn($sql, array_values((array)$id));
|
||||
$this->_class->setFieldValue($entity, $versionField, $value);
|
||||
}
|
||||
|
@ -453,7 +455,7 @@ class StandardEntityPersister
|
|||
|
||||
// Refresh simple state
|
||||
foreach ($result as $column => $value) {
|
||||
$column = $this->_class->resultColumnNames[$column];
|
||||
$column = isset($this->_resultColumnNames[$column]) ? $this->_resultColumnNames[$column] : $column;
|
||||
if (isset($this->_class->fieldNames[$column])) {
|
||||
$fieldName = $this->_class->fieldNames[$column];
|
||||
$type = Type::getType($this->_class->fieldMappings[$fieldName]['type']);
|
||||
|
@ -636,7 +638,7 @@ class StandardEntityPersister
|
|||
{
|
||||
$data = array();
|
||||
foreach ($sqlResult as $column => $value) {
|
||||
$column = $this->_class->resultColumnNames[$column];
|
||||
$column = isset($this->_resultColumnNames[$column]) ? $this->_resultColumnNames[$column] : $column;
|
||||
if (isset($this->_class->fieldNames[$column])) {
|
||||
$field = $this->_class->fieldNames[$column];
|
||||
$data[$field] = Type::getType($this->_class->fieldMappings[$field]['type'])
|
||||
|
@ -690,11 +692,18 @@ class StandardEntityPersister
|
|||
protected function _getSelectColumnList()
|
||||
{
|
||||
$columnList = '';
|
||||
$tableName = $this->_class->getQuotedTableName($this->_platform);
|
||||
$setResultColumnNames = empty($this->_resultColumnNames);
|
||||
|
||||
// Add regular columns to select list
|
||||
foreach ($this->_class->fieldNames as $field) {
|
||||
if ($columnList != '') $columnList .= ', ';
|
||||
$columnList .= $this->_class->getQuotedColumnName($field, $this->_platform);
|
||||
$columnList .= $tableName . '.' . $this->_class->getQuotedColumnName($field, $this->_platform);
|
||||
|
||||
if ($setResultColumnNames) {
|
||||
$resultColumnName = $this->_platform->getSqlResultCasing($this->_class->columnNames[$field]);
|
||||
$this->_resultColumnNames[$resultColumnName] = $this->_class->columnNames[$field];
|
||||
}
|
||||
}
|
||||
|
||||
// Add join columns (foreign keys) to select list
|
||||
|
@ -702,6 +711,11 @@ class StandardEntityPersister
|
|||
if ($assoc->isOwningSide && $assoc->isOneToOne()) {
|
||||
foreach ($assoc->targetToSourceKeyColumns as $srcColumn) {
|
||||
$columnList .= ', ' . $assoc->getQuotedJoinColumnName($srcColumn, $this->_platform);
|
||||
|
||||
if ($setResultColumnNames) {
|
||||
$resultColumnName = $this->_platform->getSqlResultCasing($srcColumn);
|
||||
$this->_resultColumnNames[$resultColumnName] = $srcColumn;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -717,22 +731,6 @@ class StandardEntityPersister
|
|||
*/
|
||||
protected function _getSelectManyToManyEntityCollectionSql($manyToMany, array &$criteria)
|
||||
{
|
||||
$columnList = '';
|
||||
$tableName = $this->_class->getQuotedTableName($this->_platform);
|
||||
|
||||
foreach ($this->_class->fieldNames as $field) {
|
||||
if ($columnList != '') $columnList .= ', ';
|
||||
$columnList .= $tableName . '.' . $this->_class->getQuotedColumnName($field, $this->_platform);
|
||||
}
|
||||
|
||||
foreach ($this->_class->associationMappings as $assoc) {
|
||||
if ($assoc->isOwningSide && $assoc->isOneToOne()) {
|
||||
foreach ($assoc->targetToSourceKeyColumns as $srcColumn) {
|
||||
$columnList .= ', ' . $assoc->getQuotedJoinColumnName($srcColumn, $this->_platform);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($manyToMany->isOwningSide) {
|
||||
$owningAssoc = $manyToMany;
|
||||
$joinClauses = $manyToMany->relationToTargetKeyColumns;
|
||||
|
@ -762,7 +760,7 @@ class StandardEntityPersister
|
|||
$conditionSql .= $columnName . ' = ?';
|
||||
}
|
||||
|
||||
return 'SELECT ' . $columnList
|
||||
return 'SELECT ' . $this->_getSelectColumnList()
|
||||
. ' FROM ' . $this->_class->getQuotedTableName($this->_platform)
|
||||
. $joinSql
|
||||
. ' WHERE ' . $conditionSql;
|
||||
|
@ -774,7 +772,7 @@ class StandardEntityPersister
|
|||
$data = array();
|
||||
$entityName = $this->_class->name;
|
||||
foreach ($sqlResult as $column => $value) {
|
||||
$column = $this->_class->resultColumnNames[$column];
|
||||
$column = isset($this->_resultColumnNames[$column]) ? $this->_resultColumnNames[$column] : $column;
|
||||
if (($class = $this->_findDeclaringClass($column)) !== false) {
|
||||
$field = $class->fieldNames[$column];
|
||||
$data[$field] = Type::getType($class->fieldMappings[$field]['type'])
|
||||
|
|
|
@ -45,7 +45,7 @@ class LifecycleCallbackTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
|||
{
|
||||
$user = new LifecycleCallbackTestUser;
|
||||
$user->setName('Bob');
|
||||
$user->setValue('');
|
||||
$user->setValue('value');
|
||||
$this->_em->persist($user);
|
||||
$this->_em->flush();
|
||||
|
||||
|
|
|
@ -10,7 +10,10 @@ class DDC168Test extends \Doctrine\Tests\OrmFunctionalTestCase
|
|||
$this->useModelSet('company');
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @group DDC-168
|
||||
*/
|
||||
public function testJoinedSubclassPersisterRequiresSpecificOrderOfMetadataReflFieldsArray()
|
||||
{
|
||||
$metadata = $this->_em->getClassMetadata('Doctrine\Tests\Models\Company\CompanyEmployee');
|
||||
|
|
|
@ -84,7 +84,7 @@ class DDC199ChildClass extends DDC199ParentClass
|
|||
public $childData;
|
||||
}
|
||||
|
||||
/** @Entity @Table(name="ddcxxx_relatedclass") */
|
||||
/** @Entity @Table(name="ddc199_relatedclass") */
|
||||
class DDC199RelatedClass
|
||||
{
|
||||
/** @Id @Column(type="integer") @GeneratedValue(strategy="AUTO") */
|
||||
|
|
|
@ -8,6 +8,8 @@ use Doctrine\ORM\Proxy\ProxyFactory;
|
|||
use Doctrine\ORM\Mapping\AssociationMapping;
|
||||
use Doctrine\ORM\Query;
|
||||
|
||||
use Doctrine\Tests\Models\CMS\CmsUser;
|
||||
|
||||
require_once __DIR__ . '/../../TestInit.php';
|
||||
|
||||
class ObjectHydratorTest extends HydrationTestCase
|
||||
|
@ -685,6 +687,62 @@ class ObjectHydratorTest extends HydrationTestCase
|
|||
$this->assertEquals(1, count($result[1]->boards));
|
||||
|
||||
}
|
||||
|
||||
public function testChainedJoinWithEmptyCollections()
|
||||
{
|
||||
$rsm = new ResultSetMapping;
|
||||
$rsm->addEntityResult('Doctrine\Tests\Models\CMS\CmsUser', 'u');
|
||||
$rsm->addJoinedEntityResult(
|
||||
'Doctrine\Tests\Models\CMS\CmsArticle',
|
||||
'a',
|
||||
'u',
|
||||
'articles'
|
||||
);
|
||||
$rsm->addJoinedEntityResult(
|
||||
'Doctrine\Tests\Models\CMS\CmsComment',
|
||||
'c',
|
||||
'a',
|
||||
'comments'
|
||||
);
|
||||
$rsm->addFieldResult('u', 'u__id', 'id');
|
||||
$rsm->addFieldResult('u', 'u__status', 'status');
|
||||
$rsm->addFieldResult('a', 'a__id', 'id');
|
||||
$rsm->addFieldResult('a', 'a__topic', 'topic');
|
||||
$rsm->addFieldResult('c', 'c__id', 'id');
|
||||
$rsm->addFieldResult('c', 'c__topic', 'topic');
|
||||
|
||||
// Faked result set
|
||||
$resultSet = array(
|
||||
//row1
|
||||
array(
|
||||
'u__id' => '1',
|
||||
'u__status' => 'developer',
|
||||
'a__id' => null,
|
||||
'a__topic' => null,
|
||||
'c__id' => null,
|
||||
'c__topic' => null
|
||||
),
|
||||
array(
|
||||
'u__id' => '2',
|
||||
'u__status' => 'developer',
|
||||
'a__id' => null,
|
||||
'a__topic' => null,
|
||||
'c__id' => null,
|
||||
'c__topic' => null
|
||||
),
|
||||
);
|
||||
|
||||
$stmt = new HydratorMockStatement($resultSet);
|
||||
$hydrator = new \Doctrine\ORM\Internal\Hydration\ObjectHydrator($this->_em);
|
||||
|
||||
$result = $hydrator->hydrateAll($stmt, $rsm, array(Query::HINT_FORCE_PARTIAL_LOAD => true));
|
||||
|
||||
$this->assertEquals(2, count($result));
|
||||
$this->assertTrue($result[0] instanceof CmsUser);
|
||||
$this->assertTrue($result[1] instanceof CmsUser);
|
||||
$this->assertEquals(0, $result[0]->articles->count());
|
||||
$this->assertEquals(0, $result[1]->articles->count());
|
||||
}
|
||||
|
||||
public function testResultIteration()
|
||||
{
|
||||
|
|
Loading…
Add table
Reference in a new issue