// <summary>ソースコード：ＨＹＳＳＯＰ ライブラリ管理基底クラス</summary>
// <author>CommonMP</author>

using System;

using CommonMP.HYSSOP.Interface.HSData;
using CommonMP.HYSSOP.Interface.HSController;
using CommonMP.HYSSOP.CoreImpl.HSData;
using CommonMP.HYSSOP.CoreImpl.HSTools;
using CommonMP.HYSSOP.Interface.HSLibraryMng;
using CommonMP.HYSSOP.CoreImpl.HSDBA;

namespace CommonMP.HYSSOP.CoreImpl.HSLibraryMng
{
    /// <summary><para>class outline:</para>
    /// <para>ＨＹＳＳＯＰ ライブラリ管理基底クラス</para>
    /// </summary>
    /// <remarks><para>history:</para>
    /// <para>[CommonMP][ver 1.0.0][2009/10/13][新規作成]</para>
    /// </remarks>
    public abstract class HySBaseLibraryManager : HySLibraryMng
    {
#region private/protectedフィールド

        /// <summary>業務動作中フラグ</summary>
        protected bool m_bWorkFlg = false;

        /// <summary>シミュレーター種別識別子</summary>
        protected HySObjectKind m_csKindID; // シミュレーター種別識別子
        /// <summary>ライブラリ管理制御クラス</summary>
        protected HySControllerRoot m_csController = null;


        /// <summary>クラス名(ログ出力用)</summary>
        const string CLASS_NAME = "HySBaseLibraryManager";
#endregion

        #region publicメソッド

        /// <summary><para>method outline:</para>
        /// <para>デフォルトコンストラクタ</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> HySBaseLibraryManager csLibManager = new HySBaseLibraryManager( ) </para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>HySBaseLibraryManager 生成されたクラスのインスタンス</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public HySBaseLibraryManager()
        {
        }

        /// <summary><para>method outline:</para>
        /// <para>初期化処理</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> bool bRtn = Initialize( ) </para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>true:正常、false:異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public virtual Boolean Initialize()
        {
            return true;
        }

        /// <summary><para>method outline:</para>
        /// <para>ファクトリ管理クラス設定</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> HyStViewer.SetFactoryManager( csFactoryManager ) </para>
        /// </example>
        /// <param name="csFactoryManager">ファクトリ管理クラス</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public virtual void SetFactoryManager(HySFactoryMng csFactoryManager)
        {
            return;
        }

        /// <summary><para>method outline:</para>
        /// <para>終了処理</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> bool bRtn = Terminate( ) </para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>true:正常、false:異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public virtual Boolean Terminate()
        {
            return true;
        }

        /// <summary><para>method outline:</para>
        /// <para>システム終了準備完了判別</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> bool bRtn = ExitOK( ) </para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>true : システムExit準備OK　、false : システムExit準備NG</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public virtual Boolean ExitOK()
        {
            if (m_bWorkFlg == true)
            {
                return false;
            }
            else
            {
                return true;
            }
        }

        /// <summary><para>method outline:</para>
        /// <para>イベントを送る</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> HySSysUnit.PutEvent( csEvent ) </para>
        /// </example>
        /// <param name="csEvent">送るイベント</param>
        /// <returns>true:=正常, false:=異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>自分からイベントを送信する時に使用する</para>
        /// </remarks>
        public virtual bool PutEvent(HySSysEvent csEvent)
        {
            bool bRtn = false;
            ((HySEventObject)csEvent).SetFromSimKind(m_csKindID);
            bRtn = m_csController.PutEvent(csEvent);
            return bRtn;
        }

        /// <summary><para>method outline:</para>
        /// <para>制御クラスを設定する</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> HySSysUnit.SetController( csCtl ) </para>
        /// </example>
        /// <param name="csCtl">制御クラス</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public virtual void SetController(HySControllerRoot csCtl)
        {
            m_csController = csCtl;
        }

        /// <summary><para>method outline:</para>
        /// <para>シミュレーター種別識別子設定</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> HySSysUnit.SetSimKind(csSimKindID)</para>
        /// </example>
        /// <param name="csSimKindID">シミュレーター種別識別子</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public virtual void SetSimKind(HySKind csSimKindID)
        {
            m_csKindID = (HySObjectKind)csSimKindID;
        }
        /// <summary><para>method outline:</para>
        /// <para>シミュレーター種別識別子取得</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> HySKind csKind = HySSysUnit.GetSimKind()</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>シミュレーター種別識別子</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public virtual HySKind GetSimKind()
        {
            return m_csKindID;
        }
        /// <summary><para>method outline:</para>
        /// <para>シミュレーター種別識別子比較</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> bool bVar = HySSysUnit.EqualSimKind(csSimKindID)</para>
        /// </example>
        /// <param name="csSimKindID">シミュレーター種別識別子</param>
        /// <returns>
        /// true : 同じ
        /// false : 異なる
        /// </returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public virtual bool EqualSimKind(HySKind csSimKindID)
        {
            return m_csKindID.Equals(csSimKindID);
        }

        /// <summary><para>method outline:</para>
        /// <para>イベントコールバック処理</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> bool bRtn = EventCallback( csEvent ) </para>
        /// </example>
        /// <param name="csEvent">送られたイベント</param>
        /// <returns>true:=正常, false:=異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>処理対象のイベントでない場合、エラーとする。</para>
        /// <para>このクラスではDBAイベントのみを対象とする。他のイベントをサポートする
        /// 場合、サブクラスで適宜オーバーライドすること。</para>
        /// </remarks>
        public virtual bool EventCallback(HySSysEvent csEvent)
        {
            bool bIsDBAEvent;   // DBAのイベント
            bool bDBAResult;    // 処理結果。bIsDBAEvent=trueの場合のみ有効

            // DBイベント処理を実行する
            ProcessDBAEvent(csEvent, out bIsDBAEvent, out bDBAResult);
            if (bIsDBAEvent)
            {   // DB処理が実行された場合、その処理結果を戻す
                return bDBAResult;
            }
            else
            {   // 対象外イベントなのでエラーとする
                HySEventObject csEventObj = (HySEventObject)csEvent;
                string csEventNoString = ((uint)csEventObj.GetEventNo()).ToString("X8");
                string csSubEventNoString = ((uint)csEventObj.GetSubEventNo()).ToString("X8");
                HySObjectKind csToSimKind = (HySObjectKind)csEventObj.GetToSimKind();
                HySObjectKind csFromSimKind = (HySObjectKind)csEventObj.GetFromSimKind();
                string csFromSimKindString = csFromSimKind == null ? "<null>" : csFromSimKind.ToString();
                string csToSimKindString = csToSimKind == null ? "<null>" : csToSimKind.ToString();
                HySID csSuppID = (HySID)csEventObj.GetSuppID();
                string csSuppIDString = csSuppID == null ? "<null>" : csSuppID.ToString();

               // ver1.5 エラートレース日本語対応
                string csLogMsg = string.Format(
                      Properties.HysMsgResources.STATEMENT_UNSUPPORT_EVENT + "{0},"
                    + Properties.HysMsgResources.STATEMENT_SUB_EVENT       + "{1},"
                    + Properties.HysMsgResources.STATEMENT_FORM_EVENT      + "{2},"
                    + Properties.HysMsgResources.STATEMENT_FORM_SIM_KIND   + "{3},"
                    + Properties.HysMsgResources.STATEMENT_TO_EVENT        + "{4},"
                    + Properties.HysMsgResources.STATEMENT_TO_SIM_KIND     + "{5},"
                    + Properties.HysMsgResources.STATEMENT_SUPPORT_ID      + "{6}",
                    csEventNoString, csSubEventNoString,
                    csEventObj.From(), csFromSimKindString,
                    csEventObj.To(), csToSimKindString,
                    csSuppIDString);
               // string csLogMsg = string.Format("unsupported event: EventNo=0x{0}, SubEventNo=0x{1}, From={2}, FromSimKind={3}, To={4}, ToSimKind={5}, SuppID={6}",
               //     csEventNoString, csSubEventNoString,
               //     csEventObj.From(), csFromSimKindString,
               //     csEventObj.To(), csToSimKindString,
               //     csSuppIDString);
                HySLog.LogOut(HySLog.ONLINE, CLASS_NAME, "EventCallback", csLogMsg);
                return false;
            }
        }


        #endregion

        #region protectedメソッド
        /// <summary><para>method outline:</para>
        /// <para>イベント送信メソッド</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> PutEvent(csEvent, lNo, lSubNo)</para>
        /// </example>
        /// <param name="csEvent">受信したイベント</param>
        /// <param name="lNo">イベント番号</param>
        /// <param name="lSubNo">サブイベント番号</param>
        /// <returns>true:=正常, false:=異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>補助識別子、付加データ、第２付加データはnullで送信する</para>
        /// </remarks>
        protected Boolean PutEvent(HySEventObject csEvent, long lNo, long lSubNo)
        {
            const HySID csSuppID = null;
            const HySDataRoot csData = null;
            const HySDataRoot csSubData = null;
            return PutEvent(csEvent, lNo, lSubNo, csSuppID, csData, csSubData);
        }

        /// <summary><para>method outline:</para>
        /// <para>イベント送信メソッド</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> PutEvent(csEvent, lNo, lSubNo, csData)</para>
        /// </example>
        /// <param name="csEvent">受信したイベント</param>
        /// <param name="lNo">イベント番号</param>
        /// <param name="lSubNo">サブイベント番号</param>
        /// <param name="csData">付加データ</param>
        /// <returns>true:=正常, false:=異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>補助識別子と第２付加データはnullで送信する</para>
        /// </remarks>
        protected Boolean PutEvent(HySEventObject csEvent, long lNo, long lSubNo, HySDataRoot csData)
        {
            const HySID csSuppID = null;
            const HySDataRoot csSubData = null;
            return PutEvent(csEvent, lNo, lSubNo, csSuppID, csData, csSubData);
        }

        /// <summary><para>method outline:</para>
        /// <para>イベント送信メソッド</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> PutEvent(csEvent, lNo, lSubNo, csID, csData)</para>
        /// </example>
        /// <param name="csEvent">受信したイベント</param>
        /// <param name="lNo">イベント番号</param>
        /// <param name="lSubNo">サブイベント番号</param>
        /// <param name="csSuppID">補助識別子</param>
        /// <param name="csData">付加データ</param>
        /// <returns>true:=正常, false:=異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>第２付加データはnullで送信する</para>
        /// </remarks>
        protected Boolean PutEvent(HySEventObject csEvent, long lNo, long lSubNo, HySID csSuppID, HySDataRoot csData)
        {
            const HySDataRoot csSubData = null;
            return PutEvent(csEvent, lNo, lSubNo, csSuppID, csData, csSubData);
        }

        /// <summary><para>method outline:</para>
        /// <para>イベント送信メソッド</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> PutEvent(csEvent, lNo, lSubNo, csID, csData)</para>
        /// </example>
        /// <param name="csEvent">受信したイベント</param>
        /// <param name="lNo">イベント番号</param>
        /// <param name="lSubNo">サブイベント番号</param>
        /// <param name="csSuppID">補助識別子</param>
        /// <param name="csData">付加データ</param>
        /// <param name="csSubData">第２付加データ</param>
        /// <returns>true:=正常, false:=異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        protected Boolean PutEvent(HySEventObject csEvent, long lNo, long lSubNo, HySID csSuppID, HySDataRoot csData, HySDataRoot csSubData)
        {
            bool bRtn = true;
            
            // 受信イベントから応答イベントを生成し、それに対して各情報を設定する
            HySEventObject csEventObject = csEvent.CreateResponceEvent(lNo);
            csEventObject.SetSubEventNo(lSubNo);
            csEventObject.SetSuppID(csSuppID);
            csEventObject.SetData(csData);
            csEventObject.SetSubData(csSubData);
            bRtn = PutEvent(csEventObject);
            return bRtn;
        }
        #endregion

        #region DB関連処理
        /// <summary><para>method outline:</para>
        /// <para>DBAイベント処理</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>csHelper.ProcessDBAEvent( csEvent, out bIsDBAEvent, out bDBAResult )</para>>
        /// </example>
        /// <param name="csEvent">送られたイベント</param>
        /// <param name="bIsDBAEvent">DBイベントとして受け付けたフラグ。</param>
        /// <param name="bDBAResult">DBAメソッドまたはイベント送信処理の戻り値。</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>bAcceptedがtrueの場合、業務へのメッセージ送信までを本メソッドで行っているため、
        /// 呼出側ではメッセージ送信処理を行ってはならない。
        /// bAccepptedがfalseの場合、呼び出し側で適切な処理分岐を行うこと。</para>
        /// <para>bResultはbAcceptedがtrueの時のみ有効。</para>
        /// </remarks>
        protected void ProcessDBAEvent(HySSysEvent csEvent, out bool bIsDBAEvent, out bool bDBAResult)
        {
            // 出力の初期化
            bIsDBAEvent = false;
            bDBAResult = false;

            bool bAccepted = false;     // DBAイベントとして受け付けたかフラグ
            Boolean bRtn = false;       // 下位処理の戻り値

            HySEventObject csEventObj = (HySEventObject)csEvent;

            // 有効なDBAイベントか調べる
            long lEventNo = csEventObj.GetEventNo();
            long lSubEventNo = csEventObj.GetSubEventNo();
            if (!IsValidDBAEvent(lEventNo, lSubEventNo))
            {
                // 有効なDBAイベントでないので処理を終了する
                return;
            }

            // オプションコンポーネントを生成する
            //HySID csDBKindID = (HySID)csEventObj.GetSubData();
            HySID csDBKindID = csEventObj.GetSuppID();
            HySCommonDBA csDBA = null;
            try
            {
                // DBAオブジェクトを生成する
                if (!CreateDBAObject(csDBKindID, out csDBA))
                {
                    // 対象外なので処理を終了する
                    return;
                }
            }
            catch (Exception ex)
            {
                // イベントで指定されたDBアクセスに対応するオプションコンポーネントが使用できない
               // ver1.5 エラートレース日本語対応
                string csLogMsg = string.Format( Properties.HysMsgResources.STATEMENT_EXCEP + "({0})\"{1}\"", ex.GetType().ToString(), ex.ToString());
               // string csLogMsg = string.Format("例外({0})\"{1}\"", ex.GetType().ToString(), ex.ToString());
                HySLog.LogOut(HySLog.ONLINE, CLASS_NAME, "EventCallback", csLogMsg);

                // 業務にエラー通知
                PutEventAfterDBAInvoke(csEventObj, false, "ProcessDBAEvent");

                // 受け付けたことにして処理を打ち切る
                bAccepted = true;
                bRtn = false;   // 処理結果は失敗にする
                return;
            }

            // DBAイベントを処理する
            bAccepted = true;   // DBAイベントとして受け付けた
            bRtn = InvokeDBA(csEventObj, csDBA);

            // 結果を出力パラメータに設定して処理終了
            bIsDBAEvent = bAccepted;
            bDBAResult = bRtn;
            return;
        }

        /// <summary><para>method outline:</para>
        /// <para>DBAイベント処理を起動する</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> bool bRtn = InvokeDBA(csEventObj, csDBA) </para>
        /// </example>
        /// <param name="csEventObj">イベントオブジェクト</param>
        /// <param name="csDBA">共通DBAオブジェクト</param>
        /// <returns>true:成功、false:失敗</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>イベント番号、サブイベント番号に対応するDBA起動メソッドを呼び出す。
        /// DBA起動メソッドはイベント送信までを行う。</para>
        /// </remarks>
        protected bool InvokeDBA(HySEventObject csEventObj, HySCommonDBA csDBA)
        {
            bool bRtn = false;
            long lEventNo = csEventObj.GetEventNo();
            long lSubEventNo = csEventObj.GetSubEventNo();

            if (lEventNo == HySEventObject.CMND_DB_QUERY)
            {
                if (lSubEventNo == HySLibraryMngDefine.DB_QUERY_DATA)
                {
                    bRtn = InvokeDBAGetData(csEventObj, csDBA);
                }
                else if (lSubEventNo == HySLibraryMngDefine.DB_QUERY_DATA_LIST)
                {
                    bRtn = InvokeDBASearchList(csEventObj, csDBA);
                }
                else
                {
                    bRtn = InvokeDBAGetDataList(csEventObj, csDBA);
                }
            }
            else if (lEventNo == HySEventObject.CMND_DB_REGISTER)
            {
                if (lSubEventNo == HySLibraryMngDefine.DB_REGISTER_DATA_NEW)
                {
                    bRtn = InvokeDBARegisterNewOne(csEventObj, csDBA);
                }
                else if (lSubEventNo == HySLibraryMngDefine.DB_REGISTER_DATA_NEW_LIST)
                {
                    bRtn = InvokeDBARegisterNewList(csEventObj, csDBA);
                }
                else if (lSubEventNo == HySLibraryMngDefine.DB_REGISTER_DATA_UPDATE)
                {
                    bRtn = InvokeDBARegisterUpdateOne(csEventObj, csDBA);
                }
                else if (lSubEventNo == HySLibraryMngDefine.DB_REGISTER_DATA_UPDATE_PARTIAL)
                {
                    bRtn = InvokeDBARegisterUpdatePartial(csEventObj, csDBA);
                }
                else
                {
                    bRtn = InvokeDBARegisterUpdateOrNew(csEventObj, csDBA);
                }
            }
            else
            {
                if (lSubEventNo == HySLibraryMngDefine.DB_DELETE_DATA)
                {
                    bRtn = InvokeDBADeleteOne(csEventObj, csDBA);
                }
                else if (lSubEventNo == HySLibraryMngDefine.DB_DELETE_DATA_LIST_BY_ID)
                {
                    bRtn = InvokeDBADeleteListByIDs(csEventObj, csDBA);
                }
                else
                {
                    bRtn = InvokeDBADeleteListByQuery(csEventObj, csDBA);
                }
            }

            return bRtn;
        }

