데이터베이스 드라이버
merql은 연결 전송 계층과 데이터베이스 방언을 분리합니다. DatabaseConnection 어댑터는 PDO 또는 mysqli를 통해 SQL을 실행하고, Driver는 데이터베이스 엔진별 메타데이터 SQL 및 식별자 인용을 처리합니다. MySQL 및 SQLite용 기본 제공 드라이버가 있습니다.
use Merql\Driver\DriverFactory;
$driver = DriverFactory::create($connection);
// Auto-detects MySQL or SQLite from the connection driver identity.
Driver 인터페이스
모든 드라이버는 다음 다섯 메서드를 구현합니다:
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 쿼리를 사용하고 식별자에는 백틱 인용을 사용합니다.
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 쿼리를 사용하고 식별자에는 큰따옴표 인용을 사용합니다.
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()에서 올바른 드라이버를 자동 감지합니다.
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은 직접 작성한 클래스를 나타냅니다:
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()의 첫 번째 인수는 연결 드라이버 식별자입니다.
초기화
테스트를 위해 팩토리를 기본 상태로 초기화하세요:
DriverFactory::reset();
// Reverts to only MySQL and SQLite drivers.
연결 도우미
Connection 클래스는 적절한 기본값으로 어댑터를 구성합니다. PDO 어댑터는 오류 시 예외를 발생시키고, 연관 배열 가져오기 모드, 실제 준비된 문, 문자열화된 가져오기를 사용합니다. mysqli 어댑터는 utf8mb4을 설정하고, mysqli 예외 모드와 준비된 문을 사용하며, 가져온 값을 동일한 문자열 또는 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()은 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는 안전한 SQL을 구성할 때
quoteIdentifier를 사용합니다.
드라이버를 지정하지 않고 Snapshotter 또는 Applier에 연결을 전달하면 DriverFactory::create()가 자동으로 호출됩니다.