Sterowniki baz danych
merql oddziela transport połączenia od dialektu bazy danych. Adapter DatabaseConnection wykonuje SQL przez PDO lub mysqli, a Driver obsługuje metadane specyficzne dla silnika bazy danych SQL oraz cytowanie identyfikatorów. Wbudowane sterowniki są dostępne dla MySQL i SQLite.
use Merql\Driver\DriverFactory;
$driver = DriverFactory::create($connection);
// Auto-detects MySQL or SQLite from the connection driver identity.
Interfejs Driver
Każdy sterownik implementuje pięć metod:
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;
}
| Metoda | Zastosowanie |
|---|---|
quoteIdentifier |
Cytuje nazwę tabeli lub kolumny do użycia w SQL. |
listTables |
Zwraca wszystkie tabele użytkownika w bieżącej bazie danych. |
readSchema |
Odczytuje nazwy i typy kolumn, klucz główny oraz klucze unikatowe tabeli. |
readForeignKeys |
Zwraca mapę zależności tabel podrzędnych od tabel nadrzędnych. |
selectAll |
Buduje zapytanie SELECT * dla tabeli. |
MysqlDriver
Używa zapytań INFORMATION_SCHEMA do pobierania metadanych i znaków odwrotnego apostrofu do cytowania identyfikatorów.
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']]
Zapytania o listę tabel pobierają INFORMATION_SCHEMA.TABLES, filtrując według bieżącej bazy danych i typu BASE TABLE. Zapytania o schemat pobierają INFORMATION_SCHEMA.COLUMNS dla kolumn oraz INFORMATION_SCHEMA.KEY_COLUMN_USAGE dla kluczy głównych i unikatowych.
SqliteDriver
Używa zapytań PRAGMA do pobierania metadanych i podwójnych cudzysłowów do cytowania identyfikatorów.
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 automatycznie wykrywa właściwy sterownik na podstawie 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
Jeśli tożsamość sterownika połączenia nie zostanie rozpoznana, zgłaszany jest RuntimeException z komunikatem Unsupported database driver: <name>. merql nie zawiera sterownika PostgreSQL.
Rejestrowanie niestandardowych sterowników
W przypadku baz danych innych niż MySQL i SQLite napisz klasę implementującą Driver i zarejestruj ją. PostgresDriver poniżej oznacza Twoją własną klasę:
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.
Klasa sterownika musi implementować interfejs Driver. Pierwszy argument funkcji register() to tożsamość sterownika połączenia.
Resetowanie
Na potrzeby testów przywróć fabrykę do stanu domyślnego:
DriverFactory::reset();
// Reverts to only MySQL and SQLite drivers.
Pomocnik połączenia
Klasa Connection tworzy adaptery z rozsądnymi ustawieniami domyślnymi. Adaptery PDO zgłaszają wyjątki w razie błędu, używają asocjacyjnego trybu pobierania, natywnych przygotowanych zapytań oraz pobierania wartości jako ciągów znaków. Adapter mysqli ustawia utf8mb4, używa trybu wyjątków mysqli i przygotowanych zapytań oraz normalizuje pobrane wartości do tego samego formatu: ciąg znaków lub 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() akceptuje dowolny DSN, który może otworzyć PDO, ale merql może tworzyć zrzuty i stosować zmiany tylko za pośrednictwem zarejestrowanego sterownika. Połączenie pgsql: zostanie otwarte (jeśli zainstalowano pdo_pgsql), ale konstruktory Merql::init() oraz Snapshotter, Applier i GuardedApplier wywołują DriverFactory::create(), które zgłasza RuntimeException: Unsupported database driver: pgsql, chyba że zarejestrowano dla niego sterownik lub przekazano go jawnie.
Connection::sqlite() automatycznie włącza też PRAGMA foreign_keys = ON, którego SQLite wymaga do egzekwowania kluczy obcych.
Gdzie używane są sterowniki
Sterowniki są używane w całym merql:
- Snapshotter używa
listTables,readSchemaiselectAlldo przechwytywania stanu bazy danych. - Applier używa
readForeignKeysdo określania kolejności operacji i przekazuje sterownik doSqlGeneratorw celu cytowania identyfikatorów. - SqlGenerator używa
quoteIdentifierdo budowania bezpiecznych zapytań SQL.
Jeśli przekażesz połączenie do Snapshotter lub Applier bez określenia sterownika, automatycznie wywołana zostanie funkcja DriverFactory::create().