        /// <summary><para>method outline:</para>
        /// <para>DBA起動：データ1件取得</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> bool bRtn = InvokeDBAGetData(csEventObj, csDBA) </para>
        /// </example>
        /// <param name="csEventObj">イベントオブジェクト</param>
        /// <param name="csDBA">共通DBAオブジェクト</param>
        /// <returns>true:成功、false:失敗</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        protected bool InvokeDBAGetData(HySEventObject csEventObj, HySCommonDBA csDBA)
        {
            //HySID csID = (csEventObj as HySEventObject).GetSuppID();
            HySIdentifier csID = (HySIdentifier)csEventObj.GetData();
            HySStockData csStockData;
            bool bRtn;
            // DBA起動
            bRtn = csDBA.GetData(csID, out csStockData);
            // イベント送信
            bRtn = PutEventAfterDBAInvoke(csEventObj, bRtn, "InvokeDBAGetData", csStockData);
            return bRtn;
        }

        /// <summary><para>method outline:</para>
        /// <para>DBA起動：データ複数件取得(検索条件指定)</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> bool bRtn = InvokeDBASearchList(csEventObj, csDBA) </para>
        /// </example>
        /// <param name="csEventObj">イベントオブジェクト</param>
        /// <param name="csDBA">共通DBAオブジェクト</param>
        /// <returns>true:成功、false:失敗</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        protected bool InvokeDBASearchList(HySEventObject csEventObj, HySCommonDBA csDBA)
        {
            HySQueryCtlData csQueryCtlData = (HySQueryCtlData)csEventObj.GetData();
            HySStockDataList csStockDataList;
            bool bRtn;
            // DBA起動
            bRtn = csDBA.SearchList(csQueryCtlData, out csStockDataList);
            // イベント送信
            bRtn = PutEventAfterDBAInvoke(csEventObj, bRtn, "InvokeDBASearchList", csStockDataList);
            return bRtn;
        }

        /// <summary><para>method outline:</para>
        /// <para>DBA起動：データ複数件取得(ID配列指定)</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> bool bRtn = InvokeDBAGetDataList(csEventObj, csDBA) </para>
        /// </example>
        /// <param name="csEventObj">イベントオブジェクト</param>
        /// <param name="csDBA">共通DBAオブジェクト</param>
        /// <returns>true:成功、false:失敗</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        protected bool InvokeDBAGetDataList(HySEventObject csEventObj, HySCommonDBA csDBA)
        {
            HySIdentifier[] csIDs = GetIDsFromEventData(csEventObj);
            HySStockDataList csStockDataList;
            bool bRtn;
            bRtn = csDBA.GetDataList(csIDs, out csStockDataList);
            bRtn = PutEventAfterDBAInvoke(csEventObj, bRtn, "InvokeDBAGetDataList", csStockDataList);
            return bRtn;
        }

        /// <summary><para>method outline:</para>
        /// <para>DBA起動：データ1件新規登録</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> bool bRtn = InvokeDBARegisterNewOne(csEventObj, csDBA) </para>
        /// </example>
        /// <param name="csEventObj">イベントオブジェクト</param>
        /// <param name="csDBA">共通DBAオブジェクト</param>
        /// <returns>true:成功、false:失敗</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        protected bool InvokeDBARegisterNewOne(HySEventObject csEventObj, HySCommonDBA csDBA)
        {
            HySStockData csStockData = (HySStockData)csEventObj.GetData();
            bool bRtn;
            bRtn = csDBA.RegisterNew(csStockData);
            bRtn = PutEventAfterDBAInvoke(csEventObj, bRtn, "InvokeDBARegisterNewOne", csStockData);
            return bRtn;
        }

        /// <summary><para>method outline:</para>
        /// <para>DBA起動：データ複数件新規登録</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> bool bRtn = InvokeDBARegisterNewList(csEventObj, csDBA) </para>
        /// </example>
        /// <param name="csEventObj">イベントオブジェクト</param>
        /// <param name="csDBA">共通DBAオブジェクト</param>
        /// <returns>true:成功、false:失敗</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        protected bool InvokeDBARegisterNewList(HySEventObject csEventObj, HySCommonDBA csDBA)
        {
            HySStockDataList csStockDataList = (HySStockDataList)csEventObj.GetData();
            bool bRtn;
            bRtn = csDBA.RegisterNew(csStockDataList);
            bRtn = PutEventAfterDBAInvoke(csEventObj, bRtn, "InvokeDBARegisterNewList");
            return bRtn;
        }

