/*
 * $Header: /home/cvs/commons/dbutils-1.0/ja/src/org/apache/commons/dbutils/DbUtils.java,v 1.1.1.1 2004/02/13 10:02:04 hioki Exp $
 * $Revision: 1.1.1.1 $
 * $Date: 2004/02/13 10:02:04 $
 * 
 * ====================================================================
 *
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 2002-2003 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution, if
 *    any, must include the following acknowledgement:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgement may appear in the software itself,
 *    if and wherever such third-party acknowledgements normally appear.
 *
 * 4. The names "The Jakarta Project", "Commons", and "Apache Software
 *    Foundation" must not be used to endorse or promote products derived
 *    from this software without prior written permission. For written
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache"
 *    nor may "Apache" appear in their names without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 *
 */

package org.apache.commons.dbutils;

import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

/**
 * JDBCのヘルパーメソッドの集合です。 このクラスはスレッドセーフです。
 * {@primary A collection of JDBC helper methods.  This class is thread safe.}
 * 
 * @author Henri Yandell
 * @author Juozas Baliuka
 * @author Steven Caswell
 * @author David Graham
 * @translator 小川 環
 * @editor 日置 聡
 * @status underproof 
 * @update 2003/12/19
 */
public final class DbUtils {

    /**
     * <code>Connection</code> を閉じ、null であれば閉じるのを回避します。
     * {@primary Close a <code>Connection</code>, avoid closing if null.}
     */
    public static void close(Connection conn) throws SQLException {
        if (conn != null) {
            conn.close();
        }
    }

    /**
     * <code>ResultSet</code> を閉じ、null であれば閉じるのを回避します。
     * {@primary Close a <code>ResultSet</code>, avoid closing if null.}
     */
    public static void close(ResultSet rs) throws SQLException {
        if (rs != null) {
            rs.close();
        }
    }

    /**
     * <code>Statement</code> を閉じ、null であれば閉じるのを回避します。
     * {@primary Close a <code>Statement</code>, avoid closing if null.}
     */
    public static void close(Statement stmt) throws SQLException {
        if (stmt != null) {
            stmt.close();
        }
    }

    /**
     * <code>Connection</code> を閉じ、 null の場合には閉じるのを回避した上で、SQLException の発生を隠蔽します。
     * {@primary Close a <code>Connection</code>, avoid closing if null and hide
     * any SQLExceptions that occur.}
     */
    public static void closeQuietly(Connection conn) {
        try {
            close(conn);
        } catch (SQLException sqle) {
            // quiet
        }
    }

    /**
     * <code>Connection</code>、<code>Statement</code>、<code>ResultSet</code> を閉じます。
     * null の場合には閉じるのを回避した上で、SQLException の発生を隠蔽します。
     * {@primary Close a <code>Connection</code>, <code>Statement</code> and 
     * <code>ResultSet</code>.  Avoid closing if null and hide any 
     * SQLExceptions that occur.}
     */
    public static void closeQuietly(
        Connection conn,
        Statement stmt,
        ResultSet rs) {
            
        closeQuietly(rs);
        closeQuietly(stmt);
        closeQuietly(conn);
    }

    /**
     * <code>ResultSet</code> を閉じ、 null の場合には閉じるのを回避した上で、SQLException の発生を隠蔽します。
     * {@primary Close a <code>ResultSet</code>, avoid closing if null and hide
     * any SQLExceptions that occur.}
     */
    public static void closeQuietly(ResultSet rs) {
        try {
            close(rs);
        } catch (SQLException sqle) {
            // quiet
        }
    }

    /**
     *  <code>Statement</code> を閉じ、 null の場合には閉じるのを回避した上で、SQLException の発生を隠蔽します。
     * {@primary Close a <code>Statement</code>, avoid closing if null and hide
     * any SQLExceptions that occur.}
     */
    public static void closeQuietly(Statement stmt) {
        try {
            close(stmt);
        } catch (SQLException sqle) {
            // quiet
        }
    }

    /**
     * <code>Connection</code> をコミットしてから を閉じ、 null の場合、閉じるのを回避します。 
     * {@primary Commits a <code>Connection</code> then closes it, avoid closing if null.}
     */
    public static void commitAndClose(Connection conn) throws SQLException {
        if (conn != null) {
            conn.commit();
            conn.close();
        }
    }

    /**
     * <code>Connection</code> をコミットしてから閉じ、null の場合、閉じるのを回避した上で、SQLException の発生を隠蔽します。
     * {@primary Commits a <code>Connection</code> then closes it, avoid closing if null 
     * and hide any SQLExceptions that occur.}
     */
    public static void commitAndCloseQuietly(Connection conn) {
        try {
            commitAndClose(conn);
        } catch (SQLException sqle) {
            // quiet
        }
    }

    /**
     * データベースのドライバクラスを読込および登録を行います。 
     * これが正常に実行されたら true が返され、そうでなければ false が返されます。
     * {@primary Loads and registers a database driver class.
     * If this succeeds, it returns true, else it returns false.}
     */
    public static boolean loadDriver(String driverClassName) {
        try {
            Class.forName(driverClassName).newInstance();
            return true;

        } catch (ClassNotFoundException e) {
            // TODO Logging?
            //e.printStackTrace();
            return false;

        } catch (IllegalAccessException e) {
            // TODO Logging?
            //e.printStackTrace();

            // Constructor is private, OK for DriverManager contract
            return true;

        } catch (InstantiationException e) {
            // TODO Logging?
            //e.printStackTrace();
            return false;

        } catch (Throwable t) {
            return false;
        }
    }

    public static void printStackTrace(SQLException sqle) {
        printStackTrace(sqle, new PrintWriter(System.err));
    }

    public static void printStackTrace(SQLException sqle, PrintWriter pw) {

        SQLException next = sqle;
        while (next != null) {
            next.printStackTrace(pw);
            next = next.getNextException();
            if (next != null) {
                pw.println("Next SQLException:");
            }
        }
    }

    public static void printWarnings(Connection connection) {
        printWarnings(connection, new PrintWriter(System.err));
    }

    public static void printWarnings(Connection conn, PrintWriter pw) {
        if (conn != null) {
            try {
                printStackTrace(conn.getWarnings(), pw);
            } catch (SQLException sqle) {
                printStackTrace(sqle, pw);
            }
        }
    }

    /**
     * 指定された接続上で蓄積された変更内容をロールバックします。
     * {@primary Rollback any changes made on the given connection.}
     * @param conn ロールバックさせるデータベースの接続。null 値も有効です。
     * {@primary The database Connection to rollback.  A null value is legal.}
     * @throws SQLException
     */
    public static void rollback(Connection conn) throws SQLException {
        if (conn != null) {
            conn.rollback();
        }
    }

}
