Author: dfabulich
Date: Wed Feb 11 08:08:01 2009
New Revision: 743269
URL: http://svn.apache.org/viewvc?rev=743269&view=rev
Log:
[DBUTILS-34] BasicRowProcessor loses any information on database field case
Submitted by: Julien Aymé
Modified:
commons/sandbox/dbutils/bugfixing/src/java/org/apache/commons/dbutils/BasicRowProcessor.java
Modified:
commons/sandbox/dbutils/bugfixing/src/java/org/apache/commons/dbutils/BasicRowProcessor.java
URL:
http://svn.apache.org/viewvc/commons/sandbox/dbutils/bugfixing/src/java/org/apache/commons/dbutils/BasicRowProcessor.java?rev=743269&r1=743268&r2=743269&view=diff
==============================================================================
---
commons/sandbox/dbutils/bugfixing/src/java/org/apache/commons/dbutils/BasicRowProcessor.java
(original)
+++
commons/sandbox/dbutils/bugfixing/src/java/org/apache/commons/dbutils/BasicRowProcessor.java
Wed Feb 11 08:08:01 2009
@@ -144,10 +144,36 @@
* A Map that converts all keys to lowercase Strings for case insensitive
* lookups. This is needed for the toMap() implementation because
* databases don't consistenly handle the casing of column names.
+ *
+ * <p>The keys are stored as they are given [BUG #DBUTILS-34], so we
maintain
+ * an internal mapping from lowercase keys to the real keys in order to
+ * achieve the case insensitive lookup.
+ *
+ * <p>Note: This implementation does not allow <tt>null</tt>
+ * for key, whereas {...@link HashMap} does, because of the code:
+ * <pre>
+ * key.toString().toLowerCase()
+ * </pre>
*/
private static class CaseInsensitiveHashMap extends HashMap {
/**
+ * The internal mapping from lowercase keys to the real keys.
+ *
+ * <p>
+ * Any query operation using the key
+ * ({...@link #get(Object)}, {...@link #containsKey(Object)})
+ * is done in three steps:
+ * <ul>
+ * <li>convert the parameter key to lower case</li>
+ * <li>get the actual key that corresponds to the lower case key</li>
+ * <li>query the map with the actual key</li>
+ * </ul>
+ * </p>
+ */
+ private Map lowerCaseMap = new HashMap();
+
+ /**
* Required for serialization support.
*
* @see java.io.Serializable
@@ -158,21 +184,37 @@
* @see java.util.Map#containsKey(java.lang.Object)
*/
public boolean containsKey(Object key) {
- return super.containsKey(key.toString().toLowerCase());
+ Object realKey = lowerCaseMap.get(key.toString().toLowerCase());
+ return super.containsKey(realKey);
+ // Possible optimisation here:
+ // Since the lowerCaseMap contains a mapping for all the keys,
+ // we could just do this:
+ // return lowerCaseMap.containsKey(key.toString().toLowerCase());
}
/**
* @see java.util.Map#get(java.lang.Object)
*/
public Object get(Object key) {
- return super.get(key.toString().toLowerCase());
+ Object realKey = lowerCaseMap.get(key.toString().toLowerCase());
+ return super.get(realKey);
}
/**
* @see java.util.Map#put(java.lang.Object, java.lang.Object)
*/
public Object put(Object key, Object value) {
- return super.put(key.toString().toLowerCase(), value);
+ /*
+ * In order to keep the map and lowerCaseMap synchronized,
+ * we have to remove the old mapping before putting the
+ * new one. Indeed, oldKey and key are not necessaliry equals.
+ * (That's why we call super.remove(oldKey) and not just
+ * super.put(key, value))
+ */
+ Object oldKey = lowerCaseMap.put(key.toString().toLowerCase(),
key);
+ Object oldValue = super.remove(oldKey);
+ super.put(key, value);
+ return oldValue;
}
/**
@@ -191,7 +233,8 @@
* @see java.util.Map#remove(java.lang.Object)
*/
public Object remove(Object key) {
- return super.remove(key.toString().toLowerCase());
+ Object realKey = lowerCaseMap.remove(key.toString().toLowerCase());
+ return super.remove(realKey);
}
}