Kaydet (Commit) 63b6b1d6 authored tarafından Lionel Elie Mamane's avatar Lionel Elie Mamane

make OTools::getValue insanely safe, factorise get{Int,Long,Byte,...}

üst bec18a80
......@@ -170,6 +170,30 @@ sal_Int32 SAL_CALL ODatabaseMetaDataResultSet::findColumn( const ::rtl::OUString
break;
return i;
}
template < typename T, SQLSMALLINT sqlTypeId > T ODatabaseMetaDataResultSet::getInteger ( sal_Int32 columnIndex )
{
checkDisposed(ODatabaseMetaDataResultSet_BASE::rBHelper.bDisposed);
::osl::MutexGuard aGuard( m_aMutex );
columnIndex = mapColumn(columnIndex);
T nVal = 0;
if(columnIndex <= m_nDriverColumnCount)
{
getValue<T>(m_pConnection, m_aStatementHandle, columnIndex, sqlTypeId, m_bWasNull, **this, nVal);
if ( !m_aValueRange.empty() )
{
::std::map<sal_Int32, ::connectivity::TInt2IntMap >::iterator aValueRangeIter (m_aValueRange.find(columnIndex));
if ( aValueRangeIter != m_aValueRange.end() )
return static_cast<T>(aValueRangeIter->second[nVal]);
}
}
else
m_bWasNull = sal_True;
return nVal;
}
// -------------------------------------------------------------------------
Reference< ::com::sun::star::io::XInputStream > SAL_CALL ODatabaseMetaDataResultSet::getBinaryStream( sal_Int32 /*columnIndex*/ ) throw(SQLException, RuntimeException)
{
......@@ -215,24 +239,7 @@ sal_Bool SAL_CALL ODatabaseMetaDataResultSet::getBoolean( sal_Int32 columnIndex
sal_Int8 SAL_CALL ODatabaseMetaDataResultSet::getByte( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
{
checkDisposed(ODatabaseMetaDataResultSet_BASE::rBHelper.bDisposed);
::osl::MutexGuard aGuard( m_aMutex );
columnIndex = mapColumn(columnIndex);
sal_Int8 nVal = 0;
if(columnIndex <= m_nDriverColumnCount)
{
OTools::getValue(m_pConnection,m_aStatementHandle,columnIndex,SQL_C_TINYINT,m_bWasNull,**this,&nVal,sizeof nVal);
::std::map<sal_Int32, ::connectivity::TInt2IntMap >::iterator aValueRangeIter;
if ( !m_aValueRange.empty() && (aValueRangeIter = m_aValueRange.find(columnIndex)) != m_aValueRange.end())
return sal_Int8((*aValueRangeIter).second[(sal_Int32)nVal]);
}
else
m_bWasNull = sal_True;
return nVal;
return getInteger<sal_Int8, SQL_C_STINYINT>( columnIndex );
}
// -------------------------------------------------------------------------
......@@ -322,24 +329,7 @@ float SAL_CALL ODatabaseMetaDataResultSet::getFloat( sal_Int32 columnIndex ) thr
sal_Int32 SAL_CALL ODatabaseMetaDataResultSet::getInt( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
{
checkDisposed(ODatabaseMetaDataResultSet_BASE::rBHelper.bDisposed);
::osl::MutexGuard aGuard( m_aMutex );
columnIndex = mapColumn(columnIndex);
sal_Int32 nVal = 0;
if(columnIndex <= m_nDriverColumnCount)
{
OTools::getValue(m_pConnection,m_aStatementHandle,columnIndex,SQL_C_LONG,m_bWasNull,**this,&nVal,sizeof nVal);
::std::map<sal_Int32, ::connectivity::TInt2IntMap >::iterator aValueRangeIter;
if ( !m_aValueRange.empty() && (aValueRangeIter = m_aValueRange.find(columnIndex)) != m_aValueRange.end())
return (*aValueRangeIter).second[(sal_Int32)nVal];
}
else
m_bWasNull = sal_True;
return nVal;
return getInteger<sal_Int32, SQL_C_SLONG>( columnIndex );
}
// -------------------------------------------------------------------------
......@@ -349,10 +339,9 @@ sal_Int32 SAL_CALL ODatabaseMetaDataResultSet::getRow( ) throw(SQLException, Ru
}
// -------------------------------------------------------------------------
sal_Int64 SAL_CALL ODatabaseMetaDataResultSet::getLong( sal_Int32 /*columnIndex*/ ) throw(SQLException, RuntimeException)
sal_Int64 SAL_CALL ODatabaseMetaDataResultSet::getLong( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
{
::dbtools::throwFunctionNotSupportedException( "XRow::getLong", *this );
return 0;
return getInteger<sal_Int64, SQL_C_SBIGINT>( columnIndex );
}
// -------------------------------------------------------------------------
......@@ -398,23 +387,7 @@ Any SAL_CALL ODatabaseMetaDataResultSet::getObject( sal_Int32 /*columnIndex*/, c
sal_Int16 SAL_CALL ODatabaseMetaDataResultSet::getShort( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
{
checkDisposed(ODatabaseMetaDataResultSet_BASE::rBHelper.bDisposed);
::osl::MutexGuard aGuard( m_aMutex );
columnIndex = mapColumn(columnIndex);
sal_Int16 nVal = 0;
if(columnIndex <= m_nDriverColumnCount)
{
OTools::getValue(m_pConnection,m_aStatementHandle,columnIndex,SQL_C_SHORT,m_bWasNull,**this,&nVal,sizeof nVal);
::std::map<sal_Int32, ::connectivity::TInt2IntMap >::iterator aValueRangeIter;
if ( !m_aValueRange.empty() && (aValueRangeIter = m_aValueRange.find(columnIndex)) != m_aValueRange.end())
return sal_Int16((*aValueRangeIter).second[(sal_Int32)nVal]);
}
else
m_bWasNull = sal_True;
return nVal;
return getInteger<sal_Int16, SQL_C_SSHORT>( columnIndex );
}
// -------------------------------------------------------------------------
......
......@@ -45,6 +45,82 @@ using namespace com::sun::star::uno;
using namespace com::sun::star::sdbc;
using namespace com::sun::star::util;
namespace {
size_t sqlTypeLen ( SQLSMALLINT _nType )
{
switch (_nType)
{
case SQL_C_CHAR:
return sizeof(SQLCHAR *);
case SQL_C_WCHAR:
return sizeof(SQLWCHAR *);
case SQL_C_SSHORT:
case SQL_C_SHORT:
return sizeof(SQLSMALLINT);
case SQL_C_USHORT:
return sizeof(SQLUSMALLINT);
case SQL_C_SLONG:
case SQL_C_LONG:
return sizeof(SQLINTEGER);
case SQL_C_ULONG:
return sizeof(SQLUINTEGER);
case SQL_C_FLOAT:
return sizeof(SQLREAL);
case SQL_C_DOUBLE:
OSL_ENSURE(sizeof(SQLDOUBLE) == sizeof(SQLFLOAT), "SQLDOUBLE/SQLFLOAT confusion");
return sizeof(SQLDOUBLE);
case SQL_C_BIT:
return sizeof(SQLCHAR);
case SQL_C_STINYINT:
case SQL_C_TINYINT:
return sizeof(SQLSCHAR);
case SQL_C_UTINYINT:
return sizeof(SQLCHAR);
case SQL_C_SBIGINT:
return sizeof(SQLBIGINT);
case SQL_C_UBIGINT:
return sizeof(SQLUBIGINT);
/* UnixODBC gives this the same value as SQL_C_UBIGINT
case SQL_C_BOOKMARK:
return sizeof(BOOKMARK); */
case SQL_C_BINARY:
// UnixODBC gives these the same value
//case SQL_C_VARBOOKMARK:
return sizeof(SQLCHAR*);
case SQL_C_TYPE_DATE:
case SQL_C_DATE:
return sizeof(SQL_DATE_STRUCT);
case SQL_C_TYPE_TIME:
case SQL_C_TIME:
return sizeof(SQL_TIME_STRUCT);
case SQL_C_TYPE_TIMESTAMP:
case SQL_C_TIMESTAMP:
return sizeof(SQL_TIMESTAMP_STRUCT);
case SQL_C_NUMERIC:
return sizeof(SQL_NUMERIC_STRUCT);
case SQL_C_GUID:
return sizeof(SQLGUID);
case SQL_C_INTERVAL_YEAR:
case SQL_C_INTERVAL_MONTH:
case SQL_C_INTERVAL_DAY:
case SQL_C_INTERVAL_HOUR:
case SQL_C_INTERVAL_MINUTE:
case SQL_C_INTERVAL_SECOND:
case SQL_C_INTERVAL_YEAR_TO_MONTH:
case SQL_C_INTERVAL_DAY_TO_HOUR:
case SQL_C_INTERVAL_DAY_TO_MINUTE:
case SQL_C_INTERVAL_DAY_TO_SECOND:
case SQL_C_INTERVAL_HOUR_TO_MINUTE:
case SQL_C_INTERVAL_HOUR_TO_SECOND:
case SQL_C_INTERVAL_MINUTE_TO_SECOND:
return sizeof(SQL_INTERVAL_STRUCT);
default:
return static_cast<size_t>(-1);
}
}
}
void OTools::getValue( OConnection* _pConnection,
SQLHANDLE _aStatementHandle,
sal_Int32 columnIndex,
......@@ -55,6 +131,23 @@ void OTools::getValue( OConnection* _pConnection,
SQLLEN _nSize) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException)
{
RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OTools::getValue" );
const size_t properSize = sqlTypeLen(_nType);
if ( properSize == static_cast<size_t>(-1) )
OSL_FAIL("connectivity::odbc::OTools::getValue: unknown SQL type - cannot check buffer size");
else
{
OSL_ENSURE(static_cast<size_t>(_nSize) == properSize, "connectivity::odbc::OTools::getValue got wrongly sized memory region to write result to");
if ( static_cast<size_t>(_nSize) > properSize )
{
OSL_FAIL("memory region is too big - trying to fudge it");
memset(_pValue, 0, _nSize);
#ifdef OSL_BIGENDIAN
// This is skewed in favour of integer types
_pValue += _nSize - properSize;
#endif
}
}
OSL_ENSURE(static_cast<size_t>(_nSize) >= properSize, "memory region is too small");
SQLLEN pcbValue = SQL_NULL_DATA;
OTools::ThrowException(_pConnection,
(*(T3SQLGetData)_pConnection->getOdbcFunction(ODBC3SQLGetData))(_aStatementHandle,
......
......@@ -125,6 +125,8 @@ namespace connectivity
sal_Int32 nHandle
) const;
~ODatabaseMetaDataResultSet();
template < typename T, SQLSMALLINT sqlTypeId > T getInteger ( sal_Int32 columnIndex );
public:
// ein Konstruktor, der fuer das Returnen des Objektes benoetigt wird:
ODatabaseMetaDataResultSet(OConnection* _pConnection);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment