/*********************************************************************
*   All Rights reserved,Copyright (c) K-Opticom
**********************************************************************
*＜プログラム内容＞
*	システム名		：eo顧客基幹システム
*	モジュール名	：JCKejbDBABase
*	ソースファイル名：JCKejbDBABase.java
*	作成者			：富士通
*	日付			：2012年05月01日
*＜機能概要＞
*	データベースアクセス共通部品のスーパークラス（顧客用）
*＜修正履歴＞
*	バージョン	修正日		修正者		修正内容
*	v1.00.00	2012/05/01	富士通		新規作成
*
**********************************************************************/

package eo.ejb.common.db;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;

import com.fujitsu.futurity.common.JCMTraceLog;
import com.fujitsu.futurity.model.base.CAANJDBCUtil;
import com.fujitsu.futurity.model.base.CAANLog;
import com.fujitsu.futurity.model.base.CAANMsg;
import com.fujitsu.futurity.model.base.CAANRuntimeException;

/**
 * <p>
 * データベースアクセス共通部品のスーパークラスです。<br>
 * メインタイプのDBABaseはこちらのクラスを継承してください。<Br>
 * </p>
 * @author 富士通
 */
public abstract class JCKejbDBABase extends JPCejbDBABase
{
	
	/**
	 * <p>
	 * 新しいJCKejbDBABaseを作成します。
	 * </p>
	 */
	public JCKejbDBABase()
	{
	}

	/**
	 * <p>
	 * 新しいJCKejbDBABaseを作成します。
	 * @param arg0 スキーマ名
	 * </p>
	 */
	public JCKejbDBABase(String arg0)
	{
		super(arg0);
	}

	/**
	 * <p>
	 * カレントレコードの検索処理を行います（１世代前カレント同時取得版）。
	 * </p>
	 * @param inMsg カレントレコードの検索キーが格納されたメッセージキャリア
	 * @return 検索結果を格納したメッセージキャリア
	 */
	protected CAANMsg[] findByCurrentSecond(CAANMsg inMsg)
	{
		CAANLog.println(CAANLog.LEVEL_FW, "CALL: JCKejbDBABase#findByCurrentSecond");
		JCMTraceLog.logging("JCKejbDBABase#findByCurrentSecond");

		Connection cnct = null;
		PreparedStatement pstmt = null;
		ResultSet rslt = null;

		try
		{
			// コネクションの取得
			cnct = getConnection(getTableName());

			String[][] selList = getSelectColumnList();
			String[][] keyList = getKeyColumnList();
			String[][] updKeyList = getPrimaryKeyList(inMsg, keyList);

			StringBuffer sql = new StringBuffer();

			// 対象テーブルの全カラムを検索
			sql.append(" select ").append(getSelectColumnListString(selList[1]));
			sql.append(" from ").append(getTableName());

			// カレントレコードを抽出する条件設定
			sql.append(" where rowid in ");
			sql.append(" ( select row_id from ( select rowid as row_id ");
			sql.append(" from ").append(getTableName());
			sql.append(" where ").append(getWhereKeyColumnListString(updKeyList[1]));

			if (isReserveMgr())
			{
				// 予約を管理するエンティティは予約適用基準日を条件に設定
				sql.append(" and ").append(getCurrentColumn()).append("<=?");
			}

			if (isReserveStateMgr())
			{
				// 予約状態を管理するエンティティは予約状態を条件に設定
				sql.append(" and ").append(getReserveStateColumn()).append("='2'");
			}

			sql.append(" and ").append(getInvalidColumn()).append("='0'");
			sql.append(" order by ");

			if (isReserveMgr())
			{
				sql.append(getCurrentColumn()).append(" desc,");
			}

			sql.append(getGenerationColumn()).append(" desc)");
			sql.append(" where rownum between 1 and 2 )");
			sql.append(" order by ");
			
			if (isReserveMgr())
			{
				sql.append(getCurrentColumn()).append(" desc,");
			}
			
			sql.append(getGenerationColumn()).append(" desc");

			CAANLog.println(CAANLog.LEVEL_FW, "sql = [" + sql + "]");
			pstmt = cnct.prepareStatement(sql.toString());

			// 検索条件設定
			setParameters(pstmt, 0, updKeyList[0], inMsg);

			if (isReserveMgr())
			{
				// カレント判定項目の検索値設定
				CAANJDBCUtil.setParam(pstmt, updKeyList[0].length + 1, inMsg.getString(getCurrentColumn()));
			}

			// SQLの実行
			rslt = pstmt.executeQuery();

			// ResultSetの値をメッセージキャリアに転記
			return mapMessageList(rslt, selList[0], getSchemaName(), 0);
 
		}
		catch (SQLException e)
		{
			throw new CAANRuntimeException(e);
		}
		finally
		{
			// このメソッドで確保した資源の解放
			try
			{
				if (rslt != null)
				{
					rslt.close();
				}
				if (pstmt != null)
				{
					pstmt.close();
				}
				if (cnct != null)
				{
					closeConnection(cnct);
				}
			}
			catch (SQLException e)
			{
				throw new CAANRuntimeException(e);
			}
		}
	}

	/**
	 * <p>
	 * エンティティのプライマリキーのリストを取得します。<br>
	 * プライマリキーに世代管理カラム名が存在する場合は、リストには含めません。
	 * </p>
	 * @param inMsg エンティティの情報を格納したメッセージキャリア
	 * @param keyList プライマリキー項目のスキーマ項目名とDBカラム名のリスト
	 * @return プライマリキーとなるリスト
	 */
	private String[][] getPrimaryKeyList(CAANMsg inMsg, String[][] keyList)
	{
		ArrayList<String> msgList = new ArrayList<String>(keyList.length);
		ArrayList<String> dbList = new ArrayList<String>(keyList.length);

		for (int i = 0; i < keyList[0].length; i++)
		{
			if (keyList[0][i].equals(getGenerationColumn()))
			{
				continue;
			}

			if (keyList[0][i].equals(getCurrentColumn()))
			{
				continue;
			}

			if (inMsg.containsKeyOfMsgData(keyList[0][i]))
			{
				msgList.add(keyList[0][i]);
				dbList.add(keyList[1][i]);
			}
		}

		String[] msgClm = msgList.toArray(new String[0]);
		String[] dbClm = dbList.toArray(new String[0]);
		return new String[][] { msgClm, dbClm };
	}

}
