All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.hibernate.cfg.reveng.JDBCReader Maven / Gradle / Ivy

There is a newer version: 5.6.15.Final
Show newest version
package org.hibernate.cfg.reveng;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.hibernate.cfg.reveng.dialect.MetaDataDialect;
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
import org.hibernate.exception.spi.SQLExceptionConverter;
import org.hibernate.mapping.ForeignKey;
import org.hibernate.mapping.Table;

public class JDBCReader {

	private final ReverseEngineeringStrategy revengStrategy;
	
	private MetaDataDialect metadataDialect;

	private final ConnectionProvider provider;

	private final SQLExceptionConverter sec;

	private final String defaultSchema;
	private final String defaultCatalog;
	
	public JDBCReader(MetaDataDialect dialect, ConnectionProvider provider, SQLExceptionConverter sec, String defaultCatalog, String defaultSchema, ReverseEngineeringStrategy reveng) {
		this.metadataDialect = dialect;
		this.provider = provider;
		this.sec = sec;
		this.revengStrategy = reveng;
		this.defaultCatalog = defaultCatalog;
		this.defaultSchema = defaultSchema;
		if(revengStrategy==null) {
			throw new IllegalStateException("Strategy cannot be null");
		}
	}
		
	public List readDatabaseSchema(DatabaseCollector dbs, String catalog, String schema, ProgressListener progress) {
		try {
			ReverseEngineeringRuntimeInfo info = new ReverseEngineeringRuntimeInfo(provider, sec, dbs);
			getMetaDataDialect().configure(info);
			revengStrategy.configure(info);
			
			Set
hasIndices = new HashSet
(); List schemaSelectors = revengStrategy.getSchemaSelections(); List
foundTables = new ArrayList
(); if(schemaSelectors==null) { foundTables.addAll(TableProcessor.processTables(getMetaDataDialect(), revengStrategy, defaultSchema, defaultCatalog, dbs, new SchemaSelection(catalog, schema), hasIndices, progress)); } else { for (Iterator iter = schemaSelectors.iterator(); iter.hasNext();) { SchemaSelection selection = iter.next(); foundTables.addAll(TableProcessor.processTables(getMetaDataDialect(), revengStrategy, defaultSchema, defaultCatalog, dbs, selection, hasIndices, progress)); } } Iterator
tables = foundTables.iterator(); // not dbs.iterateTables() to avoid "double-read" of columns etc. while ( tables.hasNext() ) { Table table = tables.next(); BasicColumnProcessor.processBasicColumns(getMetaDataDialect(), revengStrategy, defaultSchema, defaultCatalog, table, progress); PrimaryKeyProcessor.processPrimaryKey(getMetaDataDialect(), revengStrategy, defaultSchema, defaultCatalog, dbs, table); if(hasIndices.contains(table)) { IndexProcessor.processIndices(getMetaDataDialect(), defaultSchema, defaultCatalog, table); } } tables = foundTables.iterator(); //dbs.iterateTables(); Map> oneToManyCandidates = resolveForeignKeys( dbs, tables, progress ); dbs.setOneToManyCandidates(oneToManyCandidates); return foundTables; } finally { getMetaDataDialect().close(); revengStrategy.close(); } } /** * Iterates the tables and find all the foreignkeys that refers to something that is available inside the DatabaseCollector. * @param dbs * @param progress * @param tables * @return */ private Map> resolveForeignKeys(DatabaseCollector dbs, Iterator
tables, ProgressListener progress) { List fks = new ArrayList(); while ( tables.hasNext() ) { Table table = (Table) tables.next(); // Done here after the basic process of collections as we might not have touched // all referenced tables (this ensure the columns are the same instances througout the basic JDBC derived model. // after this stage it should be "ok" to divert from keeping columns in sync as it can be required if the same //column is used with different aliases in the ORM mapping. ForeignKeysInfo foreignKeys = ForeignKeyProcessor.processForeignKeys(getMetaDataDialect(), revengStrategy, defaultSchema, defaultCatalog, dbs, table, progress); fks.add( foreignKeys ); } Map> oneToManyCandidates = new HashMap>(); for (Iterator iter = fks.iterator(); iter.hasNext();) { ForeignKeysInfo element = iter.next(); Map> map = element.process( revengStrategy ); // the actual foreignkey is created here. mergeMultiMap( oneToManyCandidates, map ); } return oneToManyCandidates; } public MetaDataDialect getMetaDataDialect() { return metadataDialect; } private void mergeMultiMap(Map> dest, Map> src) { Iterator>> items = src.entrySet().iterator(); while ( items.hasNext() ) { Entry> element = items.next(); List existing = dest.get( element.getKey() ); if(existing == null) { dest.put( element.getKey(), element.getValue() ); } else { existing.addAll(element.getValue()); } } } static class NoopProgressListener implements ProgressListener { public void startSubTask(String name) { // noop }; } } public List
readDatabaseSchema(DatabaseCollector dbs, String catalog, String schema) { return readDatabaseSchema(dbs, catalog, schema, new NoopProgressListener()); } public Set readSequences(String sql) { Set sequences = new HashSet(); if (sql!=null) { Connection connection = null; try { connection = provider.getConnection(); Statement statement = null; ResultSet rs = null; try { statement = connection.createStatement(); rs = statement.executeQuery(sql); while ( rs.next() ) { sequences.add( rs.getString(1).toLowerCase().trim() ); } } finally { if (rs!=null) rs.close(); if (statement!=null) statement.close(); } } catch (SQLException e) { sec.convert(e, "Problem while closing connection", null); } finally { if(connection!=null) try { provider.closeConnection( connection ); } catch (SQLException e) { sec.convert(e, "Problem while closing connection", null); } } } return sequences; } }