Драйвери за бази данни
merql отделя преноса на връзката от диалекта на базата данни. Адаптер DatabaseConnection изпълнява SQL чрез PDO или mysqli, а Driver обработва специфичните за системата за бази данни метаданни SQL и ограждането на идентификатори с кавички. Има вградени драйвери за MySQL и SQLite.
use Merql\Driver\DriverFactory;
$driver = DriverFactory::create($connection);
// Auto-detects MySQL or SQLite from the connection driver identity.
Интерфейсът Driver
Всеки драйвер реализира пет метода:
use Merql\Driver\Driver;
interface Driver
{
public function quoteIdentifier(string $name): string;
public function listTables(DatabaseConnection $connection): array;
public function readSchema(DatabaseConnection $connection, string $table): TableSchema;
public function readForeignKeys(DatabaseConnection $connection): array;
public function selectAll(string $table): string;
}
| Метод | Предназначение |
|---|---|
quoteIdentifier |
Огражда име на таблица или колона с кавички за използване в SQL. |
listTables |
Връща всички потребителски таблици в текущата база данни. |
readSchema |
Чете имената и типовете на колоните, първичния ключ и уникалните ключове за таблица. |
readForeignKeys |
Връща съпоставяне на дъщерни таблици към родителски таблици. |
selectAll |
Създава заявка SELECT * за таблица. |
MysqlDriver
Използва заявки INFORMATION_SCHEMA за метаданни и ограждане на идентификатори с обратни апострофи.
use Merql\Driver\MysqlDriver;
$driver = new MysqlDriver();
$driver->quoteIdentifier('posts');
// `posts`
$driver->quoteIdentifier('my`table');
// `my``table`
$tables = $driver->listTables($connection);
// ['comments', 'posts', 'users']
$schema = $driver->readSchema($connection, 'posts');
// TableSchema with columns, primaryKey, uniqueKeys
$fks = $driver->readForeignKeys($connection);
// ['comments' => ['posts', 'users']]
Заявките за изброяване на таблици избират INFORMATION_SCHEMA.TABLES, филтриран по текущата база данни и тип BASE TABLE. Заявките за четене на схемата избират INFORMATION_SCHEMA.COLUMNS за колоните и INFORMATION_SCHEMA.KEY_COLUMN_USAGE за първичните и уникалните ключове.
SqliteDriver
Използва заявки PRAGMA за метаданни и ограждане на идентификатори с двойни кавички.
use Merql\Driver\SqliteDriver;
$driver = new SqliteDriver();
$driver->quoteIdentifier('posts');
// "posts"
$driver->quoteIdentifier('my"table');
// "my""table"
$tables = $driver->listTables($connection);
// Queries sqlite_master, excludes sqlite_* internal tables.
$schema = $driver->readSchema($connection, 'posts');
// Uses PRAGMA table_info() and PRAGMA index_list().
$fks = $driver->readForeignKeys($connection);
// Uses PRAGMA foreign_key_list() for each table.
DriverFactory
DriverFactory открива автоматично правилния драйвер от DatabaseConnection::driverName().
use Merql\Connection;
use Merql\Driver\DriverFactory;
$connection = Connection::mysql('127.0.0.1', 'mydb', 'root', '');
$driver = DriverFactory::create($connection);
// Returns MysqlDriver
$connection = Connection::sqlite(':memory:');
$driver = DriverFactory::create($connection);
// Returns SqliteDriver
Ако идентификаторът на драйвера на връзката не е разпознат, се хвърля RuntimeException със съобщение Unsupported database driver: <name>. merql не включва драйвер PostgreSQL.
Регистриране на персонализирани драйвери
За бази данни извън MySQL и SQLite напишете клас, който реализира Driver, и го регистрирайте. PostgresDriver по-долу обозначава вашия собствен клас:
use Merql\Driver\DriverFactory;
DriverFactory::register('pgsql', PostgresDriver::class);
$connection = Connection::fromDsn('pgsql:host=localhost;dbname=mydb', 'user', 'pass');
$driver = DriverFactory::create($connection);
// Returns your PostgresDriver instance.
Класът на драйвера трябва да реализира интерфейса Driver. Първият аргумент на register() е идентификаторът на драйвера на връзката.
Нулиране
За тестване нулирайте фабриката до състоянието ѝ по подразбиране:
DriverFactory::reset();
// Reverts to only MySQL and SQLite drivers.
Помощен клас за връзки
Класът Connection създава адаптери с подходящи настройки по подразбиране. Адаптерите PDO използват изключения при грешка, асоциативен режим на извличане, истински подготвени заявки и връщане на извлечените стойности като низове. Адаптерът mysqli задава utf8mb4, използва режим на изключенията на mysqli и подготвени заявки, а извлечените стойности нормализира до същия формат низ или null.
use Merql\Connection;
// MySQL.
$connection = Connection::mysql('127.0.0.1', 'my_database', 'root', 'password');
$connection = Connection::mysql('db.example.com', 'mydb', 'user', 'pass', port: 3307);
// MySQLi.
$connection = Connection::mysqli('127.0.0.1', 'my_database', 'root', 'password');
// SQLite.
$connection = Connection::sqlite(':memory:');
$connection = Connection::sqlite('/var/data/app.sqlite');
// Any MySQL or SQLite PDO DSN.
$connection = Connection::fromDsn('mysql:host=127.0.0.1;dbname=mydb;charset=utf8mb4', 'user', 'pass');
fromDsn() приема всеки DSN, който PDO може да отвори, но merql може да създава моментни снимки и да прилага промени само чрез регистриран драйвер. Връзка pgsql: се отваря (ако е инсталиран pdo_pgsql), но конструкторите Merql::init(), Snapshotter, Applier и GuardedApplier извикват DriverFactory::create(), който хвърля RuntimeException: Unsupported database driver: pgsql, освен ако не сте регистрирали драйвер за нея или не подадете такъв.
Connection::sqlite() също активира автоматично PRAGMA foreign_keys = ON, което SQLite изисква за налагане на външни ключове.
Къде се използват драйверите
Драйверите се използват в цялата система merql:
- Създателят на моментни снимки използва
listTables,readSchemaиselectAll, за да заснеме състоянието на базата данни. - Прилагащият механизъм използва
readForeignKeys, за да определи реда на операциите, и подава драйвера наSqlGeneratorза ограждане на идентификаторите с кавички. - Генераторът на SQL използва
quoteIdentifier, за да създава безопасни SQL.
Ако подадете връзка на Snapshotter или Applier, без да зададете драйвер, автоматично се извиква DriverFactory::create().