Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: org/apache/derby/impl/sql/GenericActivationHolder.java


1   /*
2   
3      Derby - Class org.apache.derby.impl.sql.GenericActivationHolder
4   
5      Copyright 1997, 2004 The Apache Software Foundation or its licensors, as applicable.
6   
7      Licensed under the Apache License, Version 2.0 (the "License");
8      you may not use this file except in compliance with the License.
9      You may obtain a copy of the License at
10  
11        http://www.apache.org/licenses/LICENSE-2.0
12  
13     Unless required by applicable law or agreed to in writing, software
14     distributed under the License is distributed on an "AS IS" BASIS,
15     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16     See the License for the specific language governing permissions and
17     limitations under the License.
18  
19   */
20  
21  package org.apache.derby.impl.sql;
22  
23  import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
24  
25  import org.apache.derby.iapi.types.DataValueFactory;
26  
27  import org.apache.derby.iapi.sql.execute.ExecPreparedStatement;
28  import org.apache.derby.iapi.sql.execute.ExecRow;
29  import org.apache.derby.iapi.sql.execute.ExecutionFactory;
30  import org.apache.derby.iapi.sql.execute.NoPutResultSet;
31  import org.apache.derby.iapi.sql.execute.ConstantAction;
32  
33  import org.apache.derby.impl.sql.execute.BaseActivation;
34  
35  import org.apache.derby.iapi.types.DataTypeDescriptor;
36  import org.apache.derby.iapi.sql.ParameterValueSet;
37  import org.apache.derby.iapi.sql.ResultSet;
38  import org.apache.derby.iapi.sql.ResultDescription;
39  import org.apache.derby.iapi.sql.Activation;
40  import org.apache.derby.iapi.sql.execute.CursorResultSet;
41  import org.apache.derby.iapi.sql.execute.TemporaryRowHolder;
42  
43  import org.apache.derby.iapi.sql.dictionary.IndexRowGenerator;
44  import org.apache.derby.iapi.sql.dictionary.TableDescriptor;
45  
46  import org.apache.derby.iapi.reference.SQLState;
47  
48  import org.apache.derby.iapi.error.StandardException;
49  
50  import org.apache.derby.iapi.services.loader.GeneratedClass;
51  import org.apache.derby.iapi.services.context.Context;
52  
53  import org.apache.derby.iapi.store.access.ConglomerateController;
54  import org.apache.derby.iapi.store.access.ScanController;
55  
56  import org.apache.derby.iapi.types.RowLocation;
57  
58  import org.apache.derby.iapi.services.sanity.SanityManager;
59  
60  import org.apache.derby.iapi.store.access.TransactionController;
61  
62  import java.sql.SQLWarning;
63  import java.util.Enumeration;
64  import java.util.Vector;
65  import java.util.Hashtable;
66  
67  /**
68   * This class holds an Activation, and passes through most of the calls
69   * to the activation.  The purpose of this class is to allow a PreparedStatement
70   * to be recompiled without the caller having to detect this and get a new
71   * activation.
72   *
73   * In addition to the Activation, this class holds a reference to the
74   * PreparedStatement that created it, along with a reference to the
75   * GeneratedClass that was associated with the PreparedStatement at the time
76   * this holder was created.  These references are used to validate the
77   * Activation, to ensure that an activation is used only with the
78   * PreparedStatement that created it, and to detect when recompilation has
79   * happened.
80   *
81   * We detect recompilation by checking whether the GeneratedClass has changed.
82   * If it has, we try to let the caller continue to use this ActivationHolder.
83   * We create a new instance of the new GeneratedClass (that is, we create a
84   * new Activation), and we compare the number and type of parameters.  If these
85   * are compatible, we copy the parameters from the old to the new Activation.
86   * If they are not compatible, we throw an exception telling the user that
87   * the Activation is out of date, and they need to get a new one.
88   *
89   * @author Jeff Lichtman
90   */
91  
92  final class GenericActivationHolder implements Activation
93  {
94    BaseActivation      ac;
95    ExecPreparedStatement  ps;
96    GeneratedClass      gc;
97    DataTypeDescriptor[]  paramTypes;
98    private final LanguageConnectionContext lcc;
99  
100   /**
101    * Constructor for an ActivationHolder
102    *
103    * @param gc  The GeneratedClass of the Activation
104    * @param ps  The PreparedStatement this ActivationHolder is associated
105    *        with
106    *
107    * @exception StandardException    Thrown on error
108    */
109   GenericActivationHolder(LanguageConnectionContext lcc, GeneratedClass gc, ExecPreparedStatement ps, boolean scrollable)
110       throws StandardException
111   {
112     this.lcc = lcc;
113     if (SanityManager.DEBUG)
114     {
115       SanityManager.ASSERT(gc != null, "generated class is null , ps is a " + ps.getClass());
116     }
117 
118     this.gc = gc;
119     this.ps = ps;
120 
121     ac = (BaseActivation) gc.newInstance(lcc);
122     ac.setupActivation(ps, scrollable);
123     paramTypes = ps.getParameterTypes();
124   }
125 
126   /* Activation interface */
127 
128   /**
129    * @see Activation#reset
130    *
131    * @exception StandardException thrown on failure
132    */
133   public void  reset() throws StandardException
134   {
135     ac.reset();
136   }
137 
138   /**
139    * Temporary tables can be declared with ON COMMIT DELETE ROWS. But if the table has a held curosr open at
140    * commit time, data should not be deleted from the table. This method, (gets called at commit time) checks if this
141    * activation held cursor and if so, does that cursor reference the passed temp table name.
142    *
143    * @return  true if this activation has held cursor and if it references the passed temp table name
144    */
145   public boolean checkIfThisActivationHasHoldCursor(String tableName)
146   {
147     return ac.checkIfThisActivationHasHoldCursor(tableName);
148   }
149 
150   /**
151    * @see Activation#setCursorName
152    *
153    */
154   public void  setCursorName(String cursorName)
155   {
156     ac.setCursorName(cursorName);
157   }
158 
159   /**
160    * @see Activation#getCursorName
161    */
162   public String  getCursorName()
163   {
164     return ac.getCursorName();
165   }
166 
167   /**
168    * @see Activation#setResultSetHoldability
169    *
170    */
171   public void  setResultSetHoldability(boolean resultSetHoldability)
172   {
173     ac.setResultSetHoldability(resultSetHoldability);
174   }
175 
176   /**
177    * @see Activation#getResultSetHoldability
178    */
179   public boolean  getResultSetHoldability()
180   {
181     return ac.getResultSetHoldability();
182   }
183 
184   /** @see Activation#setAutoGeneratedKeysResultsetInfo */
185   public void setAutoGeneratedKeysResultsetInfo(int[] columnIndexes, String[] columnNames)
186   {
187     ac.setAutoGeneratedKeysResultsetInfo(columnIndexes, columnNames);
188   }
189 
190   /** @see Activation#getAutoGeneratedKeysResultsetMode */
191   public boolean getAutoGeneratedKeysResultsetMode()
192   {
193     return ac.getAutoGeneratedKeysResultsetMode();
194   }
195 
196   /** @see Activation#getAutoGeneratedKeysColumnIndexes */
197   public int[] getAutoGeneratedKeysColumnIndexes()
198   {
199     return ac.getAutoGeneratedKeysColumnIndexes();
200   }
201 
202   /** @see Activation#getAutoGeneratedKeysColumnNames */
203   public String[] getAutoGeneratedKeysColumnNames()
204   {
205     return ac.getAutoGeneratedKeysColumnNames();
206   }
207 
208   /** @see org.apache.derby.iapi.sql.Activation#getLanguageConnectionContext */
209   public  LanguageConnectionContext  getLanguageConnectionContext()
210   {
211     return  lcc;
212   }
213 
214   public TransactionController getTransactionController()
215   {
216     return ac.getTransactionController();
217   }
218 
219   /** @see Activation#getExecutionFactory */
220   public  ExecutionFactory  getExecutionFactory()
221   {
222     return  ac.getExecutionFactory();
223   }
224 
225   /**
226    * @see Activation#getParameterValueSet
227    */
228   public ParameterValueSet  getParameterValueSet()
229   {
230     return ac.getParameterValueSet();
231   }
232 
233   /**
234    * @see Activation#setParameters
235    */
236   public void  setParameters(ParameterValueSet parameterValues, DataTypeDescriptor[] parameterTypes) throws StandardException
237   {
238     ac.setParameters(parameterValues, parameterTypes);
239   }
240 
241   /** 
242    * @see Activation#execute
243    *
244    * @exception StandardException    Thrown on failure
245    */
246   public ResultSet execute() throws StandardException
247   {
248     /*
249     ** Synchronize to avoid problems if another thread is preparing
250     ** the statement at the same time we're trying to execute it.
251     */
252     // synchronized (ps)
253     {
254       /* Has the activation class changed? */
255       if (gc != ps.getActivationClass())
256       {
257 
258         // ensure the statement is valid by rePreparing it.
259         ps.rePrepare(getLanguageConnectionContext());
260         
261         /*
262         ** If we get here, it means the PreparedStatement has been
263         ** recompiled.  Get a new Activation and check whether the
264         ** parameters are compatible.  If so, transfer the parameters
265         ** from the old Activation to the new one, and make that the
266         ** current Activation.  If not, throw an exception.
267         */
268         GeneratedClass    newGC = ps.getActivationClass();
269 
270         BaseActivation    newAC = (BaseActivation) newGC.newInstance(lcc);
271 
272         DataTypeDescriptor[]  newParamTypes = ps.getParameterTypes();
273 
274         /*
275         ** Link the new activation to the prepared statement.
276         */
277         newAC.setupActivation(ps, ac.getScrollable());
278 
279         newAC.setParameters(ac.getParameterValueSet(), paramTypes);
280 
281 
282         /*
283         ** IMPORTANT
284         **
285         ** Copy any essential state from the old activation
286         ** to the new activation. This must match the state
287         ** setup in EmbedStatement.
288         ** singleExecution, cursorName, holdability, maxRows.
289         */
290 
291         if (ac.isSingleExecution())
292           newAC.setSingleExecution();
293 
294         newAC.setCursorName(ac.getCursorName());
295 
296         newAC.setResultSetHoldability(ac.getResultSetHoldability());
297         if (ac.getAutoGeneratedKeysResultsetMode()) //Need to do copy only if auto generated mode is on
298           newAC.setAutoGeneratedKeysResultsetInfo(ac.getAutoGeneratedKeysColumnIndexes(),
299           ac.getAutoGeneratedKeysColumnNames());
300         newAC.setMaxRows(ac.getMaxRows());
301 
302         // break the link with the prepared statement
303         ac.setupActivation(null, false);
304         ac.close();
305 
306         /* Remember the new class information */
307         ac = newAC;
308         gc = newGC;
309         paramTypes = newParamTypes;
310       }
311     }
312 
313     String cursorName = ac.getCursorName();
314     if (cursorName != null)
315     {
316       // have to see if another activation is open
317       // with the same cursor name. If so we can't use this name
318 
319       Activation activeCursor = lcc.lookupCursorActivation(cursorName);
320 
321       if ((activeCursor != null) && (activeCursor != ac)) {
322         throw StandardException.newException(SQLState.LANG_CURSOR_ALREADY_EXISTS, cursorName);
323       }
324     }
325 
326     return ac.execute();
327   }
328 
329   /**
330    * @see Activation#getResultSet
331    *
332    * @return the current ResultSet of this activation.
333    */
334   public ResultSet getResultSet()
335   {
336     return ac.getResultSet();
337   }
338 
339   /**
340    * @see Activation#clearResultSet
341    */
342   public void clearResultSet()
343   {
344     ac.clearResultSet();
345   }
346 
347   /**
348    * @see Activation#setCurrentRow
349    *
350    */
351   public void setCurrentRow(ExecRow currentRow, int resultSetNumber) 
352   {
353     ac.setCurrentRow(currentRow, resultSetNumber);
354   }
355 
356   /**
357    * @see Activation#clearCurrentRow
358    */
359   public void clearCurrentRow(int resultSetNumber) 
360   {
361     ac.clearCurrentRow(resultSetNumber);
362   }
363 
364   /**
365    * @see Activation#getPreparedStatement
366    */
367   public ExecPreparedStatement getPreparedStatement()
368   {
369     return ps;
370   }
371 
372   public void checkStatementValidity() throws StandardException {
373     ac.checkStatementValidity();
374   }
375 
376   /**
377    * @see Activation#getResultDescription
378    */
379   public ResultDescription getResultDescription()
380   {
381     return ac.getResultDescription();
382   }
383 
384   /**
385    * @see Activation#getDataValueFactory
386    */
387   public DataValueFactory getDataValueFactory()
388   {
389     return ac.getDataValueFactory();
390   }
391 
392   /**
393    * @see Activation#getRowLocationTemplate
394    */
395   public RowLocation getRowLocationTemplate(int itemNumber)
396   {
397     return ac.getRowLocationTemplate(itemNumber);
398   }
399 
400   /**
401    * @see Activation#getHeapConglomerateController
402    */
403   public ConglomerateController getHeapConglomerateController()
404   {
405     return ac.getHeapConglomerateController();
406   }
407 
408   /**
409    * @see Activation#setHeapConglomerateController
410    */
411   public void setHeapConglomerateController(ConglomerateController updateHeapCC)
412   {
413     ac.setHeapConglomerateController(updateHeapCC);
414   }
415 
416   /**
417    * @see Activation#clearHeapConglomerateController
418    */
419   public void clearHeapConglomerateController()
420   {
421     ac.clearHeapConglomerateController();
422   }
423 
424   /**
425    * @see Activation#getIndexScanController
426    */
427   public ScanController getIndexScanController()
428   {
429     return ac.getIndexScanController();
430   }
431 
432   /**
433    * @see Activation#setIndexScanController
434    */
435   public void setIndexScanController(ScanController indexSC)
436   {
437     ac.setIndexScanController(indexSC);
438   }
439 
440   /**
441    * @see Activation#getIndexConglomerateNumber
442    */
443   public long getIndexConglomerateNumber()
444   {
445     return ac.getIndexConglomerateNumber();
446   }
447 
448   /**
449    * @see Activation#setIndexConglomerateNumber
450    */
451   public void setIndexConglomerateNumber(long indexConglomerateNumber)
452   {
453     ac.setIndexConglomerateNumber(indexConglomerateNumber);
454   }
455 
456   /**
457    * @see Activation#clearIndexScanInfo
458    */
459   public void clearIndexScanInfo()
460   {
461     ac.clearIndexScanInfo();
462   }
463 
464   /**
465    * @see Activation#close
466    *
467    * @exception StandardException    Thrown on error
468    */
469   public void close() throws StandardException
470   {
471     ac.close();
472   }
473 
474   /**
475    * @see Activation#isClosed
476    */
477   public boolean isClosed()
478   {
479     return ac.isClosed();
480   }
481 
482   /**
483     Set the activation for a single execution.
484 
485     @see Activation#setSingleExecution
486   */
487   public void setSingleExecution() {
488     ac.setSingleExecution();
489   }
490 
491   /**
492     Is the activation set up for a single execution.
493 
494     @see Activation#isSingleExecution
495   */
496   public boolean isSingleExecution() {
497     return ac.isSingleExecution();
498   }
499 
500   /**
501     Get the number of subqueries in the entire query.
502     @return int   The number of subqueries in the entire query.
503    */
504   public int getNumSubqueries() {
505     return ac.getNumSubqueries();
506   }
507 
508   /**
509    * @see Activation#setForCreateTable()
510    */
511   public void setForCreateTable()
512   {
513     ac.setForCreateTable();
514   }
515 
516   /**
517    * @see Activation#getForCreateTable()
518    */
519   public boolean getForCreateTable()
520   {
521     return ac.getForCreateTable();
522   }
523 
524   /**
525    * @see Activation#setDDLTableDescriptor
526    */
527   public void setDDLTableDescriptor(TableDescriptor td)
528   {
529     ac.setDDLTableDescriptor(td);
530   }
531 
532   /**
533    * @see Activation#getDDLTableDescriptor
534    */
535   public TableDescriptor getDDLTableDescriptor()
536   {
537     return ac.getDDLTableDescriptor();
538   }
539 
540   /**
541    * @see Activation#setMaxRows
542    */
543   public void setMaxRows(int maxRows)
544   {
545     ac.setMaxRows(maxRows);
546   }
547 
548   /**
549    * @see Activation#getMaxRows
550    */
551   public int getMaxRows()
552   {
553     return ac.getMaxRows();
554   }
555 
556   public void setTargetVTI(java.sql.ResultSet targetVTI)
557   {
558     ac.setTargetVTI(targetVTI);
559   }
560 
561   public java.sql.ResultSet getTargetVTI()
562   {
563     return ac.getTargetVTI();
564   }
565 
566   /* Class implementation */
567 
568 
569   /**
570    * Mark the activation as unused.  
571    */
572   public void markUnused()
573   {
574     ac.markUnused();
575   }
576 
577   /**
578    * Is the activation in use?
579    *
580    * @return true/false
581    */
582   public boolean isInUse()
583   {
584     return ac.isInUse();
585   }
586   /**
587     @see org.apache.derby.iapi.sql.Activation#addWarning
588     */
589   public void addWarning(SQLWarning w)
590   {
591     ac.addWarning(w);
592   }
593 
594   /**
595     @see org.apache.derby.iapi.sql.Activation#getWarnings
596     */
597   public SQLWarning getWarnings()
598   {
599     return ac.getWarnings();
600   }
601 
602   /**
603     @see org.apache.derby.iapi.sql.Activation#clearWarnings
604     */
605   public void clearWarnings()
606   {
607     ac.clearWarnings();
608   }
609 
610   /**
611     @see Activation#informOfRowCount
612     @exception StandardException  Thrown on error
613    */
614   public void informOfRowCount(NoPutResultSet resultSet, long rowCount)
615           throws StandardException
616   {
617     ac.informOfRowCount(resultSet, rowCount);
618   }
619 
620   /**
621    * @see Activation#isCursorActivation
622    */
623   public boolean isCursorActivation()
624   {
625     return ac.isCursorActivation();
626   }
627 
628   public ConstantAction getConstantAction() {
629     return ac.getConstantAction();
630   }
631 
632   public void setParentResultSet(TemporaryRowHolder rs, String resultSetId)
633   {
634     ac.setParentResultSet(rs, resultSetId);
635   }
636 
637 
638   public Vector getParentResultSet(String resultSetId)
639   {
640     return ac.getParentResultSet(resultSetId);
641   }
642 
643   public void clearParentResultSets()
644   {
645     ac.clearParentResultSets();
646   }
647 
648   public Hashtable getParentResultSets()
649   {
650     return ac.getParentResultSets();
651   }
652 
653   public void setForUpdateIndexScan(CursorResultSet forUpdateResultSet)
654   {
655     ac.setForUpdateIndexScan(forUpdateResultSet);
656   }
657 
658   public CursorResultSet getForUpdateIndexScan()
659   {
660     return ac.getForUpdateIndexScan();
661   }
662 
663   public java.sql.ResultSet[][] getDynamicResults() {
664     return ac.getDynamicResults();
665   }
666   public int getMaxDynamicResults() {
667     return ac.getMaxDynamicResults();
668   }
669 
670 }