package org.hibernate.cfg.reveng;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.hibernate.cfg.reveng.dialect.MetaDataDialect;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.mapping.Table;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class TableProcessor {
private static final Logger log = LoggerFactory.getLogger(TableProcessor.class);
public static Collection<Table> processTables(
MetaDataDialect metaDataDialect,
ReverseEngineeringStrategy revengStrategy,
String defaultSchema,
String defaultCatalog,
DatabaseCollector dbs,
SchemaSelection schemaSelection,
Set<Table> hasIndices,
ProgressListener progress) {
Map<String,Object> tableRs = null;
Iterator<Map<String,Object>> tableIterator = null;
List<Map<String,Object>> tables = new ArrayList<Map<String,Object>>();
boolean multiSchema = false;
// TODO: the code below detects if the reveng is multischema'ed, but not used for anything yet. should be used to remove schema/catalog info from output if only one schema/catalog used.
try {
progress.startSubTask("Finding tables in " + schemaSelection);
String matchCatalog = StringHelper.replace(schemaSelection.getMatchCatalog(),".*", "%");
String matchSchema = StringHelper.replace(schemaSelection.getMatchSchema(),".*", "%");
String matchTable = StringHelper.replace(schemaSelection.getMatchTable(),".*", "%");
tableIterator = metaDataDialect.getTables(matchCatalog, matchSchema, matchTable);
String[] lastQualifier = null;
String[] foundQualifier = new String[2];
while (tableIterator.hasNext() ) {
tableRs = tableIterator.next();
String tableName = (String) tableRs.get("TABLE_NAME");
String schemaName = (String) tableRs.get("TABLE_SCHEM");
String catalogName = (String) tableRs.get("TABLE_CAT");
TableIdentifier ti = new TableIdentifier(catalogName, schemaName, tableName);
if(revengStrategy.excludeTable(ti) ) {
log.debug("Table " + ti + " excluded by strategy");
continue;
}
if(!multiSchema) {
foundQualifier[0] = catalogName;
foundQualifier[1] = schemaName;
if(lastQualifier==null) {
lastQualifier=new String[2];
lastQualifier[0] = foundQualifier[0];
lastQualifier[1] = foundQualifier[1];
}
if((!safeEquals(lastQualifier[0],foundQualifier[0])) || (!safeEquals(lastQualifier[1],foundQualifier[1]))) {
multiSchema = true;
}
}
tables.add(new HashMap<String,Object>(tableRs));
}
}
finally {
try {
if (tableIterator!=null) metaDataDialect.close(tableIterator);
}
catch (Exception ignore) {
}
}
List<Table> processedTables = new ArrayList<Table>();
tableIterator = tables.iterator();
while (tableIterator.hasNext() ) {
tableRs = tableIterator.next();
String tableName = (String) tableRs.get("TABLE_NAME");
String schemaName = (String) tableRs.get("TABLE_SCHEM");
String catalogName = (String) tableRs.get("TABLE_CAT");
TableIdentifier ti = new TableIdentifier(catalogName, schemaName, tableName);
if(revengStrategy.excludeTable(ti) ) {
log.debug("Table " + ti + " excluded by strategy");
continue;
}
String comment = (String) tableRs.get("REMARKS");
String tableType = (String) tableRs.get("TABLE_TYPE");
if(dbs.getTable
(schemaName,
catalogName,
tableName)!=null) {
log.debug("Ignoring " + tableName + " since it has already been processed");
continue;
} else {
if ( ("TABLE".equalsIgnoreCase(tableType) || "VIEW".equalsIgnoreCase(tableType) || "SYNONYM".equals(tableType) ) ) { //||
// ("SYNONYM".equals(tableType) && isOracle() ) ) { // only on oracle ? TODO: HBX-218
// it's a regular table or a synonym
// ensure schema and catalogname is truly empty (especially mysql returns null schema, "" catalog)
if(schemaName!=null && schemaName.trim().length()==0) {
schemaName = null;
}
if(catalogName!=null && catalogName.trim().length()==0) {
catalogName=null;
}
log.debug("Adding table " + tableName + " of type " + tableType);
progress.startSubTask("Found " + tableName);
Table table = dbs.addTable(schemaName, catalogName, tableName);
table.setComment(comment);
if(tableType.equalsIgnoreCase("TABLE")) {
hasIndices.add(table);
}
processedTables.add( table );
}
else {
log.debug("Ignoring table " + tableName + " of type " + tableType);
}
}
}
return processedTables;
}
private static boolean safeEquals(Object value, Object tf) {
if(value==tf) return true;
if(value==null) return false;
return value.equals(tf);
}
}