From a8d77ff3631d1aa4056121995e3398d922645e1a Mon Sep 17 00:00:00 2001 From: Lukas Eder Date: Thu, 25 Jun 2020 11:21:20 +0200 Subject: [PATCH] [jOOQ/jOOQ#8948] Map JSON / JSONB to CLOB/BLOB in HSQLDB --- .../java/org/jooq/impl/DefaultBinding.java | 107 +++++++----------- .../org/jooq/util/hsqldb/HSQLDBDataType.java | 4 + 2 files changed, 48 insertions(+), 63 deletions(-) diff --git a/jOOQ/src/main/java/org/jooq/impl/DefaultBinding.java b/jOOQ/src/main/java/org/jooq/impl/DefaultBinding.java index 3399827358..5d4888b9ad 100644 --- a/jOOQ/src/main/java/org/jooq/impl/DefaultBinding.java +++ b/jOOQ/src/main/java/org/jooq/impl/DefaultBinding.java @@ -4352,49 +4352,42 @@ public class DefaultBinding implements Binding { /** * Generated UID */ - private static final long serialVersionUID = 3430629127218407737L; + private static final long serialVersionUID = 3430629127218407737L; + private static final Set EMULATE_AS_BLOB = SQLDialect.supportedBy(HSQLDB); + private final Converter BYTES_CONVERTER; + private final DefaultBytesBinding BYTES; + + @SuppressWarnings({ "serial", "unchecked", "rawtypes" }) DefaultJSONBBinding(Converter converter, boolean isLob) { super(converter, isLob); + + // [#8949] TODO: Support overriding the system default Charset + BYTES_CONVERTER = new AbstractConverter(byte[].class, JSONB.class) { + @Override + public JSONB from(byte[] t) { + return t == null ? null : JSONB.valueOf(new String(t)); + } + + @Override + public byte[] to(JSONB u) { + return u == null ? null : u.toString().getBytes(); + } + }; + BYTES = new DefaultBytesBinding<>((Converter) BYTES_CONVERTER, isLob); } - - - - - - - - - - - - - - - - - - - - - - - - - - @Override void sqlInline0(BindingSQLContext ctx, JSONB value) throws SQLException { + if (EMULATE_AS_BLOB.contains(ctx.dialect())) { + BYTES.sqlInline0(ctx, BYTES_CONVERTER.to(value)); + } + else { + super.sqlInline0(ctx, value); - - - - - super.sqlInline0(ctx, value); - - if (ctx.family() == H2 && value != null) - ctx.render().sql(' ').visit(K_FORMAT).sql(' ').visit(K_JSON); + if (ctx.family() == H2 && value != null) + ctx.render().sql(' ').visit(K_FORMAT).sql(' ').visit(K_JSON); + } } @Override @@ -4407,30 +4400,24 @@ public class DefaultBinding implements Binding { @Override final void set0(BindingSetStatementContext ctx, JSONB value) throws SQLException { - - - - - - ctx.statement().setString(ctx.index(), value.toString()); + if (EMULATE_AS_BLOB.contains(ctx.dialect())) + BYTES.set0(ctx, BYTES_CONVERTER.to(value)); + else + ctx.statement().setString(ctx.index(), value.toString()); } @Override final void set0(BindingSetSQLOutputContext ctx, JSONB value) throws SQLException { - - - - - - ctx.output().writeString(value.toString()); + if (EMULATE_AS_BLOB.contains(ctx.dialect())) + BYTES.set0(ctx, BYTES_CONVERTER.to(value)); + else + ctx.output().writeString(value.toString()); } @Override final JSONB get0(BindingGetResultSetContext ctx) throws SQLException { - - - - + if (EMULATE_AS_BLOB.contains(ctx.dialect())) + return BYTES_CONVERTER.from(BYTES.get0(ctx)); String string = ctx.resultSet().getString(ctx.index()); return string == null ? null : JSONB.valueOf(string); @@ -4438,10 +4425,8 @@ public class DefaultBinding implements Binding { @Override final JSONB get0(BindingGetStatementContext ctx) throws SQLException { - - - - + if (EMULATE_AS_BLOB.contains(ctx.dialect())) + return BYTES_CONVERTER.from(BYTES.get0(ctx)); String string = ctx.statement().getString(ctx.index()); return string == null ? null : JSONB.valueOf(string); @@ -4449,10 +4434,8 @@ public class DefaultBinding implements Binding { @Override final JSONB get0(BindingGetSQLInputContext ctx) throws SQLException { - - - - + if (EMULATE_AS_BLOB.contains(ctx.dialect())) + return BYTES_CONVERTER.from(BYTES.get0(ctx)); String string = ctx.input().readString(); return string == null ? null : JSONB.valueOf(string); @@ -4460,10 +4443,8 @@ public class DefaultBinding implements Binding { @Override final int sqltype(Statement statement, Configuration configuration) { - - - - + if (EMULATE_AS_BLOB.contains(configuration.dialect())) + BYTES.sqltype(statement, configuration); return Types.VARCHAR; } diff --git a/jOOQ/src/main/java/org/jooq/util/hsqldb/HSQLDBDataType.java b/jOOQ/src/main/java/org/jooq/util/hsqldb/HSQLDBDataType.java index e791348423..82dd684a7c 100644 --- a/jOOQ/src/main/java/org/jooq/util/hsqldb/HSQLDBDataType.java +++ b/jOOQ/src/main/java/org/jooq/util/hsqldb/HSQLDBDataType.java @@ -49,6 +49,8 @@ import java.time.OffsetTime; import java.util.UUID; import org.jooq.DataType; +import org.jooq.JSON; +import org.jooq.JSONB; import org.jooq.Record; import org.jooq.Result; import org.jooq.SQLDialect; @@ -140,6 +142,8 @@ public class HSQLDBDataType { protected static final DataType __SMALLINTUNSIGNED = new DefaultDataType<>(SQLDialect.HSQLDB, SQLDataType.SMALLINTUNSIGNED, "int"); protected static final DataType __INTEGERUNSIGNED = new DefaultDataType<>(SQLDialect.HSQLDB, SQLDataType.INTEGERUNSIGNED, "bigint"); protected static final DataType __BIGINTUNSIGNED = new DefaultDataType<>(SQLDialect.HSQLDB, SQLDataType.BIGINTUNSIGNED, "decimal"); + protected static final DataType __JSON = new DefaultDataType<>(SQLDialect.HSQLDB, SQLDataType.JSON, "clob"); + protected static final DataType __JSONB = new DefaultDataType<>(SQLDialect.HSQLDB, SQLDataType.JSONB, "blob"); // ------------------------------------------------------------------------- // Compatibility types for supported Java types