Skip to content

Commit e71ac3b

Browse files
committed
drivers: refactored reflection output (metadata arrays)
- unified FK row shape: explicit associative literals, (string) normalization - MsSqlDriver: simplified getIndexes SQL, getForeignKeys no longer indexes by synthetic id - MySqlDriver: ksort+array_values on composite index columns - SqliteDriver: parameterized PRAGMA table_info/index_list/index_info/foreign_key_list via ?name - SqliteDriver: getForeignKeys exposes PRAGMA id as synthetic name (enables grouping of composite FKs) - ForeignKey::$name is now non-nullable string
1 parent eb17157 commit e71ac3b

9 files changed

Lines changed: 148 additions & 97 deletions

File tree

src/Database/Drivers/MsSqlDriver.php

Lines changed: 30 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -105,9 +105,9 @@ public function getTables(): array
105105

106106
while ($row = $rows->fetch()) {
107107
$tables[] = [
108-
'name' => $row['TABLE_SCHEMA'] . '.' . $row['TABLE_NAME'],
108+
'name' => (string) $row['TABLE_SCHEMA'] . '.' . (string) $row['TABLE_NAME'],
109109
'view' => ($row['TABLE_TYPE'] ?? null) === 'VIEW',
110-
'comment' => $row['comment'] ?? '',
110+
'comment' => (string) ($row['comment'] ?? ''),
111111
];
112112
}
113113

@@ -168,28 +168,30 @@ public function getIndexes(string $table): array
168168

169169
$rows = $this->connection->query(<<<'X'
170170
SELECT
171-
name_index = ind.name,
172-
id_column = ic.index_column_id,
173-
name_column = col.name,
174-
ind.is_unique,
175-
ind.is_primary_key
171+
ind.name AS name,
172+
col.name AS [column],
173+
ind.is_unique,
174+
ind.is_primary_key
176175
FROM
177176
sys.indexes ind
178-
INNER JOIN sys.index_columns ic ON ind.object_id = ic.object_id and ind.index_id = ic.index_id
179-
INNER JOIN sys.columns col ON ic.object_id = col.object_id and ic.column_id = col.column_id
177+
INNER JOIN sys.index_columns ic ON ind.object_id = ic.object_id AND ind.index_id = ic.index_id
178+
INNER JOIN sys.columns col ON ic.object_id = col.object_id AND ic.column_id = col.column_id
180179
INNER JOIN sys.tables t ON ind.object_id = t.object_id
181180
WHERE
182-
t.name = ?
181+
t.name = ?
183182
ORDER BY
184-
t.name, ind.name, ind.index_id, ic.index_column_id
183+
ind.name, ic.index_column_id
185184
X, $table_name);
186185

187186
while ($row = $rows->fetch()) {
188-
$id = $row['name_index'];
189-
$indexes[$id]['name'] = $id;
190-
$indexes[$id]['unique'] = $row['is_unique'] !== 'False';
191-
$indexes[$id]['primary'] = $row['is_primary_key'] !== 'False';
192-
$indexes[$id]['columns'][$row['id_column'] - 1] = $row['name_column'];
187+
$id = (string) $row['name'];
188+
$indexes[$id] ??= [
189+
'name' => $id,
190+
'unique' => $row['is_unique'] !== 'False',
191+
'primary' => $row['is_primary_key'] !== 'False',
192+
'columns' => [],
193+
];
194+
$indexes[$id]['columns'][] = (string) $row['column'];
193195
}
194196

195197
return array_values($indexes);
@@ -203,10 +205,10 @@ public function getForeignKeys(string $table): array
203205

