Module system-core
Connectors, Connections, and Statements
Classes JDBCConnector
, SQLConnection
, and SQLQuestStatement
provide implementations for JDBC sources of corresponding source-independent interfaces DBConnector
, OntopConnection
and OntopStatement
(in the latter case, extending abstract implementation QuestStatement
). Creation of main class JDBCConnector
occurs through dependency injection via factory OntopSystemFactory
, when binding interface DBConnector
to JDBCConnector
(which is done within the module properties files).
Managing JDBC Connections and Statements
JDBC connections and statements are obtaind by JDBCConnector
by delegating to pluggable factory interfaces, whose implementations are configurable via properties in GUICE.
JDBC connections are created by factory JDBCConnectionPool
that allows implementing connection pooling, with classes HikariConnectionPool
and TomcatConnectionPool
providing implementations for HikariCP and Tomcat JDBC Connection Pool
JDBC statements are created by factory JDBCStatementInitializer
, with abstract implementation DefaultJDBCStatementInitializer
and PostgreSQL-specific implementation PostgresJDBCStatementInitializer
, which currently obtain new statements from a JDBC connection and configure their fetch size and auto-commit mode based on Ontop settings.
Result Set Implementations
Class SQLQuestStatement
uses the QueryReformulator
to reformulate the query, via QueryReformulator.reformulateIntoNativeQuery()
. The expectation is that the resulting query consists of a ConstructionNode
wrapping a NativeNode
, the first containing the projected variables returned by the query and the latter containing the native SQL query to execute. The native SQL query is then sent as a whole to the relational DB (i.e., no local execution is performed) via a wrapped JDBC statement, resulting in a JDBC result set that is mapped to the expected query output.
Tuple results (for SELECT
queries) are managed via JDBCTupleResultSet
and its extension DistinctJDBCTupleResultSet
, which both wrap a JDBC result set. The first leverage basic implementation in AbstractTupleResultSet
(which does not account for how bindings are created) and returns an SQLOntopBindingSet
(a tuple) for each JDBC result row. The latter is used if configuration property ontop.distinctResultSet
is set, and filters JDBC row removing duplicates independently of whether DISTINCT
was used or not in the input query (it is likely related to enforcing a set semantics). In case of error, an EmptyTupleResultSet
with the expected result schema but no rows is returned.
Boolean results (for ASK
queries) are managed via SQLBooleanResultSet
, which wraps a JDBC result set and returns true in case the result set is not empty. In case of errores, a PredefinedBooleanResultSet
with constant value false
is returned.
Graph results (for CONSTRUCT
and DESCRIBE
queries) are managed by first wrapping the JDBC result set in a JDBCTupleResultSet
-- with distinct post-processing not done and EmptyTupleResultSet
returned on error -- and then wrapping this tuple result set with a DefaultSimpleGraphResultSet
that maps result rows to (one or more) Assertion
s.
Remarks
- the separation between
AbstractTupleResultSet
andJDBCTupleResultSet
is unclear - the functionalities of
EmptyTupleResultSet
andDistinctJDBCTupleResultSet
may be implemented in modulesystem-core
(the latter via a wrapper result set class) - it's not clear why auto-commit (which is not PostgreSQL-specific) is set only in
PostgresJDBCStatementInitializer