FileDocCategorySizeDatePackage
QueryTranslatorTestCase.javaAPI DocHibernate 3.2.518375Thu Mar 29 07:47:50 BST 2007org.hibernate.test.hql

QueryTranslatorTestCase

public abstract class QueryTranslatorTestCase extends org.hibernate.junit.functional.FunctionalTestCase
Test case superclass for testing QueryTranslator implementations.
author
josh Dec 6, 2004 8:21:21 AM

Fields Summary
Constructors Summary
public QueryTranslatorTestCase(String x)

		super( x );
		// Create an instance of HqlToken, so that it will have an entry point outside the package.  This
		// will stop IDEA's code inspector from suggesting that HqlToken should be package local.
		new HqlToken();
	
Methods Summary
private voidassertSQLEquals(java.lang.String message, java.lang.String oldsql, java.lang.String newsql)

		Map oldMap = getTokens(oldsql);
		Map newMap = getTokens(newsql);
		if ( !oldMap.equals(newMap) ) {
			assertEquals(message, oldsql, newsql);			
		}
		
		//String oldsqlStripped = stripExtraSpaces( oldsql );
		//String newsqlStripped = stripExtraSpaces( newsql );
		//assertEquals( message, oldsqlStripped, newsqlStripped );
	
public voidassertTranslation(java.lang.String hql)

		assertTranslation( hql, null );
	
public voidassertTranslation(java.lang.String hql, boolean scalar)

		assertTranslation( hql, null, scalar, null );
	
protected voidassertTranslation(java.lang.String hql, java.util.Map replacements)

		ComparisonFailure cf = null;
		try {
			assertTranslation( hql, replacements, false, null );
		}
		catch ( ComparisonFailure e ) {
			e.printStackTrace();
			cf = e;
		}
		if ("false".equals(System.getProperty("org.hibernate.test.hql.SkipScalarQuery","false"))) {
			// Run the scalar translation anyway, even if there was a comparison failure.
			assertTranslation( hql, replacements, true, null );
		}
		if (cf != null)
			throw cf;
	
protected voidassertTranslation(java.lang.String hql, java.util.Map replacements, boolean scalar, java.lang.String sql)

		SessionFactoryImplementor factory = getSessionFactoryImplementor();

		// Create an empty replacements map if we don't have one.
		if ( replacements == null ) {
			replacements = new HashMap();
		}

		// steve -> note that the empty maps here represent the currently enabled filters...
		QueryTranslator oldQueryTranslator = null;
		Exception oldException = null;
		try {
			System.out.println("Compiling with classic QueryTranslator...");
			QueryTranslatorFactory classic = new ClassicQueryTranslatorFactory();
			oldQueryTranslator = classic.createQueryTranslator( hql, hql, Collections.EMPTY_MAP, factory );
			oldQueryTranslator.compile( replacements, scalar );
		}
		catch ( QueryException e ) {
			oldException = e;
		}
		catch ( MappingException e ) {
			oldException = e;
		}

		QueryTranslator newQueryTranslator = null;
		Exception newException = null;
		try {
			System.out.println("Compiling with AST QueryTranslator...");
			newQueryTranslator = createNewQueryTranslator( hql, replacements, scalar );
		}
		catch ( QueryException e ) {
			newException = e;
		}
		catch ( MappingException e ) {
			newException = e;
		}

		// If the old QT threw an exception, the new one should too.
		if ( oldException != null ) {
//			oldException.printStackTrace();
			assertNotNull( "New query translator did *NOT* throw an exception, the old one did : " + oldException, newException );
			assertEquals( oldException.getMessage(), newException.getMessage() );
			return;	// Don't bother with the rest of the assertions.
		}
		else if ( newException != null ) {
			newException.printStackTrace();
			assertNull( "Old query translator did not throw an exception, the new one did", newException );
		}

		// -- check all of the outputs --
		checkSql( oldQueryTranslator, newQueryTranslator, hql, scalar, sql );
		checkQuerySpaces( oldQueryTranslator, newQueryTranslator );
		checkReturnedTypes( oldQueryTranslator, newQueryTranslator );
		checkColumnNames( oldQueryTranslator, newQueryTranslator );

	
