/*
 * Copyright (C) 2005 NTT DATA Corporation
 * 
 */
package org.postgresforest.vm;

import java.net.SocketTimeoutException;
import java.sql.SQLException;

import org.postgresforest.Driver;
import org.postgresforest.core.ParameterList;
import org.postgresforest.core.Query;
import org.postgresforest.core.QueryExecutor;
import org.postgresforest.vm.Logger;
import org.postgresforest.vm.core.SimpleResultHandler;
import org.postgresforest.vm.err.DistError;

/**
 * クエリー実行スレッドクラス。
 * クエリーを実行し、結果を取得する。
 */
public class StatementExecuteSub 
{
	public static final int ERR_NONE       =  0; // エラー無し
	public static final int ERR_BROKEN     = -1; // 切り離し対象エラー
	public static final int ERR_NOT_BROKEN = -2; // 通常エラー
	public static final int ERR_TIMEOUT    = -3; // タイムアウト
	public static final int ERR_ROLLBACK   = -4; // ロールバック対象エラー

	protected SimpleResultHandler m_resultHandler;
	
	/** 実行ステータス */
	protected int m_ErrCode;

	/** 例外クラス */
	protected java.sql.SQLException m_errobj;

	/** ログ出力スレッド名 */
	protected String m_name;
	
	/**
	 * @param logUtil
	 */
	public StatementExecuteSub(String logName) {
		m_name = logName;
	}

	/**
	 * クエリーの実行を行い、実行結果を取得する。
	 * エラー発生時には、エラー判定クラスを用いてエラーを判別する
	 */
	public void execute(QueryExecutor queryExecutor,
						Query query,
						ParameterList parameterList,
						int maxRows,
						int fetchSize,
						int flags)
	{
		try{
			m_ErrCode = ERR_NONE;
			m_errobj = null;

	        m_resultHandler = new SimpleResultHandler();
	        queryExecutor.execute(query,
	        		parameterList,
                    m_resultHandler,
                    maxRows,
                    fetchSize,
                    flags);
			
			Logger.info(m_name + ": Execution of a query was completed. (" + query + ")");
		}
		catch (SQLException e)
		{
			Logger.info(m_name + ": Query execution error = " + "\n" + e.toString());

			if (e.getCause() instanceof SocketTimeoutException) {
				m_ErrCode = ERR_TIMEOUT;
				return;
			}
			
			//Ver3.1 ロールバック対象判別
			if( DistError.isRollBack(e) ) {
				Logger.info(m_name + ": RollBack!!" + "\n" + e.toString());

				m_ErrCode = ERR_ROLLBACK;
				m_errobj = e;

				return;
			}
			
			boolean isErr = DistError.isBroken(e);
			if( isErr == true ) {
				m_ErrCode = ERR_BROKEN;
			}else{
				m_ErrCode = ERR_NOT_BROKEN;
			}
			m_errobj = e;
		}

		Logger.debug(m_name + ":execute End");
	}

	/**
	 * @return
	 */
	public java.sql.SQLException getErrobj() {
		return m_errobj;
	}

	/**
	 * @return
	 */
	public int getErrCode() {
		return m_ErrCode;
	}


	public SimpleResultHandler getResultHandler() {
		return m_resultHandler;
	}
    
}
