vendor/doctrine-fixtures/lib/Doctrine/Common/DataFixtures/Purger/ORMPurger.php
author ymh <ymh.work@gmail.com>
Wed, 14 Dec 2011 23:28:58 +0100
changeset 58 624e5900f5a4
permissions -rw-r--r--
add tests and fixtures
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
58
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
     1
<?php
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
     2
/*
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
     3
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
     4
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
     5
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
     6
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
     7
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
     8
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
     9
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    10
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    11
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    12
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    13
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    14
 *
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    15
 * This software consists of voluntary contributions made by many individuals
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    16
 * and is licensed under the LGPL. For more information, see
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    17
 * <http://www.doctrine-project.org>.
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    18
 */
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    19
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    20
namespace Doctrine\Common\DataFixtures\Purger;
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    21
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    22
use Doctrine\ORM\EntityManager;
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    23
use Doctrine\ORM\Internal\CommitOrderCalculator;
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    24
use Doctrine\ORM\Mapping\ClassMetadata;
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    25
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    26
/**
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    27
 * Class responsible for purging databases of data before reloading data fixtures.
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    28
 *
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    29
 * @author Jonathan H. Wage <jonwage@gmail.com>
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    30
 * @author Benjamin Eberlei <kontakt@beberlei.de>
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    31
 */
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    32
class ORMPurger implements PurgerInterface
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    33
{
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    34
    const PURGE_MODE_DELETE = 1;
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    35
    const PURGE_MODE_TRUNCATE = 2;
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    36
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    37
    /** EntityManager instance used for persistence. */
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    38
    private $em;
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    39
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    40
    /**
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    41
     * If the purge should be done through DELETE or TRUNCATE statements
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    42
     *
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    43
     * @var int
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    44
     */
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    45
    private $purgeMode = self::PURGE_MODE_DELETE;
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    46
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    47
    /**
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    48
     * Construct new purger instance.
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    49
     *
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    50
     * @param EntityManager $em EntityManager instance used for persistence.
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    51
     */
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    52
    public function __construct(EntityManager $em = null)
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    53
    {
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    54
        $this->em = $em;
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    55
    }
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    56
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    57
    /**
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    58
     * Set the purge mode
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    59
     *
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    60
     * @param $mode
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    61
     * @return void
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    62
     */
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    63
    public function setPurgeMode($mode)
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    64
    {
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    65
        $this->purgeMode = $mode;
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    66
    }
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    67
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    68
    /**
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    69
     * Get the purge mode
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    70
     *
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    71
     * @return int
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    72
     */
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    73
    public function getPurgeMode()
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    74
    {
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    75
        return $this->purgeMode;
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    76
    }
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    77
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    78
    /**
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    79
     * Set the EntityManager instance this purger instance should use.
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    80
     *
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    81
     * @param EntityManager $em
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    82
     */
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    83
    public function setEntityManager(EntityManager $em)
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    84
    {
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    85
      $this->em = $em;
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    86
    }
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    87
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    88
    /** @inheritDoc */
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    89
    public function purge()
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    90
    {
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    91
        $classes = array();
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    92
        $metadatas = $this->em->getMetadataFactory()->getAllMetadata();
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    93
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    94
        foreach ($metadatas as $metadata) {
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    95
            if ( ! $metadata->isMappedSuperclass) {
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    96
                $classes[] = $metadata;
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    97
            }
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    98
        }
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
    99
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
   100
        $commitOrder = $this->getCommitOrder($this->em, $classes);
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
   101
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
   102
        // Drop association tables first
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
   103
        $orderedTables = $this->getAssociationTables($commitOrder);
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
   104
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
   105
        // Drop tables in reverse commit order
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
   106
        for ($i = count($commitOrder) - 1; $i >= 0; --$i) {
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
   107
            $class = $commitOrder[$i];
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
   108
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
   109
            if (($class->isInheritanceTypeSingleTable() && $class->name != $class->rootEntityName)
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
   110
                || $class->isMappedSuperclass) {
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
   111
                continue;
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
   112
            }
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
   113
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
   114
            $orderedTables[] = $class->getTableName();
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
   115
        }
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
   116
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
   117
        $platform = $this->em->getConnection()->getDatabasePlatform();
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
   118
        foreach($orderedTables as $tbl) {
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
   119
            if ($this->purgeMode === self::PURGE_MODE_DELETE) {
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
   120
                $this->em->getConnection()->executeUpdate("DELETE FROM " . $tbl);
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
   121
            } else {
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
   122
                $this->em->getConnection()->executeUpdate($platform->getTruncateTableSQL($tbl, true));
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
   123
            }
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
   124
        }
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
   125
    }
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
   126
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
   127
    private function getCommitOrder(EntityManager $em, array $classes)
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
   128
    {
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
   129
        $calc = new CommitOrderCalculator;
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
   130
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
   131
        foreach ($classes as $class) {
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
   132
            $calc->addClass($class);
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
   133
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
   134
            foreach ($class->associationMappings as $assoc) {
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
   135
                if ($assoc['isOwningSide']) {
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
   136
                    $targetClass = $em->getClassMetadata($assoc['targetEntity']);
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
   137
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
   138
                    if ( ! $calc->hasClass($targetClass->name)) {
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
   139
                        $calc->addClass($targetClass);
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
   140
                    }
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
   141
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
   142
                    // add dependency ($targetClass before $class)
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
   143
                    $calc->addDependency($targetClass, $class);
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
   144
                }
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
   145
            }
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
   146
        }
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
   147
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
   148
        return $calc->getCommitOrder();
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
   149
    }
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
   150
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
   151
    private function getAssociationTables(array $classes)
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
   152
    {
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
   153
        $associationTables = array();
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
   154
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
   155
        foreach ($classes as $class) {
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
   156
            foreach ($class->associationMappings as $assoc) {
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
   157
                if ($assoc['isOwningSide'] && $assoc['type'] == ClassMetadata::MANY_TO_MANY) {
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
   158
                    $associationTables[] = $assoc['joinTable']['name'];
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
   159
                }
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
   160
            }
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
   161
        }
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
   162
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
   163
        return $associationTables;
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
   164
    }
624e5900f5a4 add tests and fixtures
ymh <ymh.work@gmail.com>
parents:
diff changeset
   165
}