/*!
  @file           IFR_LOB.cpp
  @author         D039759
  @ingroup        
  @brief          
  @see            

\if EMIT_LICENCE
    ========== licence begin  GPL
    Copyright (c) 2001-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 "Interfaces/Runtime/IFR_Common.h"
#include "Interfaces/Runtime/IFR_LOB.h"
#include "Interfaces/Runtime/IFR_LOBHost.h"

//----------------------------------------------------------------------
IFR_LOB::IFR_LOB(IFR_Int2 column, 
                 IFR_Int4 row,
                 IFR_HostType lobhosttype,
                 IFR_ConnectionItem& clink,
                 IFR_Bool input)
:m_column(column),
 m_row(row),
 m_lobhosttype(lobhosttype),
 m_clink(clink),
 m_getvalhost(0),
 m_putvalhost(0),
 m_status(Status_Valid_C)
{
    if(input) {
        m_putvalhost = m_clink.getPutvalHost();
    } else {
        m_getvalhost = m_clink.getGetvalHost();
    }
}

//----------------------------------------------------------------------
IFR_LOB::~IFR_LOB()
{
}

//----------------------------------------------------------------------
IFR_Retcode
IFR_LOB::putData(void *data, IFR_Length* lengthindicator)
{
    DBUG_CONTEXT_METHOD_ENTER(IFR_LOB,putData, &m_clink);
    if(!assertOpen()) {
        DBUG_RETURN(IFR_NOT_OK);
    }
    if(m_putvalhost == 0) {
        m_clink.error().setRuntimeError(IFR_ERR_LOB_READONLY_I, (IFR_Int4)getColumn());
        DBUG_RETURN(IFR_NOT_OK);
    } else {
        DBUG_RETURN(m_putvalhost->putData(this, data, lengthindicator));
    }
}

//----------------------------------------------------------------------
IFR_Retcode
IFR_LOB::getData(void *data,
                 IFR_Length *lengthindicator,
                 IFR_Length bytelength,
                 IFR_Length *posindicator,
                 IFR_Bool    terminate)
{
    DBUG_CONTEXT_METHOD_ENTER(IFR_LOB, getData, &m_clink);
    if(!assertOpen()) {
        DBUG_RETURN(IFR_NOT_OK);
    }
    if(m_getvalhost == 0) {
        m_clink.error().setRuntimeError(IFR_ERR_LOB_WRITEONLY_I, (IFR_Int4)getColumn());
        DBUG_RETURN(IFR_NOT_OK);
    } else {
        DBUG_RETURN(m_getvalhost->getData(this, data, lengthindicator, bytelength, posindicator, terminate));
    }

    DBUG_RETURN(IFR_NOT_OK);
}

//----------------------------------------------------------------------
IFR_Retcode
IFR_LOB::close()
{
    DBUG_CONTEXT_METHOD_ENTER(IFR_LOB, close, &m_clink);
    IFR_Retcode rc = IFR_OK;
    if(m_status == Status_Valid_C) {
        if(m_putvalhost == 0) {
            rc = m_getvalhost->closeLOB(this);
        } else {
            rc = m_putvalhost->closeLOB(this);
        }
    }
    m_status = Status_Closed_C;
    DBUG_RETURN(IFR_OK);
}

//----------------------------------------------------------------------
IFR_Bool
IFR_LOB::assertOpen(void)
{
    switch(m_status) {
    case Status_Valid_C:
        return true;
    case Status_Closed_C:
        m_clink.error().setRuntimeError(IFR_ERR_LOB_CLOSED_I, (IFR_Int4)getColumn());
        return false;
    case Status_NullOrDefault_C:
        m_clink.error().setRuntimeError(IFR_ERR_LOB_NULLDEFAULT_I, (IFR_Int4)getColumn());
        return false;
    case Status_Invalid_C:
        m_clink.error().setRuntimeError(IFR_ERR_LOB_INVALID_I, (IFR_Int4)getColumn());
        return false;
    }
    return false;
}

//----------------------------------------------------------------------
IFR_HostType
IFR_LOB::getDataHostType() const 
{
    switch(m_lobhosttype) {
    case IFR_HOSTTYPE_BLOB:
        return IFR_HOSTTYPE_BINARY;
    case IFR_HOSTTYPE_ASCII_LOB:
        return IFR_HOSTTYPE_ASCII;
    case IFR_HOSTTYPE_UCS2_LOB:
        return IFR_HOSTTYPE_UCS2;
    case IFR_HOSTTYPE_UCS2_SWAPPED_LOB:
        return IFR_HOSTTYPE_UCS2_SWAPPED;
    case IFR_HOSTTYPE_UTF8_LOB:
        return IFR_HOSTTYPE_UTF8;
    default:
        return IFR_HOSTTYPE_PARAMETER_NOTSET;
    }
}

//----------------------------------------------------------------------
void
IFR_LOB::sqlTrace(IFR_TraceStream& s, IFR_LOBData& lobdata)
{
    if(lobdata.lobdata) {
        s << "LOB[column=" << lobdata.lobdata->m_column
          << ", row="
          << lobdata.lobdata->m_row
          << "]";
    } else {
        s << "*** UNINITIALIZED ***";
    }
}
