All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.lucene.store.jdbc.support.JdbcTemplate Maven / Gradle / Ivy

/*
 * Copyright 2004-2009 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.lucene.store.jdbc.support;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Arrays;
import javax.sql.DataSource;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.lucene.store.jdbc.JdbcDirectorySettings;
import org.apache.lucene.store.jdbc.JdbcStoreException;
import org.apache.lucene.store.jdbc.datasource.DataSourceUtils;

/**
 * Helper class that isused to encapsulate resource and transaction handling related to DataSource,
 * Statement, and ResultSet. {@link DataSourceUtils} is used to open/cose relevant
 * resources.
 *
 * @author kimchy
 * @see DataSourceUtils
 */
public class JdbcTemplate {

    private static final Log log = LogFactory.getLog(JdbcTemplate.class);

    /**
     * A callback interface used to initialize a Jdbc PreparedStatement.
     */
    public static interface PrepateStatementAwareCallback {

        /**
         * Initialize/Fill the given PreparedStatement.
         */
        void fillPrepareStatement(PreparedStatement ps) throws Exception;
    }

    /**
     * A callback used to retrieve data from a ResultSet.
     */
    public static interface ExecuteSelectCallback extends PrepateStatementAwareCallback {

        /**
         * Extract data from the ResultSet and an optional return value.
         */
        Object execute(ResultSet rs) throws Exception;
    }

    /**
     * A callback used to work with CallableStatement.
     */
    public static interface CallableStatementCallback {

        /**
         * initialize/Fill the CallableStatement before it is executed.
         */
        void fillCallableStatement(CallableStatement cs) throws Exception;

        /**
         * Read/Extract data from the result of the CallableStatement execution. CAn optionally
         * have a return value.
         */
        Object readCallableData(CallableStatement cs) throws Exception;
    }

    private DataSource dataSource;

    private JdbcDirectorySettings settings;

    /**
     * Creates a new JdbcTemplate.
     */
    public JdbcTemplate(DataSource dataSource, JdbcDirectorySettings settings) {
        this.dataSource = dataSource;
        this.settings = settings;
    }

