Пример #1
0
 @Override
 public void payment(BigDecimal amountToPay) {
   if (isSpecial && amountToPay.longValueExact() >= 50) {
     System.out.println("You poor, son! Over 50 limit");
     return;
   }
   System.out.println("creditCard : payment" + amountToPay);
   if (amountToPay.longValueExact() >= this.amount.longValueExact()
       && amountToPay.longValueExact()
           <= this.amount.longValueExact() + this.credLimit.longValueExact())
     this.amount = amount.subtract(amountToPay);
   if (amountToPay.longValueExact()
       >= this.amount.longValueExact() + this.credLimit.longValueExact()) {
     this.amount = amount.subtract(amountToPay);
   } else System.out.println("You poor, son!");
 }
Пример #2
0
 @Override
 public long getDecimalValueAsLong() {
   BigDecimal d = getDecimal();
   if (d != null) {
     return d.longValueExact();
   }
   return 0;
 }
Пример #3
0
 private void addMinMaxConstraint(
     final AbstractParam parameter,
     final String name,
     final Class<? extends Annotation> clazz,
     final BigDecimal value,
     final JVar argumentVariable) {
   try {
     final long boundary = value.longValueExact();
     argumentVariable.annotate(clazz).param(DEFAULT_ANNOTATION_PARAMETER, boundary);
   } catch (final ArithmeticException ae) {
     LOGGER.info(
         "Non integer "
             + name
             + " constraint ignored for parameter: "
             + ToStringBuilder.reflectionToString(parameter, SHORT_PREFIX_STYLE));
   }
 }
Пример #4
0
 public LiteralParseNode wholeNumber(String text) {
   int length = text.length();
   // We know it'll fit into long, might still fit into int
   if (length <= PDataType.LONG_PRECISION - 1) {
     long l = Long.parseLong(text);
     if (l <= Integer.MAX_VALUE) {
       // Fits into int
       return new LiteralParseNode((int) l);
     }
     return new LiteralParseNode(l);
   }
   // Might still fit into long
   BigDecimal d = new BigDecimal(text, PDataType.DEFAULT_MATH_CONTEXT);
   if (d.compareTo(MAX_LONG) <= 0) {
     return new LiteralParseNode(d.longValueExact());
   }
   // Doesn't fit into long
   return new LiteralParseNode(d);
 }
Пример #5
0
 /**
  * Returns the long value of this literal.
  *
  * @param exact Whether the value has to be exact. If true, and the literal is a fraction (e.g.
  *     3.14), throws. If false, discards the fractional part of the value.
  * @return Long value of this literal
  */
 public long longValue(boolean exact) {
   switch (typeName) {
     case DECIMAL:
     case DOUBLE:
       BigDecimal bd = (BigDecimal) value;
       if (exact) {
         try {
           return bd.longValueExact();
         } catch (ArithmeticException e) {
           throw SqlUtil.newContextException(
               getParserPosition(), RESOURCE.numberLiteralOutOfRange(bd.toString()));
         }
       } else {
         return bd.longValue();
       }
     default:
       throw Util.unexpected(typeName);
   }
 }
