vendor/doctrine-fixtures/lib/Doctrine/Common/DataFixtures/Purger/ORMPurger.php
changeset 58 624e5900f5a4
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vendor/doctrine-fixtures/lib/Doctrine/Common/DataFixtures/Purger/ORMPurger.php	Wed Dec 14 23:28:58 2011 +0100
@@ -0,0 +1,165 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\DataFixtures\Purger;
+
+use Doctrine\ORM\EntityManager;
+use Doctrine\ORM\Internal\CommitOrderCalculator;
+use Doctrine\ORM\Mapping\ClassMetadata;
+
+/**
+ * Class responsible for purging databases of data before reloading data fixtures.
+ *
+ * @author Jonathan H. Wage <jonwage@gmail.com>
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class ORMPurger implements PurgerInterface
+{
+    const PURGE_MODE_DELETE = 1;
+    const PURGE_MODE_TRUNCATE = 2;
+
+    /** EntityManager instance used for persistence. */
+    private $em;
+
+    /**
+     * If the purge should be done through DELETE or TRUNCATE statements
+     *
+     * @var int
+     */
+    private $purgeMode = self::PURGE_MODE_DELETE;
+
+    /**
+     * Construct new purger instance.
+     *
+     * @param EntityManager $em EntityManager instance used for persistence.
+     */
+    public function __construct(EntityManager $em = null)
+    {
+        $this->em = $em;
+    }
+
+    /**
+     * Set the purge mode
+     *
+     * @param $mode
+     * @return void
+     */
+    public function setPurgeMode($mode)
+    {
+        $this->purgeMode = $mode;
+    }
+
+    /**
+     * Get the purge mode
+     *
+     * @return int
+     */
+    public function getPurgeMode()
+    {
+        return $this->purgeMode;
+    }
+
+    /**
+     * Set the EntityManager instance this purger instance should use.
+     *
+     * @param EntityManager $em
+     */
+    public function setEntityManager(EntityManager $em)
+    {
+      $this->em = $em;
+    }
+
+    /** @inheritDoc */
+    public function purge()
+    {
+        $classes = array();
+        $metadatas = $this->em->getMetadataFactory()->getAllMetadata();
+
+        foreach ($metadatas as $metadata) {
+            if ( ! $metadata->isMappedSuperclass) {
+                $classes[] = $metadata;
+            }
+        }
+
+        $commitOrder = $this->getCommitOrder($this->em, $classes);
+
+        // Drop association tables first
+        $orderedTables = $this->getAssociationTables($commitOrder);
+
+        // Drop tables in reverse commit order
+        for ($i = count($commitOrder) - 1; $i >= 0; --$i) {
+            $class = $commitOrder[$i];
+
+            if (($class->isInheritanceTypeSingleTable() && $class->name != $class->rootEntityName)
+                || $class->isMappedSuperclass) {
+                continue;
+            }
+
+            $orderedTables[] = $class->getTableName();
+        }
+
+        $platform = $this->em->getConnection()->getDatabasePlatform();
+        foreach($orderedTables as $tbl) {
+            if ($this->purgeMode === self::PURGE_MODE_DELETE) {
+                $this->em->getConnection()->executeUpdate("DELETE FROM " . $tbl);
+            } else {
+                $this->em->getConnection()->executeUpdate($platform->getTruncateTableSQL($tbl, true));
+            }
+        }
+    }
+
+    private function getCommitOrder(EntityManager $em, array $classes)
+    {
+        $calc = new CommitOrderCalculator;
+
+        foreach ($classes as $class) {
+            $calc->addClass($class);
+
+            foreach ($class->associationMappings as $assoc) {
+                if ($assoc['isOwningSide']) {
+                    $targetClass = $em->getClassMetadata($assoc['targetEntity']);
+
+                    if ( ! $calc->hasClass($targetClass->name)) {
+                        $calc->addClass($targetClass);
+                    }
+
+                    // add dependency ($targetClass before $class)
+                    $calc->addDependency($targetClass, $class);
+                }
+            }
+        }
+
+        return $calc->getCommitOrder();
+    }
+
+    private function getAssociationTables(array $classes)
+    {
+        $associationTables = array();
+
+        foreach ($classes as $class) {
+            foreach ($class->associationMappings as $assoc) {
+                if ($assoc['isOwningSide'] && $assoc['type'] == ClassMetadata::MANY_TO_MANY) {
+                    $associationTables[] = $assoc['joinTable']['name'];
+                }
+            }
+        }
+
+        return $associationTables;
+    }
+}