KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > cocoon > components > language > markup > xsp > AbstractEsqlQuery


1 /*
2  * Copyright 1999-2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.apache.cocoon.components.language.markup.xsp;
17
18 import org.apache.avalon.framework.logger.AbstractLogEnabled;
19
20 import java.sql.Connection JavaDoc;
21 import java.sql.PreparedStatement JavaDoc;
22 import java.sql.CallableStatement JavaDoc;
23 import java.sql.ResultSet JavaDoc;
24 import java.sql.ResultSetMetaData JavaDoc;
25 import java.sql.SQLException JavaDoc;
26 import java.util.ArrayList JavaDoc;
27
28 /**
29  * This is base class for all EsqlQueries
30  *
31  * @author <a HREF="mailto:tcurdt@apache.org">Torsten Curdt</a>
32  * @version CVS $Id: AbstractEsqlQuery.java 124675 2005-01-08 20:18:53Z antonio $
33  */

34 public abstract class AbstractEsqlQuery extends AbstractLogEnabled {
35     private int maxRows = -1;
36     private int skipRows = 0;
37     private int rowCount = -1;
38     private int position = -1;
39     private String JavaDoc query = null;
40     private Connection JavaDoc connection = null;
41     private ResultSetMetaData JavaDoc resultSetMetaData = null;
42     private PreparedStatement JavaDoc preparedStatement = null;
43     private ResultSet JavaDoc resultSet = null;
44     private boolean hasResultSet = false;
45     private boolean keepgoing = true;
46
47     private int queryResultsCount = 0;
48     private int updateResultsCount = 0;
49     private int updateCount = -2;
50
51     private ArrayList JavaDoc groups = null;
52     private int groupLevel = -1;
53     private int changeLevel = -1;
54
55
56     /**
57      * Constructor
58      *
59      * @param connection
60      * @param query - The SQL query string
61      */

62     protected AbstractEsqlQuery(Connection JavaDoc connection, String JavaDoc query) {
63         this.connection = connection;
64         this.query = query;
65     }
66
67     /**
68      * Only newInstance may use this contructor
69      * @param resultSet
70      */

71     protected AbstractEsqlQuery(final ResultSet JavaDoc resultSet) {
72         this.connection = null;
73         this.query = null;
74         this.resultSet = resultSet;
75         this.hasResultSet = (resultSet != null);
76     }
77
78     /**
79      * Create a EsqlQuery of the same type
80      * @param resultSet
81      */

82     public abstract AbstractEsqlQuery newInstance(final ResultSet JavaDoc resultSet);
83
84
85     /**
86      * Return the query string ("select * from bla")
87      *
88      * NOTE: Might want to be overridden by indiviual EsqlQuery implementations
89      * e.g. for database specific LIMIT features. Be aware that there a two different
90      * limit approaches:
91      * <pre>
92      * retrieve query
93      * time time
94      * +---------+ ...........
95      * |JDBC | : :
96      * |ResultSet| : :
97      * |.........|-+ :_________:_
98      * | | | skip/max+1 |JDBC | | skip/max+1
99      * | | | window |ResultSet| | window
100      * |.........| | |_________| |
101      * | |-+ : :_|
102      * | | : :
103      * +---------+ :.........:
104      * </pre>
105      * With the "retrieve time" limit the JDBC ResultSet includes ALL of the rows of the
106      * query.
107      * With the "query time" limit only a small window of rows are in the actuall JDBC
108      * ResultSet. In order to know whether there are more rows available (without an additional
109      * query) we need to have at least one more row in the JDBC ResultSet. So we ask for getMaxRows()+1
110      *
111      * @throws SQLException
112      */

113     public String JavaDoc getQueryString() throws SQLException JavaDoc {
114         return (query);
115     }
116
117     /**
118      * NOTE: Might want to be overridden by indiviual EsqlQuery implementations
119      *
120      * @throws SQLException
121      */

122     public PreparedStatement JavaDoc prepareStatement() throws SQLException JavaDoc {
123         preparedStatement = connection.prepareStatement(getQueryString());
124         return (preparedStatement);
125     }
126
127     /**
128      * NOTE: Might want to be overridden by indiviual EsqlQuery implementations
129      *
130      * @throws SQLException
131      */

132     public CallableStatement JavaDoc prepareCall() throws SQLException JavaDoc {
133         preparedStatement = connection.prepareCall(getQueryString());
134         return ((CallableStatement JavaDoc) preparedStatement);
135     }
136
137
138     /**
139      * Gets the total number of rows of a the query WITHOUT the
140      * limits of skip/max rows.
141      *
142      * NOTE: Might want to be overridden by indiviual EsqlQuery implementations
143      *
144      * @return total number of rows
145      * @throws SQLException
146      */

147     public int getRowCount() throws SQLException JavaDoc {
148         if (rowCount < 0) {
149             String JavaDoc lowerQuery = query.toLowerCase();
150             int from = lowerQuery.indexOf(" from ");
151
152             int groupby = lowerQuery.indexOf(" group by ");
153             int orderby = lowerQuery.indexOf(" order by ");
154
155             int min = Math.min(groupby, orderby);
156
157             String JavaDoc countQuery;
158             if (min > -1) {
159                 countQuery = "select count(*)" + String.valueOf(query).substring(from, min);
160             }
161             else {
162                 countQuery = "select count(*)" + String.valueOf(query).substring(from);
163             }
164
165             if (getLogger().isDebugEnabled()) getLogger().debug("executing [" + String.valueOf(query) + "]");
166
167             ResultSet JavaDoc rs = preparedStatement.executeQuery(countQuery);
168             try {
169                 if (rs.first()) {
170                     rowCount = rs.getInt(1);
171                     if (getLogger().isDebugEnabled()) getLogger().debug("count = " + rowCount);
172                 }
173             }
174             finally {
175                 rs.close();
176             }
177         }
178
179         return (rowCount);
180     }
181
182     /**
183      * Move to the first row.
184      *
185      * NOTE: Might want to be overridden by indiviual EsqlQuery implementations
186      *
187      * @throws SQLException
188      */

189     public void getResultRows() throws SQLException JavaDoc {
190         if (skipRows > 0) {
191             while (resultSet.next()) {
192                 position++;
193                 if (position >= skipRows) {
194                     break;
195                 }
196             }
197         }
198     }
199
200     /**
201      * Clean up all database resources used by the query. In particular,
202      * close result sets and statements.
203      *
204      */

205     public void cleanUp() {
206         this.resultSetMetaData = null;
207         if (this.resultSet != null){
208             try {
209                 this.resultSet.close();
210                 this.resultSet = null;
211             } catch (SQLException JavaDoc e) {
212                 // should never happen! (only cause: access error)
213
}
214         }
215         if (this.preparedStatement != null){
216             try {
217                 this.preparedStatement.close();
218                 this.preparedStatement = null;
219             } catch (SQLException JavaDoc e) {
220                 // should never happen! (only cause: access error)
221
}
222         }
223     }
224
225     /* ************** FINAL methods *********************** */
226
227     protected final void setPosition(int p) {
228         position = p;
229     }
230
231     protected final PreparedStatement JavaDoc setPreparedStatement(final PreparedStatement JavaDoc ps) {
232         preparedStatement = ps;
233         return (preparedStatement);
234     }
235
236     public final Connection JavaDoc getConnection() {
237         return (connection);
238     }
239
240     public final int getSkipRows() {
241         return (skipRows);
242     }
243
244     public final void setSkipRows(int i) {
245         skipRows = i;
246     }
247
248     public final int getMaxRows() {
249         return (maxRows);
250     }
251
252     public final void setMaxRows(int i) {
253         maxRows = i;
254     }
255
256     public final ResultSetMetaData JavaDoc getResultSetMetaData() {
257         return (resultSetMetaData);
258     }
259
260     public final PreparedStatement JavaDoc getPreparedStatement() {
261         return (preparedStatement);
262     }
263
264     public final CallableStatement JavaDoc getCallableStatement() {
265         return ((CallableStatement JavaDoc) preparedStatement);
266     }
267
268     public final ResultSet JavaDoc getResultSet() {
269         return (resultSet);
270     }
271
272     public final boolean nextRow() throws SQLException JavaDoc {
273         position++;
274         return (resultSet.next());
275     }
276
277     public final int getCurrentRow() {
278         return (position);
279     }
280
281
282     public final boolean execute(int resultSetFromObject) throws SQLException JavaDoc {
283         if (preparedStatement != null) {
284             hasResultSet = preparedStatement.execute();
285             if (hasResultSet) {
286                 resultSet = (ResultSet JavaDoc) ((CallableStatement JavaDoc) preparedStatement).getObject(resultSetFromObject);
287                 queryResultsCount++;
288                 return (true);
289             }
290             else {
291                 updateResultsCount++;
292                 updateCount = preparedStatement.getUpdateCount();
293                 return (updateCount > -1);
294             }
295         }
296         else {
297             return (false);
298         }
299     }
300
301     public final boolean execute() throws SQLException JavaDoc {
302         if (preparedStatement != null) {
303             hasResultSet = preparedStatement.execute();
304             if (hasResultSet) {
305                 resultSet = preparedStatement.getResultSet();
306                 resultSetMetaData = resultSet.getMetaData();
307                 queryResultsCount++;
308                 return (true);
309             }
310             else {
311                 updateResultsCount++;
312                 updateCount = preparedStatement.getUpdateCount();
313                 return (updateCount > -1);
314             }
315         }
316         else {
317             return (false);
318         }
319     }
320
321     public final boolean executeQuery() throws SQLException JavaDoc {
322         if (preparedStatement != null) {
323             resultSet = preparedStatement.executeQuery();
324             if (resultSet != null) {
325                 resultSetMetaData = resultSet.getMetaData();
326                 queryResultsCount++;
327                 hasResultSet = true;
328                 return (true);
329             }
330             else {
331                 return (false);
332             }
333         }
334         else {
335             return (false);
336         }
337     }
338
339     /**
340      * Try to get the next ResultSet
341      *
342      * @return whether there is one or not
343      * @throws SQLException
344      */

345     public final boolean getMoreResults() throws SQLException JavaDoc {
346         if (preparedStatement != null) {
347             hasResultSet = preparedStatement.getMoreResults();
348             if (hasResultSet) {
349                 resultSet = preparedStatement.getResultSet();
350                 resultSetMetaData = resultSet.getMetaData();
351                 queryResultsCount++;
352                 return (true);
353             }
354             else {
355                 updateResultsCount++;
356                 updateCount = preparedStatement.getUpdateCount();
357                 return (updateCount > -1);
358             }
359         }
360         else {
361             return (false);
362         }
363     }
364
365
366     public final boolean hasResultSet() {
367         return (hasResultSet);
368     }
369
370
371     /**
372      * Returns the how many rows where updated on last update
373      */

374     public final int getUpdateCount() {
375         return (updateCount);
376     }
377
378     /**
379      * Returns the number of query results
380      */

381     public final int getQueryResultsCount() {
382         return (queryResultsCount);
383     }
384
385     /**
386      * Returns the number of update results
387      */

388     public final int getUpdateResultsCount() {
389         return (updateResultsCount);
390     }
391
392
393     public final boolean keepGoing() {
394         return (keepgoing);
395     }
396
397     public final void setKeepGoing(boolean still) {
398         keepgoing = still;
399     }
400
401     /* ************************ GROUPING ************************ */
402
403     public final void incGroupLevel() {
404         groupLevel++;
405     }
406
407     public final void decGroupLevel() {
408         groupLevel--;
409     }
410
411     public final boolean groupLevelExists() {
412         return (groups != null && groups.size() >= groupLevel + 1 && groups.get(groupLevel) != null);
413     }
414
415     public final void setGroupingVar(String JavaDoc key) throws SQLException JavaDoc {
416         if (groups == null) groups = new ArrayList JavaDoc(groupLevel);
417         groups.ensureCapacity(groupLevel);
418         groups.add(groupLevel, new EsqlGroup(key, getResultSet().getObject(key))
419         );
420     }
421
422     public final boolean hasGroupingVarChanged() throws SQLException JavaDoc {
423         if (changeLevel != -1) {
424             if (changeLevel < groupLevel) {
425                 return (true);
426             }
427             else {
428                 changeLevel = -1;
429                 return (true);
430             }
431         }
432         else {
433             boolean result = false;
434             // need to check the complete hierarchy of nested groups for changes
435
for (int i = 0; i <= groupLevel; i++) {
436                 Object JavaDoc tmp = getResultSet().getObject(((EsqlGroup) groups.get(i)).var);
437                 if (!tmp.equals(((EsqlGroup) groups.get(i)).value)) {
438                     ((EsqlGroup) groups.get(i)).value = tmp;
439                     result = true;
440                     if (changeLevel == -1 && groupLevel != i)
441                         changeLevel = i;
442                 }
443             }
444             return (result);
445         }
446     }
447
448     final static class EsqlGroup {
449         public String JavaDoc var = null;
450         public Object JavaDoc value = null;
451
452         EsqlGroup(String JavaDoc var, Object JavaDoc value) {
453             this.var = var;
454             this.value = value;
455         }
456     }
457
458 }
459
Popular Tags