private void internalAddrow()

in src/main/java/com/microsoft/sqlserver/jdbc/SQLServerDataTable.java [157:308]


    private void internalAddrow(JDBCType jdbcType, Object val, Object[] rowValues,
            Map.Entry<Integer, SQLServerDataColumn> pair) throws SQLServerException {
        int key = pair.getKey();

        if (null != val) {
            SQLServerDataColumn currentColumnMetadata = pair.getValue();
            int nValueLen;

            switch (jdbcType) {
                case BIGINT:
                    rowValues[key] = (val instanceof Long) ? val : Long.parseLong(val.toString());
                    break;

                case BIT:
                    if (val instanceof Boolean) {
                        rowValues[key] = val;
                    } else {
                        String valString = val.toString();

                        if ("0".equals(valString) || valString.equalsIgnoreCase(Boolean.FALSE.toString())) {
                            rowValues[key] = Boolean.FALSE;
                        } else if ("1".equals(valString) || valString.equalsIgnoreCase(Boolean.TRUE.toString())) {
                            rowValues[key] = Boolean.TRUE;
                        } else {
                            MessageFormat form = new MessageFormat(
                                    SQLServerException.getErrString("R_TVPInvalidColumnValue"));
                            Object[] msgArgs = {jdbcType};
                            throw new SQLServerException(null, form.format(msgArgs), null, 0, false);
                        }
                    }
                    break;

                case INTEGER:
                    rowValues[key] = (val instanceof Integer) ? val : Integer.parseInt(val.toString());
                    break;

                case SMALLINT:
                case TINYINT:
                    rowValues[key] = (val instanceof Short) ? val : Short.parseShort(val.toString());
                    break;

                case DECIMAL:
                case NUMERIC:
                    BigDecimal bd = null;
                    boolean isColumnMetadataUpdated = false;
                    bd = new BigDecimal(val.toString());
                    // BigDecimal#precision returns number of digits in the unscaled value.
                    // Say, for value 0.01, it returns 1 but the precision should be 3 for SQLServer
                    int precision = Util.getValueLengthBaseOnJavaType(bd, JavaType.of(bd), null, null, jdbcType);
                    if (bd.scale() > currentColumnMetadata.scale) {
                        currentColumnMetadata.scale = bd.scale();
                        isColumnMetadataUpdated = true;
                    }
                    if (precision > currentColumnMetadata.precision) {
                        currentColumnMetadata.precision = precision;
                        isColumnMetadataUpdated = true;
                    }

                    // precision equal: the maximum number of digits in integer part + the maximum scale
                    int numberOfDigitsIntegerPart = precision - bd.scale();
                    if (numberOfDigitsIntegerPart > currentColumnMetadata.numberOfDigitsIntegerPart) {
                        currentColumnMetadata.numberOfDigitsIntegerPart = numberOfDigitsIntegerPart;
                        isColumnMetadataUpdated = true;
                    }

                    if (isColumnMetadataUpdated) {
                        currentColumnMetadata.precision = currentColumnMetadata.scale
                                + currentColumnMetadata.numberOfDigitsIntegerPart;
                        columnMetadata.put(pair.getKey(), currentColumnMetadata);
                    }
                    rowValues[key] = bd;
                    break;

                case DOUBLE:
                    rowValues[key] = (val instanceof Double) ? val : Double.parseDouble(val.toString());
                    break;

                case FLOAT:
                case REAL:
                    rowValues[key] = (val instanceof Float) ? val : Float.parseFloat(val.toString());
                    break;

                case TIMESTAMP_WITH_TIMEZONE:
                case TIME_WITH_TIMEZONE:
                case DATE:
                case TIME:
                case TIMESTAMP:
                case DATETIMEOFFSET:
                case DATETIME:
                case SMALLDATETIME:
                    // Sending temporal types as string. Error from database is thrown if parsing fails
                    // no need to send precision for temporal types, string literal will never exceed
                    // DataTypes.SHORT_VARTYPE_MAX_BYTES

                    // java.sql.Date, java.sql.Time and java.sql.Timestamp are subclass of java.util.Date
                    if (val instanceof java.util.Date || val instanceof microsoft.sql.DateTimeOffset
                            || val instanceof OffsetDateTime || val instanceof OffsetTime)
                        rowValues[key] = val.toString();
                    else
                        rowValues[key] = val;
                    break;

                case BINARY:
                case VARBINARY:
                case LONGVARBINARY:
                    nValueLen = ((byte[]) val).length;

                    if (nValueLen > currentColumnMetadata.precision) {
                        currentColumnMetadata.precision = nValueLen;
                        columnMetadata.put(pair.getKey(), currentColumnMetadata);
                    }
                    rowValues[key] = val;
                    break;

                case CHAR:
                case VARCHAR:
                case NCHAR:
                case NVARCHAR:
                case LONGVARCHAR:
                case LONGNVARCHAR:
                case SQLXML:
                    if (val instanceof UUID)
                        val = val.toString();
                    nValueLen = (2 * ((String) val).length());

                    if (nValueLen > currentColumnMetadata.precision) {
                        currentColumnMetadata.precision = nValueLen;
                        columnMetadata.put(pair.getKey(), currentColumnMetadata);
                    }
                    rowValues[key] = val;
                    break;

                case SQL_VARIANT:
                    JDBCType internalJDBCType;
                    JavaType javaType = JavaType.of(val);
                    internalJDBCType = javaType.getJDBCType(SSType.UNKNOWN, jdbcType);
                    internalAddrow(internalJDBCType, val, rowValues, pair);
                    break;

                default:
                    MessageFormat form = new MessageFormat(SQLServerException.getErrString("R_unsupportedDataTypeTVP"));
                    Object[] msgArgs = {jdbcType};
                    throw new SQLServerException(null, form.format(msgArgs), null, 0, false);
            }
        } else {
            rowValues[key] = null;
            if (jdbcType == JDBCType.SQL_VARIANT) {
                throw new SQLServerException(SQLServerException.getErrString("R_invalidValueForTVPWithSQLVariant"),
                        null);
            }
        }
    }