/****************************************************************************
  module      : vkb04.cpp
  author      : JuergenA,UweH
  responsible : UweH
  special area: KB_object_handling_interface
  last changed: 2002-01-01  12:00
  see also    : 
  description : 

    ========== licence begin  GPL
    Copyright (c) 2000-2005 SAP AG

    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
    as published by the Free Software Foundation; either version 2
    of the License, or (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
    ========== licence end


*****************************************************************************/


/*===========================================================================*
 *  INCLUDES                                                                 *
 *===========================================================================*/

#include <string.h>

#include "hkb04.h"

#include "hbd04.h"
#include "ggg01.h"
#include "hgg01_3.h"
#include "hkb05.h"
#include "hkb50.h"   /* PTS 1120151 FF 2003-JAN-29 */
#include "hkb51.h"
#include "hkb53.h"
#include "hkb67.h"

#if COMPILEMODE_MEO00 >= SLOW_MEO00	
#include "hta99.h"
#include "hta01.h"
#endif

#include "Logging/Log_Transaction.hpp"
#include "Logging/Log_AfterImage.hpp"
#include "Logging/Log_ActionObject.hpp"
#include "Logging/Log_ActionObjectFile.hpp"
#include "liveCache/LVC_Types.hpp"
#include "Trace/Trace_Entry.hpp"
#include "KernelCommon/Kernel_OpMsg.hpp"  
#include "hkb560.h" // kb560ConvertWriteRedoEntryResultToBasisError

/*===========================================================================*
 *  DEFINES                                                                  *
 *===========================================================================*/

#define BEGIN_SUBTRANS_SET  true

struct t_TraceOutput
{
    tgg00_MessType     trcMessType;
    tgg00_MessType2    trcMessType2;
    tgg00_BasisError   trcError; 
    tgg91_TransNo      trcConsistView;
};

/*===========================================================================*
 *  GLOBAL FUNCTIONS                                                         *
 *===========================================================================*/

inline static void kb04_EnterKb (tgg00_TransContext	   &Trans,
                                 tgg00_MessType_Enum    MessType,
                                 tgg00_MessType2_Enum	MessType2,
                                 bool                   WriteVtrace,
                                 bool                   SubtransRequested,
                                 bool                   ignoreCancelFlag = false ) // PTS 1117708 FF 2002-SEP-09
{
    if (e_ok != Trans.trError_gg00) {
        if ((g01vtrace.vtrAll_gg00 || g01vtrace.vtrBdObject_gg00))                 // PTS XYZXYZ FF 2003-DEC-05
            Kernel_VTrace() << __FILE__ << " : " << __LINE__ << " Error:" << Trans.trError_gg00;
        return;
    }

    Trans.trRteCommPtr_gg00->virt_reads = -MAX_INT4_SP00;
    if  (WriteVtrace)
    {
        t_TraceOutput TraceOutput;
        
        TraceOutput.trcMessType.becomes(MessType);
        TraceOutput.trcMessType2.becomes(MessType2);
        TraceOutput.trcError       = e_ok;
        TraceOutput.trcConsistView = Trans.trConsistView_gg00; 
        
        Trace_CommonEntry( Trans, tgg00_Debug::fromConst(kb), tgg00_VtraceType::fromConst(kb04oms), 
            REINTERPRET_CAST( tsp00_BytePtr, &TraceOutput ), sizeof (TraceOutput) );
    }
    
    if ( Trans.trRteCommPtr_gg00->to_cancel
         && 
         ! ignoreCancelFlag ) // PTS 1117708 FF 
    {
        Trans.trError_gg00 = e_cancelled;
        return;
    }
    
    if (cgg_nil_transindex == Trans.trIndex_gg00)
    {
        Trans.trError_gg00 = e_nil_transindex; // trans entry of this session not found
    }
    
    if ( SubtransRequested )
    {
        Trans.trState_gg00.delElement (tsFunctRollbSet_egg00);
        REINTERPRET_CAST(Log_Transaction*,Trans.trLogContext_gg00)->BeginSubtrans();
        if ((Trans.trError_gg00 != e_ok) &&       // PTS XYZXYZ FF 2003-DEC-05
            ((g01vtrace.vtrAll_gg00 || g01vtrace.vtrBdObject_gg00)))
            Kernel_VTrace() << __FILE__ << ":" << __LINE__ << " BeginSubtrans error:" << Trans.trError_gg00; 
    }
        
#   if COMPILEMODE_MEO00 >= SLOW_MEO00
    t01trans (kb, "Trans (KB04)", Trans);
#   endif   
}


/*-----------------------------------------------------------------------------------*/

inline static void kb04_ErrorHandling (tgg00_TransContext   &Trans,
                                       tgg00_MessType_Enum	 MessType,
                                       bool                  WriteVtrace,
                                       bool                  SubtransRequested)
{
    if  (e_ok != Trans.trError_gg00)
    {
        kb05ReturnErrorHandling (Trans, SubtransRequested, MessType);
    }
    else
    {
        if ( SubtransRequested )
            REINTERPRET_CAST(Log_Transaction*,Trans.trLogContext_gg00)->EndSubtrans();
    }
    
    if  (WriteVtrace)
    {
        t_TraceOutput TraceOutput;
        
        TraceOutput.trcMessType.becomes(m_return_error);
        TraceOutput.trcMessType2.becomes((m_begin == MessType) ? mm_trans : mm_nil); // mark StartConsistTrans
        TraceOutput.trcError       = Trans.trError_gg00;
        TraceOutput.trcConsistView = Trans.trConsistView_gg00;
        
        Trace_CommonEntry( Trans, tgg00_Debug::fromConst(kb), tgg00_VtraceType::fromConst(kb04oms), 
            REINTERPRET_CAST( tsp00_BytePtr, &TraceOutput ), sizeof (TraceOutput) );
    }
}

