001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: package org.apache.cocoon.components.language.markup.xsp;
019:
020: import java.sql.PreparedStatement;
021: import java.sql.SQLException;
022: import java.sql.ResultSet;
023: import java.sql.CallableStatement;
024: import java.sql.Connection;
025:
026: /**
027: * This EsqlQuery only uses the standard JDBC API approaches.
028: * Please note that whether this is good, ok or bad depends
029: * on the driver implementation of your database vendor.
030: * It should work with all JDBC compliant databases.
031: * Unfortunately it seems NOT to work with mssql
032: *
033: * @author <a href="mailto:tcurdt@apache.org">Torsten Curdt</a>
034: * @version CVS $Id: JdbcEsqlQuery.java 433543 2006-08-22 06:22:54Z crossley $
035: */
036: final public class JdbcEsqlQuery extends AbstractEsqlQuery {
037:
038: public JdbcEsqlQuery(Connection connection, String query) {
039: super (connection, query);
040: }
041:
042: /**
043: * Only newInstance may use this contructor
044: * @param resultSet
045: */
046: private JdbcEsqlQuery(final ResultSet resultSet) {
047: super (resultSet);
048: }
049:
050: /**
051: * Create a EsqlQuery of the same type
052: * @param resultSet
053: */
054: public AbstractEsqlQuery newInstance(final ResultSet resultSet) {
055: return (new JdbcEsqlQuery(resultSet));
056: }
057:
058: public PreparedStatement prepareStatement() throws SQLException {
059: return (setPreparedStatement(getConnection().prepareStatement(
060: getQueryString(), ResultSet.TYPE_SCROLL_INSENSITIVE,
061: ResultSet.CONCUR_READ_ONLY)));
062: }
063:
064: public CallableStatement prepareCall() throws SQLException {
065: return ((CallableStatement) setPreparedStatement(getConnection()
066: .prepareCall(getQueryString(),
067: ResultSet.TYPE_SCROLL_INSENSITIVE,
068: ResultSet.CONCUR_READ_ONLY)));
069: }
070:
071: /**
072: * AFAIK this is the proposed JDBC API way to get the number
073: * of results. Unfortunately -at least some- driver implementation
074: * are transfering the complete resultset when moving to the end.
075: * Which is totally stupid for limit/paging purposes. So we probably
076: * better stick with an additional count query from the AbstractEsqlQuery
077: */
078:
079: public int getRowCount() throws SQLException {
080: ResultSet rs = getResultSet();
081: synchronized (rs) {
082: int currentRow = rs.getRow();
083: rs.last();
084: int count = rs.getRow();
085: if (currentRow > 0) {
086: rs.absolute(currentRow);
087: } else {
088: rs.first();
089: rs.relative(-1);
090: }
091: return (count);
092: }
093: }
094:
095: public void getResultRows() throws SQLException {
096: final int skip = getSkipRows();
097: if (skip > 0) {
098: getResultSet().absolute(skip);
099: }
100: setPosition(skip);
101: }
102:
103: }
|