Treci la conținut

Drivere de baze de date

merql separă transportul conexiunii de dialectul bazei de date. Un adaptor DatabaseConnection execută SQL prin PDO sau mysqli, în timp ce un Driver gestionează metadatele specifice motorului bazei de date SQL și citarea identificatorilor. Driverele incluse sunt disponibile pentru MySQL și SQLite.

PHP
use Merql\Driver\DriverFactory;

$driver = DriverFactory::create($connection);
// Auto-detects MySQL or SQLite from the connection driver identity.

Interfața Driver

Fiecare driver implementează cinci metode:

PHP
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;
}
Metodă Scop
quoteIdentifier Citează un nume de tabel sau de coloană pentru a fi folosit în SQL.
listTables Returnează toate tabelele utilizatorului din baza de date curentă.
readSchema Citește numele și tipurile coloanelor, cheia primară și cheile unice ale unui tabel.
readForeignKeys Returnează o mapare a dependențelor de la tabelul copil la tabelul părinte.
selectAll Construiește o interogare SELECT * pentru un tabel.

MysqlDriver

Folosește interogări INFORMATION_SCHEMA pentru metadate și citarea cu backtick-uri pentru identificatori.

PHP
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']]

Interogările pentru listarea tabelelor folosesc INFORMATION_SCHEMA.TABLES, filtrat după baza de date curentă și tipul BASE TABLE. Citirea schemei interoghează INFORMATION_SCHEMA.COLUMNS pentru coloane și INFORMATION_SCHEMA.KEY_COLUMN_USAGE pentru cheile primare și unice.

SqliteDriver

Folosește interogări PRAGMA pentru metadate și citarea cu ghilimele duble pentru identificatori.

PHP
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 detectează automat driverul corect din DatabaseConnection::driverName().

PHP
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

Dacă identitatea driverului conexiunii nu este recunoscută, se aruncă un RuntimeException cu mesajul Unsupported database driver: <name>. merql nu include niciun driver PostgreSQL.

Înregistrarea driverelor personalizate

Pentru alte baze de date decât MySQL și SQLite, scrieți o clasă care implementează Driver și înregistrați-o. PostgresDriver de mai jos reprezintă propria clasă:

PHP
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.

Clasa driverului trebuie să implementeze interfața Driver. Primul argument al funcției register() este identitatea driverului conexiunii.

Resetare

Pentru testare, resetați fabrica la starea implicită:

PHP
DriverFactory::reset();
// Reverts to only MySQL and SQLite drivers.

Ajutor pentru conexiuni

Clasa Connection construiește adaptoare cu valori implicite adecvate. Adaptoarele PDO folosesc excepții la erori, modul de preluare asociativă, instrucțiuni pregătite reale și valori preluate convertite în șiruri. Adaptorul mysqli setează utf8mb4, folosește modul de excepții mysqli și instrucțiuni pregătite și normalizează valorile preluate la același format șir sau null.

PHP
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() acceptă orice DSN pe care PDO îl poate deschide, dar merql poate crea instantanee și aplica modificări doar printr-un driver înregistrat. O conexiune pgsql: se deschide (dacă pdo_pgsql este instalat), dar constructorii Merql::init() și Snapshotter, Applier și GuardedApplier apelează DriverFactory::create(), care aruncă RuntimeException: Unsupported database driver: pgsql dacă nu ați înregistrat un driver pentru aceasta sau nu ați transmis unul.

Connection::sqlite() activează automat și PRAGMA foreign_keys = ON, de care SQLite are nevoie pentru aplicarea cheilor străine.

Unde sunt folosite driverele

Driverele sunt folosite în întregul merql:

  • Snapshotter folosește listTables, readSchema și selectAll pentru a captura starea bazei de date.
  • Applier folosește readForeignKeys pentru a stabili ordinea operațiilor și transmite driverul către SqlGenerator pentru citarea identificatorilor.
  • SqlGenerator folosește quoteIdentifier pentru a construi interogări SQL sigure.

Dacă transmiteți o conexiune către Snapshotter sau Applier fără a specifica un driver, DriverFactory::create() este apelată automat.