[Libreoffice-commits] .: 7 commits - connectivity/source
Libreoffice Gerrit user
logerrit at kemper.freedesktop.org
Fri Oct 26 10:13:01 PDT 2012
connectivity/source/drivers/dbase/DTable.cxx | 49 -
connectivity/source/drivers/odbcbase/OPreparedStatement.cxx | 374 ++++++------
connectivity/source/drivers/odbcbase/OResultSet.cxx | 4
connectivity/source/drivers/odbcbase/OTools.cxx | 195 ------
connectivity/source/inc/dbase/DTable.hxx | 4
connectivity/source/inc/odbc/OBoundParam.hxx | 78 --
connectivity/source/inc/odbc/OPreparedStatement.hxx | 14
connectivity/source/inc/odbc/OTools.hxx | 38 -
8 files changed, 279 insertions(+), 477 deletions(-)
New commits:
commit 2c54307713160295ad51244eee41ef959a7fd55a
Author: Lionel Elie Mamane <lionel at mamane.lu>
Date: Fri Oct 26 18:57:34 2012 +0200
ODBC PreparedStatement Parameters: redesign setXXX handling
More type-safe way, instead of void* everywhere
void* instead of sal_Int8 for raw memory / multi-use buffers
Fixed more issues than I care to count, but at least:
- updates to a DECIMAL were truncated to integer because DecimalDigits set to 0
maybe/probably also NUMERIC
- setObjectWithInfo(... DataType::LONGVARCHAR ...) was passed as AT_EXEC, but the buffer was already free()d by then -> crash or wrong data
Change-Id: I0e6791a05b96fb345bfe3f911386263e6cfedde9
diff --git a/connectivity/source/drivers/odbcbase/OPreparedStatement.cxx b/connectivity/source/drivers/odbcbase/OPreparedStatement.cxx
index 7689ac7..5e43eb1 100644
--- a/connectivity/source/drivers/odbcbase/OPreparedStatement.cxx
+++ b/connectivity/source/drivers/odbcbase/OPreparedStatement.cxx
@@ -37,6 +37,8 @@
#include "connectivity/FValue.hxx"
#include "resource/common_res.hrc"
#include "connectivity/sqlparse.hxx"
+#include <boost/type_traits/remove_reference.hpp>
+#include <boost/type_traits/is_same.hpp>
using namespace ::comphelper;
using namespace connectivity;
@@ -52,6 +54,13 @@ using namespace com::sun::star::util;
IMPLEMENT_SERVICE_INFO(OPreparedStatement,"com.sun.star.sdbcx.OPreparedStatement","com.sun.star.sdbc.PreparedStatement");
+namespace
+{
+ // for now, never use wchar,
+ // but most of code is prepared to handle it
+ // in case we make this configurable
+ const bool useWChar = false;
+}
OPreparedStatement::OPreparedStatement( OConnection* _pConnection,const ::rtl::OUString& sql)
:OStatement_BASE2(_pConnection)
@@ -233,8 +242,7 @@ sal_Int32 SAL_CALL OPreparedStatement::executeUpdate( ) throw(SQLException, Run
void SAL_CALL OPreparedStatement::setString( sal_Int32 parameterIndex, const ::rtl::OUString& x ) throw(SQLException, RuntimeException)
{
- ::rtl::OString aString(::rtl::OUStringToOString(x,getOwnConnection()->getTextEncoding()));
- setParameter(parameterIndex,DataType::CHAR,aString.getLength(),(void*)&x);
+ setParameter(parameterIndex, DataType::CHAR, invalid_scale, x);
}
// -------------------------------------------------------------------------
@@ -269,111 +277,189 @@ Reference< XResultSet > SAL_CALL OPreparedStatement::executeQuery( ) throw(SQLE
void SAL_CALL OPreparedStatement::setBoolean( sal_Int32 parameterIndex, sal_Bool x ) throw(SQLException, RuntimeException)
{
- ::osl::MutexGuard aGuard( m_aMutex );
+ // Set the parameter as if it were an integer
+ setInt (parameterIndex, x ? 1 : 0 );
+}
+// -------------------------------------------------------------------------
+// The MutexGuard must _already_ be taken!
+void OPreparedStatement::setParameterPre(sal_Int32 parameterIndex)
+{
checkDisposed(OStatement_BASE::rBHelper.bDisposed);
+ prepareStatement();
+ checkParameterIndex(parameterIndex);
+ OSL_ENSURE(m_aStatementHandle,"StatementHandle is null!");
+}
+// -------------------------------------------------------------------------
+template <typename T> void OPreparedStatement::setScalarParameter(const sal_Int32 parameterIndex, const sal_Int32 i_nType, const SQLULEN i_nColSize, const T i_Value)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ setParameterPre(parameterIndex);
- sal_Int32 value = 0;
+ typedef typename boost::remove_reference< T >::type TnoRef;
- // If the parameter is sal_True, set the value to 1
- if (x) {
- value = 1;
- }
+ TnoRef *bindBuf = static_cast< TnoRef* >( allocBindBuf(parameterIndex, sizeof(i_Value)) );
+ *bindBuf = i_Value;
- // Set the parameter as if it were an integer
- setInt (parameterIndex, value);
+ setParameter(parameterIndex, i_nType, i_nColSize, invalid_scale, bindBuf, sizeof(i_Value), sizeof(i_Value));
}
// -------------------------------------------------------------------------
-void OPreparedStatement::setParameter(sal_Int32 parameterIndex,sal_Int32 _nType,sal_Int32 _nSize,void* _pData)
+
+void OPreparedStatement::setParameter(const sal_Int32 parameterIndex, const sal_Int32 _nType, const sal_Int16 _nScale, const ::rtl::OUString &_sData)
{
::osl::MutexGuard aGuard( m_aMutex );
- checkDisposed(OStatement_BASE::rBHelper.bDisposed);
-
- prepareStatement();
- // Allocate a buffer to be used in binding. This will be
- // a 'permanent' buffer that the bridge will fill in with
- // the bound data in native format.
+ setParameterPre(parameterIndex);
+ assert (_nType == DataType::VARCHAR || _nType == DataType::CHAR || _nType == DataType::DECIMAL || _nType == DataType::NUMERIC);
- checkParameterIndex(parameterIndex);
- sal_Int32 nRealSize = _nSize;
- SQLSMALLINT fSqlType = static_cast<SQLSMALLINT>(OTools::jdbcTypeToOdbc(_nType));
- switch(fSqlType)
+ sal_Int32 nCharLen;
+ sal_Int32 nByteLen;
+ void *pData;
+ if (useWChar)
{
- case SQL_CHAR:
- case SQL_VARCHAR:
- case SQL_DECIMAL:
- case SQL_NUMERIC:
- ++nRealSize;
- break;
- case SQL_BINARY:
- case SQL_VARBINARY:
- nRealSize=1; //dummy buffer, binary data isn't copied
- break;
- default:
- break;
+ /*
+ * On Windows, wchar is 16 bits (UTF-16 encoding), the ODBC "W" variants functions take UTF-16 encoded strings
+ * and character lengths are number of UTF-16 codepoints.
+ * Reference: http://msdn.microsoft.com/en-us/library/windows/desktop/ms716246%28v=vs.85%29.aspx
+ * ODBC Programmer's reference > Developing Applications > Programming Considerations > Unicode > Unicode Function Arguments
+ * http://support.microsoft.com/kb/294169
+ *
+ * UnixODBC can be configured at compile-time so that the "W" variants expect
+ * UTF-16 or UTF-32 encoded strings, and character lengths are number of codepoints.
+ * However, UTF-16 is the default, what all/most distributions do
+ * and the established API that most drivers implement.
+ * As wchar is often 32 bits, this differs from C-style strings of wchar!
+ *
+ * Our internal OUString storage is always UTF-16, so no conversion to do here.
+ */
+ BOOST_STATIC_ASSERT( sizeof(sal_Unicode) == 2 );
+ nCharLen = _sData.getLength();
+ nByteLen = nCharLen * sizeof(sal_Unicode);
+ pData = allocBindBuf(parameterIndex, nByteLen);
+ memcpy(pData, _sData.getStr(), nByteLen);
+ }
+ else
+ {
+ ::rtl::OString sOData( ::rtl::OUStringToOString(_sData, getOwnConnection()->getTextEncoding()) );
+ nCharLen = sOData.getLength();
+ nByteLen = nCharLen;
+ pData = allocBindBuf(parameterIndex, nByteLen);
+ memcpy(pData, sOData.getStr(), nByteLen);
}
- sal_Int8* bindBuf = allocBindBuf(parameterIndex, nRealSize);
+ setParameter( parameterIndex, _nType, nCharLen, _nScale, pData, nByteLen, nByteLen );
+}
+// -------------------------------------------------------------------------
+void OPreparedStatement::setParameter(const sal_Int32 parameterIndex, const sal_Int32 _nType, const Sequence< sal_Int8 > &x)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ setParameterPre(parameterIndex);
- OSL_ENSURE(m_aStatementHandle,"StatementHandle is null!");
- OTools::bindParameter( m_pConnection,
- m_aStatementHandle,
- parameterIndex,
- bindBuf,
- getLengthBuf(parameterIndex),
- fSqlType,
- sal_False,
- m_pConnection->useOldDateFormat(),
- _pData,
- (Reference <XInterface>)*this,
- getOwnConnection()->getTextEncoding());
+ assert(_nType == DataType::BINARY || _nType == DataType::VARBINARY);
+
+ // don't copy the sequence, just point the ODBC directly at the sequence's storage array
+ // Why BINARY/Sequence is treated differently than strings (which are copied), I'm not sure
+ OSL_VERIFY(allocBindBuf(parameterIndex, 0) == NULL);
+ boundParams[parameterIndex-1].setSequence(x); // this ensures that the sequence stays alive
+
+ setParameter( parameterIndex, _nType, x.getLength(), invalid_scale, x.getConstArray(), x.getLength(), x.getLength() );
+}
+// -------------------------------------------------------------------------
+void OPreparedStatement::setParameter(const sal_Int32 parameterIndex, const sal_Int32 _nType, const SQLULEN _nColumnSize, const sal_Int32 _nScale, const void* const _pData, const SQLULEN _nDataLen, const SQLLEN _nDataAllocLen)
+{
+ SQLSMALLINT fCType, fSqlType;
+ OTools::getBindTypes(useWChar, m_pConnection->useOldDateFormat(), OTools::jdbcTypeToOdbc(_nType), fCType, fSqlType);
+
+ SQLLEN *pDataLen=boundParams[parameterIndex-1].getBindLengthBuffer();
+ *pDataLen=_nDataLen;
+
+ SQLRETURN nRetcode;
+ nRetcode = (*(T3SQLBindParameter)m_pConnection->getOdbcFunction(ODBC3SQLBindParameter))(
+ m_aStatementHandle,
+ // checkParameterIndex guarantees this is safe
+ static_cast<SQLUSMALLINT>(parameterIndex),
+ SQL_PARAM_INPUT,
+ fCType,
+ fSqlType,
+ _nColumnSize,
+ _nScale,
+ // we trust the ODBC driver not to touch it because SQL_PARAM_INPUT
+ const_cast<void*>(_pData),
+ _nDataAllocLen,
+ pDataLen);
+
+ OTools::ThrowException(m_pConnection, nRetcode, m_aStatementHandle, SQL_HANDLE_STMT, *this);
}
// -----------------------------------------------------------------------------
-void SAL_CALL OPreparedStatement::setByte( sal_Int32 parameterIndex, sal_Int8 x ) throw(SQLException, RuntimeException)
+void SAL_CALL OPreparedStatement::setByte( const sal_Int32 parameterIndex, const sal_Int8 x ) throw(SQLException, RuntimeException)
{
- setParameter(parameterIndex,DataType::TINYINT,sizeof(sal_Int8),&x);
+ setScalarParameter(parameterIndex, DataType::TINYINT, 3, x);
}
// -------------------------------------------------------------------------
-
+// For older compilers (that do not support partial specialisation of class templates)
+// uncomment if necessary (safe also on compilers that *do* support partial specialisation)
+//BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION(DATE_STRUCT);
+//BOOST_STATIC_ASSERT((boost::is_same<DATE_STRUCT, boost::remove_reference<DATE_STRUCT&>::type>::value));
void SAL_CALL OPreparedStatement::setDate( sal_Int32 parameterIndex, const Date& aData ) throw(SQLException, RuntimeException)
{
- DATE_STRUCT x = OTools::DateToOdbcDate(aData);
- setParameter(parameterIndex,DataType::DATE,sizeof(DATE_STRUCT),&x);
+ DATE_STRUCT x(OTools::DateToOdbcDate(aData));
+ setScalarParameter<DATE_STRUCT&>(parameterIndex, DataType::DATE, 10, x);
}
// -------------------------------------------------------------------------
-
void SAL_CALL OPreparedStatement::setTime( sal_Int32 parameterIndex, const Time& aVal ) throw(SQLException, RuntimeException)
{
- TIME_STRUCT x = OTools::TimeToOdbcTime(aVal);
- setParameter(parameterIndex,DataType::TIME,sizeof(TIME_STRUCT),&x);
+ const sal_uInt16 hundredths (aVal.HundredthSeconds);
+ SQLULEN nColSize;
+ if(hundredths == 0)
+ nColSize = 8;
+ else if(hundredths % 10 == 0)
+ nColSize = 10;
+ else
+ nColSize = 11;
+ TIME_STRUCT x(OTools::TimeToOdbcTime(aVal));
+ setScalarParameter<TIME_STRUCT&>(parameterIndex, DataType::TIME, nColSize, x);
}
// -------------------------------------------------------------------------
void SAL_CALL OPreparedStatement::setTimestamp( sal_Int32 parameterIndex, const DateTime& aVal ) throw(SQLException, RuntimeException)
{
- TIMESTAMP_STRUCT x = OTools::DateTimeToTimestamp(aVal);
- setParameter(parameterIndex,DataType::TIMESTAMP,sizeof(TIMESTAMP_STRUCT),&x);
+ sal_uInt16 s(aVal.Seconds);
+ sal_uInt16 hundredths(aVal.HundredthSeconds);
+ SQLULEN nColSize;
+ if(hundredths == 0)
+ {
+ if (s == 0)
+ nColSize=16;
+ else
+ nColSize=19;
+ }
+ else if(hundredths % 10 == 0)
+ nColSize = 21;
+ else
+ nColSize = 22;
+
+ TIMESTAMP_STRUCT x(OTools::DateTimeToTimestamp(aVal));
+ setScalarParameter<TIMESTAMP_STRUCT&>(parameterIndex, DataType::TIMESTAMP, nColSize, x);
}
// -------------------------------------------------------------------------
void SAL_CALL OPreparedStatement::setDouble( sal_Int32 parameterIndex, double x ) throw(SQLException, RuntimeException)
{
- setParameter(parameterIndex,DataType::DOUBLE,sizeof(double),&x);
+ setScalarParameter(parameterIndex, DataType::DOUBLE, 15, x);
}
// -------------------------------------------------------------------------
void SAL_CALL OPreparedStatement::setFloat( sal_Int32 parameterIndex, float x ) throw(SQLException, RuntimeException)
{
- setParameter(parameterIndex,DataType::FLOAT,sizeof(float),&x);
+ setScalarParameter(parameterIndex, DataType::FLOAT, 15, x);
}
// -------------------------------------------------------------------------
void SAL_CALL OPreparedStatement::setInt( sal_Int32 parameterIndex, sal_Int32 x ) throw(SQLException, RuntimeException)
{
- setParameter(parameterIndex,DataType::INTEGER,sizeof(sal_Int32),&x);
+ setScalarParameter(parameterIndex, DataType::INTEGER, 10, x);
}
// -------------------------------------------------------------------------
@@ -381,57 +467,44 @@ void SAL_CALL OPreparedStatement::setLong( sal_Int32 parameterIndex, sal_Int64 x
{
try
{
- setParameter(parameterIndex,DataType::BIGINT,sizeof(sal_Int64),&x);
+ setScalarParameter(parameterIndex, DataType::BIGINT, 19, x);
}
catch(SQLException&)
{
- setString(parameterIndex,ORowSetValue(x));
+ setString(parameterIndex, ORowSetValue(x));
}
}
// -------------------------------------------------------------------------
-void SAL_CALL OPreparedStatement::setNull( sal_Int32 parameterIndex, sal_Int32 sqlType ) throw(SQLException, RuntimeException)
+void SAL_CALL OPreparedStatement::setNull( sal_Int32 parameterIndex, const sal_Int32 _nType ) throw(SQLException, RuntimeException)
{
::osl::MutexGuard aGuard( m_aMutex );
- checkDisposed(OStatement_BASE::rBHelper.bDisposed);
-
+ setParameterPre(paramterIndex):
- prepareStatement();
- // Get the buffer needed for the length
- checkParameterIndex(parameterIndex);
+ OSL_VERIFY(allocBindBuf(parameterIndex, 0) == NULL);
+ SQLLEN * const lenBuf = getLengthBuf (parameterIndex);
+ *lenBuf = SQL_NULL_DATA;
- sal_Int8* lenBuf = getLengthBuf (parameterIndex);
- *(SQLLEN*)lenBuf = SQL_NULL_DATA;
-
-
- SQLLEN prec = 0;
- SQLULEN nColumnSize = 0;
- if (sqlType == SQL_CHAR || sqlType == SQL_VARCHAR || sqlType == SQL_LONGVARCHAR)
- {
- prec = 1;
- nColumnSize = 1;
- }
- SQLSMALLINT fCType = 0;
- SQLSMALLINT fSqlType = 0;
+ SQLSMALLINT fCType;
+ SQLSMALLINT fSqlType;
- SQLSMALLINT nDecimalDigits = 0;
- OTools::getBindTypes( sal_False,
+ OTools::getBindTypes( useWChar,
m_pConnection->useOldDateFormat(),
- (SQLSMALLINT)sqlType,
+ OTools::jdbcTypeToOdbc(_nType),
fCType,
fSqlType);
SQLRETURN nReturn = N3SQLBindParameter( m_aStatementHandle,
- (SQLUSMALLINT)parameterIndex,
- (SQLSMALLINT)SQL_PARAM_INPUT,
+ static_cast<SQLUSMALLINT>(parameterIndex),
+ SQL_PARAM_INPUT,
fCType,
fSqlType,
- nColumnSize,
- nDecimalDigits,
+ 0,
+ 0,
NULL,
- prec,
- (SQLLEN*)lenBuf
+ 0,
+ lenBuf
);
OTools::ThrowException(m_pConnection,nReturn,m_aStatementHandle,SQL_HANDLE_STMT,*this);
}
@@ -440,14 +513,14 @@ void SAL_CALL OPreparedStatement::setNull( sal_Int32 parameterIndex, sal_Int32 s
void SAL_CALL OPreparedStatement::setClob( sal_Int32 parameterIndex, const Reference< XClob >& x ) throw(SQLException, RuntimeException)
{
if ( x.is() )
- setStream(parameterIndex, x->getCharacterStream(), (SQLLEN)x->length(), DataType::LONGVARCHAR);
+ setStream(parameterIndex, x->getCharacterStream(), x->length(), DataType::LONGVARCHAR);
}
// -------------------------------------------------------------------------
void SAL_CALL OPreparedStatement::setBlob( sal_Int32 parameterIndex, const Reference< XBlob >& x ) throw(SQLException, RuntimeException)
{
if ( x.is() )
- setStream(parameterIndex, x->getBinaryStream(), (SQLLEN)x->length(), DataType::LONGVARCHAR);
+ setStream(parameterIndex, x->getBinaryStream(), x->length(), DataType::LONGVARBINARY);
}
// -------------------------------------------------------------------------
@@ -462,12 +535,6 @@ void SAL_CALL OPreparedStatement::setRef( sal_Int32 /*parameterIndex*/, const Re
::dbtools::throwFunctionNotSupportedException( "XParameters::setRef", *this );
}
// -------------------------------------------------------------------------
-void OPreparedStatement::setDecimal( sal_Int32 parameterIndex, const ::rtl::OUString& x )
-{
- ::rtl::OString aString(::rtl::OUStringToOString(x,getOwnConnection()->getTextEncoding()));
- setParameter(parameterIndex,DataType::DECIMAL,aString.getLength(),(void*)&x);
-}
-// -------------------------------------------------------------------------
void SAL_CALL OPreparedStatement::setObjectWithInfo( sal_Int32 parameterIndex, const Any& x, sal_Int32 sqlType, sal_Int32 scale ) throw(SQLException, RuntimeException)
{
checkDisposed(OStatement_BASE::rBHelper.bDisposed);
@@ -479,31 +546,29 @@ void SAL_CALL OPreparedStatement::setObjectWithInfo( sal_Int32 parameterIndex, c
switch (sqlType)
{
+ case DataType::CHAR:
case DataType::VARCHAR:
case DataType::LONGVARCHAR:
if(x.hasValue())
{
::rtl::OUString sStr;
x >>= sStr;
- ::rtl::OString aString(::rtl::OUStringToOString(sStr,getOwnConnection()->getTextEncoding()));
- setParameter(parameterIndex,sqlType,aString.getLength(),&aString);
+ setParameter(parameterIndex, sqlType, scale, sStr);
}
else
setNull(parameterIndex,sqlType);
break;
case DataType::DECIMAL:
- {
- ORowSetValue aValue;
- aValue.fill(x);
- setDecimal(parameterIndex,aValue);
- }
- break;
case DataType::NUMERIC:
+ if(x.hasValue())
{
ORowSetValue aValue;
aValue.fill(x);
- setString(parameterIndex,aValue);
+ // TODO: make sure that this calls the string overload
+ setParameter(parameterIndex, sqlType, scale, aValue);
}
+ else
+ setNull(parameterIndex,sqlType);
break;
default:
::dbtools::setObjectWithInfo(this,parameterIndex,x,sqlType,scale);
@@ -513,9 +578,6 @@ void SAL_CALL OPreparedStatement::setObjectWithInfo( sal_Int32 parameterIndex, c
void SAL_CALL OPreparedStatement::setObjectNull( sal_Int32 parameterIndex, sal_Int32 sqlType, const ::rtl::OUString& /*typeName*/ ) throw(SQLException, RuntimeException)
{
- ::osl::MutexGuard aGuard( m_aMutex );
- checkDisposed(OStatement_BASE::rBHelper.bDisposed);
-
setNull(parameterIndex,sqlType);
}
// -------------------------------------------------------------------------
@@ -531,20 +593,21 @@ void SAL_CALL OPreparedStatement::setObject( sal_Int32 parameterIndex, const Any
void SAL_CALL OPreparedStatement::setShort( sal_Int32 parameterIndex, sal_Int16 x ) throw(SQLException, RuntimeException)
{
- setParameter(parameterIndex,DataType::SMALLINT,sizeof(sal_Int16),&x);
+ setScalarParameter(parameterIndex, DataType::SMALLINT, 5, x);
}
// -------------------------------------------------------------------------
void SAL_CALL OPreparedStatement::setBytes( sal_Int32 parameterIndex, const Sequence< sal_Int8 >& x ) throw(SQLException, RuntimeException)
{
- setParameter(parameterIndex,DataType::BINARY,x.getLength(),(void*)&x);
- boundParams[parameterIndex-1].setSequence(x); // this assures that the sequence stays alive
+ setParameter(parameterIndex, DataType::BINARY, x);
}
// -------------------------------------------------------------------------
void SAL_CALL OPreparedStatement::setCharacterStream( sal_Int32 parameterIndex, const Reference< ::com::sun::star::io::XInputStream >& x, sal_Int32 length ) throw(SQLException, RuntimeException)
{
+ // LEM: It is quite unclear to me what the interface here is.
+ // The XInputStream provides *bytes*, not characters.
setStream(parameterIndex, x, length, DataType::LONGVARCHAR);
}
// -------------------------------------------------------------------------
@@ -557,6 +620,7 @@ void SAL_CALL OPreparedStatement::setBinaryStream( sal_Int32 parameterIndex, con
void SAL_CALL OPreparedStatement::clearParameters( ) throw(SQLException, RuntimeException)
{
+ ::osl::MutexGuard aGuard( m_aMutex );
prepareStatement();
OSL_ENSURE(m_aStatementHandle,"StatementHandle is null!");
SQLRETURN nRet = N3SQLFreeStmt (m_aStatementHandle, SQL_RESET_PARAMS);
@@ -566,6 +630,7 @@ void SAL_CALL OPreparedStatement::clearParameters( ) throw(SQLException, Runtim
// -------------------------------------------------------------------------
void SAL_CALL OPreparedStatement::clearBatch( ) throw(SQLException, RuntimeException)
{
+ ::dbtools::throwFunctionNotSupportedException( "XPreparedBatchExecution::clearBatch", *this );
// clearParameters( );
// m_aBatchList.erase();
}
@@ -573,11 +638,14 @@ void SAL_CALL OPreparedStatement::clearBatch( ) throw(SQLException, RuntimeExce
void SAL_CALL OPreparedStatement::addBatch( ) throw(SQLException, RuntimeException)
{
+ ::dbtools::throwFunctionNotSupportedException( "XPreparedBatchExecution::addBatch", *this );
}
// -------------------------------------------------------------------------
Sequence< sal_Int32 > SAL_CALL OPreparedStatement::executeBatch( ) throw(SQLException, RuntimeException)
{
+ ::dbtools::throwFunctionNotSupportedException( "XPreparedBatchExecution::executeBatch", *this );
+ // not reached, but keep -Werror happy
return Sequence< sal_Int32 > ();
}
// -------------------------------------------------------------------------
@@ -607,12 +675,6 @@ void OPreparedStatement::initBoundParam () throw(SQLException)
boundParams = new OBoundParam[numParams];
- // initialize each bound parameter
-
- for (sal_Int32 i = 0; i < numParams; i++)
- {
- boundParams[i].initialize ();
- }
}
}
// -------------------------------------------------------------------------
@@ -623,14 +685,13 @@ void OPreparedStatement::initBoundParam () throw(SQLException)
// parameter.
//--------------------------------------------------------------------
-sal_Int8* OPreparedStatement::allocBindBuf( sal_Int32 index,sal_Int32 bufLen)
+void* OPreparedStatement::allocBindBuf( sal_Int32 index,sal_Int32 bufLen)
{
- sal_Int8* b = NULL;
+ void* b = NULL;
// Sanity check the parameter number
- if ((index >= 1) &&
- (index <= numParams) && bufLen > 0 )
+ if ((index >= 1) && (index <= numParams))
{
b = boundParams[index - 1].allocBindDataBuffer(bufLen);
}
@@ -644,9 +705,9 @@ sal_Int8* OPreparedStatement::allocBindBuf( sal_Int32 index,sal_Int32 bufLen)
// Gets the length buffer for the given parameter index
//--------------------------------------------------------------------
-sal_Int8* OPreparedStatement::getLengthBuf (sal_Int32 index)
+SQLLEN* OPreparedStatement::getLengthBuf (sal_Int32 index)
{
- sal_Int8* b = NULL;
+ SQLLEN* b = NULL;
// Sanity check the parameter number
@@ -737,7 +798,7 @@ void OPreparedStatement::setStream(
sal_Int32 ParameterIndex,
const Reference< XInputStream>& x,
SQLLEN length,
- sal_Int32 SQLtype)
+ sal_Int32 _nType)
throw(SQLException)
{
::osl::MutexGuard aGuard( m_aMutex );
@@ -749,35 +810,33 @@ void OPreparedStatement::setStream(
checkParameterIndex(ParameterIndex);
// Get the buffer needed for the length
- sal_Int8* lenBuf = getLengthBuf(ParameterIndex);
+ SQLLEN * const lenBuf = getLengthBuf(ParameterIndex);
// Allocate a new buffer for the parameter data. This buffer
// will be returned by SQLParamData (it is set to the parameter
- // number, a 4-sal_Int8 integer)
+ // number, a sal_Int32)
- sal_Int8* dataBuf = allocBindBuf (ParameterIndex, 4);
+ sal_Int32* dataBuf = static_cast<sal_Int32*>( allocBindBuf(ParameterIndex, sizeof(ParameterIndex)) );
+ *dataBuf = ParameterIndex;
// Bind the parameter with SQL_LEN_DATA_AT_EXEC
- SQLSMALLINT Ctype = SQL_C_CHAR;
- SQLLEN atExec = SQL_LEN_DATA_AT_EXEC (length);
- memcpy (dataBuf, &ParameterIndex, sizeof(ParameterIndex));
- memcpy (lenBuf, &atExec, sizeof (atExec));
+ *lenBuf = SQL_LEN_DATA_AT_EXEC (length);
- if ((SQLtype == SQL_BINARY) || (SQLtype == SQL_VARBINARY) || (SQLtype == SQL_LONGVARBINARY))
- Ctype = SQL_C_BINARY;
+ SQLSMALLINT fCType, fSqlType;
+ OTools::getBindTypes(useWChar, m_pConnection->useOldDateFormat(), OTools::jdbcTypeToOdbc(_nType), fCType, fSqlType);
OSL_ENSURE(m_aStatementHandle,"StatementHandle is null!");
N3SQLBindParameter(m_aStatementHandle,
- (SQLUSMALLINT)ParameterIndex,
- (SQLUSMALLINT)SQL_PARAM_INPUT,
- Ctype,
- (SQLSMALLINT)SQLtype,
- (SQLULEN)length,
- 0,
- dataBuf,
- sizeof(ParameterIndex),
- (SQLLEN*)lenBuf);
+ static_cast<SQLUSMALLINT>(ParameterIndex),
+ SQL_PARAM_INPUT,
+ fCType,
+ fSqlType,
+ length,
+ invalid_scale,
+ dataBuf,
+ sizeof(ParameterIndex),
+ lenBuf);
// Save the input stream
boundParams[ParameterIndex - 1].setInputStream (x, length);
@@ -840,7 +899,9 @@ void OPreparedStatement::prepareStatement()
// -----------------------------------------------------------------------------
void OPreparedStatement::checkParameterIndex(sal_Int32 _parameterIndex)
{
- if( !_parameterIndex || _parameterIndex > numParams)
+ if( _parameterIndex > numParams ||
+ _parameterIndex < 1 ||
+ _parameterIndex > std::numeric_limits<SQLUSMALLINT>::max() )
{
::connectivity::SharedResources aResources;
const ::rtl::OUString sError( aResources.getResourceStringWithSubstitution(STR_WRONG_PARAM_INDEX,
diff --git a/connectivity/source/drivers/odbcbase/OResultSet.cxx b/connectivity/source/drivers/odbcbase/OResultSet.cxx
index 7cfebcb..96d7d8e 100644
--- a/connectivity/source/drivers/odbcbase/OResultSet.cxx
+++ b/connectivity/source/drivers/odbcbase/OResultSet.cxx
@@ -1058,7 +1058,7 @@ void SAL_CALL OResultSet::updateDouble( sal_Int32 columnIndex, double x ) throw(
void SAL_CALL OResultSet::updateString( sal_Int32 columnIndex, const ::rtl::OUString& x ) throw(SQLException, RuntimeException)
{
sal_Int32 nType = m_aRow[columnIndex].getTypeKind();
- SQLSMALLINT nOdbcType = static_cast<SQLSMALLINT>(OTools::jdbcTypeToOdbc(nType));
+ SQLSMALLINT nOdbcType = OTools::jdbcTypeToOdbc(nType);
m_aRow[columnIndex] = x;
m_aRow[columnIndex].setTypeKind(nType); // OJ: otherwise longvarchar will be recognized by fillNeededData
updateValue(columnIndex,nOdbcType,(void*)&x);
@@ -1067,7 +1067,7 @@ void SAL_CALL OResultSet::updateString( sal_Int32 columnIndex, const ::rtl::OUSt
void SAL_CALL OResultSet::updateBytes( sal_Int32 columnIndex, const Sequence< sal_Int8 >& x ) throw(SQLException, RuntimeException)
{
sal_Int32 nType = m_aRow[columnIndex].getTypeKind();
- SQLSMALLINT nOdbcType = static_cast<SQLSMALLINT>(OTools::jdbcTypeToOdbc(nType));
+ SQLSMALLINT nOdbcType = OTools::jdbcTypeToOdbc(nType);
m_aRow[columnIndex] = x;
m_aRow[columnIndex].setTypeKind(nType); // OJ: otherwise longvarbinary will be recognized by fillNeededData
updateValue(columnIndex,nOdbcType,(void*)&x);
diff --git a/connectivity/source/drivers/odbcbase/OTools.cxx b/connectivity/source/drivers/odbcbase/OTools.cxx
index b38dd2b..3e32780 100644
--- a/connectivity/source/drivers/odbcbase/OTools.cxx
+++ b/connectivity/source/drivers/odbcbase/OTools.cxx
@@ -150,190 +150,6 @@ void OTools::getValue( OConnection* _pConnection,
_aStatementHandle,SQL_HANDLE_STMT,_xInterface,sal_False);
_bWasNull = pcbValue == SQL_NULL_DATA;
}
-// -----------------------------------------------------------------------------
-void OTools::bindParameter( OConnection* _pConnection,
- SQLHANDLE _hStmt,
- sal_Int32 nPos,
- sal_Int8*& pDataBuffer,
- sal_Int8* pLenBuffer,
- SQLSMALLINT _nODBCtype,
- sal_Bool _bUseWChar,
- sal_Bool _bUseOldTimeDate,
- const void* _pValue,
- const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _xInterface,
- rtl_TextEncoding _nTextEncoding)
- throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException)
-{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen at sun.com", "OTools::bindParameter" );
- SQLRETURN nRetcode;
- SQLSMALLINT fSqlType;
- SQLSMALLINT fCType;
- SQLLEN nMaxLen = 0;
- SQLLEN* pLen = (SQLLEN*)pLenBuffer;
- SQLULEN nColumnSize=0;
- SQLSMALLINT nDecimalDigits=0;
- bool atExec;
-
- OTools::getBindTypes(_bUseWChar,_bUseOldTimeDate,_nODBCtype,fCType,fSqlType);
-
- OTools::bindData(_nODBCtype,_bUseWChar,pDataBuffer,pLen,_pValue,_nTextEncoding,nColumnSize, atExec);
- if ((nColumnSize == 0) && (fSqlType == SQL_CHAR || fSqlType == SQL_VARCHAR || fSqlType == SQL_LONGVARCHAR))
- nColumnSize = 1;
-
- if (atExec)
- memcpy(pDataBuffer,&nPos,sizeof(nPos));
-
- nRetcode = (*(T3SQLBindParameter)_pConnection->getOdbcFunction(ODBC3SQLBindParameter))(_hStmt,
- (SQLUSMALLINT)nPos,
- SQL_PARAM_INPUT,
- fCType,
- fSqlType,
- nColumnSize,
- nDecimalDigits,
- pDataBuffer,
- nMaxLen,
- pLen);
-
- OTools::ThrowException(_pConnection,nRetcode,_hStmt,SQL_HANDLE_STMT,_xInterface);
-}
-// -----------------------------------------------------------------------------
-void OTools::bindData( SQLSMALLINT _nOdbcType,
- sal_Bool _bUseWChar,
- sal_Int8 *&_pData,
- SQLLEN*& pLen,
- const void* _pValue,
- rtl_TextEncoding _nTextEncoding,
- SQLULEN& _nColumnSize,
- bool &atExec)
-{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen at sun.com", "OTools::bindData" );
- _nColumnSize = 0;
- atExec = false;
-
- switch (_nOdbcType)
- {
- case SQL_CHAR:
- case SQL_VARCHAR:
- case SQL_DECIMAL:
- if(_bUseWChar)
- {
- *pLen = SQL_NTS;
- ::rtl::OUString sStr(*(::rtl::OUString*)_pValue);
- _nColumnSize = sStr.getLength();
- *((rtl::OUString*)_pData) = sStr;
-
- // Pointer on Char*
- _pData = (sal_Int8*)((rtl::OUString*)_pData)->getStr();
- }
- else
- {
- ::rtl::OString aString(::rtl::OUStringToOString(*(::rtl::OUString*)_pValue,_nTextEncoding));
- *pLen = SQL_NTS;
- _nColumnSize = aString.getLength();
- memcpy(_pData,aString.getStr(),aString.getLength());
- ((sal_Int8*)_pData)[aString.getLength()] = '\0';
- }
- break;
-
- case SQL_BIGINT:
- *((sal_Int64*)_pData) = *(sal_Int64*)_pValue;
- *pLen = sizeof(sal_Int64);
- _nColumnSize = *pLen;
- break;
-
- case SQL_NUMERIC:
- if(_bUseWChar)
- {
- ::rtl::OUString aString = rtl::OUString::valueOf(*(double*)_pValue);
- _nColumnSize = aString.getLength();
- *pLen = _nColumnSize;
- *((rtl::OUString*)_pData) = aString;
- // Pointer on Char*
- _pData = (sal_Int8*)((rtl::OUString*)_pData)->getStr();
- }
- else
- {
- ::rtl::OString aString = ::rtl::OString::valueOf(*(double*)_pValue);
- _nColumnSize = aString.getLength();
- *pLen = _nColumnSize;
- memcpy(_pData,aString.getStr(),aString.getLength());
- ((sal_Int8*)_pData)[_nColumnSize] = '\0';
- } break;
- case SQL_BIT:
- case SQL_TINYINT:
- *((sal_Int8*)_pData) = *(sal_Int8*)_pValue;
- *pLen = sizeof(sal_Int8);
- break;
-
- case SQL_SMALLINT:
- *((sal_Int16*)_pData) = *(sal_Int16*)_pValue;
- *pLen = sizeof(sal_Int16);
- break;
- case SQL_INTEGER:
- *((sal_Int32*)_pData) = *(sal_Int32*)_pValue;
- *pLen = sizeof(sal_Int32);
- break;
- case SQL_FLOAT:
- *((float*)_pData) = *(float*)_pValue;
- *pLen = sizeof(float);
- break;
- case SQL_REAL:
- case SQL_DOUBLE:
- *((double*)_pData) = *(double*)_pValue;
- *pLen = sizeof(double);
- break;
- case SQL_BINARY:
- case SQL_VARBINARY:
- {
- const ::com::sun::star::uno::Sequence< sal_Int8 >* pSeq = static_cast< const ::com::sun::star::uno::Sequence< sal_Int8 >* >(_pValue);
- OSL_ENSURE(pSeq,"OTools::bindData: Sequence is null!");
-
- if(pSeq)
- {
- _pData = (sal_Int8*)pSeq->getConstArray();
- *pLen = pSeq->getLength();
- }
- }
- break;
- case SQL_LONGVARBINARY:
- {
- sal_Int32 nLen = 0;
- nLen = ((const ::com::sun::star::uno::Sequence< sal_Int8 > *)_pValue)->getLength();
- *pLen = (SQLLEN)SQL_LEN_DATA_AT_EXEC(nLen);
- }
- atExec = true;
- break;
- case SQL_LONGVARCHAR:
- {
- sal_Int32 nLen = 0;
- if(_bUseWChar)
- nLen = sizeof(sal_Unicode) * ((::rtl::OUString*)_pValue)->getLength();
- else
- {
- ::rtl::OString aString(::rtl::OUStringToOString(*(::rtl::OUString*)_pValue,_nTextEncoding));
- nLen = aString.getLength();
- }
- *pLen = (SQLLEN)SQL_LEN_DATA_AT_EXEC(nLen);
- atExec = true;
- } break;
- case SQL_DATE:
- *(DATE_STRUCT*)_pData = *(DATE_STRUCT*)_pValue;
- *pLen = (SQLLEN)sizeof(DATE_STRUCT);
- _nColumnSize = 10;
- break;
- case SQL_TIME:
- *(TIME_STRUCT*)_pData = *(TIME_STRUCT*)_pValue;
- *pLen = (SQLLEN)sizeof(TIME_STRUCT);
- _nColumnSize = 8;
- break;
- case SQL_TIMESTAMP:
- *(TIMESTAMP_STRUCT*)_pData = *(TIMESTAMP_STRUCT*)_pValue;
- *pLen = (SQLLEN)sizeof(TIMESTAMP_STRUCT);
- // 20+sub-zero precision; we have hundredths of seconds
- _nColumnSize = 22;
- break;
- }
-}
// -------------------------------------------------------------------------
void OTools::bindValue( OConnection* _pConnection,
SQLHANDLE _aStatementHandle,
@@ -342,7 +158,7 @@ void OTools::bindValue( OConnection* _pConnection,
SQLSMALLINT _nMaxLen,
const void* _pValue,
void* _pData,
- SQLLEN *pLen,
+ SQLLEN * const pLen,
const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _xInterface,
rtl_TextEncoding _nTextEncoding,
sal_Bool _bUseOldTimeDate) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException)
@@ -779,7 +595,7 @@ void OTools::GetInfo(OConnection* _pConnection,
_aConnectionHandle,SQL_HANDLE_DBC,_xInterface);
}
// -------------------------------------------------------------------------
-sal_Int32 OTools::MapOdbcType2Jdbc(sal_Int32 _nType)
+sal_Int32 OTools::MapOdbcType2Jdbc(SQLSMALLINT _nType)
{
sal_Int32 nValue = DataType::VARCHAR;
switch(_nType)
@@ -857,7 +673,7 @@ sal_Int32 OTools::MapOdbcType2Jdbc(sal_Int32 _nType)
// jdbcTypeToOdbc
// Convert the JDBC SQL type to the correct ODBC type
//--------------------------------------------------------------------
-sal_Int32 OTools::jdbcTypeToOdbc(sal_Int32 jdbcType)
+SQLSMALLINT OTools::jdbcTypeToOdbc(sal_Int32 jdbcType)
{
RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen at sun.com", "OTools::jdbcTypeToOdbc" );
// For the most part, JDBC types match ODBC types. We'll
@@ -876,6 +692,11 @@ sal_Int32 OTools::jdbcTypeToOdbc(sal_Int32 jdbcType)
case DataType::TIMESTAMP:
odbcType = SQL_TIMESTAMP;
break;
+ // ODBC doesn't have any notion of CLOB or BLOB
+ case DataType::CLOB:
+ odbcType = SQL_LONGVARCHAR;
+ case DataType::BLOB:
+ odbcType = SQL_LONGVARBINARY;
}
return odbcType;
diff --git a/connectivity/source/inc/odbc/OBoundParam.hxx b/connectivity/source/inc/odbc/OBoundParam.hxx
index 8e587b4..fca532b 100644
--- a/connectivity/source/inc/odbc/OBoundParam.hxx
+++ b/connectivity/source/inc/odbc/OBoundParam.hxx
@@ -20,6 +20,7 @@
#define _CONNECTIVITY_OBOUNPARAM_HXX_
#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/sdbc/DataType.hpp>
#include "odbc/odbcbasedllapi.hxx"
namespace connectivity
@@ -31,50 +32,29 @@ namespace connectivity
public:
OBoundParam()
+ : binaryData(NULL)
+ , paramInputStreamLen(0)
+ , sqlType(::com::sun::star::sdbc::DataType::SQLNULL)
+ , outputParameter(false)
{
- paramLength = NULL;
- binaryData = NULL;
- pA1=0;
- pA2=0;
- pB1=0;
- pB2=0;
- pC1=0;
- pC2=0;
- pS1=0;
- pS2=0;
}
~OBoundParam()
{
- delete [] binaryData;
- delete [] paramLength;
+ free(binaryData);
}
//--------------------------------------------------------------------
- // initialize
- // Perform an necessary initialization
- //--------------------------------------------------------------------
- void initialize ()
- {
- // Allocate storage for the length. Note - the length is
- // stored in native format, and will have to be converted
- // to a Java sal_Int32. The jdbcodbc 'C' bridge provides an
- // interface to do this.
-
- paramLength = new sal_Int8[sizeof(SQLLEN)];
- }
-
- //--------------------------------------------------------------------
// allocBindDataBuffer
// Allocates and returns a new bind data buffer of the specified
// length
//--------------------------------------------------------------------
- sal_Int8* allocBindDataBuffer (sal_Int32 bufLen)
+ void* allocBindDataBuffer (sal_Int32 bufLen)
{
- if ( binaryData )
- delete [] binaryData;
- binaryData = new sal_Int8[bufLen];
-
- // Reset the input stream, we are doing a new bind
+ // Reset the input stream and sequence, we are doing a new bind
setInputStream (NULL, 0);
+ aSequence.realloc(0);
+
+ free(binaryData);
+ binaryData = (bufLen > 0) ? malloc(bufLen) : NULL;
return binaryData;
}
@@ -83,7 +63,7 @@ namespace connectivity
// getBindDataBuffer
// Returns the data buffer to be used when binding to a parameter
//--------------------------------------------------------------------
- sal_Int8* getBindDataBuffer ()
+ void* getBindDataBuffer ()
{
return binaryData;
}
@@ -92,9 +72,9 @@ namespace connectivity
// getBindLengthBuffer
// Returns the length buffer to be used when binding to a parameter
//--------------------------------------------------------------------
- sal_Int8* getBindLengthBuffer ()
+ SQLLEN* getBindLengthBuffer ()
{
- return paramLength;
+ return ¶mLength;
}
//--------------------------------------------------------------------
@@ -176,20 +156,20 @@ namespace connectivity
// Data attributes
//====================================================================
- sal_Int8* binaryData; // Storage area to be used
- // when binding the parameter
+ void *binaryData; // Storage area to be used
+ // when binding the parameter
- sal_Int8* paramLength; // Storage area to be used
- // for the bound length of the
- // parameter. Note that this
- // data is in native format.
+ SQLLEN paramLength; // Storage area to be used
+ // for the bound length of the
+ // parameter. Note that this
+ // data is in native format.
::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream> paramInputStream;
::com::sun::star::uno::Sequence< sal_Int8 > aSequence;
// When an input stream is
- // bound to a parameter, the
- // input stream is saved
- // until needed.
+ // bound to a parameter, a
+ // reference to the input stream is saved
+ // until not needed anymore.
sal_Int32 paramInputStreamLen; // Length of input stream
@@ -197,16 +177,6 @@ namespace connectivity
// register an OUT parameter
sal_Bool outputParameter; // true for OUTPUT parameters
-
-
- sal_Int32 pA1; //pointers
- sal_Int32 pA2;
- sal_Int32 pB1;
- sal_Int32 pB2;
- sal_Int32 pC1;
- sal_Int32 pC2;
- sal_Int32 pS1;
- sal_Int32 pS2;// reserved for strings(UTFChars)
};
}
}
diff --git a/connectivity/source/inc/odbc/OPreparedStatement.hxx b/connectivity/source/inc/odbc/OPreparedStatement.hxx
index 0d34099..139ea3f 100644
--- a/connectivity/source/inc/odbc/OPreparedStatement.hxx
+++ b/connectivity/source/inc/odbc/OPreparedStatement.hxx
@@ -46,6 +46,7 @@ namespace connectivity
public OPreparedStatement_BASE
{
protected:
+ static const short invalid_scale = -1;
struct Parameter
{
::com::sun::star::uno::Any aValue;
@@ -74,15 +75,20 @@ namespace connectivity
void putParamData (sal_Int32 index) throw(::com::sun::star::sdbc::SQLException);
void setStream (sal_Int32 ParameterIndex,const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream>& x,
SQLLEN length,sal_Int32 SQLtype) throw(::com::sun::star::sdbc::SQLException);
- sal_Int8* getLengthBuf (sal_Int32 index);
- sal_Int8* allocBindBuf ( sal_Int32 index, sal_Int32 bufLen);
+ SQLLEN* getLengthBuf (sal_Int32 index);
+ void* allocBindBuf ( sal_Int32 index, sal_Int32 bufLen);
void initBoundParam () throw(::com::sun::star::sdbc::SQLException);
- void setParameter(sal_Int32 parameterIndex,sal_Int32 _nType,sal_Int32 _nSize,void* _pData);
+ void setParameterPre(sal_Int32 parameterIndex);
+ template <typename T> void setScalarParameter(sal_Int32 parameterIndex, sal_Int32 _nType, SQLULEN _nColumnSize, const T i_Value);
+ void setParameter(sal_Int32 parameterIndex, sal_Int32 _nType, SQLULEN _nColumnSize, sal_Int32 _nScale, const void* _pData, SQLULEN _nDataLen, SQLLEN _nDataAllocLen);
+ void setParameter(sal_Int32 parameterIndex, sal_Int32 _nType, sal_Int32 _nColumnSize, sal_Int32 _nByteSize, void* _pData);
+ // Wrappers for special cases
+ void setParameter(sal_Int32 parameterIndex, sal_Int32 _nType, sal_Int16 _nScale, const ::rtl::OUString &_sData);
+ void setParameter(sal_Int32 parameterIndex, sal_Int32 _nType, const com::sun::star::uno::Sequence< sal_Int8 > &_Data);
sal_Bool isPrepared() const { return m_bPrepared;}
void prepareStatement();
void checkParameterIndex(sal_Int32 _parameterIndex);
- void setDecimal( sal_Int32 parameterIndex, const ::rtl::OUString& x );
/**
creates the driver specific resultset (factory)
diff --git a/connectivity/source/inc/odbc/OTools.hxx b/connectivity/source/inc/odbc/OTools.hxx
index 0688496..a971d4c 100644
--- a/connectivity/source/inc/odbc/OTools.hxx
+++ b/connectivity/source/inc/odbc/OTools.hxx
@@ -138,8 +138,8 @@ namespace connectivity
sal_Bool &_rValue,
const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _xInterface) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
- static sal_Int32 MapOdbcType2Jdbc(sal_Int32 _nType);
- static sal_Int32 jdbcTypeToOdbc(sal_Int32 jdbcType);
+ static sal_Int32 MapOdbcType2Jdbc(SQLSMALLINT _nType);
+ static SQLSMALLINT jdbcTypeToOdbc(sal_Int32 jdbcType);
static DATE_STRUCT DateToOdbcDate(const ::com::sun::star::util::Date& x)
{
@@ -206,40 +206,6 @@ namespace connectivity
void* _pValue,
SQLLEN _nSize) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
- /**
- bindData copies data from pValue to pData
- @param _nOdbcType [in] the ODBC sql type
- @param _bUseWChar [in] true when Unicode should be used
- @param _pData [in/out] data copy destination
- @param pLen [out] buffer length of data written to _pData
- @param _pValue [in] contains the data to be copied
- @param _nTextEncoding [in] the text encoding
- @param _nColumnSize [out] columnSize of data written to _pData
- @param atExec [out] data was not copied, but setup for data-at-execution;
- caller is responsible for writing a token in _pData
- */
- static void bindData( SQLSMALLINT _nOdbcType,
- sal_Bool _bUseWChar,
- sal_Int8 *&_pData,
- SQLLEN*& pLen,
- const void* _pValue,
- rtl_TextEncoding _nTextEncoding,
- SQLULEN& _nColumnSize,
- bool &atExec);
-
- static void bindParameter( OConnection* _pConnection,
- SQLHANDLE _hStmt,
- sal_Int32 nPos,
- sal_Int8*& pDataBuffer,
- sal_Int8* pLenBuffer,
- SQLSMALLINT _nODBCtype,
- sal_Bool _bUseWChar,
- sal_Bool _bUseOldTimeDate,
- const void* _pValue,
- const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _xInterface,
- rtl_TextEncoding _nTextEncoding)
- throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
-
static void bindValue( OConnection* _pConnection,
SQLHANDLE _aStatementHandle,
sal_Int32 columnIndex,
commit 626da7211498429b55eba3b438d82e5119d3ec68
Author: Lionel Elie Mamane <lionel at mamane.lu>
Date: Fri Oct 26 17:36:49 2012 +0200
duplicated code
Change-Id: Ifa9b93b2daf0bb448711eb1bd3ebab69febf4f9c
diff --git a/connectivity/source/drivers/odbcbase/OPreparedStatement.cxx b/connectivity/source/drivers/odbcbase/OPreparedStatement.cxx
index a5d24dd..7689ac7 100644
--- a/connectivity/source/drivers/odbcbase/OPreparedStatement.cxx
+++ b/connectivity/source/drivers/odbcbase/OPreparedStatement.cxx
@@ -199,31 +199,6 @@ sal_Bool SAL_CALL OPreparedStatement::execute( ) throw(SQLException, RuntimeExc
{
}
- // Now loop while more data is needed (i.e. a data-at-
- // execution parameter was given). For each parameter
- // that needs data, put the data from the input stream.
-
- while (needData) {
-
- // Get the parameter number that requires data
-
- sal_Int32* paramIndex = 0;
- N3SQLParamData (m_aStatementHandle,(SQLPOINTER*)¶mIndex);
-
- // If the parameter index is -1, there is no more
- // data required
-
- if (*paramIndex == -1) {
- needData = sal_False;
- }
- else {
- // Now we have the proper parameter index,
- // get the data from the input stream
- // and do a SQLPutData
- putParamData(*paramIndex);
- }
- }
-
// Now determine if there is a result set associated with
// the SQL statement that was executed. Get the column
// count, and if it is not zero, there is a result set.
commit 7b4e7e027966bdd3be941d2f65399eabab0ca70e
Author: Lionel Elie Mamane <lionel at mamane.lu>
Date: Thu Oct 25 11:40:12 2012 +0200
odbc::OTools::bindParameter takes an ODBCtype, not a JDBCtype
Change-Id: I6de4e86f09be74518c9980d1b2347217cdcc4e02
diff --git a/connectivity/source/inc/odbc/OTools.hxx b/connectivity/source/inc/odbc/OTools.hxx
index 99339e2..0688496 100644
--- a/connectivity/source/inc/odbc/OTools.hxx
+++ b/connectivity/source/inc/odbc/OTools.hxx
@@ -232,7 +232,7 @@ namespace connectivity
sal_Int32 nPos,
sal_Int8*& pDataBuffer,
sal_Int8* pLenBuffer,
- SQLSMALLINT _nJDBCtype,
+ SQLSMALLINT _nODBCtype,
sal_Bool _bUseWChar,
sal_Bool _bUseOldTimeDate,
const void* _pValue,
commit 7bb42b171e0c0f5c8f5967d21418f56c52a29370
Author: Lionel Elie Mamane <lionel at mamane.lu>
Date: Thu Oct 25 11:35:10 2012 +0200
UpdateBuffer optimisation: cache column value, isBound() and isNull()
Change-Id: I70f92224e22e9a9a1283564b5b1be7bf1e0240d0
diff --git a/connectivity/source/drivers/dbase/DTable.cxx b/connectivity/source/drivers/dbase/DTable.cxx
index e88a7c1..f1bdb32 100644
--- a/connectivity/source/drivers/dbase/DTable.cxx
+++ b/connectivity/source/drivers/dbase/DTable.cxx
@@ -1814,8 +1814,11 @@ sal_Bool ODbaseTable::UpdateBuffer(OValueRefVector& rRow, OValueRefRow pOrgRow,
++nPos; // the row values start at 1
+ const ORowSetValue &thisColVal = rRow.get()[nPos]->get();
+ const bool thisColIsBound = thisColVal.isBound();
+ const bool thisColIsNull = !thisColIsBound || thisColVal.isNull();
// don't overwrite non-bound columns
- if ( ! (bForceAllFields || rRow.get()[nPos]->isBound()) )
+ if ( ! (bForceAllFields || thisColIsBound) )
{
// No - don't overwrite this field, it has not changed.
nByteOffset += nLen;
@@ -1828,14 +1831,14 @@ sal_Bool ODbaseTable::UpdateBuffer(OValueRefVector& rRow, OValueRefRow pOrgRow,
ODbaseIndex* pIndex = reinterpret_cast< ODbaseIndex* >( xTunnel->getSomething(ODbaseIndex::getUnoTunnelImplementationId()) );
OSL_ENSURE(pIndex,"ODbaseTable::UpdateBuffer: No Index returned!");
// Update !!
- if (pOrgRow.is() && rRow.get()[nPos]->isBound() && !rRow.get()[nPos]->getValue().isNull() )
- pIndex->Update(m_nFilePos,*(pOrgRow->get())[nPos],*rRow.get()[nPos]);
+ if (pOrgRow.is() && !thisColIsNull)
+ pIndex->Update(m_nFilePos, *(pOrgRow->get())[nPos], thisColVal);
else
- pIndex->Insert(m_nFilePos,*rRow.get()[nPos]);
+ pIndex->Insert(m_nFilePos, thisColVal);
}
char* pData = (char *)(m_pBuffer + nByteOffset);
- if (rRow.get()[nPos]->getValue().isNull() || !rRow.get()[nPos]->isBound())
+ if (thisColIsNull)
{
if ( bSetZero )
memset(pData,0,nLen); // Clear to NULL char ('\0')
@@ -1853,7 +1856,7 @@ sal_Bool ODbaseTable::UpdateBuffer(OValueRefVector& rRow, OValueRefRow pOrgRow,
case DataType::TIMESTAMP:
{
sal_Int32 nJulianDate = 0, nJulianTime = 0;
- lcl_CalcJulDate(nJulianDate,nJulianTime,rRow.get()[nPos]->getValue());
+ lcl_CalcJulDate(nJulianDate,nJulianTime, thisColVal);
// Exactly 8 bytes to copy:
memcpy(pData,&nJulianDate,4);
memcpy(pData+4,&nJulianTime,4);
@@ -1862,10 +1865,10 @@ sal_Bool ODbaseTable::UpdateBuffer(OValueRefVector& rRow, OValueRefRow pOrgRow,
case DataType::DATE:
{
::com::sun::star::util::Date aDate;
- if(rRow.get()[nPos]->getValue().getTypeKind() == DataType::DOUBLE)
- aDate = ::dbtools::DBTypeConversion::toDate(rRow.get()[nPos]->getValue().getDouble());
+ if(thisColVal.getTypeKind() == DataType::DOUBLE)
+ aDate = ::dbtools::DBTypeConversion::toDate(thisColVal.getDouble());
else
- aDate = rRow.get()[nPos]->getValue();
+ aDate = thisColVal;
char s[9];
snprintf(s,
sizeof(s),
@@ -1879,13 +1882,13 @@ sal_Bool ODbaseTable::UpdateBuffer(OValueRefVector& rRow, OValueRefRow pOrgRow,
} break;
case DataType::INTEGER:
{
- sal_Int32 nValue = rRow.get()[nPos]->getValue();
+ sal_Int32 nValue = thisColVal;
memcpy(pData,&nValue,nLen);
}
break;
case DataType::DOUBLE:
{
- const double d = rRow.get()[nPos]->getValue();
+ const double d = thisColVal;
m_pColumns->getByIndex(i) >>= xCol;
if (getBOOL(xCol->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_ISCURRENCY)))) // Currency is treated separately
@@ -1905,7 +1908,7 @@ sal_Bool ODbaseTable::UpdateBuffer(OValueRefVector& rRow, OValueRefRow pOrgRow,
{
memset(pData,' ',nLen); // Clear to NULL
- const double n = rRow.get()[nPos]->getValue();
+ const double n = thisColVal;
// one, because const_cast GetFormatPrecision on SvNumberFormat is not constant,
// even though it really could and should be
@@ -1937,7 +1940,7 @@ sal_Bool ODbaseTable::UpdateBuffer(OValueRefVector& rRow, OValueRefRow pOrgRow,
}
} break;
case DataType::BIT:
- *pData = rRow.get()[nPos]->getValue().getBool() ? 'T' : 'F';
+ *pData = thisColVal.getBool() ? 'T' : 'F';
break;
case DataType::LONGVARBINARY:
case DataType::LONGVARCHAR:
@@ -1949,7 +1952,7 @@ sal_Bool ODbaseTable::UpdateBuffer(OValueRefVector& rRow, OValueRefRow pOrgRow,
// Next initial character restore again:
pData[nLen] = cNext;
- if (!m_pMemoStream || !WriteMemo(rRow.get()[nPos]->get(), nBlockNo))
+ if (!m_pMemoStream || !WriteMemo(thisColVal, nBlockNo))
break;
rtl::OString aBlock(rtl::OString::valueOf(static_cast<sal_Int32>(nBlockNo)));
@@ -1965,7 +1968,7 @@ sal_Bool ODbaseTable::UpdateBuffer(OValueRefVector& rRow, OValueRefRow pOrgRow,
{
memset(pData,' ',nLen); // Clear to NULL
- ::rtl::OUString sStringToWrite( rRow.get()[nPos]->getValue().getString() );
+ ::rtl::OUString sStringToWrite( thisColVal.getString() );
// convert the string, using the connection's encoding
::rtl::OString sEncoded;
commit 77e60c005812968af9885c20fac0a098012fbeba
Author: Lionel Elie Mamane <lionel at mamane.lu>
Date: Thu Oct 25 11:16:24 2012 +0200
fdo#52392 dbase: correctly NULL out non-filled in fields in inserted rows
Change-Id: Id2e8ad5b6bed1c184de6dccf7fa43254099fb958
diff --git a/connectivity/source/drivers/dbase/DTable.cxx b/connectivity/source/drivers/dbase/DTable.cxx
index dee73fa..e88a7c1 100644
--- a/connectivity/source/drivers/dbase/DTable.cxx
+++ b/connectivity/source/drivers/dbase/DTable.cxx
@@ -1505,7 +1505,7 @@ sal_Bool ODbaseTable::InsertRow(OValueRefVector& rRow, sal_Bool bFlush,const Ref
sal_uInt32 nTempPos = m_nFilePos;
m_nFilePos = (sal_uIntPtr)m_aHeader.db_anz + 1;
- sal_Bool bInsertRow = UpdateBuffer( rRow, NULL, _xCols );
+ sal_Bool bInsertRow = UpdateBuffer( rRow, NULL, _xCols, true );
if ( bInsertRow )
{
sal_uInt32 nFileSize = 0, nMemoFileSize = 0;
@@ -1567,7 +1567,7 @@ sal_Bool ODbaseTable::UpdateRow(OValueRefVector& rRow, OValueRefRow& pOrgRow,con
m_pMemoStream->Seek(STREAM_SEEK_TO_END);
nMemoFileSize = m_pMemoStream->Tell();
}
- if (!UpdateBuffer(rRow, pOrgRow,_xCols) || !WriteBuffer())
+ if (!UpdateBuffer(rRow, pOrgRow, _xCols, false) || !WriteBuffer())
{
if (HasMemoFields() && m_pMemoStream)
m_pMemoStream->SetStreamSize(nMemoFileSize); // restore old size
@@ -1668,7 +1668,7 @@ static double toDouble(const rtl::OString& rString)
}
//------------------------------------------------------------------
-sal_Bool ODbaseTable::UpdateBuffer(OValueRefVector& rRow, OValueRefRow pOrgRow,const Reference<XIndexAccess>& _xCols)
+sal_Bool ODbaseTable::UpdateBuffer(OValueRefVector& rRow, OValueRefRow pOrgRow, const Reference<XIndexAccess>& _xCols, const bool bForceAllFields)
{
RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen at sun.com", "ODbaseTable::UpdateBuffer" );
OSL_ENSURE(m_pBuffer,"Buffer is NULL!");
@@ -1814,10 +1814,10 @@ sal_Bool ODbaseTable::UpdateBuffer(OValueRefVector& rRow, OValueRefRow pOrgRow,c
++nPos; // the row values start at 1
- // If the variable is bound at all?
- if ( !rRow.get()[nPos]->isBound() )
+ // don't overwrite non-bound columns
+ if ( ! (bForceAllFields || rRow.get()[nPos]->isBound()) )
{
- // No - the next field.
+ // No - don't overwrite this field, it has not changed.
nByteOffset += nLen;
continue;
}
@@ -1828,14 +1828,14 @@ sal_Bool ODbaseTable::UpdateBuffer(OValueRefVector& rRow, OValueRefRow pOrgRow,c
ODbaseIndex* pIndex = reinterpret_cast< ODbaseIndex* >( xTunnel->getSomething(ODbaseIndex::getUnoTunnelImplementationId()) );
OSL_ENSURE(pIndex,"ODbaseTable::UpdateBuffer: No Index returned!");
// Update !!
- if (pOrgRow.is() && !rRow.get()[nPos]->getValue().isNull() )
+ if (pOrgRow.is() && rRow.get()[nPos]->isBound() && !rRow.get()[nPos]->getValue().isNull() )
pIndex->Update(m_nFilePos,*(pOrgRow->get())[nPos],*rRow.get()[nPos]);
else
pIndex->Insert(m_nFilePos,*rRow.get()[nPos]);
}
char* pData = (char *)(m_pBuffer + nByteOffset);
- if (rRow.get()[nPos]->getValue().isNull())
+ if (rRow.get()[nPos]->getValue().isNull() || !rRow.get()[nPos]->isBound())
{
if ( bSetZero )
memset(pData,0,nLen); // Clear to NULL char ('\0')
diff --git a/connectivity/source/inc/dbase/DTable.hxx b/connectivity/source/inc/dbase/DTable.hxx
index 334a814..691b654 100644
--- a/connectivity/source/inc/dbase/DTable.hxx
+++ b/connectivity/source/inc/dbase/DTable.hxx
@@ -107,7 +107,7 @@ namespace connectivity
sal_Bool WriteMemo(const ORowSetValue& aVariable, sal_uIntPtr& rBlockNr);
sal_Bool WriteBuffer();
- sal_Bool UpdateBuffer(OValueRefVector& rRow, OValueRefRow pOrgRow,const ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexAccess>& _xCols);
+ sal_Bool UpdateBuffer(OValueRefVector& rRow, OValueRefRow pOrgRow,const ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexAccess>& _xCols, bool bForceAllFields);
::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet> isUniqueByColumnName(sal_Int32 _nColumnPos);
void AllocBuffer();
commit 41e11da6008f046d0f3f3705939775d8bcd6e712
Author: Lionel Elie Mamane <lionel at mamane.lu>
Date: Thu Oct 25 10:15:39 2012 +0200
improve comments
Change-Id: I50c64d5fcf1d642052be5edbe64dde2c03c1eba9
diff --git a/connectivity/source/drivers/dbase/DTable.cxx b/connectivity/source/drivers/dbase/DTable.cxx
index 078d630..dee73fa 100644
--- a/connectivity/source/drivers/dbase/DTable.cxx
+++ b/connectivity/source/drivers/dbase/DTable.cxx
@@ -1838,9 +1838,9 @@ sal_Bool ODbaseTable::UpdateBuffer(OValueRefVector& rRow, OValueRefRow pOrgRow,c
if (rRow.get()[nPos]->getValue().isNull())
{
if ( bSetZero )
- memset(pData,0,nLen); // Clear to NULL
+ memset(pData,0,nLen); // Clear to NULL char ('\0')
else
- memset(pData,' ',nLen); // Clear to NULL
+ memset(pData,' ',nLen); // Clear to space/blank ('\0x20')
nByteOffset += nLen;
OSL_ENSURE( nByteOffset <= m_nBufferSize ,"ByteOffset > m_nBufferSize!");
continue;
commit bacc03791d45d6f079fdf606d772ada32c108ae6
Author: Lionel Elie Mamane <lionel at mamane.lu>
Date: Thu Oct 25 10:10:15 2012 +0200
dbase::ODbaseTable::WriteMemo does not change its ORowSetValue& argument
Change-Id: Icf6a71900d79377cde84c2307ce85a9b3c96a54f
diff --git a/connectivity/source/drivers/dbase/DTable.cxx b/connectivity/source/drivers/dbase/DTable.cxx
index 28d4436..078d630 100644
--- a/connectivity/source/drivers/dbase/DTable.cxx
+++ b/connectivity/source/drivers/dbase/DTable.cxx
@@ -2002,7 +2002,7 @@ sal_Bool ODbaseTable::UpdateBuffer(OValueRefVector& rRow, OValueRefRow pOrgRow,c
}
// -----------------------------------------------------------------------------
-sal_Bool ODbaseTable::WriteMemo(ORowSetValue& aVariable, sal_uIntPtr& rBlockNr)
+sal_Bool ODbaseTable::WriteMemo(const ORowSetValue& aVariable, sal_uIntPtr& rBlockNr)
{
RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen at sun.com", "ODbaseTable::WriteMemo" );
// if the BlockNo 0 is given, the block will be appended at the end
diff --git a/connectivity/source/inc/dbase/DTable.hxx b/connectivity/source/inc/dbase/DTable.hxx
index ad352d0..334a814 100644
--- a/connectivity/source/inc/dbase/DTable.hxx
+++ b/connectivity/source/inc/dbase/DTable.hxx
@@ -105,7 +105,7 @@ namespace connectivity
sal_Bool ReadMemoHeader();
sal_Bool ReadMemo(sal_uIntPtr nBlockNo, ORowSetValue& aVariable);
- sal_Bool WriteMemo(ORowSetValue& aVariable, sal_uIntPtr& rBlockNr);
+ sal_Bool WriteMemo(const ORowSetValue& aVariable, sal_uIntPtr& rBlockNr);
sal_Bool WriteBuffer();
sal_Bool UpdateBuffer(OValueRefVector& rRow, OValueRefRow pOrgRow,const ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexAccess>& _xCols);
::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet> isUniqueByColumnName(sal_Int32 _nColumnPos);
More information about the Libreoffice-commits
mailing list