KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > mmbase > module > database > MultiStatement


1 /*
2
3 This software is OSI Certified Open Source Software.
4 OSI Certified is a certification mark of the Open Source Initiative.
5
6 The license (Mozilla version 1.0) can be read at the MMBase site.
7 See http://www.MMBase.org/license
8
9 */

10 package org.mmbase.module.database;
11
12 import java.sql.*;
13 import org.mmbase.util.logging.Logger;
14 import org.mmbase.util.logging.Logging;
15
16 /**
17  * MultiStatement is a wrapper class for a callable Statement
18  * obtained by a MultiConnection object.
19  * The sole function of this class is to log the sql statement passed to it
20  * using the MultiConnection that called it - all calls are then passed to
21  * the Statement object passed to the constructor.
22  *
23  * @sql It would possibly be better to pass the logging of the sql query
24  * to the code that calls the statement, rather than place it in
25  * the statement itself, as it's implementation leads to conflicts
26  * between various JDBC versions.
27  *
28  * @author vpro
29  * @author Pierre van Rooden
30  * @version $Id: MultiStatement.java,v 1.18 2005/07/15 10:53:22 michiel Exp $
31  */

32 public class MultiStatement implements Statement {
33     private static final Logger log = Logging.getLoggerInstance(MultiStatement.class);
34
35     /**
36      * The connection that created this statement.
37      */

38     MultiConnection parent;
39     /**
40      * The actual statement (created by the database driver)
41      */

42     private Statement s;
43
44     /**
45      * @javadoc
46      */

47     MultiStatement(MultiConnection parent,Statement s) {
48       this.parent = parent;
49       this.s=s;
50     }
51
52     /**
53      * @javadoc
54      */

55     public int executeUpdate(String JavaDoc sql) throws SQLException {
56         parent.setLastSQL(sql);
57         return s.executeUpdate(sql);
58     }
59
60     /**
61      * @javadoc
62      */

63     public void close() throws SQLException {
64         s.close();
65         s = null; // lets asign it to null to be sure
66
}
67
68     /**
69      * @javadoc
70      */

71     public int getMaxFieldSize() throws SQLException {
72         return s.getMaxFieldSize();
73     }
74
75     /**
76      * @javadoc
77      */

78     public void setMaxFieldSize(int max) throws SQLException {
79         s.setMaxFieldSize(max);
80     }
81
82     /**
83      * @javadoc
84      */

85     public int getMaxRows() throws SQLException {
86         return s.getMaxRows();
87     }
88
89     /**
90      * @javadoc
91      */

92     public void setMaxRows(int max) throws SQLException {
93         s.setMaxRows(max);
94     }
95
96     /**
97      * @javadoc
98      */

99     public void setEscapeProcessing(boolean enable) throws SQLException {
100         s.setEscapeProcessing(enable);
101     }
102
103     /**
104      * @javadoc
105      */

106     public int getQueryTimeout() throws SQLException {
107         return s.getQueryTimeout();
108     }
109
110     /**
111      * @javadoc
112      */

113     public void setQueryTimeout(int seconds) throws SQLException {
114         s.setQueryTimeout(seconds);
115     }
116
117     /**
118      * @javadoc
119      */

120     public void cancel() throws SQLException {
121         s.cancel();
122     }
123
124     /**
125      * @javadoc
126      */

127     public SQLWarning getWarnings() throws SQLException {
128         return s.getWarnings();
129     }
130
131     /**
132      * @javadoc
133      */

134     public void clearWarnings() throws SQLException {
135         s.clearWarnings();
136     }
137
138     /**
139      * @javadoc
140      */

141     public boolean execute(String JavaDoc sql) throws SQLException {
142         parent.setLastSQL(sql);
143         return s.execute(sql);
144     }
145
146     /**
147      * @javadoc
148      */

149     public ResultSet getResultSet() throws SQLException {
150         return s.getResultSet();
151     }
152
153     /**
154      * @javadoc
155      */

156     public int getUpdateCount() throws SQLException {
157         return s.getUpdateCount();
158     }
159
160     /**
161      * @javadoc
162      */

163     public boolean getMoreResults() throws SQLException {
164         return s.getMoreResults();
165     }
166
167     /**
168      * @javadoc
169      */

170     public void setCursorName(String JavaDoc name) throws SQLException {
171         s.setCursorName(name);
172     }
173
174
175     /**
176      * Tries to fix the parent connection, if it proves to be broken. It is supposed to be broken if
177      * the query "SELECT 1 FROM <OBJECT TABLE> WHERE 1 = 0" does yield an exception.
178      * This method is meant to be called in the catch after trying to exceute a statement.
179      *
180      * @return A new Statement object if a new Connection was successfully obtained. Or null, if 'SELECT 1' did succeed.
181      * @throws SQLException if SELECT 1 did fail an no new Connection could be obtained.
182      * @since MMBase-1.7.1
183      */

184     protected Statement checkAfterException() throws SQLException {
185         if (! org.mmbase.module.core.MMBase.getMMBase().getBuilder("object").created()) {
186             // if this table does not exist, this is impossible
187
return s;
188         }
189         ResultSet rs = null;
190         // check wether connection is still functional
191
try {
192             rs = s.executeQuery("SELECT 1 FROM " + org.mmbase.module.core.MMBase.getMMBase().getBuilder("object").getFullTableName() + " WHERE 1 = 0"); // if this goes wrong too it can't be the query);
193
} catch (SQLException isqe) {
194              // so, connection must be broken.
195
log.service("Found broken connection, will try to fix it.");
196             s.close();
197             parent.parent.replaceConnection(parent);
198             s = parent.createStatement();
199             // this would be more correct:
200
//s = parent.createStatement(s.getResultSetType(), s.getResultSetConcurrency(), s.getResultSetHoldability());
201
// but I have a psql driver:
202
// org.postgresql.util.PSQLException: This method is not yet implemented.
203
// at org.postgresql.Driver.notImplemented(Driver.java:388)
204
// at org.postgresql.jdbc3.AbstractJdbc3Statement.getResultSetHoldability(AbstractJdbc3Statement.java:278)
205
// It does not matter much because in all of MMBase only 'createStatement()' is used.
206
return s;
207         } finally {
208             if (rs != null) {
209                 rs.close();
210             }
211         }
212         
213         return null;
214     }
215
216     /**
217      * @javadoc
218      */

219     public ResultSet executeQuery(String JavaDoc sql) throws SQLException {
220         try {
221             parent.setLastSQL(sql);
222             return s.executeQuery(sql);
223         } catch (SQLException sqe) {
224             Statement ts = checkAfterException();
225             if (ts != null) { // there was something wrong with the connection, try it once again
226
return ts.executeQuery(sql);
227             } else {
228                 throw sqe;
229             }
230
231         }
232     }
233
234     /**
235      * @javadoc
236      */

237     public int[] executeBatch() throws SQLException {
238         return s.executeBatch();
239     }
240
241     /**
242      * @javadoc
243      */

244     public void setFetchDirection(int dir) throws SQLException {
245         s.setFetchDirection(dir);
246     }
247
248     /**
249      * @javadoc
250      */

251     public int getFetchDirection() throws SQLException {
252         return s.getFetchDirection();
253     }
254
255     /**
256      * @javadoc
257      */

258     public int getResultSetConcurrency() throws SQLException {
259         return s.getResultSetConcurrency();
260     }
261
262     /**
263      * @javadoc
264      */

265     public int getResultSetType() throws SQLException {
266         return s.getResultSetType();
267     }
268
269     /**
270      * @javadoc
271      */

272     public void addBatch(String JavaDoc sql) throws SQLException {
273         s.addBatch(sql);
274     }
275
276     /**
277      * @javadoc
278      */

279     public void clearBatch() throws SQLException {
280         s.clearBatch();
281     }
282
283     /**
284      * @javadoc
285      */

286     public Connection getConnection() throws SQLException {
287         return s.getConnection();
288     }
289
290     /**
291      * @javadoc
292      */

293     public int getFetchSize() throws SQLException {
294         return s.getFetchSize();
295     }
296
297     /**
298      * @javadoc
299      */

300     public void setFetchSize(int i) throws SQLException {
301         s.setFetchSize(i);
302     }
303
304     /**
305      * Moves to this Statement object's next result, deals with any current ResultSet object(s) according to
306      * the instructions specified by the given flag, and returns true if the next result is a ResultSet object.
307      * @param current one of CLOSE_CURRENT_RESULT, KEEP_CURRENT_RESULT, or CLOSE_ALL_RESULTS
308      * @return true if the next result is a ResultSet object; false if it is an update count or there are no more results
309      * @since MMBase 1.5, JDBC 1.4
310      */

311     public boolean getMoreResults(int current) throws SQLException {
312         return s.getMoreResults(current);
313     }
314
315     /**
316      * Retrieves any auto-generated keys created as a result of executing this Statement object.
317      * @return a ResultSet object containing the auto-generated key(s) generated by the execution of this Statement object
318      * @since MMBase 1.5, JDBC 1.4
319      */

320     public ResultSet getGeneratedKeys() throws SQLException {
321         return s.getGeneratedKeys();
322     }
323
324     /**
325      * Executes the given SQL statement and signals the driver with the given flag about whether the
326      * auto-generated keys produced by this Statement object should be made available for retrieval.
327      * @param sql must be an SQL INSERT, UPDATE or DELETE statement or an SQL statement that returns nothing
328      * @param autoGeneratedKeys a flag indicating whether auto-generated keys should be made available for retrieval
329      * @return either the row count for INSERT, UPDATE or DELETE statements, or 0 for SQL statements that return nothing
330      * @since MMBase 1.5, JDBC 1.4
331      */

332     public int executeUpdate(String JavaDoc sql, int autoGeneratedKeys) throws SQLException {
333         try {
334             parent.setLastSQL(sql);
335             return s.executeUpdate(sql, autoGeneratedKeys);
336         } catch (SQLException sqe) {
337             Statement ts = checkAfterException();
338             if (ts != null) { // there was something wrong with the connection, try it once again
339
return ts.executeUpdate(sql, autoGeneratedKeys);
340             } else {
341                 throw sqe;
342             }
343         }
344     }
345
346     /**
347      * Executes the given SQL statement and signals the driver that the auto-generated keys indicated in
348      * the given array should be made available for retrieval.
349      * @param sql must be an SQL INSERT, UPDATE or DELETE statement or an SQL statement that returns nothing
350      * @param columnIndexes an array of column indexes indicating the columns that should be returned from the inserted row
351      * @return either the row count for INSERT, UPDATE or DELETE statements, or 0 for SQL statements that return nothing
352      * @since MMBase 1.5, JDBC 1.4
353      */

354     public int executeUpdate(String JavaDoc sql, int[] columnIndexes) throws SQLException {
355         try {
356             parent.setLastSQL(sql);
357             return s.executeUpdate(sql, columnIndexes);
358         } catch (SQLException sqe) {
359             Statement ts = checkAfterException();
360             if (ts != null) { // there was something wrong with the connection, try it once again
361
return ts.executeUpdate(sql, columnIndexes);
362             } else {
363                 throw sqe;
364             }
365
366         }
367     }
368
369     /**
370      * Executes the given SQL statement and signals the driver that the auto-generated keys indicated in the given array
371      * should be made available for retrieval.
372      * @param sql must be an SQL INSERT, UPDATE or DELETE statement or an SQL statement that returns nothing
373      * @param columnNames - an array of the names of the columns that should be returned from the inserted row
374      * @return either the row count for INSERT, UPDATE or DELETE statements, or 0 for SQL statements that return nothing
375      * @since MMBase 1.5, JDBC 1.4
376      */

377     public int executeUpdate(String JavaDoc sql, String JavaDoc[] columnNames) throws SQLException {
378         try {
379             parent.setLastSQL(sql);
380             return s.executeUpdate(sql, columnNames);
381         } catch (SQLException sqe) {
382             Statement ts = checkAfterException();
383             if (ts != null) { // there was something wrong with the connection, try it once again
384
return ts.executeUpdate(sql, columnNames);
385             } else {
386                 throw sqe;
387             }
388
389         }
390     }
391
392     /**
393      * Executes the given SQL statement, which may return multiple results, and signals the driver that
394      * any auto-generated keys should be made available for retrieval.
395      * @param sql any SQL statement
396      * @param autoGeneratedKeys a flag indicating whether auto-generated keys should be made available for retrieval
397      * @return true if the first result is a ResultSet object; false if it is an update count or there are no results
398      * @since MMBase 1.5, JDBC 1.4
399      */

400     public boolean execute(String JavaDoc sql, int autoGeneratedKeys) throws SQLException {
401         try {
402             parent.setLastSQL(sql);
403             return s.execute(sql, autoGeneratedKeys);
404         } catch (SQLException sqe) {
405             Statement ts = checkAfterException();
406             if (ts != null) { // there was something wrong with the connection, try it once again
407
return ts.execute(sql, autoGeneratedKeys);
408             } else {
409                 throw sqe;
410             }
411         }
412     }
413
414     /**
415      * Executes the given SQL statement, which may return multiple results, and signals the driver that
416      * the auto-generated keys indicated in the given array should be made available for retrieval.
417      * @param sql any SQL statement
418      * @param columnIndexes an array of column indexes indicating the columns that should be returned from the inserted row
419      * @return true if the first result is a ResultSet object; false if it is an update count or there are no results
420      * @since MMBase 1.5, JDBC 1.4
421      */

422     public boolean execute(String JavaDoc sql, int[] columnIndexes) throws SQLException {
423         try {
424             parent.setLastSQL(sql);
425             return s.execute(sql, columnIndexes);
426         } catch (SQLException sqe) {
427             Statement ts = checkAfterException();
428             if (ts != null) { // there was something wrong with the connection, try it once again
429
return ts.execute(sql, columnIndexes);
430             } else {
431                 throw sqe;
432             }
433         }
434     }
435
436     /**
437      * Executes the given SQL statement, which may return multiple results, and signals the driver that
438      * the auto-generated keys indicated in the given array should be made available for retrieval.
439      * @param sql any SQL statement
440      * @param columnNames - an array of the names of the columns that should be returned from the inserted row
441      * @return true if the first result is a ResultSet object; false if it is an update count or there are no results
442      * @since MMBase 1.5, JDBC 1.4
443      */

444     public boolean execute(String JavaDoc sql, String JavaDoc[] columnNames) throws SQLException {
445         try {
446             parent.setLastSQL(sql);
447             return s.execute(sql, columnNames);
448         } catch (SQLException sqe) {
449             Statement ts = checkAfterException();
450             if (ts != null) { // there was something wrong with the connection, try it once again
451
return ts.execute(sql, columnNames);
452             } else {
453                 throw sqe;
454             }
455         }
456     }
457
458     /**
459      * Retrieves the result set holdability for ResultSet objects generated by this Statement object.
460      * @return either ResultSet.HOLD_CURSORS_OVER_COMMIT or ResultSet.CLOSE_CURSORS_AT_COMMIT
461      * @since MMBase 1.5, JDBC 1.4
462      */

463     public int getResultSetHoldability() throws SQLException {
464         return s.getResultSetHoldability();
465     }
466
467 }
468
469
Popular Tags