Ga naar de inhoud

Databasedrivers

merql scheidt het transport van verbindingen van de databasespecifieke dialecten. Een adapter van DatabaseConnection voert SQL uit via PDO of mysqli, terwijl een Driver databasespecifieke metagegevens SQL verwerkt en identifiers voorziet van aanhalingstekens. Er zijn ingebouwde drivers voor MySQL en SQLite.

PHP
use Merql\Driver\DriverFactory;

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

De Driver-interface

Elke driver implementeert vijf methoden:

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;
}
Methode Doel
quoteIdentifier Voorzie een tabel- of kolomnaam van aanhalingstekens voor gebruik in SQL.
listTables Geef alle gebruikerstabellen in de huidige database terug.
readSchema Lees kolomnamen, typen, primaire sleutel en unieke sleutels voor een tabel uit.
readForeignKeys Geef een koppeling terug van onderliggende tabel naar bovenliggende tabel.
selectAll Bouw een SELECT *-query voor een tabel.

MysqlDriver

Gebruikt INFORMATION_SCHEMA-queries voor metagegevens en backticks voor identifiers.

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

De query voor tabellijsten raadpleegt INFORMATION_SCHEMA.TABLES, gefilterd op de huidige database en het type BASE TABLE. Het schema wordt uitgelezen met queries naar INFORMATION_SCHEMA.COLUMNS voor kolommen en naar INFORMATION_SCHEMA.KEY_COLUMN_USAGE voor primaire en unieke sleutels.

SqliteDriver

Gebruikt PRAGMA-queries voor metagegevens en dubbele aanhalingstekens voor identifiers.

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 detecteert automatisch de juiste driver op basis van 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

Als de driveridentiteit van de verbinding niet wordt herkend, wordt een RuntimeException met het bericht Unsupported database driver: <name> opgegooid. merql bevat geen PostgreSQL-driver.

Aangepaste drivers registreren

Schrijf voor andere databases dan MySQL en SQLite een klasse die Driver implementeert en registreer deze. PostgresDriver staat hieronder voor uw eigen klasse:

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.

De driverklasse moet de interface Driver implementeren. Het eerste argument van register() is de driveridentiteit van de verbinding.

Opnieuw instellen

Stel voor tests de factory terug op de standaardstatus:

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

Verbindingshelper

De klasse Connection bouwt adapters met verstandige standaardinstellingen. PDO-adapters gebruiken uitzonderingen bij fouten, de associatieve fetchmodus, echte prepared statements en fetches als strings. De mysqli-adapter stelt utf8mb4 in, gebruikt de uitzonderingsmodus van mysqli, prepared statements en normaliseert opgehaalde waarden naar dezelfde vorm: een string of 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() accepteert elke DSN die PDO kan openen, maar merql kan alleen snapshots maken en toepassen via een geregistreerde driver. Een pgsql:-verbinding wordt geopend (als pdo_pgsql is geïnstalleerd), maar de constructors Merql::init(), Snapshotter, Applier en GuardedApplier roepen DriverFactory::create() aan. Die genereert RuntimeException: Unsupported database driver: pgsql, tenzij u hiervoor een driver hebt geregistreerd of er zelf een meegeeft.

Connection::sqlite() schakelt ook automatisch PRAGMA foreign_keys = ON in, wat SQLite nodig heeft om foreign key-beperkingen af te dwingen.

Waar drivers worden gebruikt

Drivers worden overal in merql gebruikt:

  • Snapshotter gebruikt listTables, readSchema en selectAll om de databasestatus vast te leggen.
  • Applier gebruikt readForeignKeys om de volgorde van bewerkingen te bepalen en geeft de driver door aan SqlGenerator om identifiers te citeren.
  • SqlGenerator gebruikt quoteIdentifier om veilige SQL op te bouwen.

Als u een verbinding doorgeeft aan Snapshotter of Applier zonder een driver op te geven, wordt DriverFactory::create() automatisch aangeroepen.