204206
$rows = $this->connection->query(<<<'X'
205207
SELECT
206-
obj.name AS [fk_name],
207-
col1.name AS [column],
208-
tab2.name AS [referenced_table],
209-
col2.name AS [referenced_column]
208+
obj.name AS name,
209+
col1.name AS local,
210+
tab2.name AS [table],
211+
col2.name AS [foreign]
210212
FROM
211213
sys.foreign_key_columns fkc
212214
INNER JOIN sys.objects obj
@@ -220,20 +222,21 @@ public function getForeignKeys(string $table): array
220222
INNER JOIN sys.tables tab2
221223
ON tab2.object_id = fkc.referenced_object_id
222224
INNER JOIN sys.columns col2
223-
ON col2.column_id = referenced_column_id AND col2.object_id = tab2.object_id
225+
ON col2.column_id = referenced_column_id AND col2.object_id = tab2.object_id
224226
WHERE
225227
tab1.name = ?
226228
X, $table_name);
227229

228-
$id = 0;
229230
while ($row = $rows->fetch()) {
230-
$keys[$id]['name'] = $row['fk_name'];
231-
$keys[$id]['local'] = $row['column'];
232-
$keys[$id]['table'] = $table_schema . '.' . $row['referenced_table'];
233-
$keys[$id++]['foreign'] = $row['referenced_column'];
231+
$keys[] = [
232+
'name' => (string) $row['name'],
233+
'local' => (string) $row['local'],
234+
'table' => $table_schema . '.' . $row['table'],
235+
'foreign' => (string) $row['foreign'],
236+
];
234237
}
235238

236-
return array_values($keys);
239+
return $keys;
237240
}
238241

239242

src/Database/Drivers/MySqlDriver.php

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -135,9 +135,9 @@ public function getTables(): array
135135

136136
while ($row = $query->fetch()) {
137137
$tables[] = [
138-
'name' => $row['TABLE_NAME'],
138+
'name' => (string) $row['TABLE_NAME'],
139139
'view' => $row['TABLE_TYPE'] === 'VIEW',
140-
'comment' => $row['TABLE_COMMENT'],
140+
'comment' => (string) $row['TABLE_COMMENT'],
141141
];
142142
}
143143

