///////////////////////////////////////////////////////////////////////////////
//                                                         
// CegoProcVar.cc
// --------------
// Cego procedure variable container class
//      
// Design and Implementation by Bjoern Lemke
//     
// (C)opyright 2000-2025 Bjoern Lemke
//
// IMPLEMENTATION MODULE
//
// Class: CegoProcVar
// 
// Description: Data structure description for cego procedure parameters
//
// Status: CLEAN
//
///////////////////////////////////////////////////////////////////////////////

// cego includes
#include "CegoProcVar.h"
#include "CegoDatabaseFormater.h"
#include "CegoTypeConverter.h"

CegoProcVar::CegoProcVar()
{
}

CegoProcVar::CegoProcVar(const Chain& name)
{
    _name = name;
}

CegoProcVar::CegoProcVar(const Chain& name, CegoProcVar::VarType paramType, CegoDataType dt, unsigned dtlen, unsigned dtdim, const CegoFieldValue& fv)
{
    _name = name;
    _paramType = paramType;
    _dt = dt;
    _dtlen = dtlen;
    _dtdim = dtdim;
    _fv = fv;
}

CegoProcVar::~CegoProcVar()
{
}
    
void CegoProcVar::setName(const Chain& name)
{
    _name = name;
}
 
const Chain& CegoProcVar::getName() const
{
    return _name;
}
    
void CegoProcVar::setVarType(CegoProcVar::VarType paramType)
{
    _paramType = paramType;
}

CegoProcVar::VarType CegoProcVar::getVarType() const
{
    return _paramType;
}

CegoDataType CegoProcVar::getType() const
{
    return _dt;
}

unsigned CegoProcVar::getLength() const
{
    return _dtlen;
}

unsigned CegoProcVar::getDim() const
{
    return _dtdim;
}

void CegoProcVar::setValue(const CegoFieldValue& fv)
{
    _fv = fv;

    // just if datatype for param has setup, we have to cast
    if ( _dt != NULL_TYPE )
    {
	if ( _fv.castTo(_dt, _dtdim) == false )
	{
	    throw Exception(EXLOC, "Cannot cast parameter value from type "
			    + CegoTypeConverter::getTypeString( fv.getType())
			    + " to "
			    + CegoTypeConverter::getTypeString( _dt));
	}
    }
}

const CegoFieldValue& CegoProcVar::getValue() const
{
    return _fv;
}

CegoProcVar& CegoProcVar::operator = ( const CegoProcVar& pp)
{
    _name = pp._name;
    _paramType = pp._paramType;
    _dt = pp._dt;
    _dtlen = pp._dtlen;
    _dtdim = pp._dtdim;
    _fv = pp._fv;
    return (*this);
}

bool CegoProcVar::operator == ( const CegoProcVar& pp)
{
    if ( _name == pp._name )
	return true;
    return false;
}

Chain CegoProcVar::toChain() const
{
    Chain s;
    s = _name;
    if ( _paramType == INVAR )
    {
	s += Chain(" in" );
    }
    else if ( _paramType == OUTVAR )
    {
	s += Chain(" out" );
    }
    switch ( _dt )
    {
    case INT_TYPE:
    {
	s += Chain(" int");
	break;
    }
    case LONG_TYPE:
    {
	s += Chain(" long");
	break;
    }
    case DATETIME_TYPE:
    {
	s += Chain(" datetime");
	break;
    }
    case VARCHAR_TYPE:
    {
	s += Chain(" string(");
	s += Chain(_dtlen);
	s += Chain(")");
	break;
    }
    case DECIMAL_TYPE:
    {
	s += Chain(" decimal(");
	s += Chain(_dtlen) + Chain(",") + Chain(_dtdim);
	s += Chain(")");
	break;
    }
    case BIGINT_TYPE:
    {
	s += Chain(" bigint(");
	s += Chain(_dtlen);
	s += Chain(")");
	break;
    }
    case FLOAT_TYPE:
    {
	s += Chain(" float");
	break;
    }
    case DOUBLE_TYPE:
    {
	s += Chain(" double");
	break;
    }
    case SMALLINT_TYPE:
    {
	s += Chain(" smallint");
	break;
    }
    case TINYINT_TYPE:
    {
	s += Chain(" tinyint");
	break;
    }
    case BOOL_TYPE:
    {
	s += Chain(" bool");
	break;
    }
    case NULL_TYPE:
    {
	s += Chain(" null");
	break;
    }
    case BLOB_TYPE:
    {
	s += Chain(" blob");
	break;
    }
    case CLOB_TYPE:
    {
	s += Chain(" clob");
	break;
    }
    case PAGEID_TYPE:
	break;
    }
    return s;
}

Chain CegoProcVar::dbFormat(CegoDatabaseFormater *pForm) const
{
    return pForm->formatProcVar(_name, _paramType, _dt, _dtlen, _dtdim);
}

ostream& operator << (ostream& s, const CegoProcVar& pp)
{    
    s <<  pp._name;
    return s;
}
