KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > amber > query > UserQuery


1 /*
2  * Copyright (c) 1998-2006 Caucho Technology -- all rights reserved
3  *
4  * This file is part of Resin(R) Open Source
5  *
6  * Each copy or derived work must preserve the copyright notice and this
7  * notice unmodified.
8  *
9  * Resin Open Source is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * Resin Open Source is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
17  * of NON-INFRINGEMENT. See the GNU General Public License for more
18  * details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with Resin Open Source; if not, write to the
22  *
23  * Free Software Foundation, Inc.
24  * 59 Temple Place, Suite 330
25  * Boston, MA 02111-1307 USA
26  *
27  * @author Scott Ferguson
28  */

29
30 package com.caucho.amber.query;
31
32 import com.caucho.amber.AmberQuery;
33 import com.caucho.amber.expr.ArgExpr;
34 import com.caucho.amber.manager.AmberConnection;
35 import com.caucho.amber.type.*;
36 import com.caucho.jdbc.JdbcMetaData;
37
38 import java.lang.reflect.InvocationTargetException JavaDoc;
39 import java.lang.reflect.Method JavaDoc;
40 import java.sql.PreparedStatement JavaDoc;
41 import java.sql.ResultSet JavaDoc;
42 import java.sql.ResultSetMetaData JavaDoc;
43 import java.sql.SQLException JavaDoc;
44 import java.util.ArrayList JavaDoc;
45 import java.util.List JavaDoc;
46 import java.util.Map JavaDoc;
47
48 /**
49  * Represents the application's view of the query.
50  */

