1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_connectivity.hxx"
30 
31 #include <stdio.h>
32 #include <osl/diagnose.h>
33 #include "odbc/OStatement.hxx"
34 #include "odbc/OConnection.hxx"
35 #include "odbc/OResultSet.hxx"
36 #include <comphelper/property.hxx>
37 #include "odbc/OTools.hxx"
38 #include <comphelper/uno3.hxx>
39 #include <osl/thread.h>
40 #include <com/sun/star/sdbc/ResultSetConcurrency.hpp>
41 #include <com/sun/star/sdbc/ResultSetType.hpp>
42 #include <com/sun/star/sdbc/FetchDirection.hpp>
43 #include <com/sun/star/lang/DisposedException.hpp>
44 #include <comphelper/sequence.hxx>
45 #include <cppuhelper/typeprovider.hxx>
46 #include <comphelper/extract.hxx>
47 #include <comphelper/types.hxx>
48 #include "diagnose_ex.h"
49 #include <algorithm>
50 #include "resource/common_res.hrc"
51 #include "connectivity/dbexception.hxx"
52 
53 using namespace ::comphelper;
54 
55 #define THROW_SQL(x) \
56 	OTools::ThrowException(m_pConnection,x,m_aStatementHandle,SQL_HANDLE_STMT,*this)
57 
58 #if OSL_DEBUG_LEVEL > 1
59 #define DEBUG_THROW					\
60 	try									\
61 	{									\
62 		THROW_SQL(nRetCode);			\
63 	}									\
64 	catch(SQLException&)				\
65 	{									\
66 		OSL_ENSURE(0,"Exception in odbc catched"); \
67 	}
68 #endif
69 
70 
71 
72 using namespace connectivity::odbc;
73 //------------------------------------------------------------------------------
74 using namespace com::sun::star::uno;
75 using namespace com::sun::star::lang;
76 using namespace com::sun::star::beans;
77 using namespace com::sun::star::sdbc;
78 using namespace com::sun::star::sdbcx;
79 using namespace com::sun::star::container;
80 using namespace com::sun::star::io;
81 using namespace com::sun::star::util;
82 //------------------------------------------------------------------------------
83 OStatement_Base::OStatement_Base(OConnection* _pConnection )
84 	:OStatement_BASE(m_aMutex)
85 	,OPropertySetHelper(OStatement_BASE::rBHelper)
86 	,m_pConnection(_pConnection)
87     ,m_aStatementHandle(SQL_NULL_HANDLE)
88 	,m_pRowStatusArray(0)
89     ,rBHelper(OStatement_BASE::rBHelper)
90 {
91 	osl_incrementInterlockedCount( &m_refCount );
92 	m_pConnection->acquire();
93 	m_aStatementHandle = m_pConnection->createStatementHandle();
94 
95 	//setMaxFieldSize(0);
96     // Don't do this. By ODBC spec, "0" is the default for the SQL_ATTR_MAX_LENGTH attribute. We once introduced
97     // this line since an PostgreSQL ODBC driver had a default other than 0. However, current drivers (at least 8.3
98     // and later) have a proper default of 0, so there should be no need anymore.
99     // On the other hand, the NotesSQL driver (IBM's ODBC driver for the Lotus Notes series) wrongly interprets
100     // "0" as "0", whereas the ODBC spec says it should in fact mean "unlimited".
101     // So, removing this line seems to be the best option for now.
102     // If we ever again encounter a ODBC driver which needs this option, then we should introduce a data source
103     // setting for it, instead of unconditionally doing it.
104 
105 	osl_decrementInterlockedCount( &m_refCount );
106 }
107 // -----------------------------------------------------------------------------
108 OStatement_Base::~OStatement_Base()
109 {
110 	OSL_ENSURE(!m_aStatementHandle,"Sohould ne null here!");
111 }
112 //------------------------------------------------------------------------------
113 void OStatement_Base::disposeResultSet()
114 {
115 	// free the cursor if alive
116 	Reference< XComponent > xComp(m_xResultSet.get(), UNO_QUERY);
117 	if (xComp.is())
118 		xComp->dispose();
119 	m_xResultSet = Reference< XResultSet>();
120 }
121 // -----------------------------------------------------------------------------
122 void SAL_CALL OStatement_Base::disposing(void)
123 {
124 	::osl::MutexGuard aGuard(m_aMutex);
125 
126 	disposeResultSet();
127 	::comphelper::disposeComponent(m_xGeneratedStatement);
128 
129 	OSL_ENSURE(m_aStatementHandle,"OStatement_BASE2::disposing: StatementHandle is null!");
130 	if (m_pConnection)
131 	{
132 		m_pConnection->freeStatementHandle(m_aStatementHandle);
133 		m_pConnection->release();
134 		m_pConnection = NULL;
135 	}
136 	OSL_ENSURE(!m_aStatementHandle,"Sohould ne null here!");
137 
138 	OStatement_BASE::disposing();
139 }
140 //------------------------------------------------------------------------------
141 void OStatement_BASE2::disposing()
142 {
143 	::osl::MutexGuard aGuard(m_aMutex);
144 
145 	dispose_ChildImpl();
146 	OStatement_Base::disposing();
147 }
148 //-----------------------------------------------------------------------------
149 void SAL_CALL OStatement_BASE2::release() throw()
150 {
151 	relase_ChildImpl();
152 }
153 //-----------------------------------------------------------------------------
154 Any SAL_CALL OStatement_Base::queryInterface( const Type & rType ) throw(RuntimeException)
155 {
156 	if ( m_pConnection && !m_pConnection->isAutoRetrievingEnabled() && rType == ::getCppuType( (const Reference< XGeneratedResultSet > *)0 ) )
157 		return Any();
158 	Any aRet = OStatement_BASE::queryInterface(rType);
159 	return aRet.hasValue() ? aRet : OPropertySetHelper::queryInterface(rType);
160 }
161 // -------------------------------------------------------------------------
162 Sequence< Type > SAL_CALL OStatement_Base::getTypes(  ) throw(RuntimeException)
163 {
164 	::cppu::OTypeCollection aTypes(	::getCppuType( (const Reference< XMultiPropertySet > *)0 ),
165 									::getCppuType( (const Reference< XFastPropertySet > *)0 ),
166 									::getCppuType( (const Reference< XPropertySet > *)0 ));
167 	Sequence< Type > aOldTypes = OStatement_BASE::getTypes();
168 	if ( m_pConnection && !m_pConnection->isAutoRetrievingEnabled() )
169 	{
170 		::std::remove(aOldTypes.getArray(),aOldTypes.getArray() + aOldTypes.getLength(),
171 						::getCppuType( (const Reference< XGeneratedResultSet > *)0 ));
172 		aOldTypes.realloc(aOldTypes.getLength() - 1);
173 	}
174 
175 	return ::comphelper::concatSequences(aTypes.getTypes(),aOldTypes);
176 }
177 // -------------------------------------------------------------------------
178 Reference< XResultSet > SAL_CALL OStatement_Base::getGeneratedValues(  ) throw (SQLException, RuntimeException)
179 {
180 	OSL_ENSURE(	m_pConnection && m_pConnection->isAutoRetrievingEnabled(),"Illegal call here. isAutoRetrievingEnabled is false!");
181 	Reference< XResultSet > xRes;
182 	if ( m_pConnection )
183 	{
184 		::rtl::OUString sStmt = m_pConnection->getTransformedGeneratedStatement(m_sSqlStatement);
185 		if ( sStmt.getLength() )
186 		{
187 			::comphelper::disposeComponent(m_xGeneratedStatement);
188 			m_xGeneratedStatement = m_pConnection->createStatement();
189 			xRes = m_xGeneratedStatement->executeQuery(sStmt);
190 		}
191 	}
192 	return xRes;
193 }
194 // -----------------------------------------------------------------------------
195 void SAL_CALL OStatement_Base::cancel(  ) throw(RuntimeException)
196 {
197 	::osl::MutexGuard aGuard( m_aMutex );
198 	checkDisposed(OStatement_BASE::rBHelper.bDisposed);
199 
200 	OSL_ENSURE(m_aStatementHandle,"StatementHandle is null!");
201 	OTools::ThrowException(m_pConnection,N3SQLCancel(m_aStatementHandle),m_aStatementHandle,SQL_HANDLE_STMT,*this);
202 }
203 // -------------------------------------------------------------------------
204 
205 void SAL_CALL OStatement_Base::close(  ) throw(SQLException, RuntimeException)
206 {
207 	{
208 		::osl::MutexGuard aGuard( m_aMutex );
209 		checkDisposed(OStatement_BASE::rBHelper.bDisposed);
210 
211 	}
212 	dispose();
213 }
214 // -------------------------------------------------------------------------
215 
216 void SAL_CALL OStatement::clearBatch(  ) throw(SQLException, RuntimeException)
217 {
218 
219 }
220 // -------------------------------------------------------------------------
221 
222 void OStatement_Base::reset() throw (SQLException)
223 {
224 	::osl::MutexGuard aGuard( m_aMutex );
225 	checkDisposed(OStatement_BASE::rBHelper.bDisposed);
226 
227 
228 	clearWarnings ();
229 
230 	if (m_xResultSet.get().is())
231 	{
232 		clearMyResultSet();
233 	}
234 	if(m_aStatementHandle)
235 	{
236 		THROW_SQL(N3SQLFreeStmt(m_aStatementHandle, SQL_CLOSE));
237 	}
238 }
239 //--------------------------------------------------------------------
240 // clearMyResultSet
241 // If a ResultSet was created for this Statement, close it
242 //--------------------------------------------------------------------
243 
244 void OStatement_Base::clearMyResultSet () throw (SQLException)
245 {
246 	::osl::MutexGuard aGuard( m_aMutex );
247 	checkDisposed(OStatement_BASE::rBHelper.bDisposed);
248 
249     try
250     {
251 	    Reference<XCloseable> xCloseable;
252 	    if ( ::comphelper::query_interface( m_xResultSet.get(), xCloseable ) )
253 		    xCloseable->close();
254     }
255     catch( const DisposedException& ) { }
256 
257     m_xResultSet = Reference< XResultSet >();
258 }
259 //--------------------------------------------------------------------
260 SQLLEN OStatement_Base::getRowCount () throw( SQLException)
261 {
262 	::osl::MutexGuard aGuard( m_aMutex );
263 	checkDisposed(OStatement_BASE::rBHelper.bDisposed);
264 
265 
266 	SQLLEN numRows = 0;
267 
268 	try {
269 		THROW_SQL(N3SQLRowCount(m_aStatementHandle,&numRows));
270 	}
271 	catch (SQLException&)
272 	{
273 	}
274 	return numRows;
275 }
276 //--------------------------------------------------------------------
277 // lockIfNecessary
278 // If the given SQL statement contains a 'FOR UPDATE' clause, change
279 // the concurrency to lock so that the row can then be updated.  Returns
280 // true if the concurrency has been changed
281 //--------------------------------------------------------------------
282 
283 sal_Bool OStatement_Base::lockIfNecessary (const ::rtl::OUString& sql) throw( SQLException)
284 {
285 	sal_Bool rc = sal_False;
286 
287 	// First, convert the statement to upper case
288 
289 	::rtl::OUString sqlStatement = sql.toAsciiUpperCase ();
290 
291 	// Now, look for the FOR UPDATE keywords.  If there is any extra white
292 	// space between the FOR and UPDATE, this will fail.
293 
294 	sal_Int32 index = sqlStatement.indexOf(::rtl::OUString::createFromAscii(" FOR UPDATE"));
295 
296 	// We found it.  Change our concurrency level to ensure that the
297 	// row can be updated.
298 
299 	if (index > 0)
300 	{
301 		OSL_ENSURE(m_aStatementHandle,"StatementHandle is null!");
302 		try
303 		{
304 			SQLINTEGER nLock = SQL_CONCUR_LOCK;
305 			THROW_SQL(N3SQLSetStmtAttr(m_aStatementHandle, SQL_CONCURRENCY,(SQLPOINTER)nLock,SQL_IS_UINTEGER));
306 		}
307 		catch (SQLWarning& warn)
308 		{
309 			// Catch any warnings and place on the warning stack
310 			setWarning (warn);
311 		}
312 		rc = sal_True;
313 	}
314 
315 	return rc;
316 }
317 //--------------------------------------------------------------------
318 // setWarning
319 // Sets the warning
320 //--------------------------------------------------------------------
321 
322 void OStatement_Base::setWarning (const	SQLWarning &ex) throw( SQLException)
323 {
324 	::osl::MutexGuard aGuard( m_aMutex );
325 	checkDisposed(OStatement_BASE::rBHelper.bDisposed);
326 
327 
328 	m_aLastWarning = ex;
329 }
330 
331 //--------------------------------------------------------------------
332 // getColumnCount
333 // Return the number of columns in the ResultSet
334 //--------------------------------------------------------------------
335 
336 sal_Int32 OStatement_Base::getColumnCount () throw( SQLException)
337 {
338 	::osl::MutexGuard aGuard( m_aMutex );
339 	checkDisposed(OStatement_BASE::rBHelper.bDisposed);
340 
341 
342 	sal_Int16	numCols = 0;
343 	OSL_ENSURE(m_aStatementHandle,"StatementHandle is null!");
344 
345 	try {
346 		THROW_SQL(N3SQLNumResultCols(m_aStatementHandle,&numCols));
347 	}
348 	catch (SQLException&)
349 	{
350 	}
351 	return numCols;
352 }
353 // -------------------------------------------------------------------------
354 
355 sal_Bool SAL_CALL OStatement_Base::execute( const ::rtl::OUString& sql ) throw(SQLException, RuntimeException)
356 {
357 	::osl::MutexGuard aGuard( m_aMutex );
358 	checkDisposed(OStatement_BASE::rBHelper.bDisposed);
359 	m_sSqlStatement = sql;
360 
361 
362 	::rtl::OString aSql(::rtl::OUStringToOString(sql,getOwnConnection()->getTextEncoding()));
363 
364 	sal_Bool hasResultSet = sal_False;
365 	SQLWarning aWarning;
366 
367 	// Reset the statement handle and warning
368 
369 	reset();
370 
371 	// Check for a 'FOR UPDATE' statement.  If present, change
372 	// the concurrency to lock
373 
374 	lockIfNecessary (sql);
375 
376 	// Call SQLExecDirect
377 	OSL_ENSURE(m_aStatementHandle,"StatementHandle is null!");
378 
379 	try {
380 		THROW_SQL(N3SQLExecDirect(m_aStatementHandle, (SDB_ODBC_CHAR*)aSql.getStr(),aSql.getLength()));
381 	}
382 	catch (SQLWarning& ex) {
383 
384 		// Save pointer to warning and save with ResultSet
385 		// object once it is created.
386 
387 		aWarning = ex;
388 	}
389 
390 	// Now determine if there is a result set associated with
391 	// the SQL statement that was executed.  Get the column
392 	// count, and if it is not zero, there is a result set.
393 
394 	if (getColumnCount () > 0)
395 	{
396 		hasResultSet = sal_True;
397 	}
398 
399 	return hasResultSet;
400 }
401 //--------------------------------------------------------------------
402 // getResultSet
403 // getResultSet returns the current result as a ResultSet.  It
404 // returns NULL if the current result is not a ResultSet.
405 //--------------------------------------------------------------------
406 Reference< XResultSet > OStatement_Base::getResultSet (sal_Bool checkCount) throw( SQLException)
407 {
408 	::osl::MutexGuard aGuard( m_aMutex );
409 	checkDisposed(OStatement_BASE::rBHelper.bDisposed);
410 
411 
412 	if (m_xResultSet.get().is())  // if resultset already retrieved,
413 	{
414 		// throw exception to avoid sequence error
415         ::dbtools::throwFunctionSequenceException(*this,Any());
416 	}
417 
418 	OResultSet* pRs = NULL;
419 	sal_Int32 numCols = 1;
420 
421 	// If we already know we have result columns, checkCount
422 	// is false.  This is an optimization to prevent unneeded
423 	// calls to getColumnCount
424 
425 	if (checkCount)
426 		numCols = getColumnCount ();
427 
428 	// Only return a result set if there are result columns
429 
430 	if (numCols > 0)
431 	{
432 		OSL_ENSURE(m_aStatementHandle,"StatementHandle is null!");
433 		pRs = createResulSet();
434 		pRs->construct();
435 
436 		// Save a copy of our last result set
437 		// Changed to save copy at getResultSet.
438 		//m_xResultSet = rs;
439 	}
440 	else
441 		clearMyResultSet ();
442 
443 	return pRs;
444 }
445 //--------------------------------------------------------------------
446 // getStmtOption
447 // Invoke SQLGetStmtOption with the given option.
448 //--------------------------------------------------------------------
449 
450 sal_Int32 OStatement_Base::getStmtOption (short fOption) const
451 {
452 	sal_Int32	result = 0;
453 	OSL_ENSURE(m_aStatementHandle,"StatementHandle is null!");
454 	N3SQLGetStmtAttr(m_aStatementHandle, fOption,&result,SQL_IS_INTEGER,NULL);
455 	return result;
456 }
457 // -------------------------------------------------------------------------
458 
459 Reference< XResultSet > SAL_CALL OStatement_Base::executeQuery( const ::rtl::OUString& sql ) throw(SQLException, RuntimeException)
460 {
461 	::osl::MutexGuard aGuard( m_aMutex );
462 	checkDisposed(OStatement_BASE::rBHelper.bDisposed);
463 
464 
465 	Reference< XResultSet > xRS = NULL;
466 
467 	// Execute the statement.  If execute returns true, a result
468 	// set exists.
469 
470 	if (execute (sql))
471 	{
472 		xRS = getResultSet (sal_False);
473 		m_xResultSet = xRS;
474 	}
475 	else
476 	{
477 		// No ResultSet was produced.  Raise an exception
478 		m_pConnection->throwGenericSQLException(STR_NO_RESULTSET,*this);
479 	}
480 	return xRS;
481 }
482 // -------------------------------------------------------------------------
483 
484 Reference< XConnection > SAL_CALL OStatement_Base::getConnection(  ) throw(SQLException, RuntimeException)
485 {
486 	::osl::MutexGuard aGuard( m_aMutex );
487 	checkDisposed(OStatement_BASE::rBHelper.bDisposed);
488 
489 	return (Reference< XConnection >)m_pConnection;
490 }
491 // -------------------------------------------------------------------------
492 
493 Any SAL_CALL OStatement::queryInterface( const Type & rType ) throw(RuntimeException)
494 {
495 	Any aRet = ::cppu::queryInterface(rType,static_cast< XBatchExecution*> (this));
496 	return aRet.hasValue() ? aRet : OStatement_Base::queryInterface(rType);
497 }
498 // -------------------------------------------------------------------------
499 
500 void SAL_CALL OStatement::addBatch( const ::rtl::OUString& sql ) throw(SQLException, RuntimeException)
501 {
502 	::osl::MutexGuard aGuard( m_aMutex );
503 	checkDisposed(OStatement_BASE::rBHelper.bDisposed);
504 
505 
506 	m_aBatchList.push_back(sql);
507 }
508 // -------------------------------------------------------------------------
509 Sequence< sal_Int32 > SAL_CALL OStatement::executeBatch(  ) throw(SQLException, RuntimeException)
510 {
511 	::osl::MutexGuard aGuard( m_aMutex );
512 	checkDisposed(OStatement_BASE::rBHelper.bDisposed);
513 
514 
515 	::rtl::OString aBatchSql;
516 	sal_Int32 nLen = 0;
517 	for(::std::list< ::rtl::OUString>::const_iterator i=m_aBatchList.begin();i != m_aBatchList.end();++i,++nLen)
518 	{
519 		aBatchSql += ::rtl::OUStringToOString(*i,getOwnConnection()->getTextEncoding());
520 		aBatchSql += ";";
521 	}
522 
523 	OSL_ENSURE(m_aStatementHandle,"StatementHandle is null!");
524 	THROW_SQL(N3SQLExecDirect(m_aStatementHandle, (SDB_ODBC_CHAR*)aBatchSql.getStr(),aBatchSql.getLength()));
525 
526 	Sequence< sal_Int32 > aRet(nLen);
527 	sal_Int32* pArray = aRet.getArray();
528 	for(sal_Int32 j=0;j<nLen;++j)
529 	{
530 		SQLRETURN nError = N3SQLMoreResults(m_aStatementHandle);
531 		if(nError == SQL_SUCCESS)
532 		{
533 			SQLLEN nRowCount=0;
534 			N3SQLRowCount(m_aStatementHandle,&nRowCount);
535 			pArray[j] = nRowCount;
536 		}
537 	}
538 	return aRet;
539 }
540 // -------------------------------------------------------------------------
541 
542 
543 sal_Int32 SAL_CALL OStatement_Base::executeUpdate( const ::rtl::OUString& sql ) throw(SQLException, RuntimeException)
544 {
545 	::osl::MutexGuard aGuard( m_aMutex );
546 	checkDisposed(OStatement_BASE::rBHelper.bDisposed);
547 
548 
549 	sal_Int32 numRows = -1;
550 
551 	// Execute the statement.  If execute returns false, a
552 	// row count exists.
553 
554 	if (!execute (sql)) {
555 		numRows = getUpdateCount();
556 	}
557 	else {
558 
559 		// No update count was produced (a ResultSet was).  Raise
560 		// an exception
561 
562         ::connectivity::SharedResources aResources;
563         const ::rtl::OUString sError( aResources.getResourceString(STR_NO_ROWCOUNT));
564 		throw SQLException (sError,	*this,::rtl::OUString(),0,Any());
565 	}
566 	return numRows;
567 
568 }
569 // -------------------------------------------------------------------------
570 
571 Reference< XResultSet > SAL_CALL OStatement_Base::getResultSet(  ) throw(SQLException, RuntimeException)
572 {
573 	::osl::MutexGuard aGuard( m_aMutex );
574 	checkDisposed(OStatement_BASE::rBHelper.bDisposed);
575 
576 
577 	m_xResultSet = getResultSet(sal_True);
578 	return m_xResultSet;
579 }
580 // -------------------------------------------------------------------------
581 
582 sal_Int32 SAL_CALL OStatement_Base::getUpdateCount(  ) throw(SQLException, RuntimeException)
583 {
584 	::osl::MutexGuard aGuard( m_aMutex );
585 	checkDisposed(OStatement_BASE::rBHelper.bDisposed);
586 
587 
588 	sal_Int32 rowCount = -1;
589 
590 	// Only return a row count for SQL statements that did not
591 	// return a result set.
592 
593 	if (getColumnCount () == 0)
594 		rowCount = getRowCount ();
595 
596 	return rowCount;
597 }
598 // -------------------------------------------------------------------------
599 
600 sal_Bool SAL_CALL OStatement_Base::getMoreResults(  ) throw(SQLException, RuntimeException)
601 {
602 	::osl::MutexGuard aGuard( m_aMutex );
603 	checkDisposed(OStatement_BASE::rBHelper.bDisposed);
604 
605 
606 	SQLWarning	warning;
607 	sal_Bool hasResultSet = sal_False;
608 
609 	// clear previous warnings
610 
611 	clearWarnings ();
612 
613 	// Call SQLMoreResults
614 	OSL_ENSURE(m_aStatementHandle,"StatementHandle is null!");
615 
616 	try {
617 		hasResultSet = N3SQLMoreResults(m_aStatementHandle) == SQL_SUCCESS;
618 	}
619 	catch (SQLWarning &ex) {
620 
621 		// Save pointer to warning and save with ResultSet
622 		// object once it is created.
623 
624 		warning = ex;
625 	}
626 
627 	// There are more results (it may not be a result set, though)
628 
629 	if (hasResultSet)
630 	{
631 
632 		// Now determine if there is a result set associated
633 		// with the SQL statement that was executed.  Get the
634 		// column count, and if it is zero, there is not a
635 		// result set.
636 
637 		if (getColumnCount () == 0)
638 			hasResultSet = sal_False;
639 	}
640 
641 	// Set the warning for the statement, if one was generated
642 
643 	setWarning (warning);
644 
645 	// Return the result set indicator
646 
647 	return hasResultSet;
648 }
649 // -------------------------------------------------------------------------
650 
651 // -------------------------------------------------------------------------
652 Any SAL_CALL OStatement_Base::getWarnings(  ) throw(SQLException, RuntimeException)
653 {
654 	::osl::MutexGuard aGuard( m_aMutex );
655 	checkDisposed(OStatement_BASE::rBHelper.bDisposed);
656 
657 
658 	return makeAny(m_aLastWarning);
659 }
660 // -------------------------------------------------------------------------
661 
662 // -------------------------------------------------------------------------
663 void SAL_CALL OStatement_Base::clearWarnings(  ) throw(SQLException, RuntimeException)
664 {
665 	::osl::MutexGuard aGuard( m_aMutex );
666 	checkDisposed(OStatement_BASE::rBHelper.bDisposed);
667 
668 
669 	m_aLastWarning = SQLWarning();
670 }
671 // -------------------------------------------------------------------------
672 //------------------------------------------------------------------------------
673 sal_Int32 OStatement_Base::getQueryTimeOut() const
674 {
675 	return getStmtOption(SQL_ATTR_QUERY_TIMEOUT);
676 }
677 //------------------------------------------------------------------------------
678 sal_Int32 OStatement_Base::getMaxRows() const
679 {
680 	return getStmtOption(SQL_ATTR_MAX_ROWS);
681 }
682 //------------------------------------------------------------------------------
683 sal_Int32 OStatement_Base::getResultSetConcurrency() const
684 {
685 	OSL_ENSURE(m_aStatementHandle,"StatementHandle is null!");
686 	sal_uInt32 nValue;
687 	SQLRETURN nRetCode = N3SQLGetStmtAttr(m_aStatementHandle,SQL_ATTR_CONCURRENCY,&nValue,SQL_IS_UINTEGER,0);
688     OSL_UNUSED( nRetCode );
689 	if(nValue == SQL_CONCUR_READ_ONLY)
690 		nValue = ResultSetConcurrency::READ_ONLY;
691 	else
692 		nValue = ResultSetConcurrency::UPDATABLE;
693 	return nValue;
694 }
695 //------------------------------------------------------------------------------
696 sal_Int32 OStatement_Base::getResultSetType() const
697 {
698 	OSL_ENSURE(m_aStatementHandle,"StatementHandle is null!");
699 	sal_uInt32 nValue = SQL_CURSOR_FORWARD_ONLY;
700 	SQLRETURN nRetCode = N3SQLGetStmtAttr(m_aStatementHandle,SQL_ATTR_CURSOR_SENSITIVITY,&nValue,SQL_IS_UINTEGER,0);
701 	nRetCode = N3SQLGetStmtAttr(m_aStatementHandle,SQL_ATTR_CURSOR_TYPE,&nValue,SQL_IS_UINTEGER,0);
702 	switch(nValue)
703 	{
704 		case SQL_CURSOR_FORWARD_ONLY:
705 			nValue = ResultSetType::FORWARD_ONLY;
706 			break;
707 		case SQL_CURSOR_KEYSET_DRIVEN:
708 		case SQL_CURSOR_STATIC:
709 			nValue = ResultSetType::SCROLL_INSENSITIVE;
710 			break;
711 		case SQL_CURSOR_DYNAMIC:
712 			nValue = ResultSetType::SCROLL_SENSITIVE;
713 			break;
714 	}
715 
716 	return nValue;
717 }
718 //------------------------------------------------------------------------------
719 sal_Int32 OStatement_Base::getFetchDirection() const
720 {
721 	OSL_ENSURE(m_aStatementHandle,"StatementHandle is null!");
722 	sal_uInt32 nValue = 0;
723 	SQLRETURN nRetCode = N3SQLGetStmtAttr(m_aStatementHandle,SQL_ATTR_CURSOR_SCROLLABLE,&nValue,SQL_IS_UINTEGER,0);
724     OSL_UNUSED( nRetCode );
725 
726 	switch(nValue)
727 	{
728 		case SQL_SCROLLABLE:
729 			nValue = FetchDirection::REVERSE;
730 			break;
731 		default:
732 			nValue = FetchDirection::FORWARD;
733 			break;
734 	}
735 
736 	return nValue;
737 }
738 //------------------------------------------------------------------------------
739 sal_Int32 OStatement_Base::getFetchSize() const
740 {
741 	OSL_ENSURE(m_aStatementHandle,"StatementHandle is null!");
742 	sal_uInt32 nValue;
743 	SQLRETURN nRetCode = N3SQLGetStmtAttr(m_aStatementHandle,SQL_ATTR_ROW_ARRAY_SIZE,&nValue,SQL_IS_UINTEGER,0);
744     OSL_UNUSED( nRetCode );
745 	return nValue;
746 }
747 //------------------------------------------------------------------------------
748 sal_Int32 OStatement_Base::getMaxFieldSize() const
749 {
750 	return getStmtOption(SQL_ATTR_MAX_LENGTH);
751 }
752 //------------------------------------------------------------------------------
753 ::rtl::OUString OStatement_Base::getCursorName() const
754 {
755 	OSL_ENSURE(m_aStatementHandle,"StatementHandle is null!");
756 	SQLCHAR pName[258];
757 	SQLSMALLINT nRealLen = 0;
758 	SQLRETURN nRetCode = N3SQLGetCursorName(m_aStatementHandle,(SQLCHAR*)pName,256,&nRealLen);
759     OSL_UNUSED( nRetCode );
760 	return ::rtl::OUString::createFromAscii((const char*)pName);
761 }
762 //------------------------------------------------------------------------------
763 void OStatement_Base::setQueryTimeOut(sal_Int32 seconds)
764 {
765 	OSL_ENSURE(m_aStatementHandle,"StatementHandle is null!");
766 	SQLRETURN nRetCode = N3SQLSetStmtAttr(m_aStatementHandle, SQL_ATTR_QUERY_TIMEOUT,(SQLPOINTER)seconds,SQL_IS_UINTEGER);
767     OSL_UNUSED( nRetCode );
768 }
769 //------------------------------------------------------------------------------
770 void OStatement_Base::setMaxRows(sal_Int32 _par0)
771 {
772 	OSL_ENSURE(m_aStatementHandle,"StatementHandle is null!");
773 	SQLRETURN nRetCode = N3SQLSetStmtAttr(m_aStatementHandle, SQL_ATTR_MAX_ROWS, (SQLPOINTER)_par0,SQL_IS_UINTEGER);
774     OSL_UNUSED( nRetCode );
775 }
776 //------------------------------------------------------------------------------
777 void OStatement_Base::setResultSetConcurrency(sal_Int32 _par0)
778 {
779 	SQLINTEGER nSet;
780 	if(_par0 == ResultSetConcurrency::READ_ONLY)
781 		nSet = SQL_CONCUR_READ_ONLY;
782 	else
783 		nSet = SQL_CONCUR_VALUES;
784 
785 	OSL_ENSURE(m_aStatementHandle,"StatementHandle is null!");
786 	N3SQLSetStmtAttr(m_aStatementHandle, SQL_ATTR_CONCURRENCY,(SQLPOINTER)nSet,SQL_IS_UINTEGER);
787 
788 }
789 //------------------------------------------------------------------------------
790 void OStatement_Base::setResultSetType(sal_Int32 _par0)
791 {
792 
793 	OSL_ENSURE(m_aStatementHandle,"StatementHandle is null!");
794 	SQLRETURN nRetCode = N3SQLSetStmtAttr(m_aStatementHandle, SQL_ATTR_ROW_BIND_TYPE,(SQLPOINTER)SQL_BIND_BY_COLUMN,SQL_IS_UINTEGER);
795     OSL_UNUSED( nRetCode );
796 
797 	sal_Bool bUseBookmark = isUsingBookmarks();
798     SQLUINTEGER nSet( SQL_UNSPECIFIED );
799 	switch(_par0)
800 	{
801 		case ResultSetType::FORWARD_ONLY:
802 			nSet = 	SQL_UNSPECIFIED;
803 			break;
804 		case ResultSetType::SCROLL_INSENSITIVE:
805 			nSet = 	SQL_INSENSITIVE;
806 			N3SQLSetStmtAttr(m_aStatementHandle, SQL_ATTR_CURSOR_TYPE,(SQLPOINTER)SQL_CURSOR_KEYSET_DRIVEN,SQL_IS_UINTEGER);
807 			break;
808 		case ResultSetType::SCROLL_SENSITIVE:
809 			if(bUseBookmark)
810 			{
811 				SQLUINTEGER nCurProp = getCursorProperties(SQL_CURSOR_DYNAMIC,sal_True);
812 				if((nCurProp & SQL_CA1_BOOKMARK) != SQL_CA1_BOOKMARK) // check if bookmark for this type isn't supported
813 				{ // we have to test the next one
814 					nCurProp = getCursorProperties(SQL_CURSOR_KEYSET_DRIVEN,sal_True);
815 					sal_Bool bNotBookmarks = ((nCurProp & SQL_CA1_BOOKMARK) != SQL_CA1_BOOKMARK);
816 					nCurProp = getCursorProperties(SQL_CURSOR_KEYSET_DRIVEN,sal_False);
817 					nSet = SQL_CURSOR_KEYSET_DRIVEN;
818 					if(	bNotBookmarks ||
819 						((nCurProp & SQL_CA2_SENSITIVITY_DELETIONS) != SQL_CA2_SENSITIVITY_DELETIONS) ||
820 						((nCurProp & SQL_CA2_SENSITIVITY_ADDITIONS) != SQL_CA2_SENSITIVITY_ADDITIONS))
821 					{
822 						// bookmarks for keyset isn't supported so reset bookmark setting
823 						setUsingBookmarks(sal_False);
824 						nSet = SQL_CURSOR_DYNAMIC;
825 					}
826 				}
827 				else
828 					nSet = SQL_CURSOR_DYNAMIC;
829 			}
830 			else
831 				nSet = SQL_CURSOR_DYNAMIC;
832 			if(N3SQLSetStmtAttr(m_aStatementHandle, SQL_ATTR_CURSOR_TYPE,(SQLPOINTER)nSet,SQL_IS_UINTEGER) != SQL_SUCCESS)
833 			{
834 				nSet = SQL_CURSOR_KEYSET_DRIVEN;
835 				N3SQLSetStmtAttr(m_aStatementHandle, SQL_ATTR_CURSOR_TYPE,(SQLPOINTER)nSet,SQL_IS_UINTEGER);
836 			}
837 			nSet = 	SQL_SENSITIVE;
838 			break;
839         default:
840             OSL_ENSURE( false, "OStatement_Base::setResultSetType: invalid result set type!" );
841             break;
842 	}
843 
844 
845 	N3SQLSetStmtAttr(m_aStatementHandle, SQL_ATTR_CURSOR_SENSITIVITY,(SQLPOINTER)nSet,SQL_IS_UINTEGER);
846 }
847 //------------------------------------------------------------------------------
848 void OStatement_Base::setEscapeProcessing( const sal_Bool _bEscapeProc )
849 {
850 	OSL_ENSURE(m_aStatementHandle,"StatementHandle is null!");
851     SQLUINTEGER nEscapeProc( _bEscapeProc ? SQL_NOSCAN_OFF : SQL_NOSCAN_ON );
852 	SQLRETURN nRetCode = N3SQLSetStmtAttr( m_aStatementHandle, SQL_ATTR_NOSCAN, (SQLPOINTER)nEscapeProc, SQL_IS_UINTEGER );
853     (void)nRetCode;
854 }
855 
856 //------------------------------------------------------------------------------
857 void OStatement_Base::setFetchDirection(sal_Int32 _par0)
858 {
859 	OSL_ENSURE(m_aStatementHandle,"StatementHandle is null!");
860 	sal_Int32 nCursType = 0;
861 	SQLRETURN nRetCode	= SQL_SUCCESS;
862 	if(_par0 == FetchDirection::FORWARD)
863 	{
864 		nCursType = SQL_NONSCROLLABLE;
865 		nRetCode = N3SQLSetStmtAttr(m_aStatementHandle,SQL_ATTR_CURSOR_SCROLLABLE,(SQLPOINTER)nCursType,SQL_IS_UINTEGER);
866 	}
867 	else if(_par0 == FetchDirection::REVERSE)
868 	{
869 		nCursType = SQL_SCROLLABLE;
870 		nRetCode = N3SQLSetStmtAttr(m_aStatementHandle,SQL_ATTR_CURSOR_SCROLLABLE,(SQLPOINTER)nCursType,SQL_IS_UINTEGER);
871 	}
872     OSL_UNUSED( nRetCode );
873 }
874 //------------------------------------------------------------------------------
875 void OStatement_Base::setFetchSize(sal_Int32 _par0)
876 {
877 	OSL_ENSURE(m_aStatementHandle,"StatementHandle is null!");
878 	OSL_ENSURE(_par0>0,"Illegal fetch size!");
879 	if ( _par0 > 0 )
880 	{
881 
882 		SQLRETURN nRetCode = N3SQLSetStmtAttr(m_aStatementHandle,SQL_ATTR_ROW_ARRAY_SIZE,(SQLPOINTER)_par0,SQL_IS_UINTEGER);
883 
884 		delete m_pRowStatusArray;
885 		m_pRowStatusArray = new SQLUSMALLINT[_par0];
886 		nRetCode = N3SQLSetStmtAttr(m_aStatementHandle,SQL_ATTR_ROW_STATUS_PTR,m_pRowStatusArray,SQL_IS_POINTER);
887 	}
888 }
889 //------------------------------------------------------------------------------
890 void OStatement_Base::setMaxFieldSize(sal_Int32 _par0)
891 {
892 	OSL_ENSURE(m_aStatementHandle,"StatementHandle is null!");
893 	N3SQLSetStmtAttr(m_aStatementHandle,SQL_ATTR_MAX_LENGTH,(SQLPOINTER)_par0,SQL_IS_UINTEGER);
894 }
895 //------------------------------------------------------------------------------
896 void OStatement_Base::setCursorName(const ::rtl::OUString &_par0)
897 {
898 	OSL_ENSURE(m_aStatementHandle,"StatementHandle is null!");
899 	::rtl::OString aName(::rtl::OUStringToOString(_par0,getOwnConnection()->getTextEncoding()));
900 	N3SQLSetCursorName(m_aStatementHandle,(SDB_ODBC_CHAR*)aName.getStr(),(SQLSMALLINT)aName.getLength());
901 }
902 // -------------------------------------------------------------------------
903 sal_Bool OStatement_Base::isUsingBookmarks() const
904 {
905 	OSL_ENSURE(m_aStatementHandle,"StatementHandle is null!");
906 	sal_uInt32 nValue = SQL_UB_OFF;
907 	SQLRETURN nRetCode = N3SQLGetStmtAttr(m_aStatementHandle,SQL_ATTR_USE_BOOKMARKS,&nValue,SQL_IS_UINTEGER,NULL);
908     OSL_UNUSED( nRetCode );
909 	return nValue != SQL_UB_OFF;
910 }
911 // -------------------------------------------------------------------------
912 sal_Bool OStatement_Base::getEscapeProcessing() const
913 {
914 	OSL_ENSURE( m_aStatementHandle, "StatementHandle is null!" );
915 	sal_uInt32 nValue = SQL_NOSCAN_OFF;
916 	SQLRETURN nRetCode = N3SQLGetStmtAttr( m_aStatementHandle, SQL_ATTR_NOSCAN, &nValue, SQL_IS_UINTEGER, NULL );
917     (void)nRetCode;
918 	return nValue == SQL_NOSCAN_OFF;
919 }
920 // -------------------------------------------------------------------------
921 void OStatement_Base::setUsingBookmarks(sal_Bool _bUseBookmark)
922 {
923 	OSL_ENSURE(m_aStatementHandle,"StatementHandle is null!");
924 	sal_uInt32 nValue = _bUseBookmark ? SQL_UB_VARIABLE : SQL_UB_OFF;
925     SQLRETURN nRetCode = N3SQLSetStmtAttr(m_aStatementHandle,SQL_ATTR_USE_BOOKMARKS,(SQLPOINTER)nValue,SQL_IS_UINTEGER);
926     OSL_UNUSED( nRetCode );
927 }
928 // -------------------------------------------------------------------------
929 ::cppu::IPropertyArrayHelper* OStatement_Base::createArrayHelper( ) const
930 {
931 	Sequence< Property > aProps(10);
932 	Property* pProperties = aProps.getArray();
933 	sal_Int32 nPos = 0;
934 	DECL_PROP0(CURSORNAME,	::rtl::OUString);
935 	DECL_BOOL_PROP0(ESCAPEPROCESSING);
936 	DECL_PROP0(FETCHDIRECTION,sal_Int32);
937 	DECL_PROP0(FETCHSIZE,	sal_Int32);
938 	DECL_PROP0(MAXFIELDSIZE,sal_Int32);
939 	DECL_PROP0(MAXROWS,		sal_Int32);
940 	DECL_PROP0(QUERYTIMEOUT,sal_Int32);
941 	DECL_PROP0(RESULTSETCONCURRENCY,sal_Int32);
942 	DECL_PROP0(RESULTSETTYPE,sal_Int32);
943 	DECL_BOOL_PROP0(USEBOOKMARKS);
944 
945 	return new ::cppu::OPropertyArrayHelper(aProps);
946 }
947 
948 // -------------------------------------------------------------------------
949 ::cppu::IPropertyArrayHelper & OStatement_Base::getInfoHelper()
950 {
951 	return *const_cast<OStatement_Base*>(this)->getArrayHelper();
952 }
953 // -------------------------------------------------------------------------
954 sal_Bool OStatement_Base::convertFastPropertyValue(
955 							Any & rConvertedValue,
956 							Any & rOldValue,
957 							sal_Int32 nHandle,
958 							const Any& rValue )
959 								throw (::com::sun::star::lang::IllegalArgumentException)
960 {
961 	sal_Bool bConverted = sal_False;
962 	try
963 	{
964 		switch(nHandle)
965 		{
966 			case PROPERTY_ID_QUERYTIMEOUT:
967 				bConverted = ::comphelper::tryPropertyValue(rConvertedValue, rOldValue, rValue, getQueryTimeOut());
968 				break;
969 
970 			case PROPERTY_ID_MAXFIELDSIZE:
971 				bConverted = ::comphelper::tryPropertyValue(rConvertedValue, rOldValue, rValue, getMaxFieldSize());
972 				break;
973 
974 			case PROPERTY_ID_MAXROWS:
975 				bConverted = ::comphelper::tryPropertyValue(rConvertedValue, rOldValue, rValue, getMaxRows());
976 				break;
977 
978 			case PROPERTY_ID_CURSORNAME:
979 				bConverted = ::comphelper::tryPropertyValue(rConvertedValue, rOldValue, rValue, getCursorName());
980 				break;
981 
982 			case PROPERTY_ID_RESULTSETCONCURRENCY:
983 				bConverted = ::comphelper::tryPropertyValue(rConvertedValue, rOldValue, rValue, getResultSetConcurrency());
984 				break;
985 
986 			case PROPERTY_ID_RESULTSETTYPE:
987 				bConverted = ::comphelper::tryPropertyValue(rConvertedValue, rOldValue, rValue, getResultSetType());
988 				break;
989 
990 			case PROPERTY_ID_FETCHDIRECTION:
991 				bConverted = ::comphelper::tryPropertyValue(rConvertedValue, rOldValue, rValue, getFetchDirection());
992 				break;
993 
994 			case PROPERTY_ID_FETCHSIZE:
995 				bConverted = ::comphelper::tryPropertyValue(rConvertedValue, rOldValue, rValue, getFetchSize());
996 				break;
997 
998 			case PROPERTY_ID_USEBOOKMARKS:
999 				bConverted = ::comphelper::tryPropertyValue(rConvertedValue, rOldValue, rValue, isUsingBookmarks());
1000 				break;
1001 
1002 			case PROPERTY_ID_ESCAPEPROCESSING:
1003 				bConverted = ::comphelper::tryPropertyValue( rConvertedValue, rOldValue, rValue, getEscapeProcessing() );
1004 				break;
1005 
1006 		}
1007 	}
1008 	catch(const SQLException&)
1009 	{
1010 		//	throw Exception(e.Message,*this);
1011 	}
1012 	return bConverted;
1013 }
1014 // -------------------------------------------------------------------------
1015 void OStatement_Base::setFastPropertyValue_NoBroadcast(sal_Int32 nHandle,const Any& rValue) throw (Exception)
1016 {
1017 	try
1018 	{
1019 		switch(nHandle)
1020 		{
1021 			case PROPERTY_ID_QUERYTIMEOUT:
1022 				setQueryTimeOut(comphelper::getINT32(rValue));
1023 				break;
1024 			case PROPERTY_ID_MAXFIELDSIZE:
1025 				setMaxFieldSize(comphelper::getINT32(rValue));
1026 				break;
1027 			case PROPERTY_ID_MAXROWS:
1028 				setMaxRows(comphelper::getINT32(rValue));
1029 				break;
1030 			case PROPERTY_ID_CURSORNAME:
1031 				setCursorName(comphelper::getString(rValue));
1032 				break;
1033 			case PROPERTY_ID_RESULTSETCONCURRENCY:
1034 				setResultSetConcurrency(comphelper::getINT32(rValue));
1035 				break;
1036 			case PROPERTY_ID_RESULTSETTYPE:
1037 				setResultSetType(comphelper::getINT32(rValue));
1038 				break;
1039 			case PROPERTY_ID_FETCHDIRECTION:
1040 				setFetchDirection(comphelper::getINT32(rValue));
1041 				break;
1042 			case PROPERTY_ID_FETCHSIZE:
1043 				setFetchSize(comphelper::getINT32(rValue));
1044 				break;
1045 			case PROPERTY_ID_USEBOOKMARKS:
1046 				setUsingBookmarks(comphelper::getBOOL(rValue));
1047 				break;
1048             case PROPERTY_ID_ESCAPEPROCESSING:
1049                 setEscapeProcessing( ::comphelper::getBOOL( rValue ) );
1050                 break;
1051             default:
1052                 OSL_ENSURE( false, "OStatement_Base::setFastPropertyValue_NoBroadcast: what property?" );
1053                 break;
1054 		}
1055 	}
1056 	catch(const SQLException& )
1057 	{
1058 		//	throw Exception(e.Message,*this);
1059 	}
1060 }
1061 // -------------------------------------------------------------------------
1062 void OStatement_Base::getFastPropertyValue(Any& rValue,sal_Int32 nHandle) const
1063 {
1064 	switch(nHandle)
1065 	{
1066 		case PROPERTY_ID_QUERYTIMEOUT:
1067 			rValue <<= getQueryTimeOut();
1068 			break;
1069 		case PROPERTY_ID_MAXFIELDSIZE:
1070 			rValue <<= getMaxFieldSize();
1071 			break;
1072 		case PROPERTY_ID_MAXROWS:
1073 			rValue <<= getMaxRows();
1074 			break;
1075 		case PROPERTY_ID_CURSORNAME:
1076 			rValue <<= getCursorName();
1077 			break;
1078 		case PROPERTY_ID_RESULTSETCONCURRENCY:
1079 			rValue <<= getResultSetConcurrency();
1080 			break;
1081 		case PROPERTY_ID_RESULTSETTYPE:
1082 			rValue <<= getResultSetType();
1083 			break;
1084 		case PROPERTY_ID_FETCHDIRECTION:
1085 			rValue <<= getFetchDirection();
1086 			break;
1087 		case PROPERTY_ID_FETCHSIZE:
1088 			rValue <<= getFetchSize();
1089 			break;
1090 		case PROPERTY_ID_USEBOOKMARKS:
1091 			rValue <<= isUsingBookmarks();
1092 			break;
1093         case PROPERTY_ID_ESCAPEPROCESSING:
1094             rValue <<= getEscapeProcessing();
1095             break;
1096         default:
1097             OSL_ENSURE( false, "OStatement_Base::getFastPropertyValue: what property?" );
1098             break;
1099 	}
1100 }
1101 // -------------------------------------------------------------------------
1102 IMPLEMENT_SERVICE_INFO(OStatement,"com.sun.star.sdbcx.OStatement","com.sun.star.sdbc.Statement");
1103 // -----------------------------------------------------------------------------
1104 void SAL_CALL OStatement_Base::acquire() throw()
1105 {
1106 	OStatement_BASE::acquire();
1107 }
1108 // -----------------------------------------------------------------------------
1109 void SAL_CALL OStatement_Base::release() throw()
1110 {
1111 	OStatement_BASE::release();
1112 }
1113 // -----------------------------------------------------------------------------
1114 void SAL_CALL OStatement::acquire() throw()
1115 {
1116 	OStatement_BASE2::acquire();
1117 }
1118 // -----------------------------------------------------------------------------
1119 void SAL_CALL OStatement::release() throw()
1120 {
1121 	OStatement_BASE2::release();
1122 }
1123 // -----------------------------------------------------------------------------
1124 OResultSet* OStatement_Base::createResulSet()
1125 {
1126 	return new OResultSet(m_aStatementHandle,this);
1127 }
1128 // -----------------------------------------------------------------------------
1129 Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL OStatement_Base::getPropertySetInfo(  ) throw(RuntimeException)
1130 {
1131 	return ::cppu::OPropertySetHelper::createPropertySetInfo(getInfoHelper());
1132 }
1133 // -----------------------------------------------------------------------------
1134 SQLUINTEGER OStatement_Base::getCursorProperties(SQLINTEGER _nCursorType,sal_Bool bFirst)
1135 {
1136 	SQLUINTEGER nValueLen = 0;
1137 	try
1138 	{
1139 		SQLUSMALLINT nAskFor = SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES2;
1140 		if(SQL_CURSOR_KEYSET_DRIVEN == _nCursorType)
1141 			nAskFor = bFirst ? SQL_KEYSET_CURSOR_ATTRIBUTES1 : SQL_KEYSET_CURSOR_ATTRIBUTES2;
1142 		else if(SQL_CURSOR_STATIC  == _nCursorType)
1143 			nAskFor = bFirst ? SQL_STATIC_CURSOR_ATTRIBUTES1 : SQL_STATIC_CURSOR_ATTRIBUTES2;
1144 		else if(SQL_CURSOR_FORWARD_ONLY == _nCursorType)
1145 			nAskFor = bFirst ? SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1 : SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES2;
1146 		else if(SQL_CURSOR_DYNAMIC == _nCursorType)
1147 			nAskFor = bFirst ? SQL_DYNAMIC_CURSOR_ATTRIBUTES1 : SQL_DYNAMIC_CURSOR_ATTRIBUTES2;
1148 
1149 
1150 		OTools::GetInfo(getOwnConnection(),getConnectionHandle(),nAskFor,nValueLen,NULL);
1151 	}
1152 	catch(Exception&)
1153 	{ // we don't want our result destroy here
1154 		nValueLen = 0;
1155 	}
1156 	return nValueLen;
1157 }
1158 // -----------------------------------------------------------------------------
1159