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.ResultSet;
26  import java.sql.SQLException;
27  import java.sql.Statement;
28  
29  import goldengate.common.database.exception.GoldenGateDatabaseNoConnectionException;
30  import goldengate.common.database.exception.GoldenGateDatabaseNoDataException;
31  import goldengate.common.database.exception.GoldenGateDatabaseSqlException;
32  
33  /**
34   * Class to handle request
35   * 
36   * @author Frederic Bregier
37   * 
38   */
39  public class DbRequest {
40      /**
41       * Internal Logger
42       */
43      private static final GgInternalLogger logger = GgInternalLoggerFactory
44              .getLogger(DbRequest.class);
45  
46      /**
47       * Internal Statement
48       */
49      private Statement stmt = null;
50  
51      /**
52       * Internal Result Set
53       */
54      private ResultSet rs = null;
55  
56      /**
57       * Internal DB Session
58       */
59      private final DbSession ls;
60  
61      /**
62       * Create a new request from the DbSession
63       * 
64       * @param ls
65       * @throws GoldenGateDatabaseNoConnectionException
66       */
67      public DbRequest(DbSession ls) throws GoldenGateDatabaseNoConnectionException {
68          if (ls.isDisconnected) {
69              ls.checkConnection();
70          }
71          this.ls = ls;
72      }
73  
74      /**
75       * Create a statement with some particular options
76       * 
77       * @return the new Statement
78       * @throws GoldenGateDatabaseNoConnectionException
79       * @throws GoldenGateDatabaseSqlException
80       */
81      private Statement createStatement()
82              throws GoldenGateDatabaseNoConnectionException,
83              GoldenGateDatabaseSqlException {
84          if (ls == null) {
85              throw new GoldenGateDatabaseNoConnectionException("No connection");
86          }
87          if (ls.conn == null) {
88              throw new GoldenGateDatabaseNoConnectionException("No connection");
89          }
90          if (ls.isDisconnected) {
91              ls.checkConnection();
92          }
93          try {
94              return ls.conn.createStatement();
95          } catch (SQLException e) {
96              ls.checkConnection();
97              try {
98                  return ls.conn.createStatement();
99              } catch (SQLException e1) {
100                 throw new GoldenGateDatabaseSqlException(
101                         "Error while Create Statement", e);
102             }
103         }
104     }
105 
106     /**
107      * Execute a SELECT statement and set of Result. The statement must not be
108      * an update/insert/delete. The previous statement and resultSet are closed.
109      * 
110      * @param select
111      * @throws GoldenGateDatabaseSqlException
112      * @throws GoldenGateDatabaseNoConnectionException
113      */
114     public void select(String select)
115             throws GoldenGateDatabaseNoConnectionException,
116             GoldenGateDatabaseSqlException {
117         close();
118         stmt = createStatement();
119         // rs = stmt.executeQuery(select);
120         // or alternatively, if you don't know ahead of time that
121         // the query will be a SELECT...
122         try {
123             if (stmt.execute(select)) {
124                 rs = stmt.getResultSet();
125             }
126         } catch (SQLException e) {
127             logger.error("SQL Exception Request:" + select + "\n" +
128                     e.getMessage());
129             DbSession.error(e);
130             ls.checkConnectionNoException();
131             throw new GoldenGateDatabaseSqlException("SQL Exception Request:" +
132                     select, e);
133         }
134     }
135 
136     /**
137      * Execute a UPDATE/INSERT/DELETE statement and returns the number of row.
138      * The previous statement and resultSet are closed.
139      * 
140      * @param query
141      * @return the number of row in the query
142      * @throws GoldenGateDatabaseSqlException
143      * @throws GoldenGateDatabaseNoConnectionException
144      */
145     public int query(String query) throws GoldenGateDatabaseNoConnectionException,
146             GoldenGateDatabaseSqlException {
147         close();
148         stmt = createStatement();
149         try {
150             int rowcount = stmt.executeUpdate(query);
151             logger.debug("QUERY(" + rowcount + "): {}", query);
152             return rowcount;
153         } catch (SQLException e) {
154             logger.error("SQL Exception Request:" + query + "\n" +
155                     e.getMessage());
156             DbSession.error(e);
157             ls.checkConnectionNoException();
158             throw new GoldenGateDatabaseSqlException("SQL Exception Request:" +
159                     query, e);
160         }
161     }
162 
163     /**
164      * Finished a Request (ready for a new one)
165      */
166     public void close() {
167         // it is a good idea to release
168         // resources in a finally{} block
169         // in reverse-order of their creation
170         // if they are no-longer needed
171         if (rs != null) {
172             try {
173                 rs.close();
174             } catch (SQLException sqlEx) {
175                 ls.checkConnectionNoException();
176             } // ignore
177             rs = null;
178         }
179         if (stmt != null) {
180             try {
181                 stmt.close();
182             } catch (SQLException sqlEx) {
183                 ls.checkConnectionNoException();
184             } // ignore
185             stmt = null;
186         }
187     }
188 
189     /**
190      * Get the last ID autoincrement from the last request
191      * 
192      * @return the long Id or DbConstant.ILLEGALVALUE (Long.MIN_VALUE) if an
193      *         error occurs.
194      * @throws GoldenGateDatabaseNoDataException
195      */
196     public long getLastId() throws GoldenGateDatabaseNoDataException {
197         ResultSet rstmp;
198         long result = DbConstant.ILLEGALVALUE;
199         try {
200             rstmp = stmt.getGeneratedKeys();
201             if (rstmp.next()) {
202                 result = rstmp.getLong(1);
203             }
204             rstmp.close();
205             rstmp = null;
206         } catch (SQLException e) {
207             DbSession.error(e);
208             ls.checkConnectionNoException();
209             throw new GoldenGateDatabaseNoDataException("No data found", e);
210         }
211         return result;
212     }
213 
214     /**
215      * Move the cursor to the next result
216      * 
217      * @return True if there is a next result, else False
218      * @throws GoldenGateDatabaseNoConnectionException
219      * @throws GoldenGateDatabaseSqlException
220      */
221     public boolean getNext() throws GoldenGateDatabaseNoConnectionException,
222             GoldenGateDatabaseSqlException {
223         if (rs == null) {
224             logger.error("SQL ResultSet is Null into getNext");
225             throw new GoldenGateDatabaseNoConnectionException(
226                     "SQL ResultSet is Null into getNext");
227         }
228         if (ls.isDisconnected) {
229             ls.checkConnection();
230             throw new GoldenGateDatabaseSqlException(
231                     "Request cannot be executed since connection was recreated between");
232         }
233         try {
234             return rs.next();
235         } catch (SQLException e) {
236             logger.warn("SQL Exception to getNextRow" + "\n" + e.getMessage());
237             DbSession.error(e);
238             ls.checkConnectionNoException();
239             throw new GoldenGateDatabaseSqlException("SQL Exception to getNextRow",
240                     e);
241         }
242     }
243 
244     /**
245      * 
246      * @return The resultSet (can be used in conjunction of getNext())
247      * @throws GoldenGateDatabaseNoConnectionException
248      */
249     public ResultSet getResultSet() throws GoldenGateDatabaseNoConnectionException {
250         if (rs == null) {
251             throw new GoldenGateDatabaseNoConnectionException(
252                     "SQL ResultSet is Null into getResultSet");
253         }
254         return rs;
255     }
256 
257     /**
258      * Test if value is null and create the string for insert/update
259      * 
260      * @param value
261      * @return the string as result
262      */
263     public static String getIsNull(String value) {
264         return value == null? " is NULL" : " = '" + value + "'";
265     }
266 }