    /**
     * A template method to execute a simple sql select statement. The jdbc
     * Connection, PreparedStatement, and ResultSet
     * are managed by the template.
     */
    public Object executeSelect(String sql, ExecuteSelectCallback callback)
            throws JdbcStoreException {
        Connection con = DataSourceUtils.getConnection(dataSource);
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            ps = con.prepareStatement(sql);
//            ps.setQueryTimeout(settings.getQueryTimeout());
            callback.fillPrepareStatement(ps);
            rs = ps.executeQuery();
            return callback.execute(rs);
        } catch (JdbcStoreException e) {
            if (log.isTraceEnabled()) {
                log.trace("Failed to execute sql [" + sql + "]", e);
            }
            throw e;
        } catch (Exception e) {
            if (log.isTraceEnabled()) {
                log.trace("Failed to execute sql [" + sql + "]", e);
            }
            throw new JdbcStoreException("Failed to execute sql [" + sql + "]", e);
        } finally {
            DataSourceUtils.closeResultSet(rs);
            DataSourceUtils.closeStatement(ps);
            DataSourceUtils.releaseConnection(con);
        }
    }

    /**
     * A template method to execute a simple sql callable statement. The jdbc
     * Connection, and CallableStatement
     * are managed by the template.
     */
    public Object executeCallable(String sql, CallableStatementCallback callback)
            throws JdbcStoreException {
        Connection con = DataSourceUtils.getConnection(dataSource);
        CallableStatement cs = null;
        try {
            cs = con.prepareCall(sql);
//            cs.setQueryTimeout(settings.getQueryTimeout());
            callback.fillCallableStatement(cs);
            cs.execute();
            return callback.readCallableData(cs);
        } catch (JdbcStoreException e) {
            if (log.isTraceEnabled()) {
                log.trace("Failed to execute sql [" + sql + "]", e);
            }
            throw e;
        } catch (Exception e) {
            if (log.isTraceEnabled()) {
                log.trace("Failed to execute sql [" + sql + "]", e);
            }
            throw new JdbcStoreException("Failed to execute sql [" + sql + "]", e);
        } finally {
            DataSourceUtils.closeStatement(cs);
            DataSourceUtils.releaseConnection(con);
        }
    }

    /**
     * A template method to execute a simple sql update. The jdbc
     * Connection, and PreparedStatement
     * are managed by the template. A PreparedStatement can be used
     * to set values to the given sql.
     */
    public void executeUpdate(String sql, PrepateStatementAwareCallback callback)
            throws JdbcStoreException {
        Connection con = DataSourceUtils.getConnection(dataSource);
        PreparedStatement ps = null;
        try {
            ps = con.prepareStatement(sql);
//            ps.setQueryTimeout(settings.getQueryTimeout());
            callback.fillPrepareStatement(ps);
            ps.executeUpdate();
        } catch (JdbcStoreException e) {
            if (log.isTraceEnabled()) {
                log.trace("Failed to execute sql [" + sql + "]", e);
            }
            throw e;
        } catch (Exception e) {
            if (log.isTraceEnabled()) {
                log.trace("Failed to execute sql [" + sql + "]", e);
            }
            throw new JdbcStoreException("Failed to execute sql [" + sql + "]", e);
        } finally {
            DataSourceUtils.closeStatement(ps);
            DataSourceUtils.releaseConnection(con);
        }
    }

    /**
     * A template method to execute a simpel sql update (with no need for data
     * initialization).
     */
    public void executeUpdate(String sql) throws JdbcStoreException {
        Connection con = DataSourceUtils.getConnection(dataSource);
        Statement statement = null;
        try {
            statement = con.createStatement();
//            statement.setQueryTimeout(settings.getQueryTimeout());
            statement.executeUpdate(sql);
        } catch (SQLException e) {
            if (log.isTraceEnabled()) {
                log.trace("Failed to execute sql [" + sql + "]", e);
            }
            throw new JdbcStoreException("Failed to execute [" + sql + "]", e);
        } finally {
            DataSourceUtils.closeStatement(statement);
            DataSourceUtils.releaseConnection(con);
        }
    }

    /**
     * A template method to execute a set of sqls in batch.
     */
    public int[] executeBatch(String[] sqls) throws JdbcStoreException {
        Connection con = DataSourceUtils.getConnection(dataSource);
        Statement statement = null;
        try {
            statement = con.createStatement();
//            statement.setQueryTimeout(settings.getQueryTimeout());
            for (String sql : sqls) {
                statement.addBatch(sql);
            }
            return statement.executeBatch();
        } catch (SQLException e) {
            if (log.isTraceEnabled()) {
                log.trace("Failed to execute sql [" + Arrays.toString(sqls) + "]", e);
            }
            throw new JdbcStoreException("Failed to execute [" + Arrays.toString(sqls) + "]", e);
        } finally {
            DataSourceUtils.closeStatement(statement);
            DataSourceUtils.releaseConnection(con);
        }
    }

    /**
     * A template method to execute that can execute the same sql several times using different
     * values set to it (in the fillPrepareStatement) callback).
     */
    public int[] executeBatch(String sql, PrepateStatementAwareCallback callback) throws JdbcStoreException {
        Connection con = DataSourceUtils.getConnection(dataSource);
        PreparedStatement ps = null;
        try {
            ps = con.prepareStatement(sql);
//            ps.setQueryTimeout(settings.getQueryTimeout());
            callback.fillPrepareStatement(ps);
            return ps.executeBatch();
        } catch (JdbcStoreException e) {
            if (log.isTraceEnabled()) {
                log.trace("Failed to execute sql [" + sql + "]", e);
            }
            throw e;
        } catch (Exception e) {
            if (log.isTraceEnabled()) {
                log.trace("Failed to execute sql [" + sql + "]", e);
            }
            throw new JdbcStoreException("Failed to execute sql [" + sql + "]", e);
        } finally {
            DataSourceUtils.closeStatement(ps);
            DataSourceUtils.releaseConnection(con);
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy