blob: dc2f3ff774341b88502f8fec339d33707c41d3e9 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// ----------------------------------------------------------------------------
//
// File: KO_DTYPE.CPP
//
// Purpose: Contains functions related to data types as per ODBC.
// For defining the type of data ODBC uses three params
// Concise Type, Verbose Type and DateTime Interval.
// All of these r intertwined, setting one of these
// influences the other two.
//
// These r stored inside the descriptors and accessed via
// descriptor functions defined in KO_DESC.CPP. These
// functions in turn call the _SQLSetDataType function
// from this file.
//
// _SQLCheckDataType is to check if the data type recd. from
// the server is valid or not.
//
// GetIRDDataTypeDefaults is used to get the default values
// for a data type. The string data type like CHAR, VARCHAR
// is passed to this function and the default length, precision
// nullability is obtained. This is then overriden by the caller
// with the specific values recd. from the server
//
// ----------------------------------------------------------------------------
#include "stdafx.h"
// ---------------------- function prototypes --------------------------
eGoodBad _SQLCheckDataType ( Word pDataType );
eGoodBad _SQLCheckIntervalCode ( Word pIntervalCode );
eGoodBad _SQLSetDataType ( pODBCDiag pDiag, Word pFldID, Word pFldValue, Word* pVerboseDataType,
Word* pConciseDataType, Word* pDateTimeIntervalCode );
eGoodBad GetIRDDataTypeDefaults ( CStrPtr pDataType, Word* pSqlDataType, Word* pNativeDataType,
Word* pPrecision, Word* pScale, Long* pLength, Long* pRadix );
// -----------------------------------------------------------------------
// to check if the specified type is a valid SQL data type
// -----------------------------------------------------------------------
eGoodBad _SQLCheckDataType ( Word pDataType )
{
switch ( pDataType )
{
case SQL_CHAR :
case SQL_VARCHAR :
case SQL_WCHAR :
case SQL_WVARCHAR :
case SQL_C_SSHORT :
case SQL_C_USHORT :
case SQL_SMALLINT :
case SQL_C_SLONG :
case SQL_C_ULONG :
case SQL_INTEGER :
case SQL_NUMERIC :
case SQL_DECIMAL :
case SQL_FLOAT :
case SQL_REAL :
case SQL_DOUBLE :
case SQL_TYPE_DATE :
case SQL_TYPE_TIME :
case SQL_TYPE_TIMESTAMP :
case SQL_BIT :
case SQL_DEFAULT :
case SQL_BIGINT :
case SQL_C_SBIGINT :
case SQL_C_UBIGINT :
case SQL_C_TINYINT :
case SQL_C_STINYINT :
case SQL_C_UTINYINT :
return GOOD;
default :
__ODBCPOPMSG ( _ODBCPopMsg ( "_SQLCheckDataType: Unknown data type: %d", pDataType ) );
return BAD;
}
}
// -----------------------------------------------------------------------
// to check if the specified type is a valid interval code
// -----------------------------------------------------------------------
eGoodBad _SQLCheckIntervalCode ( Word pIntervalCode )
{
// can check the interval code
return GOOD;
}
// -----------------------------------------------------------------------
// to set the value of data type and interval codes in descriptors
// -----------------------------------------------------------------------
eGoodBad _SQLSetDataType ( pODBCDiag pDiag, Word pFldID, Word pFldValue, Word* pVerboseDataType,
Word* pConciseDataType, Word* pDateTimeIntervalCode )
{
__ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "_SQLSetDataType is called, pFldID:%d, pFldValue:%d", pFldID, pFldValue ) );
// note
// the data type, concise data type, datetime interval code r interdependent
// setting one of these changes the other.
Word concise_type;
Word verbose_type;
Word datetime_interval;
// initial values
concise_type = pConciseDataType ? *pConciseDataType : 0;
verbose_type = pVerboseDataType ? *pVerboseDataType : 0;
datetime_interval = pDateTimeIntervalCode ? *pDateTimeIntervalCode : 0;
// check if concise type has been specified
if ( pFldID == SQL_DESC_CONCISE_TYPE )
{
// set the concise type itself first
concise_type = pFldValue;
// based on concise type set the verbose type and datetime interval
switch ( concise_type )
{
case SQL_TYPE_DATE :
//case SQL_C_TYPE_DATE:
verbose_type = SQL_DATETIME;
datetime_interval = SQL_CODE_DATE;
break;
case SQL_TYPE_TIME :
//case SQL_C_TYPE_TIME:
verbose_type = SQL_DATETIME;
datetime_interval = SQL_CODE_TIME;
break;
case SQL_TYPE_TIMESTAMP :
//case SQL_C_TYPE_TIMESTAMP:
verbose_type = SQL_DATETIME;
datetime_interval = SQL_CODE_TIMESTAMP;
break;
case SQL_INTERVAL_MONTH :
//case SQL_C_INTERVAL_MONTH:
verbose_type = SQL_INTERVAL;
datetime_interval = SQL_CODE_MONTH;
break;
case SQL_INTERVAL_YEAR :
//case SQL_C_INTERVAL_YEAR:
verbose_type = SQL_INTERVAL;
datetime_interval = SQL_CODE_YEAR;
break;
case SQL_INTERVAL_YEAR_TO_MONTH :
//case SQL_C_INTERVAL_YEAR_TO_MONTH:
verbose_type = SQL_INTERVAL;
datetime_interval = SQL_CODE_YEAR_TO_MONTH;
break;
case SQL_INTERVAL_DAY :
//case SQL_C_INTERVAL_DAY:
verbose_type = SQL_INTERVAL;
datetime_interval = SQL_CODE_DAY;
break;
case SQL_INTERVAL_HOUR :
//case SQL_C_INTERVAL_HOUR:
verbose_type = SQL_INTERVAL;
datetime_interval = SQL_CODE_HOUR;
break;
case SQL_INTERVAL_MINUTE :
//case SQL_C_INTERVAL_MINUTE:
verbose_type = SQL_INTERVAL;
datetime_interval = SQL_CODE_MINUTE;
break;
case SQL_INTERVAL_SECOND :
//case SQL_C_INTERVAL_SECOND:
verbose_type = SQL_INTERVAL;
datetime_interval = SQL_CODE_SECOND;
break;
case SQL_INTERVAL_DAY_TO_HOUR :
//case SQL_C_INTERVAL_DAY_TOHOUR:
verbose_type = SQL_INTERVAL;
datetime_interval = SQL_CODE_DAY_TO_HOUR;
break;
case SQL_INTERVAL_DAY_TO_MINUTE :
//case SQL_C_INTERVAL_DAY_TO_MINUTE:
verbose_type = SQL_INTERVAL;
datetime_interval = SQL_CODE_DAY_TO_MINUTE;
break;
case SQL_INTERVAL_DAY_TO_SECOND :
//case SQL_C_INTERVAL_DAY_TO_SECOND:
verbose_type = SQL_INTERVAL;
datetime_interval = SQL_CODE_DAY_TO_SECOND;
break;
case SQL_INTERVAL_HOUR_TO_MINUTE :
//case SQL_C_INTERVAL_HOUR_TO_MINUTE:
verbose_type = SQL_INTERVAL;
datetime_interval = SQL_CODE_HOUR_TO_MINUTE;
break;
case SQL_INTERVAL_HOUR_TO_SECOND :
//case SQL_C_INTERVAL_HOUR_TO_SECOND:
verbose_type = SQL_INTERVAL;
datetime_interval = SQL_CODE_HOUR_TO_SECOND;
break;
case SQL_INTERVAL_MINUTE_TO_SECOND :
//case SQL_C_INTERVAL_MINUTE_TO_SECOND:
verbose_type = SQL_INTERVAL;
datetime_interval = SQL_CODE_MINUTE_TO_SECOND;
break;
default :
// check if data type if valid
if ( _SQLCheckDataType ( concise_type ) != GOOD )
{
return BAD;
}
// concise type does not relate to datetime or interval
// hence both concise and verbose type r equal
verbose_type = concise_type;
datetime_interval = 0;
}
}
// check if verbose data type is being set
else if ( pFldID == SQL_DESC_TYPE )
{
// set the verbose type itself first
verbose_type = pFldValue;
// based on verbose type & datetime interval code determine concise type
switch ( verbose_type )
{
case SQL_INTERVAL :
switch ( datetime_interval )
{
case SQL_CODE_DATE :
concise_type = SQL_TYPE_DATE;
break;
case SQL_CODE_TIME :
concise_type = SQL_TYPE_TIME;
break;
case SQL_CODE_TIMESTAMP :
concise_type = SQL_TYPE_TIMESTAMP;
break;
default :
// interval should have been set
__ODBCPOPMSG ( _ODBCPopMsg ( "_SQLSetDataType: Interval code not yet set for SQL_INTERVAL" ) );
return BAD;
}
break;
case SQL_DATETIME :
switch ( datetime_interval )
{
case SQL_CODE_MONTH :
concise_type = SQL_INTERVAL_MONTH;
break;
case SQL_CODE_YEAR :
concise_type = SQL_INTERVAL_YEAR;
break;
case SQL_CODE_YEAR_TO_MONTH :
concise_type = SQL_INTERVAL_YEAR_TO_MONTH;
break;
case SQL_CODE_DAY :
concise_type = SQL_INTERVAL_DAY;
break;
case SQL_CODE_HOUR :
concise_type = SQL_INTERVAL_HOUR;
break;
case SQL_CODE_MINUTE :
concise_type = SQL_INTERVAL_MINUTE;
break;
case SQL_CODE_SECOND :
concise_type = SQL_INTERVAL_SECOND;
break;
case SQL_CODE_DAY_TO_HOUR :
concise_type = SQL_INTERVAL_DAY_TO_HOUR;
break;
case SQL_CODE_DAY_TO_MINUTE :
concise_type = SQL_INTERVAL_DAY_TO_MINUTE;
break;
case SQL_CODE_DAY_TO_SECOND :
concise_type = SQL_INTERVAL_DAY_TO_SECOND;
break;
case SQL_CODE_HOUR_TO_MINUTE :
concise_type = SQL_INTERVAL_HOUR_TO_MINUTE;
break;
case SQL_CODE_HOUR_TO_SECOND :
concise_type = SQL_INTERVAL_HOUR_TO_SECOND;
break;
case SQL_CODE_MINUTE_TO_SECOND :
concise_type = SQL_INTERVAL_MINUTE_TO_SECOND;
break;
default :
// interval should have been set
__ODBCPOPMSG ( _ODBCPopMsg ( "_SQLSetDataType: Interval code not yet set for SQL_DATETIME" ) );
return BAD;
}
break;
default :
// check if data type if valid
if ( _SQLCheckDataType ( verbose_type ) != GOOD )
{
return BAD;
}
// verbose type does not relate to datetime or interval
// hence both concise and verbose type r equal
concise_type = verbose_type;
datetime_interval = 0;
break;
}
}
else if ( pFldID == SQL_DESC_DATETIME_INTERVAL_CODE )
{
// check if date interval code is valid
if ( _SQLCheckIntervalCode ( pFldValue ) != GOOD )
{
return BAD;
}
// set the datetime interval code, autonomously
datetime_interval = pFldValue;
}
// unknown field to set
else
{
__ODBCPOPMSG ( _ODBCPopMsg ( "_SQLSetDataType: Unknown field type" ) );
return BAD;
}
// pass back values to caller
if ( pVerboseDataType )
{
*pVerboseDataType = verbose_type;
}
if ( pConciseDataType )
{
*pConciseDataType = concise_type;
}
if ( pDateTimeIntervalCode )
{
*pDateTimeIntervalCode = datetime_interval;
}
return GOOD;
}
// -----------------------------------------------------------------------
// to get specific detail about a data type
// -----------------------------------------------------------------------
eGoodBad GetIRDDataTypeDefaults ( CStrPtr pDataType, Word* pSqlDataType, Word* pNativeDataType, Word* pPrecision,
Word* pScale, Long* pLength, Long* pRadix )
{
return BAD;
}