#ifndef SQLMAN_CONTEXT_HPP
#define SQLMAN_CONTEXT_HPP

/*!
  @file           SQLMan_Context.hpp
  @author         ThomasA
  @brief          defines SQL manager context.

\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
*/


#include "vak001.h" 
#include "SQLManager/SQLMan_Types.hpp"
#include "SAPDBCommon/MemoryManagement/SAPDBMem_RawAllocator.hpp"
// #include "SQLManager/SQLMan_ContextSessionMembers.hpp"

class SQLMan_ContextSessionMembers;
class DBProc_Debugger;
class SharedSQL_SQLCache;
class Catalog_ISessionCache;
class SQLMan_MessBlock;
class SQLMan_SessionInfo;
class SysView_PseudoLongHandler;

/*!
  @class          SQLMan_Context
  @brief          implements a capsule for the pascal type tak_all_command_glob
 */
class SQLMan_Context : public tak_all_command_glob
{
public :
   /*!
      @brief constructor, create a context
    */
      SQLMan_Context(SQLMan_TransContext&);
   /*!
      @brief destructor, destructs c++ members
    */
      ~SQLMan_Context();
   /*!
      @brief returns the clients integer swap
    */
    inline tsp00_SwapKind_Param ClientSwap() const;
   /*!
      brief destroys c++ members ot the context
    */
    void DestroyCppMembers();
   /*!
      brief returns the current sql command identification
    */
    inline SAPDB_Int4 GetCurrentCommandId() const;
   /*!
      brief returns the session info object
    */
    SQLMan_SessionInfo& GetSessionInfo();
   /*!
      @brief initialises the c++ members of the context 
    */
    void InitCppMembers();
   /*!
      @brief  quick check of current error code
      @return true, if error code = 0; otherwise false
    */
    inline bool IsOk() const;
   /*!
      @brief returns the current SQLMan_Context
    */
    static SQLMan_Context* GetContext();
   /*!
      @brief  returns the session allocator
      @return a reference to the session allocator
    */
    inline SAPDBMem_RawAllocator& GetAllocator() const;
    /*!
       @brief returns registered db-procedure debug context
     */
    DBProc_Debugger* GetDBProcDebugger() const;
    /*!
       @brief returns a reference to the sessions error list
     */
    SAPDBErr_MessageList& GetErrorList() const;

    /*!
       @brief returns if sessionons error list is empty
     */
    bool IsErrorListEmpty() const;
    /*!
       @brief resets the sessions error list
     */
    void ResetErrorList();
    /*!
       @brief returns a reference to the sessions catalog cache
     */
     Catalog_ISessionCache& GetSessionCatalogCache();
    /*!
       @brief returns a reference to the sessions SharedSQL_SQLCache
     */
    SharedSQL_SQLCache& GetSharedSQL_SQLCache();
   /*!
      @brief returns the task identification 
    */
    inline RTE_TaskId GetTaskId() const;
   /*!
      @brief tells whether a given statement is still active, i.e. has been started but not yet finished
      @param statementId identification of the inquired statement
    */
    bool IsStatementActive(SAPDB_Int statementId) const;
   /*!
      @brief returns a reference to the context mess block
    */
    inline SQLMan_MessBlock& GetMessBlock();
   /*!
      @brief returns a reference to the pseudo long handler, which handles long columns of system views.
    */
    SysView_PseudoLongHandler& GetPseudoLongHandler() const;
   /*!
      @brief  returns a pointer to the current return part
      @return pointer to the current return part
    */
    inline tsp1_part * GetCurrentReturnPartPtr();
   /*!
      @brief  returns a pointer to the statement specific part of the context
      @return pointer to the statement specific part
    */
    inline void* GetStatementPartPtr();
   /*!
      @brief          returns the sizeof the statement specific part of the context
      @return         pointer to the statement specific part
    */
    inline int GetStatementPartSize() const;
   /*!
      @brief increments the syntax tree, i.e. provides new nodes to be used by the parser
    */
   void IncrementSyntaxTree();
   /*!
      @brief           creates a new syntax tree
      @param size [in] initial number of tree nodes
      @return          none
    */
    void  NewSyntaxTree(int size);
    /*!
      @brief  registers the current statement in the active statement directory
      @return the statement identification of the current statement, -1 if the statement couldn't be registered due to lack of memory.
    */
    SAPDB_Int4 RegisterCurrentStatement();
    /*!
       @brief releases the shared DDL lock hold by the current context.
     */
    void ReleaseDDLLock();
    /*!
       @brief requires a shared DDL lock for the current context. This lock is managed
              by the catalog and is requested whenever a task parses again due to -8 or -9.
     */
    void RequireDDLLock();
    /*!
      @brief unregisters the given statement from the active statement directory
    */
    void UnregisterStatement(SAPDB_Int4 statementId);
    /*!
      @brief resets the current error code (a_returncode) to 0;
    */
    inline void ResetReturnCode();
    /*!
       @brief          restores a message block saved by SaveMessBlock
       @param pmessblock [in] a pointer to the saved message block. This must be the 
                              result of a previous  SaveMessBlock call
       @return         none
     */
    void  RestoreMessBlock(void* pMessBlock);
    /*!
       @brief          returns the current sql error code
       @return         the current sql error code
     */
    inline int ReturnCode() const;
    /*!
       @brief          stores the current message block in the heap
       @return         a pointer to the saved message block, null in case 
                       of insufficient memory
     */
    void* SaveMessBlock();
    /*!
       @brief          sets the InDDLTrigger property
       @return         none
     */
    inline void SetInDDLTrigger();
    /*!
       @brief sets the member a_createSharedSQL dependent on the parameter SHAREDSQL 
     */
    void SetSharedSQL();
    /*!
       @brief returns a user defined error to the application. This is normnaly done
              from a db-procedure call. 
       @param rc [in] the error code to be returned
       @param msg [in] a pointer to the error text. The text must start with the
              correct defined byte (ascii blank or unicode defined byte)
       @param msgLength [in] the length of the message in characters (not bytes)
     */
    void SetStopMsg (SAPDB_Int2 rc,
                     const void* msg,
                     int         msgLength);
   /*!
      @brief          sets the InSession property
      @return         none
    */
    inline bool SetInSession(bool);
    /*!
       @brief sets the internal connection property. This is set to true, before the
              interface runtime is requested to create a connection.
     */
    inline void SetInternalConnection(bool isInternal);
    /*!
       @brief registers a dbproc debugger 
     */
    void  SetDBProcDebugger(DBProc_Debugger*);
    /*!
       @brief stores a no more memory error
     */
    void  SetNoMoreMemoryError();
    /*!
       @brief sets the current in sql packet
     */
    inline void SetPacket(tsp1_packet_ptr pPacket);
    /*!
       @brief sets the sessions sqlmode
     */
    inline void SetSessionSqlMode(tsp00_SqlMode_Enum sqlMode);
  /*!
     @brief returns the current transaction context contained in SQLMan_Context
  */
  inline SQLMan_TransContext& TransContext();
  /*!
    @brief translates an basis error into an sql code and stores it in context
   */
   void ThrowError (SAPDB_Int2 error, int errorPos = 1);
   /*!
      @brief          cast from acv to SQLMan_context
      @acv [in]       a reference to the acv
      @return         reference to context
    */
    inline static SQLMan_Context& AcvToContext(tak_all_command_glob& acv);
private :
    SQLMan_ContextSessionMembers& CppMembers();                  //!< returns the c++ members of the context
    const SQLMan_ContextSessionMembers& CppMembersConst() const; //!< returns the c++ members of the context
};