@@ -148,14 +148,14 @@ public function getTables(): array
148148
public function getColumns(string $table): array
149149
{
150150
$columns = [];
151-
$rows = $this->connection->query('SHOW FULL COLUMNS FROM ' . $this->delimite($table));
151+
$rows = $this->connection->query('SHOW FULL COLUMNS FROM ?name', $table);
152152
while ($row = $rows->fetch()) {
153153
$row = array_change_key_case((array) $row);
154154
$typeInfo = Nette\Database\Helpers::parseColumnType($row['type']);
155155
$columns[] = [
156156
'name' => $row['field'],
157157
'table' => $table,
158-
'nativetype' => strtoupper($typeInfo['type']),
158+
'nativetype' => strtoupper($typeInfo['type'] ?? ''),
159159
'size' => $typeInfo['length'],
160160
'nullable' => $row['null'] === 'YES',
161161
'default' => $row['default'],
@@ -173,13 +173,21 @@ public function getColumns(string $table): array
173173
public function getIndexes(string $table): array
174174
{
175175
$indexes = [];
176-
$rows = $this->connection->query('SHOW INDEX FROM ' . $this->delimite($table));
176+
$rows = $this->connection->query('SHOW INDEX FROM ?name', $table);
177177
while ($row = $rows->fetch()) {
178-
$id = $row['Key_name'];
179-
$indexes[$id]['name'] = $id;
180-
$indexes[$id]['unique'] = !$row['Non_unique'];
181-
$indexes[$id]['primary'] = $row['Key_name'] === 'PRIMARY';
182-
$indexes[$id]['columns'][$row['Seq_in_index'] - 1] = $row['Column_name'];
178+
$id = (string) $row['Key_name'];
179+
$indexes[$id] ??= [
180+
'name' => $id,
181+
'unique' => !$row['Non_unique'],
182+
'primary' => $id === 'PRIMARY',
183+
'columns' => [],
184+
];
185+
$indexes[$id]['columns'][(int) $row['Seq_in_index'] - 1] = (string) $row['Column_name'];
186+
}
187+
188+
foreach ($indexes as &$index) {
189+
ksort($index['columns']);
190+
$index['columns'] = array_values($index['columns']);
183191
}
184192

185193
return array_values($indexes);
@@ -197,15 +205,16 @@ public function getForeignKeys(string $table): array
197205
AND TABLE_NAME = ?
198206
X, $table);
199207

200-
$id = 0;
201208
while ($row = $rows->fetch()) {
202-
$keys[$id]['name'] = $row['CONSTRAINT_NAME'];
203-
$keys[$id]['local'] = $row['COLUMN_NAME'];
204-
$keys[$id]['table'] = $row['REFERENCED_TABLE_NAME'];
205-
$keys[$id++]['foreign'] = $row['REFERENCED_COLUMN_NAME'];
209+
$keys[] = [
210+
'name' => (string) $row['CONSTRAINT_NAME'],
211+
'local' => (string) $row['COLUMN_NAME'],
212+
'table' => (string) $row['REFERENCED_TABLE_NAME'],
213+
'foreign' => (string) $row['REFERENCED_COLUMN_NAME'],
214+
];
206215
}
207216

208-
return array_values($keys);
217+
return $keys;
209218
}
210219

211220

src/Database/Drivers/OciDriver.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ public function getTables(): array
106106
while ($row = $rows->fetch()) {
107107
if ($row[1] === 'TABLE' || $row[1] === 'VIEW') {
108108
$tables[] = [
109-
'name' => $row[0],
109+
'name' => (string) $row[0],
110110
'view' => $row[1] === 'VIEW',
111111
'comment' => null,
112112
];

src/Database/Drivers/PgSqlDriver.php

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,12 @@ public function getTables(): array
126126
X);
127127

128128
while ($row = $rows->fetch()) {
129-
$tables[] = (array) $row;
129+
$tables[] = [
130+
'name' => (string) $row['name'],
131+
'view' => (bool) $row['view'],
132+
'fullName' => (string) $row['fullName'],
133+
'comment' => (string) $row['comment'],
134+
];
130135
}
131136

132137
return $tables;
@@ -171,11 +176,19 @@ public function getColumns(string $table): array
171176
X, $this->delimiteFQN($table));
172177

173178
while ($row = $rows->fetch()) {
174-
$column = (array) $row;
175-
$column['vendor'] = $column;
176-
unset($column['sequence']);
177-
178-
$columns[] = $column;
179+
$vendor = (array) $row;
180+
$columns[] = [
181+
'name' => (string) $row['name'],
182+
'table' => (string) $row['table'],
183+
'nativetype' => (string) $row['nativetype'],
184+
'size' => $row['size'] !== null ? (int) $row['size'] : null,
185+
'nullable' => (bool) $row['nullable'],
186+
'default' => $row['default'],
187+
'autoincrement' => (bool) $row['autoincrement'],
188+
'primary' => (bool) $row['primary'],
189+
'comment' => (string) $row['comment'],
190+
'vendor' => $vendor,
191+
];
179192
}
180193

181194
return $columns;
@@ -202,11 +215,14 @@ public function getIndexes(string $table): array
202215
X, $this->delimiteFQN($table));
203216

204217
while ($row = $rows->fetch()) {
205-
$id = $row['name'];
206-
$indexes[$id]['name'] = $id;
207-
$indexes[$id]['unique'] = $row['unique'];
208-
$indexes[$id]['primary'] = $row['primary'];
209-
$indexes[$id]['columns'][] = $row['column'];
218+
$id = (string) $row['name'];
219+
$indexes[$id] ??= [
220+
'name' => $id,
221+
'unique' => (bool) $row['unique'],
222+
'primary' => (bool) $row['primary'],
223+
'columns' => [],
224+
];
225+
$indexes[$id]['columns'][] = (string) $row['column'];
210226
}
211227

212228
return array_values($indexes);
@@ -237,8 +253,14 @@ public function getForeignKeys(string $table): array
237253
X, $this->delimiteFQN($table));
238254

