Merql
Apply

Database Drivers

merql uses a Driver interface to abstract all database-engine-specific operations. Built-in drivers are provided for MySQL and SQLite. Custom drivers can be registered for any PDO-supported database.

use Merql\Driver\DriverFactory;

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

The Driver interface

Every driver implements five methods:

use Merql\Driver\Driver;

interface Driver
{
    public function quoteIdentifier(string $name): string;
    public function listTables(PDO $pdo): array;
    public function readSchema(PDO $pdo, string $table): TableSchema;
    public function readForeignKeys(PDO $pdo): array;
    public function selectAll(string $table): string;
}
MethodPurpose
quoteIdentifierQuote a table or column name for use in SQL.
listTablesReturn all user tables in the current database.
readSchemaRead column names, types, primary key, and unique keys for a table.
readForeignKeysReturn a map of child table to parent table dependencies.
selectAllBuild a SELECT * query for a table.

MysqlDriver

Uses INFORMATION_SCHEMA queries for metadata and backtick quoting for identifiers.

use Merql\Driver\MysqlDriver;

$driver = new MysqlDriver();

$driver->quoteIdentifier('posts');
// `posts`

$driver->quoteIdentifier('my`table');
// `my``table`

$tables = $driver->listTables($pdo);
// ['comments', 'posts', 'users']

$schema = $driver->readSchema($pdo, 'posts');
// TableSchema with columns, primaryKey, uniqueKeys

$fks = $driver->readForeignKeys($pdo);
// ['comments' => ['posts', 'users']]

Table listing queries INFORMATION_SCHEMA.TABLES filtered by the current database and BASE TABLE type. Schema reading queries INFORMATION_SCHEMA.COLUMNS for columns and INFORMATION_SCHEMA.KEY_COLUMN_USAGE for primary and unique keys.

SqliteDriver

Uses PRAGMA queries for metadata and double-quote quoting for identifiers.

use Merql\Driver\SqliteDriver;

$driver = new SqliteDriver();

$driver->quoteIdentifier('posts');
// "posts"

$driver->quoteIdentifier('my"table');
// "my""table"

$tables = $driver->listTables($pdo);
// Queries sqlite_master, excludes sqlite_* internal tables.

$schema = $driver->readSchema($pdo, 'posts');
// Uses PRAGMA table_info() and PRAGMA index_list().

$fks = $driver->readForeignKeys($pdo);
// Uses PRAGMA foreign_key_list() for each table.

DriverFactory

DriverFactory auto-detects the correct driver from a PDO connection's driver name attribute.

use Merql\Driver\DriverFactory;

$pdo = new PDO('mysql:host=localhost;dbname=mydb', 'root', '');
$driver = DriverFactory::create($pdo);
// Returns MysqlDriver

$pdo = new PDO('sqlite::memory:');
$driver = DriverFactory::create($pdo);
// Returns SqliteDriver

If the PDO driver is not recognized, a RuntimeException is thrown.

Registering custom drivers

For databases beyond MySQL and SQLite, register a custom driver class:

use Merql\Driver\DriverFactory;

DriverFactory::register('pgsql', PostgresDriver::class);

$pdo = new PDO('pgsql:host=localhost;dbname=mydb', 'user', 'pass');
$driver = DriverFactory::create($pdo);
// Returns your PostgresDriver instance.

The driver class must implement the Driver interface. The first argument to register() is the PDO driver name string (the value of PDO::ATTR_DRIVER_NAME).

Reset

For testing, reset the factory to its default state:

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

Connection helper

The Connection class builds PDO instances with sensible defaults (exceptions on error, associative fetch mode, real prepared statements, stringified fetches):

use Merql\Connection;

// MySQL.
$pdo = Connection::mysql('127.0.0.1', 'my_database', 'root', 'password');
$pdo = Connection::mysql('db.example.com', 'mydb', 'user', 'pass', port: 3307);

// SQLite.
$pdo = Connection::sqlite(':memory:');
$pdo = Connection::sqlite('/var/data/app.sqlite');

// Any DSN.
$pdo = Connection::fromDsn('pgsql:host=localhost;dbname=mydb', 'user', 'pass');

Connection::sqlite() also enables PRAGMA foreign_keys = ON automatically, which SQLite requires for foreign key enforcement.

Where drivers are used

Drivers are used throughout merql:

  • Snapshotter uses listTables, readSchema, and selectAll to capture database state.
  • Applier uses readForeignKeys to determine operation ordering and passes the driver to SqlGenerator for identifier quoting.
  • SqlGenerator uses quoteIdentifier to build safe SQL.

If you pass a PDO connection to Snapshotter or Applier without specifying a driver, DriverFactory::create() is called automatically.

On this page