| SQLite und exportierte Schlüssel |
|
Die sQLshell kann seit kurzem mit SQLite-Datenbanken zusammenarbeiten . Nun sollte SQLite als offiziell unterstütztes Datenbank-Managementsystem in die sQLshell aufgenommen werden. Als voreingestellter JDBC-Treiber sollte dabei der Xerial JDBC-Treiber zum Einsatz kommen. Dies steiß auf unvorhergesehene Hindernisse, die durch Anpassung des JDBC-Treibers ausgeräumt werden konnten.
ProblemDer JDBC-Treiber für SQLite liefert keine Informationen über exportierte Schlüssel. Jede Fremdschlüsselbeziehung hat zwei Seiten: die Spalte, die gemeinhin als Fremdschlüssel bezeichnet wird, ist der importierte Schlüssel. Die Spalte, deren Inhalt die möglichen Werte des importierten Schlüssels bestimmt, ist der exportierte Schlüssel. In der JDBC-API existieren dafür zwei Methoden: getExportedKeys und getImportedKeys. Damit kann ich von einer Tabelle ausgehend sozusagen in Vorwärts wie auch in Rückwärtsrichtung alle Tabellen bestimmen, die durch Fremdschlüsselbeziehungen an die Ausgangstabelle gebunden sind. Funktioniert eine von beiden Methoden nicht, sind verschiedene Funktionalitäten in der sQLshell gestört. Dazu gehören unter anderem:
UrsacheIn der Architektur der Datenbank SQLite sind Fremdschlüsselbeziehungen nicht bidirektional navigierbar angelegt. Dies kann man sehr schön am Quelltext der Datenstruktur einer Tabelle ablesen: struct Table { sqlite3 *dbMem; /* DB connection used for lookaside allocations. */ char *zName; /* Name of the table or view */ int iPKey; /* If not negative, use aCol[iPKey] as the primary key */ int nCol; /* Number of columns in this table */ Column *aCol; /* Information about each column */ Index *pIndex; /* List of SQL indexes on this table. */ int tnum; /* Root BTree node for this table (see note above) */ Select *pSelect; /* NULL for tables. Points to definition if a view. */ u16 nRef; /* Number of pointers to this Table */ u8 tabFlags; /* Mask of TF_* values */ u8 keyConf; /* What to do in case of uniqueness conflict on iPKey */ FKey *pFKey; /* Linked list of all foreign keys in this table */ char *zColAff; /* String defining the affinity of each column */#ifndef SQLITE_OMIT_CHECK Expr *pCheck; /* The AND of all CHECK constraints */#endif #ifndef SQLITE_OMIT_ALTERTABLE int addColOffset; /* Offset in CREATE TABLE stmt to add a new column */#endif #ifndef SQLITE_OMIT_VIRTUALTABLE VTable *pVTable; /* List of VTable objects. */ int nModuleArg; /* Number of arguments to the module */ char **azModuleArg; /* Text of all module args. [0] is module name */#endif Trigger *pTrigger; /* List of triggers stored in pSchema */ Schema *pSchema; /* Schema that contains this table */ Table *pNextZombie; /* Next on the Parse.pZombieTab list */};Das Feld pFKey enthält eine Liste aller Fremdschlüssel für eine Tabelle - damit ist die Methode getImportedKeys leicht umzusetzen. Eine vergleichbare Liste aller exportierten Schlüssel fehlt jedoch. Unsere LösungEs wurde ein neuer JDBC-Treiber für SQLite nach dem guten alten Fassaden-Entwurfsmuster erstellt. Dieser implementiert lediglich die Methode getExportedKeys neu. Innerhalb dieser Methode werden alle Fremdschlüssel aller Tabellen analysiert und nach der Tabelle gefiltert, die der Methode übergeben wurde. Damit wurde die bidrektionale Navigierbarkeit der Fremdschlüsselbeziehungen nachgerüstet. Die nächste Version der sQLshell wird damit die vollständige und offizielle Unterstützung der sQLshell enthalten. |