51 public class UserQuery implements AmberQuery {
52   private AmberConnection _aConn;
53   private AbstractQuery _query;
54   private ResultSetImpl _rs;
55
56   private QueryCacheKey _cacheKey;
57
58   private Type []_argTypes;
59   private Object JavaDoc []_argValues;
60   private int _argLength = 0;
61
62   private int _firstResult = 0;
63   private int _maxResults = -1;
64
65   private long _cacheMaxAge;
66
67   private boolean _copyOnLoad = true;
68   private boolean _loadOnQuery;
69
70   public UserQuery(AbstractQuery query)
71   {
72     _query = query;
73
74     ArgExpr []argList = query.getArgList();
75
76     _argTypes = new Type[argList.length];
77     _argValues = new Object JavaDoc[argList.length];
78
79     _argLength = argList.length;
80   }
81
82   /**
83    * Returns the query string.
84    */

85   public String JavaDoc getQueryString()
86   {
87     return _query.getQueryString();
88   }
89
90   public void init(AmberConnection aConn)
91   {
92     setSession(aConn);
93   }
94
95   public void setSession(AmberConnection aConn)
96   {
97     _aConn = aConn;
98   }
99
100   public AmberConnection getSession()
101   {
102     return _aConn;
103   }
104
105   public AmberConnection getConnection()
106   {
107     return _aConn;
108   }
109
110   /**
111    * Sets true for load-on-query.
112    */

113   public void setLoadOnQuery(boolean loadOnQuery)
114   {
115     _loadOnQuery = loadOnQuery;
116   }
117
118   /**
119    * Returns the compiled query.
120    */

121   AbstractQuery getQuery()
122   {
123     return _query;
124   }
125
126   /**
127    * Returns the arg type array.
128    */

129   Type []getArgTypes()
130   {
131     return _argTypes;
132   }
133
134   /**
135    * Returns the arg values
136    */

137   Object JavaDoc []getArgValues()
138   {
139     return _argValues;
140   }
141
142   /**
143    * Returns the arg length
144    */

145   int getArgLength()
146   {
147     return _argLength;
148   }
149
150   /**
151    * Sets the argument with a string
152    */

153   public void setString(int index, String JavaDoc v)
154   {
155     _argTypes[index - 1] = StringType.create();
156     _argValues[index - 1] = v;
157     _argLength = index;
158   }
159
160   /**
161    * Sets the argument with a byte
162    */

163   public void setByte(int index, byte v)
164   {
165     _argTypes[index - 1] = ByteType.create();
166     _argValues[index - 1] = new Integer JavaDoc(v);
167     _argLength = index;
168   }
169
170   /**
171    * Sets the argument with a short
172    */

173   public void setShort(int index, short v)
174   {
175     _argTypes[index - 1] = ShortType.create();
176     _argValues[index - 1] = new Integer JavaDoc(v);
177     _argLength = index;
178   }
179
180   /**
181    * Sets the argument with an int
182    */

183   public void setInt(int index, int v)
184   {
185     _argTypes[index - 1] = IntegerType.create();
186     _argValues[index - 1] = new Integer JavaDoc(v);
187     _argLength = index;
188   }
189
190   /**
191    * Sets the argument with a string
192    */

193   public void setLong(int index, long v)
194   {
195     _argTypes[index - 1] = LongType.create();
196     _argValues[index - 1] = new Long JavaDoc(v);
197     _argLength = index;
198   }
199
200   /**
201    * Sets the argument with a double
202    */

203   public void setDouble(int index, double v)
204   {
205     _argTypes[index - 1] = DoubleType.create();
206     _argValues[index - 1] = new Double JavaDoc(v);
207     _argLength = index;
208   }
209
210   /**
211    * Sets the argument with a double
212    */

213   public void setFloat(int index, float v)
214   {
215     _argTypes[index - 1] = FloatType.create();
216     _argValues[index - 1] = new Float JavaDoc(v);
217     _argLength = index;
218   }
219
220   /**
221    * Sets the argument with a timestamp
222    */

223   public void setTimestamp(int index, java.sql.Timestamp JavaDoc v)
224   {
225     _argTypes[index - 1] = SqlTimestampType.create();
226     _argValues[index - 1] = v;
227     _argLength = index;
228   }
229
230   /**
231    * Sets the argument with a date
232    */

233   public void setDate(int index, java.sql.Date JavaDoc v)
234   {
235     _argTypes[index - 1] = SqlDateType.create();
236     _argValues[index - 1] = v;
237     _argLength = index;
238   }
239
240   /**
241    * Sets the argument with an object.
242    */

243   public void setObject(int index, Object JavaDoc v)
244   {
245     _argTypes[index - 1] = ObjectType.create();
246     _argValues[index - 1] = v;
247     _argLength = index;
248   }
249
250   /**
251    * Sets the argument with an object and its Amber type.
252    */

253   public void setObject(int index, Object JavaDoc v, Type type)
254   {
255     _argTypes[index - 1] = type;
256     _argValues[index - 1] = v;
257     _argLength = index;
258   }
259
260   /**
261    * Sets the argument with a null
262    */

263   public void setNull(int index, int v)
264   {
265     _argTypes[index - 1] = StringType.create();
266     _argValues[index - 1] = null;
267     _argLength = index;
268   }
269
270   /**
271    * Sets the first result.
272    */

273   public void setFirstResult(int index)
274   {
275     _firstResult = index;
276   }
277
278   /**
279    * Sets the maximum number of results.
280    */

281   public void setMaxResults(int index)
282   {
283     _maxResults = index;
284   }
285
286   /**
287    * Returns the max results.
288    */

289   public int getMaxResults()
290   {
291     return _maxResults;
292   }
293
294   /**
295    * Executes the query returning a result set.
296    */

297   public ResultSet JavaDoc executeQuery()
298     throws SQLException JavaDoc
299   {
300     _aConn.flushNoChecks();
301
302     if (_rs == null)
303       _rs = new ResultSetImpl();
304
305     SelectQuery query = (SelectQuery) _query;
306
307     _rs.setQuery(query);
308     _rs.setSession(_aConn);
309     _rs.setFirstResult(_firstResult);
310     _rs.setMaxResults(_maxResults);
311
312     int chunkSize = _aConn.getCacheChunkSize();
313     boolean isCacheable;
314
315     if (chunkSize <= _firstResult)
316       isCacheable = false;
317     else if (_aConn.isInTransaction() && ! query.isTableReadOnly())
318       isCacheable = false;
319     else if (! query.isCacheable())
320       isCacheable = false;
321     else
322       isCacheable = true;
323
324     ResultSetCacheChunk cacheChunk = null;
325     ResultSetMetaData JavaDoc metaData = null;
326
327     if (isCacheable) {
328       int row = 0;
329
330       cacheChunk = _aConn.getQueryCacheChunk(query.getSQL(), _argValues, row);
331       metaData = _aConn.getQueryMetaData();
332
333       _rs.setCacheChunk(cacheChunk, metaData);
334       _rs.setUserQuery(this);
335     }
336
337     if (cacheChunk == null) {
338       ResultSet JavaDoc rs;
339
340       rs = executeQuery(0, _maxResults);
341
342       metaData = rs.getMetaData();
343
344       _rs.setResultSet(rs, metaData);
345
346       if (isCacheable) {
347         cacheChunk = new ResultSetCacheChunk();
348         cacheChunk.setQuery(query);
349
350         _rs.fillCacheChunk(cacheChunk);
351
352         _rs.setCacheChunk(cacheChunk, metaData);
353
354         _aConn.putQueryCacheChunk(query.getSQL(), _argValues, 0,
355                                   cacheChunk, metaData);
356       }
357     }
358
359     _rs.init();
360
361     return _rs;
362   }
363
364   /**
365    * Executes the query.
366    */

367   ResultSet JavaDoc executeQuery(int row, int maxResults)
368     throws SQLException JavaDoc
369   {
370     String JavaDoc sql = _query.getSQL();
371
372     if (maxResults > 0) {
373       JdbcMetaData metaData = _aConn.getAmberManager().getMetaData();
374
375       // XXX: should limit meta-data as well?
376
sql = metaData.limit(sql, maxResults);
377     }
378
379     PreparedStatement JavaDoc pstmt = _aConn.prepareStatement(sql);
380     ArgExpr []args = _query.getArgList();
381
382     if (args.length > 0)
383       pstmt.clearParameters();
384
385     for (int i = 0; i < args.length; i++) {
386       args[i].setParameter(pstmt, i + 1, _argTypes, _argValues);
387     }
388
389     ResultSet JavaDoc rs = pstmt.executeQuery();
390
391     for (int i = 0; i < row && rs.next(); i++) {
392     }
393
394     return rs;
395   }
396
397   /**
398    * Executes the query returning a result set.
399    */

400   public int executeUpdate()
401     throws SQLException JavaDoc
402   {
403     _aConn.flushNoChecks();
404     // XXX: sync
405

406     String JavaDoc sql = _query.getSQL();
407
408     PreparedStatement JavaDoc pstmt = _aConn.prepareStatement(sql);
409     ArgExpr []args = _query.getArgList();
410
411     if (args.length > 0)
412       pstmt.clearParameters();
413
414     for (int i = 0; i < args.length; i++) {
415       args[i].setParameter(pstmt, i + 1, _argTypes, _argValues);
416     }
417
418     _query.prepare(this, _aConn);
419
420     int count = pstmt.executeUpdate();
421
422     if (count != 0)
423       _query.complete(this, _aConn);
424
425     return count;
426   }
427
428   /**
429    * Sets the cache max age for the query.
430    */

431   public void setCacheMaxAge(long ms)
432   {
433     _cacheMaxAge = ms;
434   }
435
436   /**
437    * Executes the query, returning a list.
438    */

439   public List JavaDoc<Object JavaDoc> list()
440     throws SQLException JavaDoc
441   {
442     ArrayList JavaDoc<Object JavaDoc> list = new ArrayList JavaDoc<Object JavaDoc>();
443
444     list(list);
445
446     return list;
447   }
448
449   /**
450    * Executes the query returning the single result.
451    */

452   public Object JavaDoc getSingleResult()
453     throws SQLException JavaDoc
454   {
455     SelectQuery query = (SelectQuery) _query;
456     ResultSet JavaDoc rs = null;
457
458     _aConn.pushDepth();
459     try {
460       rs = executeQuery();
461       if (rs.next())
462         return rs.getObject(1);
463
464       return null;
465     } catch (SQLException JavaDoc e) {
466       throw e;
467     } finally {
468       _aConn.popDepth();
469
470       if (rs != null)
471         rs.close();
472     }
473   }
474
475   /**
476    * Executes the query, filling the list.
477    */

478   public void list(List JavaDoc<Object JavaDoc> list)
479     throws SQLException JavaDoc
480   {
481     SelectQuery query = (SelectQuery) _query;
482     ResultSet JavaDoc rs = null;
483
484     _aConn.pushDepth();
485     try {
486       rs = executeQuery();
487
488       int tupleCount = query.getResultCount();
489
490       while (rs.next()) {
491         if (tupleCount == 1) {
492           Object JavaDoc value = rs.getObject(1);
493
494           list.add(value);
495         }
496         else {
497           Object JavaDoc []values = new Object JavaDoc[tupleCount];
498
499           for (int i = 0; i < tupleCount; i++) {
500             values[i] = rs.getObject(i + 1);
501           }
502
503           list.add(values);
504         }
505       }
506     } catch (SQLException JavaDoc e) {
507       throw e;
508     } finally {
509       _aConn.popDepth();
510
511       if (rs != null)
512         rs.close();
513     }
514   }
515
516   /**
517    * Executes the query, filling the map.
518    */

519   public void list(Map JavaDoc<Object JavaDoc,Object JavaDoc> map,
520                    Method JavaDoc methodGetMapKey)
521     throws SQLException JavaDoc,
522            IllegalAccessException JavaDoc,
523            InvocationTargetException JavaDoc
524   {
525     SelectQuery query = (SelectQuery) _query;
526
527     ResultSet JavaDoc rs = null;
528
529     _aConn.pushDepth();
530     try {
531       rs = executeQuery();
532
533       int tupleCount = query.getResultCount();
534
535       while (rs.next()) {
536         if (tupleCount == 1) {
537           Object JavaDoc value = rs.getObject(1);
538
539           com.caucho.amber.entity.Entity entity;
540           entity = (com.caucho.amber.entity.Entity) value;
541
542           Object JavaDoc mapKey;
543           if (methodGetMapKey == null)
544             mapKey = entity.__caucho_getPrimaryKey();
545           else
546             mapKey = methodGetMapKey.invoke(entity, null);
547
548           map.put(mapKey, value);
549         }
550         else {
551           Object JavaDoc []values = new Object JavaDoc[tupleCount];
552
553           for (int i = 0; i < tupleCount; i++) {
554             values[i] = rs.getObject(i + 1);
555           }
556
557           // XXX: for now, assume 1st column is the key.
558
Object JavaDoc mapKey = values[0];
559           map.put(mapKey, values);
560         }
561       }
562     } catch (SQLException JavaDoc e) {
563       throw e;
564     } finally {
565       _aConn.popDepth();
566
567       if (rs != null)
568         rs.close();
569     }
570   }
571
572   public String JavaDoc toString()
573   {
574     return "UserQuery[" + _query.getQueryString() + "]";
575   }
576 }
577
Popular Tags