Saltar al contenido

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.

PHP
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:

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é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.

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

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.

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 detecta automáticamente el controlador correcto a 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 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:

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 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:

PHP
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.

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() 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, readSchema y selectAll para capturar el estado de la base de datos.
  • Applier usa readForeignKeys para determinar el orden de las operaciones y pasa el controlador a SqlGenerator para entrecomillar identificadores.
  • SqlGenerator usa quoteIdentifier para crear SQL seguros.

Si pasa una conexión a Snapshotter o Applier sin especificar un controlador, se llama automáticamente a DriverFactory::create().