private voidcheckBinds(java.sql.PreparedStatement oldps, java.sql.PreparedStatement newps, java.lang.Object[] binds)

		// Make sure the binds "feel" ok
		try {
			ParameterMetaData oldBindMetaData = oldps.getParameterMetaData();
			ParameterMetaData newBindMetaData = newps.getParameterMetaData();

			assertEquals( "Different bind parameter count", oldBindMetaData.getParameterCount(), newBindMetaData.getParameterCount() );
			assertEquals( "Incorrect number of binds passed in", oldBindMetaData.getParameterCount(), binds == null ? 0 : binds.length );

			for ( int i = 0, max = oldBindMetaData.getParameterCount(); i < max; i++ ) {
				assertEquals( "Different bind types", oldBindMetaData.getParameterType(i), newBindMetaData.getParameterType(i) );
			}
		}
		catch( Throwable t ) {
			fail( "SQLException comparing binds : " + t );
		}
	
private voidcheckColumnNames(org.hibernate.hql.QueryTranslator oldQueryTranslator, org.hibernate.hql.QueryTranslator newQueryTranslator)

		// Check the column names.

		String[][] oldColumnNames = oldQueryTranslator.getColumnNames();
		String[][] newColumnNames = newQueryTranslator.getColumnNames();
		/*assertEquals( "Column name array is not the right length!", oldColumnNames.length, newColumnNames.length );
		for ( int i = 0; i < oldColumnNames.length; i++ ) {
			assertEquals( "Column name array [" + i + "] is not the right length!", oldColumnNames[i].length, newColumnNames[i].length );
			for ( int j = 0; j < oldColumnNames[i].length; j++ ) {
				assertEquals( "Column name [" + i + "," + j + "]", oldColumnNames[i][j], newColumnNames[i][j] );
			}
		}*/
	
private voidcheckLogicalEquality(java.lang.Object oldval, java.lang.Object newval, org.hibernate.type.Type type)

		if ( oldval == null && newval == null ) {
			// two nulls are logically equivalent here...
			return;
		}
		else {
			assertTrue( "Different result values", type.isEqual(oldval, newval, EntityMode.POJO) );
		}
	
private voidcheckQuerySpaces(org.hibernate.hql.QueryTranslator oldQueryTranslator, org.hibernate.hql.QueryTranslator newQueryTranslator)

		// Check the query spaces for a regression.
		Set oldQuerySpaces = oldQueryTranslator.getQuerySpaces();
		Set querySpaces = newQueryTranslator.getQuerySpaces();
		assertEquals( "Query spaces is not the right size!", oldQuerySpaces.size(), querySpaces.size() );
		for ( Iterator iterator = oldQuerySpaces.iterator(); iterator.hasNext(); ) {
			Object o = iterator.next();
			assertTrue( "New query space does not contain " + o + "!", querySpaces.contains( o ) );
		}
	
private voidcheckResults(java.sql.ResultSet oldrs, java.sql.ResultSet newrs)

		ResultSetMetaData oldmeta = null;
		ResultSetMetaData newmeta = null;
		int colCount = 0;
		Type[] types = null;

		// first compare the metadata from the two results
		try {
			oldmeta = oldrs.getMetaData();
			newmeta = newrs.getMetaData();
			assertEquals( "Different column counts", oldmeta.getColumnCount(), newmeta.getColumnCount() );

			colCount = oldmeta.getColumnCount();
			types = new Type[colCount];

			for ( int i = 1, max = colCount; i < max; i++ ) {
				assertEquals( "Column names were different", oldmeta.getColumnName(i), newmeta.getColumnName(i) );
				assertEquals( "Column types were different", oldmeta.getColumnType(i), newmeta.getColumnType(i) );
				assertEquals( "Java types were different", oldmeta.getColumnClassName(i), newmeta.getColumnClassName(i) );
				types[i] = TypeFactory.basic( oldmeta.getColumnClassName(i) );
			}
		}
		catch( Throwable t ) {
			fail( "Error comparing result set metadata" );
		}

		// Then compare the actual results
		try {
			while ( oldrs.next() & newrs.next() ) {
				for ( int i = 1; i < colCount; i++ ) {
					Object oldval = oldrs.getObject(i);
					if ( oldrs.wasNull() ) oldval = null;
					Object newval = newrs.getObject(i);
					if ( newrs.wasNull() ) newval = null;
					checkLogicalEquality( oldval, newval, types[i] );
				}
			}

			// for "better reporting" purposes, make sure both result sets are fully exhausted
			while ( oldrs.next() );
			while ( newrs.next() );

			assertEquals( "Different row counts", oldrs.getRow(), newrs.getRow() );
		}
		catch( Throwable t ) {
			fail( "Error comparing result set structure" );
		}
	
