Search in sources :

Example 6 with SQLDialectNotSupportedException

use of org.jooq.exception.SQLDialectNotSupportedException in project jOOQ by jOOQ.

the class DefaultBinding method set.

@SuppressWarnings("unchecked")
@Override
public void set(BindingSetStatementContext<U> ctx) throws SQLException {
    Configuration configuration = ctx.configuration();
    SQLDialect dialect = ctx.dialect();
    T value = converter.to(ctx.value());
    if (log.isTraceEnabled())
        if (value != null && value.getClass().isArray() && value.getClass() != byte[].class)
            log.trace("Binding variable " + ctx.index(), Arrays.asList((Object[]) value) + " (" + type + ")");
        else
            log.trace("Binding variable " + ctx.index(), value + " (" + type + ")");
    // SQL dialect. See the following section for details
    if (value == null) {
        int sqlType = DefaultDataType.getDataType(dialect, type).getSQLType(configuration);
        // [#1126] Oracle's UDTs need to be bound with their type name
        if (UDTRecord.class.isAssignableFrom(type)) {
            ctx.statement().setNull(ctx.index(), sqlType, Tools.getMappedUDTName(configuration, (Class<UDTRecord<?>>) type));
        } else // Some dialects have trouble binding binary data as BLOB
        if (asList(POSTGRES).contains(configuration.family()) && sqlType == Types.BLOB) {
            ctx.statement().setNull(ctx.index(), Types.BINARY);
        } else // All other types can be set to null if the JDBC type is known
        if (sqlType != Types.OTHER) {
            ctx.statement().setNull(ctx.index(), sqlType);
        } else // [#729] In the absence of the correct JDBC type, try setObject
        {
            ctx.statement().setObject(ctx.index(), null);
        }
    } else {
        Class<?> actualType = type;
        // Try to infer the bind value type from the actual bind value if possible.
        if (actualType == Object.class) {
            actualType = value.getClass();
        }
        if (actualType == Blob.class) {
            ctx.statement().setBlob(ctx.index(), (Blob) value);
        } else if (actualType == Boolean.class) {
            ctx.statement().setBoolean(ctx.index(), (Boolean) value);
        } else if (actualType == BigDecimal.class) {
            if (asList(SQLITE).contains(dialect.family())) {
                ctx.statement().setString(ctx.index(), value.toString());
            } else {
                ctx.statement().setBigDecimal(ctx.index(), (BigDecimal) value);
            }
        } else if (actualType == BigInteger.class) {
            if (asList(SQLITE).contains(dialect.family())) {
                ctx.statement().setString(ctx.index(), value.toString());
            } else {
                ctx.statement().setBigDecimal(ctx.index(), new BigDecimal((BigInteger) value));
            }
        } else if (actualType == Byte.class) {
            ctx.statement().setByte(ctx.index(), (Byte) value);
        } else if (actualType == byte[].class) {
            ctx.statement().setBytes(ctx.index(), (byte[]) value);
        } else if (actualType == Clob.class) {
            ctx.statement().setClob(ctx.index(), (Clob) value);
        } else if (actualType == Double.class) {
            ctx.statement().setDouble(ctx.index(), (Double) value);
        } else if (actualType == Float.class) {
            ctx.statement().setFloat(ctx.index(), (Float) value);
        } else if (actualType == Integer.class) {
            ctx.statement().setInt(ctx.index(), (Integer) value);
        } else if (actualType == Long.class) {
            ctx.statement().setLong(ctx.index(), (Long) value);
        } else if (actualType == Short.class) {
            ctx.statement().setShort(ctx.index(), (Short) value);
        } else if (actualType == String.class) {
            ctx.statement().setString(ctx.index(), (String) value);
        } else // -------------------------------------------------------------
        if (Tools.isDate(actualType)) {
            Date date = getDate(actualType, value);
            if (dialect == SQLITE) {
                ctx.statement().setString(ctx.index(), date.toString());
            } else {
                ctx.statement().setDate(ctx.index(), date);
            }
        } else if (Tools.isTime(actualType)) {
            Time time = getTime(actualType, value);
            if (dialect == SQLITE) {
                ctx.statement().setString(ctx.index(), time.toString());
            } else {
                ctx.statement().setTime(ctx.index(), time);
            }
        } else if (Tools.isTimestamp(actualType)) {
            Timestamp timestamp = getTimestamp(actualType, value);
            if (dialect == SQLITE) {
                ctx.statement().setString(ctx.index(), timestamp.toString());
            } else {
                ctx.statement().setTimestamp(ctx.index(), timestamp);
            }
        } else if (actualType == OffsetTime.class) {
            String string = format((OffsetTime) value);
            ctx.statement().setString(ctx.index(), string);
        } else if (actualType == OffsetDateTime.class) {
            ctx.statement().setString(ctx.index(), format((OffsetDateTime) value));
        } else // [#566] Interval data types are best bound as Strings
        if (actualType == YearToMonth.class) {
            if (dialect.family() == POSTGRES) {
                ctx.statement().setObject(ctx.index(), toPGInterval((YearToMonth) value));
            } else {
                ctx.statement().setString(ctx.index(), value.toString());
            }
        } else if (actualType == DayToSecond.class) {
            if (dialect.family() == POSTGRES) {
                ctx.statement().setObject(ctx.index(), toPGInterval((DayToSecond) value));
            } else {
                ctx.statement().setString(ctx.index(), value.toString());
            }
        } else if (actualType == UByte.class) {
            ctx.statement().setShort(ctx.index(), ((UByte) value).shortValue());
        } else if (actualType == UShort.class) {
            ctx.statement().setInt(ctx.index(), ((UShort) value).intValue());
        } else if (actualType == UInteger.class) {
            ctx.statement().setLong(ctx.index(), ((UInteger) value).longValue());
        } else if (actualType == ULong.class) {
            ctx.statement().setBigDecimal(ctx.index(), new BigDecimal(value.toString()));
        } else if (actualType == UUID.class) {
            switch(dialect.family()) {
                // java.util.UUID data type
                case H2:
                case POSTGRES:
                    {
                        ctx.statement().setObject(ctx.index(), value);
                        break;
                    }
                // emulates the type
                default:
                    {
                        ctx.statement().setString(ctx.index(), value.toString());
                        break;
                    }
            }
        } else // The type byte[] is handled earlier. byte[][] can be handled here
        if (actualType.isArray()) {
            switch(dialect.family()) {
                case POSTGRES:
                    {
                        ctx.statement().setString(ctx.index(), toPGArrayString((Object[]) value));
                        break;
                    }
                case HSQLDB:
                    {
                        Object[] a = (Object[]) value;
                        Class<?> t = actualType;
                        // See also: https://sourceforge.net/p/hsqldb/bugs/1466
                        if (actualType == UUID[].class) {
                            a = Convert.convertArray(a, byte[][].class);
                            t = byte[][].class;
                        }
                        ctx.statement().setArray(ctx.index(), new MockArray(dialect, a, t));
                        break;
                    }
                case H2:
                    {
                        ctx.statement().setObject(ctx.index(), value);
                        break;
                    }
                default:
                    throw new SQLDialectNotSupportedException("Cannot bind ARRAY types in dialect " + dialect);
            }
        } else if (EnumType.class.isAssignableFrom(actualType)) {
            ctx.statement().setString(ctx.index(), ((EnumType) value).getLiteral());
        } else {
            ctx.statement().setObject(ctx.index(), value);
        }
    }
}
Also used : Configuration(org.jooq.Configuration) Time(java.sql.Time) LocalTime(java.time.LocalTime) OffsetTime(java.time.OffsetTime) OffsetDateTime(java.time.OffsetDateTime) LocalDateTime(java.time.LocalDateTime) PostgresUtils.toPGArrayString(org.jooq.util.postgres.PostgresUtils.toPGArrayString) Timestamp(java.sql.Timestamp) UUID(java.util.UUID) UShort(org.jooq.types.UShort) SQLDialectNotSupportedException(org.jooq.exception.SQLDialectNotSupportedException) ULong(org.jooq.types.ULong) DayToSecond(org.jooq.types.DayToSecond) UShort(org.jooq.types.UShort) BigDecimal(java.math.BigDecimal) LocalDate(java.time.LocalDate) Date(java.sql.Date) MockArray(org.jooq.tools.jdbc.MockArray) UInteger(org.jooq.types.UInteger) BigInteger(java.math.BigInteger) OffsetDateTime(java.time.OffsetDateTime) SQLDialect(org.jooq.SQLDialect) BigInteger(java.math.BigInteger) YearToMonth(org.jooq.types.YearToMonth)

