Completed
Pull Request — master (#4)
by Rougin
02:19
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 View Code Duplication
    public function getTable($tableName)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
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->setColumn($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 setColumn($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