/*-----------------------------------------------------------------------------------*/

externCpp void
kb04CreateObjFile (tgg00_TransContext	&Trans,
                   tgg00_FileId 	    &ObjFile,
                   tsp00_Int4       	 ObjBodyLen,
                   tsp00_Int4            ObjKeyLen,
				   tsp00_Bool            bCreateSeveralObjKeyFiles)			   
{ 
    ROUTINE_DBG_MEO00 ("kb04CreateObjFile");
    
    const tgg00_MessType_Enum	ThisMessType  = m_create_file;
    const tgg00_MessType2_Enum	ThisMessType2 = mm_object;
    const bool                  WriteVtrace   = (g01vtrace.vtrAll_gg00 || g01vtrace.vtrOmsNew_gg00 );
    const bool                  bOnlineCreateFile = true;

    tgg00_LockReqMode	GrantedLock;
    tgg00_Lkey			DummyKey;
	LVC_RootPageNoArray RootPageNoArray;
    
    kb04_EnterKb (Trans, ThisMessType, ThisMessType2, WriteVtrace, ! BEGIN_SUBTRANS_SET);
    if (e_ok != Trans.trError_gg00) return; 
    
#   if COMPILEMODE_MEO00 >= SLOW_MEO00	
    t01treeid (kb, "create Obj  ", ObjFile);
    t01trans  (kb, "trans       ", Trans );
#   endif
    
    GrantedLock.becomes(lckFree_egg00);
    k53eot_excl_lock (Trans, ObjFile, DummyKey, lckSysExcl_egg00, GrantedLock);
    
    if  (e_ok == Trans.trError_gg00)
    {
        ObjFile.fileVersion_gg00().gg90SetZero();
        
        bd04CreateObjFile (Trans, ObjFile, ObjBodyLen, ObjKeyLen, 
			bCreateSeveralObjKeyFiles, bOnlineCreateFile,  RootPageNoArray);

        if  (e_ok == Trans.trError_gg00)
        {
            // PTS 1117603 UH 2002-09-12 written shorter
            Log_Transaction     &logtrans      = *(reinterpret_cast<Log_Transaction*>(Trans.trLogContext_gg00));
            Log_AfterImage       AfterImage (Log_CreateObjectFile);
            Log_ActionObjectFile Action;
            Action.InitCreation ( ObjFile.fileObjFileNo_gg00(),
                                  ObjFile.fileObjFileType_gg00() == oftVarLenObjFile_egg00,
                                  ObjBodyLen,
                                  ObjKeyLen,
                                  bCreateSeveralObjKeyFiles,
                                  RootPageNoArray );
            Trans.trError_gg00 =
                kb560ConvertWriteRedoEntryResultToBasisError
                    ( logtrans.WriteRedoEntry (AfterImage, Action) );
        }
    }
    kb04_ErrorHandling (Trans, ThisMessType, WriteVtrace, ! BEGIN_SUBTRANS_SET);
}

/*----------------------------------------------------------------------------*/
externCpp void
kb04CreateKeyIterator (tgg00_TransContext &Trans,
				       tgg00_FileId		  &ObjFile,
				       tsp00_Int4	       KeyLen,
				       void		          *pStartKey,
				       void		          *pLowerKey,   
				       void		          *pUpperKey,   
				       void              *&pKeyIterator,
               bool              bAscendingKeyOrder,
               bool              readBuffered)   
{
    ROUTINE_DBG_MSP00 ("kb04CreateKeyIterator");
    
    const tgg00_MessType_Enum   ThisMessType  = m_select;
    const tgg00_MessType2_Enum  ThisMessType2 = mm_object;
    const bool                  WriteVtrace   = (cgg04_is_true == g01vtrace.vtrOmsGet_gg00);
    
    kb04_EnterKb (Trans, ThisMessType, ThisMessType2, WriteVtrace, ! BEGIN_SUBTRANS_SET);
    if (Trans.trError_gg00 != e_ok) return;
    
    bd04CreateKeyIterator (Trans,  ObjFile, KeyLen,  pStartKey, 
        pLowerKey, pUpperKey, pKeyIterator, bAscendingKeyOrder,
        readBuffered);
    
    kb04_ErrorHandling (Trans, ThisMessType, WriteVtrace, ! BEGIN_SUBTRANS_SET);      
}

/*----------------------------------------------------------------------------*/

