KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > derby > impl > drda > DRDAStatement


1 /*
2
3    Derby - Class org.apache.derby.impl.drda.DRDAStatement
4
5    Licensed to the Apache Software Foundation (ASF) under one or more
6    contributor license agreements. See the NOTICE file distributed with
7    this work for additional information regarding copyright ownership.
8    The ASF licenses this file to You under the Apache License, Version 2.0
9    (the "License"); you may not use this file except in compliance with
10    the License. You may obtain a copy of the License at
11
12       http://www.apache.org/licenses/LICENSE-2.0
13
14    Unless required by applicable law or agreed to in writing, software
15    distributed under the License is distributed on an "AS IS" BASIS,
16    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17    See the License for the specific language governing permissions and
18    limitations under the License.
19
20  */

21
22 package org.apache.derby.impl.drda;
23
24 import java.io.UnsupportedEncodingException JavaDoc;
25 import java.lang.reflect.InvocationTargetException JavaDoc;
26 import java.lang.reflect.Method JavaDoc;
27 import java.math.BigInteger JavaDoc;
28 import java.sql.CallableStatement JavaDoc;
29 import java.sql.Connection JavaDoc;
30 import java.sql.PreparedStatement JavaDoc;
31 import java.sql.ResultSet JavaDoc;
32 import java.sql.SQLException JavaDoc;
33 import java.sql.Statement JavaDoc;
34 import java.util.ArrayList JavaDoc;
35 import java.util.Hashtable JavaDoc;
36 import java.util.StringTokenizer JavaDoc;
37 import java.util.Vector JavaDoc;
38
39 import org.apache.derby.iapi.jdbc.BrokeredConnection;
40 import org.apache.derby.iapi.jdbc.BrokeredPreparedStatement;
41 import org.apache.derby.iapi.jdbc.EngineConnection;
42 import org.apache.derby.iapi.jdbc.EngineStatement;
43 import org.apache.derby.iapi.jdbc.EnginePreparedStatement;
44 import org.apache.derby.iapi.jdbc.EngineParameterMetaData;
45 import org.apache.derby.iapi.reference.JDBC30Translation;
46 import org.apache.derby.iapi.sql.execute.ExecutionContext;
47 import org.apache.derby.iapi.util.StringUtil;
48 import org.apache.derby.impl.jdbc.Util;
49
50 /**
51     DRDAStatement stores information about the statement being executed
52 */