239255
while ($row = $rows->fetch()) {
240-
$keys[] = (array) $row;
256+
$keys[] = [
257+
'name' => (string) $row['name'],
258+
'local' => (string) $row['local'],
259+
'table' => (string) $row['table'],
260+
'foreign' => (string) $row['foreign'],
261+
];
241262
}
263+
242264
return $keys;
243265
}
244266

src/Database/Drivers/SqliteDriver.php

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ public function getTables(): array
124124

125125
while ($row = $rows->fetch()) {
126126
$tables[] = [
127-
'name' => $row['name'],
127+
'name' => (string) $row['name'],
128128
'view' => (bool) $row['view'],
129129
'comment' => null,
130130
];
@@ -147,7 +147,7 @@ public function getColumns(string $table): array
147147
X, $table, $table)->fetch();
148148

149149
$columns = [];
150-
$rows = $this->connection->query("PRAGMA table_info({$this->delimite($table)})");
150+
$rows = $this->connection->query('PRAGMA table_info(?name)', $table);
151151
while ($row = $rows->fetch()) {
152152
$column = $row['name'];
153153
$pattern = "/(\"$column\"|`$column`|\\[$column\\]|$column)\\s+[^,]+\\s+PRIMARY\\s+KEY\\s+AUTOINCREMENT/Ui";
@@ -173,18 +173,21 @@ public function getColumns(string $table): array
173173
public function getIndexes(string $table): array
174174
{
175175
$indexes = [];
176-
$rows = $this->connection->query("PRAGMA index_list({$this->delimite($table)})");
176+
$rows = $this->connection->query('PRAGMA index_list(?name)', $table);
177177
while ($row = $rows->fetch()) {
178-
$id = $row['name'];
179-
$indexes[$id]['name'] = $id;
180-
$indexes[$id]['unique'] = (bool) $row['unique'];
181-
$indexes[$id]['primary'] = false;
178+
$id = (string) $row['name'];
179+
$indexes[$id] = [
180+
'name' => $id,
181+
'unique' => (bool) $row['unique'],
182+
'primary' => false,
183+
'columns' => [],
184+
];
182185
}
183186

184187
foreach ($indexes as $index => $values) {
185-
$res = $this->connection->query("PRAGMA index_info({$this->delimite($index)})");
188+
$res = $this->connection->query('PRAGMA index_info(?name)', $index);
186189
while ($row = $res->fetch()) {
187-
$indexes[$index]['columns'][] = $row['name'];
190+
$indexes[$index]['columns'][] = (string) $row['name'];
188191
}
189192
}
190193

@@ -220,16 +223,17 @@ public function getIndexes(string $table): array
220223
public function getForeignKeys(string $table): array
221224
{
222225
$keys = [];
223-
$rows = $this->connection->query("PRAGMA foreign_key_list({$this->delimite($table)})");
226+
$rows = $this->connection->query('PRAGMA foreign_key_list(?name)', $table);
224227
while ($row = $rows->fetch()) {
225-
$id = $row['id'];
226-
$keys[$id]['name'] = $id;
227-
$keys[$id]['local'] = $row['from'];
228-
$keys[$id]['table'] = $row['table'];
229-
$keys[$id]['foreign'] = $row['to'];
228+
$keys[] = [
229+
'name' => (string) $row['id'], // SQLite does not expose FK names via PRAGMA, synthetic id is used
230+
'local' => (string) $row['from'],
231+
'table' => (string) $row['table'],
232+
'foreign' => (string) $row['to'],
233+
];
230234
}
231235

232-
return array_values($keys);
236+
return $keys;
233237
}
234238

235239

0 commit comments

Comments
 (0)