View Javadoc

1   /**
2    * This file is part of GoldenGate Project (named also GoldenGate or GG).
3    * 
4    * Copyright 2009, Frederic Bregier, and individual contributors by the @author
5    * tags. See the COPYRIGHT.txt in the distribution for a full listing of
6    * individual contributors.
7    * 
8    * All GoldenGate Project is free software: you can redistribute it and/or
9    * modify it under the terms of the GNU General Public License as published by
10   * the Free Software Foundation, either version 3 of the License, or (at your
11   * option) any later version.
12   * 
13   * GoldenGate is distributed in the hope that it will be useful, but WITHOUT ANY
14   * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
15   * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
16   * 
17   * You should have received a copy of the GNU General Public License along with
18   * GoldenGate . If not, see <http://www.gnu.org/licenses/>.
19   */
20  package goldengate.common.database;
21  
22  import goldengate.common.logging.GgInternalLogger;
23  import goldengate.common.logging.GgInternalLoggerFactory;
24  
25  import java.sql.PreparedStatement;
26  import java.sql.ResultSet;
27  import java.sql.SQLException;
28  
29  import goldengate.common.database.exception.GoldenGateDatabaseNoConnectionException;
30  import goldengate.common.database.exception.GoldenGateDatabaseSqlException;
31  
32  /**
33   * Class to handle PrepareStatement
34   * 
35   * @author Frederic Bregier
36   * 
37   */
38  public class DbPreparedStatement {
39      /**
40       * Internal Logger
41       */
42      private static final GgInternalLogger logger = GgInternalLoggerFactory
43              .getLogger(DbPreparedStatement.class);
44  
45      /**
46       * Internal PreparedStatement
47       */
48      private PreparedStatement preparedStatement = null;
49  
50      /**
51       * The Associated request
52       */
53      private String request = null;
54  
55      /**
56       * Is this PreparedStatement ready
57       */
58      public boolean isReady = false;
59  
60      /**
61       * The associated resultSet
62       */
63      private ResultSet rs = null;
64  
65      /**
66       * The associated DB session
67       */
68      private final DbSession ls;
69  
70      /**
71       * Create a DbPreparedStatement from DbSession object
72       * 
73       * @param ls
74       * @throws GoldenGateDatabaseNoConnectionException
75       */
76      public DbPreparedStatement(DbSession ls)
77              throws GoldenGateDatabaseNoConnectionException {
78          if (ls == null) {
79              logger.error("SQL Exception PreparedStatement no session");
80              throw new GoldenGateDatabaseNoConnectionException(
81                      "PreparedStatement no session");
82          }
83          if (ls.isDisconnected) {
84              ls.checkConnection();
85          }
86          this.ls = ls;
87          rs = null;
88          preparedStatement = null;
89          isReady = false;
90      }
91  
92      /**
93       * Create a DbPreparedStatement from DbSession object and a request
94       * 
95       * @param ls
96       * @param request
97       * @throws GoldenGateDatabaseNoConnectionException
98       * @throws GoldenGateDatabaseSqlException
99       */
100     public DbPreparedStatement(DbSession ls, String request)
101             throws GoldenGateDatabaseNoConnectionException,
102             GoldenGateDatabaseSqlException {
103         if (ls == null) {
104             logger.error("SQL Exception PreparedStatement no session");
105             throw new GoldenGateDatabaseNoConnectionException(
106                     "PreparedStatement no session");
107         }
108         if (ls.isDisconnected) {
109             ls.checkConnection();
110         }
111         this.ls = ls;
112         rs = null;
113         isReady = false;
114         preparedStatement = null;
115         if (request == null) {
116             logger.error("SQL Exception PreparedStatement no request");
117             throw new GoldenGateDatabaseNoConnectionException(
118                     "PreparedStatement no request");
119         }
120         try {
121             preparedStatement = this.ls.conn.prepareStatement(request);
122             this.request = request;
123             isReady = true;
124         } catch (SQLException e) {
125             ls.checkConnection();
126             try {
127                 preparedStatement = this.ls.conn.prepareStatement(request);
128                 this.request = request;
129                 isReady = true;
130             } catch (SQLException e1) {
131                 logger.error("SQL Exception PreparedStatement: " + request +
132                         "\n" + e.getMessage());
133                 DbSession.error(e);
134                 preparedStatement = null;
135                 isReady = false;
136                 throw new GoldenGateDatabaseSqlException(
137                         "SQL Exception PreparedStatement", e);
138             }
139         }
140     }
141 
142     /**
143      * Create a DbPreparedStatement from DbSession object and a request
144      * 
145      * @param ls
146      * @param request
147      * @param nbFetch
148      *            the number of pre fetch rows
149      * @throws GoldenGateDatabaseNoConnectionException
150      * @throws GoldenGateDatabaseSqlException
151      */
152     public DbPreparedStatement(DbSession ls, String request, int nbFetch)
153             throws GoldenGateDatabaseNoConnectionException,
154             GoldenGateDatabaseSqlException {
155         if (ls == null) {
156             logger.error("SQL Exception PreparedStatement no session");
157             throw new GoldenGateDatabaseNoConnectionException(
158                     "PreparedStatement no session");
159         }
160         if (ls.isDisconnected) {
161             ls.checkConnection();
162         }
163         this.ls = ls;
164         rs = null;
165         isReady = false;
166         preparedStatement = null;
167         if (request == null) {
168             logger.error("SQL Exception PreparedStatement no request");
169             throw new GoldenGateDatabaseNoConnectionException(
170                     "PreparedStatement no request");
171         }
172         try {
173             preparedStatement = this.ls.conn.prepareStatement(request);
174             this.request = request;
175             this.preparedStatement.setFetchSize(nbFetch);
176             isReady = true;
177         } catch (SQLException e) {
178             ls.checkConnection();
179             try {
180                 preparedStatement = this.ls.conn.prepareStatement(request);
181                 this.request = request;
182                 this.preparedStatement.setFetchSize(nbFetch);
183                 isReady = true;
184             } catch (SQLException e1) {
185                 logger.error("SQL Exception PreparedStatement: " + request +
186                         "\n" + e.getMessage());
187                 DbSession.error(e);
188                 preparedStatement = null;
189                 isReady = false;
190                 throw new GoldenGateDatabaseSqlException(
191                         "SQL Exception PreparedStatement", e);
192             }
193         }
194     }
195 
196     /**
197      * Create a preparedStatement from request
198      * 
199      * @param requestarg
200      * @throws GoldenGateDatabaseNoConnectionException
201      * @throws GoldenGateDatabaseSqlException
202      */
203     public void createPrepareStatement(String requestarg)
204             throws GoldenGateDatabaseNoConnectionException,
205             GoldenGateDatabaseSqlException {
206         if (requestarg == null) {
207             logger.error("createPreparedStatement no request");
208             throw new GoldenGateDatabaseNoConnectionException(
209                     "PreparedStatement no request");
210         }
211         if (preparedStatement != null) {
212             realClose();
213         }
214         if (rs != null) {
215             close();
216         }
217         if (ls.isDisconnected) {
218             ls.checkConnection();
219         }
220         try {
221             preparedStatement = ls.conn.prepareStatement(requestarg);
222             request = requestarg;
223             isReady = true;
224         } catch (SQLException e) {
225             ls.checkConnection();
226             try {
227                 preparedStatement = ls.conn.prepareStatement(requestarg);
228                 request = requestarg;
229                 isReady = true;
230             } catch (SQLException e1) {
231                 logger.error("SQL Exception createPreparedStatement:" +
232                         requestarg + "\n" + e.getMessage());
233                 DbSession.error(e);
234                 realClose();
235                 preparedStatement = null;
236                 isReady = false;
237                 throw new GoldenGateDatabaseSqlException(
238                         "SQL Exception createPreparedStatement: " + requestarg,
239                         e);
240             }
241         }
242     }
243 
244     /**
245      * In case of closing database connection, it is possible to reopen a long
246      * term preparedStatement as it was at creation.
247      * 
248      * @throws GoldenGateDatabaseSqlException
249      * @throws GoldenGateDatabaseNoConnectionException
250      */
251     public void recreatePreparedStatement()
252             throws GoldenGateDatabaseNoConnectionException,
253             GoldenGateDatabaseSqlException {
254         this.createPrepareStatement(request);
255     }
256 
257     /**
258      * Execute a Select preparedStatement
259      * 
260      * @throws GoldenGateDatabaseNoConnectionException
261      * @throws GoldenGateDatabaseSqlException
262      * 
263      */
264     public void executeQuery() throws GoldenGateDatabaseNoConnectionException,
265             GoldenGateDatabaseSqlException {
266         if (preparedStatement == null) {
267             logger.error("executeQuery no request");
268             throw new GoldenGateDatabaseNoConnectionException(
269                     "executeQuery no request");
270         }
271         if (rs != null) {
272             close();
273         }
274         if (ls.isDisconnected) {
275             ls.checkConnection();
276             throw new GoldenGateDatabaseSqlException(
277                     "Request cannot be executed since connection was recreated between: " +
278                             request);
279         }
280         try {
281             rs = preparedStatement.executeQuery();
282         } catch (SQLException e) {
283             logger.error("SQL Exception executeQuery:" + request + "\n" +
284                     e.getMessage());
285             DbSession.error(e);
286             close();
287             rs = null;
288             ls.checkConnectionNoException();
289             throw new GoldenGateDatabaseSqlException(
290                     "SQL Exception executeQuery: " + request, e);
291         }
292     }
293 
294     /**
295      * Execute the Update/Insert/Delete preparedStatement
296      * 
297      * @return the number of row
298      * @throws GoldenGateDatabaseNoConnectionException
299      * @throws GoldenGateDatabaseSqlException
300      */
301     public int executeUpdate() throws GoldenGateDatabaseNoConnectionException,
302             GoldenGateDatabaseSqlException {
303         if (preparedStatement == null) {
304             logger.error("executeUpdate no request");
305             throw new GoldenGateDatabaseNoConnectionException(
306                     "executeUpdate no request");
307         }
308         if (rs != null) {
309             close();
310         }
311         if (ls.isDisconnected) {
312             ls.checkConnection();
313             throw new GoldenGateDatabaseSqlException(
314                     "Request cannot be executed since connection was recreated between:" +
315                             request);
316         }
317         int retour = -1;
318         try {
319             retour = preparedStatement.executeUpdate();
320         } catch (SQLException e) {
321             logger.error("SQL Exception executeUpdate:" + request + "\n" +
322                     e.getMessage());
323             DbSession.error(e);
324             ls.checkConnectionNoException();
325             throw new GoldenGateDatabaseSqlException(
326                     "SQL Exception executeUpdate: " + request, e);
327         }
328         return retour;
329     }
330 
331     /**
332      * Close the resultSet if any
333      * 
334      */
335     public void close() {
336         if (rs != null) {
337             try {
338                 rs.close();
339             } catch (SQLException e) {
340             }
341             rs = null;
342         }
343     }
344 
345     /**
346      * Really close the preparedStatement and the resultSet if any
347      * 
348      */
349     public void realClose() {
350         close();
351         if (preparedStatement != null) {
352             if (ls.isDisconnected) {
353                 ls.checkConnectionNoException();
354             }
355             try {
356                 preparedStatement.close();
357             } catch (SQLException e) {
358                 ls.checkConnectionNoException();
359             }
360             preparedStatement = null;
361         }
362         isReady = false;
363     }
364 
365     /**
366      * Move the cursor to the next result
367      * 
368      * @return True if there is a next result, else False
369      * @throws GoldenGateDatabaseNoConnectionException
370      * @throws GoldenGateDatabaseSqlException
371      */
372     public boolean getNext() throws GoldenGateDatabaseNoConnectionException,
373             GoldenGateDatabaseSqlException {
374         if (rs == null) {
375             logger.error("SQL ResultSet is Null into getNext");
376             throw new GoldenGateDatabaseNoConnectionException(
377                     "SQL ResultSet is Null into getNext");
378         }
379         if (ls.isDisconnected) {
380             ls.checkConnection();
381             throw new GoldenGateDatabaseSqlException(
382                     "Request cannot be executed since connection was recreated between");
383         }
384         try {
385             return rs.next();
386         } catch (SQLException e) {
387             logger.error("SQL Exception to getNextRow" + "\n" + e.getMessage());
388             DbSession.error(e);
389             ls.checkConnectionNoException();
390             throw new GoldenGateDatabaseSqlException(
391                     "SQL Exception to getNextRow: " + request, e);
392         }
393     }
394 
395     /**
396      * 
397      * @return The resultSet (can be used in conjunction of getNext())
398      * @throws GoldenGateDatabaseNoConnectionException
399      */
400     public ResultSet getResultSet() throws GoldenGateDatabaseNoConnectionException {
401         if (rs == null) {
402             throw new GoldenGateDatabaseNoConnectionException(
403                     "SQL ResultSet is Null into getResultSet");
404         }
405         return rs;
406     }
407 
408     /**
409      * 
410      * @return The preparedStatement (should be used in conjunction of
411      *         createPreparedStatement)
412      * @throws GoldenGateDatabaseNoConnectionException
413      */
414     public PreparedStatement getPreparedStatement()
415             throws GoldenGateDatabaseNoConnectionException {
416         if (preparedStatement == null) {
417             throw new GoldenGateDatabaseNoConnectionException(
418                     "SQL PreparedStatement is Null into getPreparedStatement");
419         }
420         return preparedStatement;
421     }
422 
423     /**
424      * @return the dbSession
425      */
426     public DbSession getDbSession() {
427         return ls;
428     }
429 
430 }