summaryrefslogtreecommitdiff
path: root/connectivity
diff options
context:
space:
mode:
authorLionel Elie Mamane <lionel@mamane.lu>2012-01-24 22:20:31 +0100
committerLionel Elie Mamane <lionel@mamane.lu>2012-01-29 19:00:38 +0100
commit63b6b1d6120d82c4baf5cb679d75dcc5427dbbc3 (patch)
treebd2f0165d5d6ace3616d244c9d8b0afeef75fd18 /connectivity
parentbec18a80f59085c034e5adb1bb61d8365c1406c3 (diff)
make OTools::getValue insanely safe, factorise get{Int,Long,Byte,...}
Diffstat (limited to 'connectivity')
-rw-r--r--connectivity/source/drivers/odbcbase/ODatabaseMetaDataResultSet.cxx85
-rw-r--r--connectivity/source/drivers/odbcbase/OTools.cxx93
-rw-r--r--connectivity/source/inc/odbc/ODatabaseMetaDataResultSet.hxx2
3 files changed, 124 insertions, 56 deletions
diff --git a/connectivity/source/drivers/odbcbase/ODatabaseMetaDataResultSet.cxx b/connectivity/source/drivers/odbcbase/ODatabaseMetaDataResultSet.cxx
index 59876bb4c2de..6dd78812d28d 100644
--- a/connectivity/source/drivers/odbcbase/ODatabaseMetaDataResultSet.cxx
+++ b/connectivity/source/drivers/odbcbase/ODatabaseMetaDataResultSet.cxx
@@ -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 );
}
// -------------------------------------------------------------------------
diff --git a/connectivity/source/drivers/odbcbase/OTools.cxx b/connectivity/source/drivers/odbcbase/OTools.cxx
index 4da70ef9f812..9e8714cb0ca8 100644
--- a/connectivity/source/drivers/odbcbase/OTools.cxx
+++ b/connectivity/source/drivers/odbcbase/OTools.cxx
@@ -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,
diff --git a/connectivity/source/inc/odbc/ODatabaseMetaDataResultSet.hxx b/connectivity/source/inc/odbc/ODatabaseMetaDataResultSet.hxx
index 1ae6042ca04f..7a17249ec8e3 100644
--- a/connectivity/source/inc/odbc/ODatabaseMetaDataResultSet.hxx
+++ b/connectivity/source/inc/odbc/ODatabaseMetaDataResultSet.hxx
@@ -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);