/* * * SchemaCrawler * http://sourceforge.net/projects/schemacrawler * Copyright (c) 2000-2012, Sualeh Fatehi. * * This library is free software; you can redistribute it and/or modify it under the terms * of the GNU Lesser General Public License as published by the Free Software Foundation; * either version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License along with this * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. * */ package schemacrawler.crawl; import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.Collection; import java.util.List; import schemacrawler.schema.DatabaseObject; import schemacrawler.schema.Schema; import schemacrawler.schema.SchemaReference; import sf.util.Utility; /** * Base class for retriever that uses database metadata to get the * details about the schema. * * @author Sualeh Fatehi */ abstract class AbstractRetriever { /** * Reads a single column result set as a list. * * @param results * Result set * @return List * @throws SQLException * On an exception */ static List<String> readResultsVector(final ResultSet results) throws SQLException { final List<String> values = new ArrayList<String>(); try { while (results.next()) { final String value = results.getString(1); values.add(value); } } finally { results.close(); } return values; } private final RetrieverConnection retrieverConnection; final MutableDatabase database; AbstractRetriever() throws SQLException { this(null, null); } AbstractRetriever(final RetrieverConnection retrieverConnection, final MutableDatabase database) throws SQLException { this.retrieverConnection = retrieverConnection; this.database = database; } /** * Checks whether the provided database object belongs to the * specified schema. * * @param dbObject * Database object to check * @param catalogName * Database catalog to check against * @param schemaName * Database schema to check against * @return Whether the database object belongs to the specified schema */ boolean belongsToSchema(final DatabaseObject dbObject, final String catalogName, final String schemaName) { if (dbObject == null) { return false; } final boolean supportsCatalogs = retrieverConnection.isSupportsCatalogs(); boolean belongsToCatalog = true; boolean belongsToSchema = true; if (supportsCatalogs) { final String dbObjectCatalogName = dbObject.getSchema().getCatalogName(); if (catalogName != null && !unquotedName(catalogName) .equals(unquotedName(dbObjectCatalogName))) { belongsToCatalog = false; } } final String dbObjectSchemaName = dbObject.getSchema().getName(); if (schemaName != null && !unquotedName(schemaName).equals(unquotedName(dbObjectSchemaName))) { belongsToSchema = false; } return belongsToCatalog && belongsToSchema; } Connection getDatabaseConnection() { return retrieverConnection.getConnection(); } DatabaseMetaData getMetaData() { return retrieverConnection.getMetaData(); } RetrieverConnection getRetrieverConnection() { return retrieverConnection; } Collection<Schema> getSchemas() { return database.getSchemas(); } /** * Creates a data type from the JDBC data type id, and the database * specific type name, if it does not exist. * * @param schema * Schema * @param javaSqlType * JDBC data type * @param databaseSpecificTypeName * Database specific type name * @return Column data type */ MutableColumnDataType lookupOrCreateColumnDataType(final Schema schema, final int javaSqlType, final String databaseSpecificTypeName) { MutableColumnDataType columnDataType = database .getColumnDataType(schema, databaseSpecificTypeName); if (columnDataType == null) { columnDataType = database .getSystemColumnDataType(databaseSpecificTypeName); } // Create new data type, if needed if (columnDataType == null) { columnDataType = new MutableColumnDataType(schema, databaseSpecificTypeName); // Set the Java SQL type code, but no mapped Java class is // available, so use the defaults columnDataType.setType(javaSqlType, null); database.addColumnDataType(columnDataType); } return columnDataType; } MutableRoutine lookupRoutine(final String catalogName, final String schemaName, final String routineName, final String specificName) { MutableRoutine routine = null; final Schema schema = new SchemaReference(catalogName, schemaName); if (schema != null) { final String routineLookupName; if (!Utility.isBlank(specificName)) { routineLookupName = specificName; } else { routineLookupName = routineName; } routine = (MutableRoutine) database .getRoutine(new SchemaReference(catalogName, schemaName), routineLookupName); } return routine; } MutableTable lookupTable(final String catalogName, final String schemaName, final String tableName) { MutableTable table = null; final Schema schema = new SchemaReference(catalogName, schemaName); if (schema != null) { table = database.getTable(new SchemaReference(catalogName, schemaName), tableName); } return table; } String quotedName(final String name) { final String quotedName; final RetrieverConnection retrieverConnection = getRetrieverConnection(); if (retrieverConnection != null && !Utility.isBlank(name)) { final String identifierQuoteString = retrieverConnection .getIdentifierQuoteString(); if (retrieverConnection.needsToBeQuoted(name)) { quotedName = identifierQuoteString + name + identifierQuoteString; } else { quotedName = name; } } else { quotedName = name; } return quotedName; } String unquotedName(final String name) { final String unquotedName; final RetrieverConnection retrieverConnection = getRetrieverConnection(); if (retrieverConnection != null && !Utility.isBlank(name)) { final String identifierQuoteString = retrieverConnection .getIdentifierQuoteString(); if (name.startsWith(identifierQuoteString) && name.endsWith(identifierQuoteString)) { final int quoteLength = identifierQuoteString.length(); unquotedName = name.substring(quoteLength, name.length() - quoteLength); } else { unquotedName = name; } } else { unquotedName = name; } return unquotedName; } }