/**
 * Copyright (c) 2003-2004 System Integrator Corporation.
 *                 All Rights Reserved.
 */

package jp.co.sint.database;

import java.sql.*;
import java.sql.ResultSet;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.DatabaseMetaData;

/**
 * レコードセットの作成
 * @version $Id: SIRecordSet.java,v 1.0 2003/06/26 jwchen Exp $
 * @author  Jinwang Chen
 */

public class SIRecordSet {

    public static final boolean PREPARED = true;
    public static final boolean CALLABLE = false;

    private int numCols;
    private Statement stmt;
    private Connection conn;
    private ResultSet columns;
    private DatabaseMetaData dmd;
    private ResultSet resultSet;
    private PreparedStatement prepStatement;
    private ResultSetMetaData rsmd;
    private SIDatabaseConnection pool;
    private Connection connection;
    private boolean mode = PREPARED;
    private String sql;


    /**
     * コンストラクタ[SIRecordSet()]
     * @ DBとの接続
     * @ リセット
     */

    public SIRecordSet(){
    }

    /**
     * コンストラクタ[SIRecordSet(Connection init_connection)]
     * @ コネクションの有無の判断
     * @ DBとの接続
     * @ リセット
    */
    public SIRecordSet(Connection initConnection) throws SQLException{
       if (initConnection==null) return ;
       this.connection=(Connection)initConnection;
    }

    public SIRecordSet(Connection initConnection,String sql){
       if (initConnection==null) return ;
       this.connection=(Connection)initConnection;
       this.sql=sql;
    }

    /**
     * SQL文のステートメント・モードの設定(PREPARED or CALLABLE)
     */
    public void setMode(boolean mode){
        this.mode = mode;
    }


    /**
     * SQL文のプリコンパイル型
     */
   public void setSql(String sql) throws SQLException{
      this.sql=sql;
      if(mode == PREPARED){
         prepStatement = conn.prepareStatement(sql);
       }else{
          prepStatement = conn.prepareCall(sql);
       }
    }

    /**
     *  statement ＆ resultset クローズ
     */
    public void close(){
    }


    /**
     * リセット
     */
    public void reset() throws SQLException{
        close();
        setMode(PREPARED);
    }


    /**
     * SQL文(選択)の実行
     * @ executeQuery()
     */
    public ResultSet executeQuery() throws SQLException{
        resultSet = prepStatement.executeQuery();
        return( resultSet );
    }


    /**
     * SQL文(更新)の実行
     * @ executeUpdate()
     */
   public int executeUpdate() throws SQLException {
      return prepStatement.executeUpdate();
   }

    /**
     * バッチ処理文の追加
     */
    public void addBatch(String batchString) throws SQLException{
        stmt.addBatch(batchString);
    }


    /**
     * バッチ更新処理
     */
    public int[] batchUpdata() throws SQLException{
        conn.setAutoCommit(false);
        int[] updateConts = stmt.executeBatch();
        conn.commit();
        return (updateConts);
    }


    /**
     * バッチ処理文の消去
     */
    public void clearBatch() throws SQLException{
        stmt.clearBatch();
    }


    /**
     * DB操作に関する処理のメソッド
     * @ 整数のセット
     */
    public void setInt( int index, int value ) throws SQLException{
        prepStatement.setInt(index, value);
    }


    /**
     * DB操作に関する処理のメソッド
     * @ 整数の取得
     */
     public int getInt( int index ) throws SQLException{
//        return ((CallableStatement)prep).getInt(index);
        return resultSet.getInt(index);
    }


    /**
     * DB操作に関する処理のメソッド
     * @ 長整数の取得
     */
     public long getLong(int index) throws SQLException{
        return resultSet.getLong(index);
    }


    /**
     * DB操作に関する処理
     * @ 文字列のセット
     */
     public void setString(int index, String value) throws SQLException{
        prepStatement.setString( index, value );
    }


    /**
     * DB操作に関する処理のメソッド
     * @ 文字列の取得
     */
    public String getString(int index) throws SQLException{
//        return ((CallableStatement)prep).getString(index);
        return resultSet.getString(index);
    }


    /**
     * DB操作に関する処理のメソッド
     * @ タイムスタンプのセット
     */
    public void setTimestamp(int index, java.sql.Timestamp time) throws SQLException{
        prepStatement.setTimestamp( index, time );
    }


    /**
     * DB操作に関する処理のメソッド
     * @ タイムスタンプの取得
     */
     public Timestamp getTimestamp(int index) throws SQLException{
        return ((CallableStatement)prepStatement).getTimestamp(index);
    }


    /**
     * DB操作に関する処理のメソッド
     * @ タイプの取得
     */
     public void registerOutParameter(int index, int type) throws SQLException{
        ((CallableStatement)prepStatement).registerOutParameter(index, type);
    }


    /**
     * DB操作に関する処理のメソッド
     * @ レコード・フィールド名取得
     */
    public String[] GetColumnnames() throws SQLException{
        String col_names[] = new String[numCols];
        for (int i = 1; i <= numCols; i++ ){
            col_names[ i - 1 ] = rsmd.getColumnName(i);
        }
        return col_names;
    }


    /**
     * フィールド数取得
     */
    public int GetNumcols(){
      return numCols;
    }


    /**
     * DB操作に関する処理のメソッド
     * @ 次のレコードの取得
     */
    public boolean hasMoreElement() throws SQLException{
        return resultSet.next();
    }


    /**
     * DB操作に関する処理のメソッド
     * @ レコードのデータの取得
     */
    public String[] fetchRow() throws SQLException{
        String[] rowSet = new String[numCols];
        for (int i = 1; i < numCols; i++){
            rowSet[i - 1] = resultSet.getString(i);
        }
        return rowSet;
    }


    /**
     * DB操作に関する処理のメソッド
     * @ レコード名で値の取得
     */
    public String getColumnValue(String columnname) throws SQLException{
        return resultSet.getString(columnname);
    }


    /**
     * DB操作に関する処理のメソッド
     * @ レコードのインデックスで値の取得
     */
    public String getColumnValue(int columnIndex) throws SQLException{
        return resultSet.getString(columnIndex);
    }


    /**
     * DB操作に関する処理のメソッド
     * @ テーブルのカラム情報を調べる
     * @ カラム情報をセットし、返す
     */
    public ResultSet getColumnType(String tablename) throws SQLException{
        if (conn==null){
           try{
              getConnection();
           }catch(SQLException e){
              throw new SQLException();
           }
        }
        dmd = conn.getMetaData();
        columns = dmd.getColumns(null, null, tablename, "%");
        return (columns);
    }


    /**
     * コネクションの取得
     */
    private void getConnection() throws SQLException{
        try{
            pool = new SIDatabaseConnection();
            conn = pool.getConnection();
        } catch (Exception e) {
            throw new SQLException();
        }
    }
}