Completed
Pull Request — master (#4)
by Rougin
02:43
created

MySQLDriver::setForeignColumn()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 23
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 17
CRAP Score 3

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 23
ccs 17
cts 17
cp 1
rs 9.0856
cc 3
eloc 15
nc 3
nop 3
crap 3
1
<?php
2
3
namespace Rougin\Describe\Driver;
4
5
use Rougin\Describe\Column;
6
7
/**
8
 * MySQL Driver
9
 *
10
 * A database driver extension for MySQL.
11
 *
12
 * @package  Describe
13
 * @category Driver
14
 * @author   Rougin Royce Gutib <[email protected]>
15
 */
16
class MySQLDriver implements DriverInterface
17
{
18
    /**
19
     * @var array
20
     */
21
    protected $columns = [];
22
23
    /**
24
     * @var string
25
     */
26
    protected $database;
27
28
    /**
29
     * @var \PDO
30
     */
31
    protected $pdo;
32
33
    /**
34
     * @param PDO    $pdo
35
     * @param string $database
36
     */
37 60
    public function __construct(\PDO $pdo, $database)
38
    {
39 60
        $this->database = $database;
40 60
        $this->pdo = $pdo;
41 60
    }
42
43
    /**
44
     * Returns the result.
45
     *
46
     * @param  string $tableName
47
     * @return array
48
     */
49 51
    public function getTable($tableName)
50
    {
51 51
        $this->columns = [];
52
53
        try {
54 51
            $information = $this->pdo->prepare('DESCRIBE ' . $tableName);
55
56 51
            $information->execute();
57 51
            $information->setFetchMode(\PDO::FETCH_OBJ);
58 51
        } catch (\PDOException $e) {
59
            // Table not found
60
        }
61
62 51
        while ($row = $information->fetch()) {
63 48
            $this->setColumns($tableName, $row);
64 48
        }
65
66 51
        return $this->columns;
67
    }
68
69
    /**
70
     * Shows the list of tables.
71
     *
72
     * @return array
73
     */
74 9
    public function showTables()
75
    {
76 9
        $tables = [];
77
78 9
        $information = $this->pdo->prepare('SHOW TABLES');
79 9
        $information->execute();
80
81 9
        while ($row = $information->fetch()) {
82 9
            array_push($tables, $row[0]);
83 9
        }
84
85 9
        return $tables;
86
    }
87
88
    /**
89
     * Prepares the defined columns.
90
     *
91
     * @param  string $tableName
92
     * @param  mixed  $row
93
     * @return void
94
     */
95 48
    protected function setColumns($tableName, $row)
96
    {
97 48
        preg_match('/(.*?)\((.*?)\)/', $row->Type, $match);
98
99 48
        $column = new Column;
100
101 48
        $this->setProperties($row, $column);
102 48
        $this->setKey($row, $column);
103
104 48
        $column->setDataType($row->Type);
105 48
        $column->setDefaultValue($row->Default);
106 48
        $column->setField($row->Field);
107
108 48
        if (isset($match[1])) {
109 48
            $column->setDataType($match[1]);
110 48
            $column->setLength($match[2]);
111 48
        }
112
113 48
        $this->setForeignColumn($tableName, $row, $column);
114
115 48
        array_push($this->columns, $column);
116 48
    }
117
118
    /**
119
     * Sets the key of the specified column.
120
     *
121
     * @param  mixed                   $row
122
     * @param  \Rougin\Describe\Column &$column
123
     * @return void
124
     */
125 48
    protected function setKey($row, Column &$column)
126
    {
127 48
        switch ($row->Key) {
128 48
            case 'PRI':
129 48
                $column->setPrimary(true);
130
131 48
                break;
132
            
133 48
            case 'MUL':
134 48
                $column->setForeign(true);
135
136 48
                break;
137
138 48
            case 'UNI':
139 48
                $column->setUnique(true);
140
141 48
                break;
142 48
        }
143 48
    }
144
145
    /**
146
     * Sets the properties of the specified column if it does exists.
147
     *
148
     * @param  string                  $tableName
149
     * @param  mixed                   $row
150
     * @param  \Rougin\Describe\Column &$column
151
     * @return void
152
     */
153 48
    protected function setForeignColumn($tableName, $row, Column &$column)
154
    {
155
        $query = 'SELECT COLUMN_NAME as "column",' .
156 48
            'REFERENCED_COLUMN_NAME as "referenced_column",' .
157 48
            'CONCAT(REFERENCED_TABLE_SCHEMA, ".", REFERENCED_TABLE_NAME) as "referenced_table"' .
158 48
            'FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE ' .
159 48
            'WHERE CONSTRAINT_SCHEMA = "' . $this->database . '" ' .
160 48
            'AND TABLE_NAME = "' . $tableName . '";';
161
162 48
        $foreignTable = $this->pdo->prepare($query);
163
164 48
        $foreignTable->execute();
165 48
        $foreignTable->setFetchMode(\PDO::FETCH_OBJ);
166
167 48
        while ($foreignRow = $foreignTable->fetch()) {
168 45
            if ($foreignRow->column == $row->Field) {
169 45
                $referencedTable = $this->stripTableSchema($foreignRow->referenced_table);
170
171 45
                $column->setReferencedField($foreignRow->referenced_column);
172 45
                $column->setReferencedTable($referencedTable);
173 45
            }
174 45
        }
175 48
    }
176
177
    /**
178
     * Sets the properties of the specified column.
179
     *
180
     * @param  mixed                   $row
181
     * @param  \Rougin\Describe\Column &$column
182
     * @return void
183
     */
184 48
    protected function setProperties($row, Column &$column)
185
    {
186 48
        $null = 'Null';
187
188 48
        if ($row->Extra == 'auto_increment') {
189 48
            $column->setAutoIncrement(true);
190 48
        }
191
192 48
        if ($row->$null == 'YES') {
193 48
            $column->setNull(true);
194 48
        }
195 48
    }
196
197
    /**
198
     * Strips the table schema from the table name.
199
     *
200
     * @param  string $table
201
     * @return string
202
     */
203 45
    protected function stripTableSchema($table)
204
    {
205 45
        return (strpos($table, '.') !== false) ? substr($table, strpos($table, '.') + 1) : $table;
206
    }
207
}
208