Search in sources :

Example 1 with MockArray

use of org.jooq.tools.jdbc.MockArray 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)

Aggregations

BigDecimal (java.math.BigDecimal)1 BigInteger (java.math.BigInteger)1 Date (java.sql.Date)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 SQLDialect (org.jooq.SQLDialect)1 SQLDialectNotSupportedException (org.jooq.exception.SQLDialectNotSupportedException)1 MockArray (org.jooq.tools.jdbc.MockArray)1 DayToSecond (org.jooq.types.DayToSecond)1 UInteger (org.jooq.types.UInteger)1 ULong (org.jooq.types.ULong)1 UShort (org.jooq.types.UShort)1 YearToMonth (org.jooq.types.YearToMonth)1