Οδηγοί βάσεων δεδομένων
Το merql διαχωρίζει τη μεταφορά σύνδεσης από τη διάλεκτο βάσης δεδομένων. Ένας προσαρμογέας DatabaseConnection εκτελεί SQL μέσω PDO ή mysqli, ενώ ένας 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']]
Τα ερωτήματα καταχώρισης πινάκων χρησιμοποιούν INFORMATION_SCHEMA.TABLES, φιλτραρισμένο με βάση την τρέχουσα βάση δεδομένων και τον τύπο BASE TABLE. Για την ανάγνωση σχήματος, χρησιμοποιούνται τα 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
Αν η ταυτότητα του οδηγού σύνδεσης δεν αναγνωρίζεται, προκαλείται ένα RuntimeException με το μήνυμα Unsupported database driver: <name>. Το 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() δέχεται οποιοδήποτε DSN μπορεί να ανοίξει το PDO, αλλά το 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().