53 class DRDAStatement
54 {
55
56     //NOTE!
57
//
58
// Since DRDAStatements are reused, ALL variables (except those noted in
59
// the comments for reset method) should be set to their default values
60
// in reset().
61

62
63     protected String JavaDoc typDefNam; //TYPDEFNAM for this statement
64
protected int byteOrder; //deduced from typDefNam, save String comparisons
65
protected int ccsidSBC; //CCSID for single byte characters
66
protected int ccsidDBC; //CCSID for double byte characters
67
protected int ccsidMBC; //CCSID for mixed byte characters
68
protected String JavaDoc ccsidSBCEncoding; //Java encoding for CCSIDSBC
69
protected String JavaDoc ccsidDBCEncoding; //Java encoding for CCSIDDBC
70
protected String JavaDoc ccsidMBCEncoding; //Java encoding for CCSIDMBC
71

72     protected Database database; // Database this statement is created for
73
private Pkgnamcsn pkgnamcsn; // Package name/section # and consistency token
74
protected ConsistencyToken pkgcnstkn; // Consistency token for the first result set
75
protected String JavaDoc pkgid; // package id
76
protected int pkgsn; // section number
77
int withHoldCursor = -1; // hold cursor after commit attribute.
78
protected int isolationLevel; //JCC isolation level for Statement
79
protected String JavaDoc cursorName;
80     protected int scrollType = ResultSet.TYPE_FORWARD_ONLY; // Sensitive or Insensitive scroll attribute
81
protected int concurType = ResultSet.CONCUR_READ_ONLY;; // Concurency type
82
protected long rowCount; // Number of rows we have processed
83
protected byte [] rslsetflg; // Result Set Flags
84
protected int maxrslcnt; // Maximum Result set count
85
protected PreparedStatement JavaDoc ps; // Prepared statement
86
protected EngineParameterMetaData stmtPmeta; // param metadata
87
protected boolean isCall;
88     protected String JavaDoc procName; // callable statement's method name
89
private int[] outputTypes; // jdbc type for output parameter or NOT_OUTPUT_PARAM
90
// if not an output parameter.
91
protected static int NOT_OUTPUT_PARAM = -100000;
92     protected boolean outputExpected; // expect output from a callable statement
93
private Statement JavaDoc stmt; // SQL statement
94

95
96     private DRDAResultSet currentDrdaRs; // Current ResultSet
97
private Hashtable JavaDoc resultSetTable; // Hashtable with resultsets
98
private ArrayList JavaDoc resultSetKeyList; // ordered list of hash keys
99
private int numResultSets = 0;
100
101     // State for parameter data
102
protected Vector JavaDoc cliParamDrdaTypes = new Vector JavaDoc();
103     protected Vector JavaDoc cliParamLens = new Vector JavaDoc();
104     protected ArrayList JavaDoc cliParamExtPositions = null;
105
106     // Query options sent on EXCSQLSTT
107
// These the default for ResultSets created for this statement.
108
// These can be overriden by OPNQRY or CNTQRY,
109
protected int nbrrow; // number of fetch or insert rows
110
protected int qryrowset; // Query row set
111
protected int blksize; // Query block size
112
protected int maxblkext; // Maximum number of extra blocks
113
protected int outovropt; // Output Override option
114
protected boolean qryrfrtbl; // Query refresh answer set table
115
private int qryprctyp = CodePoint.QRYBLKCTL_DEFAULT; // Protocol type
116

117     
118
119     boolean needsToSendParamData = false;
120     boolean explicitlyPrepared = false; //Prepared with PRPSQLSTT (reusable)
121

122     // constructor
123
/**
124      * DRDAStatement constructor
125      *
126      * @param database
127      *
128      */

129     DRDAStatement (Database database)
130     {
131         this.database = database;
132         setTypDefValues();
133         this.currentDrdaRs = new DRDAResultSet();
134     }
135
136     /**
137      * set TypDef values
138      *
139      */

140     protected void setTypDefValues()
141     {
142         // initialize statement values to current database values
143
this.typDefNam = database.typDefNam;
144         this.byteOrder = database.byteOrder;
145         this.ccsidSBC = database.ccsidSBC;
146         this.ccsidDBC = database.ccsidDBC;
147         this.ccsidMBC = database.ccsidMBC;
148         this.ccsidSBCEncoding = database.ccsidSBCEncoding;
149         this.ccsidDBCEncoding = database.ccsidDBCEncoding;
150         this.ccsidMBCEncoding = database.ccsidMBCEncoding;
151     }
152     /**
153      * Set database
154      *
155      * @param database
156      */

157     protected void setDatabase(Database database)
158     {
159         this.database = database;
160         setTypDefValues();
161     }
162     /**
163      * Set statement
164      *
165      * @param conn Connection
166      * @exception SQLException
167      */

168     protected void setStatement(Connection JavaDoc conn)
169         throws SQLException JavaDoc
170     {
171         stmt = conn.createStatement();
172         //beetle 3849 - see prepareStatement for details
173
if (cursorName != null)
174             stmt.setCursorName(cursorName);
175     }
176     /**
177      * Get the statement
178      *
179      * @return statement
180      * @exception SQLException
181      */

182     protected Statement JavaDoc getStatement()
183         throws SQLException JavaDoc
184     {
185         return stmt;
186     }
187
188     /**Set resultSet defaults to match
189      * the statement defaults sent on EXCSQLSTT
190      * This might be overridden on OPNQRY or CNTQRY
191      **/

192
193     protected void setRsDefaultOptions(DRDAResultSet drs)
194     {
195         drs.nbrrow = nbrrow;
196         drs.qryrowset = qryrowset;
197         drs.blksize = blksize;
198         drs.maxblkext = maxblkext;
199         drs.outovropt = outovropt;
200         drs.rslsetflg = rslsetflg;
201         drs.scrollType = scrollType;
202         drs.concurType = concurType;
203         drs.setQryprctyp(qryprctyp);
204         drs.qryrowset = qryrowset;
205     }
206
207     /**
208      * Get the extData Objects
209      *
210      * @return ArrayList with extdta
211      */

212     protected ArrayList JavaDoc getExtDtaObjects()
213     {
214         return currentDrdaRs.getExtDtaObjects();
215     }
216
217     /**
218      * Set the extData Objects
219      */

220     protected void setExtDtaObjects(ArrayList JavaDoc a)
221     {
222         currentDrdaRs.setExtDtaObjects(a);
223     }
224
225     public void setSplitQRYDTA(byte []data)
226     {
227         currentDrdaRs.setSplitQRYDTA(data);
228     }
229     public byte[]getSplitQRYDTA()
230     {
231         return currentDrdaRs.getSplitQRYDTA();
232     }
233     
234     /**
235      * Add extDtaObject
236      * @param o - object to add
237      * @param jdbcIndex - jdbc index for parameter
238      */

239     protected void addExtDtaObject (Object JavaDoc o, int jdbcIndex )
240     {
241         currentDrdaRs.addExtDtaObject(o,jdbcIndex);
242     }
243
244     
245     /**
246      * Clear externalized lob objects in current result set
247      */

248     protected void clearExtDtaObjects ()
249     {
250         currentDrdaRs.clearExtDtaObjects();
251     }
252
253     /**
254      *
255      * get resultSetHoldability.
256      *
257      * @return the resultSet holdability for the prepared statement
258      *
259      */

260     protected int getResultSetHoldability() throws SQLException JavaDoc
261     {
262         Statement JavaDoc rsstmt;
263         ResultSet JavaDoc rs = getResultSet();
264
265         if (rs != null)
266             rsstmt = rs.getStatement();
267         else
268             rsstmt = getPreparedStatement();
269         
270         int holdValue =
271             ((EngineStatement) rsstmt).getResultSetHoldability();
272
273         return holdValue;
274     }
275     
276     /**
277      *
278      * get resultSetHoldability.
279      *
280      * @param rs ResultSet
281      * @return the resultSet holdability for the prepared statement
282      *
283      */

284     int getResultSetHoldability(ResultSet JavaDoc rs) throws SQLException JavaDoc
285     {
286         Statement JavaDoc rsstmt;
287
288         if (rs != null)
289             rsstmt = rs.getStatement();
290         else
291             rsstmt = getPreparedStatement();
292         
293         int holdValue =
294             ((EngineStatement) rsstmt).getResultSetHoldability();
295
296         return holdValue;
297     }
298
299     /*
300      * Is lob object nullable
301      * @param index - offset starting with 0
302      * @return true if object is nullable
303      */

304     protected boolean isExtDtaValueNullable(int index)
305     {
306         return currentDrdaRs.isExtDtaValueNullable(index);
307     }
308     
309
310     /**
311      * Set query options sent on OPNQRY and pass options down to the
312      * current <code>DRDAResultSet</code> object.
313      *
314      * @param blksize QRYBLKSZ (Query Block Size)
315      * @param qryblkctl QRYPRCTYP (Query Protocol Type)
316      * @param maxblkext MAXBLKEXT (Maximum Number of Extra Blocks)
317      * @param outovropt OUTOVROPT (Output Override Option)
318      * @param qryrowset QRYROWSET (Query Rowset Size)
319      * @param qryclsimpl QRYCLSIMP (Query Close Implicit)
320      * @see DRDAResultSet#setOPNQRYOptions(int, int, int, int, int, int)
321      */

322     protected void setOPNQRYOptions(int blksize, int qryblkctl,
323                                   int maxblkext, int outovropt,int qryrowset,int qryclsimpl)
324     {
325         this.blksize = blksize;
326         this.qryprctyp = qryblkctl;
327         this.maxblkext = maxblkext;
328         this.outovropt = outovropt;
329         this.qryrowset = qryrowset;
330         currentDrdaRs.setOPNQRYOptions( blksize, qryblkctl, maxblkext,
331                 outovropt, qryrowset, qryclsimpl);
332     }
333
334     /*
335      * Set query options sent on CNTQRY
336      */

337     protected void setQueryOptions(int blksize, boolean qryrelscr,
338                                     long qryrownbr,
339                                     boolean qryfrtbl,int nbrrow,int maxblkext,
340                                     int qryscrorn, boolean qryrowsns,
341                                     boolean qryblkrst,
342                                     boolean qryrtndta,int qryrowset,
343                                     int rtnextdta)
344     {
345         currentDrdaRs.blksize = blksize;
346         currentDrdaRs.qryrelscr = qryrelscr;
347         currentDrdaRs.qryrownbr = qryrownbr;
348         currentDrdaRs.qryrfrtbl = qryrfrtbl;
349         currentDrdaRs.nbrrow = nbrrow;
350         currentDrdaRs.maxblkext = maxblkext;
351         currentDrdaRs.qryscrorn = qryscrorn;
352         currentDrdaRs.qryrowsns = qryrowsns;
353         currentDrdaRs.qryblkrst = qryblkrst;
354         currentDrdaRs.qryrtndta = qryrtndta;
355         currentDrdaRs.qryrowset = qryrowset;
356         currentDrdaRs.rtnextdta = rtnextdta;
357     }
358
359
360
361     protected void setQryprctyp(int qryprctyp)
362     {
363         this.qryprctyp = qryprctyp;
364         currentDrdaRs.setQryprctyp(qryprctyp);
365     }
366
367     protected int getQryprctyp()
368         throws SQLException JavaDoc
369     {
370         return currentDrdaRs.getQryprctyp();
371     }
372
373     protected void setQryrownbr(long qryrownbr)
374     {
375         currentDrdaRs.qryrownbr = qryrownbr;
376     }
377
378     protected long getQryrownbr()
379     {
380         return currentDrdaRs.qryrownbr;
381     }
382
383
384     protected int getQryrowset()
385     {
386         return currentDrdaRs.qryrowset;
387     }
388
389     
390     protected int getBlksize()
391     {
392         return currentDrdaRs.blksize;
393     }
394
395     protected void setQryrtndta(boolean qryrtndta)
396     {
397         currentDrdaRs.qryrtndta = qryrtndta;
398     }
399
400     protected boolean getQryrtndta()
401     {
402         return currentDrdaRs.qryrtndta;
403     }
404
405
406     protected void setQryscrorn(int qryscrorn)
407     {
408         currentDrdaRs.qryscrorn = qryscrorn;
409     }
410
411     protected int getQryscrorn()
412     {
413         return currentDrdaRs.qryscrorn;
414     }
415
416     protected void setScrollType(int scrollType)
417     {
418         currentDrdaRs.scrollType = scrollType;
419     }
420
421     protected int getScrollType()
422     {
423         return currentDrdaRs.scrollType;
424     }
425
426     /**
427      * is this a scrollable cursor?
428      * return true if this is not a forward only cursor
429      */

430     protected boolean isScrollable()
431     {
432         return (getScrollType() != ResultSet.TYPE_FORWARD_ONLY);
433     }
434
435     protected void setConcurType(int scrollType)
436     {
437         currentDrdaRs.concurType = scrollType;
438     }
439
440     protected int getConcurType()
441     {
442         return currentDrdaRs.concurType;
443     }
444
445     protected void setOutovr_drdaType(int[] outovr_drdaType)
446     {
447        currentDrdaRs.outovr_drdaType = outovr_drdaType;
448     }
449
450
451     protected int[] getOutovr_drdaType()
452     {
453         return currentDrdaRs.outovr_drdaType;
454     }
455     
456     protected boolean hasdata()
457     {
458         return currentDrdaRs.hasdata;
459     }
460     
461     protected void setHasdata(boolean hasdata)
462     {
463         currentDrdaRs.hasdata = hasdata;
464     }
465
466     /**
467      * This method is used to initialize the default statement of the database
468      * for re-use. It is different from reset() method since default statements
469      * get initiliazed differently. e.g: stmt variable used in default statement
470      * is created only once in Database.makeConnection.
471      * TODO: Need to see what exactly it means to initialize the default
472      * statement. (DERBY-1002)
473      *
474      */

475     protected void initialize()
476     {
477         setTypDefValues();
478     }
479
480
481     protected PreparedStatement JavaDoc explicitPrepare(String JavaDoc sqlStmt) throws SQLException JavaDoc
482     {
483         explicitlyPrepared = true;
484         return prepare(sqlStmt);
485     }
486
487     protected boolean wasExplicitlyPrepared()
488     {
489         return explicitlyPrepared;
490     }
491
492     /**
493      * Create a prepared statement
494      *
495      * @param sqlStmt - SQL statement
496      *
497      * @exception SQLException
498      */

499     protected PreparedStatement JavaDoc prepare(String JavaDoc sqlStmt) throws SQLException JavaDoc
500     {
501         // save current prepare iso level
502
int saveIsolationLevel = -1;
503         boolean isolationSet = false;
504         if (pkgnamcsn !=null &&
505             isolationLevel != Connection.TRANSACTION_NONE)
506         {
507             saveIsolationLevel = database.getPrepareIsolation();
508             database.setPrepareIsolation(isolationLevel);
509             isolationSet = true;
510         }
511         
512         if (isCallableSQL(sqlStmt))
513         {
514             isCall = true;
515             ps = database.getConnection().prepareCall(sqlStmt);
516             setupCallableStatementParams((CallableStatement JavaDoc)ps);
517             if (isolationSet)
518                 database.setPrepareIsolation(saveIsolationLevel);
519             return ps;
520         }
521         parsePkgidToFindHoldability();
522         ps = prepareStatementJDBC3(sqlStmt, scrollType, concurType,
523                                        withHoldCursor);
524         // beetle 3849 - Need to change the cursor name to what
525
// JCC thinks it will be, since there is no way in the
526
// protocol to communicate the actual cursor name. JCC keeps
527
// a mapping from the client cursor names to the DB2 style cursor names
528
if (cursorName != null)//cursorName not null means we are dealing with dynamic pacakges
529
ps.setCursorName(cursorName);
530         if (isolationSet)
531             database.setPrepareIsolation(saveIsolationLevel);
532                 return ps;
533     }
534
535     /**
536      * Get prepared statement
537      *
538      * @return prepared statement
539      */

540     protected PreparedStatement JavaDoc getPreparedStatement() throws SQLException JavaDoc
541     {
542         return ps;
543     }
544
545
546     /**
547      * Executes the prepared statement and populates the resultSetTable.
548      * Access to the various resultSets is then possible by using
549      * setCurrentDrdaResultSet(String pkgnamcsn) to set the current
550      * resultSet and then calling getResultSet() or the other access
551      * methods to get resultset data.
552      *
553      * @return true if the execution has resultSets
554      */

555     protected boolean execute() throws SQLException JavaDoc
556     {
557         boolean hasResultSet = ps.execute();
558
559         // java.sql.Statement says any result sets that are opened
560
// when the statement is re-executed must be closed; this
561
// is handled by the call to "ps.execute()" above--but we
562
// also have to reset our 'numResultSets' counter, since
563
// all previously opened result sets are now invalid.
564
numResultSets = 0;
565
566         ResultSet JavaDoc rs = null;
567         boolean isCallable = (ps instanceof java.sql.CallableStatement JavaDoc);
568         if (isCallable)
569             needsToSendParamData = true;
570
571         do {
572             rs = ps.getResultSet();
573             if (rs !=null)
574             {
575                 //For callable statement, get holdability of statement generating the result set
576
if(isCallable)
577                     addResultSet(rs,getResultSetHoldability(rs));
578                 else
579                     addResultSet(rs,withHoldCursor);
580                 hasResultSet = true;
581             }
582             // For normal selects we are done, but procedures might
583
// have more resultSets
584
}while (isCallable && getMoreResults(JDBC30Translation.KEEP_CURRENT_RESULT));
585
586         return hasResultSet;
587
588     }
589     
590     /**
591      * clear out type data for parameters.
592      * Unfortunately we currently overload the resultSet type info
593      * rsDRDATypes et al with parameter info.
594      * RESOLVE: Need to separate this
595      */

596    protected void finishParams()
597     {
598         needsToSendParamData = false;
599     }
600
601     /**
602      * Set the pkgid sec num for this statement and the
603      * consistency token that will be used for the first resultSet.
604      * For dyamic packages The package name is encoded as follows
605      * SYS(S/L)(H/N)xyy
606      * where 'S' represents Small package and 'L' large
607      * (ignored by cloudscape)
608      * Where 'H' represents WITH HOLD, and 'N' represents NO WITH HOLD.
609      * (May be overridden by SQLATTR for WITH
610      * HOLD")
611      *
612      * Where 'www' is the package iteration (ignored by cloudcape)
613      * Where 'x' is the isolation level: 0=NC, 1=UR, 2=CS, 3=RS, 4=RR
614      * Where 'yy' is the package iteration 00 through FF
615      * Where 'zz' is unique for each platform
616      * Happilly, these values correspond precisely to the internal cloudscape
617      * isolation levels in ExecutionContext.java
618      * x Isolation Level
619      * -- ---------------------
620      * 0 NC (java.sql.Connection.TRANSACTION_NONE)
621      * 1 UR (java.sql.Connection.TRANACTION_READ_UNCOMMITTED)
622      * 2 CS (java.sql.Connection.TRANSACTION_READ_COMMITTED)
623      * 3 RS (java.sql.Connection.TRANSACTION_REPEATABLE_READ)
624      * 4 RR (java.sql.Connection.TRANSACTION_SERIALIZABLE)
625      *
626      * static packages have preset isolation levels
627      * (see getStaticPackageIsolation)
628      * @param pkgnamcsn package id section number and token from the client
629      */

630     protected void setPkgnamcsn(Pkgnamcsn pkgnamcsn)
631     {
632         this.pkgnamcsn = pkgnamcsn;
633         // Store the consistency string for the first ResultSet.
634
// this will be used to calculate consistency strings for the
635
// other result sets.
636
pkgid = pkgnamcsn.getPkgid();
637
638         if (isDynamicPkgid(pkgid))
639         {
640             isolationLevel = Integer.parseInt(pkgid.substring(5,6));
641             
642             
643             /*
644              * generate DB2-style cursorname
645              * example value : SQL_CURSN200C1
646              * where
647              * SQL_CUR is db2 cursor name prefix;
648              * S - Small package , L -Large package
649              * N - normal cursor, H - hold cursor
650              * 200 - package id as sent by jcc
651              * C - tack-on code for cursors
652              * 1 - section number sent by jcc
653              */

654             
655             
656
657             // cursor name
658
// trim the SYS off the pkgid so it wont' be in the cursor name
659
String JavaDoc shortPkgid = pkgid.substring(pkgid.length() -5 , pkgid.length());
660             pkgsn = pkgnamcsn.getPkgsn();
661             this.cursorName = "SQL_CUR" + shortPkgid + "C" + pkgsn ;
662         }
663         else // static package
664
{
665             isolationLevel = getStaticPackageIsolation(pkgid);
666         }
667
668         this.pkgcnstkn = pkgnamcsn.getPkgcnstkn();
669
670     }
671
672
673     /**
674      * get the isolation level for a static package.
675      * @param pkgid - Package identifier string (e.g. SYSSTAT)
676      * @return isolation
677      */

678     private int getStaticPackageIsolation(String JavaDoc pkgid)
679     {
680         // SYSSTAT is used for metadata. and is the only static package used
681
// for JCC. Other static packages will need to be supported for
682
// CCC. Maybe a static hash table would then be in order.
683
if (pkgid.equals("SYSSTAT"))
684             return ExecutionContext.READ_UNCOMMITTED_ISOLATION_LEVEL;
685         else
686             return ExecutionContext.UNSPECIFIED_ISOLATION_LEVEL;
687     }
688
689     /**
690      * Get pkgnamcsn
691      *
692      * @return pkgnamcsn
693      */

694     protected Pkgnamcsn getPkgnamcsn()
695     {
696         return pkgnamcsn;
697
698     }
699     /**
700      * Get result set
701      *
702      * @return result set
703      */

704     protected ResultSet JavaDoc getResultSet()
705     {
706         return currentDrdaRs.getResultSet();
707     }
708
709     
710     /**
711      * Just get the resultset. Don't set it to current
712      * Assumes resultSet rsnum exists.
713      *
714      * @param rsNum resultSetNumber starting with 0
715      * @return The result set in the order it was retrieved
716      *
717      * with getMoreResults()
718      **/

719     private ResultSet JavaDoc getResultSet(int rsNum)
720     {
721         if (rsNum == 0)
722             return currentDrdaRs.getResultSet();
723         else
724         {
725             ConsistencyToken key = (ConsistencyToken) resultSetKeyList.get(rsNum);
726             return ((DRDAResultSet) (resultSetTable.get( key))).getResultSet();
727         }
728     }
729
730     /**
731      * Set result set
732      *
733      * @param value
734      */

735     protected void setResultSet(ResultSet JavaDoc value) throws SQLException JavaDoc
736     {
737         if (currentDrdaRs.getResultSet() == null)
738             numResultSets = 1;
739         currentDrdaRs.setResultSet(value);
740         setRsDefaultOptions(currentDrdaRs);
741     }
742     
743     /**
744      * Gets the current DRDA ResultSet
745      *
746      * @return DRDAResultSet
747      */

748     protected DRDAResultSet getCurrentDrdaResultSet()
749     {
750         return currentDrdaRs ;
751     }
752
753     /**
754      * Set currentDrdaResultSet
755      *
756      * @param rsNum The result set number starting with 0
757      *
758      */

759     protected void setCurrentDrdaResultSet(int rsNum)
760     {
761         ConsistencyToken consistToken = getResultSetPkgcnstkn(rsNum);
762         if (currentDrdaRs.pkgcnstkn == consistToken)
763             return;
764         currentDrdaRs = getDrdaResultSet(consistToken);
765
766     }
767
768     /**
769      * Set currentDrdaResultSet
770      *
771      * @param pkgnamcsn The pkgid section number and unique resultset
772      * consistency token
773      *
774      */

775     protected void setCurrentDrdaResultSet(Pkgnamcsn pkgnamcsn)
776     {
777         pkgid = pkgnamcsn.getPkgid();
778         pkgsn = pkgnamcsn.getPkgsn();
779         ConsistencyToken consistToken = pkgnamcsn.getPkgcnstkn();
780         DRDAResultSet newDrdaRs = getDrdaResultSet(consistToken);
781         if (newDrdaRs != null)
782             currentDrdaRs = newDrdaRs;
783     }
784
785
786     /*
787      * get DRDAResultSet by consistency token
788      *
789      */

790     private DRDAResultSet getDrdaResultSet(ConsistencyToken consistToken)
791     {
792         if ( resultSetTable == null ||
793              (currentDrdaRs != null &&
794               currentDrdaRs.pkgcnstkn == consistToken ))
795         {
796             return currentDrdaRs;
797         }
798         else
799         {
800             return (DRDAResultSet) (resultSetTable.get(consistToken));
801         }
802     }
803     
804     /*
805      * get DRDAResultSet by result set number
806      *
807      */

808     private DRDAResultSet getDrdaResultSet(int rsNum)
809     {
810         ConsistencyToken consistToken = getResultSetPkgcnstkn(rsNum);
811         return getDrdaResultSet(consistToken);
812     }
813
814     /** Add a new resultSet to this statement.
815      * Set as the current result set if there is not an
816      * existing current resultset.
817      * @param value - ResultSet to add
818      * @param holdValue - Holdability of the ResultSet
819      * @return Consistency token for this resultSet
820      * For a single resultSet that is the same as the statement's
821      * For multiple resultSets just the consistency token is changed
822      */

823     protected ConsistencyToken addResultSet(ResultSet JavaDoc value, int holdValue) throws SQLException JavaDoc
824     {
825
826         DRDAResultSet newDrdaRs = null;
827
828         int rsNum = numResultSets;
829         ConsistencyToken newRsPkgcnstkn = calculateResultSetPkgcnstkn(rsNum);
830
831         if (rsNum == 0)
832             newDrdaRs = currentDrdaRs;
833
834         else
835         {
836             newDrdaRs = new DRDAResultSet();
837
838             // Multiple resultSets we neeed to setup the hash table
839
if (resultSetTable == null)
840             {
841                 // If hashtable doesn't exist, create it and store resultSet 0
842
// before we store our new resultSet.
843
// For just a single resultSet we don't ever create the Hashtable.
844
resultSetTable = new Hashtable JavaDoc();
845                 resultSetTable.put(pkgcnstkn, currentDrdaRs);
846                 resultSetKeyList = new ArrayList JavaDoc();
847                 resultSetKeyList.add(0, pkgcnstkn);
848             }
849
850             resultSetTable.put(newRsPkgcnstkn, newDrdaRs);
851             resultSetKeyList.add(rsNum, newRsPkgcnstkn);
852         }
853
854         newDrdaRs.setResultSet(value);
855         newDrdaRs.setPkgcnstkn(newRsPkgcnstkn);
856         newDrdaRs.withHoldCursor = holdValue;
857         setRsDefaultOptions(newDrdaRs);
858         newDrdaRs.suspend();
859         numResultSets++;
860         return newRsPkgcnstkn;
861     }
862
863     /**
864      *
865      * @return number of result sets
866      */

867     protected int getNumResultSets()
868     {
869         return numResultSets;
870     }
871     
872     
873     /**
874      * @param rsNum result set starting with 0
875      * @return consistency token (key) for the result set
876      */

877     protected ConsistencyToken getResultSetPkgcnstkn(int rsNum)
878     {
879         if (rsNum == 0)
880             return pkgcnstkn;
881         else
882             return (ConsistencyToken) resultSetKeyList.get(rsNum);
883     }
884
885
886     /**
887      * Set ResultSet DRDA DataTypes
888      * @param value drdaTypes for columns.
889      **/

890     protected void setRsDRDATypes(int [] value)
891     {
892         currentDrdaRs.setRsDRDATypes(value);
893     }
894
895     /**
896      *@return ResultSet DRDA DataTypes
897      **/

898
899     protected int[] getRsDRDATypes()
900     {
901         return currentDrdaRs.getRsDRDATypes();
902
903     }
904
905
906     /**
907      * Set ResultSet DRDA DataTypes Lengths
908      * @param value drdaTypes for columns.
909      **/

910     protected void setRsLens(int [] value)
911     {
912         currentDrdaRs.rsLens = value;
913
914     }
915
916     /**
917      *@return ResultSet DRDA DataTypes Lengths
918      **/

919
920     protected int[] getRsLens()
921     {
922         return currentDrdaRs.rsLens;
923     }
924
925     /**
926      * Close the current resultSet
927      */

928     protected void rsClose() throws SQLException JavaDoc
929     {
930         if (currentDrdaRs.getResultSet() == null)
931             return;
932
933         currentDrdaRs.close();
934         needsToSendParamData = false;
935         numResultSets--;
936     }
937
938     /**
939      * Explicitly close the result set by CLSQRY
940      * needed to check for double close.
941      */

942     protected void CLSQRY()
943     {
944         currentDrdaRs.CLSQRY();
945     }
946
947     /*
948      * @return whether CLSQRY has been called on the
949      * current result set.
950      */

951     protected boolean wasExplicitlyClosed()
952     {
953         return currentDrdaRs.wasExplicitlyClosed();
954     }
955
956     /**
957      * This method closes the JDBC objects and frees up all references held by
958      * this object.
959      *
960      * @throws SQLException
961      */

962     protected void close() throws SQLException JavaDoc
963     {
964         if (ps != null)
965             ps.close();
966         if (stmt != null)
967             stmt.close();
968         currentDrdaRs.close();
969         resultSetTable = null;
970         resultSetKeyList = null;
971         ps = null;
972         stmtPmeta = null;
973         stmt = null;
974         rslsetflg = null;
975         procName = null;
976         outputTypes = null;
977         cliParamDrdaTypes = null;
978         cliParamLens = null;
979         cliParamExtPositions = null;
980
981     }
982     
983     /**
984      * This method resets the state of this DRDAStatement object so that it can
985      * be re-used. This method should reset all variables of this class except
986      * the following:
987      * 1. database - This variable gets initialized in the constructor and by
988      * call to setDatabase.
989      * 2. members which get initialized in setPkgnamcsn (pkgnamcsn, pkgcnstkn,
990      * pkgid, pkgsn, isolationLevel, cursorName). pkgnamcsn is the key used to
991      * find if the DRDAStatement can be re-used. Hence its value will not change
992      * when the object is re-used.
993      *
994      */

995     protected void reset()
996     {
997         setTypDefValues();
998         
999         withHoldCursor = -1;
1000        scrollType = ResultSet.TYPE_FORWARD_ONLY;
1001        concurType = ResultSet.CONCUR_READ_ONLY;;
1002        rowCount = 0;
1003        rslsetflg = null;
1004        maxrslcnt = 0;
1005        ps = null;
1006        stmtPmeta = null;
1007        isCall = false;
1008        procName = null;
1009        outputTypes = null;
1010        outputExpected = false;
1011        stmt = null;
1012        
1013        currentDrdaRs.reset();
1014        resultSetTable = null;
1015        resultSetKeyList = null;
1016        numResultSets = 0;
1017        
1018        cliParamDrdaTypes = new Vector JavaDoc();
1019        cliParamLens = new Vector JavaDoc();
1020        cliParamExtPositions = null;
1021        
1022        nbrrow = 0;
1023        qryrowset = 0;
1024        blksize = 0;
1025        maxblkext = 0;
1026        outovropt = 0;
1027        qryrfrtbl = false;
1028        qryprctyp = CodePoint.QRYBLKCTL_DEFAULT;
1029
1030        needsToSendParamData = false;
1031        explicitlyPrepared = false;
1032    }
1033
1034    /**
1035     * is Statement closed
1036     * @return whether the statement is closed
1037     */

1038    protected boolean rsIsClosed()
1039    {
1040        return currentDrdaRs.isClosed();
1041    }
1042    
1043    /**
1044     * Set state to SUSPENDED (result set is opened)
1045     */

1046    protected void rsSuspend()
1047    {
1048        currentDrdaRs.suspend();
1049    }
1050
1051
1052    /**
1053     * set resultset/out parameter precision
1054     *
1055     * @param index - starting with 1
1056     * @param precision
1057     */

1058    protected void setRsPrecision(int index, int precision)
1059    {
1060        currentDrdaRs.setRsPrecision(index,precision);
1061    }
1062
1063    /**
1064     * get resultset /out paramter precision
1065     * @param index -starting with 1
1066     * @return precision of column
1067     */

1068    protected int getRsPrecision(int index)
1069    {
1070        return currentDrdaRs.getRsPrecision(index);
1071    }
1072
1073    /**
1074     * set resultset/out parameter scale
1075     *
1076     * @param index - starting with 1
1077     * @param scale
1078     */

1079    protected void setRsScale(int index, int scale)
1080    {
1081        currentDrdaRs.setRsScale(index, scale);
1082    }
1083
1084    /**
1085     * get resultset /out paramter scale
1086     * @param index -starting with 1
1087     * @return scale of column
1088     */

1089    protected int getRsScale(int index)
1090    {
1091        return currentDrdaRs.getRsScale(index);
1092    }
1093    
1094
1095    /**
1096     * set result DRDAType
1097     *
1098     * @param index - starting with 1
1099     * @param type
1100     */

1101    protected void setRsDRDAType(int index, int type)
1102    {
1103        currentDrdaRs.setRsDRDAType(index,type);
1104        
1105    }
1106
1107    
1108    /**
1109     * get parameter DRDAType
1110     *
1111     * @param index - starting with 1
1112     * @return DRDA Type of column
1113     */

1114    protected int getParamDRDAType(int index)
1115    {
1116        
1117        return ((Byte JavaDoc)cliParamDrdaTypes.get(index -1)).intValue();
1118    }
1119
1120
1121    /**
1122     * set param DRDAType
1123     *
1124     * @param index - starting with 1
1125     * @param type
1126     */

1127    protected void setParamDRDAType(int index, byte type)
1128    {
1129        cliParamDrdaTypes.addElement(new Byte JavaDoc(type));
1130        
1131    }
1132    /**
1133     * returns drda length of parameter as sent by client.
1134     * @param index
1135     * @return data length
1136
1137     */

1138
1139    protected int getParamLen(int index)
1140    {
1141        return ((Integer JavaDoc) cliParamLens.elementAt(index -1)).intValue();
1142    }
1143    /**
1144     * get parameter precision or DB2 max (31)
1145     *
1146     * @param index parameter index starting with 1
1147     *
1148     * @return precision
1149     */

1150    protected int getParamPrecision(int index) throws SQLException JavaDoc
1151    {
1152        if (ps != null && ps instanceof CallableStatement JavaDoc)
1153        {
1154            EngineParameterMetaData pmeta = getParameterMetaData();
1155
1156            return Math.min(pmeta.getPrecision(index),
1157                            FdocaConstants.NUMERIC_MAX_PRECISION);
1158
1159        }
1160        else
1161            return -1;
1162    }
1163    
1164    /**
1165     * get parameter scale or DB2 max (31)
1166     *
1167     * @param index parameter index starting with 1
1168     *
1169     * @return scale
1170     */

1171    protected int getParamScale(int index) throws SQLException JavaDoc
1172    {
1173        if (ps != null && ps instanceof CallableStatement JavaDoc)
1174        {
1175            EngineParameterMetaData pmeta = getParameterMetaData();
1176            return Math.min(pmeta.getScale(index),FdocaConstants.NUMERIC_MAX_PRECISION);
1177        }
1178        else
1179            return -1;
1180    }
1181
1182    /**
1183     * save parameter len sent by client
1184     * @param index parameter index starting with 1
1185     * @param value length of data value
1186     *
1187     */

1188    protected void setParamLen(int index, int value)
1189    {
1190        cliParamLens.add(index -1, new Integer JavaDoc(value));
1191    }
1192
1193    /**
1194     * get the number of parameters for this statement
1195     *
1196     * @return number of parameters
1197     */

1198    protected int getNumParams()
1199    {
1200        if (cliParamDrdaTypes != null)
1201            return cliParamDrdaTypes.size();
1202        else
1203            return 0;
1204    }
1205       
1206    /**
1207     * get the number of result set columns for the current resultSet
1208     *
1209     * @return number of columns
1210     */

1211
1212    protected int getNumRsCols()
1213    {
1214        int[] rsDrdaTypes = getRsDRDATypes();
1215        if (rsDrdaTypes != null)
1216            return rsDrdaTypes.length;
1217        else
1218            return 0;
1219    }
1220
1221    /**
1222     * get resultset/out parameter DRDAType
1223     *
1224     * @param index - starting with 1
1225     * @return DRDA Type of column
1226     */

1227    protected int getRsDRDAType(int index)
1228    {
1229        return currentDrdaRs.getRsDRDAType(index);
1230    }
1231
1232    /**
1233     * get resultset/out parameter DRDALen
1234     * @param index starting with 1
1235     *
1236     * @return length of drda data
1237     */

1238     
1239    protected int getRsLen(int index)
1240    {
1241        return currentDrdaRs.getRsLen(index);
1242    }
1243
1244    /**
1245     * set resultset column data length
1246     * @param index starting with 1
1247     * @param value length
1248     */

1249    protected void setRsLen(int index, int value)
1250    {
1251        currentDrdaRs.setRsLen(index,value);
1252    }
1253
1254    /**
1255     * @param rsNum - result set # starting with 0
1256     */

1257    public String JavaDoc getResultSetCursorName(int rsNum) throws SQLException JavaDoc
1258    {
1259        DRDAResultSet drdaRs = getDrdaResultSet(rsNum);
1260        return drdaRs.getResultSetCursorName();
1261
1262    }
1263
1264
1265    protected String JavaDoc toDebugString(String JavaDoc indent)
1266    {
1267        ResultSet JavaDoc rs = currentDrdaRs.getResultSet();
1268        
1269        String JavaDoc s ="";
1270        if (ps == null)
1271            s += indent + ps;
1272        else
1273        {
1274            s += indent + pkgid + pkgsn ;
1275            s += "\t" + getSQLText();
1276        }
1277        return s;
1278    }
1279
1280    /** For a single result set, just echo the consistency token that the client sent us.
1281     * For subsequent resultSets, just subtract the resultset number from
1282     * the consistency token and that will differentiate the result sets.
1283     * This seems to be what DB2 does
1284     * @param rsNum - result set # starting with 0
1285     *
1286     * @return Consistency token for result set
1287     */

1288
1289    protected ConsistencyToken calculateResultSetPkgcnstkn(int rsNum)
1290    {
1291        ConsistencyToken consistToken = pkgcnstkn;
1292
1293        if (rsNum == 0 || pkgcnstkn == null)
1294            return consistToken;
1295        else
1296        {
1297            BigInteger JavaDoc consistTokenBi =
1298                new BigInteger JavaDoc(consistToken.getBytes());
1299            BigInteger JavaDoc rsNumBi = BigInteger.valueOf(rsNum);
1300            consistTokenBi = consistTokenBi.subtract(rsNumBi);
1301            consistToken = new ConsistencyToken(consistTokenBi.toByteArray());
1302        }
1303        return consistToken;
1304    }
1305
1306    protected boolean isCallableStatement()
1307    {
1308        return isCall;
1309    }
1310
1311    private boolean isCallableSQL(String JavaDoc sql)
1312    {
1313        java.util.StringTokenizer JavaDoc tokenizer = new java.util.StringTokenizer JavaDoc
1314            (sql, "\t\n\r\f=? (");
1315         String JavaDoc firstToken = tokenizer.nextToken();
1316         if (StringUtil.SQLEqualsIgnoreCase(firstToken,
1317                                            "call")) // captures CALL...and ?=CALL...
1318
return true;
1319         return false;
1320                 
1321    }
1322
1323    private void setupCallableStatementParams(CallableStatement JavaDoc cs) throws SQLException JavaDoc
1324    {
1325        EngineParameterMetaData pmeta = getParameterMetaData();
1326        int numElems = pmeta.getParameterCount();
1327
1328        for ( int i = 0; i < numElems; i ++)
1329        {
1330            boolean outputFlag = false;
1331            
1332            int parameterMode = pmeta.getParameterMode(i + 1);
1333            int parameterType = pmeta.getParameterType(i + 1);
1334
1335            switch (parameterMode) {
1336                case JDBC30Translation.PARAMETER_MODE_IN:
1337                    break;
1338                case JDBC30Translation.PARAMETER_MODE_OUT:
1339                case JDBC30Translation.PARAMETER_MODE_IN_OUT:
1340                    outputFlag = true;
1341                    break;
1342                case JDBC30Translation.PARAMETER_MODE_UNKNOWN:
1343                    // It's only unknown if array
1344
String JavaDoc objectType = pmeta.getParameterClassName(i+1);
1345                    parameterType =
1346                        getOutputParameterTypeFromClassName(objectType);
1347                    if (parameterType != NOT_OUTPUT_PARAM)
1348                        outputFlag = true;
1349            }
1350
1351            if (outputFlag)
1352            {
1353                if (outputTypes == null) //not initialized yet, since previously none output
1354
{
1355                    outputTypes = new int[numElems];
1356                    for (int j = 0; j < numElems; j++)
1357                        outputTypes[j] = NOT_OUTPUT_PARAM; //default init value
1358
}
1359                // save the output type so we can register when we parse
1360
// the SQLDTA
1361
outputTypes[i] = parameterType;
1362            }
1363            
1364        }
1365    }
1366
1367
1368
1369    /**
1370        Given an object class name get the paramameter type if the
1371        parameter mode is unknown.
1372        
1373        Arrays except for byte arrrays are assumed to be output parameters
1374        TINYINT output parameters are going to be broken because there
1375        is no way to differentiate them from binary input parameters.
1376        @param objectName Class name of object being evaluated.
1377        indicating if this an output parameter
1378        @return type from java.sql.Types
1379    **/

1380    
1381    protected static int getOutputParameterTypeFromClassName(String JavaDoc
1382                                                                    objectName)
1383    {
1384        
1385        if (objectName.endsWith("[]"))
1386        {
1387                    // For byte[] we are going to assume it is input.
1388
// For TINYINT output params you gotta use
1389
// object Integer[] or use a procedure
1390
if (objectName.equals("byte[]"))
1391                    {
1392                        return NOT_OUTPUT_PARAM;
1393                            
1394                            //isOutParam[offset] = false;
1395
//return java.sql.Types.VARBINARY;
1396
}
1397                    
1398                    // Known arrays are output parameters
1399
// otherwise we pass it's a JAVA_OBJECT
1400
if (objectName.equals("java.lang.Byte[]"))
1401                        return java.sql.Types.TINYINT;
1402                    
1403                    if (objectName.equals("byte[][]"))
1404                        return java.sql.Types.VARBINARY;
1405                    if (objectName.equals("java.lang.String[]"))
1406                        return java.sql.Types.VARCHAR;
1407                    if (objectName.equals("int[]") ||
1408                        objectName.equals("java.lang.Integer[]"))
1409                        return java.sql.Types.INTEGER;
1410                    else if (objectName.equals("long[]")
1411                             || objectName.equals("java.lang.Long[]"))
1412                        return java.sql.Types.BIGINT;
1413                    else if (objectName.equals("java.math.BigDecimal[]"))
1414                        return java.sql.Types.NUMERIC;
1415                    else if (objectName.equals("boolean[]") ||
1416                             objectName.equals("java.lang.Boolean[]"))
1417                        return java.sql.Types.BIT;
1418                    else if (objectName.equals("short[]"))
1419                        return java.sql.Types.SMALLINT;
1420                    else if (objectName.equals("float[]") ||
1421                             objectName.equals("java.lang.Float[]"))
1422                        return java.sql.Types.REAL;
1423                    else if (objectName.equals("double[]") ||
1424                             objectName.equals("java.lang.Double[]"))
1425                        return java.sql.Types.DOUBLE;
1426                    else if (objectName.equals("java.sql.Date[]"))
1427                        return java.sql.Types.DATE;
1428                    else if (objectName.equals("java.sql.Time[]"))
1429                        return java.sql.Types.TIME;
1430                    else if (objectName.equals("java.sql.Timestamp[]"))
1431                        return java.sql.Types.TIMESTAMP;
1432        }
1433        // Not one of the ones we know. This must be a JAVA_OBJECT
1434
return NOT_OUTPUT_PARAM;
1435        //isOutParam[offset] = false;
1436
//return java.sql.Types.JAVA_OBJECT;
1437

1438    }
1439    
1440    
1441    public void registerAllOutParams() throws SQLException JavaDoc
1442    {
1443        if (isCall && (outputTypes != null))
1444            for (int i = 1; i <= outputTypes.length; i ++)
1445                registerOutParam(i);
1446        
1447    }
1448    
1449    public void registerOutParam(int paramNum) throws SQLException JavaDoc
1450    {
1451        CallableStatement JavaDoc cs;
1452        if (isOutputParam(paramNum))
1453        {
1454            cs = (CallableStatement JavaDoc) ps;
1455            cs.registerOutParameter(paramNum, getOutputParamType(paramNum));
1456        }
1457    }
1458
1459    protected boolean hasOutputParams()
1460    {
1461        return (outputTypes != null);
1462    }
1463
1464    /**
1465     * is parameter an ouput parameter
1466     * @param paramNum parameter number starting with 1.
1467     * return true if this is an output parameter.
1468     */

1469    boolean isOutputParam(int paramNum)
1470    {
1471        if (outputTypes != null)
1472            return (outputTypes[paramNum - 1] != NOT_OUTPUT_PARAM);
1473        return false;
1474        
1475    }
1476    /**
1477     * get type for output parameter.
1478     *
1479     * @param paramNum - parameter number starting with 1
1480     * @return jdbcType or NOT_OUTPUT_PARAM if this is not an output parameter
1481     */

1482    int getOutputParamType(int paramNum)
1483    {
1484        if (outputTypes != null)
1485            return (outputTypes[ paramNum - 1 ]);
1486        return NOT_OUTPUT_PARAM;
1487    }
1488
1489    private boolean isDynamicPkgid(String JavaDoc pkgid)
1490    {
1491        char size = pkgid.charAt(3);
1492        
1493        // separate attribute used for holdability in 5.1.60
1494
// this is just for checking that it is a dynamic package
1495
char holdability = pkgid.charAt(4);
1496        return (pkgid.substring(0,3).equals("SYS") && (size == 'S' ||
1497                                                       size == 'L')
1498                && (holdability == 'H' || holdability == 'N'));
1499        
1500    }
1501
1502   
1503    private void parsePkgidToFindHoldability()
1504    {
1505        if (withHoldCursor != -1)
1506            return;
1507        
1508        //First, check if holdability was passed as a SQL attribute "WITH HOLD" for this prepare. If yes, then withHoldCursor
1509
//should not get overwritten by holdability from package name and that is why the check for -1
1510
if (isDynamicPkgid(pkgid))
1511        {
1512            if(pkgid.charAt(4) == 'N')
1513                withHoldCursor = JDBC30Translation.CLOSE_CURSORS_AT_COMMIT;
1514            else
1515                withHoldCursor = JDBC30Translation.HOLD_CURSORS_OVER_COMMIT;
1516        }
1517        else
1518        {
1519            withHoldCursor = JDBC30Translation.HOLD_CURSORS_OVER_COMMIT;
1520        
1521        }
1522    }
1523
1524
1525    /**
1526     * prepare a statement using EngineConnection.prepareStatement
1527     * so that server can run on jdk131 and still pass holdability.
1528     * @param sqlStmt - SQL statement text
1529     * @param scrollType - scroll type
1530     * @param concurType - concurrency type
1531     * @param withHoldCursor - holdability
1532     *
1533     * @throws SQLException
1534     * @return Prepared Statement
1535     * @see java.sql.Connection#prepareStatement
1536     */

1537    private PreparedStatement JavaDoc prepareStatementJDBC3(String JavaDoc sqlStmt, int
1538                                                    scrollType, int concurType,
1539                                                    int withHoldCursor) throws SQLException JavaDoc
1540    {
1541        EngineConnection conn = database.getConnection();
1542        if (withHoldCursor == -1) {
1543            // Holdability not explictly set, let the
1544
// connection provide the default.
1545
return conn.prepareStatement(sqlStmt,
1546                    scrollType, concurType);
1547        }
1548        
1549        // Holdability explictly set.
1550
return conn.prepareStatement(sqlStmt,
1551                scrollType, concurType, withHoldCursor);
1552    }
1553
1554    
1555    /**
1556     * Retrieve the ParameterMetaData for the prepared statement.
1557     * To do so, use the engine defined interfaces:
1558     * @see org.apache.derby.iapi.jdbc.EnginePreparedStatement
1559     * @see org.apache.derby.iapi.jdbc.EngineParameterMetaData
1560     * @return EngineParameterMetaData for the prepared statement.
1561     * Note: there is no separate BrokeredParameterSetMetaData.
1562     */

1563    protected EngineParameterMetaData getParameterMetaData() throws SQLException JavaDoc
1564    {
1565        if (stmtPmeta != null)
1566            return stmtPmeta;
1567
1568        stmtPmeta = ((EnginePreparedStatement)ps).getEmbedParameterSetMetaData();
1569        
1570        return stmtPmeta;
1571    }
1572    
1573    /**
1574     * get more results using reflection.
1575     * @param current - flag to pass to Statement.getMoreResults(current)
1576     * @return true if there are more results.
1577     * @throws SQLException
1578     * @see java.sql.Statement#getMoreResults
1579     *
1580     */

1581    private boolean getMoreResults(int current) throws SQLException JavaDoc
1582    {
1583        return
1584            ((EngineStatement) getPreparedStatement()).getMoreResults(current);
1585    }
1586
1587    /**
1588     * Use reflection to retrieve SQL Text for EmbedPreparedStatement
1589     * or BrokeredPreparedStatement.
1590     * @return SQL text
1591     */

1592    private String JavaDoc getSQLText()
1593    {
1594       String JavaDoc retVal = null;
1595        Class JavaDoc[] emptyPARAM = {};
1596        Object JavaDoc[] args = null;
1597        try {
1598            Method JavaDoc sh = getPreparedStatement().getClass().getMethod("getSQLText",emptyPARAM);
1599            retVal = (String JavaDoc) sh.invoke(getPreparedStatement(),args);
1600        }
1601        catch (Exception JavaDoc e)
1602        {
1603            // do nothing we will just return a null string
1604
}
1605        return retVal;
1606
1607    }
1608
1609    /** helper method to handle exceptions generated by methods invoked
1610     * through reflection.
1611     * @param e - exception thrown
1612     * @throws SQLException - actual exception that occurred
1613     */

1614    private void handleReflectionException(Exception JavaDoc e) throws SQLException JavaDoc
1615    {
1616        if (e instanceof InvocationTargetException JavaDoc)
1617        {
1618            Throwable JavaDoc t = ((InvocationTargetException JavaDoc) e).getTargetException();
1619            
1620            if (t instanceof SQLException JavaDoc)
1621            {
1622                throw (SQLException JavaDoc) t;
1623            }
1624            else
1625            {
1626                t.printStackTrace();
1627                throw Util.javaException(t);
1628            }
1629        }
1630        else
1631            // invoke can throw IllegalAccessException or
1632
// IllegalArgumentException, but these should not
1633
// occur from this code. Just in case we will throw it
1634
throw Util.javaException(e);
1635        
1636    }
1637    
1638    /**
1639     * Method to decide whether the ResultSet should be closed
1640     * implicitly based on the QRYCLSIMP value sent from the
1641     * client. Only forward-only result sets should be implicitly
1642     * closed. Some clients do not expect result sets to be closed
1643     * implicitly if the protocol is LMTBLKPRC.
1644     *
1645     * @param lmtblkprcOK <code>true</code> if the client expects
1646     * QRYCLSIMP to be respected for the LMTBLKPRC protocol
1647     * @return implicit close boolean
1648     * @exception SQLException
1649     */

1650    boolean isRSCloseImplicit(boolean lmtblkprcOK) throws SQLException JavaDoc {
1651        return
1652            (currentDrdaRs.qryclsimp == CodePoint.QRYCLSIMP_YES) &&
1653            !isScrollable() &&
1654            (lmtblkprcOK ||
1655             (currentDrdaRs.getQryprctyp() != CodePoint.LMTBLKPRC));
1656    }
1657}
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
Popular Tags