private voidcheckReturnedTypes(org.hibernate.hql.QueryTranslator oldQueryTranslator, org.hibernate.hql.QueryTranslator newQueryTranslator)

		// Check the returned types for a regression.
		Type[] oldReturnTypes = oldQueryTranslator.getReturnTypes();
		Type[] returnTypes = newQueryTranslator.getReturnTypes();
		assertEquals( "Return types array is not the right length!", oldReturnTypes.length, returnTypes.length );
		for ( int i = 0; i < returnTypes.length; i++ ) {
			assertNotNull( returnTypes[i] );
			assertNotNull( oldReturnTypes[i] );
			assertEquals( "Returned types did not match!", oldReturnTypes[i].getReturnedClass(), returnTypes[i].getReturnedClass() );
			System.out.println("returnedType[" + i + "] = " + returnTypes[i] + " oldReturnTypes[" + i + "] = " + oldReturnTypes[i]);
		}
	
private voidcheckSql(org.hibernate.hql.QueryTranslator oldQueryTranslator, org.hibernate.hql.QueryTranslator newQueryTranslator, java.lang.String hql, boolean scalar, java.lang.String sql)


		String oldsql = oldQueryTranslator.getSQLString();
		String newsql = newQueryTranslator.getSQLString();
		System.out.println( "HQL    : " + ASTPrinter.escapeMultibyteChars(hql) );
		System.out.println( "OLD SQL: " + ASTPrinter.escapeMultibyteChars(oldsql) );
		System.out.println( "NEW SQL: " + ASTPrinter.escapeMultibyteChars(newsql) );
		if ( sql == null ) {
			// Check the generated SQL.                                          ASTPrinter.escapeMultibyteChars(
			assertSQLEquals( "SQL is not the same as the old SQL (scalar=" + scalar + ")", oldsql, newsql );
		}
		else {
			assertSQLEquals( "SQL is not the same as the expected SQL (scalar=" + scalar + ")", sql, newsql );
		}
	
private voidcheckSqlByResultSet(org.hibernate.hql.QueryTranslator oldQueryTranslator, org.hibernate.hql.QueryTranslator newQueryTranslator, java.lang.Object[] binds)

		String oldsql = oldQueryTranslator.getSQLString();
		String newsql = newQueryTranslator.getSQLString();

		Session session = openSession();
		Connection connection = session.connection();

		PreparedStatement oldps = null;
		PreparedStatement newps = null;
		ResultSet oldrs = null;
		ResultSet newrs = null;

		try {
			try {
				oldps = connection.prepareStatement( oldsql );
			}
			catch( Throwable t ) {
				fail( "Unable to prepare sql generated by old parser : " + t );
			}
			try {
				newps = connection.prepareStatement( newsql );
			}
			catch( Throwable t ) {
				fail( "Unable to prepare sql generated by new parser : " + t );
			}

			checkBinds(oldps, newps, binds);

			try {
				oldrs = executeQuery( oldps, binds );
			}
			catch( Throwable t ) {
				fail( "Unable to execute sql generated by old parser : " + t );
			}

			try {
				newrs = executeQuery( newps, binds );
			}
			catch( Throwable t ) {
				fail( "Unable to execute sql generated by new parser : " + t );
			}

			checkResults( oldrs, newrs );
		}
		finally {
			// make *sure* the sql resources get cleaned up
			release(oldrs);
			release(newrs);
			release(oldps);
			release(newps);
			release(session);
		}
	