        /// <summary><para>method outline:</para>
        /// <para>DBA起動：データ1件更新</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> bool bRtn = InvokeDBARegisterUpdateOne(csEventObj, csDBA) </para>
        /// </example>
        /// <param name="csEventObj">イベントオブジェクト</param>
        /// <param name="csDBA">共通DBAオブジェクト</param>
        /// <returns>true:成功、false:失敗</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        protected bool InvokeDBARegisterUpdateOne(HySEventObject csEventObj, HySCommonDBA csDBA)
        {
            HySStockData csStockData = (HySStockData)csEventObj.GetData();
            bool bRtn;
            bRtn = csDBA.Update(csStockData);
            bRtn = PutEventAfterDBAInvoke(csEventObj, bRtn, "InvokeDBARegisterUpdateOne", csStockData);
            return bRtn;
        }

        /// <summary><para>method outline:</para>
        /// <para>DBA起動：データ1件削除</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> bool bRtn = InvokeDBADeleteOne(csEventObj, csDBA) </para>
        /// </example>
        /// <param name="csEventObj">イベントオブジェクト</param>
        /// <param name="csDBA">共通DBAオブジェクト</param>
        /// <returns>true:成功、false:失敗</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        protected bool InvokeDBADeleteOne(HySEventObject csEventObj, HySCommonDBA csDBA)
        {
            //HySID csID = (HySID)csEventObj.GetSuppID();
            HySIdentifier csID = (HySIdentifier)csEventObj.GetData();
            bool bRtn;
            bRtn = csDBA.Delete(csID);
            bRtn = PutEventAfterDBAInvoke(csEventObj, bRtn, "InvokeDBADeleteOne");
            return bRtn;
        }

        /// <summary><para>method outline:</para>
        /// <para>DBA起動：データ複数件削除(ID配列指定)</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> bool bRtn = InvokeDBADeleteListByIDs(csEventObj, csDBA) </para>
        /// </example>
        /// <param name="csEventObj">イベントオブジェクト</param>
        /// <param name="csDBA">共通DBAオブジェクト</param>
        /// <returns>true:成功、false:失敗</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        protected bool InvokeDBADeleteListByIDs(HySEventObject csEventObj, HySCommonDBA csDBA)
        {
            HySIdentifier[] csIDs = GetIDsFromEventData(csEventObj);
            bool bRtn;
            bRtn = csDBA.Delete(csIDs);
            bRtn = PutEventAfterDBAInvoke(csEventObj, bRtn, "InvokeDBADeleteListByIDs");
            return bRtn;
        }

        /// <summary><para>method outline:</para>
        /// <para>DBA起動：データ複数件削除(検索条件指定)</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> bool bRtn = InvokeDBADeleteListByQuery(csEventObj, csDBA) </para>
        /// </example>
        /// <param name="csEventObj">イベントオブジェクト</param>
        /// <param name="csDBA">共通DBAオブジェクト</param>
        /// <returns>true:成功、false:失敗</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        protected bool InvokeDBADeleteListByQuery(HySEventObject csEventObj, HySCommonDBA csDBA)
        {
            HySQueryCtlData csQueryCtlData = (HySQueryCtlData)csEventObj.GetData();
            bool bRtn;
            bRtn = csDBA.Delete(csQueryCtlData);
            bRtn = PutEventAfterDBAInvoke(csEventObj, bRtn, "InvokeDBADeleteListByQuery");
            return bRtn;
        }

        /// <summary><para>method outline:</para>
        /// <para>DBA起動：データ部分更新</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> bool bRtn = InvokeDBARegisterUpdatePartial(csEventObj, csDBA) </para>
        /// </example>
        /// <param name="csEventObj">イベントオブジェクト</param>
        /// <param name="csDBA">共通DBAオブジェクト</param>
        /// <returns>true:成功、false:失敗</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        protected bool InvokeDBARegisterUpdatePartial(HySEventObject csEventObj, HySCommonDBA csDBA)
        {
            HySDBPartialUpdateSpec csPartialUpdateSpec = (HySDBPartialUpdateSpec)csEventObj.GetData();
            bool bRtn;
            bRtn = csDBA.UpdatePartial(csPartialUpdateSpec.GetQueryCtlData(), csPartialUpdateSpec.GetModifyData());
            bRtn = PutEventAfterDBAInvoke(csEventObj, bRtn, "InvokeDBARegisterUpdatePartial");
            return bRtn;
        }

