1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
32 #include <osl/diagnose.h>
33 #include "diagnose_ex.h"
34 #include "odbc/OPreparedStatement.hxx"
35 #include "odbc/OBoundParam.hxx"
36 #include <com/sun/star/sdbc/DataType.hpp>
37 #include "odbc/OTools.hxx"
38 #include "odbc/ODriver.hxx"
39 #include "odbc/OResultSet.hxx"
40 #include "odbc/OResultSetMetaData.hxx"
41 #include <cppuhelper/typeprovider.hxx>
42 #include <comphelper/sequence.hxx>
43 #include <com/sun/star/lang/DisposedException.hpp>
44 #include "connectivity/dbtools.hxx"
45 #include <comphelper/types.hxx>
46 #include "connectivity/FValue.hxx"
47 #include "resource/common_res.hrc"
48 #include "connectivity/sqlparse.hxx"
50 using namespace ::comphelper
;
51 using namespace connectivity
;
52 using namespace connectivity::odbc
;
53 using namespace com::sun::star::uno
;
54 using namespace com::sun::star::lang
;
55 using namespace com::sun::star::beans
;
56 using namespace com::sun::star::sdbc
;
57 using namespace com::sun::star::sdbcx
;
58 using namespace com::sun::star::container
;
59 using namespace com::sun::star::io
;
60 using namespace com::sun::star::util
;
62 IMPLEMENT_SERVICE_INFO(OPreparedStatement
,"com.sun.star.sdbcx.OPreparedStatement","com.sun.star.sdbc.PreparedStatement");
65 OPreparedStatement::OPreparedStatement( OConnection
* _pConnection
,const ::rtl::OUString
& sql
)
66 :OStatement_BASE2(_pConnection
)
69 ,m_bPrepared(sal_False
)
71 m_sSqlStatement
= sql
;
74 if(_pConnection
->isParameterSubstitutionEnabled())
76 OSQLParser
aParser(_pConnection
->getDriver()->getORB());
77 ::rtl::OUString sErrorMessage
;
78 ::rtl::OUString sNewSql
;
79 ::std::auto_ptr
<OSQLParseNode
> pNode( aParser
.parseTree(sErrorMessage
,sql
) );
81 { // special handling for parameters
82 OSQLParseNode::substituteParameterNames(pNode
.get());
83 pNode
->parseNodeToStr( sNewSql
, _pConnection
);
84 m_sSqlStatement
= sNewSql
;
92 // -----------------------------------------------------------------------------
93 void SAL_CALL
OPreparedStatement::acquire() throw()
95 OStatement_BASE2::acquire();
97 // -----------------------------------------------------------------------------
98 void SAL_CALL
OPreparedStatement::release() throw()
100 OStatement_BASE2::release();
102 // -----------------------------------------------------------------------------
103 Any SAL_CALL
OPreparedStatement::queryInterface( const Type
& rType
) throw(RuntimeException
)
105 Any aRet
= OStatement_BASE2::queryInterface(rType
);
106 return aRet
.hasValue() ? aRet
: OPreparedStatement_BASE::queryInterface(rType
);
108 // -------------------------------------------------------------------------
109 ::com::sun::star::uno::Sequence
< ::com::sun::star::uno::Type
> SAL_CALL
OPreparedStatement::getTypes( ) throw(::com::sun::star::uno::RuntimeException
)
111 return ::comphelper::concatSequences(OPreparedStatement_BASE::getTypes(),OStatement_BASE2::getTypes());
113 // -------------------------------------------------------------------------
115 Reference
< XResultSetMetaData
> SAL_CALL
OPreparedStatement::getMetaData( ) throw(SQLException
, RuntimeException
)
117 ::osl::MutexGuard
aGuard( m_aMutex
);
118 checkDisposed(OStatement_BASE::rBHelper
.bDisposed
);
122 OSL_ENSURE(m_aStatementHandle
,"StatementHandle is null!");
123 if(!m_xMetaData
.is())
124 m_xMetaData
= new OResultSetMetaData(getOwnConnection(),m_aStatementHandle
);
127 // -------------------------------------------------------------------------
129 void SAL_CALL
OPreparedStatement::close( ) throw(SQLException
, RuntimeException
)
131 ::osl::MutexGuard
aGuard( m_aMutex
);
132 checkDisposed(OStatement_BASE::rBHelper
.bDisposed
);
135 // Close/clear our result set
138 // Reset last warning message
142 OStatement_BASE2::close();
145 catch (SQLException
&) {
146 // If we get an error, ignore
149 // Remove this Statement object from the Connection object's
152 // -------------------------------------------------------------------------
154 sal_Bool SAL_CALL
OPreparedStatement::execute( ) throw(SQLException
, RuntimeException
)
156 ::osl::MutexGuard
aGuard( m_aMutex
);
157 checkDisposed(OStatement_BASE::rBHelper
.bDisposed
);
160 sal_Bool needData
= sal_False
;
166 // Reset the statement handle, warning and saved Resultset
173 OSL_ENSURE(m_aStatementHandle
,"StatementHandle is null!");
176 SQLRETURN nReturn
= N3SQLExecute(m_aStatementHandle
);
178 OTools::ThrowException(m_pConnection
,nReturn
,m_aStatementHandle
,SQL_HANDLE_STMT
,*this);
179 needData
= nReturn
== SQL_NEED_DATA
;
181 // Now loop while more data is needed (i.e. a data-at-
182 // execution parameter was given). For each parameter
183 // that needs data, put the data from the input stream.
187 // Get the parameter number that requires data
189 sal_Int32
* paramIndex
= 0;
190 nReturn
= N3SQLParamData(m_aStatementHandle
,(SQLPOINTER
*)¶mIndex
);
192 // If the parameter index is -1, there is no
193 // more data required
195 if ( !paramIndex
|| ( *paramIndex
== -1 ) )
196 needData
= sal_False
;
199 // Now we have the proper parameter
200 // index, get the data from the input
201 // stream and do a SQLPutData
202 putParamData (*paramIndex
);
207 catch (const SQLWarning
&)
211 // Now loop while more data is needed (i.e. a data-at-
212 // execution parameter was given). For each parameter
213 // that needs data, put the data from the input stream.
217 // Get the parameter number that requires data
219 sal_Int32
* paramIndex
= 0;
220 N3SQLParamData (m_aStatementHandle
,(SQLPOINTER
*)¶mIndex
);
222 // If the parameter index is -1, there is no more
225 if (*paramIndex
== -1) {
226 needData
= sal_False
;
229 // Now we have the proper parameter index,
230 // get the data from the input stream
231 // and do a SQLPutData
232 putParamData(*paramIndex
);
236 // Now determine if there is a result set associated with
237 // the SQL statement that was executed. Get the column
238 // count, and if it is not zero, there is a result set.
241 return getColumnCount() > 0;
243 // -------------------------------------------------------------------------
245 sal_Int32 SAL_CALL
OPreparedStatement::executeUpdate( ) throw(SQLException
, RuntimeException
)
247 ::osl::MutexGuard
aGuard( m_aMutex
);
248 checkDisposed(OStatement_BASE::rBHelper
.bDisposed
);
250 sal_Int32 numRows
= -1;
253 // Execute the statement. If execute returns sal_False, a
257 numRows
= getUpdateCount ();
260 // No update count was produced (a ResultSet was). Raise
262 m_pConnection
->throwGenericSQLException(STR_NO_ROWCOUNT
,*this);
266 // -------------------------------------------------------------------------
268 void SAL_CALL
OPreparedStatement::setString( sal_Int32 parameterIndex
, const ::rtl::OUString
& x
) throw(SQLException
, RuntimeException
)
270 ::rtl::OString
aString(::rtl::OUStringToOString(x
,getOwnConnection()->getTextEncoding()));
271 setParameter(parameterIndex
,DataType::CHAR
,aString
.getLength(),(void*)&x
);
273 // -------------------------------------------------------------------------
275 Reference
< XConnection
> SAL_CALL
OPreparedStatement::getConnection( ) throw(SQLException
, RuntimeException
)
277 ::osl::MutexGuard
aGuard( m_aMutex
);
278 checkDisposed(OStatement_BASE::rBHelper
.bDisposed
);
280 return (Reference
< XConnection
>)m_pConnection
;
282 // -------------------------------------------------------------------------
284 Reference
< XResultSet
> SAL_CALL
OPreparedStatement::executeQuery( ) throw(SQLException
, RuntimeException
)
286 ::osl::MutexGuard
aGuard( m_aMutex
);
287 checkDisposed(OStatement_BASE::rBHelper
.bDisposed
);
289 Reference
< XResultSet
> rs
= NULL
;
294 rs
= getResultSet(sal_False
);
297 // No ResultSet was produced. Raise an exception
298 m_pConnection
->throwGenericSQLException(STR_NO_RESULTSET
,*this);
302 // -------------------------------------------------------------------------
304 void SAL_CALL
OPreparedStatement::setBoolean( sal_Int32 parameterIndex
, sal_Bool x
) throw(SQLException
, RuntimeException
)
306 ::osl::MutexGuard
aGuard( m_aMutex
);
307 checkDisposed(OStatement_BASE::rBHelper
.bDisposed
);
312 // If the parameter is sal_True, set the value to 1
317 // Set the parameter as if it were an integer
318 setInt (parameterIndex
, value
);
320 // -------------------------------------------------------------------------
321 void OPreparedStatement::setParameter(sal_Int32 parameterIndex
,sal_Int32 _nType
,sal_Int32 _nSize
,void* _pData
)
323 ::osl::MutexGuard
aGuard( m_aMutex
);
324 checkDisposed(OStatement_BASE::rBHelper
.bDisposed
);
327 // Allocate a buffer to be used in binding. This will be
328 // a 'permanent' buffer that the bridge will fill in with
329 // the bound data in native format.
332 checkParameterIndex(parameterIndex
);
333 sal_Int32 nRealSize
= _nSize
;
334 SQLSMALLINT fSqlType
= static_cast<SQLSMALLINT
>(OTools::jdbcTypeToOdbc(_nType
));
345 nRealSize
=1; //dummy buffer, binary data isn't copied
351 sal_Int8
* bindBuf
= allocBindBuf(parameterIndex
, nRealSize
);
353 OSL_ENSURE(m_aStatementHandle
,"StatementHandle is null!");
354 OTools::bindParameter( m_pConnection
,
358 getLengthBuf(parameterIndex
),
361 m_pConnection
->useOldDateFormat(),
363 (Reference
<XInterface
>)*this,
364 getOwnConnection()->getTextEncoding());
366 // -----------------------------------------------------------------------------
367 void SAL_CALL
OPreparedStatement::setByte( sal_Int32 parameterIndex
, sal_Int8 x
) throw(SQLException
, RuntimeException
)
369 setParameter(parameterIndex
,DataType::TINYINT
,sizeof(sal_Int8
),&x
);
371 // -------------------------------------------------------------------------
373 void SAL_CALL
OPreparedStatement::setDate( sal_Int32 parameterIndex
, const Date
& aData
) throw(SQLException
, RuntimeException
)
375 DATE_STRUCT x
= OTools::DateToOdbcDate(aData
);
376 setParameter(parameterIndex
,DataType::DATE
,sizeof(DATE_STRUCT
),&x
);
378 // -------------------------------------------------------------------------
381 void SAL_CALL
OPreparedStatement::setTime( sal_Int32 parameterIndex
, const Time
& aVal
) throw(SQLException
, RuntimeException
)
383 TIME_STRUCT x
= OTools::TimeToOdbcTime(aVal
);
384 setParameter(parameterIndex
,DataType::TIME
,sizeof(TIME_STRUCT
),&x
);
386 // -------------------------------------------------------------------------
388 void SAL_CALL
OPreparedStatement::setTimestamp( sal_Int32 parameterIndex
, const DateTime
& aVal
) throw(SQLException
, RuntimeException
)
390 TIMESTAMP_STRUCT x
= OTools::DateTimeToTimestamp(aVal
);
391 setParameter(parameterIndex
,DataType::TIMESTAMP
,sizeof(TIMESTAMP_STRUCT
),&x
);
393 // -------------------------------------------------------------------------
395 void SAL_CALL
OPreparedStatement::setDouble( sal_Int32 parameterIndex
, double x
) throw(SQLException
, RuntimeException
)
397 setParameter(parameterIndex
,DataType::DOUBLE
,sizeof(double),&x
);
400 // -------------------------------------------------------------------------
402 void SAL_CALL
OPreparedStatement::setFloat( sal_Int32 parameterIndex
, float x
) throw(SQLException
, RuntimeException
)
404 setParameter(parameterIndex
,DataType::FLOAT
,sizeof(float),&x
);
406 // -------------------------------------------------------------------------
408 void SAL_CALL
OPreparedStatement::setInt( sal_Int32 parameterIndex
, sal_Int32 x
) throw(SQLException
, RuntimeException
)
410 setParameter(parameterIndex
,DataType::INTEGER
,sizeof(sal_Int32
),&x
);
412 // -------------------------------------------------------------------------
414 void SAL_CALL
OPreparedStatement::setLong( sal_Int32 parameterIndex
, sal_Int64 x
) throw(SQLException
, RuntimeException
)
418 setParameter(parameterIndex
,DataType::BIGINT
,sizeof(sal_Int64
),&x
);
422 setString(parameterIndex
,ORowSetValue(x
));
425 // -------------------------------------------------------------------------
427 void SAL_CALL
OPreparedStatement::setNull( sal_Int32 parameterIndex
, sal_Int32 sqlType
) throw(SQLException
, RuntimeException
)
429 ::osl::MutexGuard
aGuard( m_aMutex
);
430 checkDisposed(OStatement_BASE::rBHelper
.bDisposed
);
434 // Get the buffer needed for the length
435 checkParameterIndex(parameterIndex
);
437 sal_Int8
* lenBuf
= getLengthBuf (parameterIndex
);
438 *(SQLLEN
*)lenBuf
= SQL_NULL_DATA
;
442 SQLULEN nColumnSize
= 0;
443 if (sqlType
== SQL_CHAR
|| sqlType
== SQL_VARCHAR
|| sqlType
== SQL_LONGVARCHAR
)
449 SQLSMALLINT fCType
= 0;
450 SQLSMALLINT fSqlType
= 0;
452 SQLSMALLINT nDecimalDigits
= 0;
453 OTools::getBindTypes( sal_False
,
454 m_pConnection
->useOldDateFormat(),
455 (SQLSMALLINT
)sqlType
,
459 SQLRETURN nReturn
= N3SQLBindParameter( m_aStatementHandle
,
460 (SQLUSMALLINT
)parameterIndex
,
461 (SQLSMALLINT
)SQL_PARAM_INPUT
,
470 OTools::ThrowException(m_pConnection
,nReturn
,m_aStatementHandle
,SQL_HANDLE_STMT
,*this);
472 // -------------------------------------------------------------------------
474 void SAL_CALL
OPreparedStatement::setClob( sal_Int32 parameterIndex
, const Reference
< XClob
>& x
) throw(SQLException
, RuntimeException
)
477 setStream(parameterIndex
, x
->getCharacterStream(), (SQLLEN
)x
->length(), DataType::LONGVARCHAR
);
479 // -------------------------------------------------------------------------
481 void SAL_CALL
OPreparedStatement::setBlob( sal_Int32 parameterIndex
, const Reference
< XBlob
>& x
) throw(SQLException
, RuntimeException
)
484 setStream(parameterIndex
, x
->getBinaryStream(), (SQLLEN
)x
->length(), DataType::LONGVARCHAR
);
486 // -------------------------------------------------------------------------
488 void SAL_CALL
OPreparedStatement::setArray( sal_Int32
/*parameterIndex*/, const Reference
< XArray
>& /*x*/ ) throw(SQLException
, RuntimeException
)
490 ::dbtools::throwFunctionNotSupportedException( "XParameters::setArray", *this );
492 // -------------------------------------------------------------------------
494 void SAL_CALL
OPreparedStatement::setRef( sal_Int32
/*parameterIndex*/, const Reference
< XRef
>& /*x*/ ) throw(SQLException
, RuntimeException
)
496 ::dbtools::throwFunctionNotSupportedException( "XParameters::setRef", *this );
498 // -------------------------------------------------------------------------
499 void OPreparedStatement::setDecimal( sal_Int32 parameterIndex
, const ::rtl::OUString
& x
)
501 ::rtl::OString
aString(::rtl::OUStringToOString(x
,getOwnConnection()->getTextEncoding()));
502 setParameter(parameterIndex
,DataType::DECIMAL
,aString
.getLength(),(void*)&x
);
504 // -------------------------------------------------------------------------
505 void SAL_CALL
OPreparedStatement::setObjectWithInfo( sal_Int32 parameterIndex
, const Any
& x
, sal_Int32 sqlType
, sal_Int32 scale
) throw(SQLException
, RuntimeException
)
507 checkDisposed(OStatement_BASE::rBHelper
.bDisposed
);
508 ::osl::MutexGuard
aGuard( m_aMutex
);
511 // For each known SQL Type, call the appropriate
516 case DataType::VARCHAR
:
517 case DataType::LONGVARCHAR
:
520 ::rtl::OUString sStr
;
522 ::rtl::OString
aString(::rtl::OUStringToOString(sStr
,getOwnConnection()->getTextEncoding()));
523 setParameter(parameterIndex
,sqlType
,aString
.getLength(),&aString
);
526 setNull(parameterIndex
,sqlType
);
528 case DataType::DECIMAL
:
532 setDecimal(parameterIndex
,aValue
);
535 case DataType::NUMERIC
:
539 setString(parameterIndex
,aValue
);
543 ::dbtools::setObjectWithInfo(this,parameterIndex
,x
,sqlType
,scale
);
546 // -------------------------------------------------------------------------
548 void SAL_CALL
OPreparedStatement::setObjectNull( sal_Int32 parameterIndex
, sal_Int32 sqlType
, const ::rtl::OUString
& /*typeName*/ ) throw(SQLException
, RuntimeException
)
550 ::osl::MutexGuard
aGuard( m_aMutex
);
551 checkDisposed(OStatement_BASE::rBHelper
.bDisposed
);
553 setNull(parameterIndex
,sqlType
);
555 // -------------------------------------------------------------------------
557 void SAL_CALL
OPreparedStatement::setObject( sal_Int32 parameterIndex
, const Any
& x
) throw(SQLException
, RuntimeException
)
559 if (!::dbtools::implSetObject(this, parameterIndex
, x
))
560 { // there is no other setXXX call which can handle the value in x
561 throw SQLException();
564 // -------------------------------------------------------------------------
566 void SAL_CALL
OPreparedStatement::setShort( sal_Int32 parameterIndex
, sal_Int16 x
) throw(SQLException
, RuntimeException
)
568 setParameter(parameterIndex
,DataType::SMALLINT
,sizeof(sal_Int16
),&x
);
570 // -------------------------------------------------------------------------
572 void SAL_CALL
OPreparedStatement::setBytes( sal_Int32 parameterIndex
, const Sequence
< sal_Int8
>& x
) throw(SQLException
, RuntimeException
)
574 setParameter(parameterIndex
,DataType::BINARY
,x
.getLength(),(void*)&x
);
575 boundParams
[parameterIndex
-1].setSequence(x
); // this assures that the sequence stays alive
577 // -------------------------------------------------------------------------
580 void SAL_CALL
OPreparedStatement::setCharacterStream( sal_Int32 parameterIndex
, const Reference
< ::com::sun::star::io::XInputStream
>& x
, sal_Int32 length
) throw(SQLException
, RuntimeException
)
582 setStream(parameterIndex
, x
, length
, DataType::LONGVARCHAR
);
584 // -------------------------------------------------------------------------
586 void SAL_CALL
OPreparedStatement::setBinaryStream( sal_Int32 parameterIndex
, const Reference
< ::com::sun::star::io::XInputStream
>& x
, sal_Int32 length
) throw(SQLException
, RuntimeException
)
588 setStream(parameterIndex
, x
, length
, DataType::LONGVARBINARY
);
590 // -------------------------------------------------------------------------
592 void SAL_CALL
OPreparedStatement::clearParameters( ) throw(SQLException
, RuntimeException
)
595 OSL_ENSURE(m_aStatementHandle
,"StatementHandle is null!");
596 SQLRETURN nRet
= N3SQLFreeStmt (m_aStatementHandle
, SQL_RESET_PARAMS
);
597 nRet
= N3SQLFreeStmt (m_aStatementHandle
, SQL_UNBIND
);
600 // -------------------------------------------------------------------------
601 void SAL_CALL
OPreparedStatement::clearBatch( ) throw(SQLException
, RuntimeException
)
603 // clearParameters( );
604 // m_aBatchList.erase();
606 // -------------------------------------------------------------------------
608 void SAL_CALL
OPreparedStatement::addBatch( ) throw(SQLException
, RuntimeException
)
611 // -------------------------------------------------------------------------
613 Sequence
< sal_Int32
> SAL_CALL
OPreparedStatement::executeBatch( ) throw(SQLException
, RuntimeException
)
615 return Sequence
< sal_Int32
> ();
617 // -------------------------------------------------------------------------
619 //====================================================================
621 //====================================================================
623 //--------------------------------------------------------------------
625 // Initialize the bound parameter objects
626 //--------------------------------------------------------------------
628 void OPreparedStatement::initBoundParam () throw(SQLException
)
630 OSL_ENSURE(m_aStatementHandle
,"StatementHandle is null!");
631 // Get the number of parameters
633 N3SQLNumParams (m_aStatementHandle
,&numParams
);
635 // There are parameter markers, allocate the bound
640 // Allocate an array of bound parameter objects
642 boundParams
= new OBoundParam
[numParams
];
644 // initialize each bound parameter
646 for (sal_Int32 i
= 0; i
< numParams
; i
++)
648 boundParams
[i
].initialize ();
652 // -------------------------------------------------------------------------
654 //--------------------------------------------------------------------
656 // Allocate storage for the permanent data buffer for the bound
658 //--------------------------------------------------------------------
660 sal_Int8
* OPreparedStatement::allocBindBuf( sal_Int32 index
,sal_Int32 bufLen
)
664 // Sanity check the parameter number
667 (index
<= numParams
) && bufLen
> 0 )
669 b
= boundParams
[index
- 1].allocBindDataBuffer(bufLen
);
674 // -------------------------------------------------------------------------
676 //--------------------------------------------------------------------
678 // Gets the length buffer for the given parameter index
679 //--------------------------------------------------------------------
681 sal_Int8
* OPreparedStatement::getLengthBuf (sal_Int32 index
)
685 // Sanity check the parameter number
688 (index
<= numParams
))
690 b
= boundParams
[index
- 1].getBindLengthBuffer ();
695 // -------------------------------------------------------------------------
697 //--------------------------------------------------------------------
699 // Puts parameter data from a previously bound input stream. The
700 // input stream was bound using SQL_LEN_DATA_AT_EXEC.
701 //--------------------------------------------------------------------
703 void OPreparedStatement::putParamData (sal_Int32 index
) throw(SQLException
)
705 // Sanity check the parameter index
712 // We'll transfer up to MAX_PUT_DATA_LENGTH at a time
713 Sequence
< sal_Int8
> buf( MAX_PUT_DATA_LENGTH
);
715 // Get the information about the input stream
717 Reference
< XInputStream
> inputStream
= boundParams
[index
- 1].getInputStream ();
718 if ( !inputStream
.is() )
720 ::connectivity::SharedResources aResources
;
721 const ::rtl::OUString
sError( aResources
.getResourceString(STR_NO_INPUTSTREAM
));
722 throw SQLException (sError
, *this,::rtl::OUString(),0,Any());
725 sal_Int32 maxBytesLeft
= boundParams
[index
- 1].getInputStreamLen ();
727 // Loop while more data from the input stream
728 sal_Int32 haveRead
= 0;
734 sal_Int32 toReadThisRound
= ::std::min( MAX_PUT_DATA_LENGTH
, maxBytesLeft
);
736 // Read some data from the input stream
737 haveRead
= inputStream
->readBytes( buf
, toReadThisRound
);
738 OSL_ENSURE( haveRead
== buf
.getLength(), "OPreparedStatement::putParamData: inconsistency!" );
741 // no more data in the stream - the given stream length was a maximum which could not be
742 // fulfilled by the stream
746 OSL_ENSURE( m_aStatementHandle
, "OPreparedStatement::putParamData: StatementHandle is null!" );
747 N3SQLPutData ( m_aStatementHandle
, buf
.getArray(), buf
.getLength() );
749 // decrement the number of bytes still needed
750 maxBytesLeft
-= haveRead
;
752 while ( maxBytesLeft
> 0 );
754 catch (const IOException
& ex
)
757 // If an I/O exception was generated, turn
758 // it into a SQLException
760 throw SQLException(ex
.Message
,*this,::rtl::OUString(),0,Any());
763 // -------------------------------------------------------------------------
765 //--------------------------------------------------------------------
767 // Sets an input stream as a parameter, using the given SQL type
768 //--------------------------------------------------------------------
770 void OPreparedStatement::setStream(
771 sal_Int32 ParameterIndex
,
772 const Reference
< XInputStream
>& x
,
777 ::osl::MutexGuard
aGuard( m_aMutex
);
778 checkDisposed(OStatement_BASE::rBHelper
.bDisposed
);
783 checkParameterIndex(ParameterIndex
);
784 // Get the buffer needed for the length
786 sal_Int8
* lenBuf
= getLengthBuf(ParameterIndex
);
788 // Allocate a new buffer for the parameter data. This buffer
789 // will be returned by SQLParamData (it is set to the parameter
790 // number, a 4-sal_Int8 integer)
792 sal_Int8
* dataBuf
= allocBindBuf (ParameterIndex
, 4);
794 // Bind the parameter with SQL_LEN_DATA_AT_EXEC
795 SQLSMALLINT Ctype
= SQL_C_CHAR
;
796 SQLLEN atExec
= SQL_LEN_DATA_AT_EXEC (length
);
797 memcpy (dataBuf
, &ParameterIndex
, sizeof(ParameterIndex
));
798 memcpy (lenBuf
, &atExec
, sizeof (atExec
));
800 if ((SQLtype
== SQL_BINARY
) || (SQLtype
== SQL_VARBINARY
) || (SQLtype
== SQL_LONGVARBINARY
))
801 Ctype
= SQL_C_BINARY
;
804 OSL_ENSURE(m_aStatementHandle
,"StatementHandle is null!");
805 N3SQLBindParameter(m_aStatementHandle
,
806 (SQLUSMALLINT
)ParameterIndex
,
807 (SQLUSMALLINT
)SQL_PARAM_INPUT
,
809 (SQLSMALLINT
)SQLtype
,
813 sizeof(ParameterIndex
),
816 // Save the input stream
817 boundParams
[ParameterIndex
- 1].setInputStream (x
, length
);
819 // -------------------------------------------------------------------------
821 // -------------------------------------------------------------------------
823 void OPreparedStatement::FreeParams()
826 delete [] boundParams
;
829 // -------------------------------------------------------------------------
830 void OPreparedStatement::setFastPropertyValue_NoBroadcast(sal_Int32 nHandle
,const Any
& rValue
) throw (Exception
)
836 case PROPERTY_ID_RESULTSETCONCURRENCY
:
838 setResultSetConcurrency(comphelper::getINT32(rValue
));
840 case PROPERTY_ID_RESULTSETTYPE
:
842 setResultSetType(comphelper::getINT32(rValue
));
844 case PROPERTY_ID_FETCHDIRECTION
:
846 setFetchDirection(comphelper::getINT32(rValue
));
848 case PROPERTY_ID_USEBOOKMARKS
:
850 setUsingBookmarks(comphelper::getBOOL(rValue
));
853 OStatement_Base::setFastPropertyValue_NoBroadcast(nHandle
,rValue
);
856 catch(const SQLException
&)
858 // throw Exception(e.Message,*this);
861 // -----------------------------------------------------------------------------
862 void OPreparedStatement::prepareStatement()
866 OSL_ENSURE(m_aStatementHandle
,"StatementHandle is null!");
867 ::rtl::OString
aSql(::rtl::OUStringToOString(m_sSqlStatement
,getOwnConnection()->getTextEncoding()));
868 SQLRETURN nReturn
= N3SQLPrepare(m_aStatementHandle
,(SDB_ODBC_CHAR
*) aSql
.getStr(),aSql
.getLength());
869 OTools::ThrowException(m_pConnection
,nReturn
,m_aStatementHandle
,SQL_HANDLE_STMT
,*this);
870 m_bPrepared
= sal_True
;
874 // -----------------------------------------------------------------------------
875 void OPreparedStatement::checkParameterIndex(sal_Int32 _parameterIndex
)
877 if( !_parameterIndex
|| _parameterIndex
> numParams
)
879 ::connectivity::SharedResources aResources
;
880 const ::rtl::OUString
sError( aResources
.getResourceStringWithSubstitution(STR_WRONG_PARAM_INDEX
,
881 "$pos$", ::rtl::OUString::valueOf(_parameterIndex
),
882 "$count$", ::rtl::OUString::valueOf((sal_Int32
)numParams
)
884 SQLException
aNext(sError
,*this, ::rtl::OUString(),0,Any());
886 ::dbtools::throwInvalidIndexException(*this,makeAny(aNext
));
889 // -----------------------------------------------------------------------------
890 OResultSet
* OPreparedStatement::createResulSet()
892 OResultSet
* pReturn
= new OResultSet(m_aStatementHandle
,this);
893 pReturn
->setMetaData(getMetaData());
896 // -----------------------------------------------------------------------------
898 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */