LCOV - code coverage report
Current view: top level - connectivity/source/drivers/odbc - OPreparedStatement.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 374 0.0 %
Date: 2014-04-14 Functions: 0 63 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : 
      21             : #include <stdio.h>
      22             : #include <string.h>
      23             : #include <osl/diagnose.h>
      24             : #include "diagnose_ex.h"
      25             : #include "odbc/OPreparedStatement.hxx"
      26             : #include "odbc/OBoundParam.hxx"
      27             : #include <com/sun/star/sdbc/DataType.hpp>
      28             : #include "odbc/OTools.hxx"
      29             : #include "odbc/ODriver.hxx"
      30             : #include "odbc/OResultSet.hxx"
      31             : #include "odbc/OResultSetMetaData.hxx"
      32             : #include <cppuhelper/typeprovider.hxx>
      33             : #include <comphelper/processfactory.hxx>
      34             : #include <comphelper/sequence.hxx>
      35             : #include <com/sun/star/lang/DisposedException.hpp>
      36             : #include "connectivity/dbtools.hxx"
      37             : #include <comphelper/types.hxx>
      38             : #include "connectivity/FValue.hxx"
      39             : #include "resource/common_res.hrc"
      40             : #include "connectivity/sqlparse.hxx"
      41             : #include <boost/scoped_ptr.hpp>
      42             : #include <boost/type_traits/remove_reference.hpp>
      43             : #include <boost/type_traits/is_same.hpp>
      44             : 
      45             : using namespace ::comphelper;
      46             : using namespace connectivity;
      47             : using namespace connectivity::odbc;
      48             : using namespace com::sun::star::uno;
      49             : using namespace com::sun::star::lang;
      50             : using namespace com::sun::star::beans;
      51             : using namespace com::sun::star::sdbc;
      52             : using namespace com::sun::star::sdbcx;
      53             : using namespace com::sun::star::container;
      54             : using namespace com::sun::star::io;
      55             : using namespace com::sun::star::util;
      56             : 
      57           0 : IMPLEMENT_SERVICE_INFO(OPreparedStatement,"com.sun.star.sdbcx.OPreparedStatement","com.sun.star.sdbc.PreparedStatement");
      58             : 
      59             : namespace
      60             : {
      61             :     // for now, never use wchar,
      62             :     // but most of code is prepared to handle it
      63             :     // in case we make this configurable
      64             :     const bool useWChar = false;
      65             : }
      66             : 
      67           0 : OPreparedStatement::OPreparedStatement( OConnection* _pConnection,const OUString& sql)
      68             :     :OStatement_BASE2(_pConnection)
      69             :     ,numParams(0)
      70             :     ,boundParams(NULL)
      71           0 :     ,m_bPrepared(sal_False)
      72             : {
      73           0 :     m_sSqlStatement = sql;
      74             :     try
      75             :     {
      76           0 :         if(_pConnection->isParameterSubstitutionEnabled())
      77             :         {
      78           0 :             OSQLParser aParser( comphelper::getComponentContext(_pConnection->getDriver()->getORB()) );
      79           0 :             OUString sErrorMessage;
      80           0 :             OUString sNewSql;
      81           0 :             boost::scoped_ptr<OSQLParseNode> pNode( aParser.parseTree(sErrorMessage,sql) );
      82           0 :             if ( pNode.get() )
      83             :             {   // special handling for parameters
      84           0 :                 OSQLParseNode::substituteParameterNames(pNode.get());
      85           0 :                 pNode->parseNodeToStr( sNewSql, _pConnection );
      86           0 :                 m_sSqlStatement = sNewSql;
      87           0 :             }
      88             :         }
      89             :     }
      90           0 :     catch(Exception&)
      91             :     {
      92             :     }
      93           0 : }
      94             : 
      95           0 : void SAL_CALL OPreparedStatement::acquire() throw()
      96             : {
      97           0 :     OStatement_BASE2::acquire();
      98           0 : }
      99             : 
     100           0 : void SAL_CALL OPreparedStatement::release() throw()
     101             : {
     102           0 :     OStatement_BASE2::release();
     103           0 : }
     104             : 
     105           0 : Any SAL_CALL OPreparedStatement::queryInterface( const Type & rType ) throw(RuntimeException, std::exception)
     106             : {
     107           0 :     Any aRet = OStatement_BASE2::queryInterface(rType);
     108           0 :     return aRet.hasValue() ? aRet : OPreparedStatement_BASE::queryInterface(rType);
     109             : }
     110             : 
     111           0 : ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL OPreparedStatement::getTypes(  ) throw(::com::sun::star::uno::RuntimeException, std::exception)
     112             : {
     113           0 :     return ::comphelper::concatSequences(OPreparedStatement_BASE::getTypes(),OStatement_BASE2::getTypes());
     114             : }
     115             : 
     116             : 
     117           0 : Reference< XResultSetMetaData > SAL_CALL OPreparedStatement::getMetaData(  ) throw(SQLException, RuntimeException, std::exception)
     118             : {
     119           0 :     ::osl::MutexGuard aGuard( m_aMutex );
     120           0 :     checkDisposed(OStatement_BASE::rBHelper.bDisposed);
     121             : 
     122             : 
     123           0 :     prepareStatement();
     124             :     OSL_ENSURE(m_aStatementHandle,"StatementHandle is null!");
     125           0 :     if(!m_xMetaData.is())
     126           0 :         m_xMetaData = new OResultSetMetaData(getOwnConnection(),m_aStatementHandle);
     127           0 :     return m_xMetaData;
     128             : }
     129             : 
     130             : 
     131           0 : void SAL_CALL OPreparedStatement::close(  ) throw(SQLException, RuntimeException, std::exception)
     132             : {
     133           0 :     ::osl::MutexGuard aGuard( m_aMutex );
     134           0 :     checkDisposed(OStatement_BASE::rBHelper.bDisposed);
     135             : 
     136             : 
     137             :     // Close/clear our result set
     138           0 :     clearMyResultSet ();
     139             : 
     140             :     // Reset last warning message
     141             : 
     142             :     try {
     143           0 :         clearWarnings ();
     144           0 :         OStatement_BASE2::close();
     145           0 :         FreeParams();
     146             :     }
     147           0 :     catch (SQLException &) {
     148             :         // If we get an error, ignore
     149           0 :     }
     150             : 
     151             :     // Remove this Statement object from the Connection object's
     152             :     // list
     153           0 : }
     154             : 
     155             : 
     156           0 : sal_Bool SAL_CALL OPreparedStatement::execute(  ) throw(SQLException, RuntimeException, std::exception)
     157             : {
     158           0 :     ::osl::MutexGuard aGuard( m_aMutex );
     159           0 :     checkDisposed(OStatement_BASE::rBHelper.bDisposed);
     160             : 
     161             : 
     162           0 :     sal_Bool needData = sal_False;
     163             : 
     164             :     // Reset warnings
     165             : 
     166           0 :     clearWarnings ();
     167             : 
     168             :     // Reset the statement handle, warning and saved Resultset
     169             : 
     170           0 :     reset();
     171             : 
     172             :     // Call SQLExecute
     173           0 :     prepareStatement();
     174             : 
     175             :     OSL_ENSURE(m_aStatementHandle,"StatementHandle is null!");
     176             :     try
     177             :     {
     178           0 :         SQLRETURN nReturn = N3SQLExecute(m_aStatementHandle);
     179             : 
     180           0 :         OTools::ThrowException(m_pConnection,nReturn,m_aStatementHandle,SQL_HANDLE_STMT,*this);
     181           0 :         needData = nReturn == SQL_NEED_DATA;
     182             : 
     183             :         // Now loop while more data is needed (i.e. a data-at-
     184             :         // execution parameter was given).  For each parameter
     185             :         // that needs data, put the data from the input stream.
     186             : 
     187           0 :         while (needData) {
     188             : 
     189             :             // Get the parameter number that requires data
     190             : 
     191           0 :             sal_Int32* paramIndex = 0;
     192           0 :             nReturn = N3SQLParamData(m_aStatementHandle,(SQLPOINTER*)&paramIndex);
     193             : 
     194             :             // If the parameter index is -1, there is no
     195             :             // more data required
     196             : 
     197           0 :             if ( !paramIndex || ( *paramIndex == -1 ) )
     198           0 :                 needData = sal_False;
     199             :             else
     200             :             {
     201             :                 // Now we have the proper parameter
     202             :                 // index, get the data from the input
     203             :                 // stream and do a SQLPutData
     204           0 :                 putParamData (*paramIndex);
     205             :             }
     206             :         }
     207             : 
     208             :     }
     209           0 :     catch (const SQLWarning&)
     210             :     {
     211             :     }
     212             : 
     213             :     // Now determine if there is a result set associated with
     214             :     // the SQL statement that was executed.  Get the column
     215             :     // count, and if it is not zero, there is a result set.
     216             : 
     217             : 
     218           0 :     return getColumnCount() > 0;
     219             : }
     220             : 
     221             : 
     222           0 : sal_Int32 SAL_CALL OPreparedStatement::executeUpdate(  ) throw(SQLException, RuntimeException, std::exception)
     223             : {
     224           0 :     ::osl::MutexGuard aGuard( m_aMutex );
     225           0 :     checkDisposed(OStatement_BASE::rBHelper.bDisposed);
     226             : 
     227           0 :     sal_Int32 numRows = -1;
     228             : 
     229           0 :     prepareStatement();
     230             :     // Execute the statement.  If execute returns sal_False, a
     231             :     // row count exists.
     232             : 
     233           0 :     if (!execute())
     234           0 :         numRows = getUpdateCount ();
     235             :     else
     236             :     {
     237             :         // No update count was produced (a ResultSet was).  Raise
     238             :         // an exception
     239           0 :         m_pConnection->throwGenericSQLException(STR_NO_ROWCOUNT,*this);
     240             :     }
     241           0 :     return numRows;
     242             : }
     243             : 
     244             : 
     245           0 : void SAL_CALL OPreparedStatement::setString( sal_Int32 parameterIndex, const OUString& x ) throw(SQLException, RuntimeException, std::exception)
     246             : {
     247           0 :     setParameter(parameterIndex, DataType::CHAR, invalid_scale, x);
     248           0 : }
     249             : 
     250             : 
     251           0 : Reference< XConnection > SAL_CALL OPreparedStatement::getConnection(  ) throw(SQLException, RuntimeException, std::exception)
     252             : {
     253           0 :     ::osl::MutexGuard aGuard( m_aMutex );
     254           0 :     checkDisposed(OStatement_BASE::rBHelper.bDisposed);
     255             : 
     256           0 :     return (Reference< XConnection >)m_pConnection;
     257             : }
     258             : 
     259             : 
     260           0 : Reference< XResultSet > SAL_CALL OPreparedStatement::executeQuery(  ) throw(SQLException, RuntimeException, std::exception)
     261             : {
     262           0 :     ::osl::MutexGuard aGuard( m_aMutex );
     263           0 :     checkDisposed(OStatement_BASE::rBHelper.bDisposed);
     264             : 
     265           0 :     Reference< XResultSet > rs = NULL;
     266             : 
     267           0 :     prepareStatement();
     268             : 
     269           0 :     if (execute())
     270           0 :         rs = getResultSet(sal_False);
     271             :     else
     272             :     {
     273             :         // No ResultSet was produced.  Raise an exception
     274           0 :         m_pConnection->throwGenericSQLException(STR_NO_RESULTSET,*this);
     275             :     }
     276           0 :     return rs;
     277             : }
     278             : 
     279             : 
     280           0 : void SAL_CALL OPreparedStatement::setBoolean( sal_Int32 parameterIndex, sal_Bool x ) throw(SQLException, RuntimeException, std::exception)
     281             : {
     282             :     // Set the parameter as if it were an integer
     283           0 :     setInt (parameterIndex, x ? 1 : 0 );
     284           0 : }
     285             : 
     286             : // The MutexGuard must _already_ be taken!
     287           0 : void OPreparedStatement::setParameterPre(sal_Int32 parameterIndex)
     288             : {
     289           0 :     checkDisposed(OStatement_BASE::rBHelper.bDisposed);
     290           0 :     prepareStatement();
     291           0 :     checkParameterIndex(parameterIndex);
     292             :     OSL_ENSURE(m_aStatementHandle,"StatementHandle is null!");
     293           0 : }
     294             : 
     295             : 
     296           0 : template <typename T> void OPreparedStatement::setScalarParameter(const sal_Int32 parameterIndex, const sal_Int32 i_nType, const SQLULEN i_nColSize, const T i_Value)
     297             : {
     298           0 :     ::osl::MutexGuard aGuard( m_aMutex );
     299           0 :     setParameterPre(parameterIndex);
     300             : 
     301             :     typedef typename boost::remove_reference< T >::type TnoRef;
     302             : 
     303           0 :     TnoRef *bindBuf = static_cast< TnoRef* >( allocBindBuf(parameterIndex, sizeof(i_Value)) );
     304           0 :     *bindBuf = i_Value;
     305             : 
     306           0 :     setParameter(parameterIndex, i_nType, i_nColSize, invalid_scale, bindBuf, sizeof(i_Value), sizeof(i_Value));
     307           0 : }
     308             : 
     309             : 
     310           0 : void OPreparedStatement::setParameter(const sal_Int32 parameterIndex, const sal_Int32 _nType, const sal_Int16 _nScale, const OUString &_sData)
     311             : {
     312           0 :     ::osl::MutexGuard aGuard( m_aMutex );
     313           0 :     setParameterPre(parameterIndex);
     314             : 
     315             :     assert (_nType == DataType::VARCHAR || _nType == DataType::CHAR || _nType == DataType::DECIMAL || _nType == DataType::NUMERIC);
     316             : 
     317             :     sal_Int32 nCharLen;
     318             :     sal_Int32 nByteLen;
     319             :     void *pData;
     320             :     if (useWChar)
     321             :     {
     322             :         /*
     323             :          * On Windows, wchar is 16 bits (UTF-16 encoding), the ODBC "W" variants functions take UTF-16 encoded strings
     324             :          * and character lengths are number of UTF-16 codepoints.
     325             :          * Reference: http://msdn.microsoft.com/en-us/library/windows/desktop/ms716246%28v=vs.85%29.aspx
     326             :          * ODBC Programmer's reference > Developing Applications > Programming Considerations > Unicode >  Unicode Function Arguments
     327             :          *            http://support.microsoft.com/kb/294169
     328             :          *
     329             :          * UnixODBC can be configured at compile-time so that the "W" variants expect
     330             :          * UTF-16 or UTF-32 encoded strings, and character lengths are number of codepoints.
     331             :          * However, UTF-16 is the default, what all/most distributions do
     332             :          * and the established API that most drivers implement.
     333             :          * As wchar is often 32 bits, this differs from C-style strings of wchar!
     334             :          *
     335             :          * Our internal OUString storage is always UTF-16, so no conversion to do here.
     336             :          */
     337             :         BOOST_STATIC_ASSERT( sizeof(sal_Unicode) == 2 );
     338             :         BOOST_STATIC_ASSERT( sizeof(SQLWCHAR)    == 2 );
     339             :         nCharLen = _sData.getLength();
     340             :         nByteLen = nCharLen * sizeof(sal_Unicode);
     341             :         pData = allocBindBuf(parameterIndex, nByteLen);
     342             :         memcpy(pData, _sData.getStr(), nByteLen);
     343             :     }
     344             :     else
     345             :     {
     346           0 :         OString sOData( OUStringToOString(_sData, getOwnConnection()->getTextEncoding()) );
     347           0 :         nCharLen = sOData.getLength();
     348           0 :         nByteLen = nCharLen;
     349           0 :         pData = allocBindBuf(parameterIndex, nByteLen);
     350           0 :         memcpy(pData, sOData.getStr(), nByteLen);
     351             :     }
     352             : 
     353           0 :     setParameter( parameterIndex, _nType, nCharLen, _nScale, pData, nByteLen, nByteLen );
     354           0 : }
     355             : 
     356           0 : void OPreparedStatement::setParameter(const sal_Int32 parameterIndex, const sal_Int32 _nType, const Sequence< sal_Int8 > &x)
     357             : {
     358           0 :     ::osl::MutexGuard aGuard( m_aMutex );
     359           0 :     setParameterPre(parameterIndex);
     360             : 
     361             :     assert(_nType == DataType::BINARY || _nType == DataType::VARBINARY);
     362             : 
     363             :     // don't copy the sequence, just point the ODBC directly at the sequence's storage array
     364             :     // Why BINARY/Sequence is treated differently than strings (which are copied), I'm not sure
     365           0 :     OSL_VERIFY(allocBindBuf(parameterIndex, 0) == NULL);
     366           0 :     boundParams[parameterIndex-1].setSequence(x); // this ensures that the sequence stays alive
     367             : 
     368           0 :     setParameter( parameterIndex, _nType, x.getLength(), invalid_scale, x.getConstArray(), x.getLength(), x.getLength() );
     369           0 : }
     370             : 
     371           0 : 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)
     372             : {
     373             :     SQLSMALLINT fCType, fSqlType;
     374           0 :     OTools::getBindTypes(useWChar, m_pConnection->useOldDateFormat(), OTools::jdbcTypeToOdbc(_nType), fCType, fSqlType);
     375             : 
     376           0 :     SQLLEN *pDataLen=boundParams[parameterIndex-1].getBindLengthBuffer();
     377           0 :     *pDataLen=_nDataLen;
     378             : 
     379             :     SQLRETURN nRetcode;
     380           0 :     nRetcode = (*(T3SQLBindParameter)m_pConnection->getOdbcFunction(ODBC3SQLBindParameter))(
     381             :                   m_aStatementHandle,
     382             :                   // checkParameterIndex guarantees this is safe
     383             :                   static_cast<SQLUSMALLINT>(parameterIndex),
     384             :                   SQL_PARAM_INPUT,
     385             :                   fCType,
     386             :                   fSqlType,
     387             :                   _nColumnSize,
     388             :                   _nScale,
     389             :                   // we trust the ODBC driver not to touch it because SQL_PARAM_INPUT
     390             :                   const_cast<void*>(_pData),
     391             :                   _nDataAllocLen,
     392           0 :                   pDataLen);
     393             : 
     394           0 :     OTools::ThrowException(m_pConnection, nRetcode, m_aStatementHandle, SQL_HANDLE_STMT, *this);
     395           0 : }
     396             : 
     397           0 : void SAL_CALL OPreparedStatement::setByte( const sal_Int32 parameterIndex, const sal_Int8 x ) throw(SQLException, RuntimeException, std::exception)
     398             : {
     399           0 :     setScalarParameter(parameterIndex, DataType::TINYINT, 3, x);
     400           0 : }
     401             : 
     402             : // For older compilers (that do not support partial specialisation of class templates)
     403             : // uncomment if necessary (safe also on compilers that *do* support partial specialisation)
     404             : //BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION(DATE_STRUCT);
     405             : //BOOST_STATIC_ASSERT((boost::is_same<DATE_STRUCT, boost::remove_reference<DATE_STRUCT&>::type>::value));
     406           0 : void SAL_CALL OPreparedStatement::setDate( sal_Int32 parameterIndex, const Date& aData ) throw(SQLException, RuntimeException, std::exception)
     407             : {
     408           0 :     DATE_STRUCT x(OTools::DateToOdbcDate(aData));
     409           0 :     setScalarParameter<DATE_STRUCT&>(parameterIndex, DataType::DATE, 10, x);
     410           0 : }
     411             : 
     412             : 
     413           0 : void SAL_CALL OPreparedStatement::setTime( sal_Int32 parameterIndex, const Time& aVal ) throw(SQLException, RuntimeException, std::exception)
     414             : {
     415             :     SQLULEN nColSize;
     416           0 :     if(aVal.NanoSeconds == 0)
     417           0 :         nColSize = 8;
     418           0 :     else if(aVal.NanoSeconds % 100000000 == 0)
     419           0 :         nColSize = 10;
     420           0 :     else if(aVal.NanoSeconds % 10000000 == 0)
     421           0 :         nColSize = 11;
     422           0 :     else if(aVal.NanoSeconds % 1000000 == 0)
     423           0 :         nColSize = 12;
     424           0 :     else if(aVal.NanoSeconds % 100000 == 0)
     425           0 :         nColSize = 13;
     426           0 :     else if(aVal.NanoSeconds % 10000 == 0)
     427           0 :         nColSize = 14;
     428           0 :     else if(aVal.NanoSeconds % 1000 == 0)
     429           0 :         nColSize = 15;
     430           0 :     else if(aVal.NanoSeconds % 100 == 0)
     431           0 :         nColSize = 16;
     432           0 :     else if(aVal.NanoSeconds % 10 == 0)
     433           0 :         nColSize = 17;
     434             :     else
     435           0 :         nColSize = 18;
     436           0 :     TIME_STRUCT x(OTools::TimeToOdbcTime(aVal));
     437           0 :     setScalarParameter<TIME_STRUCT&>(parameterIndex, DataType::TIME, nColSize, x);
     438           0 : }
     439             : 
     440             : 
     441           0 : void SAL_CALL OPreparedStatement::setTimestamp( sal_Int32 parameterIndex, const DateTime& aVal ) throw(SQLException, RuntimeException, std::exception)
     442             : {
     443             :     SQLULEN nColSize;
     444           0 :     if(aVal.NanoSeconds == 0)
     445             :     {
     446           0 :         if (aVal.Seconds == 0)
     447           0 :             nColSize=16;
     448             :         else
     449           0 :             nColSize=19;
     450             :     }
     451           0 :     else if(aVal.NanoSeconds % 100000000 == 0)
     452           0 :         nColSize = 21;
     453           0 :     else if(aVal.NanoSeconds % 10000000 == 0)
     454           0 :         nColSize = 22;
     455           0 :     else if(aVal.NanoSeconds % 1000000 == 0)
     456           0 :         nColSize = 23;
     457           0 :     else if(aVal.NanoSeconds % 100000 == 0)
     458           0 :         nColSize = 24;
     459           0 :     else if(aVal.NanoSeconds % 10000 == 0)
     460           0 :         nColSize = 25;
     461           0 :     else if(aVal.NanoSeconds % 1000 == 0)
     462           0 :         nColSize = 26;
     463           0 :     else if(aVal.NanoSeconds % 100 == 0)
     464           0 :         nColSize = 27;
     465           0 :     else if(aVal.NanoSeconds % 10 == 0)
     466           0 :         nColSize = 28;
     467             :     else
     468           0 :         nColSize = 29;
     469             : 
     470           0 :     TIMESTAMP_STRUCT x(OTools::DateTimeToTimestamp(aVal));
     471           0 :     setScalarParameter<TIMESTAMP_STRUCT&>(parameterIndex, DataType::TIMESTAMP, nColSize, x);
     472           0 : }
     473             : 
     474             : 
     475           0 : void SAL_CALL OPreparedStatement::setDouble( sal_Int32 parameterIndex, double x ) throw(SQLException, RuntimeException, std::exception)
     476             : {
     477           0 :     setScalarParameter(parameterIndex, DataType::DOUBLE, 15, x);
     478           0 : }
     479             : 
     480             : 
     481             : 
     482           0 : void SAL_CALL OPreparedStatement::setFloat( sal_Int32 parameterIndex, float x ) throw(SQLException, RuntimeException, std::exception)
     483             : {
     484           0 :     setScalarParameter(parameterIndex, DataType::FLOAT, 15, x);
     485           0 : }
     486             : 
     487             : 
     488           0 : void SAL_CALL OPreparedStatement::setInt( sal_Int32 parameterIndex, sal_Int32 x ) throw(SQLException, RuntimeException, std::exception)
     489             : {
     490           0 :     setScalarParameter(parameterIndex, DataType::INTEGER, 10, x);
     491           0 : }
     492             : 
     493             : 
     494           0 : void SAL_CALL OPreparedStatement::setLong( sal_Int32 parameterIndex, sal_Int64 x ) throw(SQLException, RuntimeException, std::exception)
     495             : {
     496             :     try
     497             :     {
     498           0 :         setScalarParameter(parameterIndex, DataType::BIGINT, 19, x);
     499             :     }
     500           0 :     catch(SQLException&)
     501             :     {
     502           0 :         setString(parameterIndex, ORowSetValue(x));
     503             :     }
     504           0 : }
     505             : 
     506             : 
     507           0 : void SAL_CALL OPreparedStatement::setNull( sal_Int32 parameterIndex, const sal_Int32 _nType ) throw(SQLException, RuntimeException, std::exception)
     508             : {
     509           0 :     ::osl::MutexGuard aGuard( m_aMutex );
     510           0 :     setParameterPre(parameterIndex);
     511             : 
     512           0 :     OSL_VERIFY(allocBindBuf(parameterIndex, 0) == NULL);
     513           0 :     SQLLEN * const lenBuf = getLengthBuf (parameterIndex);
     514           0 :     *lenBuf = SQL_NULL_DATA;
     515             : 
     516             : 
     517             :     SQLSMALLINT fCType;
     518             :     SQLSMALLINT fSqlType;
     519             : 
     520             :     OTools::getBindTypes(   useWChar,
     521           0 :                             m_pConnection->useOldDateFormat(),
     522           0 :                             OTools::jdbcTypeToOdbc(_nType),
     523             :                             fCType,
     524           0 :                             fSqlType);
     525             : 
     526           0 :     SQLRETURN nReturn = N3SQLBindParameter( m_aStatementHandle,
     527             :                                             static_cast<SQLUSMALLINT>(parameterIndex),
     528             :                                             SQL_PARAM_INPUT,
     529             :                                             fCType,
     530             :                                             fSqlType,
     531             :                                             0,
     532             :                                             0,
     533             :                                             NULL,
     534             :                                             0,
     535             :                                             lenBuf
     536             :                                             );
     537           0 :     OTools::ThrowException(m_pConnection,nReturn,m_aStatementHandle,SQL_HANDLE_STMT,*this);
     538           0 : }
     539             : 
     540             : 
     541           0 : void SAL_CALL OPreparedStatement::setClob( sal_Int32 parameterIndex, const Reference< XClob >& x ) throw(SQLException, RuntimeException, std::exception)
     542             : {
     543           0 :     if ( x.is() )
     544           0 :         setStream(parameterIndex, x->getCharacterStream(), x->length(), DataType::LONGVARCHAR);
     545           0 : }
     546             : 
     547             : 
     548           0 : void SAL_CALL OPreparedStatement::setBlob( sal_Int32 parameterIndex, const Reference< XBlob >& x ) throw(SQLException, RuntimeException, std::exception)
     549             : {
     550           0 :     if ( x.is() )
     551           0 :         setStream(parameterIndex, x->getBinaryStream(), x->length(), DataType::LONGVARBINARY);
     552           0 : }
     553             : 
     554             : 
     555           0 : void SAL_CALL OPreparedStatement::setArray( sal_Int32 /*parameterIndex*/, const Reference< XArray >& /*x*/ ) throw(SQLException, RuntimeException, std::exception)
     556             : {
     557           0 :     ::dbtools::throwFunctionNotSupportedException( "XParameters::setArray", *this );
     558           0 : }
     559             : 
     560             : 
     561           0 : void SAL_CALL OPreparedStatement::setRef( sal_Int32 /*parameterIndex*/, const Reference< XRef >& /*x*/ ) throw(SQLException, RuntimeException, std::exception)
     562             : {
     563           0 :     ::dbtools::throwFunctionNotSupportedException( "XParameters::setRef", *this );
     564           0 : }
     565             : 
     566           0 : void SAL_CALL OPreparedStatement::setObjectWithInfo( sal_Int32 parameterIndex, const Any& x, sal_Int32 sqlType, sal_Int32 scale ) throw(SQLException, RuntimeException, std::exception)
     567             : {
     568           0 :     checkDisposed(OStatement_BASE::rBHelper.bDisposed);
     569           0 :     ::osl::MutexGuard aGuard( m_aMutex );
     570             : 
     571           0 :     prepareStatement();
     572             :     // For each known SQL Type, call the appropriate
     573             :         // set routine
     574             : 
     575           0 :     switch (sqlType)
     576             :     {
     577             :         case DataType::CHAR:
     578             :         case DataType::VARCHAR:
     579             :         case DataType::LONGVARCHAR:
     580           0 :             if(x.hasValue())
     581             :             {
     582           0 :                 OUString sStr;
     583           0 :                 x >>= sStr;
     584           0 :                 setParameter(parameterIndex, sqlType, scale, sStr);
     585             :             }
     586             :             else
     587           0 :                 setNull(parameterIndex,sqlType);
     588           0 :             break;
     589             :         case DataType::DECIMAL:
     590             :         case DataType::NUMERIC:
     591           0 :             if(x.hasValue())
     592             :             {
     593           0 :                 ORowSetValue aValue;
     594           0 :                 aValue.fill(x);
     595             :                 // TODO: make sure that this calls the string overload
     596           0 :                 setParameter(parameterIndex, sqlType, scale, aValue);
     597             :             }
     598             :             else
     599           0 :                 setNull(parameterIndex,sqlType);
     600           0 :             break;
     601             :         default:
     602           0 :             ::dbtools::setObjectWithInfo(this,parameterIndex,x,sqlType,scale);
     603           0 :         }
     604           0 : }
     605             : 
     606             : 
     607           0 : void SAL_CALL OPreparedStatement::setObjectNull( sal_Int32 parameterIndex, sal_Int32 sqlType, const OUString& /*typeName*/ ) throw(SQLException, RuntimeException, std::exception)
     608             : {
     609           0 :     setNull(parameterIndex,sqlType);
     610           0 : }
     611             : 
     612             : 
     613           0 : void SAL_CALL OPreparedStatement::setObject( sal_Int32 parameterIndex, const Any& x ) throw(SQLException, RuntimeException, std::exception)
     614             : {
     615           0 :     if (!::dbtools::implSetObject(this, parameterIndex, x))
     616             :     {   // there is no other setXXX call which can handle the value in x
     617           0 :         throw SQLException();
     618             :     }
     619           0 : }
     620             : 
     621             : 
     622           0 : void SAL_CALL OPreparedStatement::setShort( sal_Int32 parameterIndex, sal_Int16 x ) throw(SQLException, RuntimeException, std::exception)
     623             : {
     624           0 :     setScalarParameter(parameterIndex, DataType::SMALLINT, 5, x);
     625           0 : }
     626             : 
     627             : 
     628           0 : void SAL_CALL OPreparedStatement::setBytes( sal_Int32 parameterIndex, const Sequence< sal_Int8 >& x ) throw(SQLException, RuntimeException, std::exception)
     629             : {
     630           0 :     setParameter(parameterIndex, DataType::BINARY, x);
     631           0 : }
     632             : 
     633             : 
     634             : 
     635           0 : void SAL_CALL OPreparedStatement::setCharacterStream( sal_Int32 parameterIndex, const Reference< ::com::sun::star::io::XInputStream >& x, sal_Int32 length ) throw(SQLException, RuntimeException, std::exception)
     636             : {
     637             :     // LEM: It is quite unclear to me what the interface here is.
     638             :     // The XInputStream provides *bytes*, not characters.
     639           0 :     setStream(parameterIndex, x, length, DataType::LONGVARCHAR);
     640           0 : }
     641             : 
     642             : 
     643           0 : void SAL_CALL OPreparedStatement::setBinaryStream( sal_Int32 parameterIndex, const Reference< ::com::sun::star::io::XInputStream >& x, sal_Int32 length ) throw(SQLException, RuntimeException, std::exception)
     644             : {
     645           0 :     setStream(parameterIndex, x, length, DataType::LONGVARBINARY);
     646           0 : }
     647             : 
     648             : 
     649           0 : void SAL_CALL OPreparedStatement::clearParameters(  ) throw(SQLException, RuntimeException, std::exception)
     650             : {
     651           0 :     ::osl::MutexGuard aGuard( m_aMutex );
     652           0 :     prepareStatement();
     653             :     OSL_ENSURE(m_aStatementHandle,"StatementHandle is null!");
     654           0 :     SQLRETURN nRet = N3SQLFreeStmt (m_aStatementHandle, SQL_RESET_PARAMS);
     655           0 :     nRet = N3SQLFreeStmt (m_aStatementHandle, SQL_UNBIND);
     656           0 :     OSL_UNUSED(nRet);
     657           0 : }
     658             : 
     659           0 : void SAL_CALL OPreparedStatement::clearBatch(  ) throw(SQLException, RuntimeException, std::exception)
     660             : {
     661           0 :     ::dbtools::throwFunctionNotSupportedException( "XPreparedBatchExecution::clearBatch", *this );
     662             :     //  clearParameters(  );
     663             :     //  m_aBatchList.erase();
     664           0 : }
     665             : 
     666             : 
     667           0 : void SAL_CALL OPreparedStatement::addBatch( ) throw(SQLException, RuntimeException, std::exception)
     668             : {
     669           0 :     ::dbtools::throwFunctionNotSupportedException( "XPreparedBatchExecution::addBatch", *this );
     670           0 : }
     671             : 
     672             : 
     673           0 : Sequence< sal_Int32 > SAL_CALL OPreparedStatement::executeBatch(  ) throw(SQLException, RuntimeException, std::exception)
     674             : {
     675           0 :     ::dbtools::throwFunctionNotSupportedException( "XPreparedBatchExecution::executeBatch", *this );
     676             :     // not reached, but keep -Werror happy
     677           0 :     return Sequence< sal_Int32 > ();
     678             : }
     679             : 
     680             : 
     681             : 
     682             : // methods
     683             : 
     684             : 
     685             : 
     686             : // initBoundParam
     687             : // Initialize the bound parameter objects
     688             : 
     689             : 
     690           0 : void OPreparedStatement::initBoundParam () throw(SQLException)
     691             : {
     692             :     OSL_ENSURE(m_aStatementHandle,"StatementHandle is null!");
     693             :     // Get the number of parameters
     694           0 :     numParams = 0;
     695           0 :     N3SQLNumParams (m_aStatementHandle,&numParams);
     696             : 
     697             :     // There are parameter markers, allocate the bound
     698             :     // parameter objects
     699             : 
     700           0 :     if (numParams > 0)
     701             :     {
     702             :         // Allocate an array of bound parameter objects
     703             : 
     704           0 :         boundParams = new OBoundParam[numParams];
     705             : 
     706             :     }
     707           0 : }
     708             : 
     709             : 
     710             : 
     711             : // allocBindBuf
     712             : // Allocate storage for the permanent data buffer for the bound
     713             : // parameter.
     714             : 
     715             : 
     716           0 : void* OPreparedStatement::allocBindBuf( sal_Int32 index,sal_Int32 bufLen)
     717             : {
     718           0 :     void* b = NULL;
     719             : 
     720             :     // Sanity check the parameter number
     721             : 
     722           0 :     if ((index >= 1) && (index <= numParams))
     723             :     {
     724           0 :         b = boundParams[index - 1].allocBindDataBuffer(bufLen);
     725             :     }
     726             : 
     727           0 :     return b;
     728             : }
     729             : 
     730             : 
     731             : 
     732             : // getLengthBuf
     733             : // Gets the length buffer for the given parameter index
     734             : 
     735             : 
     736           0 : SQLLEN* OPreparedStatement::getLengthBuf (sal_Int32 index)
     737             : {
     738           0 :     SQLLEN* b = NULL;
     739             : 
     740             :     // Sanity check the parameter number
     741             : 
     742           0 :     if ((index >= 1) &&
     743           0 :         (index <= numParams))
     744             :     {
     745           0 :         b = boundParams[index - 1].getBindLengthBuffer ();
     746             :     }
     747             : 
     748           0 :     return b;
     749             : }
     750             : 
     751             : 
     752             : 
     753             : // putParamData
     754             : // Puts parameter data from a previously bound input stream.  The
     755             : // input stream was bound using SQL_LEN_DATA_AT_EXEC.
     756             : 
     757             : 
     758           0 : void OPreparedStatement::putParamData (sal_Int32 index) throw(SQLException)
     759             : {
     760             :     // Sanity check the parameter index
     761           0 :     if ((index < 1) ||
     762           0 :         (index > numParams))
     763             :     {
     764           0 :         return;
     765             :     }
     766             : 
     767             :     // We'll transfer up to MAX_PUT_DATA_LENGTH at a time
     768           0 :     Sequence< sal_Int8 > buf( MAX_PUT_DATA_LENGTH );
     769             : 
     770             :     // Get the information about the input stream
     771             : 
     772           0 :     Reference< XInputStream> inputStream =  boundParams[index - 1].getInputStream ();
     773           0 :     if ( !inputStream.is() )
     774             :     {
     775           0 :         ::connectivity::SharedResources aResources;
     776           0 :         const OUString sError( aResources.getResourceString(STR_NO_INPUTSTREAM));
     777           0 :         throw SQLException (sError, *this,OUString(),0,Any());
     778             :     }
     779             : 
     780           0 :     sal_Int32 maxBytesLeft = boundParams[index - 1].getInputStreamLen ();
     781             : 
     782             :     // Loop while more data from the input stream
     783           0 :     sal_Int32 haveRead = 0;
     784             :     try
     785             :     {
     786             : 
     787           0 :         do
     788             :         {
     789           0 :             sal_Int32 toReadThisRound = ::std::min( MAX_PUT_DATA_LENGTH, maxBytesLeft );
     790             : 
     791             :             // Read some data from the input stream
     792           0 :             haveRead = inputStream->readBytes( buf, toReadThisRound );
     793             :             OSL_ENSURE( haveRead == buf.getLength(), "OPreparedStatement::putParamData: inconsistency!" );
     794             : 
     795           0 :             if ( !haveRead )
     796             :                 // no more data in the stream - the given stream length was a maximum which could not be
     797             :                 // fulfilled by the stream
     798           0 :                 break;
     799             : 
     800             :             // Put the data
     801             :             OSL_ENSURE( m_aStatementHandle, "OPreparedStatement::putParamData: StatementHandle is null!" );
     802           0 :             N3SQLPutData ( m_aStatementHandle, buf.getArray(), buf.getLength() );
     803             : 
     804             :             // decrement the number of bytes still needed
     805           0 :             maxBytesLeft -= haveRead;
     806             :         }
     807           0 :         while ( maxBytesLeft > 0 );
     808             :     }
     809           0 :     catch (const IOException& ex)
     810             :     {
     811             : 
     812             :         // If an I/O exception was generated, turn
     813             :         // it into a SQLException
     814             : 
     815           0 :         throw SQLException(ex.Message,*this,OUString(),0,Any());
     816           0 :     }
     817             : }
     818             : 
     819             : 
     820             : 
     821             : // setStream
     822             : // Sets an input stream as a parameter, using the given SQL type
     823             : 
     824             : 
     825           0 : void OPreparedStatement::setStream(
     826             :                                     sal_Int32 ParameterIndex,
     827             :                                     const Reference< XInputStream>& x,
     828             :                                     SQLLEN length,
     829             :                                     sal_Int32 _nType)
     830             :                                     throw(SQLException)
     831             : {
     832           0 :     ::osl::MutexGuard aGuard( m_aMutex );
     833           0 :     checkDisposed(OStatement_BASE::rBHelper.bDisposed);
     834             : 
     835             : 
     836           0 :     prepareStatement();
     837             : 
     838           0 :     checkParameterIndex(ParameterIndex);
     839             :     // Get the buffer needed for the length
     840             : 
     841           0 :     SQLLEN * const lenBuf = getLengthBuf(ParameterIndex);
     842             : 
     843             :     // Allocate a new buffer for the parameter data.  This buffer
     844             :     // will be returned by SQLParamData (it is set to the parameter
     845             :     // number, a sal_Int32)
     846             : 
     847           0 :     sal_Int32* dataBuf = static_cast<sal_Int32*>( allocBindBuf(ParameterIndex, sizeof(ParameterIndex)) );
     848           0 :     *dataBuf = ParameterIndex;
     849             : 
     850             :     // Bind the parameter with SQL_LEN_DATA_AT_EXEC
     851           0 :     *lenBuf = SQL_LEN_DATA_AT_EXEC (length);
     852             : 
     853             :     SQLSMALLINT fCType, fSqlType;
     854           0 :     OTools::getBindTypes(useWChar, m_pConnection->useOldDateFormat(), OTools::jdbcTypeToOdbc(_nType), fCType, fSqlType);
     855             : 
     856             : 
     857             :     OSL_ENSURE(m_aStatementHandle,"StatementHandle is null!");
     858           0 :     N3SQLBindParameter(m_aStatementHandle,
     859             :                        static_cast<SQLUSMALLINT>(ParameterIndex),
     860             :                        SQL_PARAM_INPUT,
     861             :                        fCType,
     862             :                        fSqlType,
     863             :                        length,
     864             :                        invalid_scale,
     865             :                        dataBuf,
     866             :                        sizeof(ParameterIndex),
     867           0 :                        lenBuf);
     868             : 
     869             :     // Save the input stream
     870           0 :     boundParams[ParameterIndex - 1].setInputStream (x, length);
     871           0 : }
     872             : 
     873             : 
     874             : 
     875             : 
     876           0 : void OPreparedStatement::FreeParams()
     877             : {
     878           0 :     numParams = 0;
     879           0 :     delete [] boundParams;
     880           0 :     boundParams = NULL;
     881           0 : }
     882             : 
     883           0 : void OPreparedStatement::setFastPropertyValue_NoBroadcast(sal_Int32 nHandle,const Any& rValue) throw (Exception, std::exception)
     884             : {
     885             :     try
     886             :     {
     887           0 :         switch(nHandle)
     888             :         {
     889             :             case PROPERTY_ID_RESULTSETCONCURRENCY:
     890           0 :                 if(!isPrepared())
     891           0 :                     setResultSetConcurrency(comphelper::getINT32(rValue));
     892           0 :                 break;
     893             :             case PROPERTY_ID_RESULTSETTYPE:
     894           0 :                 if(!isPrepared())
     895           0 :                     setResultSetType(comphelper::getINT32(rValue));
     896           0 :                 break;
     897             :             case PROPERTY_ID_FETCHDIRECTION:
     898           0 :                 if(!isPrepared())
     899           0 :                     setFetchDirection(comphelper::getINT32(rValue));
     900           0 :                 break;
     901             :             case PROPERTY_ID_USEBOOKMARKS:
     902           0 :                 if(!isPrepared())
     903           0 :                     setUsingBookmarks(comphelper::getBOOL(rValue));
     904           0 :                 break;
     905             :             default:
     906           0 :                 OStatement_Base::setFastPropertyValue_NoBroadcast(nHandle,rValue);
     907             :         }
     908             :     }
     909           0 :     catch(const SQLException&)
     910             :     {
     911             :         //  throw Exception(e.Message,*this);
     912             :     }
     913           0 : }
     914             : 
     915           0 : void OPreparedStatement::prepareStatement()
     916             : {
     917           0 :     if(!isPrepared())
     918             :     {
     919             :         OSL_ENSURE(m_aStatementHandle,"StatementHandle is null!");
     920           0 :         OString aSql(OUStringToOString(m_sSqlStatement,getOwnConnection()->getTextEncoding()));
     921           0 :         SQLRETURN nReturn = N3SQLPrepare(m_aStatementHandle,(SDB_ODBC_CHAR *) aSql.getStr(),aSql.getLength());
     922           0 :         OTools::ThrowException(m_pConnection,nReturn,m_aStatementHandle,SQL_HANDLE_STMT,*this);
     923           0 :         m_bPrepared = sal_True;
     924           0 :         initBoundParam();
     925             :     }
     926           0 : }
     927             : 
     928           0 : void OPreparedStatement::checkParameterIndex(sal_Int32 _parameterIndex)
     929             : {
     930           0 :     if( _parameterIndex > numParams ||
     931           0 :         _parameterIndex < 1 ||
     932           0 :         _parameterIndex > std::numeric_limits<SQLUSMALLINT>::max() )
     933             :     {
     934           0 :         ::connectivity::SharedResources aResources;
     935             :         const OUString sError( aResources.getResourceStringWithSubstitution(STR_WRONG_PARAM_INDEX,
     936             :             "$pos$", OUString::number(_parameterIndex),
     937             :             "$count$", OUString::number(numParams)
     938           0 :             ));
     939           0 :         SQLException aNext(sError,*this, OUString(),0,Any());
     940             : 
     941           0 :         ::dbtools::throwInvalidIndexException(*this,makeAny(aNext));
     942             :     }
     943           0 : }
     944             : 
     945           0 : OResultSet* OPreparedStatement::createResulSet()
     946             : {
     947           0 :     OResultSet* pReturn = new OResultSet(m_aStatementHandle,this);
     948           0 :     pReturn->setMetaData(getMetaData());
     949           0 :     return pReturn;
     950             : }
     951             : 
     952             : 
     953             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10