[#7242] Add support for JSON / JSONB types in PostgreSQL

This commit is contained in:
Lukas Eder 2019-07-15 12:42:18 +02:00
parent c435401163
commit 3560efe0d4
3 changed files with 130 additions and 2 deletions

View File

@ -155,6 +155,8 @@ import org.jooq.Converters;
import org.jooq.DataType;
import org.jooq.EnumType;
import org.jooq.Field;
import org.jooq.JSON;
import org.jooq.JSONB;
// ...
import org.jooq.Record;
import org.jooq.RenderContext;
@ -244,6 +246,10 @@ public class DefaultBinding<T, U> implements Binding<T, U> {
return new DefaultFloatBinding(converter, isLob);
else if (type == Integer.class || type == int.class)
return new DefaultIntegerBinding(converter, isLob);
else if (type == JSON.class)
return new DefaultJSONBinding(converter, isLob);
else if (type == JSONB.class)
return new DefaultJSONBBinding(converter, isLob);
else if (type == LocalDate.class) {
DateToLocalDateConverter c1 = new DateToLocalDateConverter();
@ -603,6 +609,17 @@ public class DefaultBinding<T, U> implements Binding<T, U> {
case POSTGRES:
return true;
}
}
// [#7242] Other vendor specific types also need a lot of casting
if (type == JSON.class || type == JSONB.class) {
switch (ctx.family()) {
case POSTGRES:
return true;
}
@ -662,7 +679,13 @@ public class DefaultBinding<T, U> implements Binding<T, U> {
// [#4338] ... specifically when using JSR-310 types
// [#1130] TODO type can be null for ARRAY types, etc.
// [#7351] UUID data types need to be cast too
else if (( POSTGRES == family) && (sqlDataType == null || (!sqlDataType.isTemporal() && sqlDataType != SQLDataType.UUID)))
// [#7242] JSON(B) data types need to be cast too
else if (( POSTGRES == family) &&
(sqlDataType == null ||
(!sqlDataType.isTemporal()
&& sqlDataType != SQLDataType.UUID
&& sqlDataType != SQLDataType.JSON
&& sqlDataType != SQLDataType.JSONB)))
sql(ctx, converted);
// [#1727] VARCHAR types should be cast to their actual lengths in some
@ -4141,6 +4164,90 @@ public class DefaultBinding<T, U> implements Binding<T, U> {
}
}
static final class DefaultJSONBinding<U> extends AbstractBinding<JSON, U> {
/**
* Generated UID
*/
private static final long serialVersionUID = 3430629127218407737L;
DefaultJSONBinding(Converter<JSON, U> converter, boolean isLob) {
super(converter, isLob);
}
@Override
final void set0(BindingSetStatementContext<U> ctx, JSON value) throws SQLException {
ctx.statement().setString(ctx.index(), value.toString());
}
@Override
final void set0(BindingSetSQLOutputContext<U> ctx, JSON value) throws SQLException {
ctx.output().writeString(value.toString());
}
@Override
final JSON get0(BindingGetResultSetContext<U> ctx) throws SQLException {
return JSON.valueOf(ctx.resultSet().getString(ctx.index()));
}
@Override
final JSON get0(BindingGetStatementContext<U> ctx) throws SQLException {
return JSON.valueOf(ctx.statement().getString(ctx.index()));
}
@Override
final JSON get0(BindingGetSQLInputContext<U> ctx) throws SQLException {
return JSON.valueOf(ctx.input().readString());
}
@Override
final int sqltype(Statement statement, Configuration configuration) {
return Types.VARCHAR;
}
}
static final class DefaultJSONBBinding<U> extends AbstractBinding<JSONB, U> {
/**
* Generated UID
*/
private static final long serialVersionUID = 3430629127218407737L;
DefaultJSONBBinding(Converter<JSONB, U> converter, boolean isLob) {
super(converter, isLob);
}
@Override
final void set0(BindingSetStatementContext<U> ctx, JSONB value) throws SQLException {
ctx.statement().setString(ctx.index(), value.toString());
}
@Override
final void set0(BindingSetSQLOutputContext<U> ctx, JSONB value) throws SQLException {
ctx.output().writeString(value.toString());
}
@Override
final JSONB get0(BindingGetResultSetContext<U> ctx) throws SQLException {
return JSONB.valueOf(ctx.resultSet().getString(ctx.index()));
}
@Override
final JSONB get0(BindingGetStatementContext<U> ctx) throws SQLException {
return JSONB.valueOf(ctx.statement().getString(ctx.index()));
}
@Override
final JSONB get0(BindingGetSQLInputContext<U> ctx) throws SQLException {
return JSONB.valueOf(ctx.input().readString());
}
@Override
final int sqltype(Statement statement, Configuration configuration) {
return Types.VARCHAR;
}
}
static final class DefaultYearToSecondBinding<U> extends AbstractBinding<YearToSecond, U> {
/**

View File

@ -81,6 +81,8 @@ import java.util.UUID;
import org.jooq.Configuration;
import org.jooq.DataType;
import org.jooq.JSON;
import org.jooq.JSONB;
import org.jooq.Record;
import org.jooq.Result;
import org.jooq.RowId;
@ -656,6 +658,22 @@ public final class SQLDataType {
*/
public static final DataType<UUID> UUID = new DefaultDataType<>(null, UUID.class, "uuid");
/**
* The {@link JSON} type.
* <p>
* This is not a SQL or JDBC standard. This type handles JSON types where
* they are supported.
*/
public static final DataType<JSON> JSON = new DefaultDataType<>(null, JSON.class, "json");
/**
* The {@link JSONB} type.
* <p>
* This is not a SQL or JDBC standard. This type handles JSONB types where
* they are supported
*/
public static final DataType<JSONB> JSONB = new DefaultDataType<>(null, JSONB.class, "jsonb");
// -------------------------------------------------------------------------
// Static initialisation of dialect-specific data types
// -------------------------------------------------------------------------

View File

@ -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;
@ -166,7 +168,8 @@ public class PostgresDataType {
public static final DataType<Result<Record>> REFCURSOR = new DefaultDataType<>(SQLDialect.POSTGRES, SQLDataType.RESULT, "refcursor");
public static final DataType<Object> ANY = new DefaultDataType<>(SQLDialect.POSTGRES, SQLDataType.OTHER, "any");
public static final DataType<UUID> UUID = new DefaultDataType<>(SQLDialect.POSTGRES, SQLDataType.UUID, "uuid");
public static final DataType<Object> JSON = new DefaultDataType<>(SQLDialect.POSTGRES, SQLDataType.OTHER, "json");
public static final DataType<JSON> JSON = new DefaultDataType<>(SQLDialect.POSTGRES, SQLDataType.JSON, "json");
public static final DataType<JSONB> JSONB = new DefaultDataType<>(SQLDialect.POSTGRES, SQLDataType.JSONB, "jsonb");
// Meta-table types
public static final DataType<Long> OID = new DefaultDataType<>(SQLDialect.POSTGRES, SQLDataType.BIGINT, "oid");