Skip to content

Commit

Permalink
feat(jdbc): implement ResultSet#getObject with requested type
Browse files Browse the repository at this point in the history
Closes: #601
  • Loading branch information
gotson committed Nov 7, 2022
1 parent 9e9d144 commit 8bcba01
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 5 deletions.
2 changes: 1 addition & 1 deletion src/main/java/org/sqlite/jdbc3/JDBC3ResultSet.java
Original file line number Diff line number Diff line change
Expand Up @@ -962,7 +962,7 @@ private void requireCalendarNotNull(Calendar cal) throws SQLException {
}
}

private int safeGetColumnType(int col) throws SQLException {
protected int safeGetColumnType(int col) throws SQLException {
return stmt.pointer.safeRunInt((db, ptr) -> db.column_type(ptr, col));
}

Expand Down
33 changes: 29 additions & 4 deletions src/main/java/org/sqlite/jdbc4/JDBC4ResultSet.java
Original file line number Diff line number Diff line change
Expand Up @@ -311,13 +311,38 @@ public void updateNClob(String columnLabel, Reader reader) throws SQLException {
}

public <T> T getObject(int columnIndex, Class<T> type) throws SQLException {
// TODO Support this
throw new SQLFeatureNotSupportedException();
if(type == null) throw new SQLException("requested type cannot be null");
if(type == String.class) return type.cast( getString(columnIndex));
if(type == Boolean.class) return type.cast( getBoolean(columnIndex));
if(type == BigDecimal.class) return type.cast(getBigDecimal(columnIndex));
if(type == byte[].class) return type.cast(getBytes(columnIndex));
if(type == Date.class) return type.cast(getDate(columnIndex));
if(type == Time.class) return type.cast(getTime(columnIndex));
if(type == Timestamp.class) return type.cast(getTimestamp(columnIndex));

int columnType = safeGetColumnType(markCol(columnIndex));
if(type == Double.class) {
if(columnType == SQLITE_INTEGER || columnType == SQLITE_FLOAT) return type.cast(getDouble(columnIndex));
throw new SQLException("Bad value for type Double");
}
if(type == Long.class) {
if(columnType == SQLITE_INTEGER || columnType == SQLITE_FLOAT) return type.cast(getLong(columnIndex));
throw new SQLException("Bad value for type Long");
}
if(type == Float.class) {
if(columnType == SQLITE_INTEGER || columnType == SQLITE_FLOAT) return type.cast(getFloat(columnIndex));
throw new SQLException("Bad value for type Float");
}
if(type == Integer.class) {
if(columnType == SQLITE_INTEGER || columnType == SQLITE_FLOAT) return type.cast(getInt(columnIndex));
throw new SQLException("Bad value for type Integer");
}

throw unsupported();
}

public <T> T getObject(String columnLabel, Class<T> type) throws SQLException {
// TODO Support this
throw new SQLFeatureNotSupportedException();
return getObject(findColumn(columnLabel), type);
}

protected SQLException unsupported() {
Expand Down
49 changes: 49 additions & 0 deletions src/test/java/org/sqlite/ResultSetTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,15 @@

import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.Date;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Time;
import java.sql.Timestamp;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
Expand Down Expand Up @@ -277,4 +281,49 @@ public void testGetBigDecimal() throws SQLException {

assertThat(rs.next()).isFalse();
}

@Test
void getObjectWithRequestedType() throws SQLException {
stat.executeUpdate(
"create table getobject(c1)");
stat.executeUpdate("insert into getobject values (1)");
stat.executeUpdate("insert into getobject values ('abc')");

ResultSet rs = stat.executeQuery("select * from getobject");

assertThat(rs.next()).isTrue();
assertThat(rs.getObject(1, String.class)).isEqualTo("1");
assertThat(rs.getObject(1, Boolean.class)).isTrue();
assertThat(rs.getObject(1, BigDecimal.class)).isEqualTo(rs.getBigDecimal(1));
assertThat(rs.getObject(1, byte[].class)).isEqualTo(rs.getBytes(1));
assertThat(rs.getObject(1, Double.class)).isEqualTo(rs.getDouble(1));
assertThat(rs.getObject(1, Long.class)).isEqualTo(rs.getLong(1));
assertThat(rs.getObject(1, Float.class)).isEqualTo(rs.getFloat(1));
assertThat(rs.getObject(1, Integer.class)).isEqualTo(rs.getInt(1));
assertThat(rs.getObject(1, Date.class)).isEqualTo(rs.getDate(1));
assertThat(rs.getObject(1, Time.class)).isEqualTo(rs.getTime(1));
assertThat(rs.getObject(1, Timestamp.class)).isEqualTo(rs.getTimestamp(1));

assertThat(rs.next()).isTrue();
assertThat(rs.getObject(1, String.class)).isEqualTo("abc");
assertThat(rs.getObject(1, Boolean.class)).isFalse();
assertThat(rs.getObject(1, byte[].class)).isEqualTo(rs.getBytes(1));
assertThatExceptionOfType(SQLException.class)
.isThrownBy(() -> rs.getObject(1, BigDecimal.class))
.withMessageContaining("Bad value for type BigDecimal");
assertThatExceptionOfType(SQLException.class)
.isThrownBy(() -> rs.getObject(1, Double.class))
.withMessageContaining("Bad value for type Double");
assertThatExceptionOfType(SQLException.class)
.isThrownBy(() -> rs.getObject(1, Long.class))
.withMessageContaining("Bad value for type Long");
assertThatExceptionOfType(SQLException.class)
.isThrownBy(() -> rs.getObject(1, Float.class))
.withMessageContaining("Bad value for type Float");
assertThatExceptionOfType(SQLException.class)
.isThrownBy(() -> rs.getObject(1, Integer.class))
.withMessageContaining("Bad value for type Integer");

assertThat(rs.next()).isFalse();
}
}

0 comments on commit 8bcba01

Please sign in to comment.