
# Veritabanı Sürücüleri

merql, bağlantı aktarımını veritabanı lehçesinden ayırır. Bir
`DatabaseConnection` bağdaştırıcısı, PDO veya mysqli üzerinden SQL yürütür; `Driver` ise veritabanı motoruna özgü meta verileri SQL ve tanımlayıcı tırnaklamasını yönetir. Yerleşik
sürücüler MySQL ve SQLite için sunulur.

```php
use Merql\Driver\DriverFactory;

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

## Driver arayüzü

Her sürücü beş yöntem uygular:

```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;
}
```

| Yöntem | Amaç |
|---|---|
| `quoteIdentifier` | SQL içinde kullanılmak üzere tablo veya sütun adını tırnaklar. |
| `listTables` | Geçerli veritabanındaki tüm kullanıcı tablolarını döndürür. |
| `readSchema` | Bir tablo için sütun adlarını, türlerini, birincil anahtarı ve benzersiz anahtarları okur. |
| `readForeignKeys` | Alt tablodan üst tabloya bağımlılıkların eşlemesini döndürür. |
| `selectAll` | Bir tablo için `SELECT *` sorgusu oluşturur. |

## MysqlDriver

Meta veriler için `INFORMATION_SCHEMA` sorgularını, tanımlayıcılar için ters tırnak tırnaklamasını kullanır.

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

Tablo listeleme sorguları, geçerli veritabanına ve `BASE TABLE` türüne göre filtrelenmiş `INFORMATION_SCHEMA.TABLES` değerini sorgular. Şema okuma işlemi sütunlar için `INFORMATION_SCHEMA.COLUMNS`, birincil ve benzersiz anahtarlar için `INFORMATION_SCHEMA.KEY_COLUMN_USAGE` değerini sorgular.

## SqliteDriver

Meta veriler için `PRAGMA` sorgularını, tanımlayıcılar için çift tırnak tırnaklamasını kullanır.

```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`, doğru sürücüyü `DatabaseConnection::driverName()` üzerinden otomatik algılar.

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

Bağlantı sürücüsü kimliği tanınmazsa `Unsupported database driver: <name>` iletisini içeren bir `RuntimeException` fırlatılır. merql herhangi bir PostgreSQL sürücüsü içermez.

### Özel sürücüleri kaydetme

MySQL ve SQLite dışındaki veritabanları için `Driver` arayüzünü uygulayan bir sınıf yazıp kaydedin. Aşağıdaki `PostgresDriver` kendi sınıfınızı temsil eder:

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

Sürücü sınıfı `Driver` arayüzünü uygulamalıdır. `register()` işlevinin ilk bağımsız değişkeni bağlantı sürücüsü kimliğidir.

### Sıfırlama

Test için fabrikayı varsayılan durumuna sıfırlayın:

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

## Bağlantı yardımcısı

`Connection` sınıfı, uygun varsayılan değerlerle bağdaştırıcılar oluşturur. PDO bağdaştırıcıları hata durumunda istisnalar kullanır, ilişkisel getirme modunu, gerçek hazırlanmış ifadeleri ve dizge biçimindeki getirme değerlerini kullanır. mysqli bağdaştırıcısı `utf8mb4` değerini ayarlar, mysqli istisna modunu ve hazırlanmış ifadeleri kullanır, getirilen değerleri aynı dizge veya null biçimine dönüştürür.

```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'nun açabildiği her DSN'yi kabul eder; ancak merql yalnızca kayıtlı bir sürücü üzerinden anlık görüntü alabilir ve uygulama yapabilir. `pgsql:` bağlantısı açılır (`pdo_pgsql` yüklüyse), ancak `Merql::init()` ile `Snapshotter`, `Applier` ve `GuardedApplier` kurucuları, sürücüyü önceden [kaydetmediyseniz](#registering-custom-drivers) veya bağlantı sırasında bir sürücü sağlamazsanız `DriverFactory::create()` işlevini çağırır; bu da `RuntimeException: Unsupported database driver: pgsql` fırlatır.

`Connection::sqlite()`, SQLite yabancı anahtar denetimi için gerektiğinden `PRAGMA foreign_keys = ON` özelliğini de otomatik olarak etkinleştirir.

## Sürücülerin kullanıldığı yerler

Sürücüler merql genelinde kullanılır:

- **Snapshotter**, veritabanı durumunu yakalamak için `listTables`, `readSchema` ve `selectAll` kullanır.
- **Applier**, işlem sırasını belirlemek için `readForeignKeys` kullanır ve tanımlayıcıları tırnaklamak üzere sürücüyü `SqlGenerator` öğesine iletir.
- **SqlGenerator**, güvenli SQL oluşturmak için `quoteIdentifier` kullanır.

Bir sürücü belirtmeden `Snapshotter` veya `Applier` öğesine bağlantı iletirseniz `DriverFactory::create()` otomatik olarak çağrılır.
