コンテンツへスキップ

データベースドライバー

merqlは接続の転送方式とデータベース方言を分離します。 DatabaseConnection アダプターはPDOまたはmysqli経由で SQL を実行し、Driver はデータベースエンジン固有のメタデータ SQL と識別子の引用符処理を担います。MySQLとSQLite用の組み込みドライバーが用意されています。

PHP
use Merql\Driver\DriverFactory;

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

Driverインターフェース

すべてのドライバーは次の5つのメソッドを実装します:

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;
}
メソッド 目的
quoteIdentifier SQL で使用するテーブル名または列名を引用符で囲みます。
listTables 現在のデータベース内にあるすべてのユーザーテーブルを返します。
readSchema テーブルの列名、型、主キー、一意キーを読み取ります。
readForeignKeys 子テーブルから親テーブルへの依存関係マップを返します。
selectAll テーブル用の SELECT * クエリを構築します。

MysqlDriver

メタデータの取得には INFORMATION_SCHEMA クエリを使い、識別子はバッククォートで囲みます。

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

テーブル一覧の取得では、現在のデータベースと BASE TABLE 型で絞り込んだ INFORMATION_SCHEMA.TABLES をクエリします。スキーマの読み取りでは、列に INFORMATION_SCHEMA.COLUMNS、主キーと一意キーに INFORMATION_SCHEMA.KEY_COLUMN_USAGE をクエリします。

SqliteDriver

メタデータの取得には PRAGMA クエリを使い、識別子は二重引用符で囲みます。

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

接続ドライバーの識別情報が認識されない場合、メッセージ Unsupported database driver: <name> を持つ RuntimeException がスローされます。merqlにはPostgreSQL用ドライバーは含まれていません。

カスタムドライバーの登録

MySQLとSQLite以外のデータベースでは、Driver を実装するクラスを作成して登録します。以下の PostgresDriver は独自のクラスに置き換えてください:

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.

ドライバークラスは Driver インターフェースを実装する必要があります。register() の最初の引数は接続ドライバーの識別情報です。

リセット

テスト時にファクトリーをデフォルト状態に戻します:

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

接続ヘルパー

Connection クラスは適切なデフォルト設定でアダプターを構築します。PDOアダプターでは、エラー時の例外、連想配列形式の取得、ネイティブのプリペアドステートメント、文字列化された取得値が使われます。mysqliアダプターは utf8mb4 を設定し、mysqliの例外モードとプリペアドステートメントを使って、取得値を同じ文字列または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() はPDOが開ける任意のDSNを受け付けますが、merqlでスナップショットの作成と適用を行うには、登録済みドライバーが必要です。pgsql: 接続は(pdo_pgsql がインストールされていれば)開けますが、Merql::init() と Snapshotter、Applier、GuardedApplier のコンストラクターは DriverFactory::create() を呼び出します。ドライバーを登録するか、ドライバーを渡さない限り、RuntimeException: Unsupported database driver: pgsql がスローされます。

Connection::sqlite() は PRAGMA foreign_keys = ON も自動的に有効にします。これはSQLiteで外部キー制約を有効にするために必要です。

ドライバーの使用箇所

merqlではさまざまな箇所でドライバーを使用します:

  • Snapshotter は listTables、readSchema、selectAll を使ってデータベースの状態を取得します。
  • Applier は readForeignKeys を使って操作順を決め、識別子を引用符で囲むためにドライバーを SqlGenerator に渡します。
  • SqlGenerator は quoteIdentifier を使って安全な SQL を構築します。

ドライバーを指定せずに Snapshotter または Applier に接続を渡すと、DriverFactory::create() が自動的に呼び出されます。