
# Andmebaasidraiverid

merql eristab ühenduse transporti andmebaasi dialektist. Adapter `DatabaseConnection` käivitab SQL PDO või mysqli kaudu, samas kui `Driver` käsitleb andmebaasimootoripõhist metaandmete SQL päringut ja identifikaatorite jutumärkidesse panemist. Sisseehitatud draiverid on saadaval MySQL ja SQLite jaoks.

```php
use Merql\Driver\DriverFactory;

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

## Draiveri liides

Iga draiver rakendab viit meetodit:

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

| Meetod | Eesmärk |
|---|---|
| `quoteIdentifier` | Paneb tabeli või veeru nime SQL-s kasutamiseks jutumärkidesse. |
| `listTables` | Tagastab kõik praeguse andmebaasi kasutajatabelid. |
| `readSchema` | Loeb tabeli veerunimed, tüübid, primaarvõtme ja kordumatud võtmed. |
| `readForeignKeys` | Tagastab alamtabelite ja ematabelite sõltuvuste seose. |
| `selectAll` | Koostab tabeli kohta `SELECT *` päringu. |

## MysqlDriver

Kasutab metaandmete jaoks `INFORMATION_SCHEMA` päringuid ja identifikaatorite jaoks tagurpidi jutumärke.

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

Tabelite loetlemise päringud teevad päringuid objektist `INFORMATION_SCHEMA.TABLES`, filtreerides praeguse andmebaasi ja `BASE TABLE` tüübi järgi. Skeemi lugemisel tehakse veergude kohta päringuid objektist `INFORMATION_SCHEMA.COLUMNS` ning primaar- ja kordumatute võtmete kohta objektist `INFORMATION_SCHEMA.KEY_COLUMN_USAGE`.

## SqliteDriver

Kasutab metaandmete jaoks `PRAGMA` päringuid ja identifikaatorite jaoks jutumärke.

```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` tuvastab ühenduse `DatabaseConnection::driverName()` põhjal õige draiveri automaatselt.

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

Kui ühenduse draiveriidentiteeti ei tunta ära, tekitatakse `RuntimeException` sõnumiga `Unsupported database driver: <name>`. merql ei sisalda PostgreSQL draiverit.

### Kohandatud draiverite registreerimine

Muude andmebaaside kui MySQL ja SQLite jaoks kirjuta liidest `Driver` rakendav klass ja registreeri see. Allpool tähistab `PostgresDriver` sinu enda klassi:

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

Draiveriklass peab rakendama liidest `Driver`. Meetodi `register()` esimene argument on ühenduse draiveriidentiteet.

### Lähtestamine

Testimiseks lähtesta tehas vaikeseisundisse:

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

## Ühenduse abifunktsioon

`Connection` klass loob adapterid mõistlike vaikeväärtustega. PDO-adapterid kasutavad vigade korral erandeid, assotsiatiivset laadimisrežiimi, päris ettevalmistatud päringuid ja stringina tagastatavaid väärtusi. mysqli-adapter määrab `utf8mb4`, kasutab mysqli erandirežiimi ja ettevalmistatud päringuid ning teisendab laaditud väärtused ühtsesse stringi või nulli vormingusse.

```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()` aktsepteerib mis tahes DSN-i, mida PDO saab avada, kuid merql saab hetktõmmiseid teha ja rakendada ainult registreeritud draiveri kaudu. `pgsql:` ühendus avaneb (kui `pdo_pgsql` on installitud), kuid `Merql::init()` ning konstruktorid `Snapshotter`, `Applier` ja `GuardedApplier` kutsuvad välja `DriverFactory::create()`, mis viskab erandi `RuntimeException: Unsupported database driver: pgsql`, kui te pole selle jaoks draiverit [registreerinud](#registering-custom-drivers) ega seda kaasa andnud.

`Connection::sqlite()` lubab automaatselt ka `PRAGMA foreign_keys = ON`, mida SQLite vajab võõrvõtmete jõustamiseks.

## Kus draivereid kasutatakse

Draivereid kasutatakse merql-is läbivalt:

- **Snapshotter** kasutab andmebaasi oleku salvestamiseks väärtusi `listTables`, `readSchema` ja `selectAll`.
- **Applier** kasutab operatsioonide järjestuse määramiseks väärtust `readForeignKeys` ning edastab draiveri väärtusele `SqlGenerator` identifikaatorite jutumärkidesse panemiseks.
- **SqlGenerator** kasutab turvaliste SQL koostamiseks väärtust `quoteIdentifier`.

Kui edastate ühenduse väärtusele `Snapshotter` või `Applier` draiverit määramata, kutsutakse automaatselt välja `DriverFactory::create()`.
