/** Convert a type name (using precision and scale) into a Java class */ public static DataType<?> getDialectDataType(SQLDialect dialect, String t, int p, int s) throws SQLDialectNotSupportedException { DataType<?> result = AbstractDataType.getDataType(dialect, normalise(t)); if (result.getType() == BigDecimal.class) { result = AbstractDataType.getDataType(dialect, getClass(Types.NUMERIC, p, s)); } return result; }
@Override public R operate(R target) throws MappingException { AbstractRecord source = AbstractRecord.this; try { // [#1522] [#2989] If possible the complete state of this record should be copied onto the // other record if (target instanceof AbstractRecord) { AbstractRecord t = (AbstractRecord) target; // Iterate over target fields, to avoid ambiguities when two source fields share the same // name. for (int targetIndex = 0; targetIndex < t.size(); targetIndex++) { Field<?> targetField = t.field(targetIndex); int sourceIndex = fields.indexOf(targetField); if (sourceIndex >= 0) { DataType<?> targetType = targetField.getDataType(); Value<?> sourceValue = values[sourceIndex]; t.values[targetIndex] = new Value<Object>( targetType.convert(sourceValue.getValue()), targetType.convert(sourceValue.getOriginal()), sourceValue.isChanged()); } } } else { for (Field<?> targetField : target.fields()) { Field<?> sourceField = field(targetField); if (sourceField != null) { Utils.setValue(target, targetField, source, sourceField); } } } return target; } // All reflection exceptions are intercepted catch (Exception e) { throw new MappingException("An error ocurred when mapping record to " + target, e); } }
private static <T> void writeToSQLOutput( SQLOutput stream, Class<? extends T> type, DataType<T> dataType, T value) throws SQLException { if (value == null) { stream.writeObject(null); } else if (type == Blob.class) { stream.writeBlob((Blob) value); } else if (type == Boolean.class) { stream.writeBoolean((Boolean) value); } else if (type == BigInteger.class) { stream.writeBigDecimal(new BigDecimal((BigInteger) value)); } else if (type == BigDecimal.class) { stream.writeBigDecimal((BigDecimal) value); } else if (type == Byte.class) { stream.writeByte((Byte) value); } else if (type == byte[].class) { // [#1327] Oracle cannot serialise BLOBs as byte[] to SQLOutput // Use reflection to avoid dependency on OJDBC if (dataType.isLob()) { Blob blob = null; try { blob = on("oracle.sql.BLOB") .call( "createTemporary", on(stream).call("getSTRUCT").call("getJavaSqlConnection").get(), false, on("oracle.sql.BLOB").get("DURATION_SESSION")) .get(); blob.setBytes(1, (byte[]) value); stream.writeBlob(blob); } finally { DefaultExecuteContext.register(blob); } } else { stream.writeBytes((byte[]) value); } } else if (type == Clob.class) { stream.writeClob((Clob) value); } else if (type == Date.class) { stream.writeDate((Date) value); } else if (type == Double.class) { stream.writeDouble((Double) value); } else if (type == Float.class) { stream.writeFloat((Float) value); } else if (type == Integer.class) { stream.writeInt((Integer) value); } else if (type == Long.class) { stream.writeLong((Long) value); } else if (type == Short.class) { stream.writeShort((Short) value); } else if (type == String.class) { // [#1327] Oracle cannot serialise CLOBs as String to SQLOutput // Use reflection to avoid dependency on OJDBC if (dataType.isLob()) { Clob clob = null; try { clob = on("oracle.sql.CLOB") .call( "createTemporary", on(stream).call("getSTRUCT").call("getJavaSqlConnection").get(), false, on("oracle.sql.CLOB").get("DURATION_SESSION")) .get(); clob.setString(1, (String) value); stream.writeClob(clob); } finally { DefaultExecuteContext.register(clob); } } else { stream.writeString((String) value); } } else if (type == Time.class) { stream.writeTime((Time) value); } else if (type == Timestamp.class) { stream.writeTimestamp((Timestamp) value); } else if (type == YearToMonth.class) { stream.writeString(value.toString()); } else if (type == DayToSecond.class) { stream.writeString(value.toString()); } // else if (type.isArray()) { // stream.writeArray(value); // } else if (UNumber.class.isAssignableFrom(type)) { stream.writeString(value.toString()); } else if (ArrayRecord.class.isAssignableFrom(type)) { // [#1544] We can safely assume that localConfiguration has been // set on DefaultBindContext, prior to serialising arrays to SQLOut Connection connection = getDriverConnection(DefaultBindContext.LOCAL_CONFIGURATION.get()); ArrayRecord<?> arrayRecord = (ArrayRecord<?>) value; stream.writeArray( on(connection) .call("createARRAY", arrayRecord.getName(), arrayRecord.get()) .<Array>get()); } else if (EnumType.class.isAssignableFrom(type)) { stream.writeString(((EnumType) value).getLiteral()); } else if (MasterDataType.class.isAssignableFrom(type)) { Object key = ((MasterDataType<?>) value).getPrimaryKey(); writeToSQLOutput(stream, key.getClass(), key); } else if (UDTRecord.class.isAssignableFrom(type)) { stream.writeObject((UDTRecord<?>) value); } else { throw new UnsupportedOperationException("Type " + type + " is not supported"); } }
@SuppressWarnings("unchecked") public static <T> T getFromSQLInput(Configuration configuration, SQLInput stream, Field<T> field) throws SQLException { Class<? extends T> type = field.getType(); DataType<T> dataType = field.getDataType(); if (type == Blob.class) { return (T) stream.readBlob(); } else if (type == Boolean.class) { return (T) checkWasNull(stream, Boolean.valueOf(stream.readBoolean())); } else if (type == BigInteger.class) { BigDecimal result = stream.readBigDecimal(); return (T) (result == null ? null : result.toBigInteger()); } else if (type == BigDecimal.class) { return (T) stream.readBigDecimal(); } else if (type == Byte.class) { return (T) checkWasNull(stream, Byte.valueOf(stream.readByte())); } else if (type == byte[].class) { // [#1327] Oracle cannot deserialise BLOBs as byte[] from SQLInput if (dataType.isLob()) { Blob blob = null; try { blob = stream.readBlob(); return (T) (blob == null ? null : blob.getBytes(1, (int) blob.length())); } finally { Util.safeFree(blob); } } else { return (T) stream.readBytes(); } } else if (type == Clob.class) { return (T) stream.readClob(); } else if (type == Date.class) { return (T) stream.readDate(); } else if (type == Double.class) { return (T) checkWasNull(stream, Double.valueOf(stream.readDouble())); } else if (type == Float.class) { return (T) checkWasNull(stream, Float.valueOf(stream.readFloat())); } else if (type == Integer.class) { return (T) checkWasNull(stream, Integer.valueOf(stream.readInt())); } else if (type == Long.class) { return (T) checkWasNull(stream, Long.valueOf(stream.readLong())); } else if (type == Short.class) { return (T) checkWasNull(stream, Short.valueOf(stream.readShort())); } else if (type == String.class) { return (T) stream.readString(); } else if (type == Time.class) { return (T) stream.readTime(); } else if (type == Timestamp.class) { return (T) stream.readTimestamp(); } else if (type == YearToMonth.class) { String string = stream.readString(); return (T) (string == null ? null : YearToMonth.valueOf(string)); } else if (type == DayToSecond.class) { String string = stream.readString(); return (T) (string == null ? null : DayToSecond.valueOf(string)); } else if (type == UByte.class) { String string = stream.readString(); return (T) (string == null ? null : UByte.valueOf(string)); } else if (type == UShort.class) { String string = stream.readString(); return (T) (string == null ? null : UShort.valueOf(string)); } else if (type == UInteger.class) { String string = stream.readString(); return (T) (string == null ? null : UInteger.valueOf(string)); } else if (type == ULong.class) { String string = stream.readString(); return (T) (string == null ? null : ULong.valueOf(string)); } // The type byte[] is handled earlier. byte[][] can be handled here else if (type.isArray()) { Array result = stream.readArray(); return (T) (result == null ? null : result.getArray()); } else if (ArrayRecord.class.isAssignableFrom(type)) { return (T) getArrayRecord(configuration, stream.readArray(), (Class<? extends ArrayRecord<?>>) type); } else if (EnumType.class.isAssignableFrom(type)) { return getEnumType(type, stream.readString()); } else if (MasterDataType.class.isAssignableFrom(type)) { return (T) getMasterDataType(type, stream.readObject()); } else if (UDTRecord.class.isAssignableFrom(type)) { return (T) stream.readObject(); } else { return (T) stream.readObject(); } }
@Override public final Class<? extends T> getType() { return type.getType(); }
@Override public final DataType<T> getDataType(Configuration configuration) { return type.getDataType(configuration); }
protected final SQLDataType<T> getSQLDataType() { return type.getSQLDataType(); }