Skip to content

Commit dd1125b

Browse files
committed
mysqli WIP
1 parent f108c2f commit dd1125b

4 files changed

Lines changed: 884 additions & 0 deletions

File tree

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
<?php
2+
3+
/**
4+
* This file is part of the Dibi, smart database abstraction layer (https://dibiphp.com)
5+
* Copyright (c) 2005 David Grudl (https://davidgrudl.com)
6+
*/
7+
8+
declare(strict_types=1);
9+
10+
namespace Dibi\Drivers;
11+
12+
use Dibi;
13+
14+
15+
/**
16+
* The reflector for MySQL databases.
17+
* @internal
18+
*/
19+
class MySqlReflector implements Dibi\Reflector
20+
{
21+
use Dibi\Strict;
22+
23+
private Dibi\Driver $driver;
24+
25+
26+
public function __construct(Dibi\Driver $driver)
27+
{
28+
$this->driver = $driver;
29+
}
30+
31+
32+
/**
33+
* Returns list of tables.
34+
*/
35+
public function getTables(): array
36+
{
37+
$res = $this->driver->query('SHOW FULL TABLES');
38+
$tables = [];
39+
while ($row = $res->fetch(false)) {
40+
$tables[] = [
41+
'name' => $row[0],
42+
'view' => isset($row[1]) && $row[1] === 'VIEW',
43+
];
44+
}
45+
return $tables;
46+
}
47+
48+
49+
/**
50+
* Returns metadata for all columns in a table.
51+
*/
52+
public function getColumns(string $table): array
53+
{
54+
$res = $this->driver->query("SHOW FULL COLUMNS FROM {$this->driver->escapeIdentifier($table)}");
55+
$columns = [];
56+
while ($row = $res->fetch(true)) {
57+
$type = explode('(', $row['Type']);
58+
$columns[] = [
59+
'name' => $row['Field'],
60+
'table' => $table,
61+
'nativetype' => strtoupper($type[0]),
62+
'size' => isset($type[1]) ? (int) $type[1] : null,
63+
'nullable' => $row['Null'] === 'YES',
64+
'default' => $row['Default'],
65+
'autoincrement' => $row['Extra'] === 'auto_increment',
66+
'vendor' => $row,
67+
];
68+
}
69+
return $columns;
70+
}
71+
72+
73+
/**
74+
* Returns metadata for all indexes in a table.
75+
*/
76+
public function getIndexes(string $table): array
77+
{
78+
$res = $this->driver->query("SHOW INDEX FROM {$this->driver->escapeIdentifier($table)}");
79+
$indexes = [];
80+
while ($row = $res->fetch(true)) {
81+
$indexes[$row['Key_name']]['name'] = $row['Key_name'];
82+
$indexes[$row['Key_name']]['unique'] = !$row['Non_unique'];
83+
$indexes[$row['Key_name']]['primary'] = $row['Key_name'] === 'PRIMARY';
84+
$indexes[$row['Key_name']]['columns'][$row['Seq_in_index'] - 1] = $row['Column_name'];
85+
}
86+
return array_values($indexes);
87+
}
88+
89+
90+
/**
91+
* Returns metadata for all foreign keys in a table.
92+
* @throws Dibi\NotSupportedException
93+
*/
94+
public function getForeignKeys(string $table): array
95+
{
96+
$data = $this->driver->query("SELECT `ENGINE` FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = {$this->driver->escapeText($table)}")->fetch(true);
97+
if ($data['ENGINE'] !== 'InnoDB') {
98+
throw new Dibi\NotSupportedException("Foreign keys are not supported in {$data['ENGINE']} tables.");
99+
}
100+
101+
$res = $this->driver->query("
102+
SELECT rc.CONSTRAINT_NAME, rc.UPDATE_RULE, rc.DELETE_RULE, kcu.REFERENCED_TABLE_NAME,
103+
GROUP_CONCAT(kcu.REFERENCED_COLUMN_NAME ORDER BY kcu.ORDINAL_POSITION) AS REFERENCED_COLUMNS,
104+
GROUP_CONCAT(kcu.COLUMN_NAME ORDER BY kcu.ORDINAL_POSITION) AS COLUMNS
105+
FROM information_schema.REFERENTIAL_CONSTRAINTS rc
106+
INNER JOIN information_schema.KEY_COLUMN_USAGE kcu ON
107+
kcu.CONSTRAINT_NAME = rc.CONSTRAINT_NAME
108+
AND kcu.CONSTRAINT_SCHEMA = rc.CONSTRAINT_SCHEMA
109+
WHERE rc.CONSTRAINT_SCHEMA = DATABASE()
110+
AND rc.TABLE_NAME = {$this->driver->escapeText($table)}
111+
GROUP BY rc.CONSTRAINT_NAME
112+
");
113+
114+
$foreignKeys = [];
115+
while ($row = $res->fetch(true)) {
116+
$keyName = $row['CONSTRAINT_NAME'];
117+
118+
$foreignKeys[$keyName]['name'] = $keyName;
119+
$foreignKeys[$keyName]['local'] = explode(',', $row['COLUMNS']);
120+
$foreignKeys[$keyName]['table'] = $row['REFERENCED_TABLE_NAME'];
121+
$foreignKeys[$keyName]['foreign'] = explode(',', $row['REFERENCED_COLUMNS']);
122+
$foreignKeys[$keyName]['onDelete'] = $row['DELETE_RULE'];
123+
$foreignKeys[$keyName]['onUpdate'] = $row['UPDATE_RULE'];
124+
}
125+
return array_values($foreignKeys);
126+
}
127+
}

0 commit comments

Comments
 (0)