///////////////////////////////////////////////////////////////////////////////
//                                                         
// CegoAlterDesc.cc
// ---------------
// Cego database alter description implementation
//      
// Design and Implementation by Bjoern Lemke
//     
// (C)opyright 2000-2010 Bjoern Lemke
//
// 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, 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; see the file COPYING.  If not, write to
// the Free Software Foundation, 59 Temple Place - Suite 330,
// Boston, MA 02111-1307, USA.
//
// IMPLEMENTATION MODULE
//
// Class: CegoAlterDesc
// 
// Description: 
//
// Status: QG-2.6
//
///////////////////////////////////////////////////////////////////////////////

#include "CegoAlterDesc.h"
#include "CegoXMLdef.h"

#include <stdlib.h>
#include <string.h>

CegoAlterDesc::CegoAlterDesc()
{
}

CegoAlterDesc::CegoAlterDesc(Element *pAlterElement)
{
    fromElement(pAlterElement);
}

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& 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.isNullable() == false )
	    s += Chain(" not null");
	break;
    }
    case CegoAlterDesc::DROP:
    {
	s = Chain("drop column ") + _f.getAttrName();
	break;
    }
    case CegoAlterDesc::MODIFY:
    {
	s = Chain("modify column ") + _f.getAttrName() + Chain(" ") + _f.typeToChain();
	if ( _f.isNullable() == false )
	    s += Chain(" not null");
	break;
    }
    case CegoAlterDesc::RENAME:
    {
	s = Chain("rename ") + _f.getAttrName() + Chain(" to ") +  _attrName;
	break;
    }
    }
    return s;
}

Element* CegoAlterDesc::toElement() const
{

    Element* pAlterElement = new Element(XML_ALTER_ELEMENT);

    switch ( _type )
    {
    case CegoAlterDesc::ADD:
    {
	pAlterElement->setAttribute( XML_TYPE_ATTR, XML_ADD_VALUE ); 
	break;
    }
    case CegoAlterDesc::DROP:
    {
	pAlterElement->setAttribute( XML_TYPE_ATTR, XML_DROP_VALUE ); 
	break;
    }
    case CegoAlterDesc::MODIFY:
    {
	pAlterElement->setAttribute( XML_TYPE_ATTR, XML_MODIFY_VALUE ); 
	break;
    }
    case CegoAlterDesc::RENAME:
    {
	pAlterElement->setAttribute( XML_TYPE_ATTR, XML_RENAME_VALUE ); 
	break;
    }
    }
    pAlterElement->setAttribute( XML_ATTRNAME_ATTR, _attrName ); 
    pAlterElement->addContent( _f.toElement() );
    
    return pAlterElement;
    
}

void CegoAlterDesc::fromElement(Element *pAlterElement)
{
    
    Chain alterTypeString = pAlterElement->getAttributeValue( XML_TYPE_ATTR );
    
    if ( alterTypeString == Chain(XML_ADD_VALUE) )
    {
	_type = CegoAlterDesc::ADD;
    }
    else if ( alterTypeString == Chain(XML_MODIFY_VALUE) )
    {
	_type = CegoAlterDesc::MODIFY;
    }
    else if ( alterTypeString == Chain(XML_DROP_VALUE) )
    {
	_type = CegoAlterDesc::DROP;
    }
    else if ( alterTypeString == Chain(XML_RENAME_VALUE) )
    {
	_type = CegoAlterDesc::RENAME;
    }
    
    ListT<Element*> fl = pAlterElement->getChildren(XML_FIELD_ELEMENT);
    Element **pFE = fl.First();
    if ( pFE )
    {
	_f.fromElement(*pFE);
    }
    _attrName = pAlterElement->getAttributeValue( XML_ATTRNAME_ATTR);    

}

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