Example 7 with SQLDialectNotSupportedException

use of org.jooq.exception.SQLDialectNotSupportedException in project jOOQ by jOOQ.

the class AbstractTypedElementDefinition method mapDefinedType.

public static final DataTypeDefinition mapDefinedType(Definition container, Definition child, DataTypeDefinition definedType, JavaTypeResolver resolver) {
    DataTypeDefinition result = definedType;
    Database db = container.getDatabase();
    log.debug("Type mapping", child + " with type " + definedType.getType());
    // [#976] Mapping DATE as TIMESTAMP
    if (db.dateAsTimestamp()) {
        DataType<?> dataType = null;
        try {
            dataType = getDataType(db, result.getType(), 0, 0);
        } catch (SQLDialectNotSupportedException ignore) {
        }
        if (dataType != null) {
            // [#5239] [#5762] [#6453] Don't rely on getSQLType()
            if (SQLDataType.DATE.equals(dataType.getSQLDataType())) {
                DataType<?> forcedDataType = getDataType(db, SQLDataType.TIMESTAMP.getTypeName(), 0, 0);
                String binding = DateAsTimestampBinding.class.getName();
                if (db.javaTimeTypes())
                    binding = org.jooq.impl.LocalDateAsLocalDateTimeBinding.class.getName();
                result = new DefaultDataTypeDefinition(db, child.getSchema(), forcedDataType.getTypeName(), 0, 0, 0, result.isNullable(), result.getDefaultValue(), result.isIdentity(), (Name) null, null, binding, null);
            }
        }
    }
    // [#677] Forced types for matching regular expressions
    ForcedType forcedType = db.getConfiguredForcedType(child, definedType);
    if (forcedType != null) {
        String uType = forcedType.getName();
        String converter = null;
        String binding = result.getBinding();
        CustomType customType = customType(db, forcedType);
        if (customType != null) {
            uType = (!StringUtils.isBlank(customType.getType())) ? customType.getType() : customType.getName();
            // [#5877] [#6567] EnumConverters profit from simplified configuration
            if (Boolean.TRUE.equals(customType.isEnumConverter()) || EnumConverter.class.getName().equals(customType.getConverter())) {
                String tType = tType(db, resolver, definedType);
                converter = resolver.constructorCall(EnumConverter.class.getName() + "<" + resolver.ref(tType) + ", " + resolver.ref(uType) + ">") + "(" + resolver.classLiteral(tType) + ", " + resolver.classLiteral(uType) + ")";
            } else if (customType.getLambdaConverter() != null) {
                LambdaConverter c = customType.getLambdaConverter();
                String tType = tType(db, resolver, definedType);
                converter = resolver.ref(Converter.class) + ".of" + (!FALSE.equals(c.isNullable()) ? "Nullable" : "") + "(" + resolver.classLiteral(tType) + ", " + resolver.classLiteral(uType) + ", " + c.getFrom() + ", " + c.getTo() + ")";
            } else if (!StringUtils.isBlank(customType.getConverter())) {
                converter = customType.getConverter();
            }
            if (!StringUtils.isBlank(customType.getBinding()))
                binding = customType.getBinding();
        }
        if (uType != null) {
            db.markUsed(forcedType);
            log.info("Forcing type", child + " to " + forcedType);
            DataType<?> forcedDataType = null;
            boolean n = result.isNullable();
            String d = result.getDefaultValue();
            boolean i = result.isIdentity();
            boolean r = result.isReadonly();
            String g = result.getGeneratedAlwaysAs();
            int l = 0;
            int p = 0;
            int s = 0;
            // [#2486] Allow users to override length, precision, and scale
            Matcher matcher = LENGTH_PRECISION_SCALE_PATTERN.matcher(uType);
            if (matcher.find()) {
                if (!isEmpty(matcher.group(1))) {
                    l = p = convert(matcher.group(1), int.class);
                } else {
                    p = convert(matcher.group(2), int.class);
                    s = convert(matcher.group(3), int.class);
                }
            }
            try {
                forcedDataType = getDataType(db, uType, p, s);
            } catch (SQLDialectNotSupportedException ignore) {
            }
            // [#677] SQLDataType matches are actual type-rewrites
            if (forcedDataType != null) {
                // [#3704] When <forcedType/> matches a custom type AND a data type rewrite, the rewrite was usually accidental.
                if (customType != null)
                    log.warn("Custom type conflict", child + " has custom type " + customType + " forced by " + forcedType + " but a data type rewrite applies");
                result = new DefaultDataTypeDefinition(db, child.getSchema(), uType, l, p, s, n, r, g, d, i, (Name) null, converter, binding, null);
            } else // Other forced types are UDT's, enums, etc.
            if (customType != null) {
                l = result.getLength();
                p = result.getPrecision();
                s = result.getScale();
                String t = result.getType();
                Name u = result.getQualifiedUserType();
                result = new DefaultDataTypeDefinition(db, definedType.getSchema(), t, l, p, s, n, r, g, d, i, u, converter, binding, uType);
            } else // [#4597] If we don't have a type-rewrite (forcedDataType) or a
            // matching customType, the user probably malconfigured
            // their <forcedTypes/> or <customTypes/>
            {
                // [#7373] [#10944] Refer to <customType/> only if someone is still using the feature
                if (db.getConfiguredCustomTypes().isEmpty())
                    log.warn("Bad configuration for <forcedType/> " + forcedType.getName() + ". No matching SQLDataType found: " + forcedType);
                else
                    log.warn("Bad configuration for <forcedType/> " + forcedType.getName() + ". No matching <customType/> found, and no matching SQLDataType found: " + forcedType);
            }
        }
    }
    return result;
}
Also used : CustomType(org.jooq.meta.jaxb.CustomType) ForcedType(org.jooq.meta.jaxb.ForcedType) SQLDialectNotSupportedException(org.jooq.exception.SQLDialectNotSupportedException) LambdaConverter(org.jooq.meta.jaxb.LambdaConverter) Matcher(java.util.regex.Matcher) Name(org.jooq.Name) Converter(org.jooq.Converter) LambdaConverter(org.jooq.meta.jaxb.LambdaConverter) EnumConverter(org.jooq.impl.EnumConverter)

