Reflexe
Nette Database предоставляет инструменты для интроспекции структуры базы данных с помощью класса Nette\Database\Reflection\Reflection. Это позволяет получать информацию о таблицах, столбцах, индексах и внешних ключах. Отражение можно использовать для генерации схем, создания гибких приложений, управляемых базами данных, или общих инструментов работы с базами данных.
Объект отражения можно получить из экземпляра соединения с базой данных:
$reflection = $connection->getReflection();
Работа с таблицами
Используя отражение, мы можем просматривать все таблицы в базе данных:
getTables(): Nette\Database\Reflection\Table[]
Возвращает ассоциативный массив, где ключом является имя таблицы, а значением – массив метаданных таблицы.
// Перечисление имен всех таблиц
foreach ($reflection->getTables() as $table) {
echo $table['name'] . "\n";
}
hasTable(string $name): bool
Возвращает true
, если таблица существует, иначе false
.
// Проверка существования таблицы
if ($reflection->hasTable('users')) {
echo "The 'users' table exists";
}
getTable(string $name): Nette\Database\Reflection\Table
Возвращает объект Nette\Database\Reflection\Table
, представляющий заданную
таблицу. Если таблица не существует, выбрасывается исключение
Nette\Database\Exception\MissingTableException
.
// Получение определенной таблицы
$table = $reflection->getTable('users');
Информация о колоннах
Объект Nette\Database\Reflection\Table,
получаемый при вызове getTable()
, позволяет получить подробную
информацию о столбцах таблицы.
getColumns(): Nette\Database\Reflection\Column[]
Возвращает массив объектов Nette\Database\Reflection\Column
, представляющих
столбцы таблицы.
getColumn(string $name): Nette\Database\Reflection\Column
Возвращает объект Nette\Database\Reflection\Column,
представляющий заданный столбец. Если столбец не существует,
выбрасывается исключение Nette\Database\Exception\MissingColumnException
.
Объект Column
предоставляет следующие свойства:
name
: Имя столбца.nativeType
: Тип данных столбца, специфичный для базы данных.type
: нормализованный тип данных столбца (см. константыNette\Utils\Type
).nullable
:true
, если столбец может содержатьNULL
, в противном случаеfalse
.primary
:true
если столбец является частью первичного ключа, иначеfalse
.autoIncrement
:true
если столбец является автоинкрементным, иначеfalse
.default
: Значение столбца по умолчанию, илиnull
, если он не определен.vendor
: Массив с дополнительной информацией, специфичной для базы данных.
// Итерация по всем столбцам таблицы 'users'
$table = $reflection->getTable('users');
foreach ($table->getColumns() as $column) {
echo "Column: " . $column->name . "\n";
echo "Type: " . $column->nativeType . "\n";
echo "Allows NULL: " . ($column->nullable ? 'Yes': 'No') . "\n";
echo "Default value: " . ($column->default ?? 'None') . "\n";
echo "Is primary key: " . ($column->primary ? 'Yes': 'No') . "\n";
echo "Is auto-increment: " . ($column->autoIncrement ? 'Yes': 'No') . "\n";
}
// Получение определенного столбца
$idColumn = $table->getColumn('id');
Индексы и первичные ключи
getIndexes(): Nette\Database\Reflection\Index[]
Возвращает массив объектов Nette\Database\Reflection\Index
, представляющих
индексы таблиц.
getIndex(string $name): Nette\Database\Reflection\Index
Возвращает объект Nette\Database\Reflection\Index,
представляющий заданный индекс. Если индекс не существует,
выбрасывается исключение Nette\Database\Exception\MissingIndexException
.
getPrimaryKey(): ?Nette\Database\Reflection\Index
Возвращает объект Nette\Database\Reflection\Index
, представляющий первичный
ключ таблицы, или null
, если таблица не имеет первичного ключа.
Объект Index
предоставляет следующие свойства:
name
: Имя индекса.columns
: Массив объектовNette\Database\Reflection\Column
, представляющих столбцы, которые являются частью индекса.unique
:true
если индекс уникален, иначеfalse
.primary
:true
если индекс является первичным ключом, иначеfalse
.
$table = $reflection->getTable('users');
$printColumnNames = fn(array $columns) => implode(', ', array_map(fn($col) => $col->name, $columns));
// Перечисление всех индексов
foreach ($table->getIndexes() as $index) {
echo "Index: " . ($index->name ?? 'Unnamed') . "\n";
echo "Columns: " . $printColumnNames($index->columns) . "\n";
echo "Is unique: " . ($index->unique ? 'Yes': 'No') . "\n";
echo "Is primary key: " . ($index->primary ? 'Yes': 'No') . "\n";
}
// Получение первичного ключа
if ($primaryKey = $table->getPrimaryKey()) {
echo "Primary key: " . $printColumnNames($primaryKey->columns) . "\n";
}
Иностранные ключи
getForeignKeys(): Nette\Database\Reflection\ForeignKey[]
Возвращает массив объектов Nette\Database\Reflection\ForeignKey
,
представляющих внешние ключи таблицы.
getForeignKey(string $name): Nette\Database\Reflection\ForeignKey
Возвращает объект Nette\Database\Reflection\ForeignKey,
представляющий заданный внешний ключ. Если внешний ключ не существует,
выбрасывается исключение Nette\Database\Exception\MissingForeignKeyException
.
Объект ForeignKey
предоставляет следующие свойства:
name
: Имя внешнего ключа.localColumns
: Массив объектовNette\Database\Reflection\Column
, представляющих локальные столбцы, которые составляют внешний ключ.foreignTable
: ОбъектNette\Database\Reflection\Table
, представляющий внешнюю таблицу, на которую ссылается внешний ключ.foreignColumns
: Массив объектовNette\Database\Reflection\Column
, представляющих иностранные столбцы, на которые ссылается внешний ключ.
$table = $reflection->getTable('books');
$printColumnNames = fn(array $columns) => implode(', ', array_map(fn($col) => $col->name, $columns));
foreach ($table->getForeignKeys() as $fk) {
echo "Foreign key: " . ($fk->name ?? 'Unnamed') . "\n";
echo "Local columns: " . $printColumnNames($fk->localColumns) . "\n";
echo "References table: {$fk->foreignTable->name}\n";
echo "References columns: " . $printColumnNames($fk->foreignColumns) . "\n";
}