externCpp void
kb04DeleteAllObj (tgg00_TransContext  &Trans,
				  tgg00_FileId		  &ObjFile,
				  tsp00_Int4          &NumDelObj,
                  tgg92_KernelOid     &ErrorOid)				  
{ 
	ROUTINE_DBG_MSP00 ("kb04DeleteAllObj");
	
	const tgg00_MessType_Enum	ThisMessType  = m_delete;
	const tgg00_MessType2_Enum	ThisMessType2 = mm_object;
	const bool                  WriteVtrace   = (cgg04_is_true == g01vtrace.vtrOmsUpd_gg00);
	
    kb04_EnterKb (Trans, ThisMessType, ThisMessType2, WriteVtrace, BEGIN_SUBTRANS_SET);
    if (Trans.trError_gg00 != e_ok) return; // timeout !

    bd04DelAllObj (Trans, ObjFile, NumDelObj, ErrorOid);
	kb04_ErrorHandling (Trans, ThisMessType, WriteVtrace, BEGIN_SUBTRANS_SET);      
}


/*----------------------------------------------------------------------------*/

externCpp void
kb04DeleteObj (tgg00_TransContext	&Trans,
               tgg00_FileId			&ObjFile,
               tgg92_KernelOid  	 Oid,
               tgg91_PageRef	     WantedObjVers)
               //tgg00_ObjColDesc		&ColDesc)   // PTS !"§$
{ 
    ROUTINE_DBG_MEO00 ("kb04DeleteObj");
    
    const tgg00_MessType_Enum	ThisMessType  = m_delete;
    const tgg00_MessType2_Enum	ThisMessType2 = mm_object;
    const bool                  WriteVtrace   = (cgg04_is_true == g01vtrace.vtrOmsUpd_gg00);
    
    kb04_EnterKb (Trans, ThisMessType, ThisMessType2, WriteVtrace, BEGIN_SUBTRANS_SET);
    if (e_ok != Trans.trError_gg00) return;
    
    bd04DelObj (Trans, ObjFile, Oid, WantedObjVers);
    if (e_ok == Trans.trError_gg00)
        kb67WriteDeleteObjectAfterImage ( Trans,
                                          ObjFile.fileObjFileNo_gg00(),
                                          Oid, 
                                          WantedObjVers );
    kb04_ErrorHandling (Trans, ThisMessType, WriteVtrace, BEGIN_SUBTRANS_SET);      
}


/*----------------------------------------------------------------------------*/

externCpp void
kb04DestroyKeyIterator (tgg00_TransContext &Trans,
				        void              *&pKeyIterator)
{
    ROUTINE_DBG_MEO00 ("kb04DestroyKeyIterator");

	const tgg00_MessType_Enum	ThisMessType  = m_drop;
    const tgg00_MessType2_Enum	ThisMessType2 = mm_object;
    const bool                  WriteVtrace   = (cgg04_is_true == g01vtrace.vtrOmsUpd_gg00);

	kb04_EnterKb (Trans, ThisMessType, ThisMessType2, WriteVtrace, ! BEGIN_SUBTRANS_SET);
    if (Trans.trError_gg00 != e_ok) return;

	bd04DestroyKeyIterator(Trans, pKeyIterator);
	kb04_ErrorHandling (Trans, ThisMessType, WriteVtrace, ! BEGIN_SUBTRANS_SET);    
}

/*----------------------------------------------------------------------------*/

externCpp void
kb04DropObjFile (tgg00_TransContext    &Trans,
                 tgg00_FileId          &ObjFileId)
{
    ROUTINE_DBG_MEO00 ("kb04DropObjFile");
    
    const tgg00_MessType_Enum	ThisMessType  = m_drop;
    const tgg00_MessType2_Enum	ThisMessType2 = mm_object;
    const bool                  WriteVtrace   = (g01vtrace.vtrAll_gg00 || g01vtrace.vtrOmsNew_gg00 );

    kb04_EnterKb (Trans, ThisMessType, ThisMessType2, WriteVtrace, ! BEGIN_SUBTRANS_SET);
    if (e_ok != Trans.trError_gg00) return;
    
#   if COMPILEMODE_MEO00 >= SLOW_MEO00	
    t01treeid (kb, "drop Obj    ", ObjFileId);
    t01trans  (kb, "trans       ", Trans );
#   endif
    
    tgg00_LockReqMode	GrantedLock;
    tgg00_Lkey			DummyKey;
    GrantedLock.becomes(lckFree_egg00);
    k53eot_excl_lock (Trans, ObjFileId, DummyKey, lckSysExcl_egg00, GrantedLock);
    if  (e_ok == Trans.trError_gg00)
    {
        bd04DropObjFile (Trans, ObjFileId);

        if  (e_ok == Trans.trError_gg00)
        {
            // PTS 1117603 UH 2002-09-12 written shorter
            Log_Transaction     &logtrans      = *(reinterpret_cast<Log_Transaction*>(Trans.trLogContext_gg00));
            Log_AfterImage       AfterImage (Log_DropObjectFile);
            Log_ActionObjectFile Action;
            Action.InitDeletion (ObjFileId.fileObjFileNo_gg00());

            Trans.trError_gg00 =
                kb560ConvertWriteRedoEntryResultToBasisError
                    ( logtrans.WriteRedoEntry (AfterImage, Action) );
        }
    }
    kb04_ErrorHandling (Trans, ThisMessType, WriteVtrace, ! BEGIN_SUBTRANS_SET);
}

/*----------------------------------------------------------------------------*/

