diff --git a/libsql-jdbc/src/main/java/com/github/magnusp/libsql/jdbc/LibsqlDatabaseMetaData.java b/libsql-jdbc/src/main/java/com/github/magnusp/libsql/jdbc/LibsqlDatabaseMetaData.java index 0488771..76bd3ff 100644 --- a/libsql-jdbc/src/main/java/com/github/magnusp/libsql/jdbc/LibsqlDatabaseMetaData.java +++ b/libsql-jdbc/src/main/java/com/github/magnusp/libsql/jdbc/LibsqlDatabaseMetaData.java @@ -34,12 +34,14 @@ public LibsqlDatabaseMetaData(LibsqlConnection connection) { } private String resolveDatabaseProductVersion() throws SQLException { + connection.checkClosed(); if (cachedDatabaseProductVersion == null) { try (var statement = connection.createStatement(); var rs = statement.executeQuery("SELECT sqlite_version()")) { - cachedDatabaseProductVersion = rs.next() ? rs.getString(1) : "3.0"; - } catch (SQLException e) { - cachedDatabaseProductVersion = "3.0"; + if (!rs.next()) { + throw new SQLException("SELECT sqlite_version() returned no row"); + } + cachedDatabaseProductVersion = rs.getString(1); } } return cachedDatabaseProductVersion; diff --git a/libsql-jdbc/src/test/java/com/github/magnusp/libsql/jdbc/LibsqlDatabaseMetaDataTest.java b/libsql-jdbc/src/test/java/com/github/magnusp/libsql/jdbc/LibsqlDatabaseMetaDataTest.java index e870792..1d2c8cf 100644 --- a/libsql-jdbc/src/test/java/com/github/magnusp/libsql/jdbc/LibsqlDatabaseMetaDataTest.java +++ b/libsql-jdbc/src/test/java/com/github/magnusp/libsql/jdbc/LibsqlDatabaseMetaDataTest.java @@ -22,6 +22,7 @@ import java.util.stream.Stream; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.junit.jupiter.params.provider.Arguments.arguments; class LibsqlDatabaseMetaDataTest { @@ -64,6 +65,37 @@ void getDatabaseProductVersionOpensOneStatementAcrossTwoCalls() throws SQLExcept .hasSize(1); } + @Test + void getDatabaseProductVersionRetriesAfterAFailedLookup() throws SQLException { + RecordingConnection connection = new RecordingConnection(versionResult("3.45.1")); + connection.failuresRemaining = 1; + LibsqlDatabaseMetaData metadata = new LibsqlDatabaseMetaData(connection); + + assertThatThrownBy(metadata::getDatabaseProductVersion) + .as("the first lookup must surface the failure instead of caching a fallback") + .isInstanceOf(SQLException.class); + assertThat(metadata.getDatabaseProductVersion()) + .as("the second lookup must retry and return the server version") + .isEqualTo("3.45.1"); + assertThat(metadata.getDatabaseMajorVersion()).isEqualTo(3); + assertThat(metadata.getDatabaseMinorVersion()).isEqualTo(45); + } + + @Test + void getDatabaseProductVersionThrowsOnClosedConnection() throws SQLException { + RecordingConnection connection = new RecordingConnection(versionResult("3.45.1")); + LibsqlDatabaseMetaData metadata = new LibsqlDatabaseMetaData(connection); + assertThat(metadata.getDatabaseProductVersion()).isEqualTo("3.45.1"); + connection.close(); + + assertThatThrownBy(metadata::getDatabaseProductVersion) + .as("an already cached version must not outlive the connection") + .isInstanceOf(SQLException.class); + assertThatThrownBy(() -> new LibsqlDatabaseMetaData(connection).getDatabaseProductVersion()) + .as("an uncached lookup on a closed connection must not return a fallback") + .isInstanceOf(SQLException.class); + } + @Test void escapesSingleQuoteInTableNamePattern() throws SQLException { RecordingConnection connection = new RecordingConnection(emptyResult()); @@ -429,6 +461,7 @@ private static final class RecordingConnection extends LibsqlConnection { private final StmtResult result; private final List statements = new ArrayList<>(); private String lastSql; + private int failuresRemaining; private RecordingConnection(StmtResult result) { super(null, null); @@ -445,6 +478,10 @@ public Statement createStatement() throws SQLException { @Override public StmtResult executeStatement(Stmt stmt) throws SQLException { lastSql = stmt.sql(); + if (failuresRemaining > 0) { + failuresRemaining--; + throw new SQLException("simulated product-version lookup failure"); + } return result; } }