Пример #6
0
  /**
   * Converts a {@link BigDecimal} value into the requested return type if possible.
   *
   * @param value the value
   * @param returnType the class of the returned value; it must be one of {@link BigDecimal}, {@link
   *     Double}, {@link Float}, {@link BigInteger}, {@link Long}, {@link Integer}, {@link Short},
   *     or {@link Byte}
   * @return the converted value
   * @throws IllegalArgumentException if the conversion is not possible or would lead to loss of
   *     data
   * @throws ClassCastException if the return type is not allowed
   */
  protected static <T> T convertDecimal(final BigDecimal value, final Class<T> returnType)
      throws IllegalArgumentException, ClassCastException {

    if (returnType.isAssignableFrom(BigDecimal.class)) {
      return returnType.cast(value);
    } else if (returnType.isAssignableFrom(Double.class)) {
      final double doubleValue = value.doubleValue();
      if (BigDecimal.valueOf(doubleValue).compareTo(value) == 0) {
        return returnType.cast(doubleValue);
      } else {
        throw new IllegalArgumentException();
      }
    } else if (returnType.isAssignableFrom(Float.class)) {
      final Float floatValue = value.floatValue();
      if (BigDecimal.valueOf(floatValue).compareTo(value) == 0) {
        return returnType.cast(floatValue);
      } else {
        throw new IllegalArgumentException();
      }
    } else {
      try {
        if (returnType.isAssignableFrom(BigInteger.class)) {
          return returnType.cast(value.toBigIntegerExact());
        } else if (returnType.isAssignableFrom(Long.class)) {
          return returnType.cast(value.longValueExact());
        } else if (returnType.isAssignableFrom(Integer.class)) {
          return returnType.cast(value.intValueExact());
        } else if (returnType.isAssignableFrom(Short.class)) {
          return returnType.cast(value.shortValueExact());
        } else if (returnType.isAssignableFrom(Byte.class)) {
          return returnType.cast(value.byteValueExact());
        } else {
          throw new ClassCastException("unsupported return type " + returnType.getSimpleName());
        }
      } catch (final ArithmeticException e) {
        throw new IllegalArgumentException(e);
      }
    }
  }
 /**
  * Check whether value represents a whole number
  *
  * @param value
  * @return
  */
 private static boolean isInt(Number value) {
   if (value instanceof Long
       || value instanceof Integer
       || value instanceof Short
       || value instanceof Byte
       || value instanceof BigInteger) {
     return true;
   }
   final BigDecimal bigDecimalValue;
   if (value instanceof Double || value instanceof Float) {
     bigDecimalValue = new BigDecimal(value.toString());
   } else if (value instanceof BigDecimal) {
     bigDecimalValue = (BigDecimal) value;
   } else {
     throw new IllegalArgumentException("Unexpected dataType: " + value.getClass().getName());
   }
   try {
     bigDecimalValue.longValueExact();
     return true;
   } catch (ArithmeticException e) {
     return false;
   }
 }
Пример #8
0
 public static Comparable<?> round(Comparable<?> param, Calendar cal) throws ParseException {
   if (param == null) {
     return null;
   }
   if (param instanceof String) {
     param = parse((String) param);
   }
   if (param instanceof BigDecimal) { // BigInteger is not supported
     BigDecimal b = ((BigDecimal) param).setScale(0, BigDecimal.ROUND_HALF_UP);
     try {
       return b.longValueExact();
     } catch (ArithmeticException e) {
     }
     return b;
   }
   if (param instanceof Double || param instanceof Float) {
     return Math.round(((Number) param).doubleValue());
   }
   if (param instanceof Number) { // Long, Integer, Short, Byte
     return param;
   }
   if (param instanceof Timestamp) {
     Timestamp ts = (Timestamp) param;
     cal.setTimeInMillis(ts.getTime());
     int year = cal.get(YEAR);
     int month = cal.get(MONTH);
     int date = cal.get(DATE);
     int hour = cal.get(HOUR_OF_DAY);
     cal.clear();
     if (hour > 11) {
       date++;
     }
     cal.set(year, month, date);
     return new Timestamp(cal.getTimeInMillis());
   }
   throw new ParseException(WRONG_TYPE + " round(" + param.getClass() + ")");
 }