externCpp void
kb04EndConsistentTrans (tgg00_TransContext &Trans)
{ 
    ROUTINE_DBG_MEO00 ("kb04EndConsistentTrans");
    
    const tgg00_MessType_Enum	ThisMessType  = m_end;
    const tgg00_MessType2_Enum	ThisMessType2 = mm_trans;
    const bool                  WriteVtrace   = (cgg04_is_true == g01vtrace.vtrOmsGet_gg00);
    const bool                  IgnoreCancelFlag = true; // PTS 1117708 FF 2002-SEP-09
    
    kb04_EnterKb (Trans, ThisMessType, ThisMessType2, WriteVtrace, ! BEGIN_SUBTRANS_SET, IgnoreCancelFlag);
    if (e_ok != Trans.trError_gg00) return; 
    
    kb51DelConsistTrans (Trans.trTaskId_gg00, Trans.trConsistView_gg00 );
    Trans.trConsistView_gg00.gg90SetNil();
    kb04_ErrorHandling (Trans, ThisMessType, WriteVtrace, ! BEGIN_SUBTRANS_SET);   
}

/*----------------------------------------------------------------------------*/
// PTS 1120478
externCpp void
kb04GetContainerId (tgg00_TransContext &Trans,
                    tgg00_FileId       &ObjFile,     
                    tgg92_KernelOid     Oid)
{ 
    ROUTINE_DBG_MEO00 ("kb04GetContainerId ");
    
    const tgg00_MessType_Enum   ThisMessType  = m_get_object;
    const tgg00_MessType2_Enum  ThisMessType2 = mm_consistent;
    const bool                  WriteVtrace   = (cgg04_is_true == g01vtrace.vtrOmsGet_gg00);
    
    kb04_EnterKb (Trans, ThisMessType, ThisMessType2, WriteVtrace, ! BEGIN_SUBTRANS_SET);
    if (e_ok != Trans.trError_gg00) return; // timeout !

    bd04GetContainerId (Trans, ObjFile, Oid); 
    kb04_ErrorHandling (Trans, ThisMessType, WriteVtrace, ! BEGIN_SUBTRANS_SET);
}

/*----------------------------------------------------------------------------*/

externCpp void
kb04GetObjConsistent (tgg00_TransContext &Trans,
                      tgg00_FileId       &ObjFile,     
                      tgg92_KernelOid     Oid,
                      tsp00_Int4         ObjBodySize,      //[inp=buffer size for object] 
                      void               *pObjBody,        //[inp]
                      bool                bDoLock,         //[inp] 
                      tsp00_Int4         &ObjBodyLen,      //[out=real object length]
                      tsp00_Int4         &LogReadAccesses, //[out] PTS 1107890 TA 13/09/2000
                      tgg91_PageRef      &ResultObjVers)
{ 
    ROUTINE_DBG_MEO00 ("kb04GetObjConsistent");
    
    const tgg00_MessType_Enum ThisMessType  = m_get_object;
    const tgg00_MessType2_Enum  ThisMessType2 = mm_consistent;
    const bool                  WriteVtrace   = (cgg04_is_true == g01vtrace.vtrOmsGet_gg00);
    
    tsp00_Byte *pKey   = NULL;
    tsp00_Int4  KeyLen = 0;
    
    kb04_EnterKb (Trans, ThisMessType, ThisMessType2, WriteVtrace, ! BEGIN_SUBTRANS_SET);
    if (e_ok != Trans.trError_gg00) return; // timeout !
    
    if ((cgg_nil_transindex == Trans.trIndex_gg00)
        ||
        Trans.trConsistView_gg00.gg90IsNil() )
    {
        Kernel_OpWarning( csp3_bd_msg, csp3_n_obj )
            << __FILE__ << __LINE__ << "trIndex OR trConsistView_gg00 is NIL";
        Trans.trError_gg00 = e_unknown_consist_vers;
    }
    else
    {
        const tsp00_Int4  ZeroHashKeyLen  = 0;
        void             *DummyHashKeyPtr = NULL;
        
        bd04GetObjConsistent (Trans, ObjFile, Oid, ObjBodySize, pObjBody,
            ZeroHashKeyLen, DummyHashKeyPtr, bDoLock, ObjBodyLen,
            KeyLen, &pKey, ResultObjVers, LogReadAccesses); //PTS 1107890 AK 12/09/2000
    }
    
#   if COMPILEMODE_MEO00 >= SLOW_MEO00
    if (e_ok == Trans.trError_gg00) t01moveobj (kb, pObjBody, 1, ObjBodyLen);
#   endif   
    
    kb04_ErrorHandling (Trans, ThisMessType, WriteVtrace, ! BEGIN_SUBTRANS_SET);
}

/*----------------------------------------------------------------------------*/

