From 67caf5b24c5a257332ff92fde8ec49f2b96b3bed Mon Sep 17 00:00:00 2001 From: Lukas Eder Date: Wed, 25 Feb 2015 16:22:30 +0100 Subject: [PATCH] [#3188] [#3889] Add DataType.getBinding() --- jOOQ/src/main/java/org/jooq/DataType.java | 10 +++++ .../java/org/jooq/impl/AbstractField.java | 17 +++---- .../java/org/jooq/impl/ConvertedDataType.java | 18 +++----- .../java/org/jooq/impl/DefaultBinding.java | 21 ++++----- .../java/org/jooq/impl/DefaultDataType.java | 44 +++++++++++++++++-- .../java/org/jooq/impl/ParameterImpl.java | 16 ++----- .../src/main/java/org/jooq/impl/RowField.java | 44 ++++++++++++++++++- 7 files changed, 117 insertions(+), 53 deletions(-) diff --git a/jOOQ/src/main/java/org/jooq/DataType.java b/jOOQ/src/main/java/org/jooq/DataType.java index 35d51d6af0..b2757ff4c2 100644 --- a/jOOQ/src/main/java/org/jooq/DataType.java +++ b/jOOQ/src/main/java/org/jooq/DataType.java @@ -74,6 +74,16 @@ public interface DataType extends Serializable { */ int getSQLType(); + /** + * Get the data type binding associated with this data type. + */ + Binding getBinding(); + + /** + * Get the converter associated with this data type. + */ + Converter getConverter(); + /** * Retrieve the Java type associated with this data type. */ diff --git a/jOOQ/src/main/java/org/jooq/impl/AbstractField.java b/jOOQ/src/main/java/org/jooq/impl/AbstractField.java index 5fe8512155..d1ec5995a2 100644 --- a/jOOQ/src/main/java/org/jooq/impl/AbstractField.java +++ b/jOOQ/src/main/java/org/jooq/impl/AbstractField.java @@ -113,25 +113,18 @@ abstract class AbstractField extends AbstractQueryPart implements Field { private final String name; private final String comment; private final DataType dataType; - private final Binding binding; AbstractField(String name, DataType type) { - this(name, type, null, null); + this(name, type, null, type.getBinding()); } + @SuppressWarnings("unchecked") AbstractField(String name, DataType type, String comment, Binding binding) { super(); this.name = name; this.comment = defaultString(comment); - this.dataType = type; - - this.binding = - binding != null - ? binding - : type instanceof ConvertedDataType - ? ((ConvertedDataType) type).binding() - : new DefaultBinding(new IdentityConverter(type.getType()), type.isLob()); + this.dataType = type.asConvertedDataType((Binding) binding); } // ------------------------------------------------------------------------ @@ -172,12 +165,12 @@ abstract class AbstractField extends AbstractQueryPart implements Field { @Override public final Converter getConverter() { - return binding.converter(); + return getBinding().converter(); } @Override public final Binding getBinding() { - return binding; + return dataType.getBinding(); } @Override diff --git a/jOOQ/src/main/java/org/jooq/impl/ConvertedDataType.java b/jOOQ/src/main/java/org/jooq/impl/ConvertedDataType.java index cb76390657..28011166e7 100644 --- a/jOOQ/src/main/java/org/jooq/impl/ConvertedDataType.java +++ b/jOOQ/src/main/java/org/jooq/impl/ConvertedDataType.java @@ -49,7 +49,10 @@ import org.jooq.DataType; * A DataType used for converted types using {@link Converter} * * @author Lukas Eder + * @deprecated - 3.6.0 - [#3889] - Remove this type, it should not be needed any + * longer */ +@Deprecated class ConvertedDataType extends DefaultDataType { /** @@ -58,12 +61,12 @@ class ConvertedDataType extends DefaultDataType { private static final long serialVersionUID = -2321926692580974126L; private final DataType delegate; - private final Binding binding; ConvertedDataType(DataType delegate, Binding binding) { super( null, binding.converter().toType(), + binding, delegate.getTypeName(), delegate.getCastTypeName(), delegate.precision(), @@ -74,7 +77,6 @@ class ConvertedDataType extends DefaultDataType { ); this.delegate = delegate; - this.binding = binding; } @Override @@ -95,21 +97,13 @@ class ConvertedDataType extends DefaultDataType { @SuppressWarnings("unchecked") @Override public U convert(Object object) { - if (binding.converter().toType().isInstance(object)) { + if (getConverter().toType().isInstance(object)) { return (U) object; } // [#3200] Try to convert arbitrary objects to T else { - return binding.converter().from(delegate.convert(object)); + return ((Converter) getConverter()).from(delegate.convert(object)); } } - - Binding binding() { - return binding; - } - - Converter converter() { - return binding.converter(); - } } diff --git a/jOOQ/src/main/java/org/jooq/impl/DefaultBinding.java b/jOOQ/src/main/java/org/jooq/impl/DefaultBinding.java index d5931ac591..667be6d6dd 100644 --- a/jOOQ/src/main/java/org/jooq/impl/DefaultBinding.java +++ b/jOOQ/src/main/java/org/jooq/impl/DefaultBinding.java @@ -109,6 +109,7 @@ import org.jooq.Converters; import org.jooq.DataType; import org.jooq.EnumType; import org.jooq.Field; +import org.jooq.Record; import org.jooq.RenderContext; import org.jooq.Result; import org.jooq.Row; @@ -168,7 +169,7 @@ public class DefaultBinding implements Binding { if (converter == null && binding == null) { - theBinding = (Binding) new DefaultBinding(new IdentityConverter(type.getType()), type.isLob()); + theBinding = (Binding) type.getBinding(); } else if (converter == null) { theBinding = (Binding) binding; @@ -1218,19 +1219,15 @@ public class DefaultBinding implements Binding { xxxx xx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx x xx xxxxxxx xx xxx xxxxxx xxxxxx xxxx xxxxxxxxxxxxxxxxxx xxx xxxx - xx xxx xx xxxxxxxxxxxxxxxxxxx xxxxx xx xxxxxxxxxxx xxxxxx xx xxxxxx + xx xxx xx xxxxxxxxxxxxxxxxxxx xxxxx xx xxxxxxxxxxx xxxxxx xx xxxxxxxxx xxxxxxxxxxxxxx xxxxxxxxxxx x xxxxxxxxxxxxxxxx xxxxxx xxxxxxxx xxxxx x xxxxxxxxxxxxxxxxxx + xxxxxxxx xxxxxxxxx x xxx xxxxxxxxxxxxxxxxxxxxx - xx xxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxx xxxxxxxxxxxxxxxxxx x - xxxxxxxx xxxxxxxxx x xxx xxxxxxxxxxxxxxxxxxxxx + xxx xxxx x x xx x x xxxxxxxxxxxxxxxxx xxxx + xxxxxxxxxxxx x xxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - xxx xxxx x x xx x x xxxxxxxxxxxxxxxxx xxxx - xxxxxxxxxxxx x xxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - - xxxxx x xxxxxxxxxx - x - xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxx x xx [/pro] */ else if (EnumType.class.isAssignableFrom(type)) { @@ -2006,7 +2003,7 @@ public class DefaultBinding implements Binding { * @return The converted {@link UDTRecord} */ @SuppressWarnings("unchecked") - private static final UDTRecord pgNewUDTRecord(Class type, final Object object) throws SQLException { + static final UDTRecord pgNewUDTRecord(Class type, final Object object) throws SQLException { if (object == null) { return null; } @@ -2126,7 +2123,7 @@ public class DefaultBinding implements Binding { } } - private static final void pgSetValue(UDTRecord record, Field field, String value) throws SQLException { + static final void pgSetValue(Record record, Field field, String value) throws SQLException { record.setValue(field, pgFromString(field.getType(), value)); } diff --git a/jOOQ/src/main/java/org/jooq/impl/DefaultDataType.java b/jOOQ/src/main/java/org/jooq/impl/DefaultDataType.java index 67e847e30a..ef2b266152 100644 --- a/jOOQ/src/main/java/org/jooq/impl/DefaultDataType.java +++ b/jOOQ/src/main/java/org/jooq/impl/DefaultDataType.java @@ -177,6 +177,11 @@ public class DefaultDataType implements DataType { */ private final Class type; + /** + * The data type binding corresponding to this data type. + */ + private final Binding binding; + /** * The Java class corresponding to arrays of this data type. */ @@ -242,7 +247,15 @@ public class DefaultDataType implements DataType { this(dialect, null, type, typeName, castTypeName, precision, scale, length, nullable, defaulted); } + DefaultDataType(SQLDialect dialect, Class type, Binding binding, String typeName, String castTypeName, int precision, int scale, int length, boolean nullable, boolean defaulted) { + this(dialect, null, type, binding, typeName, castTypeName, precision, scale, length, nullable, defaulted); + } + DefaultDataType(SQLDialect dialect, DataType sqlDataType, Class type, String typeName, String castTypeName, int precision, int scale, int length, boolean nullable, boolean defaulted) { + this(dialect, sqlDataType, type, null, typeName, castTypeName, precision, scale, length, nullable, defaulted); + } + + DefaultDataType(SQLDialect dialect, DataType sqlDataType, Class type, Binding binding, String typeName, String castTypeName, int precision, int scale, int length, boolean nullable, boolean defaulted) { // Initialise final instance members // --------------------------------- @@ -307,6 +320,10 @@ public class DefaultDataType implements DataType { SQL_DATATYPES_BY_TYPE.put(type, this); } } + + this.binding = binding != null + ? binding + : new DefaultBinding(new IdentityConverter(type), this.isLob()); } @Override @@ -529,6 +546,16 @@ public class DefaultDataType implements DataType { return type; } + @Override + public final Binding getBinding() { + return binding; + } + + @Override + public final Converter getConverter() { + return binding.converter(); + } + @Override public final Class getArrayType() { return arrayType; @@ -590,9 +617,16 @@ public class DefaultDataType implements DataType { return asConvertedDataType(DefaultBinding.newBinding(converter, this, null)); } + @SuppressWarnings("deprecation") @Override - public final DataType asConvertedDataType(Binding binding) { - return new ConvertedDataType(this, binding); + public final DataType asConvertedDataType(Binding newBinding) { + if (binding == newBinding) + return (DataType) this; + + if (newBinding == null) + newBinding = (Binding) new DefaultBinding(new IdentityConverter(getType()), isLob()); + + return new ConvertedDataType(this, newBinding); } @Override @@ -748,7 +782,11 @@ public class DefaultDataType implements DataType { @Override public final boolean isLob() { DataType t = getSQLDataType(); - return (t == BLOB || t == CLOB || t == NCLOB); + + if (t == this) + return getTypeName().endsWith("lob"); + else + return (t == BLOB || t == CLOB || t == NCLOB); } @Override diff --git a/jOOQ/src/main/java/org/jooq/impl/ParameterImpl.java b/jOOQ/src/main/java/org/jooq/impl/ParameterImpl.java index 400e4ad891..edd5600c8d 100644 --- a/jOOQ/src/main/java/org/jooq/impl/ParameterImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/ParameterImpl.java @@ -61,21 +61,13 @@ class ParameterImpl extends AbstractQueryPart implements Parameter { private final String name; private final DataType type; - private final Binding binding; private final boolean isDefaulted; - @SuppressWarnings({ "unchecked" }) + @SuppressWarnings("unchecked") ParameterImpl(String name, DataType type, boolean isDefaulted, Binding binding) { this.name = name; this.isDefaulted = isDefaulted; - this.type = type; - - this.binding = - binding != null - ? binding - : type instanceof ConvertedDataType - ? ((ConvertedDataType) type).binding() - : new DefaultBinding(new IdentityConverter(type.getType()), type.isLob()); + this.type = type.asConvertedDataType((Binding) binding); } @Override @@ -85,12 +77,12 @@ class ParameterImpl extends AbstractQueryPart implements Parameter { @Override public final Converter getConverter() { - return binding.converter(); + return type.getBinding().converter(); } @Override public final Binding getBinding() { - return binding; + return type.getBinding(); } @Override diff --git a/jOOQ/src/main/java/org/jooq/impl/RowField.java b/jOOQ/src/main/java/org/jooq/impl/RowField.java index 03987bc434..ce2b9d7912 100644 --- a/jOOQ/src/main/java/org/jooq/impl/RowField.java +++ b/jOOQ/src/main/java/org/jooq/impl/RowField.java @@ -42,11 +42,16 @@ package org.jooq.impl; import static org.jooq.impl.Utils.DATA_LIST_ALREADY_INDENTED; +import java.sql.SQLException; +import java.util.List; + import org.jooq.Context; +import org.jooq.Converter; import org.jooq.DataType; import org.jooq.Field; import org.jooq.Record; import org.jooq.Row; +import org.jooq.util.postgres.PostgresUtils; /** * @author Lukas Eder @@ -66,8 +71,43 @@ class RowField extends AbstractField { this(row, "row"); } - RowField(ROW row, String as) { - super(as, (DataType) SQLDataType.RECORD); + RowField(final ROW row, String as) { + super(as, (DataType) SQLDataType.RECORD, "", new DefaultBinding(new Converter() { + + @Override + public REC from(final Object t) { + return t == null ? null : Utils.newRecord(true, (Class) RecordImpl.class, row.fields()).operate(new RecordOperation() { + + @Override + public REC operate(REC record) { + List values = PostgresUtils.toPGObject(t.toString()); + + for (int i = 0; i < row.size(); i++) { + try { + DefaultBinding.pgSetValue(record, row.field(i), values.get(i)); + } + catch (SQLException ignore) {} + } + + return record; + } + }); + } + + @Override + public Object to(REC u) { + return null; + } + + @Override + public Class fromType() { + return Object.class; + } + + @Override + public Class toType() { + return (Class) RecordImpl.class; + }})); this.row = row; this.as = as;