/*!
  @file           Catalog_SessionCache.hpp
  @author         ThomasA
  @special area   Catalog
  @brief          Catalog Session Cache
  @see            example.html ...
  @first created  000-03-09  18:21

\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 CATALOG_SESSIONCACHE_HPP
#define CATALOG_SESSIONCACHE_HPP

#include "SQLManager/Catalog/Catalog_Object.hpp"
#include "SQLManager/SQLMan_Types.hpp"
#include "SQLManager/Catalog/Catalog_ISessionCache.hpp"

class SharedSQL_PrepareHandle;
class SharedSQL_SQLCache;
class SQLMan_Context;
class Catalog_MessBlockObject;
class Catalog_DBProcObject;

/*!

  @brief encapsulation of pascal AK cache
*/

class Catalog_SessionCache : public Catalog_ISessionCache
{
public :
    enum { ObjectHeader = mxak_cache_dir_entry };
/*!
@brief iterator over all entries in cache in lru order
    */
    class LruIterator
    {
        friend class Catalog_SessionCache;
    public :
        inline operator bool() const; //!< true if iterator didn't reached the end
        inline void operator++();     //!< steps to next cache entry
        inline tak_cache_dir_ptr operator()() const; //!< returns current entry
        inline Catalog_Object*   GetCatalogObject() const; //!< returns catalog object of current entry
    private :
        LruIterator(SQLMan_Context& context);
        SQLMan_Context&   m_context;  //!< SQLManager session and statement context
        tak_cache_dir_ptr m_curr;     //!< current cache entry
		tak_cache_dir_ptr m_next;     //!< next cache entry
    };

    /*!
    @brief constructor
    */
    Catalog_SessionCache(SQLMan_Context& context);
    /*!
    @brief loads the description of a db-procedure into the session cache
    */
    virtual Catalog_DBProcObject* LoadDBProcObject(const SQLMan_Surrogate& procId);
    /*!
    @brief loads the info description of a db-procedure into the session cache
    */
    virtual Catalog_DBProcInfoObject* LoadDBProcInfoObject(const SQLMan_Surrogate& procId);
    /*!
    @brief loads the file description of a db-procedure into the session cache
    */
    virtual Catalog_DBProcFileObject* LoadDBProcFileObject(const SQLMan_Surrogate& procId);
    /*
    @brief loads the byte code of a stored procedure
    @param context the current sql manager context
    @param procId  the internal name of the procedure
    @return a pointer to the code or NULL if the code does not exist
    */
    virtual Catalog_MessBlockObject* LoadCode(const SQLMan_Surrogate& procId);
    /*!
    @brief  stores the current plan into the shared sql plan cache
	@return returns true if the plan could be stored successfully, otherwise false
    */
    virtual bool StorePlan(SharedSQL_SQLCache&   sharedSQLManager, 
		           SharedSQL_PrepareHandle* handle, 
				   SQLMan_ParseId&           parseId,
                   bool                      prepareFlag);
	/*!
	   @brief destroys a catalog object stored in memory of a given allocator
    */
    static void DestroyPlanObject(SAPDBMem_IRawAllocator& allocator, void* p);
    /*!
       @brief returns the error code of the last operation
     */
    virtual SAPDB_Int2 GetLastError() const;
    /*!
    @brief returns the address of the Catalog_Object contained in the instance
    */
    inline static const Catalog_Object* GetObject(const void* p);

    private :
        /*!
         @brief returns an iterator of cache entries in lru order
         */
        LruIterator Begin() const;
        /*!
        @brief loads a catalog object with given key into session cache
        */
        Catalog_Object* Load (Catalog_Object::Catalog_Key & key);
        /*!
        @brief stores a part (record) of a plan into the shared sql manager
        */
        bool StorePlanObject (
            Catalog_Object&          planObject,
            SAPDBMem_IRawAllocator&  allocator,
            SharedSQL_ParseID&       PID,
            SharedSQL_PrepareHandle* cmdHandle);

        SQLMan_Context& m_context;    //!< sql manager context
        SAPDB_Int2      m_lastError;  //!< last occured error 
};
 
#endif