protected TInstance typeForSQLType( TypeId typeId, DataTypeDescriptor sqlType, int defaultCharsetId, int defaultCollationId, String schemaName, String tableName, String columnName) { switch (typeId.getTypeFormatId()) { /* No attribute types. */ case TypeId.FormatIds.TINYINT_TYPE_ID: return typeForJDBCType( Types.TINYINT, sqlType.isNullable(), schemaName, tableName, columnName); case TypeId.FormatIds.SMALLINT_TYPE_ID: return typeForJDBCType( Types.SMALLINT, sqlType.isNullable(), schemaName, tableName, columnName); case TypeId.FormatIds.MEDIUMINT_ID: case TypeId.FormatIds.INT_TYPE_ID: return typeForJDBCType( Types.INTEGER, sqlType.isNullable(), schemaName, tableName, columnName); case TypeId.FormatIds.LONGINT_TYPE_ID: return typeForJDBCType( Types.BIGINT, sqlType.isNullable(), schemaName, tableName, columnName); case TypeId.FormatIds.DATE_TYPE_ID: return typeForJDBCType(Types.DATE, sqlType.isNullable(), schemaName, tableName, columnName); case TypeId.FormatIds.TIME_TYPE_ID: return typeForJDBCType(Types.TIME, sqlType.isNullable(), schemaName, tableName, columnName); case TypeId.FormatIds.TIMESTAMP_TYPE_ID: return typeForJDBCType( Types.TIMESTAMP, sqlType.isNullable(), schemaName, tableName, columnName); case TypeId.FormatIds.REAL_TYPE_ID: return typeForJDBCType(Types.REAL, sqlType.isNullable(), schemaName, tableName, columnName); case TypeId.FormatIds.DOUBLE_TYPE_ID: return typeForJDBCType( Types.DOUBLE, sqlType.isNullable(), schemaName, tableName, columnName); case TypeId.FormatIds.BLOB_TYPE_ID: return typeForJDBCType( Types.LONGVARBINARY, sqlType.isNullable(), // TODO: Types.BLOB schemaName, tableName, columnName); /* Width attribute types. */ case TypeId.FormatIds.BIT_TYPE_ID: return typeForJDBCType( Types.BIT, sqlType.getMaximumWidth(), sqlType.isNullable(), schemaName, tableName, columnName); case TypeId.FormatIds.VARBIT_TYPE_ID: return typeForJDBCType( Types.VARBINARY, sqlType.getMaximumWidth(), sqlType.isNullable(), schemaName, tableName, columnName); case TypeId.FormatIds.LONGVARBIT_TYPE_ID: return typeForJDBCType( Types.LONGVARBINARY, sqlType.isNullable(), schemaName, tableName, columnName); /* Precision, scale attribute types. */ case TypeId.FormatIds.DECIMAL_TYPE_ID: return typeForJDBCType( Types.DECIMAL, sqlType.getPrecision(), sqlType.getScale(), sqlType.isNullable(), schemaName, tableName, columnName); case TypeId.FormatIds.NUMERIC_TYPE_ID: return typeForJDBCType( Types.NUMERIC, sqlType.getPrecision(), sqlType.getScale(), sqlType.isNullable(), schemaName, tableName, columnName); /* String (charset, collation) attribute types. */ case TypeId.FormatIds.CHAR_TYPE_ID: return typeForStringType( Types.CHAR, sqlType, defaultCharsetId, defaultCollationId, schemaName, tableName, columnName); case TypeId.FormatIds.VARCHAR_TYPE_ID: return typeForStringType( Types.VARCHAR, sqlType, defaultCharsetId, defaultCollationId, schemaName, tableName, columnName); case TypeId.FormatIds.LONGVARCHAR_TYPE_ID: return typeForStringType( Types.LONGVARCHAR, sqlType, defaultCharsetId, defaultCollationId, schemaName, tableName, columnName); case TypeId.FormatIds.CLOB_TYPE_ID: return typeForStringType( Types.LONGVARCHAR, sqlType, // TODO: Types.CLOB defaultCharsetId, defaultCollationId, schemaName, tableName, columnName); case TypeId.FormatIds.XML_TYPE_ID: return typeForStringType( Types.SQLXML, sqlType, defaultCharsetId, defaultCollationId, schemaName, tableName, columnName); /* Special case AkSQL types. */ case TypeId.FormatIds.BOOLEAN_TYPE_ID: return AkBool.INSTANCE.instance(sqlType.isNullable()); case TypeId.FormatIds.INTERVAL_DAY_SECOND_ID: return AkInterval.SECONDS.typeFrom(sqlType); case TypeId.FormatIds.INTERVAL_YEAR_MONTH_ID: return AkInterval.MONTHS.typeFrom(sqlType); case TypeId.FormatIds.ROW_MULTISET_TYPE_ID_IMPL: { TypeId.RowMultiSetTypeId rmsTypeId = (TypeId.RowMultiSetTypeId) typeId; String[] columnNames = rmsTypeId.getColumnNames(); DataTypeDescriptor[] columnTypes = rmsTypeId.getColumnTypes(); List<AkResultSet.Column> columns = new ArrayList<>(columnNames.length); for (int i = 0; i < columnNames.length; i++) { columns.add(new AkResultSet.Column(columnNames[i], typeForSQLType(columnTypes[i]))); } return AkResultSet.INSTANCE.instance(columns); } case TypeId.FormatIds.GUID_TYPE_ID: return AkGUID.INSTANCE.instance(sqlType.isNullable()); case TypeId.FormatIds.USERDEFINED_TYPE_ID: { String name = typeId.getSQLTypeName(); TClass tclass = typeClassForUserDefined(name); return tclass.instance(sqlType.isNullable()); } default: if (columnName != null) { throw new UnsupportedColumnDataTypeException( schemaName, tableName, columnName, sqlType.toString()); } else { throw new UnsupportedDataTypeException(sqlType.toString()); } } }
/** * Creates a Value from the given object, deriving the type from the object. * * @throws java.lang.UnsupportedOperationException if the type cannot be inferred */ public static Value fromObject(Object object) { final TInstance type; Value value = null; if (object == null) { value = new Value(null); value.putNull(); } else if (object instanceof String) { String s = (String) object; type = MString.VARCHAR.instance( s.length(), StringFactory.DEFAULT_CHARSET.ordinal(), StringFactory.NULL_COLLATION_ID, false); value = new Value(type, s); } else if (object instanceof Long) { type = MNumeric.BIGINT.instance(false); value = new Value(type, (Long) object); } else if (object instanceof Integer) { type = MNumeric.INT.instance(false); value = new Value(type, (Integer) object); } else if (object instanceof Double) { type = MApproximateNumber.DOUBLE.instance(false); value = new Value(type, (Double) object); } else if (object instanceof Float) { type = MApproximateNumber.FLOAT.instance(false); value = new Value(type, (Float) object); } else if (object instanceof BigDecimalWrapper) { BigDecimalWrapper bdw = (BigDecimalWrapper) object; type = MNumeric.DECIMAL.instance(bdw.getPrecision(), bdw.getScale(), false); value = new Value(type); value.putObject(bdw); } else if (object instanceof BigDecimal) { BigDecimal bd = (BigDecimal) object; type = MNumeric.DECIMAL.instance( BigDecimalWrapperImpl.sqlPrecision(bd), BigDecimalWrapperImpl.sqlScale(bd), false); value = new Value(type); value.putObject(new BigDecimalWrapperImpl(bd)); } else if (object instanceof ByteSource || object instanceof byte[]) { byte[] bytes; if (object instanceof byte[]) { bytes = (byte[]) object; } else { ByteSource source = (ByteSource) object; byte[] srcArray = source.byteArray(); int offset = source.byteArrayOffset(); int end = offset + source.byteArrayLength(); bytes = Arrays.copyOfRange(srcArray, offset, end); } type = MBinary.VARBINARY.instance(bytes.length, false); value = new Value(type, bytes); } else if (object instanceof BigInteger) { type = MNumeric.BIGINT_UNSIGNED.instance(false); BigInteger bi = (BigInteger) object; value = new Value(type, bi.longValue()); } else if (object instanceof Boolean) { type = AkBool.INSTANCE.instance(false); value = new Value(type, (Boolean) object); } else if (object instanceof Character) { type = MString.VARCHAR.instance(1, false); value = new Value(type, object.toString()); } else if (object instanceof Short) { type = MNumeric.SMALLINT.instance(false); value = new Value(type, (Short) object); } else if (object instanceof Byte) { type = MNumeric.TINYINT.instance(false); value = new Value(type, (Byte) object); } else if (object instanceof UUID) { type = AkGUID.INSTANCE.instance(false); value = new Value(type); value.putObject(object); } else if (object instanceof BlobRef) { type = AkBlob.INSTANCE.instance(false); value = new Value(type); value.putObject(type); } else { throw new UnsupportedOperationException( "can't convert " + object + " of type " + object.getClass()); } return value; }