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