Clover Coverage Report - SmartWeb
Coverage timestamp: Sun Jun 8 2008 21:20:12 CEST
../../../img/srcFileCovDistChart0.png 29% of files have more coverage
133   386   53   3,91
38   309   0,4   34
34     1,56  
1    
 
  SQLQueryImpl       Line # 52 133 53 0% 0.0
 
No Tests
 
1    //$Id: SQLQueryImpl.java 10861 2006-11-22 00:11:25Z steve.ebersole@jboss.com $
2    package org.hibernate.impl;
3   
4    import java.util.ArrayList;
5    import java.util.Arrays;
6    import java.util.Collection;
7    import java.util.Iterator;
8    import java.util.List;
9    import java.util.Map;
10    import java.util.Set;
11    import java.io.Serializable;
12    import java.math.BigInteger;
13   
14    import org.hibernate.FlushMode;
15    import org.hibernate.HibernateException;
16    import org.hibernate.LockMode;
17    import org.hibernate.Query;
18    import org.hibernate.QueryException;
19    import org.hibernate.SQLQuery;
20    import org.hibernate.ScrollMode;
21    import org.hibernate.ScrollableResults;
22    import org.hibernate.MappingException;
23    import org.hibernate.Session;
24    import org.hibernate.engine.query.sql.NativeSQLQuerySpecification;
25    import org.hibernate.engine.ResultSetMappingDefinition;
26    import org.hibernate.engine.NamedSQLQueryDefinition;
27    import org.hibernate.engine.QueryParameters;
28    import org.hibernate.engine.SessionImplementor;
29    import org.hibernate.engine.TypedValue;
30    import org.hibernate.engine.query.ParameterMetadata;
31    import org.hibernate.engine.query.sql.NativeSQLQueryJoinReturn;
32    import org.hibernate.engine.query.sql.NativeSQLQueryScalarReturn;
33    import org.hibernate.engine.query.sql.NativeSQLQueryRootReturn;
34    import org.hibernate.engine.query.sql.NativeSQLQueryReturn;
35    import org.hibernate.type.Type;
36    import org.hibernate.util.CollectionHelper;
37    import org.hibernate.util.StringHelper;
38   
39    /**
40    * Implements SQL query passthrough.
41    *
42    * <pre>
43    * <sql-query name="mySqlQuery">
44    * <return alias="person" class="eg.Person"/>
45    * SELECT {person}.NAME AS {person.name}, {person}.AGE AS {person.age}, {person}.SEX AS {person.sex}
46    * FROM PERSON {person} WHERE {person}.NAME LIKE 'Hiber%'
47    * </sql-query>
48    * </pre>
49    *
50    * @author gperrone
51    */
 