externCpp void
kb04GetObjWithKeyConsistent (tgg00_TransContext	  &Trans,
                             tgg00_FileId	      &ObjFile,
                             tsp00_Int4		       ObjBodySize,
                             void			      *pObjBody,
                             tsp00_Int4	           KeyLen,
                             void		          *pKey,
                             bool                  bDoLock,      //[inp] 
                             tsp00_Int4           &LogReadAccesses, //[out] PTS 1107890 TA 13/09/2000
                             tgg92_KernelOid      &ResultOid,
                             tgg91_PageRef        &ResultObjVers)
{ 
    ROUTINE_DBG_MEO00 ("kb04GetObjWithKeyConsistent");
    
    const tgg00_MessType_Enum	ThisMessType  = m_get_object;
    const tgg00_MessType2_Enum	ThisMessType2 = mm_object_id;
    const bool                  WriteVtrace   = (cgg04_is_true == g01vtrace.vtrOmsGet_gg00);
    
    kb04_EnterKb (Trans, ThisMessType, ThisMessType2, WriteVtrace, ! BEGIN_SUBTRANS_SET);
    if (e_ok != Trans.trError_gg00) return;
    
    if ((cgg_nil_transindex == Trans.trIndex_gg00)
        ||
        Trans.trConsistView_gg00.gg90IsNil() )
    {
        Kernel_OpWarning( csp3_bd_msg, csp3_n_obj )
            << __FILE__ << __LINE__ << "trIndex OR trConsistView_gg00 is NIL";
        Trans.trError_gg00 = e_unknown_consist_vers;
    }
    else
    {      
        bd04GetObjWithKeyConsistent (Trans, ObjFile, ObjBodySize,
            pObjBody, KeyLen, pKey, bDoLock, ResultOid, ResultObjVers, LogReadAccesses); //PTS 1107890 AK 12/09/2000        
        if (e_object_not_found == Trans.trError_gg00)
            Trans.trError_gg00 = e_hash_key_not_found;
    }
    
#   if COMPILEMODE_MEO00 >= SLOW_MEO00
    if (e_ok == Trans.trError_gg00) t01moveobj (kb, pObjBody, 1, ObjBodySize);
#   endif   
    
    kb04_ErrorHandling (Trans, ThisMessType, WriteVtrace, ! BEGIN_SUBTRANS_SET); 
}


/*---------------------------------------------------------------------------*/

externCpp void
kb04IsObjHistoryUsed (tgg00_TransContext &Trans,
                      tgg00_FileId       &ObjFile,
                      tgg92_KernelOid     Oid,
                      bool               &bHistoryIsUsed)
{
    /* PTS 1106284 UH 07-04-2000 new */
    ROUTINE_DBG_MSP00 ("kb04IsObjHistoryUsed");
    if (e_ok != Trans.trError_gg00) return;

    const tgg00_MessType_Enum	ThisMessType  = m_history;
    const tgg00_MessType2_Enum	ThisMessType2 = mm_test;
    const bool                  WriteVtrace   = (cgg04_is_true == g01vtrace.vtrOmsUpd_gg00);

    kb04_EnterKb (Trans, ThisMessType, ThisMessType2, WriteVtrace, ! BEGIN_SUBTRANS_SET);
    if (e_ok != Trans.trError_gg00) return;

    bd04IsObjHistoryUsed (Trans, ObjFile, Oid, bHistoryIsUsed);
    kb04_ErrorHandling (Trans, ThisMessType, WriteVtrace, ! BEGIN_SUBTRANS_SET); 
}


/*----------------------------------------------------------------------------*/

externCpp void
kb04IsObjSelfLocked (tgg00_TransContext  &Trans,
                     tgg00_FileId        &ObjFile,
                     tgg92_KernelOid      Oid,
                     bool                &IsSelfLocked)
                     /* PTS 1001745 UH 23-11-1998 new */
{
    ROUTINE_DBG_MSP00 ("kb04IsObjSelfLocked");
    
    const tgg00_MessType_Enum	ThisMessType  = m_lock;
    const tgg00_MessType2_Enum	ThisMessType2 = mm_test;
    const bool                  WriteVtrace   = (cgg04_is_true == g01vtrace.vtrOmsUpd_gg00);
    
    kb04_EnterKb (Trans, ThisMessType, ThisMessType2, WriteVtrace, ! BEGIN_SUBTRANS_SET);
    if (e_ok != Trans.trError_gg00) return;
    
    bd04IsObjSelfLocked (Trans, ObjFile, Oid, IsSelfLocked);    
    kb04_ErrorHandling (Trans, ThisMessType, WriteVtrace, ! BEGIN_SUBTRANS_SET); 
}

/*----------------------------------------------------------------------------*/

externCpp void
kb04LockObj (tgg00_TransContext	&Trans,
             tgg00_FileId	    &ObjFile,	   
             tgg92_KernelOid     Oid,
             tgg91_PageRef   	 WantedObjVers)
{ 
    ROUTINE_DBG_MEO00 ("kb04LockObj");
    
    const tgg00_MessType_Enum	ThisMessType  = m_lock;
    const tgg00_MessType2_Enum	ThisMessType2 = mm_object;
    const bool                  WriteVtrace   = (cgg04_is_true == g01vtrace.vtrOmsUpd_gg00);
    
    kb04_EnterKb (Trans, ThisMessType, ThisMessType2, WriteVtrace, ! BEGIN_SUBTRANS_SET);
    if (e_ok != Trans.trError_gg00) return;
    
    bd04LockObj (Trans, ObjFile, Oid, WantedObjVers);
    kb04_ErrorHandling (Trans, ThisMessType, WriteVtrace, ! BEGIN_SUBTRANS_SET); 
}

/*---------------------------------------------------------------------------*/

