Update of /cvsroot/hibernate/Hibernate2/src/net/sf/hibernate/hql In directory sc8-pr-cvs1:/tmp/cvs-serv1150/sf/hibernate/hql Modified Files: ClauseParser.java PathExpressionParser.java QueryTranslator.java SelectParser.java Log Message: support for select new Result(....) syntax in HQL Index: ClauseParser.java =================================================================== RCS file: /cvsroot/hibernate/Hibernate2/src/net/sf/hibernate/hql/ClauseParser.java,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** ClauseParser.java 5 Jan 2003 02:11:21 -0000 1.3 --- ClauseParser.java 1 Mar 2003 12:15:26 -0000 1.4 *************** *** 22,28 **** String lcToken = token.toLowerCase(); ! if ( byExpected && !lcToken.equals("by") ) ! throw new QueryException("BY expected after GROUP or ORDER: " + token); ! if ( !enableSubselect && lcToken.equals("select") ) { --- 22,28 ---- String lcToken = token.toLowerCase(); ! if ( byExpected && !lcToken.equals("by") ) { ! throw new QueryException("BY expected after GROUP or ORDER: " + token); ! } if ( !enableSubselect && lcToken.equals("select") ) { Index: PathExpressionParser.java =================================================================== RCS file: /cvsroot/hibernate/Hibernate2/src/net/sf/hibernate/hql/PathExpressionParser.java,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** PathExpressionParser.java 1 Mar 2003 06:14:10 -0000 1.10 --- PathExpressionParser.java 1 Mar 2003 12:15:27 -0000 1.11 *************** *** 70,74 **** public void token(String token, QueryTranslator q) throws QueryException { ! path += token; String alias = q.getPathAlias(path); --- 70,74 ---- public void token(String token, QueryTranslator q) throws QueryException { ! if (token!=null) path += token; String alias = q.getPathAlias(path); Index: QueryTranslator.java =================================================================== RCS file: /cvsroot/hibernate/Hibernate2/src/net/sf/hibernate/hql/QueryTranslator.java,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -d -r1.15 -r1.16 *** QueryTranslator.java 1 Mar 2003 06:14:10 -0000 1.15 --- QueryTranslator.java 1 Mar 2003 12:15:27 -0000 1.16 *************** *** 3,6 **** --- 3,7 ---- import java.io.Serializable; + import java.lang.reflect.Constructor; import java.sql.PreparedStatement; import java.sql.ResultSet; *************** *** 36,39 **** --- 37,41 ---- import net.sf.hibernate.sql.QuerySelect; import net.sf.hibernate.type.EntityType; + import net.sf.hibernate.type.PrimitiveType; import net.sf.hibernate.type.Type; import net.sf.hibernate.util.ArrayHelper; *************** *** 79,83 **** protected boolean compiled; private String sqlString; ! private boolean hasScalars; private boolean shallowQuery; --- 81,86 ---- protected boolean compiled; private String sqlString; ! private Class holderClass; ! private Constructor holderConstructor; private boolean hasScalars; private boolean shallowQuery; *************** *** 480,483 **** --- 483,500 ---- sqlString = sql.toQueryString(); + Class[] classes = new Class[types.length]; + for ( int i=0; i<types.length; i++ ) { + if ( types[i]!=null ) classes[i] = (types[i] instanceof PrimitiveType) ? + ( (PrimitiveType) types[i] ).getPrimitiveClass() : + types[i].getReturnedClass(); + } + + try { + if (holderClass!=null) holderConstructor = holderClass.getConstructor(classes); + } + catch (NoSuchMethodException nsme) { + throw new QueryException("could not find constructor for: " + holderClass.getName(), nsme); + } + } *************** *** 777,780 **** --- 794,801 ---- } + Class getImportedClass(String name) { + return getImportedClass(name, factory); + } + private static Class getImportedClass(String name, SessionFactoryImplementor factory) { try { *************** *** 821,845 **** String[][] names = getScalarColumnNames(); int queryCols = returnTypes.length; ! if ( queryCols==1 ) { return returnTypes[0].nullSafeGet( rs, names[0], session, null ); } else { ! Object[] queryRow = new Object[queryCols]; for ( int i=0; i<queryCols; i++ ) ! queryRow[i] = returnTypes[i].nullSafeGet( rs, names[i], session, null ); ! return queryRow; } } ! else if ( returnTypes.length==1 && persisters.length>1 ) { // we are doing some outerjoining return row[ persisters.length-1 ]; ! } ! else { return (row.length==1) ? row[0] : row; } } QueryJoinFragment createJoinFragment() { return new QueryJoinFragment( factory.getDialect() ); } --- 842,877 ---- String[][] names = getScalarColumnNames(); int queryCols = returnTypes.length; ! if ( holderClass==null && queryCols==1 ) { return returnTypes[0].nullSafeGet( rs, names[0], session, null ); } else { ! row = new Object[queryCols]; for ( int i=0; i<queryCols; i++ ) ! row[i] = returnTypes[i].nullSafeGet( rs, names[i], session, null ); ! if (holderClass==null) return row; } } ! /*else if ( returnTypes.length==1 && persisters.length>1 ) { // we are doing some outerjoining return row[ persisters.length-1 ]; ! }*/ ! else if (holderClass==null) { return (row.length==1) ? row[0] : row; } + + try { + return holderConstructor.newInstance(row); + } + catch (Exception e) { + throw new QueryException("could not instantiate: " + holderClass, e); + } } QueryJoinFragment createJoinFragment() { return new QueryJoinFragment( factory.getDialect() ); + } + + void setHolderClass(Class clazz) { + holderClass = clazz; } Index: SelectParser.java =================================================================== RCS file: /cvsroot/hibernate/Hibernate2/src/net/sf/hibernate/hql/SelectParser.java,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** SelectParser.java 28 Feb 2003 07:01:28 -0000 1.6 --- SelectParser.java 1 Mar 2003 12:15:27 -0000 1.7 *************** *** 33,36 **** --- 33,38 ---- private boolean count; private boolean first; + private boolean afterNew; + private Class holderClass; private SelectPathExpressionParser pathExpressionParser = new SelectPathExpressionParser(); *************** *** 53,63 **** } ! if ( token.equals(StringHelper.COMMA) ) { if (ready) throw new QueryException("alias or expression expected in SELECT"); q.appendScalarSelectToken(StringHelper.COMMA_SPACE); ready=true; } else if ( StringHelper.OPEN_PAREN.equals(token) ) { ! if (aggregate) { q.appendScalarSelectToken(token); } --- 55,79 ---- } ! if (afterNew) { ! afterNew=false; ! holderClass = q.getImportedClass(token); ! if (holderClass==null) throw new QueryException("class not found: " + token); ! q.setHolderClass(holderClass); ! } ! else if ( token.equals(StringHelper.COMMA) ) { if (ready) throw new QueryException("alias or expression expected in SELECT"); q.appendScalarSelectToken(StringHelper.COMMA_SPACE); ready=true; } + else if ( "new".equals(lctoken) ) { + afterNew=true; + ready=false; + } else if ( StringHelper.OPEN_PAREN.equals(token) ) { ! if (holderClass!=null && !ready) { ! //opening paren in new Foo ( ... ) ! ready=true; ! } ! else if (aggregate) { q.appendScalarSelectToken(token); } *************** *** 68,72 **** } else if ( StringHelper.CLOSE_PAREN.equals(token) ) { ! if (aggregate && ready) { q.appendScalarSelectToken(token); } --- 84,91 ---- } else if ( StringHelper.CLOSE_PAREN.equals(token) ) { ! if (holderClass!=null && !ready) { ! //closing paren in new Foo ( ... ) ! } ! else if (aggregate && ready) { q.appendScalarSelectToken(token); } *************** *** 84,90 **** else if ( aggregateFunctions.contains(lctoken) ) { if (!ready) throw new QueryException(", expected before aggregate function in SELECT: " + token); - /*if ( !q.supportsScalars() ) throw new QueryException( - "aggregate functions may only be used in the select clause of iterate() queries: " + token - );*/ if ( lctoken.equals("count") ) { q.addScalarType(Hibernate.INTEGER); --- 103,106 ---- *************** *** 135,138 **** --- 151,156 ---- aggregate=false; count = false; + afterNew = false; + holderClass = null; } |