/*!
  @file   Data_PageAccessManager.hpp
  @author UweH
  @brief  The one and only page access manager in the kernel. (c++ interface to c and pascal coding)

\if EMIT_LICENCE

    ========== 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



\endif
*/
#ifndef DATA_PAGE_ACCESS_MANAGER_HPP
#define DATA_PAGE_ACCESS_MANAGER_HPP

#include "ggg00.h" // tgg00_TransContext
#include "gbd00.h" // tbd_current_tree
#include "DataAccess/Data_FileTypes.hpp"
#include "DataAccess/Data_BasePage.hpp"
#include "Converter/Converter_IPageNoManager.hpp"
#include "Converter/Converter_IVerify.hpp"
/*!
    @class   Data_PageAccessManager
    @brief   encapsulates the page access manager (Data_Cache)
 */
class Data_PageAccessManager
{
public:
    /*!
       @brief This initializes a context to access pages of a special type.
       @param TransContext [in/out] 
       @param FileType [in] 
       @param RecoveryMode [in] 
       @param RootPageNo [in] 
     */
    Data_PageAccessManager (tgg00_TransContext&             TransContext,
                            const Data_FileType             FileType,
                            const Data_PageRecoveryMode&    RecoveryMode,
                            const Data_PageNo               RootPageNo);
    
    /*!
       @brief This initializes a context to access pages for a given file
       @param current [in/out] 
     */
    Data_PageAccessManager ( tbd_current_tree   &current )
    :m_Current( current )
    {}
    
    /*!
       @brief This initializes a context for and uses some internals from the given pam
       @param current [in/out] 
     */
    Data_PageAccessManager (Data_PageAccessManager          &Pam,
                            const Data_FileType             FileType,
                            const Data_PageRecoveryMode&    RecoveryMode,
                            const Data_PageNo               RootPageNo)
    {
        *this = Data_PageAccessManager ( *(Pam.m_Current.curr_trans), FileType, RecoveryMode, RootPageNo);
    }
    /// ---------------------------------------------------------------------------
    bool GetPage (Data_BasePage               &Page,
                  const Data_PageNo&           PageNo,
                  const Data_PageRecoveryMode &RecoveryMode,
                  Data_AccessMode              AccessMode);
    /// ---------------------------------------------------------------------------
    bool GetPage (Data_BasePage             &Page,
                  const Data_PageNo         &PageNo,
                  Data_AccessMode           AccessMode)
    {
        return GetPage (Page, PageNo, Page.RecoveryMode(), AccessMode);
    }
    /// ---------------------------------------------------------------------------
    bool GetPage (Data_BasePage             &Page,
                  const Data_PageNo           &PageNo)
    {
        return GetPage (Page, PageNo, Page.RecoveryMode(), Page.AccessMode());
    }
    /// ---------------------------------------------------------------------------
    void ReleasePage (Data_BasePage &Page);
    /// ---------------------------------------------------------------------------
    bool CheckSpace (SAPDB_UInt pagecount ) const
    {
        // PTS 1115170 UH 2002-04-09 new
        Converter_IPageNoManager::Instance().HandleDBFull( *(m_Current.curr_trans), pagecount);
        return e_ok == m_Current.curr_trans->trError_gg00;
    }
    /// ---------------------------------------------------------------------------
    void NewPage (Data_BasePage&      Page,
                  Data_PageRecoveryMode Mode = Data_PageRecoveryMode());
    /// ---------------------------------------------------------------------------
    void FreePage (Data_BasePage &Page);
    /// ---------------------------------------------------------------------------
    void FreePageNo (const Data_PageNo&           PageNo,
                     const Data_PageRecoveryMode& RecoveryMode,
                     const SAPDB_Int4             PageConverterVersion);
    /// ---------------------------------------------------------------------------
    void Invalidate()
    {
        m_Current.curr_tree_id.fileRoot_gg00() = NIL_PAGE_NO_GG00;
    }
    /// ---------------------------------------------------------------------------
    bool IsValid() const
    {
        return Data_PageNo(m_Current.curr_tree_id.fileRoot_gg00()).IsValid();
    }
    /// ---------------------------------------------------------------------------
    void MarkPageIdAsUsed (const Data_PageId &pageid)
    {
        // 2003-05-09 UH added
        Converter_IVerify::Instance().MarkPageNoAsUsed ( m_Current.curr_trans->trTaskId_gg00,
                                                         pageid.PageNo(),
                                                         pageid.PageRecoveryMode().GetAddressingMode() );
    }
    /// ---------------------------------------------------------------------------
    SAPDB_Int GetLastError () const
    {
        // 2003-05-09 UH added
        return m_Current.curr_trans->trError_gg00;
    }
    /// ---------------------------------------------------------------------------
    void ResetLastError ()
    {
        // 2003-05-09 UH added
        m_Current.curr_trans->trError_gg00 = e_ok;
    }

    /// writes current file information to the knldiag
    virtual void WriteBadFileInfo();

private:
    /// The Accessmanagers can save themself here,so the page destructor can do a release.
    void RegisterToPage (Data_BasePage&             Page,
                         tbd_node_ptrs&               Nptrs,
                         const Data_PageRecoveryMode& RecoveryMode,
                         Data_AccessMode              AccessMode)
    {
    
        Page.m_pAccessManager = this;
        Page.m_AccessMode     = AccessMode;
        Page.SetRecoveryMode(RecoveryMode);
        Page.SetHint(Nptrs.np_cbptr());
        Page.SetNodePtr(Nptrs.np_ptr());
    
        if ( Data_ForUpdate          == Page.m_AccessMode ||
                Data_ForStructureChange == Page.m_AccessMode )
            Page.m_ReleaseMode = Data_Changed;
        else
            Page.m_ReleaseMode = Data_Unchanged;
    }
    /// this is used by bd13 interface
    tbd_current_tree m_Current;
};
#endif // DATA_PAGE_ACCESS_MANAGER_HPP