externCpp void
kb04LockUpdObj (tgg00_TransContext &Trans,
                tgg00_FileId       &ObjFile,    
                tgg92_KernelOid     Oid,
                tgg91_PageRef       WantedObjVers)
{ 
    /* PTS 1109298 UH 2001-01-26 new */
    ROUTINE_DBG_MEO00 ("kb04LockUpdObj");
    
    const tgg00_MessType_Enum	ThisMessType  = m_change;
    const tgg00_MessType2_Enum	ThisMessType2 = mm_object;
    const bool                  WriteVtrace   = (cgg04_is_true == g01vtrace.vtrOmsUpd_gg00);
    
    kb04_EnterKb (Trans, ThisMessType, ThisMessType2, WriteVtrace, BEGIN_SUBTRANS_SET);
    if (e_ok != Trans.trError_gg00) return;
    
    bd04LockUpdObj (Trans, ObjFile, Oid, WantedObjVers);
    kb04_ErrorHandling (Trans, ThisMessType, WriteVtrace, BEGIN_SUBTRANS_SET); 
}


/*----------------------------------------------------------------------------*/

externCpp void
kb04NewObj (tgg00_TransContext  &Trans,
            tgg00_FileId	    &ObjFile,
            tsp00_Int4		     KeyLen,
            void			    *Key,
            tgg92_KernelOid     &ResultOid,
            tgg91_PageRef       &ResultObjVers)
{ 
    ROUTINE_DBG_MEO00 ("kb04NewObj");
    
    const tgg00_MessType_Enum	ThisMessType  = m_new;
    const tgg00_MessType2_Enum	ThisMessType2 = mm_object;
    const bool                  WriteVtrace   = (cgg04_is_true == g01vtrace.vtrOmsNew_gg00);
    
    kb04_EnterKb (Trans, ThisMessType, ThisMessType2, WriteVtrace, BEGIN_SUBTRANS_SET);
    if (e_ok != Trans.trError_gg00) return; 
    
    // PTS 1117603 UH 2002-09-12 The AfterImageHandling was rewritten
    Log_Transaction &logtrans = *(reinterpret_cast<Log_Transaction*>(Trans.trLogContext_gg00));

    tsp00_Int4 FrameLen = 0;
    bd04NewObj (Trans, ObjFile, FrameLen, KeyLen, Key, ResultOid, ResultObjVers);

    if ( e_ok == Trans.trError_gg00 )
    {
        Log_AfterImage   newObjectAfterImage (Log_NewObject);
        Log_ActionObject newObjectAction;
    
        newObjectAction.InitNew ( ObjFile, ResultOid, ResultObjVers,
                                  KeyLen, reinterpret_cast<SAPDB_Byte*>(Key) );
    
        Trans.trError_gg00 = 
            kb560ConvertWriteRedoEntryResultToBasisError
                ( logtrans.WriteRedoEntry (newObjectAfterImage, newObjectAction) );
    }

    if ( e_ok == Trans.trError_gg00
         &&
         KeyLen > 0 )
    {
        tgg91_PageRef   ReUsedObjVers;
        tgg92_KernelOid	ReUsedOId;
        
        // PTS 1116896 mb 2002-07-25 // PTS 1117603 UH 2002-09-12 removed again
        
        bd04NewObjKey (Trans, ObjFile, KeyLen, Key, ResultOid, ReUsedOId, ReUsedObjVers);
        
        if ( e_ok == Trans.trError_gg00 )
        {
            if ( ! ReUsedOId.gg92IsNilPno() )
            {
                // An object could be reused for the given key,
                // so we have to delete the newly created object.
                // The Key is not deleted, because the key's oid doesn't match.

                bd04DelObj (Trans, ObjFile, ResultOid, ResultObjVers);
                
                if (e_ok == Trans.trError_gg00)
                    kb67WriteDeleteObjectAfterImage ( Trans,
                                                      ObjFile.fileObjFileNo_gg00(),
                                                      ResultOid, 
                                                      ResultObjVers );
                
                ResultOid     = ReUsedOId;
                ResultObjVers = ReUsedObjVers;
                
                if ( e_ok == Trans.trError_gg00 )
                {
                    Log_AfterImage   reusedObjectAfterImage (Log_NewObject);
                    Log_ActionObject reusedObjectAction;
                
                    reusedObjectAction.InitNew ( ObjFile, ResultOid, ResultObjVers,
                                                 KeyLen, reinterpret_cast<SAPDB_Byte*>(Key) );
                
                    Trans.trError_gg00 = 
                        kb560ConvertWriteRedoEntryResultToBasisError
                            ( logtrans.WriteRedoEntry (reusedObjectAfterImage, reusedObjectAction) );
                }
            }
        }
        else
        {
            // PTS 1132118 UH 2004-10-25 ResultOid is always assigned
            /* return OId of object which already belongs to the   */
            /* current key, PTS 1105726 Alexander Kley 29/02/2000  */     

            ResultOid     = ReUsedOId;
            ResultObjVers = ReUsedObjVers;

            // PTS 1116896 mb 2002-07-25 write rollback-information in order to perform
            // a rollback of the newObj at restart-time
            // PTS 1117603 UH 2002-09-12 removed again
        }
    }

    kb04_ErrorHandling (Trans, ThisMessType, WriteVtrace, BEGIN_SUBTRANS_SET);
}

/*----------------------------------------------------------------------------*/

