Return-Path: Delivered-To: apmail-commons-commits-archive@minotaur.apache.org Received: (qmail 67567 invoked from network); 11 Feb 2009 08:08:27 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 11 Feb 2009 08:08:27 -0000 Received: (qmail 54069 invoked by uid 500); 11 Feb 2009 08:08:25 -0000 Delivered-To: apmail-commons-commits-archive@commons.apache.org Received: (qmail 53995 invoked by uid 500); 11 Feb 2009 08:08:25 -0000 Mailing-List: contact commits-help@commons.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@commons.apache.org Delivered-To: mailing list commits@commons.apache.org Received: (qmail 53986 invoked by uid 99); 11 Feb 2009 08:08:25 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 11 Feb 2009 00:08:25 -0800 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 11 Feb 2009 08:08:23 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 1F8DC2388AE7; Wed, 11 Feb 2009 08:08:02 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Subject: svn commit: r743269 - /commons/sandbox/dbutils/bugfixing/src/java/org/apache/commons/dbutils/BasicRowProcessor.java Date: Wed, 11 Feb 2009 08:08:01 -0000 To: commits@commons.apache.org From: dfabulich@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20090211080802.1F8DC2388AE7@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org 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. + * + *

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. + * + *

Note: This implementation does not allow null + * for key, whereas {@link HashMap} does, because of the code: + *

+     * key.toString().toLowerCase()
+     * 
*/ private static class CaseInsensitiveHashMap extends HashMap { /** + * The internal mapping from lowercase keys to the real keys. + * + *

+ * Any query operation using the key + * ({@link #get(Object)}, {@link #containsKey(Object)}) + * is done in three steps: + *

    + *
  • convert the parameter key to lower case
  • + *
  • get the actual key that corresponds to the lower case key
  • + *
  • query the map with the actual key
  • + *
+ *

+ */ + 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); } }