Completed
Push — master ( 99696f...35c3f5 )
by Rougin
02:37
created

MySQLDriver::columns()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

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