externCpp void
kb04NextObjConsistent (tgg00_TransContext &Trans,
                       tgg00_FileId		    &ObjFile,	   
                       tgg92_KernelOid    &CurrOid,
                       bool                bWithObject,
                       tsp00_Int4		       ObjBodySize,   //[inp=buffer size for object]
                       void				        *pObjBody,
                       tsp00_Int4&        LogReadAccesses,// PTS 1107890 TA 13/09/2000
                       tgg91_PageRef      &ResultObjVers)
{ 
    ROUTINE_DBG_MEO00 ("kb04NextObjConsistent");
    
    const tgg00_MessType_Enum	ThisMessType  = m_get_object;
    const tgg00_MessType2_Enum	ThisMessType2 = mm_qual;
    const bool                  WriteVtrace   = (cgg04_is_true == g01vtrace.vtrOmsGet_gg00);
    tsp00_Int4                  ObjBodyLen;

    kb04_EnterKb (Trans, ThisMessType, ThisMessType2, WriteVtrace, ! BEGIN_SUBTRANS_SET);
    if (e_ok != Trans.trError_gg00) return;

    bd04NextObjConsistent (Trans, ObjFile, CurrOid, bWithObject,
        ObjBodySize, pObjBody, ObjBodyLen, ResultObjVers, LogReadAccesses); //PTS 1107890 AK 12/09/2000
    
#   if COMPILEMODE_MEO00 >= SLOW_MEO00
    if (e_ok == Trans.trError_gg00) t01moveobj (kb, pObjBody, 1, ObjBodySize);
#   endif   
    
    kb04_ErrorHandling (Trans, ThisMessType, WriteVtrace, ! BEGIN_SUBTRANS_SET); 
}

/*----------------------------------------------------------------------------*/

externCpp void
kb04NextOidsConsistent (tgg00_TransContext    &Trans,
                       tgg00_FileId           &ObjFile,	   
                       const tgg92_KernelOid  &CurrOid,
                       tsp00_Int4             &noOfOid,
                       tgg92_KernelOid        *pOid,
                       tgg91_PageRef          *pObjVers,
                       tsp00_Int4             &LogReadAccesses)
{ 
    ROUTINE_DBG_MEO00 ("kb04NextOidsConsistent");
    
    const tgg00_MessType_Enum	ThisMessType  = m_get_object;
    const tgg00_MessType2_Enum	ThisMessType2 = mm_qual;
    const bool                  WriteVtrace   = (cgg04_is_true == g01vtrace.vtrOmsGet_gg00);

    kb04_EnterKb (Trans, ThisMessType, ThisMessType2, WriteVtrace, ! BEGIN_SUBTRANS_SET);
    if (e_ok != Trans.trError_gg00) return;

    bd04NextOidsConsistent (Trans, ObjFile, CurrOid, noOfOid, pOid, pObjVers, LogReadAccesses); 
    
    kb04_ErrorHandling (Trans, ThisMessType, WriteVtrace, ! BEGIN_SUBTRANS_SET); 
}

/*----------------------------------------------------------------------------*/
// PTS 1119480 Interface changed
externCpp void
kb04NextObjFromKeyIterator (tgg00_TransContext &Trans,
                            void               *pUntypedKeyIterator,    
                            bool                bInclusive,  
                            tsp00_Int4          KeyLen,    
                            tsp00_Int4          objBodySize,
                            void               *pRestartKey, 
                            tsp00_Int4         &noOfOid,
                            tgg92_KernelOid    *pResultOId, 
                            tgg91_PageRef      *pObjVers,
                            tsp00_Int4         &LogReadAccesses,
                            tsp00_MoveObj      *pObjBody)
{ 
    ROUTINE_DBG_MEO00 ("kb04NextObjConsistent");
    
    const tgg00_MessType_Enum	ThisMessType  = m_get_object;
    const tgg00_MessType2_Enum	ThisMessType2 = mm_qual;
    const bool                  WriteVtrace   = (cgg04_is_true == g01vtrace.vtrOmsGet_gg00);

    kb04_EnterKb (Trans, ThisMessType, ThisMessType2, WriteVtrace, ! BEGIN_SUBTRANS_SET);
    if (e_ok != Trans.trError_gg00) return;
	
	  bd04NextObjFromKeyIterator (Trans, pUntypedKeyIterator, bInclusive, KeyLen, objBodySize,
                                pRestartKey, noOfOid, pResultOId, pObjVers, LogReadAccesses,
                                pObjBody);

    /* PTS 1119480
    #   if COMPILEMODE_MEO00 >= SLOW_MEO00
    if (e_ok == Trans.trError_gg00) t01moveobj (kb, pExtObjBody, 1, ResultObjBodySize);
#   endif   
    */
    
    kb04_ErrorHandling (Trans, ThisMessType, WriteVtrace, ! BEGIN_SUBTRANS_SET); 
}

