///////////////////////////////////////////////////////////////////////////////
//                                                         
// CegoTypeConverter.cc
// --------------------
// Cego type converter implementation
//     
// Design and Implementation by Bjoern Lemke
//     
// (C)opyright 2000-2025 Bjoern Lemke
//
// IMPLEMENTATION MODULE
//
// Class: CegoTypeConverter
// 
// Description: Type conversion utility class
//
// Status: CLEAN
//
///////////////////////////////////////////////////////////////////////////////

// base includes
#include <lfcbase/Exception.h>

// cego includes
#include "CegoDefs.h"
#include "CegoTypeConverter.h"
#include "CegoXMLdef.h"

const char *CEGO_TYPE_MAP[] =
{
    "int",
    "long",
    "string",
    "bool",
    "datetime",
    "bigint",
    "float",
    "double",
    "decimal",
    "smallint",
    "tinyint",
    "blob",
    "clob",
    "null"
};

const int CEGO_JAVATYPE_MAP[] =
{
    4,
    2,
    12,
    16,
    93,
    -5,
    6,
    8,
    3,
    5,
    -6,
    2004,
    2005,
    0
};

const char *CEGO_OBJECT_MAP[] =
{
    "system table", 
    "table",
    "primary avl",
    "unique avl",
    "avl",		      
    "view",
    "rbseg",
    "foreign key",
    "procedure",
    "check",
    "join",
    "primary btree",
    "unique btree",
    "btree",
    "trigger",
    "alias",
    "undefined"
};

CegoTypeConverter::CegoTypeConverter()
{
}

CegoTypeConverter::~CegoTypeConverter()
{
}

Chain CegoTypeConverter::getTypeString(CegoDataType type)
{
    switch  ( type ) 
    {
    case INT_TYPE:
	return Chain(XML_INT_VALUE);
    case LONG_TYPE:
	return Chain(XML_LONG_VALUE);
    case VARCHAR_TYPE:
	return Chain(XML_STRING_VALUE);
    case BOOL_TYPE:
	return Chain(XML_BOOL_VALUE);
    case DATETIME_TYPE:
	return Chain(XML_DATETIME_VALUE);
    case BIGINT_TYPE:
	return Chain(XML_BIGINT_VALUE);
    case FLOAT_TYPE:
	return Chain(XML_FLOAT_VALUE);
    case DOUBLE_TYPE:
	return Chain(XML_DOUBLE_VALUE);
    case DECIMAL_TYPE:
	return Chain(XML_DECIMAL_VALUE);
    case SMALLINT_TYPE:
	return Chain(XML_SMALLINT_VALUE);
    case TINYINT_TYPE:
	return Chain(XML_TINYINT_VALUE);
    case BLOB_TYPE:
	return Chain(XML_BLOB_VALUE);
    case CLOB_TYPE:
	return Chain(XML_CLOB_VALUE);
    case NULL_TYPE:
	return Chain(XML_NULL_VALUE);
    case PAGEID_TYPE:
	return Chain(XML_PAGEIDTYPE_VALUE);
    default:
        throw Exception(EXLOC, Chain("Unknown data type"));	
    }
}

unsigned CegoTypeConverter::getTypeLen(CegoDataType type, const Chain& val)
{
    switch  ( type ) 
    {
    case INT_TYPE:
	return sizeof(int);
    case LONG_TYPE:
	return sizeof(long long);
    case BOOL_TYPE:
	return sizeof(char);
    case DATETIME_TYPE:
	return sizeof(unsigned long long);
    case VARCHAR_TYPE:
    case BIGINT_TYPE:
    case DECIMAL_TYPE:
	return val.length();
    case FLOAT_TYPE:
	return sizeof(float);
    case DOUBLE_TYPE:
	return sizeof(double);
    case SMALLINT_TYPE:
	return sizeof(short);
    case TINYINT_TYPE:
	return sizeof(char);
    case BLOB_TYPE:
	return 2 * sizeof(int);
    case CLOB_TYPE:
	return 2 * sizeof(int);
    case NULL_TYPE:
	return 0;
    // just internal use
    case PAGEID_TYPE:
	return sizeof(PageIdType);
    default:
        throw Exception(EXLOC, Chain("Unknown data type"));
    }
}