Пример #9
0
  /**
   * Type converts values to other classes. For example an Integer can be converted to a Long.
   *
   * @param <T> Data Type.
   * @param value The value to be converted.
   * @param to The class to be converted to. Must be one of the Java types corresponding to the
   *     DataTypes.
   * @return The converted value.
   * @throws TypeMismatchException Thrown desired class is incompatible with the source class.
   * @throws OverflowException Thrown only on narrowing value conversions, e.g from a BigInteger to
   *     an Integer.
   */
  @Nullable
  public static <T> T convert(Object value, Class<?> to)
      throws TypeMismatchException, OverflowException {
    final Object result;

    if (value == null || value.getClass() == to) {
      result = value;
    } else {
      final Class<?> from = value.getClass();
      try {
        if (from == Integer.class) { // Integer -> ...
          if (to == Long.class) {
            result = new Long(((Number) value).longValue());
          } else if (to == BigInteger.class) {
            result = BigInteger.valueOf(((Number) value).intValue());
          } else if (to == Float.class) {
            result = new Float(((Number) value).floatValue());
          } else if (to == Double.class) {
            result = new Double(((Number) value).doubleValue());
          } else if (to == BigDecimal.class) {
            // Use intValue() to avoid precision errors
            result = new BigDecimal(((Number) value).intValue());
          } else {
            throw new TypeMismatchException(value.getClass(), to);
          }

        } else if (from == Long.class) { // Long -> ...
          if (to == Integer.class) {
            final long l = ((Long) value).longValue();
            if (l < Integer.MIN_VALUE || l > Integer.MAX_VALUE) {
              throw new OverflowException((Number) value, to);
            }
            result = new Integer((int) l);
          } else if (to == BigInteger.class) {
            result = BigInteger.valueOf(((Number) value).longValue());
          } else if (to == Float.class) {
            result = new Float(((Number) value).floatValue());
          } else if (to == Double.class) {
            result = new Double(((Number) value).doubleValue());
          } else if (to == BigDecimal.class) {
            // Use longValue() to avoid precision errors
            result = new BigDecimal(((Number) value).longValue());
          } else {
            throw new TypeMismatchException(value.getClass(), to);
          }

        } else if (from == BigInteger.class) { // BigInteger -> ...
          final BigInteger bi = (BigInteger) value;
          if (to == Integer.class) {
            result = new Integer(bi.intValueExact());
          } else if (to == Long.class) {
            result = new Long(bi.longValueExact());
          } else if (to == Float.class) {
            final float f1 = bi.floatValue();
            if (f1 == Float.NEGATIVE_INFINITY || f1 == Float.POSITIVE_INFINITY) {
              throw new OverflowException(bi, to);
            }
            result = new Float(f1);
          } else if (to == Double.class) {
            final double d = bi.doubleValue();
            if (d == Double.NEGATIVE_INFINITY || d == Double.POSITIVE_INFINITY) {
              throw new OverflowException(bi, to);
            }
            result = new Double(d);
          } else if (to == BigDecimal.class) {
            result = new BigDecimal(bi);
          } else {
            throw new TypeMismatchException(value.getClass(), to);
          }

        } else if (from == Float.class) { // Float -> ...
          final float fl = ((Float) value).floatValue();
          if (to == Integer.class) {
            if (fl < Integer.MIN_VALUE || fl > Integer.MAX_VALUE | fl % 1 > 0) {
              throw new OverflowException((Number) value, to);
            }
            result = new Integer((int) fl);
          } else if (to == Long.class) {
            if (fl < Long.MIN_VALUE || fl > Long.MAX_VALUE | fl % 1 > 0) {
              throw new OverflowException((Number) value, to);
            }
            result = new Long((long) fl);
          } else if (to == BigInteger.class) {
            if (fl % 1 > 0) {
              throw new OverflowException((Number) value, to);
            }
            final BigDecimal bd = BigDecimal.valueOf(fl);
            result = bd.toBigInteger();
          } else if (to == Double.class) {
            result = new Double(((Number) value).doubleValue());
          } else if (to == BigDecimal.class) {
            result = BigDecimal.valueOf(fl);
          } else {
            throw new TypeMismatchException(value.getClass(), to);
          }

        } else if (from == Double.class) { // Double -> ...
          final double d = ((Double) value).doubleValue();
          if (to == Integer.class) {
            if (d < Integer.MIN_VALUE || d > Integer.MAX_VALUE || d % 1 > 0) {
              throw new OverflowException((Number) value, to);
            }
            result = new Integer((int) d);
          } else if (to == Long.class) { // OK
            if (d < Long.MIN_VALUE || d > Long.MAX_VALUE || d % 1 > 0) {
              throw new OverflowException((Number) value, to);
            }
            result = new Long((int) d);
          } else if (to == BigInteger.class) { // OK
            if (d % 1 > 0) {
              throw new OverflowException((Number) value, to);
            }
            final BigDecimal bd = BigDecimal.valueOf(d);
            result = bd.toBigInteger();
          } else if (to == Float.class) { // OK
            if (d < -Float.MAX_VALUE || d > Float.MAX_VALUE) {
              throw new OverflowException((Number) value, to);
            }
            result = new Float((float) d);
          } else if (to == BigDecimal.class) { // OK
            result = BigDecimal.valueOf(d);
          } else {
            throw new TypeMismatchException(value.getClass(), to);
          }

        } else if (from == BigDecimal.class) { // BigDecimal -> ...
          final BigDecimal bd = (BigDecimal) value;
          if (to == Integer.class) { // OK
            result = new Integer(bd.intValueExact());
          } else if (to == Long.class) { // OK
            result = new Long(bd.longValueExact());
          } else if (to == BigInteger.class) { // OK
            // BigDecimal modulus
            final BigDecimal remainder = bd.remainder(BigDecimal.ONE);
            if (!remainder.equals(BigDecimal.ZERO)) {
              throw new OverflowException(bd, to);
            }
            result = bd.toBigInteger();
          } else if (to == Float.class) { // OK
            if (bd.compareTo(BigDecimal_MIN_FLOAT) < 0 || bd.compareTo(BigDecimal_MAX_FLOAT) > 0) {
              throw new OverflowException(bd, to);
            }
            result = new Float(bd.floatValue());
          } else if (to == Double.class) { // OK
            if (bd.compareTo(BigDecimal_MIN_DOUBLE) < 0
                || bd.compareTo(BigDecimal_MAX_DOUBLE) > 0) {
              throw new OverflowException(bd, to);
            }
            result = new Double(bd.doubleValue());
          } else {
            throw new TypeMismatchException(value.getClass(), to);
          }

        } else {
          throw new UnexpectedException("convert: " + from.getName());
        }
      } catch (final ArithmeticException e) {
        // Thrown by intValueExact() etc.
        throw new OverflowException((Number) value, to);
      }
    }

    @SuppressWarnings("unchecked")
    final T t = (T) result;
    return t;
  }
