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";
}