You are viewing a plain text version of this content. The canonical link for it is here.
Posted to ddlutils-dev@db.apache.org by to...@apache.org on 2010/09/30 06:21:15 UTC

svn commit: r1002945 - in /db/ddlutils/trunk/src: main/java/org/apache/ddlutils/platform/ main/java/org/apache/ddlutils/platform/db2/ main/java/org/apache/ddlutils/platform/firebird/ main/java/org/apache/ddlutils/platform/interbase/ main/java/org/apach...

Author: tomdz
Date: Thu Sep 30 04:21:15 2010
New Revision: 1002945

URL: http://svn.apache.org/viewvc?rev=1002945&view=rev
Log:
Applied Tony Rippy's patch for DDLUTILS-246: JdbcModelReader merges metadata between tables, with minor modifications

Added:
    db/ddlutils/trunk/src/test/java/org/apache/ddlutils/platform/TestDatabaseMetaDataWrapper.java
Modified:
    db/ddlutils/trunk/src/main/java/org/apache/ddlutils/platform/DatabaseMetaDataWrapper.java
    db/ddlutils/trunk/src/main/java/org/apache/ddlutils/platform/JdbcModelReader.java
    db/ddlutils/trunk/src/main/java/org/apache/ddlutils/platform/db2/Db2ModelReader.java
    db/ddlutils/trunk/src/main/java/org/apache/ddlutils/platform/firebird/FirebirdModelReader.java
    db/ddlutils/trunk/src/main/java/org/apache/ddlutils/platform/interbase/InterbaseModelReader.java
    db/ddlutils/trunk/src/main/java/org/apache/ddlutils/platform/mssql/MSSqlModelReader.java

Modified: db/ddlutils/trunk/src/main/java/org/apache/ddlutils/platform/DatabaseMetaDataWrapper.java
URL: http://svn.apache.org/viewvc/db/ddlutils/trunk/src/main/java/org/apache/ddlutils/platform/DatabaseMetaDataWrapper.java?rev=1002945&r1=1002944&r2=1002945&view=diff
==============================================================================
--- db/ddlutils/trunk/src/main/java/org/apache/ddlutils/platform/DatabaseMetaDataWrapper.java (original)
+++ db/ddlutils/trunk/src/main/java/org/apache/ddlutils/platform/DatabaseMetaDataWrapper.java Thu Sep 30 04:21:15 2010
@@ -22,14 +22,15 @@ package org.apache.ddlutils.platform;
 import java.sql.DatabaseMetaData;
 import java.sql.ResultSet;
 import java.sql.SQLException;
+import java.util.regex.Pattern;
 
 /**
  * Wrapper class for database meta data that stores additional info.
- * 
- * @version $Revision: 329426 $
  */
 public class DatabaseMetaDataWrapper
 {
+    /** Matches the characters not allowed in search strings. */
+    private final Pattern searchStringPattern = Pattern.compile("[_%]");
     /** The database meta data. */
     private DatabaseMetaData _metaData;
     /** The catalog to acess in the database. */
@@ -137,6 +138,49 @@ public class DatabaseMetaDataWrapper
             System.arraycopy(types, 0, _tableTypes, 0, types.length);
         }
     }