        /// <summary><para>method outline:</para>
        /// <para>DBA起動：更新または新規登録</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> bool bRtn = InvokeDBARegisterUpdateOrNew(csEventObj, csDBA) </para>
        /// </example>
        /// <param name="csEventObj">イベントオブジェクト</param>
        /// <param name="csDBA">共通DBAオブジェクト</param>
        /// <returns>true:成功、false:失敗</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        protected bool InvokeDBARegisterUpdateOrNew(HySEventObject csEventObj, HySCommonDBA csDBA)
        {
            // DB保存データからIDを取得し、検索条件を組み立てる
            HySStockData csStockData = (HySStockData)csEventObj.GetData();
            HySID csID = GetIDFromStockData(csStockData);
            HySQueryCtlData csQueryCtlData = new HySQueryCtlData();
            csQueryCtlData.SetQueryEntryData(new HySQueryEntryData(HySQueryFieldNames.ID, typeof(HySID),
                HySQueryCompareMode.EQUALS, csID));
            csQueryCtlData.SetIsMetaDataOnly(true); // メタデータのみ
            HySStockDataList csStockDataList;
            bool bRtn;

            // 新規または更新を判断するために検索を行う
            bRtn = csDBA.SearchList(csQueryCtlData, out csStockDataList);
            if (bRtn)
            {
                if (csStockDataList.GetCount() == 0)
                {
                    bRtn = csDBA.RegisterNew(csStockData);
                }
                else
                {
                    bRtn = csDBA.Update(csStockData);
                }
            }
            bRtn = PutEventAfterDBAInvoke(csEventObj, bRtn, "InvokeDBARegisterUpdateOrNew", csStockData);
            return bRtn;
        }

        /// <summary><para>method outline:</para>
        /// <para>DB保存データからIDを取得する</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> HySID csID = GetIDFromStockData( csStockData ) </para>
        /// </example>
        /// <param name="csStockData">DB保存データ</param>
        /// <returns>データのユニークID</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>サブクラスで固有のデータ構造を持つ場合、オーバーライドすること。</para>
        /// </remarks>
        protected virtual HySID GetIDFromStockData(HySStockData csStockData)
        {
            HySID csID = csStockData.GetID();
            return csID;
        }

        /// <summary><para>method outline:</para>
        /// <para>DBA起動後のメッセージ送信処理</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> bool bRtn = PutEventAfterDBAInvoke(csEventObj, bDBARtn, csMethodName, csEventData) </para>
        /// </example>
        /// <param name="csEventObj">イベントオブジェクト</param>
        /// <param name="bDBARtn">DBAメソッド戻り値</param>
        /// <param name="csMethodName">ログ出力用メソッド名</param>
        /// <param name="csEventData">イベント付属データ</param>
        /// <returns>true:成功(bDBARtnがtrueかつNOTICE_DB_OKイベント送信成功)、false:失敗</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>イベント送信処理に失敗した場合、ログを出力する。</para>
        /// </remarks>
        protected bool PutEventAfterDBAInvoke(HySEventObject csEventObj, bool bDBARtn, string csMethodName, HySDataRoot csEventData)
        {
            // DBA結果によりイベント番号を選択する
            long lEventNo;
            if (bDBARtn)
            {
                lEventNo = HySEventObject.NOTICE_DB_OK;
            }
            else
            {
                lEventNo = HySEventObject.NOTICE_DB_NG;
            }
            // イベント送信実行
            bool bRtn = PutEvent(csEventObj, lEventNo, csEventObj.GetSubEventNo(), csEventObj.GetSuppID(), csEventData, csEventObj.GetSubData());
            if (!bRtn)
            {
               // ver1.5 エラートレース日本語対応
                HySLog.LogOut(HySLog.ONLINE, CLASS_NAME, csMethodName, Properties.HysMsgResources.STATEMENT_SEND_FAILURE + "(NOTICE_DB_OK)");
               // HySLog.LogOut(HySLog.ONLINE, CLASS_NAME, csMethodName, "イベント送信エラー(NOTICE_DB_OK)");
            }
            // DBA正常かつイベント送信成功の場合のみtrueを返す
            return (bDBARtn && bRtn);
        }

        /// <summary><para>method outline:</para>
        /// （オーバーロード）DBA起動後のメッセージ送信処理
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> bool bRtn = PutEventAfterDBAInvoke(csEventObj, bDBARtn, csMethodName) </para>
        /// </example>
        /// <param name="csEventObj">イベントオブジェクト</param>
        /// <param name="bDBARtn">DBAメソッド戻り値</param>
        /// <param name="csMethodName">ログ出力用メソッド名</param>
        /// <returns>true:成功、false:失敗</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>イベント送信処理に失敗した場合、ログを出力する。イベント付属データはnullを設定する。</para>
        /// </remarks>
        protected bool PutEventAfterDBAInvoke(HySEventObject csEventObj, bool bDBARtn, string csMethodName)
        {
            return PutEventAfterDBAInvoke(csEventObj, bDBARtn, csMethodName, null);
        }

