Skip to content

Commit

Permalink
Support primitive numeric types
Browse files Browse the repository at this point in the history
  • Loading branch information
David Sykes committed Sep 19, 2022
1 parent 74ba1b2 commit 04add9d
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 15 deletions.
72 changes: 62 additions & 10 deletions src/main/java/org/dt/japper/CallResult.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,34 @@ public class CallResult {
CallResult() {}

public <T> T get(String name, Class<T> resultType) {
if (resultType.isPrimitive()) {
return magicBox(resultType, valueMap.get(name));
}

return resultType.cast(valueMap.get(name));
}


@SuppressWarnings("unchecked")
private <T> T magicBox(Class<T> resultType, Object value) {
if (resultType == short.class) {
return (T) new Short(value != null ? (short) value : 0);
}
if (resultType == int.class) {
return (T) new Integer(value != null ? (int) value : 0);
}
if (resultType == long.class) {
return (T) new Long(value != null ? (long) value : 0);
}
if (resultType == float.class) {
return (T) new Float(value != null ? (float) value : 0);
}
if (resultType == double.class) {
return (T) new Double(value != null ? (double) value : 0);
}

throw new IllegalArgumentException("Unsupported primitive type in OUT parameter wrangling: " + resultType.getName() + " from " + (value == null ? "(null)" : value.getClass()));
}

void register(CallableStatement cs, String name, Class<?> type, int index) throws SQLException {
Parameter p = new Parameter(name, type, index);

Expand Down Expand Up @@ -81,14 +106,37 @@ private void setValue(CallableStatement cs, Parameter p) throws SQLException {
valueMap.put(p.getName(), cs.getTimestamp(p.getIndex()));
return;
}

if (p.getType().equals(Date.class)) {
valueMap.put(p.getName(), cs.getDate(p.getIndex()));
return;
}

// TODO add in options for Java types: Integer, Long, Double, Float


if (p.getType().equals(Short.class) || p.getType().equals(short.class)) {
valueMap.put(p.getName(), cs.getShort(p.getIndex()));
return;
}

if (p.getType().equals(Integer.class) || p.getType().equals(int.class)) {
valueMap.put(p.getName(), cs.getInt(p.getIndex()));
return;
}

if (p.getType().equals(Long.class) || p.getType().equals(long.class)) {
valueMap.put(p.getName(), cs.getLong(p.getIndex()));
return;
}

if (p.getType().equals(Float.class) || p.getType().equals(float.class)) {
valueMap.put(p.getName(), cs.getFloat(p.getIndex()));
return;
}

if (p.getType().equals(Double.class) || p.getType().equals(double.class)) {
valueMap.put(p.getName(), cs.getDouble(p.getIndex()));
return;
}

throw new IllegalArgumentException("Unsupported OUT parameter type: "+p.getName()+"("+p.getType().getName()+")");
}

Expand All @@ -97,20 +145,24 @@ private int getSqlType(Class<?> type) {
return Types.VARCHAR;
}

if (type.equals(BigDecimal.class)) {
if (type.equals(BigDecimal.class) ||
type.equals(Short.class) || type.equals(short.class) ||
type.equals(Integer.class) || type.equals(int.class) ||
type.equals(Long.class) || type.equals(long.class) ||
type.equals(Float.class) || type.equals(float.class) ||
type.equals(Double.class) || type.equals(double.class)
) {
return Types.NUMERIC;
}

if (type.equals(Timestamp.class)) {
return Types.TIMESTAMP;
}

if (type.equals(Date.class)) {
return Types.DATE;
}

// TODO add in options for Java types: Integer, Long, Double, Float


throw new IllegalArgumentException("Unsupported OUT parameter type: "+type.getName());
}

Expand Down
32 changes: 27 additions & 5 deletions src/test/java/org/dt/japper/SimpleStoredProcedureTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public static void setupDB() throws Exception {
}

@AfterAll
public static void clearDB() throws Exception {
public static void clearDB() {
if (testData != null) testData.destroy();
}

Expand All @@ -31,7 +31,7 @@ public void callTest() throws Exception {
Connection conn = testData.connect();

CallResult callResult = Japper.call(conn, SQL_CALL, "NAME", "something", "MANGLED", out(String.class), "NAME_RANK", out(BigDecimal.class));
assertEquals(new String("something"), callResult.get("MANGLED", String.class));
assertEquals("something", callResult.get("MANGLED", String.class));
assertEquals(new BigDecimal(5), callResult.get("NAME_RANK", BigDecimal.class));

conn.close();
Expand All @@ -42,7 +42,7 @@ public void callWithUnusedParameterTest() throws Exception {
Connection conn = testData.connect();

CallResult callResult = Japper.call(conn, SQL_CALL, "NAME", "something", "DUMMY", "value", "MANGLED", out(String.class), "NAME_RANK", out(BigDecimal.class));
assertEquals(new String("something"), callResult.get("MANGLED", String.class));
assertEquals("something", callResult.get("MANGLED", String.class));
assertEquals(new BigDecimal(5), callResult.get("NAME_RANK", BigDecimal.class));

conn.close();
Expand All @@ -53,14 +53,36 @@ public void callWithTargetTypeTest() throws Exception {
Connection conn = testData.connect();

ProcResult result = Japper.call(conn, ProcResult.class, SQL_CALL, "NAME", "something", "MANGLED", out(String.class), "NAME_RANK", out(BigDecimal.class));
assertEquals(new String("something"), result.getMangled());
assertEquals("something", result.getMangled());
assertEquals(new BigDecimal(5), result.getNameRank());

// Do it again so we can see the 2nd time performce
result = Japper.call(conn, ProcResult.class, SQL_CALL, "NAME", "something", "MANGLED", out(String.class), "NAME_RANK", out(BigDecimal.class));
assertEquals(new String("something"), result.getMangled());
assertEquals("something", result.getMangled());
assertEquals(new BigDecimal(5), result.getNameRank());

conn.close();
}

@Test
public void callWithPrimitypeTypesTest() throws Exception {
Connection conn = testData.connect();

CallResult callResult = Japper.call(conn, SQL_CALL, "NAME", "something", "DUMMY", "value", "MANGLED", out(String.class), "NAME_RANK", out(Integer.class));
assertEquals(5, callResult.get("NAME_RANK", Integer.class));

// Do the same again with a floating point type
callResult = Japper.call(conn, SQL_CALL, "NAME", "something", "DUMMY", "value", "MANGLED", out(String.class), "NAME_RANK", out(Double.class));
assertEquals(5.0, callResult.get("NAME_RANK", Double.class));

// And now with the primitive type by itself
callResult = Japper.call(conn, SQL_CALL, "NAME", "something", "DUMMY", "value", "MANGLED", out(String.class), "NAME_RANK", out(double.class));
assertEquals(5.0, callResult.get("NAME_RANK", double.class));

// And one more time to make sure boxing stuff works as expected
callResult = Japper.call(conn, SQL_CALL, "NAME", "something", "DUMMY", "value", "MANGLED", out(String.class), "NAME_RANK", out(double.class));
assertEquals(5.0, callResult.get("NAME_RANK", Double.class));

conn.close();
}
}

0 comments on commit 04add9d

Please sign in to comment.