Controladores de bases de datos
merql separa el transporte de conexión del dialecto de base de datos. Un adaptador DatabaseConnection ejecuta SQL mediante PDO o mysqli, mientras que un Driver gestiona los metadatos SQL específicos del motor de base de datos y el entrecomillado de identificadores. Hay controladores integrados para MySQL y SQLite.
use Merql\Driver\DriverFactory;
$driver = DriverFactory::create($connection);
// Auto-detects MySQL or SQLite from the connection driver identity.
La interfaz Driver
Todos los controladores implementan cinco métodos:
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étodo | Propósito |
|---|---|
quoteIdentifier |
Entrecomillar el nombre de una tabla o columna para usarlo en SQL. |
listTables |
Devolver todas las tablas de usuario de la base de datos actual. |
readSchema |
Leer los nombres y tipos de columna, la clave primaria y las claves únicas de una tabla. |
readForeignKeys |
Devolver un mapa de las tablas secundarias y sus dependencias de tablas principales. |
selectAll |
Crear una consulta SELECT * para una tabla. |
MysqlDriver
Usa consultas INFORMATION_SCHEMA para los metadatos y comillas invertidas para entrecomillar identificadores.
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']]
Las consultas para enumerar tablas consultan INFORMATION_SCHEMA.TABLES filtrando por la base de datos actual y el tipo BASE TABLE. Las consultas para leer esquemas consultan INFORMATION_SCHEMA.COLUMNS para las columnas y INFORMATION_SCHEMA.KEY_COLUMN_USAGE para las claves primarias y únicas.
SqliteDriver
Usa consultas PRAGMA para los metadatos y comillas dobles para entrecomillar identificadores.
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 detecta automáticamente el controlador correcto a 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 no se reconoce la identidad del controlador de conexión, se lanza un RuntimeException con el mensaje Unsupported database driver: <name>. merql no incluye ningún controlador PostgreSQL.
Registro de controladores personalizados
Para bases de datos distintas de MySQL y SQLite, escriba una clase que implemente Driver y regístrela. PostgresDriver representa su propia clase:
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 clase del controlador debe implementar la interfaz Driver. El primer argumento de register() es la identidad del controlador de conexión.
Restablecer
Para realizar pruebas, restablezca la fábrica a su estado predeterminado:
DriverFactory::reset();
// Reverts to only MySQL and SQLite drivers.
Ayudante de conexión
La clase Connection crea adaptadores con valores predeterminados adecuados. Los adaptadores PDO usan excepciones ante errores, modo de obtención asociativo, instrucciones preparadas reales y resultados obtenidos convertidos a cadenas. El adaptador mysqli configura utf8mb4, usa el modo de excepciones de mysqli e instrucciones preparadas, y normaliza los valores obtenidos al mismo formato de cadena o 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() acepta cualquier DSN que PDO pueda abrir, pero merql solo puede crear instantáneas y aplicar cambios mediante un controlador registrado. Una conexión pgsql: se abre (si pdo_pgsql está instalado), pero los constructores Merql::init(), Snapshotter, Applier y GuardedApplier llaman a DriverFactory::create(), que lanza RuntimeException: Unsupported database driver: pgsql salvo que haya registrado un controlador para ella o que le pase uno.
Connection::sqlite() también activa PRAGMA foreign_keys = ON automáticamente, algo que SQLite necesita para aplicar las restricciones de claves externas.
Dónde se usan los controladores
Los controladores se usan en todo merql:
- Snapshotter usa
listTables,readSchemayselectAllpara capturar el estado de la base de datos. - Applier usa
readForeignKeyspara determinar el orden de las operaciones y pasa el controlador aSqlGeneratorpara entrecomillar identificadores. - SqlGenerator usa
quoteIdentifierpara crear SQL seguros.
Si pasa una conexión a Snapshotter o Applier sin especificar un controlador, se llama automáticamente a DriverFactory::create().