package org.beanfuse.db.meta;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.apache.commons.collections.map.CaseInsensitiveMap;
import org.apache.commons.lang.StringUtils;
import org.beanfuse.db.dialect.Dialect;
import org.beanfuse.db.dialect.SequenceSupport;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* JDBC database metadata
*
* @author chaostone
*/
public class DatabaseMetadata {
private static final Logger logger = LoggerFactory.getLogger(DatabaseMetadata.class);
private final Map<String, TableMetadata> tables = new CaseInsensitiveMap();
private final Set sequences = new HashSet();
private final boolean extras;
private DatabaseMetaData meta;
private Dialect dialect;
public DatabaseMetadata(Connection connection, Dialect dialect) {
this(connection, dialect, false);
}
public DatabaseMetadata(Connection connection, Dialect dialect, boolean extras) {
try {
meta = connection.getMetaData();
this.extras = extras;
this.dialect = dialect;
initSequences(connection);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
private static final String[] TYPES = { "TABLE", "VIEW" };
public TableMetadata getTableMetadata(String qualifiedName) {
return getTableMetadata(qualifiedName, null, null);
}
public TableMetadata getTableMetadata(String name, String schema, String catalog) {
String identifier = TableMetadata.qualify(catalog, schema, name);
TableMetadata table = (TableMetadata) tables.get(identifier);
if (table != null) {
return table;
} else {
try {
ResultSet rs = null;
try {
if (meta.storesUpperCaseQuotedIdentifiers()
&& meta.storesUpperCaseIdentifiers()) {
rs = meta.getTables(StringUtils.upperCase(catalog), StringUtils
.upperCase(schema), StringUtils.upperCase(name), TYPES);
} else if (meta.storesLowerCaseQuotedIdentifiers()
&& meta.storesLowerCaseIdentifiers()) {
rs = meta.getTables(StringUtils.lowerCase(catalog), StringUtils
.lowerCase(schema), StringUtils.lowerCase(name), TYPES);
} else {
rs = meta.getTables(catalog, schema, name, TYPES);
}
while (rs.next()) {
String tableName = rs.getString("TABLE_NAME");
if (name.equalsIgnoreCase(tableName)) {
table = new TableMetadata(rs, meta, extras);
tables.put(identifier, table);
return table;
}
}
logger.info("table not found: " + name);
return null;
} finally {
if (rs != null)
rs.close();
}
} catch (SQLException sqle) {
throw new RuntimeException(sqle);
}
}
}
public void loadAllMetadata(String schema, String catalog, boolean isQuoted) {
try {
ResultSet rs = null;
try {
if (meta.storesUpperCaseQuotedIdentifiers() && meta.storesUpperCaseIdentifiers()) {
rs = meta.getTables(StringUtils.upperCase(catalog), StringUtils
.upperCase(schema), null, TYPES);
} else if (meta.storesLowerCaseQuotedIdentifiers()
&& meta.storesLowerCaseIdentifiers()) {
rs = meta.getTables(StringUtils.lowerCase(catalog), StringUtils
.lowerCase(schema), null, TYPES);
} else {
rs = meta.getTables(catalog, schema, null, TYPES);
}
while (rs.next()) {
TableMetadata table = new TableMetadata(rs, meta, extras);
tables.put(table.identifier(), table);
}
} finally {
if (rs != null)
rs.close();
}
} catch (SQLException sqle) {
throw new RuntimeException(sqle);
}
}
private void initSequences(Connection connection) throws SQLException {
SequenceSupport ss = dialect.getSequenceSupport();
if (null == ss)
return;
String sql = ss.getQuerySequenceSql();
if (sql != null) {
Statement statement = null;
ResultSet rs = null;
try {
statement = connection.createStatement();
rs = statement.executeQuery(sql);
while (rs.next()) {
sequences.add(new SequenceMetadata(rs.getString(1).toLowerCase().trim()));
}
} finally {
if (rs != null)
rs.close();
if (statement != null)
statement.close();
}
}
}
public String toString() {
return "DatabaseMetadata" + tables.keySet().toString() + sequences.toString();
}
public Map<String, TableMetadata> getTables() {
return tables;
}
public Set getSequences() {
return sequences;
}
public Dialect getDialect() {
return dialect;
}
}