1<?php
2
3namespace Doctrine\DBAL\Schema\Visitor;
4
5use Doctrine\DBAL\Platforms\AbstractPlatform;
6use Doctrine\DBAL\Schema\ForeignKeyConstraint;
7use Doctrine\DBAL\Schema\SchemaException;
8use Doctrine\DBAL\Schema\Sequence;
9use Doctrine\DBAL\Schema\Table;
10use SplObjectStorage;
11
12use function assert;
13use function strlen;
14
15/**
16 * Gathers SQL statements that allow to completely drop the current schema.
17 */
18class DropSchemaSqlCollector extends AbstractVisitor
19{
20    /** @var SplObjectStorage */
21    private $constraints;
22
23    /** @var SplObjectStorage */
24    private $sequences;
25
26    /** @var SplObjectStorage */
27    private $tables;
28
29    /** @var AbstractPlatform */
30    private $platform;
31
32    public function __construct(AbstractPlatform $platform)
33    {
34        $this->platform = $platform;
35        $this->initializeQueries();
36    }
37
38    /**
39     * {@inheritdoc}
40     */
41    public function acceptTable(Table $table)
42    {
43        $this->tables->attach($table);
44    }
45
46    /**
47     * {@inheritdoc}
48     */
49    public function acceptForeignKey(Table $localTable, ForeignKeyConstraint $fkConstraint)
50    {
51        if (strlen($fkConstraint->getName()) === 0) {
52            throw SchemaException::namedForeignKeyRequired($localTable, $fkConstraint);
53        }
54
55        $this->constraints->attach($fkConstraint, $localTable);
56    }
57
58    /**
59     * {@inheritdoc}
60     */
61    public function acceptSequence(Sequence $sequence)
62    {
63        $this->sequences->attach($sequence);
64    }
65
66    /**
67     * @return void
68     */
69    public function clearQueries()
70    {
71        $this->initializeQueries();
72    }
73
74    /**
75     * @return string[]
76     */
77    public function getQueries()
78    {
79        $sql = [];
80
81        foreach ($this->constraints as $fkConstraint) {
82            assert($fkConstraint instanceof ForeignKeyConstraint);
83            $localTable = $this->constraints[$fkConstraint];
84            $sql[]      = $this->platform->getDropForeignKeySQL($fkConstraint, $localTable);
85        }
86
87        foreach ($this->sequences as $sequence) {
88            assert($sequence instanceof Sequence);
89            $sql[] = $this->platform->getDropSequenceSQL($sequence);
90        }
91
92        foreach ($this->tables as $table) {
93            assert($table instanceof Table);
94            $sql[] = $this->platform->getDropTableSQL($table);
95        }
96
97        return $sql;
98    }
99
100    private function initializeQueries(): void
101    {
102        $this->constraints = new SplObjectStorage();
103        $this->sequences   = new SplObjectStorage();
104        $this->tables      = new SplObjectStorage();
105    }
106}
107