Completed
Push — master ( db1323...27dbeb )
by Sébastien
03:00
created

MysqlDriver51   A

Complexity

Total Complexity 30

Size/Duplication

Total Lines 261
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 100%

Importance

Changes 2
Bugs 1 Features 0
Metric Value
wmc 30
c 2
b 1
f 0
lcom 1
cbo 3
dl 0
loc 261
ccs 137
cts 137
cp 1
rs 10

2 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
F getSchemaConfig() 0 233 29
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\strinb>.

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