All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.debezium.connector.db2.Db2ValueConverters Maven / Gradle / Ivy

There is a newer version: 3.0.0.CR1
Show newest version
/*
 * Copyright Debezium Authors.
 *
 * Licensed under the Apache Software License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0
 */
package io.debezium.connector.db2;

import java.math.BigDecimal;
import java.sql.Types;
import java.time.ZoneOffset;

import org.apache.kafka.connect.data.Field;
import org.apache.kafka.connect.data.SchemaBuilder;

import io.debezium.data.SpecialValueDecimal;
import io.debezium.data.VariableScaleDecimal;
import io.debezium.jdbc.JdbcValueConverters;
import io.debezium.jdbc.JdbcValueConverters.DecimalMode;
import io.debezium.jdbc.TemporalPrecisionMode;
import io.debezium.relational.Column;
import io.debezium.relational.ValueConverter;

/**
 * Conversion of DB2 specific datatypes.
 *
 * @author Jiri Pechanec, Peter Urbanetz
 *
 */
public class Db2ValueConverters extends JdbcValueConverters {

    public Db2ValueConverters() {
    }

    /**
     * Create a new instance that always uses UTC for the default time zone when
     * converting values without timezone information to values that require
     * timezones.
     * 

* * @param decimalMode * how {@code DECIMAL} and {@code NUMERIC} values should be * treated; may be null if * {@link io.debezium.jdbc.JdbcValueConverters.DecimalMode#PRECISE} * is to be used * @param temporalPrecisionMode * date/time value will be represented either as Connect datatypes or Debezium specific datatypes */ public Db2ValueConverters(DecimalMode decimalMode, TemporalPrecisionMode temporalPrecisionMode) { super(decimalMode, temporalPrecisionMode, ZoneOffset.UTC, null, null, null); } @Override public SchemaBuilder schemaBuilder(Column column) { switch (column.jdbcType()) { // Numeric integers case Types.TINYINT: // values are an 8-bit unsigned integer value between 0 and 255, we thus need to store it in short int return SchemaBuilder.int16(); case Types.OTHER: if (matches(column.typeName().toUpperCase(), "DECFLOAT")) { return decfloatSchema(column); } default: return super.schemaBuilder(column); } } @Override public ValueConverter converter(Column column, Field fieldDefn) { switch (column.jdbcType()) { // Numeric integers case Types.TINYINT: // values are an 8-bit unsigned integer value between 0 and 255, we thus need to store it in short int return (data) -> convertSmallInt(column, fieldDefn, data); case Types.OTHER: if (matches(column.typeName().toUpperCase(), "DECFLOAT")) { return (data) -> convertDecfloat(column, fieldDefn, data, decimalMode); } default: return super.converter(column, fieldDefn); } } protected Object convertDecfloat(Column column, Field fieldDefn, Object data, DecimalMode mode) { SpecialValueDecimal value; BigDecimal newDecimal; if (data instanceof SpecialValueDecimal) { value = (SpecialValueDecimal) data; if (value.getDecimalValue().isEmpty()) { return SpecialValueDecimal.fromLogical(value, mode, column.name()); } } else { final Object o = toBigDecimal(column, fieldDefn, data); if (!(o instanceof BigDecimal)) { return o; } value = new SpecialValueDecimal((BigDecimal) o); } newDecimal = withScaleAdjustedIfNeeded(column, value.getDecimalValue().get()); if (mode == DecimalMode.PRECISE) { newDecimal = newDecimal.stripTrailingZeros(); if (newDecimal.scale() < 0) { newDecimal = newDecimal.setScale(0); } return VariableScaleDecimal.fromLogical(fieldDefn.schema(), new SpecialValueDecimal(newDecimal)); } return SpecialValueDecimal.fromLogical(new SpecialValueDecimal(newDecimal), mode, column.name()); } /** * Time precision in DB2 is defined in scale, the default one is 7 */ @Override protected int getTimePrecision(Column column) { return column.scale().get(); } protected Object convertTimestampWithZone(Column column, Field fieldDefn, Object data) { // dummy return return super.convertTimestampWithZone(column, fieldDefn, data); } /** * Determine if the uppercase form of a column's type exactly matches or begins with the specified prefix. * Note that this logic works when the column's {@link Column#typeName() type} contains the type name followed by parentheses. * * @param upperCaseTypeName the upper case form of the column's {@link Column#typeName() type name} * @param upperCaseMatch the upper case form of the expected type or prefix of the type; may not be null * @return {@code true} if the type matches the specified type, or {@code false} otherwise */ protected static boolean matches(String upperCaseTypeName, String upperCaseMatch) { if (upperCaseTypeName == null) { return false; } return upperCaseMatch.equals(upperCaseTypeName) || upperCaseTypeName.startsWith(upperCaseMatch + "("); } private SchemaBuilder decfloatSchema(Column column) { if (decimalMode == DecimalMode.PRECISE) { return VariableScaleDecimal.builder(); } return SpecialValueDecimal.builder(decimalMode, column.length(), column.scale().orElse(0)); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy