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.
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 :
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.
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.
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().
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 :
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 :
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.
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,readSchemaetselectAllpour capturer l'état de la base de données. - Applier utilise
readForeignKeyspour déterminer l'ordre des opérations et transmet le pilote àSqlGeneratorpour citer les identifiants. - SqlGenerator utilise
quoteIdentifierpour construire des SQL sûrs.
Si vous transmettez une connexion à Snapshotter ou Applier sans spécifier de pilote, DriverFactory::create() est appelé automatiquement.