Custom JDBC driver without database introspection

Answered

Hello,

I am trying to write a simple JDBC driver that, instead of interacting with a database directly, sends queries to another system over HTTPS.

The end goal is to be able to set up a Driver + Data Source in IntelliJ IDEA Ultimate, have IntelliJ send the SQL queries over, and present the results in the IDE's table view (https://resources.jetbrains.com/help/img/idea/2022.3/db_ui_query_console_result_tab.png).

The interfaces to implement are quite large (especially `PreparedStatement` and `DatabaseMetadata`), and I was wondering if it is possible to implement a subset of these to get _just_ the ability to see results of SELECT queries? I know the IDE is able to perform DB introspection to figure out what schemas are available, etc. but I do not need that information.

I can see the JOOQ library allows turning a `ResultSet` into JSON, and then turn JSON back into a `ResultSet`. So I made the system with access to the DB serialize its ResultSet, send it over, and then my driver turns the JSON back into a `ResultSet`. Given result sets contain both the data and column type information, I was hoping it would be enough for IntelliJ, however I'm getting errors while executing simple `SELECT 1` queries and am not sure what is actually being called.

In the Data Source view, the "Test Connection" action succeeds and I get the metadata back from the driver. I can also see the `SELECT version()` query is sent to the server. But if I try to execute "SELECT 1" in the "Playground" view, I get back "Connection was established but closed as invalid".

2022-12-02 11:13:58,193 [44345239]   INFO - #c.i.d.d.DatabaseConnectionEstablisher - Connecting to: <URL>
2022-12-02 11:13:58,195 [44345241]   INFO - #c.i.d.d.DatabaseConnectionEstablisher - Auth provider: user-pass
2022-12-02 11:13:58,205 [44345251]   INFO - #c.i.d.d.DatabaseCredentialsAuthProvider - No user name provided (may be in url)
2022-12-02 11:13:58,263 [44345309]   INFO - #c.i.e.r.RemoteProcessSupport - setting driver log level to FINEST
2022-12-02 11:13:58,263 [44345309]   INFO - #c.i.e.r.RemoteProcessSupport - setting driver log path to /Users/martynas/Desktop/log.txt
2022-12-02 11:13:58,264 [44345310]   INFO - #c.i.e.r.RemoteProcessSupport - DriverManager.LogWriter.level=FINEST
2022-12-02 11:13:58,264 [44345310]   INFO - #c.i.e.r.RemoteProcessSupport - lt.martynas.driver.level=FINEST
2022-12-02 11:13:58,264 [44345310]   INFO - #c.i.e.r.RemoteProcessSupport - Setting `LogLevel` to `6`
2022-12-02 11:13:58,264 [44345310]   INFO - #c.i.e.r.RemoteProcessSupport - Setting `LogPath` to `/Users/martynas/Desktop/log.txt`
2022-12-02 11:13:58,991 [44346037]   INFO - #c.i.i.s.IdeScriptEngineManagerImpl - 129 ms to enumerate javax.scripting engines on EDT
2022-12-02 11:13:59,904 [44346950]   INFO - #c.i.e.r.RemoteProcessSupport - Driver: MyCustomDriver 1.1
2022-12-02 11:14:00,743 [44347789]   INFO - #c.i.e.r.RemoteProcessSupport - version: PostgreSQL 13.7 on aarch64-unknown-linux-gnu, compiled by aarch64-unknown-linux-gnu-gcc (GCC) 7.4.0, 64-bit
2022-12-02 11:14:00,743 [44347789]   INFO - #c.i.e.r.RemoteProcessSupport - Detected: POSTGRES null
2022-12-02 11:14:00,786 [44347832]   INFO - #c.i.d.c.JdbcEngineUtils - Connection is invalid

Is there a way to get more information about _why_ it is not valid? I tried updating the "VM Options" of the driver and attaching a debugger, but can't step into any of IntelliJ's internal classes.

Alternatively, maybe it's possible to feed IntelliJ the serialized `ResultSet` and have it open up a read-only table window, without involvinig JDBC at all?

Serialized output of `SELECT 1`:

{
"fields": [
{
"name": "?column?",
"type": "INTEGER"
}
],
"records": [
[1]
]
}

Regards,
Martynas

0
1 comment
Hi Martynas,

Thank you for contacting us.

You've incorrectly implemented the Connection.isValid method in your code. It returns false, and therefore, the connection is being terminated.

Please let us know if you have questions.
0

Please sign in to leave a comment.