We're hacking JDBC...
... so you don't have to
Code that you don't want to write...
How to fetch generated keys in some DBs
case DERBY:
case H2:
case MARIADB:
case MYSQL: {
try {
listener.executeStart(ctx);
result = ctx.statement().executeUpdate();
ctx.rows(result);
listener.executeEnd(ctx);
}
// Yes. Not all warnings may have been consumed yet
finally {
consumeWarnings(ctx, listener);
}
// Yep. Should be as simple as this. But it isn't.
rs = ctx.statement().getGeneratedKeys();
try {
List<Object> list = new ArrayList<Object>();
// Some JDBC drivers seem to illegally return null
// from getGeneratedKeys() sometimes
if (rs != null) {
while (rs.next()) {
list.add(rs.getObject(1));
}
}
// Because most JDBC drivers cannot fetch all
// columns, only identity columns
selectReturning(ctx.configuration(), list.toArray());
return result;
}
finally {
JDBCUtils.safeClose(rs);
}
}
How to fetch generated keys in other DBs
// [#2744] DB2 knows the SELECT .. FROM FINAL TABLE (INSERT ..) syntax
case DB2:
// Firebird and Postgres can execute the INSERT .. RETURNING
// clause like a select clause. JDBC support is not implemented
// in the Postgres JDBC driver
case FIREBIRD:
case POSTGRES: {
try {
listener.executeStart(ctx);
rs = ctx.statement().executeQuery();
listener.executeEnd(ctx);
}
finally {
consumeWarnings(ctx, listener);
}
break;
}
How fetch all exceptions in SQL Server
switch (configuration.dialect().family()) {
case SQLSERVER:
consumeLoop: for (;;)
try {
if (!stmt.getMoreResults() &&
stmt.getUpdateCount() == -1)
break consumeLoop;
}
catch (SQLException e) {
previous.setNextException(e);
previous = e;
}
}
Inlining boolean literals
// [#1153] Some dialects don't support boolean literals
// TRUE and FALSE
if (asList(ASE, DB2, FIREBIRD, ORACLE,
SQLSERVER, SQLITE, SYBASE).contains(family)) {
context.sql(((Boolean) val) ? "1" : "0");
}
else {
context.keyword(((Boolean) val).toString());
}
How to deserialise lobs from UDTs
// [#1327] Oracle cannot deserialise BLOBs as byte[] from SQLInput
if (dataType.isLob()) {
Blob blob = null;
try {
blob = stream.readBlob();
return (T) (blob == null ? null :
blob.getBytes(1, (int) blob.length()));
}
finally {
safeFree(blob);
}
}
else {
return (T) stream.readBytes();
}
How to serialise lobs to UDTs
// [#1327] Oracle cannot serialise BLOBs as byte[] to SQLOutput
// Use reflection to avoid dependency on OJDBC
if (dataType.isLob()) {
Blob blob = null;
try {
blob = on("oracle.sql.BLOB").call("createTemporary",
on(stream).call("getSTRUCT")
.call("getJavaSqlConnection").get(),
false,
on("oracle.sql.BLOB").get("DURATION_SESSION")
).get();
blob.setBytes(1, (byte[]) value);
stream.writeBlob(blob);
}
finally {
DefaultExecuteContext.register(blob);
}
}
else {
stream.writeBytes((byte[]) value);
}
How to handle BigInteger and BigDecimal
else if (type == BigInteger.class) {
// The SQLite JDBC driver doesn't support BigDecimals
if (ctx.configuration().dialect() == SQLDialect.SQLITE) {
return Convert.convert(rs.getString(index),
(Class) BigInteger.class);
}
else {
BigDecimal result = rs.getBigDecimal(index);
return (T) (result == null ? null :
result.toBigInteger());
}
}
else if (type == BigDecimal.class) {
// The SQLite JDBC driver doesn't support BigDecimals
if (ctx.configuration().dialect() == SQLDialect.SQLITE) {
return Convert.convert(rs.getString(index),
(Class) BigDecimal.class);
}
else {
return (T) rs.getBigDecimal(index);
}
}
Inlining date literals
// The SQLite JDBC driver does not implement the escape syntax
// [#1253] SQL Server and Sybase do not implement date literals
if (asList(ASE, SQLITE, SQLSERVER, SYBASE).contains(family)) {
context.sql("'").sql(escape(val)).sql("'");
}
else if (asList(ACCESS).contains(family)) {
context.sql("#")
.sql(new SimpleDateFormat("yyyy/MM/dd")
.format((Date) val))
.sql("#");
}
// [#1253] Derby doesn't support the standard literal
else if (family == DERBY) {
context.keyword("date('").sql(escape(val)).sql("')");
}
// Most dialects implement SQL standard date literals
else {
context.keyword("date '").sql(escape(val)).sql("'");
}
We could go on for hours...
Image copyright information
The above images were used with permission from various sources:
- Cables: Matthew Straubmuller. License: CC-BY SA 2.0
- Cables: Greg Grossmeier. License: CC-BY SA 2.0.
- Electric Engineers: Marco Sarli. All rights reserved. Explicit permission granted.