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.
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:
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.
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.
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().
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:
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:
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.
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,readSchemaenselectAllom de databasestatus vast te leggen. - Applier gebruikt
readForeignKeysom de volgorde van bewerkingen te bepalen en geeft de driver door aanSqlGeneratorom identifiers te citeren. - SqlGenerator gebruikt
quoteIdentifierom 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.