//inline SQLMan_ContextSessionMembers& SQLMan_Context::CppMembers()
//{
//    return *REINTERPRET_CAST(SQLMan_ContextSessionMembers*, a_cpp_session_members);
//}
//
//inline const SQLMan_ContextSessionMembers& SQLMan_Context::CppMembersConst() const
//{
//    return *REINTERPRET_CAST(const SQLMan_ContextSessionMembers*, a_cpp_session_members);
//}

inline tsp00_SwapKind_Param SQLMan_Context::ClientSwap() const
{
    return a_out_packet->sp1_header.sp1h_mess_swap;
}

inline SAPDB_Int4 SQLMan_Context::GetCurrentCommandId() const
{
    return a_command_count;
}

inline bool SQLMan_Context::IsOk() const
{
    return (0 == a_returncode);
}

inline SAPDBMem_RawAllocator& SQLMan_Context::GetAllocator() const
{
    return *REINTERPRET_CAST(SAPDBMem_RawAllocator*, a_transinf.tri_trans.trAllocator_gg00);
}

//inline bool SQLMan_Context::IsStatementActive(SAPDB_Int statementId) const
//{
//    return CppMembersConst().m_activeStatementDirectory.IsActive(statementId);
//}

inline SQLMan_MessBlock& SQLMan_Context::GetMessBlock() 
{
    return *REINTERPRET_CAST(SQLMan_MessBlock*, &a_mblock);
}

inline tsp1_part * SQLMan_Context::GetCurrentReturnPartPtr()
{
	return a_curr_retpart;
}

inline void* SQLMan_Context::GetStatementPartPtr() 
{
    return this;
}

inline int SQLMan_Context::GetStatementPartSize() const
{
    int partSize = (char*) &a_end_of_statement_part - (char*) this;
    return partSize;
}

inline RTE_TaskId SQLMan_Context::GetTaskId() const
{
    return a_transinf.tri_trans.trTaskId_gg00;
}

inline SQLMan_Context& SQLMan_Context::AcvToContext(tak_all_command_glob& acv)
{
    return *REINTERPRET_CAST(SQLMan_Context*, &acv);
}

//inline SAPDB_Int4 SQLMan_Context::RegisterCurrentStatement()
//{
//    if (CppMembers().m_activeStatementDirectory.RegisterStatement(a_command_count))
//    {
//      return a_command_count;
//    }
//    else
//    {
//        return -1;
//    }
//}

//inline void SQLMan_Context::ReleaseDDLLock()
//{
//    CppMembers().ReleaseDDLLock();
//}
//
//inline void SQLMan_Context::RequireDDLLock()
//{
//    CppMembers().RequireDDLLock();
//}

inline void SQLMan_Context::ResetReturnCode()
{
    a_returncode = 0;
}

inline int SQLMan_Context::ReturnCode() const
{
    return a_returncode;
}

inline bool SQLMan_Context::SetInSession(bool inSession)
{
    bool res = ((pasbool) true == a_in_session);
    a_in_session = inSession;
    return res;
}

inline void SQLMan_Context::SetInternalConnection(bool isInternal)
{
    a_internalConnection = isInternal;
}

inline void SQLMan_Context::SetInDDLTrigger()
{
    a_in_ddl_trigger = true;
}

inline void SQLMan_Context::SetPacket(tsp1_packet_ptr pPacket)
{
    a_in_packet = pPacket;
}

inline void SQLMan_Context::SetSessionSqlMode(tsp00_SqlMode_Enum sqlMode)
{
    a_session_sqlmode.becomes(sqlMode);
}

inline SQLMan_TransContext& SQLMan_Context::TransContext()
{
    return a_transinf.tri_trans;
}

//inline void SQLMan_Context::UnregisterStatement(SAPDB_Int4 statementId)
//{
//    CppMembers().m_activeStatementDirectory.UnregisterStatement(statementId);
//}

#endif
