This is an automated email from the ASF dual-hosted git repository.
doebele pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/empire-db.git
The following commit(s) were added to refs/heads/master by this push:
new cd4f6fc8 EMPIREDB-444 ValueUtils: some additinal optimizations
cd4f6fc8 is described below
commit cd4f6fc82bcbbbb72a670e47b59b492fdf2a2bff
Author: Rainer Döbele <[email protected]>
AuthorDate: Thu Oct 24 21:30:39 2024 +0200
EMPIREDB-444
ValueUtils: some additinal optimizations
---
.../org/apache/empire/commons/ObjectUtils.java | 59 ++++----
.../java/org/apache/empire/commons/ValueUtils.java | 148 +++++++--------------
.../main/java/org/apache/empire/db/DBCmdParam.java | 6 +
.../main/java/org/apache/empire/db/DBDatabase.java | 20 +--
.../java/org/apache/empire/db/DBSQLBuilder.java | 3 +-
.../main/java/org/apache/empire/db/DBTable.java | 2 +-
.../exceptions/ValueConversionException.java | 40 ++++++
7 files changed, 125 insertions(+), 153 deletions(-)
diff --git a/empire-db/src/main/java/org/apache/empire/commons/ObjectUtils.java
b/empire-db/src/main/java/org/apache/empire/commons/ObjectUtils.java
index 015e0339..3514e4cc 100644
--- a/empire-db/src/main/java/org/apache/empire/commons/ObjectUtils.java
+++ b/empire-db/src/main/java/org/apache/empire/commons/ObjectUtils.java
@@ -23,17 +23,18 @@ import java.math.BigDecimal;
import java.text.ParseException;
import java.time.LocalDate;
import java.time.LocalDateTime;
+import java.time.format.DateTimeParseException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.List;
-import java.util.Locale;
import org.apache.commons.beanutils.MethodUtils;
import org.apache.empire.data.ColumnExpr;
import org.apache.empire.data.DataType;
import org.apache.empire.exceptions.InvalidArgumentException;
+import org.apache.empire.exceptions.ValueConversionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -444,32 +445,6 @@ public final class ObjectUtils
return valueUtils.getString(value);
}
- /**
- * Converts an object value to a Date.
- * <P>
- * @param v the object to convert
- * @return the Date value of o or null
- * @throws ParseException
- */
- public static Date toDate(Object v)
- throws ParseException
- {
- return valueUtils.toDate(v);
- }
-
- /**
- * Converts an object value to a Date.
- * <P>
- * If the object value supplied is null or if conversion is not possible
then null is returned.
- * @param v the object to convert
- * @param locale the locale used for conversion
- * @return the Date value of o or null
- */
- public static Date getDate(Object v, Locale locale)
- {
- return valueUtils.getDate(v, locale);
- }
-
/**
* Converts an object value to a Date.
* <P>
@@ -478,29 +453,43 @@ public final class ObjectUtils
*/
public static Date getDate(Object v)
{
- return valueUtils.getDate(v);
+ try {
+ return valueUtils.toDate(v);
+ } catch (ParseException e) {
+ throw new ValueConversionException(Date.class, v, e);
+ }
}
/**
- * Converts an object value to a Date.
+ * Converts an object value to a LocalDate.
* <P>
* @param v the object to convert
- * @return the Date value of o or null
+ * @return the LocalDate value of o or null
*/
public static LocalDate getLocalDate(Object v)
{
- return valueUtils.getLocalDate(v);
+ try {
+ // DateTimeFormatter.ISO_LOCAL_DATE_TIME
+ return valueUtils.toLocalDate(v);
+ } catch (DateTimeParseException e) {
+ throw new ValueConversionException(LocalDate.class, v, e);
+ }
}
/**
- * Converts an object value to a Date.
+ * Converts an object value to a LocalDateTime.
* <P>
* @param v the object to convert
- * @return the Date value of o or null
+ * @return the LocalDateTime value of o or null
*/
public static LocalDateTime getLocalDateTime(Object v)
{
- return valueUtils.getLocalDateTime(v);
+ try {
+ // DateTimeFormatter.ISO_LOCAL_DATE_TIME
+ return valueUtils.toLocalDateTime(v);
+ } catch (DateTimeParseException e) {
+ throw new ValueConversionException(LocalDateTime.class, v, e);
+ }
}
/**
@@ -523,7 +512,7 @@ public final class ObjectUtils
* @param c the class type to convert to
* @param v the object to convert
*
- * @return the Date value of o or null
+ * @return the converted value of o or null
*
* @throws ClassCastException if the object is not null and is not
assignable to the type T.
*/
diff --git a/empire-db/src/main/java/org/apache/empire/commons/ValueUtils.java
b/empire-db/src/main/java/org/apache/empire/commons/ValueUtils.java
index 9385365b..9ab51dfe 100644
--- a/empire-db/src/main/java/org/apache/empire/commons/ValueUtils.java
+++ b/empire-db/src/main/java/org/apache/empire/commons/ValueUtils.java
@@ -20,28 +20,26 @@ package org.apache.empire.commons;
import java.math.BigDecimal;
import java.math.BigInteger;
+import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
-import java.time.format.DateTimeParseException;
import java.time.temporal.Temporal;
import java.util.Collection;
import java.util.Date;
-import java.util.Locale;
import org.apache.commons.beanutils.MethodUtils;
import org.apache.empire.data.DataType;
+import org.apache.empire.db.DBExpr;
import org.apache.empire.db.expr.column.DBValueExpr;
import org.apache.empire.exceptions.InvalidValueException;
import org.apache.empire.exceptions.ItemNotFoundException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.apache.empire.exceptions.ValueConversionException;
/**
* This class allows to customize value type conversion as well as other value
related functions.
- * The functions and methods are called indirectly via the corresponding
static functions in the ObjectUtils class.
- *
+ * The functions and methods are called indirectly via the corresponding
static functions in the ObjectUtils class. *
* You may create your own derived class and overwrite the methods.
* In order to activate your ValueUtils implementation use the static function
*
@@ -52,7 +50,7 @@ import org.slf4j.LoggerFactory;
public class ValueUtils
{
// Logger
- private static final Logger log =
LoggerFactory.getLogger(ValueUtils.class);
+ // private static final Logger log =
LoggerFactory.getLogger(ValueUtils.class);
protected static final String DATE_FORMAT = "yyyy-MM-dd";
protected static final String DATETIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
@@ -159,6 +157,9 @@ public class ValueUtils
// Use equal check first
if (o1.equals(o2) || o2.equals(o1))
return true;
+ // DBExpr
+ if ((o1 instanceof DBExpr) || (o2 instanceof DBExpr))
+ return false;
// Compare Numbers
if (o1 instanceof Number && o2 instanceof Number)
{ // boolean test = obj1.equals(obj2);
@@ -521,92 +522,28 @@ public class ValueUtils
return DateUtils.toDate((LocalDate)v);
if (v instanceof java.time.LocalDateTime)
return DateUtils.toDate((LocalDateTime)v);
- // Convert from String
- String str = v.toString();
- if (str.length() > 10)
- return dateTimeFormatter.get().parse(str);
- else
- return dateOnlyFormatter.get().parse(str);
- }
-
- /**
- * Converts an object value to a Date.
- * <P>
- * If the object value supplied is null or if conversion is not possible
then null is returned.
- * @param v the object to convert
- * @param locale the locale used for conversion
- * @return the Date value of o or null
- */
- public Date getDate(Object v, Locale locale)
- {
- // Get DateTime value
- if (isEmpty(v))
- return null;
- if (v instanceof Date)
- return ((Date)v);
- if (v instanceof java.time.LocalDate)
- return DateUtils.toDate((LocalDate)v);
- if (v instanceof java.time.LocalDateTime)
- return DateUtils.toDate((LocalDateTime)v);
- // Get Calendar
if (v instanceof Number)
{ // Get Date from a number
long l = ((Number)v).longValue();
- if (l==0)
- return DateUtils.getDateNow();
- // Year or full date/time?
- /*
- if (l<10000)
- { // Year only
- Calendar calendar =
Calendar.getInstance(getSafeLocale(locale));
- calendar.set((int)l, 1, 1);
- return calendar.getTime();
- }
- */
- // Date from long
- return new Date(l);
+ return (l==0 ? null : new Date(l));
}
- // Try to parse
- return DateUtils.parseDate(v.toString(), locale);
- }
-
- /**
- * Converts an object value to a Date.
- * <P>
- * @param v the object to convert
- * @return the Date value of o or null
- */
- public Date getDate(Object v)
- {
- // Get DateTime value
- if (isEmpty(v))
- return null;
- if (v instanceof java.util.Date)
- return ((java.util.Date)v);
- if (v instanceof java.time.LocalDate)
- return DateUtils.toDate((LocalDate)v);
- if (v instanceof java.time.LocalDateTime)
- return DateUtils.toDate((LocalDateTime)v);
// Convert from String
String str = v.toString();
- try
- { if (str.length() > 10)
- return dateTimeFormatter.get().parse(str);
- else
- return dateOnlyFormatter.get().parse(str);
- } catch (ParseException e) {
- log.error(String.format("Cannot convert value [%s] to Date", str),
e);
- return null;
- }
+ if (str.length() > 20)
+ return Timestamp.valueOf(str);
+ if (str.length() > 10)
+ return dateTimeFormatter.get().parse(str);
+ else
+ return dateOnlyFormatter.get().parse(str);
}
/**
* Converts an object value to a Date.
* <P>
* @param v the object to convert
- * @return the Date value of o or null
+ * @return the LocalDate value of o or null
*/
- public LocalDate getLocalDate(Object v)
+ public LocalDate toLocalDate(Object v)
{
// Get DateTime value
if (isEmpty(v))
@@ -622,23 +559,18 @@ public class ValueUtils
if (v instanceof java.util.Date)
return DateUtils.toLocalDate((Date)v);
// Convert from String
+ // DateTimeFormatter.ISO_LOCAL_DATE_TIME
String str = v.toString();
- try
- { // DateTimeFormatter ISO_LOCAL_DATE
- return LocalDate.parse(str);
- } catch (DateTimeParseException e) {
- log.error(String.format("Cannot convert value [%s] to LocalDate",
str), e);
- return null;
- }
+ return LocalDate.parse(str);
}
/**
* Converts an object value to a Date.
* <P>
* @param v the object to convert
- * @return the Date value of o or null
+ * @return the LocalDateTime value of o or null
*/
- public LocalDateTime getLocalDateTime(Object v)
+ public LocalDateTime toLocalDateTime(Object v)
{
// Get DateTime value
if (isEmpty(v))
@@ -654,14 +586,9 @@ public class ValueUtils
if (v instanceof java.util.Date)
return DateUtils.toLocalDateTime((Date)v);
// Convert from String
+ // DateTimeFormatter.ISO_LOCAL_DATE_TIME
String str = v.toString();
- try
- { // DateTimeFormatter.ISO_LOCAL_DATE_TIME
- return LocalDateTime.parse(str);
- } catch (DateTimeParseException e) {
- log.error(String.format("Cannot convert value [%s] to
LocalDateTime", str), e);
- return null;
- }
+ return LocalDateTime.parse(str);
}
/**
@@ -741,19 +668,24 @@ public class ValueUtils
// check null
if (value == null)
return null;
+ // Cannot convert DBEXpr, return as is
+ if (value instanceof DBExpr)
+ return value;
// Strings special
if ((value instanceof String) && ((String)value).length()==0)
value = null;
- // check for enum
- if (value instanceof Enum<?>)
- { // convert enum
- value = getEnumValue((Enum<?>)value, dataType.isNumeric());
- }
// check option entry
- else if (value instanceof OptionEntry)
+ if (value instanceof OptionEntry)
{ // option value
value = ((OptionEntry)value).getValue();
}
+ // check for enum
+ if (value instanceof Enum<?>)
+ { // Convert Enum now (optional)
+ // value = getEnumValue((Enum<?>)value, dataType.isNumeric());
+ // Otherwise Enum will be converted later
+ return value;
+ }
// check type
switch (dataType)
{
@@ -761,6 +693,18 @@ public class ValueUtils
return value; // unchanged
case BOOL:
return getBoolean(value, false);
+ case DATE:
+ case DATETIME:
+ case TIMESTAMP:
+ // check type
+ if ((value instanceof Date) || (value instanceof Temporal))
+ return value; // already a date or temporal
+ // try to convert
+ try {
+ return toDate(value);
+ } catch (ParseException e) {
+ throw new ValueConversionException(Date.class, value, e);
+ }
case INTEGER:
return (value instanceof Number) ? value : toLong(value);
case FLOAT:
diff --git a/empire-db/src/main/java/org/apache/empire/db/DBCmdParam.java
b/empire-db/src/main/java/org/apache/empire/db/DBCmdParam.java
index f532e203..3d2ebfea 100644
--- a/empire-db/src/main/java/org/apache/empire/db/DBCmdParam.java
+++ b/empire-db/src/main/java/org/apache/empire/db/DBCmdParam.java
@@ -22,6 +22,7 @@ import java.util.Set;
import org.apache.empire.commons.ObjectUtils;
import org.apache.empire.data.DataType;
+import org.apache.empire.exceptions.InvalidOperationException;
/**
* This class defines a parameter for a prepared statement query.
@@ -57,10 +58,15 @@ public class DBCmdParam extends DBExpr
*/
protected Object getCmdParamValue(Object value)
{
+ if (value instanceof DBExpr)
+ throw new InvalidOperationException("DBCmdParam does not accept
DBExpr");
if (value!=null)
value = ObjectUtils.convertValue(type, value);
if (value==null)
return value;
+ // If still an Enum, convert now (Lazy conversion)
+ if (value instanceof Enum<?>)
+ value = ObjectUtils.getEnumValue((Enum<?>)value, type.isNumeric());
// Check CLOB and BLOB
switch (type)
{
diff --git a/empire-db/src/main/java/org/apache/empire/db/DBDatabase.java
b/empire-db/src/main/java/org/apache/empire/db/DBDatabase.java
index 536b661e..4e615941 100644
--- a/empire-db/src/main/java/org/apache/empire/db/DBDatabase.java
+++ b/empire-db/src/main/java/org/apache/empire/db/DBDatabase.java
@@ -22,7 +22,6 @@ import java.lang.ref.WeakReference;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.sql.Timestamp;
-import java.text.ParseException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
@@ -63,6 +62,7 @@ import org.apache.empire.exceptions.ItemExistsException;
import org.apache.empire.exceptions.NotSupportedException;
import org.apache.empire.exceptions.ObjectNotValidException;
import org.apache.empire.exceptions.PropertyReadOnlyException;
+import org.apache.empire.exceptions.ValueConversionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -1102,10 +1102,10 @@ public abstract class DBDatabase extends DBObject
if (!(value instanceof LocalDateTime) && !(value instanceof
Date) && !DBDatabase.SYSDATE.equals(value))
{ try {
// Parse Date
- value = ObjectUtils.toDate(value);
- } catch(ParseException e) {
+ value = ObjectUtils.getDate(value);
+ } catch (ValueConversionException e) {
log.info("Parsing '{}' to Date failed for column {}.
Message is "+e.toString(), value, column.getName());
- throw new FieldIllegalValueException(column,
String.valueOf(value), e);
+ throw new FieldIllegalValueException(column,
String.valueOf(value), e.getCause());
}
}
break;
@@ -1113,9 +1113,7 @@ public abstract class DBDatabase extends DBObject
case DECIMAL:
// check enum
if (value instanceof Enum<?>)
- { // convert enum
- value = ((Enum<?>)value).ordinal();
- }
+ break; // Convert later...
// check number
if (!(value instanceof java.lang.Number))
{ try
@@ -1149,9 +1147,7 @@ public abstract class DBDatabase extends DBObject
case INTEGER:
// check enum
if (value instanceof Enum<?>)
- { // convert enum
- value = ((Enum<?>)value).ordinal();
- }
+ break; // Convert later...
// check number
if (!(value instanceof java.lang.Number))
{ try
@@ -1170,9 +1166,7 @@ public abstract class DBDatabase extends DBObject
case CHAR:
// check enum
if (value instanceof Enum<?>)
- { // convert enum
- value = ObjectUtils.getString((Enum<?>)value);
- }
+ break; // Convert later...
// check length
if (value.toString().length() > (int)column.getSize())
{
diff --git a/empire-db/src/main/java/org/apache/empire/db/DBSQLBuilder.java
b/empire-db/src/main/java/org/apache/empire/db/DBSQLBuilder.java
index 8c83aefb..26bb1378 100644
--- a/empire-db/src/main/java/org/apache/empire/db/DBSQLBuilder.java
+++ b/empire-db/src/main/java/org/apache/empire/db/DBSQLBuilder.java
@@ -283,8 +283,7 @@ public abstract class DBSQLBuilder implements Appendable
protected void appendSimpleValue(DataType type, Object value)
{
if (value instanceof Enum<?>)
- { // convert enum
- log.warn("Enum of type {} supplied for getValueString. Converting
value...", value.getClass().getName());
+ { // If still an Enum, convert now (Lazy conversion)
value = ObjectUtils.getEnumValue((Enum<?>)value, type.isNumeric());
}
if (ObjectUtils.isEmpty(value))
diff --git a/empire-db/src/main/java/org/apache/empire/db/DBTable.java
b/empire-db/src/main/java/org/apache/empire/db/DBTable.java
index 96e2ca16..1841767b 100644
--- a/empire-db/src/main/java/org/apache/empire/db/DBTable.java
+++ b/empire-db/src/main/java/org/apache/empire/db/DBTable.java
@@ -395,7 +395,7 @@ public class DBTable extends DBRowSet implements Cloneable
*/
public final DBTableColumn addColumn(String columnName, DataType type,
double size, boolean required, Enum<?> enumValue)
{
- Object defValue = ObjectUtils.getEnumValue(enumValue,
type.isNumeric());
+ Object defValue = ObjectUtils.convertValue(type, enumValue);
DBTableColumn col = this.createAndAppendColumn(columnName, type, size,
required, defValue);
if (enumValue!=null)
col.setEnumOptions(enumValue.getClass());
diff --git
a/empire-db/src/main/java/org/apache/empire/exceptions/ValueConversionException.java
b/empire-db/src/main/java/org/apache/empire/exceptions/ValueConversionException.java
new file mode 100644
index 00000000..32f4e299
--- /dev/null
+++
b/empire-db/src/main/java/org/apache/empire/exceptions/ValueConversionException.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.empire.exceptions;
+
+import org.apache.empire.commons.ErrorType;
+import org.apache.empire.commons.StringUtils;
+
+public class ValueConversionException extends EmpireException
+{
+ private static final long serialVersionUID = 1L;
+
+ public static final ErrorType errorType = new
ErrorType("error.valueConversion", "Error converting from {1} to {0}. Invalid
value: {2}");
+
+ protected ValueConversionException(ErrorType errorType, String[] params)
+ {
+ super(errorType, params);
+ }
+
+ public ValueConversionException(Class<?> targetType, Object value,
Exception cause)
+ {
+ super(errorType, new String[] { targetType.getName(),
value.getClass().getName(), StringUtils.valueOf(value) }, cause);
+ }
+
+}