vendor/doctrine/lib/Doctrine/ORM/Internal/Hydration/AbstractHydrator.php
author ymh <ymh.work@gmail.com>
Sat, 24 Sep 2011 15:40:41 +0200
changeset 0 7f95f8617b0b
permissions -rwxr-xr-x
first commit
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
     1
<?php
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
     2
/*
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
     3
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
     4
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
     5
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
     6
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
     7
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
     8
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
     9
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    10
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    11
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    12
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    13
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    14
 *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    15
 * This software consists of voluntary contributions made by many individuals
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    16
 * and is licensed under the LGPL. For more information, see
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    17
 * <http://www.doctrine-project.org>.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    18
 */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    19
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    20
namespace Doctrine\ORM\Internal\Hydration;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    21
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    22
use PDO,
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    23
    Doctrine\DBAL\Connection,
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    24
    Doctrine\DBAL\Types\Type,
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    25
    Doctrine\ORM\EntityManager;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    26
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    27
/**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    28
 * Base class for all hydrators. A hydrator is a class that provides some form
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    29
 * of transformation of an SQL result set into another structure.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    30
 *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    31
 * @since       2.0
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    32
 * @author      Konsta Vesterinen <kvesteri@cc.hut.fi>
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    33
 * @author      Roman Borschel <roman@code-factory.org>
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    34
 */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    35