+    
+    /**
+     * Escape a string literal so that it can be used as a search pattern.
+     * 
+     * @param literalString The string to escape.
+     * @return A string that can be properly used as a search string.
+     * @throws SQLException If an error occurred retrieving the meta data
+     */
+    public String escapeForSearch(String literalString) throws SQLException
+    {
+        String escape = getMetaData().getSearchStringEscape();
+
+        if (escape == "")
+        {
+            // No escape string, so nothing to do...
+            return literalString;
+        }
+        else
+        {
+            // with Java 5, we would just use Matcher.quoteReplacement
+            StringBuffer quotedEscape = new StringBuffer();
+
+            for (int idx = 0; idx < escape.length(); idx++)
+            {
+                char c = escape.charAt(idx);
+
+                switch (c)
+                {
+                    case '\\':
+                        quotedEscape.append("\\\\");
+                        break;
+                    case '$':
+                        quotedEscape.append("\\$");
+                        break;
+                    default:
+                        quotedEscape.append(c);
+                }
+            }
+            quotedEscape.append("$0");
+
+            return searchStringPattern.matcher(literalString).replaceAll(quotedEscape.toString());
+        }
+    }
 
     /**
      * Convenience method to return the table meta data using the configured catalog,

Modified: db/ddlutils/trunk/src/main/java/org/apache/ddlutils/platform/JdbcModelReader.java
URL: http://svn.apache.org/viewvc/db/ddlutils/trunk/src/main/java/org/apache/ddlutils/platform/JdbcModelReader.java?rev=1002945&r1=1002944&r2=1002945&view=diff
==============================================================================
--- db/ddlutils/trunk/src/main/java/org/apache/ddlutils/platform/JdbcModelReader.java (original)
+++ db/ddlutils/trunk/src/main/java/org/apache/ddlutils/platform/JdbcModelReader.java Thu Sep 30 04:21:15 2010
@@ -773,7 +773,7 @@ public class JdbcModelReader
 
         try
         {
-            columnData = metaData.getColumns(tableName, getDefaultColumnPattern());
+            columnData = metaData.getColumns(metaData.escapeForSearch(tableName), getDefaultColumnPattern());
 
             List columns = new ArrayList();
 
@@ -856,7 +856,7 @@ public class JdbcModelReader
 
         try
         {
-            pkData = metaData.getPrimaryKeys(tableName);
+            pkData = metaData.getPrimaryKeys(metaData.escapeForSearch(tableName));
             while (pkData.next())
             {
                 Map values = readColumns(pkData, getColumnsForPK());
@@ -897,7 +897,7 @@ public class JdbcModelReader
 
         try
         {
-            fkData = metaData.getForeignKeys(tableName);
+            fkData = metaData.getForeignKeys(metaData.escapeForSearch(tableName));
 
             while (fkData.next())
             {
@@ -1004,7 +1004,7 @@ public class JdbcModelReader
 
         try 
         {
-            indexData = metaData.getIndices(tableName, false, false);
+            indexData = metaData.getIndices(metaData.escapeForSearch(tableName), false, false);
 
             while (indexData.next())
             {
@@ -1236,7 +1236,7 @@ public class JdbcModelReader
                 tablePattern = tablePattern.toUpperCase();
             }
 
-            tableData = metaData.getTables(tablePattern);
+            tableData = metaData.getTables(metaData.escapeForSearch(tablePattern));
 
             boolean found  = false;
             String  schema = null;
@@ -1249,7 +1249,7 @@ public class JdbcModelReader
                 if ((tableName != null) && (tableName.length() > 0))
                 {
                     schema     = (String)values.get("TABLE_SCHEM");
-                    columnData = metaData.getColumns(tableName, getDefaultColumnPattern());
+                    columnData = metaData.getColumns(metaData.escapeForSearch(tableName), getDefaultColumnPattern());
                     found      = true;
 
                     while (found && columnData.next())

Modified: db/ddlutils/trunk/src/main/java/org/apache/ddlutils/platform/db2/Db2ModelReader.java
URL: http://svn.apache.org/viewvc/db/ddlutils/trunk/src/main/java/org/apache/ddlutils/platform/db2/Db2ModelReader.java?rev=1002945&r1=1002944&r2=1002945&view=diff
==============================================================================
--- db/ddlutils/trunk/src/main/java/org/apache/ddlutils/platform/db2/Db2ModelReader.java (original)
+++ db/ddlutils/trunk/src/main/java/org/apache/ddlutils/platform/db2/Db2ModelReader.java Thu Sep 30 04:21:15 2010
@@ -233,7 +233,7 @@ public class Db2ModelReader extends Jdbc
 
             try
             {
-                pkData = metaData.getPrimaryKeys(table.getName());
+                pkData = metaData.getPrimaryKeys(metaData.escapeForSearch(table.getName()));
                 while (pkData.next())
                 {
                     Map values = readColumns(pkData, getColumnsForPK());

Modified: db/ddlutils/trunk/src/main/java/org/apache/ddlutils/platform/firebird/FirebirdModelReader.java
URL: http://svn.apache.org/viewvc/db/ddlutils/trunk/src/main/java/org/apache/ddlutils/platform/firebird/FirebirdModelReader.java?rev=1002945&r1=1002944&r2=1002945&view=diff
==============================================================================
--- db/ddlutils/trunk/src/main/java/org/apache/ddlutils/platform/firebird/FirebirdModelReader.java (original)
+++ db/ddlutils/trunk/src/main/java/org/apache/ddlutils/platform/firebird/FirebirdModelReader.java Thu Sep 30 04:21:15 2010
@@ -106,7 +106,7 @@ public class FirebirdModelReader extends
         	}
         	else
         	{
-        		columnData = metaData.getColumns(tableName, getDefaultColumnPattern());
+        		columnData = metaData.getColumns(metaData.escapeForSearch(tableName), getDefaultColumnPattern());
 
         		while (columnData.next())
                 {
@@ -221,7 +221,7 @@ public class FirebirdModelReader extends
         	}
             else
             {
-	            pkData = metaData.getPrimaryKeys(tableName);
+	            pkData = metaData.getPrimaryKeys(metaData.escapeForSearch(tableName));
 	            while (pkData.next())
 	            {
 	                Map values = readColumns(pkData, getColumnsForPK());
@@ -265,7 +265,7 @@ public class FirebirdModelReader extends
         	}
             else
             {
-	            fkData = metaData.getForeignKeys(tableName);
+	            fkData = metaData.getForeignKeys(metaData.escapeForSearch(tableName));
 	            while (fkData.next())
 	            {
 	                Map values = readColumns(fkData, getColumnsForFK());
@@ -410,7 +410,7 @@ public class FirebirdModelReader extends
                 tablePattern = tablePattern.toUpperCase();
             }
 
-            tableData = metaData.getTables(tablePattern);
+            tableData = metaData.getTables(metaData.escapeForSearch(tablePattern));
 
             boolean found  = false;
             String  schema = null;
@@ -434,7 +434,7 @@ public class FirebirdModelReader extends
                     }
                     else
                     {
-                        columnData = metaData.getColumns(tableName, getDefaultColumnPattern());
+                        columnData = metaData.getColumns(metaData.escapeForSearch(tableName), getDefaultColumnPattern());
                     }
 
                     while (found && columnData.next())

Modified: db/ddlutils/trunk/src/main/java/org/apache/ddlutils/platform/interbase/InterbaseModelReader.java
URL: http://svn.apache.org/viewvc/db/ddlutils/trunk/src/main/java/org/apache/ddlutils/platform/interbase/InterbaseModelReader.java?rev=1002945&r1=1002944&r2=1002945&view=diff
==============================================================================
--- db/ddlutils/trunk/src/main/java/org/apache/ddlutils/platform/interbase/InterbaseModelReader.java (original)
+++ db/ddlutils/trunk/src/main/java/org/apache/ddlutils/platform/interbase/InterbaseModelReader.java Thu Sep 30 04:21:15 2010
@@ -109,7 +109,7 @@ public class InterbaseModelReader extend
             }
             else
             {
-                columnData = metaData.getColumns(tableName, getDefaultColumnPattern());
+                columnData = metaData.getColumns(metaData.escapeForSearch(tableName), getDefaultColumnPattern());
 
                 while (columnData.next())
                 {
@@ -303,7 +303,7 @@ public class InterbaseModelReader extend
             }
             else
             {
-                pkData = metaData.getPrimaryKeys(tableName);
+                pkData = metaData.getPrimaryKeys(metaData.escapeForSearch(tableName));
                 while (pkData.next())
                 {
                     Map values = readColumns(pkData, getColumnsForPK());
@@ -347,7 +347,7 @@ public class InterbaseModelReader extend
             }
             else
             {
-                fkData = metaData.getForeignKeys(tableName);
+                fkData = metaData.getForeignKeys(metaData.escapeForSearch(tableName));
                 while (fkData.next())
                 {
                     Map values = readColumns(fkData, getColumnsForFK());
@@ -449,7 +449,7 @@ public class InterbaseModelReader extend
                 tablePattern = tablePattern.toUpperCase();
             }
 
-            tableData = metaData.getTables(tablePattern);
+            tableData = metaData.getTables(metaData.escapeForSearch(tablePattern));
 
             boolean found  = false;
             String  schema = null;
@@ -473,7 +473,7 @@ public class InterbaseModelReader extend
                     }
                     else
                     {
-                        columnData = metaData.getColumns(tableName, getDefaultColumnPattern());
+                        columnData = metaData.getColumns(metaData.escapeForSearch(tableName), getDefaultColumnPattern());
                     }
 
                     while (found && columnData.next())

Modified: db/ddlutils/trunk/src/main/java/org/apache/ddlutils/platform/mssql/MSSqlModelReader.java
URL: http://svn.apache.org/viewvc/db/ddlutils/trunk/src/main/java/org/apache/ddlutils/platform/mssql/MSSqlModelReader.java?rev=1002945&r1=1002944&r2=1002945&view=diff
==============================================================================
--- db/ddlutils/trunk/src/main/java/org/apache/ddlutils/platform/mssql/MSSqlModelReader.java (original)
+++ db/ddlutils/trunk/src/main/java/org/apache/ddlutils/platform/mssql/MSSqlModelReader.java Thu Sep 30 04:21:15 2010
@@ -147,7 +147,7 @@ public class MSSqlModelReader extends Jd
 
         try
         {
-            pks = metaData.getPrimaryKeys(table.getName());
+            pks = metaData.getPrimaryKeys(metaData.escapeForSearch(table.getName()));
 
             while (pks.next())
             {

Added: db/ddlutils/trunk/src/test/java/org/apache/ddlutils/platform/TestDatabaseMetaDataWrapper.java
URL: http://svn.apache.org/viewvc/db/ddlutils/trunk/src/test/java/org/apache/ddlutils/platform/TestDatabaseMetaDataWrapper.java?rev=1002945&view=auto
==============================================================================
--- db/ddlutils/trunk/src/test/java/org/apache/ddlutils/platform/TestDatabaseMetaDataWrapper.java (added)
+++ db/ddlutils/trunk/src/test/java/org/apache/ddlutils/platform/TestDatabaseMetaDataWrapper.java Thu Sep 30 04:21:15 2010
@@ -0,0 +1,77 @@
+package org.apache.ddlutils.platform;
+
+/*
+ * 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.
+ */
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.sql.DatabaseMetaData;
+import org.apache.ddlutils.TestBase;
+
+/**
+ * Tests for the utility methods in the {@link DatabaseMetaDataWrapper} class.
+ */
+public class TestDatabaseMetaDataWrapper extends TestBase
+{
+    /**
+     * Helper method to create a proxied DatabaseMetaData instance using the given invocation handler.
+     * 
+     * @param handler The handler
+     * @return The proxy object
+     */
+    private DatabaseMetaData createMockDatabaseMetaData(final InvocationHandler handler)
+    {
+        return (DatabaseMetaData)Proxy.newProxyInstance(getClass().getClassLoader(),
+                                                        new Class[] { DatabaseMetaData.class },
+                                                        handler);
+    }
+
+    /**
+     * Tests the {@link DatabaseMetaDataWrapper#escapeForSearch(String)} method (see DDLUTILS-246).
+     */
+    public void testEscapeSearchString() throws Exception
+    {
+        DatabaseMetaData metaData = createMockDatabaseMetaData(new InvocationHandler()
+            {
+                /**
+                 * {@inheritDoc}
+                 */
+                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
+                {
+                    if ("getSearchStringEscape".equals(method.getName()))
+                    {
+                        return "\\";
+                    }
+                    else
+                    {
+                        throw new UnsupportedOperationException();
+                    }
+                }
+            });
+
+        DatabaseMetaDataWrapper wrapper = new DatabaseMetaDataWrapper();
+
+        wrapper.setMetaData(metaData);
+
+        assertEquals("FOOMATIC", wrapper.escapeForSearch("FOOMATIC"));
+        assertEquals("FOO\\_MATIC", wrapper.escapeForSearch("FOO_MATIC"));
+        assertEquals("FOO\\%MATIC", wrapper.escapeForSearch("FOO%MATIC"));
+    }
+}