SQL von Erweiterungen für jede Engine prüfen
Diese Seite richtet sich an Datenbankadministratoren, die eine Erweiterung freigeben müssen, bevor sie auf einer Website mit PostgreSQL, SQLite, Oracle oder MongoDB installiert wird. Das eigene SQL von Exponential läuft auf jeder unterstützten Engine; Erweiterungscode und handgeschriebenes SQL oft nicht, weil die meisten Erweiterungen gegen MySQL geschrieben wurden. Diese Seite listet, worauf Sie achten und wo. Quelle: 9.8 Hinweise über Engines hinweg.
Inhalt
- Wo das SQL einer Erweiterung liegt
- Wonach Sie suchen
- Treiberhelfer
- Abweichende Semantik
- MongoDB
- Testen
- Checkliste
Wo das SQL einer Erweiterung liegt
share/db_schema.dbaundshare/db_data.dba: das engine-neutrale Schema, der beste Fall; die Upgrade-Prüfung liest es.sql/<engine>/*.sql: DDL je Engine. Eine Erweiterung mit nursql/mysql/hat noch keine Tabellen für andere Engines.- PHP: Definitionen von
eZPersistentObject(portabel) und handgeschriebene Anweisungen in Aufrufen vonquery()undarrayQuery()(die zu lesenden). - Update-Dateien der eigenen Releases der Erweiterung.
Wonach Sie suchen
grep -rn '`' extension/<name> --include=*.php | grep -i 'select\|insert\|update\|delete' # backticks
grep -rniE 'FROM [a-z_]+ AS [a-z_]+' extension/<name> --include=*.php # AS before a table alias
grep -rniE 'SET (NAMES|FOREIGN_KEY_CHECKS|SQL_MODE|AUTOCOMMIT)' extension/<name> # MySQL session statements
grep -rniE 'LIMIT [0-9]+ *, *[0-9]+|IFNULL|GROUP_CONCAT|ON DUPLICATE KEY|REPLACE INTO' extension/<name> # MySQL dialect| Befund | Problem | Lösung |
|---|---|---|
| Backticks um Namen | PostgreSQL und Oracle lehnen sie ab; der Parser des MongoDB-Adapters erwartet sie nicht | Tabellen und Spalten schlicht benennen |
AS vor einem Tabellenalias | Oracle lehnt es ab (ORA-00933) | den Alias ohne AS schreiben; AS vor einem Spaltenalias ist überall in Ordnung |
SET NAMES, SET FOREIGN_KEY_CHECKS und ähnliche | SQLite ignoriert sie (der Treiber akzeptiert und verwirft sie); PostgreSQL versteht nur SET NAMES; Oracle hat keine solche Anweisung | sie aus Code für jede Engine herauslassen |
| Reine MySQL-Funktionen und -Syntax | scheitern anderswo | die Helfer des Treibers oder die Parameter für Offset und Limit von arrayQuery() verwenden |
Treiberhelfer
Die Treiber implementieren, was sich zwischen Engines unterscheidet; Code sollte sie aufrufen, statt das SQL zu schreiben:
| Helfer | Für |
|---|---|
$db->subString(), $db->concatString() | Teilzeichenkette und Verkettung |
$db->md5() | MD5 (PostgreSQL über pgcrypto, Oracle über STANDARD_HASH, SQLite über eine registrierte Funktion) |
$db->bitAnd(), $db->bitOr() | bitweise Operationen (Oracle BITAND) |
$db->escapeString() | Werte maskieren |
$db->lastSerialID() | die ID des letzten Inserts (Sequenzen von PostgreSQL und Oracle) |
arrayQuery( $sql, array( 'offset' => ..., 'limit' => ... ) ) | Blättern |
$db->databaseName() | mysql, postgresql, sqlite, mongo oder oracle, wenn eine Verzweigung unvermeidlich ist |
Abweichende Semantik
- Leere Zeichenketten: Oracle gibt für
''NULL zurück, sofern nichtOracleEmptyStringForNull=enabled. - Groß-/Kleinschreibung: Die Standard-Sortierfolgen von MySQL ignorieren sie; PostgreSQL und Oracle vergleichen mit
Beachtung; SQLite vergleicht
=mit Beachtung und ignoriert ASCII-Schreibweise inLIKE. Vergleichen Sielower(...)auf beiden Seiten, wo die Schreibweise keine Rolle spielen darf (Zeichensätze und Sortierfolgen). - Scheitern gegenüber leerem Ergebnis: Eine gescheiterte Anweisung und ein leeres Ergebnis werden nicht auf jeder Engine
gleich gemeldet. Um zu fragen, ob eine Tabelle existiert, fragen Sie den Katalog (
eZTableList()des Treibers), nicht einSELECT, das scheitern kann. - Indexnamen gelten auf SQLite und PostgreSQL datenbankweit; die Schema-Handler legen einen kollidierenden Namen als
<table>__<name>an. Halten Sie Namen innerhalb der Lint-Grenzen (Das .dba-Schemaformat). - Ganzzahlen: Die Spaltenbereiche unterscheiden sich (
$db::MAX_INT);$db->clampInteger()hält einen Wert im Bereich. - Fehlercodes unterscheiden sich (Fehlercodes und Meldungen der Datenbank).
MongoDB
Der Adapter führt nie SQL aus; er übersetzt, was er kann, und liefert für den Rest ein leeres Ergebnis, wobei er
MONGO TODO protokolliert. Eine Erweiterung mit handgeschriebenem SQL braucht entweder SQL, das der Adapter versteht, oder
einen eigenen MongoDB-Weg. Klicken Sie jede Funktion der Erweiterung auf einer MongoDB-Staging-Kopie durch und durchsuchen Sie
die Logs (MongoDB: Grenzen und Betrieb).
Testen
- Installieren Sie die Erweiterung auf einer Staging-Kopie der Ziel-Engine.
- Führen Sie ihr Schema über
ezsqlinsertschema.phpoder ihren Installer aus; führen Sie die Upgrade-Prüfung aus. - Verwenden Sie jede Funktion; beobachten Sie
var/log/error.logund die Debug-Ausgabe mitSQLOutput=enabledfür Ihre Adresse. - Führen Sie die eigenen Tests der Erweiterung aus, falls sie welche hat.
Checkliste
- To do: Die Erweiterung hat
share/db_schema.dbaoder SQL-Dateien für die Ziel-Engine. - To do: Keine Backticks, kein
ASvor Tabellenaliasen, keine reinen MySQL-Session-Anweisungen. - To do: Treiberhelfer für Zeichenketten, Hashes, Bits, Blättern und IDs verwendet.
- To do: Suchen ohne Beachtung der Groß-/Kleinschreibung verwenden
lower(...). - To do: Auf Staging auf der Ziel-Engine ohne neue Fehler getestet.
Verwandte Seiten
- Erweiterungsentwicklung
- Eine Engine wählen
- Datenbankunterstützung
- Freie Dokumentation: Diese Seite darf unter der GNU FDL 1.3 frei kopiert, übersetzt und verbessert werden.
Werden Sie Exponential-Partner
Partner teilen ihre Informationen, stellen Mittel bereit, geben Beiträge zurück und entwickeln die Produkte mit uns, und so wächst Exponential. Eine Partner-Website und ein Dashboard sind für Mitte 2027 geplant: Werden Sie noch heute Partner, damit wir schneller wachsen und neue Funktionen früher liefern.