CegoDataType CegoTypeConverter::getTypeId(const Chain& typeString)
{
    CegoDataType type;
    
    if ( typeString == Chain(XML_STRING_VALUE) )
    {
	type = VARCHAR_TYPE;	
    } 
    else if ( typeString == Chain(XML_INT_VALUE) )
    {		
	type = INT_TYPE;
    }
    else if ( typeString == Chain(XML_LONG_VALUE) )
    {		
	type = LONG_TYPE;
    }
    else if ( typeString == Chain(XML_BOOL_VALUE) )
    {
	type = BOOL_TYPE;
    }
    else if ( typeString == Chain(XML_DATETIME_VALUE) )
    {
	type = DATETIME_TYPE;
    }
    else if ( typeString == Chain(XML_DECIMAL_VALUE) )
    {
	type = DECIMAL_TYPE;
    }
    else if ( typeString == Chain(XML_BIGINT_VALUE) )
    {
	type = BIGINT_TYPE;
    }
    else if ( typeString == Chain(XML_SMALLINT_VALUE) )
    {
	type = SMALLINT_TYPE;
    }
    else if ( typeString == Chain(XML_TINYINT_VALUE) )
    {
	type = TINYINT_TYPE;
    }
    else if ( typeString == Chain(XML_FLOAT_VALUE) )
    {
	type = FLOAT_TYPE;
    }
    else if ( typeString == Chain(XML_DOUBLE_VALUE) )
    {
	type = DOUBLE_TYPE;
    }
    else if ( typeString == Chain(XML_BLOB_VALUE) )
    {
	type = BLOB_TYPE;
    }
    else if ( typeString == Chain(XML_CLOB_VALUE) )
    {
	type = CLOB_TYPE;
    }
    else
    {
	throw Exception(EXLOC, Chain("Unknown type string ") + typeString);
    }
    return type;
}

Chain CegoTypeConverter::getObjectTypeString(CegoObject::ObjectType type)
{    
    switch ( type )
    {
    case CegoObject::SYSTEM:
	return Chain(XML_SYSOBJ_VALUE);
    case CegoObject::TABLE:
	return Chain(XML_TABOBJ_VALUE);
    case CegoObject::PAVLTREE:
	return Chain(XML_PIXOBJ_VALUE);
    case CegoObject::UAVLTREE:
	return Chain(XML_UIXOBJ_VALUE);
    case CegoObject::AVLTREE:
      return Chain(XML_IDXOBJ_VALUE);
    case CegoObject::PBTREE:
	return Chain(XML_PBTREEOBJ_VALUE);
    case CegoObject::UBTREE:
	return Chain(XML_UBTREEOBJ_VALUE);
    case CegoObject::BTREE:
      return Chain(XML_BTREEOBJ_VALUE);
    case CegoObject::VIEW:
	return Chain(XML_VIEWOBJ_VALUE);
    case CegoObject::RBSEG:
	return Chain(XML_RBSEGOBJ_VALUE);
    case CegoObject::FKEY:
	return Chain(XML_FKEYOBJ_VALUE);
    case CegoObject::PROCEDURE:
	return Chain(XML_PROCOBJ_VALUE);
    case CegoObject::TRIGGER:
	return Chain(XML_TRIGGEROBJ_VALUE);
    case CegoObject::ALIAS:
	return Chain(XML_ALIASOBJ_VALUE);
    case CegoObject::CHECK:
	return Chain(XML_CHECKOBJ_VALUE);
    default:
    // case CegoObject::JOIN:
    // case CegoObject::UNDEFINED:	
	throw Exception(EXLOC, "Invalid type id");
    }
}

CegoObject::ObjectType CegoTypeConverter::getObjectTypeId(const Chain& typeString)
{
    if ( typeString == Chain(XML_SYSOBJ_VALUE) )
	return CegoObject::SYSTEM;
    if ( typeString == Chain(XML_TABOBJ_VALUE) )
	return CegoObject::TABLE;
    if ( typeString == Chain(XML_PIXOBJ_VALUE) )
	return CegoObject::PAVLTREE;
    if ( typeString == Chain(XML_UIXOBJ_VALUE) )
	return CegoObject::UAVLTREE;
    if ( typeString == Chain(XML_IDXOBJ_VALUE) )
	return CegoObject::AVLTREE;
    if ( typeString == Chain(XML_PBTREEOBJ_VALUE) )
	return CegoObject::PBTREE;
    if ( typeString == Chain(XML_UBTREEOBJ_VALUE) )
	return CegoObject::UBTREE;
    if ( typeString == Chain(XML_BTREEOBJ_VALUE) )
      return CegoObject::BTREE;
    if ( typeString == Chain(XML_VIEWOBJ_VALUE) )
	return CegoObject::VIEW;
    if ( typeString == Chain(XML_RBSEGOBJ_VALUE) )
	return CegoObject::RBSEG;
    if ( typeString == Chain(XML_FKEYOBJ_VALUE) )
	return CegoObject::FKEY;
    if ( typeString == Chain(XML_PROCOBJ_VALUE) )
	return CegoObject::PROCEDURE;
    if ( typeString == Chain(XML_TRIGGEROBJ_VALUE) )
	return CegoObject::TRIGGER;    
    if ( typeString == Chain(XML_CHECKOBJ_VALUE) )
	return CegoObject::CHECK;
    if ( typeString == Chain(XML_ALIASOBJ_VALUE) )
	return CegoObject::ALIAS;

    throw Exception(EXLOC, Chain("Unknown object type"));
}