Example 8 with SQLDialectNotSupportedException

use of org.jooq.exception.SQLDialectNotSupportedException in project jOOQ by jOOQ.

the class DefaultDataType method getDataType.

public static final DataType<?> getDataType(SQLDialect dialect, String typeName) {
    SQLDialect family = dialect.family();
    int ordinal = family.ordinal();
    String upper = typeName.toUpperCase();
    String normalised = typeName;
    DataType<?> result = TYPES_BY_NAME[ordinal].get(upper);
    // [#3225] Normalise only if necessary
    if (result == null) {
        result = TYPES_BY_NAME[ordinal].get(normalised = DefaultDataType.normalise(typeName));
        // UDT data types and others are registered using DEFAULT
        if (result == null) {
            result = TYPES_BY_NAME[SQLDialect.DEFAULT.ordinal()].get(normalised);
            // [#5713] TODO: A more generic type aliasing system would be useful, in general!
            if (result == null && "INT".equals(normalised))
                result = TYPES_BY_NAME[SQLDialect.DEFAULT.ordinal()].get("INTEGER");
            else // [#4065] PostgreSQL reports array types as _typename, e.g. _varchar
            if (result == null && SUPPORT_POSTGRES_ARRAY_NOTATION.contains(dialect) && normalised.charAt(0) == '_')
                result = getDataType(dialect, normalised.substring(1)).getArrayDataType();
            else // [#6466] HSQLDB reports array types as XYZARRAY. H2 should, too
            if (result == null && SUPPORT_HSQLDB_ARRAY_NOTATION.contains(dialect) && upper.endsWith(" ARRAY"))
                result = getDataType(dialect, typeName.substring(0, typeName.length() - 6)).getArrayDataType();
            else // [#9609] H2 might still report an untyped array, too
            if (result == null && SUPPORT_HSQLDB_ARRAY_NOTATION.contains(dialect) && upper.equals("ARRAY"))
                result = SQLDataType.OTHER.getArrayDataType();
            // catching the exception in jOOQ-codegen
            if (result == null)
                throw new SQLDialectNotSupportedException("Type " + typeName + " is not supported in dialect " + dialect, false);
        }
    }
    return result;
}
Also used : SQLDialectNotSupportedException(org.jooq.exception.SQLDialectNotSupportedException) SQLDialect(org.jooq.SQLDialect)

Aggregations

SQLDialectNotSupportedException (org.jooq.exception.SQLDialectNotSupportedException)8 Name (org.jooq.Name)4 Matcher (java.util.regex.Matcher)2 SQLDialect (org.jooq.SQLDialect)2 EnumConverter (org.jooq.impl.EnumConverter)2 StringWriter (java.io.StringWriter)1 BigDecimal (java.math.BigDecimal)1 BigInteger (java.math.BigInteger)1 Date (java.sql.Date)1 SQLException (java.sql.SQLException)1 Time (java.sql.Time)1 Timestamp (java.sql.Timestamp)1 LocalDate (java.time.LocalDate)1 LocalDateTime (java.time.LocalDateTime)1 LocalTime (java.time.LocalTime)1 OffsetDateTime (java.time.OffsetDateTime)1 OffsetTime (java.time.OffsetTime)1 UUID (java.util.UUID)1 Configuration (org.jooq.Configuration)1 Converter (org.jooq.Converter)1