///////////////////////////////////////////////////////////////////////////////
//                                                         
// CegoAlterDesc.cc
// ---------------
// Cego database alter description implementation
//      
// Design and Implementation by Bjoern Lemke
//     
// (C)opyright 2000-2025 Bjoern Lemke
//
// IMPLEMENTATION MODULE
//
// Class: CegoAlterDesc
// 
// Description: Utility class for table modification statements
//
// Status: CLEAN
//
///////////////////////////////////////////////////////////////////////////////

// CEGO INCLUDES
#include "CegoAlterDesc.h"
#include "CegoXMLdef.h"
#include "CegoDatabaseFormater.h"

// POSIX INCLUDES
#include <stdlib.h>
#include <string.h>

CegoAlterDesc::CegoAlterDesc()
{
}

CegoAlterDesc::CegoAlterDesc(CegoAlterDesc::AlterType type, const CegoField& f)
{
    _f = f;
    _type = type;
}

CegoAlterDesc::CegoAlterDesc(CegoAlterDesc::AlterType type, const Chain& attrName)
{
    _f.setAttrName(attrName);
    _type = type;
}

CegoAlterDesc::CegoAlterDesc(const Chain& attrName)
{
    _f.setAttrName(attrName);
}

CegoAlterDesc::CegoAlterDesc(const Chain& attrName, const CegoFieldValue& defaultValue)
{
    _type = MODIFY_DEFAULT;
    _f.setValue(defaultValue);
    _f.setAttrName(attrName);    
}

CegoAlterDesc::CegoAlterDesc(const Chain& oldAttrName, const Chain& newAttrName)
{
    _type = RENAME;
    _attrName = oldAttrName;
    _f.setAttrName(newAttrName);
}

CegoAlterDesc::~CegoAlterDesc()
{
}

CegoField& CegoAlterDesc::getField()
{
    return _f;
}

const Chain& CegoAlterDesc::getAttrName() const 
{
    return _f.getAttrName();
}

const Chain& CegoAlterDesc::getOldAttrName() const 
{
    return _attrName;
}

CegoAlterDesc::AlterType CegoAlterDesc::getType() const
{
    return _type;
}

CegoAlterDesc& CegoAlterDesc::operator = ( const CegoAlterDesc& ad )
{
    _attrName = ad._attrName;
    _f = ad._f;
    _type = ad._type;
    return (*this);
}

bool CegoAlterDesc::operator == ( const CegoAlterDesc& ad )
{    
    Chain a1 = _f.getAttrName();
    Chain a2 = ad.getAttrName();

    if ( a1 == a2 )
	return true;
    return false;
}

Chain CegoAlterDesc::toChain() const 
{
    Chain s;

    switch ( _type )
    {
    case CegoAlterDesc::ADD:
    {
	s = Chain("add ") + _f.getAttrName() + Chain(" ") + _f.typeToChain();
	if ( _f.getValue().getValue() )
	    s += Chain(" default ") + _f.getValue().valAsChain();
	if ( _f.isNullable() == false )
	    s += Chain(" not null");
	break;
    }
    case CegoAlterDesc::DROP:
    {
	s = Chain("drop column ") + _f.getAttrName();
	break;
    }
    case CegoAlterDesc::MODIFY_COLUMN:
    {
	s = Chain("modify column ") + _f.getAttrName() + Chain(" ") + _f.typeToChain();
	if ( _f.getValue().getValue() )
	    s += Chain(" default ") + _f.getValue().valAsChain();
	if ( _f.isNullable() == false )
	    s += Chain(" not null");
	break;
    }
    case CegoAlterDesc::MODIFY_DEFAULT:
    {
	s = Chain("modify column ") + _f.getAttrName() + Chain(" default ") + _f.getValue().valAsChain();
	break;
    }
    
    case CegoAlterDesc::RENAME:
    {
	s = Chain("rename ") + _f.getAttrName() + Chain(" to ") +  _attrName;
	break;
    }
    }
    return s;
}

Chain CegoAlterDesc::dbFormat(CegoDatabaseFormater *pForm) const
{
    return pForm->formatAlter(_type, _f, _attrName);    
}

ostream& operator << (ostream& s, const CegoAlterDesc& a)
{
    s <<  a.toChain();
    return s;
}
