Driver Database
merql memisahkan transport koneksi dari dialek database. Adaptor DatabaseConnection menjalankan SQL melalui PDO atau mysqli, sedangkan Driver menangani metadata khusus mesin database SQL dan pengutipan identifier. Driver bawaan tersedia untuk MySQL dan SQLite.
use Merql\Driver\DriverFactory;
$driver = DriverFactory::create($connection);
// Auto-detects MySQL or SQLite from the connection driver identity.
Antarmuka Driver
Setiap driver menerapkan lima metode:
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;
}
| Metode | Tujuan |
|---|---|
quoteIdentifier |
Mengutip nama tabel atau kolom untuk digunakan dalam SQL. |
listTables |
Mengembalikan semua tabel pengguna dalam database saat ini. |
readSchema |
Membaca nama dan jenis kolom, kunci utama, serta kunci unik untuk tabel. |
readForeignKeys |
Mengembalikan pemetaan dependensi dari tabel anak ke tabel induk. |
selectAll |
Membuat kueri SELECT * untuk tabel. |
MysqlDriver
Menggunakan kueri INFORMATION_SCHEMA untuk metadata dan pengutipan backtick untuk identifier.
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']]
Kueri daftar tabel INFORMATION_SCHEMA.TABLES yang difilter berdasarkan database saat ini dan jenis BASE TABLE. Pembacaan skema mengueri INFORMATION_SCHEMA.COLUMNS untuk kolom dan INFORMATION_SCHEMA.KEY_COLUMN_USAGE untuk kunci utama dan unik.
SqliteDriver
Menggunakan kueri PRAGMA untuk metadata dan pengutipan tanda kutip ganda untuk identifier.
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 mendeteksi driver yang tepat secara otomatis dari 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
Jika identitas driver koneksi tidak dikenali, RuntimeException akan dilempar dengan pesan Unsupported database driver: <name>. merql tidak menyertakan driver PostgreSQL.
Mendaftarkan driver khusus
Untuk database selain MySQL dan SQLite, tulis kelas yang menerapkan Driver lalu daftarkan. PostgresDriver di bawah ini mewakili kelas Anda sendiri:
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.
Kelas driver harus menerapkan antarmuka Driver. Argumen pertama untuk register() adalah identitas driver koneksi.
Reset
Untuk pengujian, reset factory ke keadaan default:
DriverFactory::reset();
// Reverts to only MySQL and SQLite drivers.
Helper koneksi
Kelas Connection membuat adaptor dengan default yang sesuai. Adaptor PDO menggunakan pengecualian saat terjadi kesalahan, mode pengambilan asosiatif, pernyataan yang disiapkan sungguhan, dan hasil pengambilan yang diubah menjadi string. Adaptor mysqli menetapkan utf8mb4, menggunakan mode pengecualian mysqli dan pernyataan yang disiapkan, serta menormalkan nilai yang diambil ke bentuk string atau null yang sama.
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() menerima DSN apa pun yang dapat dibuka PDO, tetapi merql hanya dapat mengambil snapshot dan menerapkan perubahan melalui driver terdaftar. Koneksi pgsql: terbuka (jika pdo_pgsql terinstal), tetapi konstruktor Merql::init(), Snapshotter, Applier, dan GuardedApplier memanggil DriverFactory::create(), yang melempar RuntimeException: Unsupported database driver: pgsql kecuali Anda telah mendaftarkan driver untuknya dengan mendaftarkan driver atau meneruskan driver.
Connection::sqlite() juga mengaktifkan PRAGMA foreign_keys = ON secara otomatis, yang diperlukan SQLite untuk menerapkan kunci asing.
Penggunaan driver
Driver digunakan di seluruh merql:
- Snapshotter menggunakan
listTables,readSchema, danselectAlluntuk merekam keadaan database. - Applier menggunakan
readForeignKeysuntuk menentukan urutan operasi dan meneruskan driver keSqlGeneratoruntuk mengutip identifier. - SqlGenerator menggunakan
quoteIdentifieruntuk membuat SQL yang aman.
Jika Anda meneruskan koneksi ke Snapshotter atau Applier tanpa menentukan driver, DriverFactory::create() akan dipanggil secara otomatis.