KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > db > sql > QueryContext


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.db.sql;
31
32 import com.caucho.db.jdbc.GeneratedKeysResultSet;
33 import com.caucho.db.store.Block;
34 import com.caucho.db.store.Transaction;
35 import com.caucho.db.table.TableIterator;
36 import com.caucho.log.Log;
37 import com.caucho.util.FreeList;
38 import com.caucho.util.L10N;
39
40 import java.io.IOException JavaDoc;
41 import java.sql.SQLException JavaDoc;
42 import java.util.HashMap JavaDoc;
43 import java.util.Iterator JavaDoc;
44 import java.util.logging.Level JavaDoc;
45 import java.util.logging.Logger JavaDoc;
46
47 /**
48  * Represents the state of the query at any particular time.
49  */

50 public class QueryContext {
51   private static final Logger JavaDoc log = Log.open(QueryContext.class);
52   private static final L10N L = new L10N(QueryContext.class);
53
54   private static final long LOCK_TIMEOUT = 120000;
55
56   private static final FreeList<QueryContext> _freeList
57     = new FreeList<QueryContext>(64);
58
59   private Transaction _xa;
60   private TableIterator []_tableIterators;
61   private boolean _isWrite;
62
63   private Data []_parameters = new Data[8];
64
65   private GroupItem _tempGroupItem;
66   private GroupItem _groupItem;
67
68   private boolean _isReturnGeneratedKeys;
69   private SelectResult _result;
70   private GeneratedKeysResultSet _generatedKeys;
71   private int _rowUpdateCount;
72
73   private Block []_blockLocks;
74   private boolean _isLocked;
75
76   private HashMap JavaDoc<GroupItem,GroupItem> _groupMap;
77
78   private byte []_buffer = new byte[256];
79
80   private QueryContext()
81   {
82     _tempGroupItem = GroupItem.allocate(new boolean[8]);
83   }
84
85   /**
86    * Returns a new query context.
87    */

88   public static QueryContext allocate()
89   {
90     QueryContext queryContext = _freeList.allocate();
91     
92     if (queryContext == null)
93       queryContext = new QueryContext();
94
95     queryContext.clearParameters();
96
97     return queryContext;
98   }
99
100   public void clearParameters()
101   {
102     for (int i = _parameters.length - 1; i >= 0; i--) {
103       if (_parameters[i] == null)
104     _parameters[i] = new Data();
105       
106       _parameters[i].clear();
107     }
108   }
109
110   /**
111    * Initializes the query state.
112    */

113   public void init(Transaction xa,
114            TableIterator []tableIterators,
115            boolean isReadOnly)
116   {
117     _xa = xa;
118     _isWrite = ! isReadOnly;
119     _tableIterators = tableIterators;
120     _blockLocks = new Block[_tableIterators.length];
121     _isLocked = false;
122
123     _rowUpdateCount = 0;
124     _groupItem = _tempGroupItem;
125     _groupItem.init(0, null);
126   }
127
128   /**
129    * Initializes the group.
130    */

131   public void initGroup(int size, boolean []isGroupByFields)
132   {
133     _groupItem = _tempGroupItem;
134     
135     _groupItem.init(size, isGroupByFields);
136
137     if (_groupMap == null)
138       _groupMap = new HashMap JavaDoc<GroupItem,GroupItem>();
139   }
140
141   /**
142    * Selects the actual group item.
143    */

144   public void selectGroup()
145   {
146     GroupItem item = _groupMap.get(_groupItem);
147
148     if (item == null) {
149       item = _groupItem.allocateCopy();
150
151       _groupMap.put(item, item);
152     }
153
154     _groupItem = item;
155   }
156
157   /**
158    * Returns the group results.
159    */

160   Iterator<GroupItem> groupResults()
161   {
162     if (_groupMap == null)
163       return com.caucho.util.NullIterator.create();
164     
165     Iterator<GroupItem> results = _groupMap.values().iterator();
166     _groupMap = null;
167
168     return results;
169   }
170   
171   /**
172    * Sets the current result.
173    */

174   void setGroupItem(GroupItem item)
175   {
176     _groupItem = item;
177   }
178
179
180   /**
181    * Returns the table iterator.
182    */

183   public TableIterator []getTableIterators()
184   {
185     return _tableIterators;
186   }
187
188   /**
189    * Sets the transaction.
190    */

191   public void setTransaction(Transaction xa)
192   {
193     _xa = xa;
194   }
195
196   /**
197    * Returns the transaction.
198    */

199   public Transaction getTransaction()
200   {
201     return _xa;
202   }
203
204   /**
205    * Returns the temp buffer.
206    */

207   public byte []getBuffer()
208   {
209     return _buffer;
210   }
211
212   /**
213    * Returns the number of rows updated.
214    */

215   public int getRowUpdateCount()
216   {
217     return _rowUpdateCount;
218   }
219
220   /**
221    * Sets the number of rows updated.
222    */

223   public void setRowUpdateCount(int count)
224   {
225     _rowUpdateCount = count;
226   }
227
228   /**
229    * Set if the query should return the generated keys.
230    */

231   public boolean isReturnGeneratedKeys()
232   {
233     return _isReturnGeneratedKeys;
234   }
235
236   /**
237    * Set if the query should return the generated keys.
238    */

239   public void setReturnGeneratedKeys(boolean isReturnGeneratedKeys)
240   {
241     _isReturnGeneratedKeys = isReturnGeneratedKeys;
242     
243     if (_isReturnGeneratedKeys && _generatedKeys != null)
244       _generatedKeys.init();
245   }
246
247   /**
248    * Sets the indexed group field.
249    */

250   public boolean isGroupNull(int index)
251   {
252     return _groupItem.isNull(index);
253   }
254
255   /**
256    * Sets the indexed group field.
257    */

258   public void setGroupString(int index, String JavaDoc value)
259   {
260     _groupItem.setString(index, value);
261   }
262
263   /**
264    * Sets the indexed group field.
265    */

266   public String JavaDoc getGroupString(int index)
267   {
268     return _groupItem.getString(index);
269   }
270
271   /**
272    * Sets the indexed group field as a long.
273    */

274   public void setGroupLong(int index, long value)
275   {
276     _groupItem.setLong(index, value);
277   }
278
279   /**
280    * Sets the indexed group field as a long.
281    */

282   public long getGroupLong(int index)
283   {
284     return _groupItem.getLong(index);
285   }
286
287   /**
288    * Sets the indexed group field as a double.
289    */

290   public void setGroupDouble(int index, double value)
291   {
292     _groupItem.setDouble(index, value);
293   }
294
295   /**
296    * Sets the indexed group field as a double.
297    */

298   public double getGroupDouble(int index)
299   {
300     return _groupItem.getDouble(index);
301   }
302
303   /**
304    * Returns the indexed group field.
305    */

306   public Data getGroupData(int index)
307   {
308     return _groupItem.getData(index);
309   }
310
311   /**
312    * Set a null parameter.
313    */

314   public void setNull(int index)
315   {
316     _parameters[index].setString(null);
317   }
318
319   /**
320    * Returns the null parameter.
321    */

322   public boolean isNull(int index)
323   {
324     return _parameters[index].isNull();
325   }
326
327   /**
328    * Set a long parameter.
329    */

330   public void setLong(int index, long value)
331   {
332     _parameters[index].setLong(value);
333   }
334
335   /**
336    * Returns the boolean parameter.
337    */

338   public int getBoolean(int index)
339   {
340     return _parameters[index].getBoolean();
341   }
342
343   /**
344    * Set a boolean parameter.
345    */

346   public void setBoolean(int index, boolean value)
347   {
348     _parameters[index].setBoolean(value);
349   }
350
351   /**
352    * Returns the long parameter.
353    */

354   public long getLong(int index)
355   {
356     return _parameters[index].getLong();
357   }
358
359   /**
360    * Returns the long parameter.
361    */

362   public long getDate(int index)
363   {
364     return _parameters[index].getDate();
365   }
366
367   /**
368    * Set a double parameter.
369    */

370   public void setDouble(int index, double value)
371   {
372     _parameters[index].setDouble(value);
373   }
374
375   /**
376    * Returns the double parameter.
377    */

378   public double getDouble(int index)
379   {
380     return _parameters[index].getDouble();
381   }
382
383   /**
384    * Set a string parameter.
385    */

386   public void setString(int index, String JavaDoc value)
387   {
388     _parameters[index].setString(value);
389   }
390
391   /**
392    * Returns the string parameter.
393    */

394   public String JavaDoc getString(int index)
395   {
396     return _parameters[index].getString();
397   }
398
399   /**
400    * Sets the result set.
401    */

402   public void setResult(SelectResult result)
403   {
404     _result = result;
405   }
406
407   /**
408    * Gets the result set.
409    */

410   public SelectResult getResult()
411   {
412     return _result;
413   }
414
415   /**
416    * Gets the generated keys result set.
417    */

418   public GeneratedKeysResultSet getGeneratedKeysResultSet()
419   {
420     if (! _isReturnGeneratedKeys)
421       return null;
422
423     if (_generatedKeys == null)
424       _generatedKeys = new GeneratedKeysResultSet();
425     
426     return _generatedKeys;
427   }
428
429   /**
430    * Lock the blocks. The blocks are locked in ascending block id
431    * order to avoid deadlocks.
432    *
433    * @param isWrite if true, the block should be locked for writing
434    */

435   public void lock()
436     throws SQLException JavaDoc
437   {
438     if (_isLocked)
439       throw new IllegalStateException JavaDoc(L.l("blocks are already locked"));
440     _isLocked = true;
441     
442     int len = _blockLocks.length;
443
444     for (int i = 0; i < len; i++) {
445       Block bestBlock = null;
446       long bestId = Long.MAX_VALUE;
447
448       loop:
449       for (int j = 0; j < len; j++) {
450     TableIterator iter = _tableIterators[j];
451
452     if (iter == null)
453       continue;
454     
455     Block block = iter.getBlock();
456
457     if (block == null)
458       continue;
459
460     long id = block.getBlockId();
461     if (bestId <= id)
462       continue;
463     
464     for (int k = 0; k < i; k++) {
465       if (_blockLocks[k] == block)
466         continue loop;
467     }
468
469     bestId = id;
470     bestBlock = block;
471       }
472
473       _blockLocks[i] = bestBlock;
474
475       if (bestBlock == null) {
476       }
477       else if (_isWrite)
478     _xa.lockWrite(bestBlock.getLock());
479       else
480     _xa.lockRead(bestBlock.getLock());
481     }
482   }
483
484   /**
485    * Unlock the blocks. The blocks are unlocked in descending order.
486    *
487    * @param isWrite if true, the block should be unlocked for writing
488    */

489   public void unlock()
490     throws SQLException JavaDoc
491   {
492     if (! _isLocked)
493       return;
494     
495     _isLocked = false;
496
497     try {
498       _xa.writeData();
499     } finally {
500       int len = _blockLocks.length;
501
502       for (int i = len - 1; i >= 0; i--) {
503     Block block = _blockLocks[i];
504     _blockLocks[i] = null;
505
506     if (block == null) {
507     }
508     else if (_isWrite) {
509       _xa.unlockReadAndWrite(block.getLock());
510
511       try {
512         block.commit();
513       } catch (IOException JavaDoc e) {
514         log.log(Level.FINE, e.toString(), e);
515       }
516     }
517     else
518       _xa.unlockRead(block.getLock());
519       }
520     }
521   }
522
523   /**
524    * Returns a new query context.
525    */

526   public static void free(QueryContext queryContext)
527   {
528     queryContext._groupMap = null;
529     
530     _freeList.free(queryContext);
531   }
532 }
533
Popular Tags