[hibernate-commits] Hibernate SVN: r11394 - in branches/Branch_3_2/HibernateExt/tools/src: test/org/hibernate/tool/hbm2x and 1 other directory.

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Sat Apr 7 04:43:43 EDT 2007


Author: max.andersen at jboss.com
Date: 2007-04-07 04:43:43 -0400 (Sat, 07 Apr 2007)
New Revision: 11394

Added:
   branches/Branch_3_2/HibernateExt/tools/src/java/org/hibernate/cfg/reveng/dialect/CachedMetaDataDialect.java
   branches/Branch_3_2/HibernateExt/tools/src/test/org/hibernate/tool/hbm2x/CachedMetaDataTest.java
Log:
HBX-924  Create a CachedMetaDataDialect

Added: branches/Branch_3_2/HibernateExt/tools/src/java/org/hibernate/cfg/reveng/dialect/CachedMetaDataDialect.java
===================================================================
--- branches/Branch_3_2/HibernateExt/tools/src/java/org/hibernate/cfg/reveng/dialect/CachedMetaDataDialect.java	                        (rev 0)
+++ branches/Branch_3_2/HibernateExt/tools/src/java/org/hibernate/cfg/reveng/dialect/CachedMetaDataDialect.java	2007-04-07 08:43:43 UTC (rev 11394)
@@ -0,0 +1,191 @@
+package org.hibernate.cfg.reveng.dialect;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.hibernate.connection.ConnectionProvider;
+import org.hibernate.exception.SQLExceptionConverter;
+
+public class CachedMetaDataDialect implements MetaDataDialect {
+	
+	MetaDataDialect delegate;
+	private Map cachedTables = new HashMap();
+	private Map cachedColumns = new HashMap();
+	private Map cachedExportedKeys = new HashMap();
+	private Map cachedPrimaryKeys = new HashMap();
+	private Map cachedIndexInfo = new HashMap();
+
+	public CachedMetaDataDialect(MetaDataDialect realMetaData) {
+		this.delegate = realMetaData;
+	}
+	
+	public void close() {
+		delegate.close();
+	}
+
+	public void close(Iterator iterator) {
+		if(iterator instanceof CachedIterator) {
+			CachedIterator ci = (CachedIterator) iterator;
+			if(ci.getOwner()==this) {
+				ci.store();
+				return;
+			} 
+		}
+		delegate.close( iterator );
+	}
+
+	public void configure(ConnectionProvider provider, SQLExceptionConverter sec) {
+		delegate.configure( provider, sec );
+	}
+
+	public Iterator getColumns(String catalog, String schema, String table, String column) {
+		StringKey sk = new StringKey(new String[] { catalog, schema, table, column });
+		List cached = (List) cachedColumns.get( sk );
+		if(cached==null) {
+			cached = new ArrayList();
+			return new CachedIterator(this, cachedColumns, sk, cached, delegate.getColumns( catalog, schema, table, column ));
+		} else {
+			return cached.iterator();
+		}		
+	}
+
+	public Iterator getExportedKeys(String catalog, String schema, String table) {
+		StringKey sk = new StringKey(new String[] { catalog, schema, table });
+		List cached = (List) cachedExportedKeys.get( sk );
+		if(cached==null) {
+			cached = new ArrayList();
+			return new CachedIterator(this, cachedExportedKeys, sk, cached, delegate.getExportedKeys( catalog, schema, table ));
+		} else {
+			return cached.iterator();
+		}		
+	}
+
+	public Iterator getIndexInfo(String catalog, String schema, String table) {
+		StringKey sk = new StringKey(new String[] { catalog, schema, table });
+		List cached = (List) cachedIndexInfo.get( sk );
+		if(cached==null) {
+			cached = new ArrayList();
+			return new CachedIterator(this, cachedIndexInfo, sk, cached, delegate.getIndexInfo( catalog, schema, table ));
+		} else {
+			return cached.iterator();
+		}
+	}
+
+	public Iterator getPrimaryKeys(String catalog, String schema, String name) {
+		StringKey sk = new StringKey(new String[] { catalog, schema, name });
+		List cached = (List) cachedPrimaryKeys .get( sk );
+		if(cached==null) {
+			cached = new ArrayList();
+			return new CachedIterator(this, cachedPrimaryKeys, sk, cached, delegate.getPrimaryKeys( catalog, schema, name ));
+		} else {
+			return cached.iterator();
+		}
+	}
+
+	public Iterator getTables(String catalog, String schema, String table) {
+		StringKey sk = new StringKey(new String[] { catalog, schema, table });
+		List cached = (List) cachedTables.get( sk );
+		if(cached==null) {
+			cached = new ArrayList();
+			return new CachedIterator(this, cachedTables, sk, cached, delegate.getTables( catalog, schema, table ));
+		} else {
+			return cached.iterator();
+		}
+	}
+
+	public boolean needQuote(String name) {
+		return delegate.needQuote( name );
+	}
+	
+	private static class StringKey {
+		String[] keys;
+		
+		StringKey(String[] key) {
+			this.keys=key;
+		}
+		
+		public int hashCode() {
+			if (keys == null)
+	            return 0;
+	 
+	        int result = 1;
+	 
+	        for (int i = 0; i < keys.length; i++) {
+				Object element = keys[i];
+			    result = 31 * result + (element == null ? 0 : element.hashCode());
+	        }
+	        
+	        return result;	 
+		}
+		
+		public boolean equals(Object obj) {
+			StringKey other = (StringKey) obj;
+			String[] otherKeys = other.keys;
+			
+			if(otherKeys.length!=keys.length) {
+				return false;
+			}
+			
+			for (int i = otherKeys.length-1; i >= 0; i--) {
+				if(!safeEquals(otherKeys[i],(keys[i]))) {
+					return false;
+				}
+			}
+			
+			return true;
+		}
+		
+		private boolean safeEquals(Object obj1, Object obj2) {
+			if ( obj1 == null ) {
+				return obj2 == null;
+			}
+	        return obj1.equals( obj2 );
+		}
+	}
+	
+	private static class CachedIterator implements Iterator {
+
+		private List cache; 
+		private StringKey target;
+		private Map destination;
+		private Iterator realIterator;
+		final CachedMetaDataDialect owner;
+		public CachedIterator(CachedMetaDataDialect owner, Map destination, StringKey sk, List cache, Iterator realIterator) {
+			this.owner = owner;
+			this.destination = destination;
+			this.target = sk;
+			this.realIterator = realIterator;
+			this.cache = cache;
+		}
+		
+		public CachedMetaDataDialect getOwner() {
+			return owner;
+		}
+
+		public boolean hasNext() {			
+			return realIterator.hasNext();
+		}
+
+		public Object next() {
+			Map map = (Map) realIterator.next();
+			cache.add(new HashMap(map)); // need to copy since MetaDataDialect might reuse it.
+			return map;
+		}
+
+		public void remove() {
+			realIterator.remove();
+		}
+
+		public void store() {
+			destination.put( target, cache );
+			cache = null;
+			target = null;
+			destination = null;
+			realIterator = null;			
+		}
+	}
+		
+}

