aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJames Ahlborn <jtahlborn@yahoo.com>2015-01-16 04:27:21 +0000
committerJames Ahlborn <jtahlborn@yahoo.com>2015-01-16 04:27:21 +0000
commit6b74a49d9b03abc9d9d8c347c6e2297266f4a378 (patch)
tree894261d128e75c55320c054bf86ac0599edd4af3 /src
parentb5ba01ff3b20bf33f656d195fb5fae40603f5ae2 (diff)
downloadjackcess-6b74a49d9b03abc9d9d8c347c6e2297266f4a378.tar.gz
jackcess-6b74a49d9b03abc9d9d8c347c6e2297266f4a378.zip
make SimpleColumnMatcher handle a wider range of input data types by coercing them to the appropriate internal value typefg
git-svn-id: https://svn.code.sf.net/p/jackcess/code/jackcess/trunk@908 f203690c-595d-4dc9-a70b-905162fa7fd2
Diffstat (limited to 'src')
-rw-r--r--src/main/java/com/healthmarketscience/jackcess/impl/ColumnImpl.java79
-rw-r--r--src/main/java/com/healthmarketscience/jackcess/util/SimpleColumnMatcher.java30
2 files changed, 97 insertions, 12 deletions
diff --git a/src/main/java/com/healthmarketscience/jackcess/impl/ColumnImpl.java b/src/main/java/com/healthmarketscience/jackcess/impl/ColumnImpl.java
index 224348a..e244d31 100644
--- a/src/main/java/com/healthmarketscience/jackcess/impl/ColumnImpl.java
+++ b/src/main/java/com/healthmarketscience/jackcess/impl/ColumnImpl.java
@@ -825,16 +825,24 @@ public class ColumnImpl implements Column, Comparable<ColumnImpl> {
*/
public double toDateDouble(Object value)
{
- // seems access stores dates in the local timezone. guess you just
- // hope you read it in the same timezone in which it was written!
- long time = ((value instanceof Date) ?
- ((Date)value).getTime() :
- ((value instanceof Calendar) ?
- ((Calendar)value).getTimeInMillis() :
- ((Number)value).longValue()));
- time += getToLocalTimeZoneOffset(time);
- time += MILLIS_BETWEEN_EPOCH_AND_1900;
- return time / MILLISECONDS_PER_DAY;
+ // seems access stores dates in the local timezone. guess you just
+ // hope you read it in the same timezone in which it was written!
+ long time = toDateLong(value);
+ time += getToLocalTimeZoneOffset(time);
+ time += MILLIS_BETWEEN_EPOCH_AND_1900;
+ return time / MILLISECONDS_PER_DAY;
+ }
+
+ /**
+ * @return an appropriate Date long value for the given object
+ */
+ private static long toDateLong(Object value)
+ {
+ return ((value instanceof Date) ?
+ ((Date)value).getTime() :
+ ((value instanceof Calendar) ?
+ ((Calendar)value).getTimeInMillis() :
+ ((Number)value).longValue()));
}
/**
@@ -1470,6 +1478,8 @@ public class ColumnImpl implements Column, Comparable<ColumnImpl> {
} catch(SQLException e) {
throw (IOException)(new IOException(e.getMessage())).initCause(e);
}
+ } else if(value instanceof RawData) {
+ return ((RawData)value).getBytes();
}
ByteArrayOutputStream bout = new ByteArrayOutputStream();
@@ -1696,6 +1706,55 @@ public class ColumnImpl implements Column, Comparable<ColumnImpl> {
}
/**
+ * Converts the given value to the "internal" representation for the given
+ * data type.
+ */
+ public static Object toInternalValue(DataType dataType, Object value)
+ throws IOException
+ {
+ if(value != null) {
+ switch(dataType) {
+ case BOOLEAN:
+ return ((value instanceof Boolean) ? value : toBooleanValue(value));
+ case BYTE:
+ return ((value instanceof Byte) ? value : toNumber(value).byteValue());
+ case INT:
+ return ((value instanceof Short) ? value :
+ toNumber(value).shortValue());
+ case LONG:
+ return ((value instanceof Integer) ? value :
+ toNumber(value).intValue());
+ case MONEY:
+ return toBigDecimal(value);
+ case FLOAT:
+ return ((value instanceof Float) ? value :
+ toNumber(value).floatValue());
+ case DOUBLE:
+ return ((value instanceof Double) ? value :
+ toNumber(value).doubleValue());
+ case SHORT_DATE_TIME:
+ return ((value instanceof DateExt) ? value :
+ new Date(toDateLong(value)));
+ case TEXT:
+ case MEMO:
+ case GUID:
+ return ((value instanceof String) ? value :
+ toCharSequence(value).toString());
+ case NUMERIC:
+ return toBigDecimal(value);
+ case COMPLEX_TYPE:
+ // leave alone for now?
+ break;
+ default:
+ // some variation of binary data
+ return toByteArray(value);
+ }
+ }
+
+ return value;
+ }
+
+ /**
* Date subclass which stashes the original date bits, in case we attempt to
* re-write the value (will not lose precision).
*/
diff --git a/src/main/java/com/healthmarketscience/jackcess/util/SimpleColumnMatcher.java b/src/main/java/com/healthmarketscience/jackcess/util/SimpleColumnMatcher.java
index 95db6a9..35ecfbd 100644
--- a/src/main/java/com/healthmarketscience/jackcess/util/SimpleColumnMatcher.java
+++ b/src/main/java/com/healthmarketscience/jackcess/util/SimpleColumnMatcher.java
@@ -20,11 +20,17 @@ USA
package com.healthmarketscience.jackcess.util;
+import java.io.IOException;
+
+import com.healthmarketscience.jackcess.DataType;
import com.healthmarketscience.jackcess.Table;
+import com.healthmarketscience.jackcess.impl.ColumnImpl;
import org.apache.commons.lang.ObjectUtils;
/**
- * Simple concrete implementation of ColumnMatcher which test for equality.
+ * Simple concrete implementation of ColumnMatcher which tests for equality.
+ * If initial comparison fails, attempts to coerce the values to a common type
+ * for comparison.
*
* @author James Ahlborn
* @usage _general_class_
@@ -39,6 +45,26 @@ public class SimpleColumnMatcher implements ColumnMatcher {
public boolean matches(Table table, String columnName, Object value1,
Object value2)
{
- return ObjectUtils.equals(value1, value2);
+ if(ObjectUtils.equals(value1, value2)) {
+ return true;
+ }
+
+ if((value1 != null) && (value2 != null) &&
+ (value1.getClass() != value2.getClass())) {
+
+ // the values aren't the same type, try coercing them to "internal"
+ // values and try again
+ DataType dataType = table.getColumn(columnName).getType();
+ try {
+ Object internalV1 = ColumnImpl.toInternalValue(dataType, value1);
+ Object internalV2 = ColumnImpl.toInternalValue(dataType, value2);
+
+ return ObjectUtils.equals(internalV1, internalV2);
+ } catch(IOException e) {
+ // ignored, just go with the original result
+ }
+ }
+ return false;
}
+
}