protected java.lang.ExceptioncompileBadHql(java.lang.String hql, boolean scalar)

		QueryTranslator newQueryTranslator;
		Map replacements = null;
		Exception newException = null;
		SessionFactoryImplementor factory = getSessionFactoryImplementor();
		try {
			QueryTranslatorFactory ast = new ASTQueryTranslatorFactory();
			newQueryTranslator = ast.createQueryTranslator( hql, hql, Collections.EMPTY_MAP, factory );
			newQueryTranslator.compile( replacements, scalar );
		}
		catch ( QueryException e ) {
			newException = e;
		}
		catch ( MappingException e ) {
			newException = e;
		}
		assertNotNull( "Expected exception from compilation of '" + hql + "'!", newException );
		return newException;
	
protected org.hibernate.hql.ast.QueryTranslatorImplcreateNewQueryTranslator(java.lang.String hql, java.util.Map replacements, boolean scalar)

		SessionFactoryImplementor factory = getSessionFactoryImplementor();
		return createNewQueryTranslator( hql, replacements, scalar, factory );
	
private org.hibernate.hql.ast.QueryTranslatorImplcreateNewQueryTranslator(java.lang.String hql, java.util.Map replacements, boolean scalar, org.hibernate.engine.SessionFactoryImplementor factory)

		QueryTranslatorFactory ast = new ASTQueryTranslatorFactory();
		QueryTranslatorImpl newQueryTranslator = ( QueryTranslatorImpl ) ast.createQueryTranslator( hql, hql, Collections.EMPTY_MAP, factory );
		newQueryTranslator.compile( replacements, scalar );
		return newQueryTranslator;
	
protected org.hibernate.hql.ast.QueryTranslatorImplcreateNewQueryTranslator(java.lang.String hql)

		return createNewQueryTranslator( hql, new HashMap(), false );
	
protected org.hibernate.hql.ast.QueryTranslatorImplcreateNewQueryTranslator(java.lang.String hql, org.hibernate.engine.SessionFactoryImplementor sfimpl)

		return createNewQueryTranslator( hql, new HashMap(), false, sfimpl );
	
protected org.hibernate.engine.query.HQLQueryPlancreateQueryPlan(java.lang.String hql, boolean scalar)

		return new HQLQueryPlan( hql, scalar, Collections.EMPTY_MAP, getSessionFactoryImplementor() );
	
protected org.hibernate.engine.query.HQLQueryPlancreateQueryPlan(java.lang.String hql)

		return createQueryPlan( hql, false );
	
public booleancreateSchema()

		return false;
	
private java.sql.ResultSetexecuteQuery(java.sql.PreparedStatement ps, java.lang.Object[] binds)

		if ( binds != null ) {
			for ( int i = 0, max = binds.length; i < max; i++ ) {
				ps.setObject( i, binds[i] );
			}
		}

		return ps.executeQuery();
	
public java.lang.String[]getMappings()

		return new String[] {
				"hql/Animal.hbm.xml",
				"hql/EntityWithCrazyCompositeKey.hbm.xml",
				"hql/CrazyIdFieldNames.hbm.xml",
				"hql/SimpleEntityWithAssociation.hbm.xml",
				"hql/ComponentContainer.hbm.xml",
				"batchfetch/ProductLine.hbm.xml",
				"cid/Customer.hbm.xml",
				"cid/Order.hbm.xml",
				"cid/LineItem.hbm.xml",
				"cid/Product.hbm.xml",
				"legacy/Baz.hbm.xml",
				"legacy/Category.hbm.xml",
				"legacy/Commento.hbm.xml",
				"legacy/Container.hbm.xml",
				"legacy/Custom.hbm.xml",
				"legacy/Eye.hbm.xml",
				"legacy/Fee.hbm.xml",
				"legacy/FooBar.hbm.xml",
				"legacy/Fum.hbm.xml",
				"legacy/Glarch.hbm.xml",
				"legacy/Holder.hbm.xml",
				"legacy/Many.hbm.xml",
				"legacy/Marelo.hbm.xml",
				"legacy/MasterDetail.hbm.xml",
				"legacy/Middle.hbm.xml",
				"legacy/Multi.hbm.xml",
				"legacy/Nameable.hbm.xml",
				"legacy/One.hbm.xml",
				"legacy/Qux.hbm.xml",
				"legacy/Simple.hbm.xml",
				"legacy/SingleSeveral.hbm.xml",
				"legacy/WZ.hbm.xml",
				"legacy/UpDown.hbm.xml",
				"compositeelement/Parent.hbm.xml",
				"onetoone/joined/Person.hbm.xml",
				"any/Properties.hbm.xml"
		};
	