        /// <summary><para>method outline:</para>
        /// <para>イベントオブジェクトの付属データからID配列を取得する</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> HySIdentifier[] csIDs = GetIDsFromEventData( csEventObj ) </para>
        /// </example>
        /// <param name="csEventObj">イベントオブジェクト</param>
        /// <returns>ID配列</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>HySIdentifier[]はHySDataRootでないため、イベントオブジェクトに格納できない。
        /// そのため、呼び出し側ではHySDataLinkedListを用いるものとする。</para>
        /// </remarks>
        protected static HySIdentifier[] GetIDsFromEventData(HySEventObject csEventObj)
        {
            HySDataLinkedList csDataList = (HySDataLinkedList)csEventObj.GetData();
            csDataList.SetCursorFirst();
            HySIdentifier csID;
            HySIdentifier[] csIDs = new HySIdentifier[csDataList.GetCount()];
            int iArrayIndex = 0;
            for (long i = 0; i < csDataList.GetCount(); i++)
            {
                csID = (HySIdentifier)csDataList.GetCursorData();
                csIDs[iArrayIndex++] = csID;
                csDataList.MoveCursorNext();
            }
            return csIDs;
        }

        /// <summary><para>method outline:</para>
        /// <para>DBAオブジェクトを作成する</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> bool bRtn = CreateDBAObject( csDBKindID, out csDBA ) </para>
        /// </example>
        /// <param name="csDBKindID">DB種別ID</param>
        /// <param name="csDBA">DBAオブジェクト</param>
        /// <returns>true:DB種別IDに該当するDBAオブジェクトを生成した、false:対象外</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>DBAが利用できない場合、例外が発生する。</para>
        /// <para>サブクラスでオーバーライドする場合、サブクラスでサポートしない
        /// DB種別IDに対して基底クラスのメソッドを呼び出すこと。そうしないと
        /// 基本クラスでサポートしているDBが利用できなくなる。</para>
        /// </remarks>
        protected abstract bool CreateDBAObject(HySID csDBKindID, out HySCommonDBA csDBA);

        /// <summary><para>method outline:</para>
        /// <para>DBAイベントチェック</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> bool bRtn = IsValidDBAEvent( lEventNo, lSubEventNo ) </para>
        /// </example>
        /// <param name="lEventNo">イベント番号</param>
        /// <param name="lSubEventNo">サブイベント番号</param>
        /// <returns>true:DBAイベントである、false:DBAイベントでない</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        protected bool IsValidDBAEvent(long lEventNo, long lSubEventNo)
        {
            bool bResult = false;
            // イベント番号、サブイベント番号で処理を振り分ける
            if (lEventNo == HySEventObject.CMND_DB_QUERY)
            {   // 検索ならば
                if (lSubEventNo == HySLibraryMngDefine.DB_QUERY_DATA ||
                    lSubEventNo == HySLibraryMngDefine.DB_QUERY_DATA_LIST ||
                    lSubEventNo == HySLibraryMngDefine.DB_QUERY_DATA_LIST_BY_ID)
                {
                    bResult = true;
                }
            }
            else if (lEventNo == HySEventObject.CMND_DB_REGISTER)
            {   // 登録ならば
                if (lSubEventNo == HySLibraryMngDefine.DB_REGISTER_DATA_NEW ||
                    lSubEventNo == HySLibraryMngDefine.DB_REGISTER_DATA_NEW_LIST ||
                    lSubEventNo == HySLibraryMngDefine.DB_REGISTER_DATA_UPDATE ||
                    lSubEventNo == HySLibraryMngDefine.DB_REGISTER_DATA_UPDATE_PARTIAL ||
                    lSubEventNo == HySLibraryMngDefine.DB_REGISTER_DATA_UPDATE_OR_NEW)
                {
                    bResult = true;
                }
            }
            else if (lEventNo == HySEventObject.CMND_DB_DELETE)
            {   // 削除ならば
                if (lSubEventNo == HySLibraryMngDefine.DB_DELETE_DATA ||
                    lSubEventNo == HySLibraryMngDefine.DB_DELETE_DATA_LIST ||
                    lSubEventNo == HySLibraryMngDefine.DB_DELETE_DATA_LIST_BY_ID)
                {
                    bResult = true;
                }
            }
            return bResult;
        }
        #endregion
    }
}
