KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > derby > iapi > jdbc > BrokeredStatement


1 /*
2
3    Derby - Class org.apache.derby.iapi.jdbc.BrokeredStatement
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.iapi.jdbc;
23
24 import org.apache.derby.iapi.reference.JDBC30Translation;
25 import org.apache.derby.iapi.reference.SQLState;
26
27 import org.apache.derby.iapi.error.StandardException;
28 import org.apache.derby.iapi.error.PublicAPI;
29 import org.apache.derby.iapi.services.info.JVMInfo;
30 import org.apache.derby.impl.jdbc.Util;
31
32 import java.sql.Connection JavaDoc;
33 import java.sql.ResultSet JavaDoc;
34 import java.sql.SQLException JavaDoc;
35 import java.sql.SQLWarning JavaDoc;
36 import java.sql.Statement JavaDoc;
37
38 import java.lang.reflect.*;
39
40 /**
41     A Statement implementation that forwards all of its requests to an underlying Statement.
42  */

43 public class BrokeredStatement implements EngineStatement
44 {
45
46     /**
47         My control. Use the controlCheck() method to obtain the control
48         when calling a check method. This will result in the correct exception
49         being thrown if the statement is already closed.
50     */

51     final BrokeredStatementControl control;
52
53     final int jdbcLevel;
54     final int resultSetType;
55     final int resultSetConcurrency;
56     final int resultSetHoldability;
57
58     /**
59         My state
60     */

61     private String JavaDoc cursorName;
62     private Boolean JavaDoc escapeProcessing;
63
64     BrokeredStatement(BrokeredStatementControl control, int jdbcLevel) throws SQLException JavaDoc
65     {
66         this.control = control;
67         this.jdbcLevel = jdbcLevel;
68
69         // save the state of the Statement while we are pretty much guaranteed the
70
// underlying statement is open.
71
resultSetType = getResultSetType();
72         resultSetConcurrency = getResultSetConcurrency();
73
74         resultSetHoldability = getResultSetHoldability();
75     }
76
77
78     public final void addBatch(String JavaDoc sql)
79               throws SQLException JavaDoc
80     {
81         getStatement().addBatch( sql);
82     }
83
84     public final void clearBatch()
85         throws SQLException JavaDoc
86     {
87            getStatement().clearBatch();
88     }
89
90     public final int[] executeBatch()
91         throws SQLException JavaDoc
92     {
93         return getStatement().executeBatch();
94     }
95
96
97     public final void cancel()
98         throws SQLException JavaDoc
99     {
100         getStatement().cancel();
101     }
102
103     public final boolean execute(String JavaDoc sql) throws SQLException JavaDoc
104     {
105         return getStatement().execute(sql);
106     }
107
108     public final ResultSet JavaDoc executeQuery(String JavaDoc sql) throws SQLException JavaDoc
109     {
110         return wrapResultSet(getStatement().executeQuery(sql));
111     }
112
113     public final int executeUpdate(String JavaDoc sql) throws SQLException JavaDoc
114     {
115         return getStatement().executeUpdate(sql);
116     }
117
118         
119     /**
120      * In many cases, it is desirable to immediately release a
121      * Statements's database and JDBC resources instead of waiting for
122      * this to happen when it is automatically closed; the close
123      * method provides this immediate release.
124      *
125      * <P><B>Note:</B> A Statement is automatically closed when it is
126      * garbage collected. When a Statement is closed its current
127      * ResultSet, if one exists, is also closed.
128      * @exception SQLException thrown on failure.
129      */

130     public final void close() throws SQLException JavaDoc
131     {
132         getStatement().close();
133     }
134
135     public final Connection JavaDoc getConnection()
136         throws SQLException JavaDoc
137     {
138         return getStatement().getConnection();
139     }
140
141     public final int getFetchDirection()
142         throws SQLException JavaDoc
143     {
144         return getStatement().getFetchDirection();
145     }
146
147     public final int getFetchSize()
148         throws SQLException JavaDoc
149     {
150         return getStatement().getFetchSize();
151     }
152
153     public final int getMaxFieldSize()
154         throws SQLException JavaDoc
155     {
156         return getStatement().getMaxFieldSize();
157     }
158
159     public final int getMaxRows()
160         throws SQLException JavaDoc
161     {
162         return getStatement().getMaxRows();
163     }
164
165     public final int getResultSetConcurrency()
166         throws SQLException JavaDoc
167     {
168         return getStatement().getResultSetConcurrency();
169     }
170
171     /**
172      * The maxFieldSize limit (in bytes) is set to limit the size of
173      * data that can be returned for any column value; it only applies
174      * to BINARY, VARBINARY, LONGVARBINARY, CHAR, VARCHAR, and
175      * LONGVARCHAR fields. If the limit is exceeded, the excess data
176      * is silently discarded.
177      *
178      * @param max the new max column size limit; zero means unlimited
179      * @exception SQLException thrown on failure.
180      */

181     public final void setMaxFieldSize(int max) throws SQLException JavaDoc
182     {
183         getStatement().setMaxFieldSize(max);
184     }
185
186     /**
187      * The maxRows limit is set to limit the number of rows that any
188      * ResultSet can contain. If the limit is exceeded, the excess
189      * rows are silently dropped.
190      *
191      * @param max the new max rows limit; zero means unlimited
192      * @exception SQLException thrown on failure.
193      */

194     public final void setMaxRows(int max) throws SQLException JavaDoc
195     {
196         getStatement().setMaxRows( max);
197     }
198
199     /**
200      * If escape scanning is on (the default) the driver will do
201      * escape substitution before sending the SQL to the database.
202      *
203      * @param enable true to enable; false to disable
204      * @exception SQLException thrown on failure.
205      */

206     public final void setEscapeProcessing(boolean enable) throws SQLException JavaDoc
207     {
208         getStatement().setEscapeProcessing( enable);
209         escapeProcessing = enable ? Boolean.TRUE : Boolean.FALSE;
210     }
211
212     /**
213      * The first warning reported by calls on this Statement is
214      * returned. A Statment's execute methods clear its SQLWarning
215      * chain. Subsequent Statement warnings will be chained to this
216      * SQLWarning.
217      *
218      * <p>The warning chain is automatically cleared each time
219      * a statement is (re)executed.
220      *
221      * <P><B>Note:</B> If you are processing a ResultSet then any
222      * warnings associated with ResultSet reads will be chained on the
223      * ResultSet object.
224      *
225      * @return the first SQLWarning or null
226      * @exception SQLException thrown on failure.
227      */

228     public final SQLWarning JavaDoc getWarnings() throws SQLException JavaDoc
229     {
230         return getStatement().getWarnings();
231     }
232
233     /**
234      * After this call getWarnings returns null until a new warning is
235      * reported for this Statement.
236      * @exception SQLException thrown on failure.
237      */

238     public final void clearWarnings() throws SQLException JavaDoc
239     {
240         getStatement().clearWarnings();
241     }
242
243     /**
244      * setCursorName defines the SQL cursor name that will be used by
245      * subsequent Statement execute methods. This name can then be
246      * used in SQL positioned update/delete statements to identify the
247      * current row in the ResultSet generated by this getStatement(). If
248      * the database doesn't support positioned update/delete, this
249      * method is a noop.
250      *
251      * <P><B>Note:</B> By definition, positioned update/delete
252      * execution must be done by a different Statement than the one
253      * which generated the ResultSet being used for positioning. Also,
254      * cursor names must be unique within a Connection.
255      *
256      * @param name the new cursor name.
257      */

258     public final void setCursorName(String JavaDoc name) throws SQLException JavaDoc
259     {
260         getStatement().setCursorName( name);
261         cursorName = name;
262     }
263     
264     
265     /**
266      * getResultSet returns the current result as a ResultSet. It
267      * should only be called once per result.
268      *
269      * @return the current result as a ResultSet; null if the result
270      * is an update count or there are no more results or the statement
271      * was closed.
272      * @see #execute
273      */

274     public final ResultSet JavaDoc getResultSet() throws SQLException JavaDoc
275     {
276         return wrapResultSet(getStatement().getResultSet());
277     }
278     
279     /**
280      * getUpdateCount returns the current result as an update count;
281      * if the result is a ResultSet or there are no more results -1
282      * is returned. It should only be called once per result.
283      *
284      * <P>The only way to tell for sure that the result is an update
285      * count is to first test to see if it is a ResultSet. If it is
286      * not a ResultSet it is either an update count or there are no
287      * more results.
288      *
289      * @return the current result as an update count; -1 if it is a
290      * ResultSet or there are no more results
291      * @see #execute
292      */

293     public final int getUpdateCount() throws SQLException JavaDoc
294     {
295         return getStatement().getUpdateCount();
296     }
297
298     /**
299      * getMoreResults moves to a Statement's next result. It returns true if
300      * this result is a ResultSet. getMoreResults also implicitly
301      * closes any current ResultSet obtained with getResultSet.
302      *
303      * There are no more results when (!getMoreResults() &&
304      * (getUpdateCount() == -1)
305      *
306      * @return true if the next result is a ResultSet; false if it is
307      * an update count or there are no more results
308      * @see #execute
309      * @exception SQLException thrown on failure.
310      */

311     public final boolean getMoreResults() throws SQLException JavaDoc
312     {
313         return getStatement().getMoreResults();
314     }
315
316     /**
317      * JDBC 2.0
318      *
319      * Determine the result set type.
320      *
321      * @exception SQLException Feature not implemented for now.
322      */

323     public final int getResultSetType()
324         throws SQLException JavaDoc
325     {
326         return getStatement().getResultSetType();
327     }
328
329     /**
330      * JDBC 2.0
331      *
332      * Give a hint as to the direction in which the rows in a result set
333      * will be processed. The hint applies only to result sets created
334      * using this Statement object. The default value is
335      * ResultSet.FETCH_FORWARD.
336      *
337      * @param direction the initial direction for processing rows
338      * @exception SQLException if a database-access error occurs or direction
339      * is not one of ResultSet.FETCH_FORWARD, ResultSet.FETCH_REVERSE, or
340      * ResultSet.FETCH_UNKNOWN
341      */

342     public final void setFetchDirection(int direction) throws SQLException JavaDoc
343     {
344         getStatement().setFetchDirection( direction);
345     }
346
347     /**
348      * JDBC 2.0
349      *
350      * Give the JDBC driver a hint as to the number of rows that should
351      * be fetched from the database when more rows are needed. The number
352      * of rows specified only affects result sets created using this
353      * getStatement(). If the value specified is zero, then the hint is ignored.
354      * The default value is zero.
355      *
356      * @param rows the number of rows to fetch
357      * @exception SQLException if a database-access error occurs, or the
358      * condition 0 <= rows <= this.getMaxRows() is not satisfied.
359      */

360     public final void setFetchSize(int rows) throws SQLException JavaDoc
361     {
362         getStatement().setFetchSize( rows);
363     }
364
365     public final int getQueryTimeout()
366         throws SQLException JavaDoc
367     {
368         return getStatement().getQueryTimeout();
369     }
370
371     public final void setQueryTimeout(int seconds)
372         throws SQLException JavaDoc
373     {
374         getStatement().setQueryTimeout( seconds);
375     }
376
377
378     /*
379     ** JDBC 3.0 methods
380     */

381     public final boolean execute(String JavaDoc sql,
382                            int autoGeneratedKeys)
383         throws SQLException JavaDoc
384     {
385
386         return getStatement().execute( sql, autoGeneratedKeys);
387     }
388
389
390     public final boolean execute(String JavaDoc sql,
391                            int[] columnIndexes)
392         throws SQLException JavaDoc
393     {
394         return getStatement().execute( sql, columnIndexes);
395     }
396
397     public final boolean execute(String JavaDoc sql,
398                            String JavaDoc[] columnNames)
399         throws SQLException JavaDoc
400     {
401         return getStatement().execute( sql, columnNames);
402     }
403
404     public final int executeUpdate(String JavaDoc sql,
405                            int autoGeneratedKeys)
406         throws SQLException JavaDoc
407     {
408                 int retVal = getStatement().executeUpdate( sql, autoGeneratedKeys);
409                 return retVal;
410     }
411
412     public final int executeUpdate(String JavaDoc sql,
413                            int[] columnIndexes)
414         throws SQLException JavaDoc
415     {
416              return getStatement().executeUpdate( sql, columnIndexes);
417     }
418
419     public final int executeUpdate(String JavaDoc sql,
420                            String JavaDoc[] columnNames)
421         throws SQLException JavaDoc
422     {
423
424         return getStatement().executeUpdate( sql, columnNames);
425     }
426
427
428
429     /**
430      * JDBC 3.0
431      *
432      * Moves to this Statement obect's next result, deals with any current ResultSet
433      * object(s) according to the instructions specified by the given flag, and
434      * returns true if the next result is a ResultSet object
435      *
436      * @param current - one of the following Statement constants indicating what
437      * should happen to current ResultSet objects obtained using the method
438      * getResultSetCLOSE_CURRENT_RESULT, KEEP_CURRENT_RESULT, or CLOSE_ALL_RESULTS
439      * @return true if the next result is a ResultSet; false if it is
440      * an update count or there are no more results
441      * @see #execute
442      * @exception SQLException thrown on failure.
443      */

444     public final boolean getMoreResults(int current) throws SQLException JavaDoc
445     {
446         return ((EngineStatement) getStatement()).getMoreResults( current);
447     }
448
449     /**
450      * JDBC 3.0
451      *
452      * Retrieves any auto-generated keys created as a result of executing this
453      * Statement object. If this Statement object did not generate any keys, an empty
454      * ResultSet object is returned. If this Statement is a non-insert statement,
455      * an exception will be thrown.
456      *
457      * @return a ResultSet object containing the auto-generated key(s) generated by
458      * the execution of this Statement object
459      * @exception SQLException if a database access error occurs
460      */

461     public final ResultSet JavaDoc getGeneratedKeys() throws SQLException JavaDoc
462     {
463         return wrapResultSet(getStatement().getGeneratedKeys());
464     }
465
466     /**
467      * Return the holdability of ResultSets created by this Statement.
468      * If this Statement is active in a global transaction the
469      * CLOSE_CURSORS_ON_COMMIT will be returned regardless of
470      * the holdability it was created with. In a local transaction
471      * the original create holdabilty will be returned.
472      */

473     public final int getResultSetHoldability()
474         throws SQLException JavaDoc
475     {
476         int holdability =
477             ((EngineStatement) getStatement()).getResultSetHoldability();
478         
479         // Holdability might be downgraded.
480
return controlCheck().checkHoldCursors(holdability);
481     }
482
483     /*
484     ** Control methods
485     */

486
487     public Statement JavaDoc createDuplicateStatement(Connection JavaDoc conn, Statement JavaDoc oldStatement) throws SQLException JavaDoc {
488
489         Statement JavaDoc newStatement;
490         
491         if (jdbcLevel == 2)
492             newStatement = conn.createStatement(resultSetType, resultSetConcurrency);
493         else
494             newStatement = conn.createStatement(resultSetType, resultSetConcurrency,
495                     resultSetHoldability);
496
497         setStatementState(oldStatement, newStatement);
498
499         return newStatement;
500     }
501
502     void setStatementState(Statement JavaDoc oldStatement, Statement JavaDoc newStatement) throws SQLException JavaDoc {
503         if (cursorName != null)
504             newStatement.setCursorName(cursorName);
505         if (escapeProcessing != null)
506             newStatement.setEscapeProcessing(escapeProcessing.booleanValue());
507
508         newStatement.setFetchDirection(oldStatement.getFetchDirection());
509         newStatement.setFetchSize(oldStatement.getFetchSize());
510         newStatement.setMaxFieldSize(oldStatement.getMaxFieldSize());
511         newStatement.setMaxRows(oldStatement.getMaxRows());
512         newStatement.setQueryTimeout(oldStatement.getQueryTimeout());
513     }
514
515     public Statement JavaDoc getStatement() throws SQLException JavaDoc {
516         return control.getRealStatement();
517     }
518     
519     /**
520      * Provide the control access to every ResultSet we return.
521      * If required the control can wrap the ResultSet, but
522      * it (the control) must ensure a underlying ResultSet is
523      * only wrapped once, if say java.sql.Statement.getResultSet
524      * is returned twice.
525      *
526      * @param rs ResultSet being returned, can be null.
527      */

528     final ResultSet JavaDoc wrapResultSet(ResultSet JavaDoc rs) {
529         return control.wrapResultSet(this, rs);
530     }
531
532     /**
533         Get the BrokeredStatementControl in order to perform a check.
534         Obtained indirectly to ensure that the correct exception is
535         thrown if the Statement has been closed.
536     */

537     final BrokeredStatementControl controlCheck() throws SQLException JavaDoc
538     {
539         // simplest method that will throw an exception if the Statement is closed
540
getStatement().getConnection();
541         return control;
542     }
543
544     /**
545      * Returns false unless <code>iface</code> is implemented
546      *
547      * @param iface a Class defining an interface.
548      * @return true if this implements the interface or
549      * directly or indirectly wraps an object
550      * that does.
551      * @throws java.sql.SQLException if an error occurs while determining
552      * whether this is a wrapper for an object
553      * with the given interface.
554      */

555     public boolean isWrapperFor(Class JavaDoc iface) throws SQLException JavaDoc {
556         checkIfClosed();
557         return iface.isInstance(this);
558     }
559
560     /**
561      * Checks if the statement is closed. Not implemented for this
562      * class since <code>isClosed()</code> is a new method in JDBC
563      * 4.0. The JDBC 4.0 sub-classes should override this method.
564      *
565      * @return <code>true</code> if the statement is closed,
566      * <code>false</code> otherwise
567      * @exception SQLException not-implemented exception
568      */

569     protected boolean isClosed() throws SQLException JavaDoc {
570         // Not implemented since we cannot forward the call to a JDBC
571
// 4.0 method from this class. This dummy implementation is
572
// provided here so that checkIfClosed() can be implemented
573
// once in this class instead of once in each of the
574
// Brokered*Statement40 classes.
575
throw Util.notImplemented();
576     }
577
578     /**
579      * Checks if the statement is closed and throws an exception if it
580      * is. This method relies on the <code>isClosed()</code> method
581      * and therefore only works with JDBC 4.0.
582      *
583      * @exception SQLException if the statement is closed
584      */

585     protected final void checkIfClosed()
586         throws SQLException JavaDoc
587     {
588         if (isClosed()) {
589             throw Util.generateCsSQLException(SQLState.ALREADY_CLOSED,
590                                               "Statement");
591         }
592     }
593 }
594
Popular Tags