From c0de704faa7eea6540fc52b5640f4dafc0ae8be0 Mon Sep 17 00:00:00 2001 From: Grant Fitzsimmons <37256050+grantfitzsimmons@users.noreply.github.com> Date: Mon, 27 Oct 2025 13:23:57 -0500 Subject: [PATCH] Improve handling of numeric SQL types and BigDecimal conversion Added support for NUMERIC and DECIMAL SQL types in `BasicSQLUtils`, ensuring proper conversion from various data types. In `GenericDBConversion`, introduced a helper method to safely convert objects to BigDecimal and updated relevant code to use it, improving robustness and error handling. Also added logic to set nulls for specific field patterns during DB conversion. Co-Authored-By: Gitesh Sagvekar --- .../brc/specify/conversion/BasicSQLUtils.java | 10 +++- .../conversion/GenericDBConversion.java | 54 +++++++++++++++++-- 2 files changed, 59 insertions(+), 5 deletions(-) diff --git a/src/edu/ku/brc/specify/conversion/BasicSQLUtils.java b/src/edu/ku/brc/specify/conversion/BasicSQLUtils.java index 32a9441e4..3fe29968f 100644 --- a/src/edu/ku/brc/specify/conversion/BasicSQLUtils.java +++ b/src/edu/ku/brc/specify/conversion/BasicSQLUtils.java @@ -1792,12 +1792,20 @@ public static void setData(final PreparedStatement pStmt, final int type, final case java.sql.Types.REAL: case java.sql.Types.DOUBLE: + case java.sql.Types.NUMERIC: + case java.sql.Types.DECIMAL: if (isStr) { pStmt.setString(colInx, (String)data); } else { - pStmt.setDouble(colInx, (Double)data); + if (data instanceof Number) + { + pStmt.setDouble(colInx, ((Number)data).doubleValue()); + } else + { + pStmt.setDouble(colInx, Double.parseDouble(data.toString())); + } } break; diff --git a/src/edu/ku/brc/specify/conversion/GenericDBConversion.java b/src/edu/ku/brc/specify/conversion/GenericDBConversion.java index 33296d594..71c3750d2 100644 --- a/src/edu/ku/brc/specify/conversion/GenericDBConversion.java +++ b/src/edu/ku/brc/specify/conversion/GenericDBConversion.java @@ -6369,6 +6369,20 @@ public boolean convertDeterminationRecords() { pStmt.setInt(fldInx, getCollectionMemberId()); + } else if (newFieldName.matches("Integer[1-5]") || + newFieldName.matches("Number[1-5]") || + newFieldName.matches("Text[3-8]") || + newFieldName.matches("YesNo[3-5]")) + { + FieldMetaData fldMetaData = newFieldMetaData.get(i); + if (fldMetaData != null) + { + pStmt.setNull(fldInx, fldMetaData.getSqlType()); + } else + { + pStmt.setObject(fldInx, null); + } + } else { Integer index = null; @@ -10248,6 +10262,38 @@ protected GeologicTimePeriodTreeDefItem addGtpDefItem(Integer rankCode, return item; } + private BigDecimal toBigDecimal(final Object value) + { + if (value == null) + { + return null; + } + if (value instanceof BigDecimal) + { + return (BigDecimal)value; + } + if (value instanceof Number) + { + try + { + return new BigDecimal(value.toString()); + } catch (NumberFormatException ex) + { + log.error("Unable to convert numeric value [" + value + "] to BigDecimal", ex); + return null; + } + } + + try + { + return new BigDecimal(value.toString()); + } catch (NumberFormatException ex) + { + log.error("Unable to convert value [" + value + "] to BigDecimal", ex); + return null; + } + } + /** * @param tblWriter * @param treeDef @@ -10315,10 +10361,10 @@ public void convertGTP(final TableWriter tblWriter, final GeologicTimePeriodTree Date creTDate = rs.getDate(7); Timestamp modT = (modTDate != null) ? new Timestamp(modTDate.getTime()) : null; Timestamp creT = (creTDate != null) ? new Timestamp(creTDate.getTime()) : null; - BigDecimal upper = new BigDecimal((Double)rs.getObject(8)); - BigDecimal uError = new BigDecimal((Double)rs.getObject(9)); - BigDecimal lower = new BigDecimal((Double)rs.getObject(10)); - BigDecimal lError = new BigDecimal((Double)rs.getObject(11)); + BigDecimal upper = toBigDecimal(rs.getObject(8)); + BigDecimal uError = toBigDecimal(rs.getObject(9)); + BigDecimal lower = toBigDecimal(rs.getObject(10)); + BigDecimal lError = toBigDecimal(rs.getObject(11)); if (isEmpty(name)) {