protected org.hibernate.engine.SessionFactoryImplementorgetSessionFactoryImplementor()

		SessionFactoryImplementor factory = ( SessionFactoryImplementor ) getSessions();
		if ( factory == null ) {
			throw new NullPointerException( "Unable to create factory!" );
		}
		return factory;
	
private java.util.MapgetTokens(java.lang.String sql)

		Map result = new TreeMap();
		if (sql==null) return result;
		result.put( "=", new Integer( StringHelper.countUnquoted(sql, '=") ) );
		StringTokenizer tokenizer = new StringTokenizer( sql, "(),= " );
		while ( tokenizer.hasMoreTokens() ) {
			String fragment = tokenizer.nextToken();
			/*if ( "on".equals(fragment) ) fragment = "and";
			if ( "join".equals(fragment) || "inner".equals(fragment) ) continue;*/
			Integer count = (Integer) result.get(fragment);
			if ( count==null ) {
				count = new Integer(1);
			}
			else {
				count = new Integer( count.intValue() + 1 );
			}
			result.put(fragment, count);
		}
		return result;
	
public booleanrecreateSchemaAfterFailure()

		return false;
	
private voidrelease(java.sql.PreparedStatement ps)

		if ( ps != null ) {
			try {
				ps.close();
			}
			catch( Throwable t ) {}
		}
	
private voidrelease(java.sql.ResultSet rs)

		if ( rs != null ) {
			try {
				rs.close();
			}
			catch( Throwable t ) {}
		}
	
private voidrelease(org.hibernate.classic.Session session)

		if ( session != null ) {
			try {
				session.close();
			}
			catch( Throwable t ) {}
		}
	
protected voidrunClassicTranslator(java.lang.String hql)

		SessionFactoryImplementor factory = getSessionFactoryImplementor();
		Map replacements = new HashMap();
		QueryTranslator oldQueryTranslator = null;
		try {
			QueryTranslatorFactory classic = new ClassicQueryTranslatorFactory();
			oldQueryTranslator = classic.createQueryTranslator( hql, hql, Collections.EMPTY_MAP, factory );
			oldQueryTranslator.compile( replacements, false );
		}
		catch ( Exception e ) {
			e.printStackTrace();
			throw e;
		}
		String oldsql = oldQueryTranslator.getSQLString();
		System.out.println( "HQL    : " + hql );
		System.out.println( "OLD SQL: " + oldsql );
	
private java.lang.StringstripExtraSpaces(java.lang.String string)

		if ( string == null ) {
			return null;
		}

		StringBuffer buffer = new StringBuffer( string.length() );
		char[] chars = string.toCharArray();
		int length = chars.length;
		boolean wasSpace = false;
		for ( int i = 0; i < length; i++ ) {
			boolean isSpace = chars[i] == ' ";
			if ( wasSpace && isSpace ) {
				continue;
			}
			else {
				buffer.append( chars[i] );
			}

			wasSpace = isSpace;
		}
//		StringTokenizer tokenizer = new StringTokenizer( string.trim(), " " );
//		while ( tokenizer.hasMoreTokens() ) {
//			final String fragment = tokenizer.nextToken();
//			buffer.append( fragment );
//			buffer.append( " " );
//		}
//
		return buffer.toString();