Aller au contenu

Pilotes de base de données

merql sépare le transport de connexion du dialecte de base de données. Un adaptateur DatabaseConnection exécute SQL via PDO ou mysqli, tandis qu'un Driver gère les métadonnées propres au moteur de base de données SQL ainsi que la citation des identifiants. Des pilotes intégrés sont fournis pour MySQL et SQLite.

PHP
use Merql\Driver\DriverFactory;

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

L'interface Driver

Chaque pilote implémente cinq méthodes :

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;
}
Méthode Fonction
quoteIdentifier Mettre entre guillemets un nom de table ou de colonne pour l'utiliser dans SQL.
listTables Renvoyer toutes les tables utilisateur de la base de données actuelle.
readSchema Lire les noms et types des colonnes, la clé primaire et les clés uniques d'une table.
readForeignKeys Renvoyer une correspondance entre les tables enfants et leurs tables parentes.
selectAll Construire une requête SELECT * pour une table.

MysqlDriver

Utilise des requêtes INFORMATION_SCHEMA pour les métadonnées et des accents graves pour citer les identifiants.

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

La liste des tables interroge INFORMATION_SCHEMA.TABLES, filtré selon la base de données actuelle et le type BASE TABLE. La lecture du schéma interroge INFORMATION_SCHEMA.COLUMNS pour les colonnes et INFORMATION_SCHEMA.KEY_COLUMN_USAGE pour les clés primaires et uniques.

SqliteDriver

Utilise des requêtes PRAGMA pour les métadonnées et des guillemets doubles pour citer les identifiants.

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 détecte automatiquement le pilote adéquat à partir de 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

Si l'identité du pilote de connexion n'est pas reconnue, un RuntimeException avec le message Unsupported database driver: <name> est levé. merql ne fournit aucun pilote PostgreSQL.

Enregistrer des pilotes personnalisés

Pour les bases de données autres que MySQL et SQLite, écrivez une classe qui implémente Driver, puis enregistrez-la. PostgresDriver ci-dessous représente votre propre classe :

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.

La classe du pilote doit implémenter l'interface Driver. Le premier argument de register() est l'identité du pilote de connexion.

Réinitialiser

Pour les tests, réinitialisez la fabrique à son état par défaut :

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

Assistant de connexion

La classe Connection construit des adaptateurs avec des valeurs par défaut adaptées. Les adaptateurs PDO utilisent les exceptions en cas d'erreur, le mode de récupération associatif, de vraies requêtes préparées et des résultats convertis en chaînes. L'adaptateur mysqli définit utf8mb4, utilise le mode d'exception mysqli et les requêtes préparées, puis normalise les valeurs récupérées au même format chaîne ou 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() accepte tout DSN que PDO peut ouvrir, mais merql ne peut effectuer des instantanés et des applications qu'avec un pilote enregistré. Une connexion pgsql: s'ouvre (si pdo_pgsql est installé), mais les constructeurs Merql::init(), Snapshotter, Applier et GuardedApplier appellent DriverFactory::create(), qui lève RuntimeException: Unsupported database driver: pgsql à moins que vous n'ayez enregistré un pilote pour cette connexion ou que vous en fournissiez un.

Connection::sqlite() active également automatiquement PRAGMA foreign_keys = ON, ce dont SQLite a besoin pour appliquer les clés étrangères.

Où les pilotes sont utilisés

Les pilotes sont utilisés dans tout merql :

  • Snapshotter utilise listTables, readSchema et selectAll pour capturer l'état de la base de données.
  • Applier utilise readForeignKeys pour déterminer l'ordre des opérations et transmet le pilote à SqlGenerator pour citer les identifiants.
  • SqlGenerator utilise quoteIdentifier pour construire des SQL sûrs.

Si vous transmettez une connexion à Snapshotter ou Applier sans spécifier de pilote, DriverFactory::create() est appelé automatiquement.