GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

CreateDatabase::diff()   D
last analyzed

Complexity

Conditions 21
Paths 16

Size

Total Lines 60
Code Lines 35

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 30
CRAP Score 21

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 21
eloc 35
nc 16
nop 2
dl 0
loc 60
rs 4.1666
c 1
b 0
f 0
ccs 30
cts 30
cp 1
crap 21

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
namespace Graze\Morphism\Parse;
3
4
use RuntimeException;
5
6
/**
7
 * Represents the definition of a database.
8
 */
9
class CreateDatabase
10
{
11
    /** @var string */
12
    public $name = '';
13
14
    /**
15
     * @var CreateTable[]
16
     *
17
     * indexed by (string) table name; when enumerated, reflects the order
18
     * in which the table definitions were parsed.
19
     */
20
    public $tables = [];
21
22
    /** @var CollationInfo */
23
    private $collation = null;
24
    /** @var CollationInfo */
25
    private $defaultCollation = null;
26
27
    /**
28
     * Constructor.
29
     *
30
     * @param CollationInfo $defaultCollation
31
     */
32 12
    public function __construct(CollationInfo $defaultCollation)
33
    {
34 12
        $this->collation = new CollationInfo();
35 12
        $this->defaultCollation = clone $defaultCollation;
36 12
    }
37
38
    /**
39
     * Parses a database declaration from $stream.
40
     *
41
     * Declarations must be of the form 'CREATE DATABASE ...' or
42
     * 'CREATE DATABASE IF NOT EXISTS ...'. Anything else will cause
43
     * an exception to be thrown.
44
     *
45
     * @param TokenStream $stream
46
     */
47 8
    public function parse(TokenStream $stream)
48
    {
49 8
        if ($stream->consume('CREATE DATABASE')) {
50 7
            $stream->consume('IF NOT EXISTS');
51
        } else {
52 1
            throw new RuntimeException("Expected CREATE DATABASE");
53
        }
54
55 7
        $this->name = $stream->expectName();
56 7
        while (true) {
57 7
            $stream->consume('DEFAULT');
58 7
            if ($stream->consume('CHARSET') ||
59 7
                $stream->consume('CHARACTER SET')
60
            ) {
61 3
                $stream->consume([[Token::SYMBOL, '=']]);
62 3
                $charset = $stream->expectName();
63 3
                if (strtoupper($charset) === 'DEFAULT') {
64 2
                    $this->collation = new CollationInfo();
65
                } else {
66 3
                    $this->collation->setCharset($charset);
67
                }
68 7
            } elseif ($stream->consume('COLLATE')) {
69 2
                $stream->consume([[Token::SYMBOL, '=']]);
70 2
                $collation = $stream->expectName();
71 2
                if (strtoupper($collation) === 'DEFAULT') {
72 1
                    $this->collation = new CollationInfo();
73
                } else {
74 2
                    $this->collation->setCollation($collation);
75
                }
76
            } else {
77 7
                break;
78
            }
79
        }
80 7
    }
81
82
    /**
83
     * Returns the default collation associated with the database.
84
     *
85
     * @return CollationInfo
86
     */
87 8
    public function getCollation()
88
    {
89 8
        return $this->collation->isSpecified()
90 2
            ? $this->collation
91 8
            : $this->defaultCollation;
92
    }
93
94
    /**
95
     * @param CreateTable $table
96
     * @throws RuntimeException
97
     */
98 2
    public function addTable(CreateTable $table)
99
    {
100 2
        if ($table->getName()) {
101 1
            $this->tables[$table->getName()] = $table;
102
        } else {
103 1
            throw new RuntimeException("No table name in Create Table object");
104
        }
105 1
    }
106
107
    /**
108
     * Returns an array of SQL DDL statements to create the database.
109
     *
110
     * The returned DDL only refers to the database itself, it does not include
111
     * the necessary DDL to create any contained tables. For that you will need
112
     * to iterate over the $tables property, calling getDDL() on each element.
113
     *
114
     * @return array
115
     * @throws RuntimeException
116
     */
117 4
    public function getDDL()
118
    {
119 4
        if (!$this->name) {
120 1
            throw new RuntimeException('No database name specified');
121
        }
122
123 3
        $text = "CREATE DATABASE IF NOT EXISTS " . Token::escapeIdentifier($this->name);
124
125 3
        $collation = $this->getCollation();
126 3
        if ($collation->isSpecified()) {
127 2
            $text .= " DEFAULT CHARACTER SET " . $collation->getCharset();
128 2
            if (!$collation->isDefaultCollation()) {
129 1
                $text .= " COLLATE " . $collation->getCollation();
130
            }
131
        }
132
133 3
        return [$text];
134
    }
135
136
    /**
137
     * Returns an array of SQL DDL statements to transform this database and
138
     * all contained tables into the database specified by $that.
139
     *
140
     * $flags        |
141
     * :-------------|----
142
     * 'createTable' | (bool) include 'CREATE TABLE' statements [default: true]
143
     * 'dropTable'   | (bool) include 'DROP TABLE' statements [default: true]
144
     * 'alterEngine' | (bool) include ALTER TABLE ... ENGINE= [default: true]
145
     * 'matchTables' | ['include' => $regex, 'exclude' => $regex] regex of tables to include/exclude
146
     *
147
     * @param CreateDatabase $that
148
     * @param array $flags
149
     * @return string[]
150
     */
151 9
    public function diff(CreateDatabase $that, array $flags = [])
152
    {
153
        $flags += [
154 9
            'createTable' => true,
155
            'dropTable'   => true,
156
            'alterEngine' => true,
157
            'matchTables' => [
158
                'include' => '',
159
                'exclude' => '',
160
            ],
161
        ];
162
163 9
        $thisTableNames = array_keys($this->tables);
164 9
        $thatTableNames = array_keys($that->tables);
165
166 9
        $commonTableNames  = array_intersect($thisTableNames, $thatTableNames);
167 9
        $droppedTableNames = array_diff($thisTableNames, $thatTableNames);
168 9
        $createdTableNames = array_diff($thatTableNames, $thisTableNames);
169
170 9
        $diff = [];
171
172 9
        $includeTablesRegex = $flags['matchTables']['include'];
173 9
        $excludeTablesRegex = $flags['matchTables']['exclude'];
174
175 9
        if ($flags['dropTable'] && count($droppedTableNames) > 0) {
176 1
            foreach ($droppedTableNames as $tableName) {
177 1
                if (($includeTablesRegex == '' || preg_match($includeTablesRegex, $tableName)) &&
178 1
                    ($excludeTablesRegex == '' || !preg_match($excludeTablesRegex, $tableName))
179
                ) {
180 1
                    $diff[] = "DROP TABLE IF EXISTS " . Token::escapeIdentifier($tableName);
181
                }
182
            }
183
        }
184
185 9
        if ($flags['createTable'] && count($createdTableNames) > 0) {
186 2
            foreach ($createdTableNames as $tableName) {
187 2
                if (($includeTablesRegex == '' || preg_match($includeTablesRegex, $tableName)) &&
188 2
                    ($excludeTablesRegex == '' || !preg_match($excludeTablesRegex, $tableName))
189
                ) {
190 2
                    $diff = array_merge($diff, $that->tables[$tableName]->getDDL());
191
                }
192
            }
193
        }
194
195 9
        foreach ($commonTableNames as $tableName) {
196 2
            if (($includeTablesRegex == '' || preg_match($includeTablesRegex, $tableName)) &&
197 2
                ($excludeTablesRegex == '' || !preg_match($excludeTablesRegex, $tableName))
198
            ) {
199 2
                $thisTable = $this->tables[$tableName];
200 2
                $thatTable = $that->tables[$tableName];
201 2
                $tableDiff = $thisTable->diff($thatTable, [
202 2
                    'alterEngine' => $flags['alterEngine'],
203
                ]);
204 2
                if (!empty($tableDiff)) {
205 1
                    $diff = array_merge($diff, $tableDiff);
206
                }
207
            }
208
        }
209
210 9
        return $diff;
211
    }
212
}
213