Completed
Push — master ( 7b7ebd...db1323 )
by Sébastien
02:06
created

MysqlDriver51::getSchemaConfig()   F

Complexity

Conditions 30
Paths 19456

Size

Total Lines 237
Code Lines 127

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 135
CRAP Score 30.0028

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 237
ccs 135
cts 137
cp 0.9854
rs 2
cc 30
eloc 127
nc 19456
nop 2
crap 30.0028

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
3
namespace Soluble\Schema\Source\Mysql;
4
5
use Soluble\Schema\Db\Wrapper\MysqlConnectionAdapter;
6
use ArrayObject;
7
use Zend\Config\Config;
8
9
class MysqlDriver51 extends AbstractMysqlDriver
10
{
11
12
    /**
13
     * @var MysqlConnectionAdapter
14
     */
15
    protected $adapter;
16
17
    /**
18
     * Schema name
19
     * @var string
20
     */
21
    protected $schema;
22
23
    /**
24
     *
25
     * @param MysqlConnectionAdapter $adapter
26
     * @param string $schema Schema name
27
     */
28 23
    public function __construct(MysqlConnectionAdapter $adapter, $schema)
29
    {
30 23
        parent::__construct($adapter, $schema);
0 ignored issues
show
Documentation introduced by
$schema is of type string, but the function expects a object<Soluble\Schema\Source\Mysql\strinbg>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
31 23
    }
32
33
    /**
34
     * Return object (table/schema) configuration
35
     *
36
     * @throws Exception\ErrorException
37
     *
38
     * @param string $table
39
     * @param boolean|null $include_options
40
     * @return ArrayObject
41
     */
42 6
    public function getSchemaConfig($table = null, $include_options = null)
43
    {
44 6
        if ($include_options === null) {
45
            $include_options = $this->include_options;
0 ignored issues
show
Bug introduced by
The property include_options does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
46
        }
47
48 6
        $schema = $this->schema;
49 6
        $qSchema = $this->adapter->quoteValue($schema);
50
51 6
        if ($table !== null) {
52 4
            $qTable = $this->adapter->quoteValue($table);
53 4
            $table_clause = "and (t.TABLE_NAME = $qTable or (kcu.referenced_table_name = $qTable and kcu.constraint_name = 'FOREIGN KEY'))";
54 4
            $table_join_condition = "(t.table_name = kcu.table_name or  kcu.referenced_table_name = t.table_name)";
55 4
        } else {
56 2
            $table_join_condition = "t.table_name = kcu.table_name";
57 2
            $table_clause = '';
58
        }
59
60
        $query = "
61
62
            SELECT
63
                    t.table_name,
64
                    c.column_name,
65
                    c.data_type,
66
                    c.column_type,
67
68
                    c.extra,
69
70
                    tc.constraint_type,
71
                    kcu.constraint_name,
72
                    kcu.referenced_table_name,
73
                    kcu.referenced_column_name,
74
75
                    c.column_default,
76
                    c.is_nullable,
77
                    c.numeric_precision,
78
                    c.numeric_scale,
79
                    c.character_octet_length,
80
                    c.character_maximum_length,
81
                    c.ordinal_position,
82
83
                    c.column_key, -- UNI/MUL/PRI
84
                    c.character_set_name,
85
86
87
                    c.collation_name,
88
89
                    c.column_comment,
90
91
                    t.table_type,
92
                    t.engine,
93
                    t.table_comment,
94
                    t.table_collation
95
96
            FROM `INFORMATION_SCHEMA`.`COLUMNS` c
97
            INNER JOIN `INFORMATION_SCHEMA`.`TABLES` t on c.TABLE_NAME = t.TABLE_NAME
98
            LEFT JOIN `INFORMATION_SCHEMA`.`KEY_COLUMN_USAGE` kcu
99
               on (
100
                    $table_join_condition
101
                     and kcu.table_schema = t.table_schema
102
                     and kcu.column_name = c.column_name
103
                 )
104
              LEFT JOIN
105
                `INFORMATION_SCHEMA`.`TABLE_CONSTRAINTS` tc
106
               on (
107
                     t.table_name = tc.table_name
108
                      and tc.table_schema = t.table_schema
109
                      and tc.constraint_name = kcu.constraint_name
110
                  )
111
112
113 6
            where c.TABLE_SCHEMA = $qSchema
114 6
            and t.TABLE_SCHEMA = $qSchema
115 6
            $table_clause
116 6
            and (kcu.table_schema = $qSchema  or kcu.table_schema is null)
117
118
            and (kcu.column_name = c.column_name or kcu.column_name is null)
119
            order by t.table_name, c.ordinal_position
120 6
        ";
121
122 6
        $this->disableInnoDbStats();
123
        try {
124 6
            $results = $this->adapter->query($query);
125 6
        } catch (\Exception $e) {
126
            //@codeCoverageIgnoreStart
127
            $this->restoreInnoDbStats();
128
            throw new Exception\ErrorException(__METHOD__ . ": " . $e->getMessage());
129
            //@codeCoverageIgnoreEnd
130
        }
131 6
        $this->restoreInnoDbStats();
132
133 6
        $references = array();
134 6
        $config = new Config(array('tables' => array()), true);
135 6
        $tables = $config->offsetGet('tables');
136
137
138 6
        foreach ($results as $r) {
139
            // Setting table information
140 3
            $table_name = $r['table_name'];
141 3
            if (!$tables->offsetExists($table_name)) {
142
                $table_def = array(
143 3
                    'name'          => $table_name,
144 3
                    'columns'       => array(),
145 3
                    'primary_keys'  => array(),
146 3
                    'unique_keys'   => array(),
147 3
                    'foreign_keys'  => array(),
148 3
                    'references'    => array(),
149 3
                    'indexes'       => array(),
150 3
                );
151 3
                if ($include_options) {
152 3
                    $table_def['options'] = array(
153 3
                       'comment'   => $r['table_comment'],
154 3
                       'collation' => $r['table_collation'],
155 3
                       'type'      => $r['table_type'],
156 3
                       'engine'    => $r['engine']
157 3
                    );
158 3
                }
159 3
                $tables->offsetSet($table_name, $table_def);
160 3
            }
161 3
            $table   = $tables->offsetGet($table_name);
162 3
            $columns = $table->columns;
163 3
            $column_name = $r['column_name'];
164
165 3
            $data_type = strtolower($r['data_type']);
166
167
            $col_def = array(
168 3
                'type'          => $data_type,
169 3
                'primary'       => ($r['constraint_type'] == 'PRIMARY KEY'),
170 3
                'nullable'      => ($r['is_nullable'] == 'YES'),
171 3
                'default'       => $r['column_default']
172 3
            );
173 3
            if (($r['constraint_type'] == 'PRIMARY KEY')) {
174 2
                $col_def['primary'] = true;
175 2
                $col_def['autoincrement'] = ($r['extra'] == 'auto_increment');
176 2
            }
177
178 3
            $has_charset = false;
179 3
            if (in_array($data_type, array('int', 'tinyint', 'mediumint', 'bigint', 'int', 'smallint', 'year'))) {
180 3
                $col_def['unsigned']  = (bool) preg_match('/unsigned/', strtolower($r['column_type']));
181 3
                $col_def['precision'] = is_numeric($r['numeric_precision']) ? (int) $r['numeric_precision'] : null;
182 3
            } elseif (in_array($data_type, array('real', 'double precision', 'decimal', 'numeric', 'float', 'dec', 'fixed'))) {
183 1
                $col_def['precision'] = is_numeric($r['numeric_precision']) ? (int) $r['numeric_precision'] : null;
184 1
                $col_def['scale']     = is_numeric($r['numeric_scale']) ? (int) $r['numeric_scale'] : null;
185 2
            } elseif (in_array($data_type, array('timestamp', 'date', 'time', 'datetime'))) {
186
                // nothing yet
187 2
            } elseif (in_array($data_type, array('char', 'varchar', 'binary', 'varbinary', 'text', 'tinytext', 'mediumtext', 'longtext'))) {
188 2
                $col_def['octet_length'] = is_numeric($r['character_octet_length']) ? (int) $r['character_octet_length'] : null;
189 2
                $col_def['length'] = is_numeric($r['character_maximum_length']) ? (int) $r['character_maximum_length'] : null;
190 2
                $has_charset = true;
191 2
            } elseif (in_array($data_type, array('blob', 'tinyblob', 'mediumblob', 'longblob'))) {
192 1
                $col_def['octet_length'] = (int) $r['character_octet_length'];
193 1
                $col_def['length'] = (int) $r['character_maximum_length'];
194 1
            } elseif (in_array($data_type, array('enum', 'set'))) {
195 1
                $col_def['octet_length'] = (int) $r['character_octet_length'];
196 1
                $col_def['length'] = (int) $r['character_maximum_length'];
197 1
                $def = $r['column_type'];
198
199 1
                preg_match_all("/'([^']+)'/", $def, $matches);
200 1
                if (is_array($matches[1]) && count($matches) > 0) {
201 1
                    $col_def['values'] = $matches[1];
202 1
                }
203 1
            }
204
205 3
            if ($include_options) {
206 3
                $col_def['options'] = array(
207 3
                        'comment'           => $r['column_comment'],
208 3
                        'definition'        => $r['column_type'],
209 3
                        'column_key'        => $r['column_key'],
210 3
                        'ordinal_position'  => $r['ordinal_position'],
211 3
                        'constraint_type'   => $r['constraint_type'], // 'PRIMARY KEY', 'FOREIGN_KEY', 'UNIQUE'
212
                    );
213 3
                if ($has_charset) {
214 2
                    $col_def['options']['charset']     = $r['character_set_name'];
215 2
                    $col_def['options']['collation']   = $r['collation_name'];
216 2
                }
217 3
            }
218
219 3
            $columns[$column_name] = $col_def;
220
221 3
            $foreign_keys = $table->foreign_keys;
222 3
            $unique_keys  = $table->unique_keys;
223
224 3
            $constraint_name = $r['constraint_name'];
225 3
            $referenced_table_name = $r['referenced_table_name'];
226 3
            $referenced_column_name = $r['referenced_column_name'];
227 3
            switch ($r['constraint_type']) {
228 3
                case 'PRIMARY KEY':
229 2
                    $table->primary_keys = array_merge($table->primary_keys->toArray(), (array) $column_name);
230 2
                    break;
231 3
                case 'UNIQUE':
232 2
                    if (!$unique_keys->offsetExists($constraint_name)) {
233 2
                        $unique_keys[$constraint_name] = array();
234 2
                    }
235 2
                    $unique_keys[$constraint_name] = array_merge($unique_keys[$constraint_name]->toArray(), (array) $column_name);
236 2
                    break;
237 3
                case 'FOREIGN KEY':
238
                    /*
239
                    if (!$foreign_keys->offsetExists($constraint_name)) {
240
                        $foreign_keys[$constraint_name] = array();
241
                    }
242
                     *
243
                     */
244
                    $fk = array(
245 1
                       'referenced_table'  => $referenced_table_name,
246 1
                       'referenced_column' => $referenced_column_name,
247
                       'constraint_name' => $constraint_name
248 1
                    );
249 1
                    $foreign_keys[$column_name] = $fk;
250
                    //$table->references[$referenced_table_name] = array($column_name => $r['referenced_column_name']);
251
252 1
                    if (!array_key_exists($referenced_table_name, $references)) {
253 1
                        $references[$referenced_table_name] = array();
254 1
                    }
255
256 1
                    $k = "$table_name:$referenced_column_name->$column_name";
257 1
                    $references[$referenced_table_name][$k] = array(
258 1
                        'column' => $column_name,
259 1
                        'referencing_table' => $table_name,
260 1
                        'referencing_column' => $referenced_column_name,
261
                        'constraint_name' => $constraint_name
262 1
                    );
263 1
                    break;
264 3
            }
265 6
        }
266
267 6
        foreach ($references as $referenced_table_name => $refs) {
268 1
            if ($tables->offsetExists($referenced_table_name)) {
269 1
                $table = $tables[$referenced_table_name];
270 1
                $table->references = $refs;
271 1
            }
272 6
        }
273
274 6
        $array = new ArrayObject($config->toArray());
275 6
        unset($config);
276 6
        return $array;
277
278
    }
279
}
280