/*----------------------------------------------------------------------------*/
// PTS 1119480   new function
externCpp void
kb04PrevObjFromKeyIterator (tgg00_TransContext &Trans,
                            void               *pUntypedKeyIterator,    
                            bool                bInclusive,  
                            tsp00_Int4          KeyLen,      
                            tsp00_Int4          objBodySize,
                            void               *pRestartKey, 
                            tsp00_Int4         &noOfOid,
                            tgg92_KernelOid    *pResultOId, 
                            tgg91_PageRef      *pObjVers,
                            tsp00_Int4         &LogReadAccesses,
                            tsp00_MoveObj      *pObjBody)
{ 
    ROUTINE_DBG_MEO00 ("kb04PrevObjConsistent");
    
    const tgg00_MessType_Enum	ThisMessType  = m_get_object;
    const tgg00_MessType2_Enum	ThisMessType2 = mm_qual;
    const bool                  WriteVtrace   = (cgg04_is_true == g01vtrace.vtrOmsGet_gg00);

    kb04_EnterKb (Trans, ThisMessType, ThisMessType2, WriteVtrace, ! BEGIN_SUBTRANS_SET);
    if (e_ok != Trans.trError_gg00) return;
    
    bd04PrevObjFromKeyIterator (Trans, pUntypedKeyIterator, bInclusive, KeyLen, objBodySize,
                                pRestartKey, noOfOid, pResultOId, pObjVers, LogReadAccesses,
                                pObjBody);

    /* PTS 1119480
#   if COMPILEMODE_MEO00 >= SLOW_MEO00
    if (e_ok == Trans.trError_gg00) t01moveobj (kb, pExtObjBody, 1, ResultObjBodySize);
#   endif   
    */
    
    kb04_ErrorHandling (Trans, ThisMessType, WriteVtrace, ! BEGIN_SUBTRANS_SET); 
}

/*---------------------------------------------------------------------------*/

externCpp void
kb04StartConsistentTrans (tgg00_TransContext &Trans)
{ 
    ROUTINE_DBG_MEO00 ("kb04StartConsistentTrans");
    
    const tgg00_MessType_Enum	ThisMessType  = m_begin;
    const tgg00_MessType2_Enum	ThisMessType2 = mm_trans;
    const bool                  WriteVtrace   = (cgg04_is_true == g01vtrace.vtrOmsGet_gg00);
    
    kb04_EnterKb (Trans, ThisMessType, ThisMessType2, WriteVtrace, ! BEGIN_SUBTRANS_SET);
    if (e_ok != Trans.trError_gg00) return;
    
    kb51StartConsistTrans (Trans);
    kb04_ErrorHandling (Trans, ThisMessType, WriteVtrace, ! BEGIN_SUBTRANS_SET); 
}


/*----------------------------------------------------------------------------*/

externCpp void
kb04UnlockObj (tgg00_TransContext   &Trans,
               tgg00_FileId         &ObjFile,	   
               tgg92_KernelOid       Oid)
{ 
    ROUTINE_DBG_MEO00 ("kb04UnlockObj");
    
    const tgg00_MessType_Enum	ThisMessType  = m_unlock;
    const tgg00_MessType2_Enum	ThisMessType2 = mm_object;
    const bool                  WriteVtrace   = (cgg04_is_true == g01vtrace.vtrOmsUpd_gg00);
    
    kb04_EnterKb (Trans, ThisMessType, ThisMessType2, WriteVtrace, ! BEGIN_SUBTRANS_SET);
    if (e_ok != Trans.trError_gg00) return;
    
    bd04UnlockObj (Trans, ObjFile, Oid);
    kb04_ErrorHandling (Trans, ThisMessType, WriteVtrace, ! BEGIN_SUBTRANS_SET); 
}

/*----------------------------------------------------------------------------*/

externCpp void
kb04UpdateObj (tgg00_TransContext	&Trans,
               tgg00_FileId			  &ObjFile,
               tgg92_KernelOid  	 Oid,
               tgg91_PageRef    	&ObjVers,
               tsp00_Int4			     NewBodySize,
               void			          *pNewBody)
               //tgg00_ObjColDesc		&ColDesc  // PTS !"§$
{ 
    ROUTINE_DBG_MEO00 ("kb04UpdateObj");
    
    const tgg00_MessType_Enum	ThisMessType  = m_update;
    const tgg00_MessType2_Enum	ThisMessType2 = mm_object;
    const bool                  WriteVtrace   = (cgg04_is_true == g01vtrace.vtrOmsUpd_gg00);
    
    kb04_EnterKb (Trans, ThisMessType, ThisMessType2, WriteVtrace, BEGIN_SUBTRANS_SET);
    if (e_ok != Trans.trError_gg00) return; // timeout !
    
    tgg91_PageRef PrevObjVers = ObjVers;
    
    bd04UpdateObj (Trans, ObjFile, Oid, ObjVers, NewBodySize, pNewBody);
    
    if (e_ok == Trans.trError_gg00)
    {
        // PTS 1117603 UH 2002-09-12 written shorter
        Log_Transaction &logtrans      = *(reinterpret_cast<Log_Transaction*>(Trans.trLogContext_gg00));
        Log_AfterImage   AfterImage (Log_UpdateObject);
        Log_ActionObject Action;

        Action.InitInsUpd (Log_UpdateObject,
                           ObjFile, Oid, PrevObjVers,
                           0, NewBodySize, REINTERPRET_CAST(SAPDB_Byte*,pNewBody));

        Trans.trError_gg00 =
            kb560ConvertWriteRedoEntryResultToBasisError
                ( logtrans.WriteRedoEntry (AfterImage, Action) );
    }
    kb04_ErrorHandling (Trans, ThisMessType, WriteVtrace, BEGIN_SUBTRANS_SET); 
}