abstract class AbstractHydrator
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    36
{
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    37
    /** @var ResultSetMapping The ResultSetMapping. */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    38
    protected $_rsm;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    39
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    40
    /** @var EntityManager The EntityManager instance. */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    41
    protected $_em;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    42
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    43
    /** @var AbstractPlatform The dbms Platform instance */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    44
    protected $_platform;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    45
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    46
    /** @var UnitOfWork The UnitOfWork of the associated EntityManager. */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    47
    protected $_uow;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    48
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    49
    /** @var array The cache used during row-by-row hydration. */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    50
    protected $_cache = array();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    51
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    52
    /** @var Statement The statement that provides the data to hydrate. */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    53
    protected $_stmt;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    54
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    55
    /** @var array The query hints. */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    56
    protected $_hints;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    57
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    58
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    59
     * Initializes a new instance of a class derived from <tt>AbstractHydrator</tt>.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    60
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    61
     * @param Doctrine\ORM\EntityManager $em The EntityManager to use.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    62
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    63
    public function __construct(EntityManager $em)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    64
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    65
        $this->_em = $em;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    66
        $this->_platform = $em->getConnection()->getDatabasePlatform();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    67
        $this->_uow = $em->getUnitOfWork();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    68
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    69
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    70
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    71
     * Initiates a row-by-row hydration.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    72
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    73
     * @param object $stmt
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    74
     * @param object $resultSetMapping
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    75
     * @return IterableResult
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    76
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    77
    public function iterate($stmt, $resultSetMapping, array $hints = array())
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    78
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    79
        $this->_stmt = $stmt;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    80
        $this->_rsm = $resultSetMapping;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    81
        $this->_hints = $hints;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    82
        $this->_prepare();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    83
        return new IterableResult($this);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    84
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    85
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    86
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    87
     * Hydrates all rows returned by the passed statement instance at once.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    88
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    89
     * @param object $stmt
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    90
     * @param object $resultSetMapping
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    91
     * @return mixed
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    92
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    93
    public function hydrateAll($stmt, $resultSetMapping, array $hints = array())
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    94
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    95
        $this->_stmt = $stmt;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    96
        $this->_rsm = $resultSetMapping;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    97
        $this->_hints = $hints;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    98
        $this->_prepare();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    99
        $result = $this->_hydrateAll();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   100
        $this->_cleanup();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   101
        return $result;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   102
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   103
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   104
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   105
     * Hydrates a single row returned by the current statement instance during
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   106
     * row-by-row hydration with {@link iterate()}.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   107
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   108
     * @return mixed
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   109
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   110
    public function hydrateRow()
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   111
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   112
        $row = $this->_stmt->fetch(PDO::FETCH_ASSOC);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   113
        if ( ! $row) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   114
            $this->_cleanup();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   115
            return false;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   116
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   117
        $result = array();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   118
        $this->_hydrateRow($row, $this->_cache, $result);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   119
        return $result;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   120
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   121
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   122
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   123
     * Excutes one-time preparation tasks, once each time hydration is started
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   124
     * through {@link hydrateAll} or {@link iterate()}.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   125
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   126
    protected function _prepare()
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   127
    {}
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   128
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   129
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   130
     * Excutes one-time cleanup tasks at the end of a hydration that was initiated
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   131
     * through {@link hydrateAll} or {@link iterate()}.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   132
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   133
    protected function _cleanup()
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   134
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   135
        $this->_rsm = null;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   136
        $this->_stmt->closeCursor();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   137
        $this->_stmt = null;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   138
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   139
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   140
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   141
     * Hydrates a single row from the current statement instance.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   142
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   143
     * Template method.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   144
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   145
     * @param array $data The row data.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   146
     * @param array $cache The cache to use.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   147
     * @param mixed $result The result to fill.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   148
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   149
    protected function _hydrateRow(array $data, array &$cache, array &$result)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   150
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   151
        throw new HydrationException("_hydrateRow() not implemented by this hydrator.");
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   152
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   153
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   154
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   155
     * Hydrates all rows from the current statement instance at once.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   156
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   157
    abstract protected function _hydrateAll();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   158
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   159
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   160
     * Processes a row of the result set.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   161
     * Used for identity-based hydration (HYDRATE_OBJECT and HYDRATE_ARRAY).
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   162
     * Puts the elements of a result row into a new array, grouped by the class
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   163
     * they belong to. The column names in the result set are mapped to their
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   164
     * field names during this procedure as well as any necessary conversions on
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   165
     * the values applied.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   166
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   167
     * @return array  An array with all the fields (name => value) of the data row,
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   168
     *                grouped by their component alias.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   169
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   170
    protected function _gatherRowData(array $data, array &$cache, array &$id, array &$nonemptyComponents)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   171
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   172
        $rowData = array();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   173
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   174
        foreach ($data as $key => $value) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   175
            // Parse each column name only once. Cache the results.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   176
            if ( ! isset($cache[$key])) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   177
                if (isset($this->_rsm->scalarMappings[$key])) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   178
                    $cache[$key]['fieldName'] = $this->_rsm->scalarMappings[$key];
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   179
                    $cache[$key]['isScalar'] = true;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   180
                } else if (isset($this->_rsm->fieldMappings[$key])) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   181
                    $fieldName = $this->_rsm->fieldMappings[$key];
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   182
                    $classMetadata = $this->_em->getClassMetadata($this->_rsm->declaringClasses[$key]);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   183
                    $cache[$key]['fieldName'] = $fieldName;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   184
                    $cache[$key]['type'] = Type::getType($classMetadata->fieldMappings[$fieldName]['type']);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   185
                    $cache[$key]['isIdentifier'] = $classMetadata->isIdentifier($fieldName);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   186
                    $cache[$key]['dqlAlias'] = $this->_rsm->columnOwnerMap[$key];
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   187
                } else if (!isset($this->_rsm->metaMappings[$key])) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   188
                    // this column is a left over, maybe from a LIMIT query hack for example in Oracle or DB2
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   189
                    // maybe from an additional column that has not been defined in a NativeQuery ResultSetMapping.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   190
                    continue;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   191
                } else {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   192
                    // Meta column (has meaning in relational schema only, i.e. foreign keys or discriminator columns).
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   193
                    $fieldName = $this->_rsm->metaMappings[$key];
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   194
                    $cache[$key]['isMetaColumn'] = true;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   195
                    $cache[$key]['fieldName'] = $fieldName;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   196
                    $cache[$key]['dqlAlias'] = $this->_rsm->columnOwnerMap[$key];
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   197
                    $classMetadata = $this->_em->getClassMetadata($this->_rsm->aliasMap[$cache[$key]['dqlAlias']]);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   198
                    $cache[$key]['isIdentifier'] = isset($this->_rsm->isIdentifierColumn[$cache[$key]['dqlAlias']][$key]);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   199
                }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   200
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   201
            
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   202
            if (isset($cache[$key]['isScalar'])) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   203
                $rowData['scalars'][$cache[$key]['fieldName']] = $value;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   204
                continue;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   205
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   206
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   207
            $dqlAlias = $cache[$key]['dqlAlias'];
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   208
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   209
            if ($cache[$key]['isIdentifier']) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   210
                $id[$dqlAlias] .= '|' . $value;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   211
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   212
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   213
            if (isset($cache[$key]['isMetaColumn'])) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   214
                if (!isset($rowData[$dqlAlias][$cache[$key]['fieldName']]) || $value !== null) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   215
                    $rowData[$dqlAlias][$cache[$key]['fieldName']] = $value;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   216
                }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   217
                continue;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   218
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   219
            
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   220
            // in an inheritance hierachy the same field could be defined several times.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   221
            // We overwrite this value so long we dont have a non-null value, that value we keep.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   222
            // Per definition it cannot be that a field is defined several times and has several values.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   223
            if (isset($rowData[$dqlAlias][$cache[$key]['fieldName']]) && $value === null) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   224
                continue;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   225
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   226
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   227
            $rowData[$dqlAlias][$cache[$key]['fieldName']] = $cache[$key]['type']->convertToPHPValue($value, $this->_platform);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   228
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   229
            if ( ! isset($nonemptyComponents[$dqlAlias]) && $value !== null) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   230
                $nonemptyComponents[$dqlAlias] = true;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   231
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   232
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   233
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   234
        return $rowData;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   235
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   236
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   237
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   238
     * Processes a row of the result set.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   239
     * Used for HYDRATE_SCALAR. This is a variant of _gatherRowData() that
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   240
     * simply converts column names to field names and properly converts the
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   241
     * values according to their types. The resulting row has the same number
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   242
     * of elements as before.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   243
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   244
     * @param array $data
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   245
     * @param array $cache
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   246
     * @return array The processed row.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   247
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   248
    protected function _gatherScalarRowData(&$data, &$cache)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   249
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   250
        $rowData = array();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   251
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   252
        foreach ($data as $key => $value) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   253
            // Parse each column name only once. Cache the results.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   254
            if ( ! isset($cache[$key])) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   255
                if (isset($this->_rsm->scalarMappings[$key])) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   256
                    $cache[$key]['fieldName'] = $this->_rsm->scalarMappings[$key];
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   257
                    $cache[$key]['isScalar'] = true;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   258
                } else if (isset($this->_rsm->fieldMappings[$key])) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   259
                    $fieldName = $this->_rsm->fieldMappings[$key];
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   260
                    $classMetadata = $this->_em->getClassMetadata($this->_rsm->declaringClasses[$key]);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   261
                    $cache[$key]['fieldName'] = $fieldName;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   262
                    $cache[$key]['type'] = Type::getType($classMetadata->fieldMappings[$fieldName]['type']);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   263
                    $cache[$key]['dqlAlias'] = $this->_rsm->columnOwnerMap[$key];
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   264
                } else if (!isset($this->_rsm->metaMappings[$key])) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   265
                    // this column is a left over, maybe from a LIMIT query hack for example in Oracle or DB2
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   266
                    // maybe from an additional column that has not been defined in a NativeQuery ResultSetMapping.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   267
                    continue;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   268
                } else {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   269
                    // Meta column (has meaning in relational schema only, i.e. foreign keys or discriminator columns).
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   270
                    $cache[$key]['isMetaColumn'] = true;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   271
                    $cache[$key]['fieldName'] = $this->_rsm->metaMappings[$key];
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   272
                    $cache[$key]['dqlAlias'] = $this->_rsm->columnOwnerMap[$key];
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   273
                }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   274
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   275
            
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   276
            $fieldName = $cache[$key]['fieldName'];
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   277
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   278
            if (isset($cache[$key]['isScalar'])) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   279
                $rowData[$fieldName] = $value;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   280
            } else if (isset($cache[$key]['isMetaColumn'])) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   281
                $rowData[$cache[$key]['dqlAlias'] . '_' . $fieldName] = $value;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   282
            } else {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   283
                $rowData[$cache[$key]['dqlAlias'] . '_' . $fieldName] = $cache[$key]['type']
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   284
                        ->convertToPHPValue($value, $this->_platform);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   285
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   286
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   287
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   288
        return $rowData;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   289
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   290
    
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   291
    protected function registerManaged($class, $entity, $data)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   292
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   293
        if ($class->isIdentifierComposite) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   294
            $id = array();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   295
            foreach ($class->identifier as $fieldName) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   296
                if (isset($class->associationMappings[$fieldName])) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   297
                    $id[$fieldName] = $data[$class->associationMappings[$fieldName]['joinColumns'][0]['name']];
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   298
                } else {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   299
                    $id[$fieldName] = $data[$fieldName];
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   300
                }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   301
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   302
        } else {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   303
            if (isset($class->associationMappings[$class->identifier[0]])) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   304
                $id = array($class->identifier[0] => $data[$class->associationMappings[$class->identifier[0]]['joinColumns'][0]['name']]);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   305
            } else {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   306
                $id = array($class->identifier[0] => $data[$class->identifier[0]]);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   307
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   308
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   309
        $this->_em->getUnitOfWork()->registerManaged($entity, $id, $data);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   310
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   311
}