Пример #10
0
  public static Object parseType(ResultSet result, Integer i, int type)
      throws SQLException, IOException, ParseException {
    logger.trace("i={} type={}", i, type);
    switch (type) {
        /**
         * The JDBC types CHAR, VARCHAR, and LONGVARCHAR are closely related. CHAR represents a
         * small, fixed-length character string, VARCHAR represents a small, variable-length
         * character string, and LONGVARCHAR represents a large, variable-length character string.
         */
      case Types.CHAR:
      case Types.VARCHAR:
      case Types.LONGVARCHAR:
        {
          return result.getString(i);
        }
      case Types.NCHAR:
      case Types.NVARCHAR:
      case Types.LONGNVARCHAR:
        {
          return result.getNString(i);
        }
        /**
         * The JDBC types BINARY, VARBINARY, and LONGVARBINARY are closely related. BINARY
         * represents a small, fixed-length binary value, VARBINARY represents a small,
         * variable-length binary value, and LONGVARBINARY represents a large, variable-length
         * binary value
         */
      case Types.BINARY:
      case Types.VARBINARY:
      case Types.LONGVARBINARY:
        {
          byte[] b = result.getBytes(i);
          return b;
        }
        /**
         * The JDBC type ARRAY represents the SQL3 type ARRAY.
         *
         * <p>An ARRAY value is mapped to an instance of the Array interface in the Java programming
         * language. If a driver follows the standard implementation, an Array object logically
         * points to an ARRAY value on the server rather than containing the elements of the ARRAY
         * object, which can greatly increase efficiency. The Array interface contains methods for
         * materializing the elements of the ARRAY object on the client in the form of either an
         * array or a ResultSet object.
         */
      case Types.ARRAY:
        {
          Array arr = result.getArray(i);
          return arr == null ? null : arr.getArray();
        }
        /**
         * The JDBC type BIGINT represents a 64-bit signed integer value between
         * -9223372036854775808 and 9223372036854775807.
         *
         * <p>The corresponding SQL type BIGINT is a nonstandard extension to SQL. In practice the
         * SQL BIGINT type is not yet currently implemented by any of the major databases, and we
         * recommend that its use be avoided in code that is intended to be portable.
         *
         * <p>The recommended Java mapping for the BIGINT type is as a Java long.
         */
      case Types.BIGINT:
        {
          Object o = result.getLong(i);
          return result.wasNull() ? null : o;
        }
        /**
         * The JDBC type BIT represents a single bit value that can be zero or one.
         *
         * <p>SQL-92 defines an SQL BIT type. However, unlike the JDBC BIT type, this SQL-92 BIT
         * type can be used as a parameterized type to define a fixed-length binary string.
         * Fortunately, SQL-92 also permits the use of the simple non-parameterized BIT type to
         * represent a single binary digit, and this usage corresponds to the JDBC BIT type.
         * Unfortunately, the SQL-92 BIT type is only required in "full" SQL-92 and is currently
         * supported by only a subset of the major databases. Portable code may therefore prefer to
         * use the JDBC SMALLINT type, which is widely supported.
         */
      case Types.BIT:
        {
          try {
            Object o = result.getInt(i);
            return result.wasNull() ? null : o;
          } catch (Exception e) {
            String exceptionClassName = e.getClass().getName();
            // postgresql can not handle boolean, it will throw PSQLException, something like "Bad
            // value for type int : t"
            if ("org.postgresql.util.PSQLException".equals(exceptionClassName)) {
              return "t".equals(result.getString(i));
            }
            throw new IOException(e);
          }
        }
        /**
         * The JDBC type BOOLEAN, which is new in the JDBC 3.0 API, maps to a boolean in the Java
         * programming language. It provides a representation of true and false, and therefore is a
         * better match than the JDBC type BIT, which is either 1 or 0.
         */
      case Types.BOOLEAN:
        {
          return result.getBoolean(i);
        }
        /**
         * The JDBC type BLOB represents an SQL3 BLOB (Binary Large Object).
         *
         * <p>A JDBC BLOB value is mapped to an instance of the Blob interface in the Java
         * programming language. If a driver follows the standard implementation, a Blob object
         * logically points to the BLOB value on the server rather than containing its binary data,
         * greatly improving efficiency. The Blob interface provides methods for materializing the
         * BLOB data on the client when that is desired.
         */
      case Types.BLOB:
        {
          Blob blob = result.getBlob(i);
          if (blob != null) {
            long n = blob.length();
            if (n > Integer.MAX_VALUE) {
              throw new IOException("can't process blob larger than Integer.MAX_VALUE");
            }
            byte[] tab = blob.getBytes(1, (int) n);
            blob.free();
            return tab;
          }
          break;
        }
        /**
         * The JDBC type CLOB represents the SQL3 type CLOB (Character Large Object).
         *
         * <p>A JDBC CLOB value is mapped to an instance of the Clob interface in the Java
         * programming language. If a driver follows the standard implementation, a Clob object
         * logically points to the CLOB value on the server rather than containing its character
         * data, greatly improving efficiency. Two of the methods on the Clob interface materialize
         * the data of a CLOB object on the client.
         */
      case Types.CLOB:
        {
          Clob clob = result.getClob(i);
          if (clob != null) {
            long n = clob.length();
            if (n > Integer.MAX_VALUE) {
              throw new IOException("can't process clob larger than Integer.MAX_VALUE");
            }
            String str = clob.getSubString(1, (int) n);
            clob.free();
            return str;
          }
          break;
        }
      case Types.NCLOB:
        {
          NClob nclob = result.getNClob(i);
          if (nclob != null) {
            long n = nclob.length();
            if (n > Integer.MAX_VALUE) {
              throw new IOException("can't process nclob larger than Integer.MAX_VALUE");
            }
            String str = nclob.getSubString(1, (int) n);
            nclob.free();
            return str;
          }
          break;
        }
        /**
         * The JDBC type DATALINK, new in the JDBC 3.0 API, is a column value that references a file
         * that is outside of a data source but is managed by the data source. It maps to the Java
         * type java.net.URL and provides a way to manage external files. For instance, if the data
         * source is a DBMS, the concurrency controls it enforces on its own data can be applied to
         * the external file as well.
         *
         * <p>A DATALINK value is retrieved from a ResultSet object with the ResultSet methods
         * getURL or getObject. If the Java platform does not support the type of URL returned by
         * getURL or getObject, a DATALINK value can be retrieved as a String object with the method
         * getString.
         *
         * <p>java.net.URL values are stored in a database using the method setURL. If the Java
         * platform does not support the type of URL being set, the method setString can be used
         * instead.
         */
      case Types.DATALINK:
        {
          return result.getURL(i);
        }
        /**
         * The JDBC DATE type represents a date consisting of day, month, and year. The
         * corresponding SQL DATE type is defined in SQL-92, but it is implemented by only a subset
         * of the major databases. Some databases offer alternative SQL types that support similar
         * semantics.
         */
      case Types.DATE:
        {
          try {
            Date d = result.getDate(i, calendar);
            return d != null ? formatDate(d.getTime()) : null;
          } catch (SQLException e) {
            return null;
          }
        }
      case Types.TIME:
        {
          try {
            Time t = result.getTime(i, calendar);
            return t != null ? formatDate(t.getTime()) : null;
          } catch (SQLException e) {
            return null;
          }
        }
      case Types.TIMESTAMP:
        {
          try {
            Timestamp t = result.getTimestamp(i, calendar);
            return t != null ? formatDate(t.getTime()) : null;
          } catch (SQLException e) {
            // java.sql.SQLException: Cannot convert value '0000-00-00 00:00:00' from column ... to
            // TIMESTAMP.
            return null;
          }
        }
        /**
         * The JDBC types DECIMAL and NUMERIC are very similar. They both represent fixed-precision
         * decimal values.
         *
         * <p>The corresponding SQL types DECIMAL and NUMERIC are defined in SQL-92 and are very
         * widely implemented. These SQL types take precision and scale parameters. The precision is
         * the total number of decimal digits supported, and the scale is the number of decimal
         * digits after the decimal point. For most DBMSs, the scale is less than or equal to the
         * precision. So for example, the value "12.345" has a precision of 5 and a scale of 3, and
         * the value ".11" has a precision of 2 and a scale of 2. JDBC requires that all DECIMAL and
         * NUMERIC types support both a precision and a scale of at least 15.
         *
         * <p>The sole distinction between DECIMAL and NUMERIC is that the SQL-92 specification
         * requires that NUMERIC types be represented with exactly the specified precision, whereas
         * for DECIMAL types, it allows an implementation to add additional precision beyond that
         * specified when the type was created. Thus a column created with type NUMERIC(12,4) will
         * always be represented with exactly 12 digits, whereas a column created with type
         * DECIMAL(12,4) might be represented by some larger number of digits.
         *
         * <p>The recommended Java mapping for the DECIMAL and NUMERIC types is
         * java.math.BigDecimal. The java.math.BigDecimal type provides math operations to allow
         * BigDecimal types to be added, subtracted, multiplied, and divided with other BigDecimal
         * types, with integer types, and with floating point types.
         *
         * <p>The method recommended for retrieving DECIMAL and NUMERIC values is
         * ResultSet.getBigDecimal. JDBC also allows access to these SQL types as simple Strings or
         * arrays of char. Thus, Java programmers can use getString to receive a DECIMAL or NUMERIC
         * result. However, this makes the common case where DECIMAL or NUMERIC are used for
         * currency values rather awkward, since it means that application writers have to perform
         * math on strings. It is also possible to retrieve these SQL types as any of the Java
         * numeric types.
         */
      case Types.DECIMAL:
      case Types.NUMERIC:
        {
          BigDecimal bd = null;
          try {
            // getBigDecimal() should get obsolete. Most seem to use getString/getObject anyway...
            bd = result.getBigDecimal(i);
          } catch (NullPointerException e) {
            // But is it true? JDBC NPE exists since 13 years?
            // http://forums.codeguru.com/archive/index.php/t-32443.html
            // Null values are driving us nuts in JDBC:
            // http://stackoverflow.com/questions/2777214/when-accessing-resultsets-in-jdbc-is-there-an-elegant-way-to-distinguish-betwee
          }
          if (bd == null || result.wasNull()) {
            return null;
          }
          int scale = 2;
          if (scale >= 0) {
            bd = bd.setScale(scale, BigDecimal.ROUND_UP);
            try {
              long l = bd.longValueExact();
              if (Long.toString(l).equals(result.getString(i))) {
                // convert to long if possible
                return l;
              } else {
                // convert to double (with precision loss)
                return bd.doubleValue();
              }
            } catch (ArithmeticException e) {
              return bd.doubleValue();
            }
          } else {
            return bd.toPlainString();
          }
        }
        /**
         * The JDBC type DOUBLE represents a "double precision" floating point number that supports
         * 15 digits of mantissa.
         *
         * <p>The corresponding SQL type is DOUBLE PRECISION, which is defined in SQL-92 and is
         * widely supported by the major databases. The SQL-92 standard leaves the precision of
         * DOUBLE PRECISION up to the implementation, but in practice all the major databases
         * supporting DOUBLE PRECISION support a mantissa precision of at least 15 digits.
         *
         * <p>The recommended Java mapping for the DOUBLE type is as a Java double.
         */
      case Types.DOUBLE:
        {
          String s = result.getString(i);
          if (result.wasNull() || s == null) {
            return null;
          }
          NumberFormat format = NumberFormat.getInstance(locale);
          Number number = format.parse(s);
          return number.doubleValue();
        }
        /**
         * The JDBC type FLOAT is basically equivalent to the JDBC type DOUBLE. We provided both
         * FLOAT and DOUBLE in a possibly misguided attempt at consistency with previous database
         * APIs. FLOAT represents a "double precision" floating point number that supports 15 digits
         * of mantissa.
         *
         * <p>The corresponding SQL type FLOAT is defined in SQL-92. The SQL-92 standard leaves the
         * precision of FLOAT up to the implementation, but in practice all the major databases
         * supporting FLOAT support a mantissa precision of at least 15 digits.
         *
         * <p>The recommended Java mapping for the FLOAT type is as a Java double. However, because
         * of the potential confusion between the double precision SQL FLOAT and the single
         * precision Java float, we recommend that JDBC programmers should normally use the JDBC
         * DOUBLE type in preference to FLOAT.
         */
      case Types.FLOAT:
        {
          String s = result.getString(i);
          if (result.wasNull() || s == null) {
            return null;
          }
          NumberFormat format = NumberFormat.getInstance(locale);
          Number number = format.parse(s);
          return number.doubleValue();
        }
        /**
         * The JDBC type JAVA_OBJECT, added in the JDBC 2.0 core API, makes it easier to use objects
         * in the Java programming language as values in a database. JAVA_OBJECT is simply a type
         * code for an instance of a class defined in the Java programming language that is stored
         * as a database object. The type JAVA_OBJECT is used by a database whose type system has
         * been extended so that it can store Java objects directly. The JAVA_OBJECT value may be
         * stored as a serialized Java object, or it may be stored in some vendor-specific format.
         *
         * <p>The type JAVA_OBJECT is one of the possible values for the column DATA_TYPE in the
         * ResultSet objects returned by various DatabaseMetaData methods, including getTypeInfo,
         * getColumns, and getUDTs. The method getUDTs, part of the new JDBC 2.0 core API, will
         * return information about the Java objects contained in a particular schema when it is
         * given the appropriate parameters. Having this information available facilitates using a
         * Java class as a database type.
         */
      case Types.OTHER:
      case Types.JAVA_OBJECT:
        {
          return result.getObject(i);
        }
        /**
         * The JDBC type REAL represents a "single precision" floating point number that supports
         * seven digits of mantissa.
         *
         * <p>The corresponding SQL type REAL is defined in SQL-92 and is widely, though not
         * universally, supported by the major databases. The SQL-92 standard leaves the precision
         * of REAL up to the implementation, but in practice all the major databases supporting REAL
         * support a mantissa precision of at least seven digits.
         *
         * <p>The recommended Java mapping for the REAL type is as a Java float.
         */
      case Types.REAL:
        {
          String s = result.getString(i);
          if (result.wasNull() || s == null) {
            return null;
          }
          NumberFormat format = NumberFormat.getInstance(locale);
          Number number = format.parse(s);
          return number.doubleValue();
        }
        /**
         * The JDBC type TINYINT represents an 8-bit integer value between 0 and 255 that may be
         * signed or unsigned.
         *
         * <p>The corresponding SQL type, TINYINT, is currently supported by only a subset of the
         * major databases. Portable code may therefore prefer to use the JDBC SMALLINT type, which
         * is widely supported.
         *
         * <p>The recommended Java mapping for the JDBC TINYINT type is as either a Java byte or a
         * Java short. The 8-bit Java byte type represents a signed value from -128 to 127, so it
         * may not always be appropriate for larger TINYINT values, whereas the 16-bit Java short
         * will always be able to hold all TINYINT values.
         */
        /**
         * The JDBC type SMALLINT represents a 16-bit signed integer value between -32768 and 32767.
         *
         * <p>The corresponding SQL type, SMALLINT, is defined in SQL-92 and is supported by all the
         * major databases. The SQL-92 standard leaves the precision of SMALLINT up to the
         * implementation, but in practice, all the major databases support at least 16 bits.
         *
         * <p>The recommended Java mapping for the JDBC SMALLINT type is as a Java short.
         */
        /**
         * The JDBC type INTEGER represents a 32-bit signed integer value ranging between
         * -2147483648 and 2147483647.
         *
         * <p>The corresponding SQL type, INTEGER, is defined in SQL-92 and is widely supported by
         * all the major databases. The SQL-92 standard leaves the precision of INTEGER up to the
         * implementation, but in practice all the major databases support at least 32 bits.
         *
         * <p>The recommended Java mapping for the INTEGER type is as a Java int.
         */
      case Types.TINYINT:
      case Types.SMALLINT:
      case Types.INTEGER:
        {
          try {
            Integer integer = result.getInt(i);
            return result.wasNull() ? null : integer;
          } catch (SQLDataException e) {
            Long l = result.getLong(i);
            return result.wasNull() ? null : l;
          }
        }

      case Types.SQLXML:
        {
          SQLXML xml = result.getSQLXML(i);
          return xml != null ? xml.getString() : null;
        }

      case Types.NULL:
        {
          return null;
        }
        /**
         * The JDBC type DISTINCT field (Types class)>DISTINCT represents the SQL3 type DISTINCT.
         *
         * <p>The standard mapping for a DISTINCT type is to the Java type to which the base type of
         * a DISTINCT object would be mapped. For example, a DISTINCT type based on a CHAR would be
         * mapped to a String object, and a DISTINCT type based on an SQL INTEGER would be mapped to
         * an int.
         *
         * <p>The DISTINCT type may optionally have a custom mapping to a class in the Java
         * programming language. A custom mapping consists of a class that implements the interface
         * SQLData and an entry in a java.util.Map object.
         */
      case Types.DISTINCT:
        {
          logger.warn("JDBC type not implemented: {}", type);
          return null;
        }
        /**
         * The JDBC type STRUCT represents the SQL99 structured type. An SQL structured type, which
         * is defined by a user with a CREATE TYPE statement, consists of one or more attributes.
         * These attributes may be any SQL data type, built-in or user-defined.
         *
         * <p>The standard mapping for the SQL type STRUCT is to a Struct object in the Java
         * programming language. A Struct object contains a value for each attribute of the STRUCT
         * value it represents.
         *
         * <p>A STRUCT value may optionally be custom mapped to a class in the Java programming
         * language, and each attribute in the STRUCT may be mapped to a field in the class. A
         * custom mapping consists of a class that implements the interface SQLData and an entry in
         * a java.util.Map object.
         */
      case Types.STRUCT:
        {
          logger.warn("JDBC type not implemented: {}", type);
          return null;
        }
      case Types.REF:
        {
          logger.warn("JDBC type not implemented: {}", type);
          return null;
        }
      case Types.ROWID:
        {
          logger.warn("JDBC type not implemented: {}", type);
          return null;
        }
      default:
        {
          logger.warn("unknown JDBC type ignored: {}", type);
          return null;
        }
    }
    return null;
  }