From 6d4554c2fd61d8cec15232bd8b508406a09a80e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9gory=20Mantelet?= <gregory.mantelet@astro.unistra.fr> Date: Wed, 6 Mar 2019 18:28:32 +0100 Subject: [PATCH] [TAP] Improve support of BigDecimal and BigInteger while formatting a DB result. _This commit fixes the GitHub issue #97 ._ --- src/tap/data/ResultSetTableIterator.java | 48 +++++++++++++++++++----- 1 file changed, 39 insertions(+), 9 deletions(-) diff --git a/src/tap/data/ResultSetTableIterator.java b/src/tap/data/ResultSetTableIterator.java index 61867cb..0dc3012 100644 --- a/src/tap/data/ResultSetTableIterator.java +++ b/src/tap/data/ResultSetTableIterator.java @@ -16,7 +16,8 @@ package tap.data; * You should have received a copy of the GNU Lesser General Public License * along with TAPLibrary. If not, see <http://www.gnu.org/licenses/>. * - * Copyright 2014-2017 - Astronomisches Rechen Institut (ARI) + * Copyright 2014-2019 - Astronomisches Rechen Institut (ARI), + * UDS/Centre de DonnĂ©es astronomiques de Strasbourg (CDS) */ import java.math.BigDecimal; @@ -47,8 +48,8 @@ import uws.ISO8601Format; * {@link #getColType()} will return a TAP type based on the one declared in the {@link ResultSetMetaData} object. * </i></p> * - * @author Grégory Mantelet (ARI) - * @version 2.1 (07/2017) + * @author Grégory Mantelet (ARI;CDS) + * @version 2.3 (03/2019) * @since 2.0 */ public class ResultSetTableIterator implements TableIterator { @@ -716,32 +717,59 @@ public class ResultSetTableIterator implements TableIterator { protected Object formatColValue(Object colValue) throws DataReadException{ if (colValue != null){ DBType colType = getColType(); + // if the column value is a java.sql.Time object, format it into an ISO8601 time (i.e. with the format: HH:mm:ss): if (colValue instanceof java.sql.Time) colValue = timeFormat.format((java.sql.Time)colValue); + // if the column value is a java.sql.Date object, format it into an ISO8601 date (i.e. with the format: yyyy-MM-dd): else if (colValue instanceof java.sql.Date) colValue = dateFormat.format((java.sql.Date)colValue); + // if the column value is a Timestamp (or java.util.Date) object, format it into an ISO8601 date-time: // note: java.sql.Timestamp extends java.util.Date. That's why the next condition also works for java.sql.Timestamp. else if (colValue instanceof java.util.Date) colValue = ISO8601Format.format((java.util.Date)colValue); - // if the type is a BigDecimal object (this is possible for instance with PostgreSQL "numeric" datatype, + + // if the type is a BigDecimal object (this is possible for instance with PostgreSQL "numeric" datatype or Sybase IQ, // but this type can not be supported in FITS and VOTable): - else if (colValue instanceof BigDecimal) - colValue = ((BigDecimal)colValue).doubleValue(); + else if (colValue instanceof BigDecimal){ + BigDecimal bd = (BigDecimal)colValue; + if (colType.type == DBDatatype.BIGINT) + colValue = bd.longValue(); + else if (colType.type == DBDatatype.INTEGER) + colValue = bd.intValue(); + else if (colType.type == DBDatatype.SMALLINT) + colValue = bd.shortValue(); + else if (colType.type == DBDatatype.REAL) + colValue = bd.floatValue(); + else + colValue = bd.doubleValue(); + } + // if the type is a BigInteger object (as BigDecimal, this type can not be supported in FITS and VOTable): - else if (colValue instanceof BigInteger) - colValue = ((BigInteger)colValue).longValue(); + else if (colValue instanceof BigInteger){ + BigInteger bi = (BigInteger)colValue; + if (colType.type == DBDatatype.INTEGER) + colValue = bi.intValue(); + else if (colType.type == DBDatatype.SMALLINT) + colValue = bi.shortValue(); + else + colValue = bi.longValue(); + } + // if the type is Integer but it is declared as a SMALLINT cast the value (absolutely required for the FITS format): else if (colValue instanceof Integer && colType != null && colValue != null && colType.type == DBDatatype.SMALLINT) colValue = new Short(((Integer)colValue).shortValue()); + // if the column value is a Boolean object, format it as a SMALLINT: else if (colValue instanceof Boolean) colValue = ((Boolean)colValue) ? new Short((short)1) : new Short((short)0); + // if the column should be only a character: else if (colType != null && colValue != null && colType.type == DBDatatype.CHAR && (colType.length == 1 || colType.length <= 0) && colValue instanceof String) colValue = ((String)colValue).charAt(0); + // if the column value is a geometrical object, it must be serialized in STC-S: else if (translator != null && colType != null && colType.isGeometry()){ try{ @@ -753,6 +781,7 @@ public class ResultSetTableIterator implements TableIterator { } } } + return colValue; } @@ -858,7 +887,8 @@ public class ResultSetTableIterator implements TableIterator { if (params != null && params.length > 0){ try{ lengthParam = Integer.parseInt(params[0]); - }catch(NumberFormatException nfe){} + }catch(NumberFormatException nfe){ + } } // CASE: SQLITE -- GitLab