52    public class SQLQueryImpl extends AbstractQueryImpl implements SQLQuery {
53   
54    private final List queryReturns;
55    private Collection querySpaces;
56    private final boolean callable;
57    private boolean autodiscovertypes;
58   
59    /**
60    * Constructs a SQLQueryImpl given a sql query defined in the mappings.
61    *
62    * @param queryDef The representation of the defined <sql-query/>.
63    * @param session The session to which this SQLQueryImpl belongs.
64    * @param parameterMetadata Metadata about parameters found in the query.
65    */
 
66  0 toggle SQLQueryImpl(NamedSQLQueryDefinition queryDef, SessionImplementor session, ParameterMetadata parameterMetadata) {
67  0 super( queryDef.getQueryString(), queryDef.getFlushMode(), session, parameterMetadata );
68  0 if ( queryDef.getResultSetRef() != null ) {
69  0 ResultSetMappingDefinition definition = session.getFactory()
70    .getResultSetMapping( queryDef.getResultSetRef() );
71  0 if (definition == null) {
72  0 throw new MappingException(
73    "Unable to find resultset-ref definition: " +
74    queryDef.getResultSetRef()
75    );
76    }
77  0 this.queryReturns = Arrays.asList( definition.getQueryReturns() );
78    }
79    else {
80  0 this.queryReturns = Arrays.asList( queryDef.getQueryReturns() );
81    }
82   
83  0 this.querySpaces = queryDef.getQuerySpaces();
84  0 this.callable = queryDef.isCallable();
85    }
86   
 
87  0 toggle SQLQueryImpl(
88    final String sql,
89    final List queryReturns,
90    final Collection querySpaces,
91    final FlushMode flushMode,
92    boolean callable,
93    final SessionImplementor session,
94    ParameterMetadata parameterMetadata) {
95    // TODO : absolutely no usages of this constructor form; can it go away?
96  0 super( sql, flushMode, session, parameterMetadata );
97  0 this.queryReturns = queryReturns;
98  0 this.querySpaces = querySpaces;
99  0 this.callable = callable;
100    }
101   
 
102  0 toggle SQLQueryImpl(
103    final String sql,
104    final String returnAliases[],
105    final Class returnClasses[],
106    final LockMode[] lockModes,
107    final SessionImplementor session,
108    final Collection querySpaces,
109    final FlushMode flushMode,
110    ParameterMetadata parameterMetadata) {
111    // TODO : this constructor form is *only* used from constructor directly below us; can it go away?
112  0 super( sql, flushMode, session, parameterMetadata );
113  0 queryReturns = new ArrayList(returnAliases.length);
114  0 for ( int i=0; i<returnAliases.length; i++ ) {
115  0 NativeSQLQueryRootReturn ret = new NativeSQLQueryRootReturn(
116    returnAliases[i],
117    returnClasses[i].getName(),
118  0 lockModes==null ? LockMode.NONE : lockModes[i]
119    );
120  0 queryReturns.add(ret);
121    }
122  0 this.querySpaces = querySpaces;
123  0 this.callable = false;
124    }
125   
 
126  0 toggle SQLQueryImpl(
127    final String sql,
128    final String returnAliases[],
129    final Class returnClasses[],
130    final SessionImplementor session,
131    ParameterMetadata parameterMetadata) {
132  0 this( sql, returnAliases, returnClasses, null, session, null, null, parameterMetadata );
133    }
134   
 
135  0 toggle SQLQueryImpl(String sql, SessionImplementor session, ParameterMetadata parameterMetadata) {
136  0 super( sql, null, session, parameterMetadata );
137  0 queryReturns = new ArrayList();
138  0 querySpaces = null;
139  0 callable = false;
140    }
141   
142    private static final NativeSQLQueryReturn[] NO_SQL_RETURNS = new NativeSQLQueryReturn[0];
143   
 
144  0 toggle private NativeSQLQueryReturn[] getQueryReturns() {
145  0 return ( NativeSQLQueryReturn[] ) queryReturns.toArray( NO_SQL_RETURNS );
146    }
147   
 
148  0 toggle public List list() throws HibernateException {
149  0 verifyParameters();
150  0 before();
151   
152  0 Map namedParams = getNamedParams();
153  0 NativeSQLQuerySpecification spec = generateQuerySpecification( namedParams );
154   
155  0 try {
156  0 return getSession().list( spec, getQueryParameters( namedParams ) );
157    }
158    finally {
159  0 after();
160    }
161    }
162   
 
163  0 toggle private NativeSQLQuerySpecification generateQuerySpecification(Map namedParams) {
164  0 return new NativeSQLQuerySpecification(
165    expandParameterLists(namedParams),
166    getQueryReturns(),
167    querySpaces
168    );
169    }
170   
 
171  0 toggle public ScrollableResults scroll(ScrollMode scrollMode) throws HibernateException {
172  0 verifyParameters();
173  0 before();
174   
175  0 Map namedParams = getNamedParams();
176  0 NativeSQLQuerySpecification spec = generateQuerySpecification( namedParams );
177   
178  0 QueryParameters qp = getQueryParameters( namedParams );
179  0 qp.setScrollMode( scrollMode );
180   
181  0 try {
182  0 return getSession().scroll( spec, qp );
183    }
184    finally {
185  0 after();
186    }
187    }
188   
 
189  0 toggle public ScrollableResults scroll() throws HibernateException {
190  0 return scroll(ScrollMode.SCROLL_INSENSITIVE);
191    }
192   
 
193  0 toggle public Iterator iterate() throws HibernateException {
194  0 throw new UnsupportedOperationException("SQL queries do not currently support iteration");
195    }
196   
 
197  0 toggle public QueryParameters getQueryParameters(Map namedParams) {
198  0 QueryParameters qp = super.getQueryParameters(namedParams);
199  0 qp.setCallable(callable);
200  0 qp.setAutoDiscoverScalarTypes(autodiscovertypes);
201  0 return qp;
202    }
203   
 
204  0 toggle protected void verifyParameters() {
205  0 verifyParameters( callable );
206  0 boolean noReturns = queryReturns==null || queryReturns.isEmpty();
207  0 if ( noReturns ) {
208  0 this.autodiscovertypes = noReturns;
209    }
210    else {
211  0 Iterator itr = queryReturns.iterator();
212  0 while ( itr.hasNext() ) {
213  0 NativeSQLQueryReturn rtn = ( NativeSQLQueryReturn ) itr.next();
214  0 if ( rtn instanceof NativeSQLQueryScalarReturn ) {
215  0 NativeSQLQueryScalarReturn scalar = ( NativeSQLQueryScalarReturn ) rtn;
216  0 if ( scalar.getType() == null ) {
217  0 autodiscovertypes = true;
218  0 break;
219    }
220    }
221    }
222    }
223    }
224   
 
225  0 toggle public String[] getReturnAliases() throws HibernateException {
226  0 throw new UnsupportedOperationException("SQL queries do not currently support returning aliases");
227    }
228   
 
229  0 toggle public Type[] getReturnTypes() throws HibernateException {
230  0 throw new UnsupportedOperationException("not yet implemented for SQL queries");
231    }
232   
 
233  0 toggle public Query setLockMode(String alias, LockMode lockMode) {
234  0 throw new UnsupportedOperationException("cannot set the lock mode for a native SQL query");
235    }
236   
 
237  0 toggle protected Map getLockModes() {
238    //we never need to apply locks to the SQL
239  0 return CollectionHelper.EMPTY_MAP;
240    }
241   
 
242  0 toggle public SQLQuery addScalar(String columnAlias, Type type) {
243  0 queryReturns.add( new NativeSQLQueryScalarReturn( columnAlias, type ) );
244  0 return this;
245    }
246   
 
247  0 toggle public SQLQuery addScalar(String columnAlias) {
248  0 autodiscovertypes = true;
249  0 queryReturns.add( new NativeSQLQueryScalarReturn( columnAlias, null ) );
250  0 return this;
251    }
252   
 
253  0 toggle public SQLQuery addJoin(String alias, String path) {
254  0 return addJoin(alias, path, LockMode.READ);
255    }
256   
 
257  0 toggle public SQLQuery addEntity(Class entityClass) {
258  0 return addEntity( StringHelper.unqualify( entityClass.getName() ), entityClass );
259    }
260   
 
261  0 toggle public SQLQuery addEntity(String entityName) {
262  0 return addEntity( StringHelper.unqualify( entityName ), entityName );
263    }
264   
 
265  0 toggle public SQLQuery addEntity(String alias, String entityName) {
266  0 return addEntity(alias, entityName, LockMode.READ);
267    }
268   
 
269  0 toggle public SQLQuery addEntity(String alias, Class entityClass) {
270  0 return addEntity( alias, entityClass.getName() );
271    }
272   
 
273  0 toggle public SQLQuery addJoin(String alias, String path, LockMode lockMode) {
274  0 int loc = path.indexOf('.');
275  0 if ( loc < 0 ) {
276  0 throw new QueryException( "not a property path: " + path );
277    }
278  0 String ownerAlias = path.substring(0, loc);
279  0 String role = path.substring(loc+1);
280  0 queryReturns.add( new NativeSQLQueryJoinReturn(alias, ownerAlias, role, CollectionHelper.EMPTY_MAP, lockMode) );
281  0 return this;
282    }
283   
 
284  0 toggle public SQLQuery addEntity(String alias, String entityName, LockMode lockMode) {
285  0 queryReturns.add( new NativeSQLQueryRootReturn(alias, entityName, lockMode) );
286  0 return this;
287    }
288   
 
289  0 toggle public SQLQuery addEntity(String alias, Class entityClass, LockMode lockMode) {
290  0 return addEntity( alias, entityClass.getName(), lockMode );
291    }
292   
 
293  0 toggle public SQLQuery setResultSetMapping(String name) {
294  0 ResultSetMappingDefinition mapping = session.getFactory().getResultSetMapping( name );
295  0 if ( mapping == null ) {
296  0 throw new MappingException( "Unknown SqlResultSetMapping [" + name + "]" );
297    }
298  0 NativeSQLQueryReturn[] returns = mapping.getQueryReturns();
299  0 int length = returns.length;
300  0 for ( int index = 0 ; index < length ; index++ ) {
301  0 queryReturns.add( returns[index] );
302    }
303  0 return this;
304    }
305   
 
306  0 toggle public SQLQuery addSynchronizedQuerySpace(String querySpace) {
307  0 if ( querySpaces == null ) {
308  0 querySpaces = new ArrayList();
309    }
310  0 querySpaces.add( querySpace );
311  0 return this;
312    }
313   
 
314  0 toggle public SQLQuery addSynchronizedEntityName(String entityName) {
315  0 return addQuerySpaces( getSession().getFactory().getEntityPersister( entityName ).getQuerySpaces() );
316    }
317   
 
318  0 toggle public SQLQuery addSynchronizedEntityClass(Class entityClass) {
319  0 return addQuerySpaces( getSession().getFactory().getEntityPersister( entityClass.getName() ).getQuerySpaces() );
320    }
321   
 
322  0 toggle private SQLQuery addQuerySpaces(Serializable[] spaces) {
323  0 if ( spaces != null ) {
324  0 if ( querySpaces == null ) {
325  0 querySpaces = new ArrayList();
326    }
327  0 for ( int i = 0; i < spaces.length; i++ ) {
328  0 querySpaces.add( spaces[i] );
329    }
330    }
331  0 return this;
332    }
333   
 
334  0 toggle public int executeUpdate() throws HibernateException {
335  0 Map namedParams = getNamedParams();
336  0 before();
337  0 try {
338  0 return getSession().executeNativeUpdate(
339    generateQuerySpecification( namedParams ),
340    getQueryParameters( namedParams )
341    );
342    }
343    finally {
344  0 after();
345    }
346    }
347   
348    /**
349    * @see org.hibernate.Query#count()
350    */
 
351  0 toggle public int count() throws HibernateException {
352  0 StringBuffer sqlQuery = new StringBuffer(this.getQueryString().toUpperCase());
353  0 StringBuffer sqlQueryBuffer = new StringBuffer();
354  0 sqlQueryBuffer.append("SELECT COUNT(*) ");
355  0 int start = sqlQuery.indexOf("FROM");
356  0 int stop = sqlQuery.indexOf("ORDER BY");
357  0 if (stop >= 0) {
358  0 sqlQueryBuffer.append(this.getQueryString().substring(start, stop));
359    } else {
360  0 sqlQueryBuffer.append(this.getQueryString().substring(start));
361    }
362  0 Query countQuery = ((Session)this.session).createSQLQuery(sqlQueryBuffer.toString());
363   
364    //SET NAMED PARAMS
365  0 Map parameters = this.getNamedParams();
366  0 Set parameterNames = parameters.keySet();
367  0 Iterator iter = parameterNames.iterator();
368  0 while (iter.hasNext()) {
369  0 String name = (String)iter.next();
370  0 TypedValue typedValue = (TypedValue)parameters.get(name);
371  0 countQuery.setParameter(name, typedValue.getValue(), typedValue.getType());
372    }
373   
374    //SET POSITIONAL PARAMS
375  0 List paramTypes = this.getTypes();
376  0 List paramValues = this.getValues();
377  0 if (paramTypes != null && paramTypes.size() > 0) {
378  0 for (int i = 0; i < paramTypes.size(); i++) {
379  0 countQuery.setParameter(i, paramValues.get(i), (Type)paramTypes.get(i));
380    }
381    }
382  0 int count = ((BigInteger)countQuery.uniqueResult()).intValue();
383  0 return count;
384    }
385   
386    }