Completed
Push — master ( 35c3f5...647ae2 )
by Rougin
02:51
created

MySQLDriver::columns()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
cc 1
eloc 2
nc 1
nop 1
crap 1
1
<?php
2
3
namespace Rougin\Describe\Driver;
4
5
use Rougin\Describe\Column;
6
use Rougin\Describe\Table;
7
8
/**
9
 * MySQL Driver
10
 *
11
 * A database driver extension for MySQL.
12
 * NOTE: Should be renamed to "MySqlDriver" in v2.0.0.
13
 *
14
 * @package Describe
15
 * @author  Rougin Royce Gutib <[email protected]>
16
 */
17
class MySQLDriver extends AbstractDriver implements DriverInterface
18
{
19
    /**
20
     * @var string
21
     */
22
    protected $database;
23
24
    /**
25
     * @var \PDO
26
     */
27
    protected $pdo;
28
29
    /**
30
     * Initializes the driver instance.
31
     *
32
     * @param \PDO   $pdo
33
     * @param string $database
34
     */
35 105
    public function __construct(\PDO $pdo, $database)
36
    {
37 105
        $this->database = $database;
38
39 105
        $pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
40
41 105
        $this->pdo = $pdo;
42 105
    }
43
44
    /**
45
     * Returns an array of Column instances from a table.
46
     *
47
     * @param  string $table
48
     * @return \Rougin\Describe\Column[]
49
     */
50 84
    public function columns($table)
51
    {
52 84
        return $this->query($table, 'DESCRIBE ' . $table);
53
    }
54
55
    /**
56
     * Returns an array of Column instances from a table.
57
     * NOTE: To be removed in v2.0.0. Use columns() instead.
58
     *
59
     * @param  string $table
60
     * @return \Rougin\Describe\Column[]
61
     */
62 48
    public function getColumns($table)
63
    {
64 48
        return $this->columns($table);
65
    }
66
67
    /**
68
     * Returns an array of Column instances from a table.
69
     * NOTE: To be removed in v2.0.0. Use getColumns() instead.
70
     *
71
     * @param  string $table
72
     * @return \Rougin\Describe\Column[]
73
     */
74 42
    public function getTable($table)
75
    {
76 42
        return $this->getColumns($table);
77
    }
78
79
    /**
80
     * Returns an array of table names.
81
     * NOTE: To be removed in v2.0.0. Use tables() instead.
82
     *
83
     * @return array
84
     */
85 6
    public function getTableNames()
86
    {
87 6
        return $this->items(false);
88
    }
89
90
    /**
91
     * Returns an array of table names.
92
     * NOTE: To be removed in v2.0.0. Use getTableNames() instead.
93
     *
94
     * @return array
95
     */
96 3
    public function showTables()
97
    {
98 3
        return $this->getTableNames();
99
    }
100
101
    /**
102
     * Returns an array of Table instances.
103
     *
104
     * @return \Rougin\Describe\Table[]
105
     */
106 12
    public function tables()
107
    {
108 12
        return $this->items(true);
109
    }
110
111
    /**
112
     * Prepares the defined columns.
113
     *
114
     * @param  \Rougin\Describe\Column $column
115
     * @param  string                  $table
116
     * @param  mixed                   $row
117
     * @return \Rougin\Describe\Column
118
     */
119 78
    protected function column(Column $column, $table, $row)
120
    {
121 78
        preg_match('/(.*?)\((.*?)\)/', $row->Type, $match);
122
123 78
        $column->setDataType($row->Type);
124
125 78
        $column->setDefaultValue($row->Default);
126
127 78
        $column->setField($row->Field);
128
129 78
        if (isset($match[1]) === true) {
130 78
            $column->setDataType($match[1]);
131
132 78
            $column->setLength($match[2]);
133 78
        }
134
135 78
        $column = $this->properties($row, $column);
136
137 78
        $column = $this->keys($row, $column);
138
139 78
        return $this->foreign($table, $row, $column);
140
    }
141
142
    /**
143
     * Sets the properties of a column if it does exists.
144
     *
145
     * @param  string                  $name
146
     * @param  mixed                   $row
147
     * @param  \Rougin\Describe\Column $column
148
     * @return \Rougin\Describe\Column
149
     */
150 78
    protected function foreign($name, $row, Column $column)
151
    {
152
        $query = 'SELECT COLUMN_NAME as "column", REFERENCED_COLUMN_NAME as "referenced_column",' .
153 78
            'CONCAT(REFERENCED_TABLE_SCHEMA, ".", REFERENCED_TABLE_NAME) as "referenced_table"' .
154 78
            'FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE ' .
155 78
            'WHERE CONSTRAINT_SCHEMA = "' . $this->database . '" AND TABLE_NAME = "' . $name . '";';
156
157 78
        $table = $this->pdo->prepare($query);
158
159 78
        $table->execute();
160
161 78
        $table->setFetchMode(\PDO::FETCH_OBJ);
162
163 78
        while ($item = $table->fetch()) {
164 78
            if ($item->column === $row->Field) {
165 78
                $referenced = $this->strip($item->referenced_table);
166
167 78
                $column->setReferencedField($item->referenced_column);
168
169 78
                $column->setReferencedTable($referenced);
170 78
            }
171 78
        }
172
173 78
        return $column;
174
    }
175
176
    /**
177
     * Returns an array of table names or Table instances.
178
     * NOTE: To be removed in v2.0.0. Move to tables() instead.
179
     *
180
     * @param  boolean $instance
181
     * @param  array   $tables
182
     * @return array|\Rougin\Describe\Table[]
183
     */
184 18
    protected function items($instance = false, $tables = array())
185
    {
186 18
        $information = $this->pdo->prepare('SHOW TABLES');
187
188 18
        $information->execute();
189
190 18
        while ($row = $information->fetch()) {
191
            // NOTE: To be removed in v2.0.0. Always return Table instance.
192 18
            $instance && $row[0] = new Table($row[0], $this);
193
194 18
            array_push($tables, $row[0]);
195 18
        }
196
197 18
        return $tables;
198
    }
199
200
    /**
201
     * Sets the key of a column.
202
     *
203
     * @param  mixed                   $row
204
     * @param  \Rougin\Describe\Column $column
205
     * @return \Rougin\Describe\Column
206
     */
207 78
    protected function keys($row, Column $column)
208
    {
209 78
        switch ($row->Key) {
210 78
            case 'PRI':
211 78
                $column->setPrimary(true);
212
213 78
                break;
214
            
215 78
            case 'MUL':
216 78
                $column->setForeign(true);
217
218 78
                break;
219
220 78
            case 'UNI':
221 78
                $column->setUnique(true);
222
223 78
                break;
224 78
        }
225
226 78
        return $column;
227
    }
228
229
    /**
230
     * Sets the properties of a column.
231
     *
232
     * @param  mixed                   $row
233
     * @param  \Rougin\Describe\Column $column
234
     * @return \Rougin\Describe\Column
235
     */
236 78
    protected function properties($row, Column $column)
237
    {
238 78
        $increment = $row->Extra === 'auto_increment';
239
240 78
        $column->setAutoIncrement($increment);
241
242 78
        $column->setNull($row->Null === 'YES');
243
244 78
        return $column;
245
    }
246
247
    /**
248
     * Strips the table schema from the table name.
249
     *
250
     * @param  string $table
251
     * @return string
252
     */
253 78
    protected function strip($table)
254
    {
255 78
        $exists = strpos($table, '.') !== false;
256
257 78
        $updated = substr($table, strpos($table, '.') + 1);
258
259 78
        return $exists ? $updated : $table;
260
    }
261
}
262