Added: branches/Branch_3_2/HibernateExt/tools/src/test/org/hibernate/tool/hbm2x/CachedMetaDataTest.java
===================================================================
--- branches/Branch_3_2/HibernateExt/tools/src/test/org/hibernate/tool/hbm2x/CachedMetaDataTest.java	                        (rev 0)
+++ branches/Branch_3_2/HibernateExt/tools/src/test/org/hibernate/tool/hbm2x/CachedMetaDataTest.java	2007-04-07 08:43:43 UTC (rev 11394)
@@ -0,0 +1,176 @@
+/*
+ * Created on 2004-12-01
+ *
+ */
+package org.hibernate.tool.hbm2x;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.hibernate.cfg.JDBCMetaDataConfiguration;
+import org.hibernate.cfg.JDBCReaderFactory;
+import org.hibernate.cfg.Settings;
+import org.hibernate.cfg.reveng.DatabaseCollector;
+import org.hibernate.cfg.reveng.DefaultDatabaseCollector;
+import org.hibernate.cfg.reveng.DefaultReverseEngineeringStrategy;
+import org.hibernate.cfg.reveng.JDBCReader;
+import org.hibernate.cfg.reveng.SchemaSelection;
+import org.hibernate.cfg.reveng.dialect.CachedMetaDataDialect;
+import org.hibernate.cfg.reveng.dialect.JDBCMetaDataDialect;
+import org.hibernate.cfg.reveng.dialect.MetaDataDialect;
+import org.hibernate.connection.ConnectionProvider;
+import org.hibernate.exception.SQLExceptionConverter;
+import org.hibernate.mapping.Table;
+import org.hibernate.tool.JDBCMetaDataBinderTestCase;
+import org.hibernate.tool.hbm2x.IncrementalSchemaReadingTest.MockedMetaDataDialect;
+import org.hibernate.tool.hbmlint.detector.TableSelectorStrategy;
+
+
+
+/**
+ * @author max
+ *
+ */
+public class CachedMetaDataTest extends JDBCMetaDataBinderTestCase {
+
+	protected void configure(JDBCMetaDataConfiguration cfg) {
+		super.configure( cfg );
+	}
+	
+	public class MockedMetaDataDialect implements MetaDataDialect {
+
+		MetaDataDialect delegate;
+		private boolean failOnDelegateAccess;
+
+		public MockedMetaDataDialect(MetaDataDialect realMetaData) {
+			delegate = realMetaData;
+		}
+
+		public void close() {
+			delegate.close();
+		}
+
+		public void close(Iterator iterator) {
+			delegate.close( iterator );
+		}
+
+		public void configure(ConnectionProvider provider, SQLExceptionConverter sec) {
+			delegate.configure( provider, sec );			
+		}
+
+		public Iterator getColumns(String catalog, String schema, String table, String column) {
+			if(failOnDelegateAccess) {
+				throw new IllegalStateException("delegate not accessible");
+			} else {
+				return delegate.getColumns( catalog, schema, table, column );
+			}
+		}
+
+		public Iterator getExportedKeys(String catalog, String schema, String table) {
+			if(failOnDelegateAccess) {
+				throw new IllegalStateException("delegate not accessible");
+			} else {
+				return delegate.getExportedKeys( catalog, schema, table );
+			}
+		}
+
+		public Iterator getIndexInfo(String catalog, String schema, String table) {
+			if(failOnDelegateAccess) {
+				throw new IllegalStateException("delegate not accessible");
+			} else {
+				return delegate.getIndexInfo( catalog, schema, table );
+			}
+		}
+
+		public Iterator getPrimaryKeys(String catalog, String schema, String name) {
+			if(failOnDelegateAccess) {
+				throw new IllegalStateException("delegate not accessible");
+			} else {
+				return delegate.getPrimaryKeys( catalog, schema, name );
+			}
+		}
+
+		public Iterator getTables(String catalog, String schema, String table) {
+			if(failOnDelegateAccess) {
+				throw new IllegalStateException("delegate not accessible");
+			} else {
+				return delegate.getTables( catalog, schema, table );
+			}
+		}
+
+		public boolean needQuote(String name) {
+			return delegate.needQuote( name );
+		}
+
+		public void setDelegate(Object object) {
+			this.delegate = null;			
+		}
+
+		public void setFailOnDelegateAccess(boolean b) {
+			failOnDelegateAccess = b;			
+		}
+		
+	}
+	
+	public void testCachedDialect() {
+		Settings buildSettings = cfg.buildSettings();
+				
+		MetaDataDialect realMetaData = JDBCReaderFactory.newMetaDataDialect( cfg.getProperties() );
+		
+		MockedMetaDataDialect mock = new MockedMetaDataDialect(realMetaData);
+		CachedMetaDataDialect dialect = new CachedMetaDataDialect(mock);
+		
+		JDBCReader reader = JDBCReaderFactory.newJDBCReader( buildSettings, new DefaultReverseEngineeringStrategy(), dialect );
+		
+		DatabaseCollector dc = new DefaultDatabaseCollector();
+		reader.readDatabaseSchema( dc, null, null );
+
+		validate( dc );		
+		
+		mock.setFailOnDelegateAccess(true);
+		
+		reader = JDBCReaderFactory.newJDBCReader( buildSettings, new DefaultReverseEngineeringStrategy(), dialect );
+		
+		dc = new DefaultDatabaseCollector();
+		reader.readDatabaseSchema( dc, null, null );
+
+		validate(dc);
+		
+		
+		
+		
+	}
+
+	private void validate(DatabaseCollector dc) {
+		Iterator iterator = dc.iterateTables();
+		Table firstChild = (Table) iterator.next();
+		assertEquals(firstChild.getName(), "CHILD");
+		assertTrue(iterator.hasNext());
+		
+		iterator = dc.iterateTables();
+		assertNotNull(iterator.next());
+		assertNotNull(iterator.next());
+		assertFalse(iterator.hasNext());
+		
+		
+		assertHasNext("should have recorded one foreignkey to child table", 1, firstChild.getForeignKeyIterator() );
+	}
+
+	protected String[] getCreateSQL() {
+		
+		return new String[] {
+				"create table master ( id char not null, name varchar(20), primary key (id) )",
+				"create table child  ( childid char not null, masterref char, primary key (childid), foreign key (masterref) references master(id) )",				
+		};
+	}
+
+	protected String[] getDropSQL() {
+		
+		return new String[]  {
+				"drop table child",
+				"drop table master",				
+		};
+	}	
+	
+}




More information about the hibernate-commits mailing list