XQuare Bridge 1.1
Notice: This document is currently made of hints rather than a complete guide.
This document explains how to proceed to add a new relational database vendor support to XQuare Bridge.
Common JDBC typing abstraction layer
The org.xquark.jdbc.typing package contains classes that encapsulate JDBC type information, which tends to vary widely from one vendor to another.
To port the typing abstraction layer:
- You must create a new XML file in the org.xquark.jdbc.typing.resources for your database basing on the ones already existing. These files contain mainly a map definition between an exhaustive list of native SQL types and JDBC types.
- To trigger the loading of the XML file basing on driver information, you must modify the org.xquark.jdbc.typing.DBMSInfoMap class doing just like for other databases.
The mapping feature uses a JDBC abstraction layer that encapsulate SQL features that are not correctly encapsulated by JDBC drivers. To port this layer:
- Create a new package in the org.xquark.mapping.dbms package as done for other databases.
- Create an AbstractConnection implementation in this new package extending the JDBC2Connection class (if you use a JDBC 2 driver) and containing specific features for the interface.
- Modify the org.xquark.mapping.dbms.AbstractConnectionFactory.getAbstractConnection(Connection, short) method to instantiate your AbstractConnection implementation. Note that the « routing » is delegated to the typing abstraction layer described previously and thus not twice.
Database metadata access
The Bridge XQuery extraction feature uses an internal representation of the relational data model to perform queries called database metadata. To implement your database metadata access:
- Create a new package in the org.xquark.extractor package as done for other databases.
- Create a Loader class in this new package extending the org.xquark.extractor.metadata.Loader class and containing specific features for your RDBMS.
- Modify the org.xquark.extractor.Extractor.initMetaData(Connection) method to instantiate your Loader implementation. Note that the « routing » is delegated to the typing abstraction layer described previously and thus not twice.
Relational algebra rewriting
The XQuare XQuery front-end produces a « direct » relational algebra that need several transformations to become a « standard » algebra. Some databases which SQL may be limited (for instance concerning the subquery support) also need transformations to get « simpler » SQL. This may be the trickiest part of the port especially if your database has a basic implementation of SQL features. Port consists in:
- Creating a derivated class in the new org.xquark.extractor.<rdbms> package extending the org.xquark.extractor.runtime.QueryFactory class and containing specific relational algebra transformations for your RDBMS. Note that an example of the minimal transformation needed may be the ones performed for Oracle 8 which has a powerful SQL, whereas the most complicated example should be MySQL 3.23 that does not support subqueries.
- Modify the org.xquark.extractor.ExtractorConnection.createQueryFactory(String) method to instantiate yourQueryFactory implementation. Note that the « routing » is delegated to the typing abstraction layer described previously and thus not twice.
The last step is to adapt the SQL generation to take into account SQL syntax specificities. The relational algebra tree is first transformed in a syntactical SQL tree. Then the tree is browsed to generate one or more SQL statements. To adapt the SQL generation:
- Create a new AbstractGenSqlVisitor implementation in the org.xquark.extractor.<rdbms> package to produce the syntactical SQL tree from the transformed relational algebra tree. Note that this visitor is instantiated in the previously created QueryFactory. This process might be different from one database to another since SQL rewriting may not be sufficient and may have impact at the syntactical level. For instance for databases that do not suppport subqueries in the FROM clause, a temporary table may be created and thus even the number of SQL statements may be different...
- Create a new org.xquark.extractor.<rdbms>.sql package where you will have to create derivated class for the specific SQL syntaxes of your RDBMS. The base implementation for nodes of the syntactical SQL tree is contained in the org.xquark.extractor.sql.
- Derive the org.xquark.extractor.sql.DefaultSqlFactory in the org.xquark.extractor.<rdbms> package to instantiate the specific nodes created at the previous step. Note that this factory is instantiated in the previously created <rdbms>GenSqlVisitor.
by Stéphane ROUGES