xref: /AOO41X/main/dbaccess/source/core/api/statement.cxx (revision 96de54900b79e13b861fbc62cbf36018b54e21b7) !
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_dbaccess.hxx"
26 #ifndef _DBA_COREAPI_STATEMENT_HXX_
27 #include <statement.hxx>
28 #endif
29 #ifndef _DBA_COREAPI_RESULTSET_HXX_
30 #include <resultset.hxx>
31 #endif
32 #ifndef DBACCESS_SHARED_DBASTRINGS_HRC
33 #include "dbastrings.hrc"
34 #endif
35 #ifndef _COM_SUN_STAR_LANG_DISPOSEDEXCEPTION_HPP_
36 #include <com/sun/star/lang/DisposedException.hpp>
37 #endif
38 #ifndef _COM_SUN_STAR_SDBC_XDATABASEMETADATA_HPP_
39 #include <com/sun/star/sdbc/XDatabaseMetaData.hpp>
40 #endif
41 #ifndef _COMPHELPER_SEQUENCE_HXX_
42 #include <comphelper/sequence.hxx>
43 #endif
44 #ifndef _CPPUHELPER_TYPEPROVIDER_HXX_
45 #include <cppuhelper/typeprovider.hxx>
46 #endif
47 #ifndef _COMPHELPER_PROPERTY_HXX_
48 #include <comphelper/property.hxx>
49 #endif
50 #ifndef _COMPHELPER_TYPES_HXX_
51 #include <comphelper/types.hxx>
52 #endif
53 #ifndef _TOOLS_DEBUG_HXX //autogen
54 #include <tools/debug.hxx>
55 #endif
56 #ifndef TOOLS_DIAGNOSE_EX_H
57 #include <tools/diagnose_ex.h>
58 #endif
59 #ifndef _DBHELPER_DBEXCEPTION_HXX_
60 #include <connectivity/dbexception.hxx>
61 #endif
62 #include <rtl/logfile.hxx>
63 
64 using namespace ::com::sun::star::sdb;
65 using namespace ::com::sun::star::sdbc;
66 using namespace ::com::sun::star::beans;
67 using namespace ::com::sun::star::uno;
68 using namespace ::com::sun::star::lang;
69 using namespace ::cppu;
70 using namespace ::osl;
71 using namespace dbaccess;
72 using namespace dbtools;
73 
DBG_NAME(OStatementBase)74 DBG_NAME(OStatementBase)
75 
76 //--------------------------------------------------------------------------
77 OStatementBase::OStatementBase(const Reference< XConnection > & _xConn,
78                                const Reference< XInterface > & _xStatement)
79     :OSubComponent(m_aMutex, _xConn)
80     ,OPropertySetHelper(OComponentHelper::rBHelper)
81     ,m_bUseBookmarks( sal_False )
82     ,m_bEscapeProcessing( sal_True )
83 
84 {
85     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStatementBase::OStatementBase" );
86     DBG_CTOR(OStatementBase, NULL);
87     OSL_ENSURE(_xStatement.is() ,"Statement is NULL!");
88     m_xAggregateAsSet.set(_xStatement,UNO_QUERY);
89     m_xAggregateAsCancellable = Reference< ::com::sun::star::util::XCancellable > (m_xAggregateAsSet, UNO_QUERY);
90 }
91 
92 //--------------------------------------------------------------------------
~OStatementBase()93 OStatementBase::~OStatementBase()
94 {
95     DBG_DTOR(OStatementBase, NULL);
96 }
97 
98 // com::sun::star::lang::XTypeProvider
99 //--------------------------------------------------------------------------
getTypes()100 Sequence< Type > OStatementBase::getTypes() throw (RuntimeException)
101 {
102     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStatementBase::getTypes" );
103     OTypeCollection aTypes(::getCppuType( (const Reference< XPropertySet > *)0 ),
104                            ::getCppuType( (const Reference< XWarningsSupplier > *)0 ),
105                            ::getCppuType( (const Reference< XCloseable > *)0 ),
106                            ::getCppuType( (const Reference< XMultipleResults > *)0 ),
107                            ::getCppuType( (const Reference< ::com::sun::star::util::XCancellable > *)0 ),
108                             OSubComponent::getTypes() );
109     Reference< XGeneratedResultSet > xGRes(m_xAggregateAsSet, UNO_QUERY);
110     if ( xGRes.is() )
111         aTypes = OTypeCollection(::getCppuType( (const Reference< XGeneratedResultSet > *)0 ),aTypes.getTypes());
112     Reference< XPreparedBatchExecution > xPreparedBatchExecution(m_xAggregateAsSet, UNO_QUERY);
113     if ( xPreparedBatchExecution.is() )
114         aTypes = OTypeCollection(::getCppuType( (const Reference< XPreparedBatchExecution > *)0 ),aTypes.getTypes());
115 
116     return aTypes.getTypes();
117 }
118 
119 // com::sun::star::uno::XInterface
120 //--------------------------------------------------------------------------
queryInterface(const Type & rType)121 Any OStatementBase::queryInterface( const Type & rType ) throw (RuntimeException)
122 {
123     //RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStatementBase::queryInterface" );
124     Any aIface = OSubComponent::queryInterface( rType );
125     if (!aIface.hasValue())
126     {
127         aIface = ::cppu::queryInterface(
128                     rType,
129                     static_cast< XPropertySet * >( this ),
130                     static_cast< XWarningsSupplier * >( this ),
131                     static_cast< XCloseable * >( this ),
132                     static_cast< XMultipleResults * >( this ),
133                     static_cast< ::com::sun::star::util::XCancellable * >( this ));
134         if ( !aIface.hasValue() )
135         {
136             Reference< XGeneratedResultSet > xGRes(m_xAggregateAsSet, UNO_QUERY);
137             if ( ::getCppuType( (const Reference< XGeneratedResultSet > *)0 ) == rType && xGRes.is() )
138                 aIface = ::cppu::queryInterface(rType,static_cast< XGeneratedResultSet * >( this ));
139         } // if ( !aIface.hasValue() )
140         if ( !aIface.hasValue() )
141         {
142             Reference< XPreparedBatchExecution > xGRes(m_xAggregateAsSet, UNO_QUERY);
143             if ( ::getCppuType( (const Reference< XPreparedBatchExecution > *)0 ) == rType && xGRes.is() )
144                 aIface = ::cppu::queryInterface(rType,static_cast< XPreparedBatchExecution * >( this ));
145         }
146     }
147     return aIface;
148 }
149 
150 //--------------------------------------------------------------------------
acquire()151 void OStatementBase::acquire() throw ()
152 {
153     OSubComponent::acquire();
154 }
155 
156 //--------------------------------------------------------------------------
release()157 void OStatementBase::release() throw ()
158 {
159     OSubComponent::release();
160 }
161 
162 //------------------------------------------------------------------------------
disposeResultSet()163 void OStatementBase::disposeResultSet()
164 {
165     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStatementBase::disposeResultSet" );
166     // free the cursor if alive
167     Reference< XComponent > xComp(m_aResultSet.get(), UNO_QUERY);
168     if (xComp.is())
169         xComp->dispose();
170     m_aResultSet = NULL;
171 }
172 
173 // OComponentHelper
174 //------------------------------------------------------------------------------
disposing()175 void OStatementBase::disposing()
176 {
177     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStatementBase::disposing" );
178     OPropertySetHelper::disposing();
179 
180     MutexGuard aGuard(m_aMutex);
181 
182     // free pending results
183     disposeResultSet();
184 
185     // free the original statement
186     {
187         MutexGuard aCancelGuard(m_aCancelMutex);
188         m_xAggregateAsCancellable = NULL;
189     }
190 
191     if ( m_xAggregateAsSet.is() )
192     {
193         try
194         {
195             Reference< XCloseable > (m_xAggregateAsSet, UNO_QUERY)->close();
196         }
197         catch(RuntimeException& )
198         {// don't care for anymore
199         }
200     }
201     m_xAggregateAsSet = NULL;
202 
203     // free the parent at last
204     OSubComponent::disposing();
205 }
206 
207 // XCloseable
208 //------------------------------------------------------------------------------
close(void)209 void OStatementBase::close(void) throw( SQLException, RuntimeException )
210 {
211     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStatementBase::close" );
212     {
213         MutexGuard aGuard( m_aMutex );
214         ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed);
215     }
216     dispose();
217 }
218 
219 // OPropertySetHelper
220 //------------------------------------------------------------------------------
getPropertySetInfo()221 Reference< XPropertySetInfo > OStatementBase::getPropertySetInfo() throw (RuntimeException)
222 {
223     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStatementBase::getPropertySetInfo" );
224     return createPropertySetInfo( getInfoHelper() ) ;
225 }
226 
227 // comphelper::OPropertyArrayUsageHelper
228 //------------------------------------------------------------------------------
createArrayHelper() const229 ::cppu::IPropertyArrayHelper* OStatementBase::createArrayHelper( ) const
230 {
231     //RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStatementBase::createArrayHelper" );
232     BEGIN_PROPERTY_HELPER(10)
233         DECL_PROP0(CURSORNAME,              ::rtl::OUString);
234         DECL_PROP0_BOOL(ESCAPE_PROCESSING);
235         DECL_PROP0(FETCHDIRECTION,          sal_Int32);
236         DECL_PROP0(FETCHSIZE,               sal_Int32);
237         DECL_PROP0(MAXFIELDSIZE,            sal_Int32);
238         DECL_PROP0(MAXROWS,                 sal_Int32);
239         DECL_PROP0(QUERYTIMEOUT,            sal_Int32);
240         DECL_PROP0(RESULTSETCONCURRENCY,    sal_Int32);
241         DECL_PROP0(RESULTSETTYPE,           sal_Int32);
242         DECL_PROP0_BOOL(USEBOOKMARKS);
243     END_PROPERTY_HELPER();
244 }
245 
246 // cppu::OPropertySetHelper
247 //------------------------------------------------------------------------------
getInfoHelper()248 ::cppu::IPropertyArrayHelper& OStatementBase::getInfoHelper()
249 {
250     //RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStatementBase::getInfoHelper" );
251     return *getArrayHelper();
252 }
253 
254 //------------------------------------------------------------------------------
convertFastPropertyValue(Any & rConvertedValue,Any & rOldValue,sal_Int32 nHandle,const Any & rValue)255 sal_Bool OStatementBase::convertFastPropertyValue( Any & rConvertedValue, Any & rOldValue, sal_Int32 nHandle, const Any& rValue ) throw( IllegalArgumentException  )
256 {
257     //RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStatementBase::convertFastPropertyValue" );
258     sal_Bool bModified(sal_False);
259     switch (nHandle)
260     {
261         case PROPERTY_ID_USEBOOKMARKS:
262             bModified = ::comphelper::tryPropertyValue( rConvertedValue, rOldValue, rValue, m_bUseBookmarks );
263             break;
264 
265         case PROPERTY_ID_ESCAPE_PROCESSING:
266             bModified = ::comphelper::tryPropertyValue( rConvertedValue, rOldValue, rValue, m_bEscapeProcessing );
267             break;
268 
269         default:
270             if ( m_xAggregateAsSet.is() )
271             {
272                 // get the property name
273                 ::rtl::OUString sPropName;
274                 getInfoHelper().fillPropertyMembersByHandle( &sPropName, NULL, nHandle );
275 
276                 // now set the value
277                 Any aCurrentValue = m_xAggregateAsSet->getPropertyValue( sPropName );
278                 if ( aCurrentValue != rValue )
279                 {
280                     rOldValue = aCurrentValue;
281                     rConvertedValue = rValue;
282                     bModified = sal_True;
283                 }
284             }
285             break;
286     }
287     return bModified;
288 }
289 
290 //------------------------------------------------------------------------------
setFastPropertyValue_NoBroadcast(sal_Int32 nHandle,const Any & rValue)291 void OStatementBase::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const Any& rValue ) throw (Exception)
292 {
293     //RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStatementBase::setFastPropertyValue_NoBroadcast" );
294     switch ( nHandle )
295     {
296         case PROPERTY_ID_USEBOOKMARKS:
297         {
298             m_bUseBookmarks = ::comphelper::getBOOL( rValue );
299             if ( m_xAggregateAsSet.is() && m_xAggregateAsSet->getPropertySetInfo()->hasPropertyByName( PROPERTY_USEBOOKMARKS ) )
300                 m_xAggregateAsSet->setPropertyValue( PROPERTY_USEBOOKMARKS, rValue );
301         }
302         break;
303 
304         case PROPERTY_ID_ESCAPE_PROCESSING:
305             m_bEscapeProcessing = ::comphelper::getBOOL( rValue );
306             if ( m_xAggregateAsSet.is() )
307                 m_xAggregateAsSet->setPropertyValue( PROPERTY_ESCAPE_PROCESSING, rValue );
308             break;
309 
310         default:
311             if ( m_xAggregateAsSet.is() )
312             {
313                 ::rtl::OUString sPropName;
314                 getInfoHelper().fillPropertyMembersByHandle( &sPropName, NULL, nHandle );
315                 m_xAggregateAsSet->setPropertyValue( sPropName, rValue );
316             }
317             break;
318     }
319 }
320 
321 //------------------------------------------------------------------------------
getFastPropertyValue(Any & rValue,sal_Int32 nHandle) const322 void OStatementBase::getFastPropertyValue( Any& rValue, sal_Int32 nHandle ) const
323 {
324     //RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStatementBase::getFastPropertyValue" );
325     switch (nHandle)
326     {
327         case PROPERTY_ID_USEBOOKMARKS:
328             rValue <<= m_bUseBookmarks;
329             break;
330 
331         case PROPERTY_ID_ESCAPE_PROCESSING:
332             // don't rely on our aggregate - if it implements this wrong, and always returns
333             // TRUE here, then we would loop in impl_doEscapeProcessing_nothrow
334             rValue <<= m_bEscapeProcessing;
335             break;
336 
337         default:
338             if ( m_xAggregateAsSet.is() )
339             {
340                 ::rtl::OUString sPropName;
341                 const_cast< OStatementBase* >( this )->getInfoHelper().fillPropertyMembersByHandle( &sPropName, NULL, nHandle );
342                 rValue = m_xAggregateAsSet->getPropertyValue( sPropName );
343             }
344             break;
345     }
346 }
347 
348 // XWarningsSupplier
349 //------------------------------------------------------------------------------
getWarnings(void)350 Any OStatementBase::getWarnings(void) throw( SQLException, RuntimeException )
351 {
352     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStatementBase::getWarnings" );
353     MutexGuard aGuard(m_aMutex);
354     ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed);
355 
356     return Reference< XWarningsSupplier >(m_xAggregateAsSet, UNO_QUERY)->getWarnings();
357 }
358 
359 //------------------------------------------------------------------------------
clearWarnings(void)360 void OStatementBase::clearWarnings(void) throw( SQLException, RuntimeException )
361 {
362     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStatementBase::clearWarnings" );
363     MutexGuard aGuard(m_aMutex);
364     ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed);
365 
366     Reference< XWarningsSupplier >(m_xAggregateAsSet, UNO_QUERY)->clearWarnings();
367 }
368 
369 // ::com::sun::star::util::XCancellable
370 //------------------------------------------------------------------------------
cancel(void)371 void OStatementBase::cancel(void) throw( RuntimeException )
372 {
373     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStatementBase::cancel" );
374     // no blocking as cancel is typically called from a different thread
375     ClearableMutexGuard aCancelGuard(m_aCancelMutex);
376     if (m_xAggregateAsCancellable.is())
377         m_xAggregateAsCancellable->cancel();
378     // else do nothing
379 }
380 
381 // XMultipleResults
382 //------------------------------------------------------------------------------
getResultSet()383 Reference< XResultSet > SAL_CALL OStatementBase::getResultSet(  ) throw(SQLException, RuntimeException)
384 {
385     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStatementBase::getResultSet" );
386     MutexGuard aGuard(m_aMutex);
387     ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed);
388 
389     // first check the meta data
390     Reference<XDatabaseMetaData> xMeta = Reference< XConnection > (m_xParent, UNO_QUERY)->getMetaData();
391     if (!xMeta.is() && !xMeta->supportsMultipleResultSets())
392         throwFunctionSequenceException(*this);
393 
394     return Reference< XMultipleResults >(m_xAggregateAsSet, UNO_QUERY)->getResultSet();
395 }
396 
397 //------------------------------------------------------------------------------
getUpdateCount()398 sal_Int32 SAL_CALL OStatementBase::getUpdateCount(  ) throw(SQLException, RuntimeException)
399 {
400     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStatementBase::getUpdateCount" );
401     MutexGuard aGuard(m_aMutex);
402     ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed);
403 
404     // first check the meta data
405     Reference<XDatabaseMetaData> xMeta = Reference< XConnection > (m_xParent, UNO_QUERY)->getMetaData();
406     if (!xMeta.is() && !xMeta->supportsMultipleResultSets())
407         throwFunctionSequenceException(*this);
408 
409     return Reference< XMultipleResults >(m_xAggregateAsSet, UNO_QUERY)->getUpdateCount();
410 }
411 
412 //------------------------------------------------------------------------------
getMoreResults()413 sal_Bool SAL_CALL OStatementBase::getMoreResults(  ) throw(SQLException, RuntimeException)
414 {
415     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStatementBase::getMoreResults" );
416     MutexGuard aGuard(m_aMutex);
417     ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed);
418 
419     // first check the meta data
420     Reference<XDatabaseMetaData> xMeta = Reference< XConnection > (m_xParent, UNO_QUERY)->getMetaData();
421     if (!xMeta.is() && !xMeta->supportsMultipleResultSets())
422         throwFunctionSequenceException(*this);
423         throwFunctionSequenceException(*this);
424 
425     // free the previous results
426     disposeResultSet();
427 
428     return Reference< XMultipleResults >(m_xAggregateAsSet, UNO_QUERY)->getMoreResults();
429 }
430 
431 // XPreparedBatchExecution
432 //------------------------------------------------------------------------------
addBatch()433 void SAL_CALL OStatementBase::addBatch(  ) throw(SQLException, RuntimeException)
434 {
435     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStatementBase::addBatch" );
436     MutexGuard aGuard(m_aMutex);
437     ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed);
438 
439     // first check the meta data
440     Reference<XDatabaseMetaData> xMeta = Reference< XConnection > (m_xParent, UNO_QUERY)->getMetaData();
441     if (!xMeta.is() && !xMeta->supportsBatchUpdates())
442         throwFunctionSequenceException(*this);
443 
444     Reference< XPreparedBatchExecution >(m_xAggregateAsSet, UNO_QUERY)->addBatch();
445 }
446 
447 //------------------------------------------------------------------------------
clearBatch()448 void SAL_CALL OStatementBase::clearBatch(  ) throw(SQLException, RuntimeException)
449 {
450     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStatementBase::clearBatch" );
451     MutexGuard aGuard(m_aMutex);
452     ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed);
453 
454     // first check the meta data
455     Reference<XDatabaseMetaData> xMeta = Reference< XConnection > (m_xParent, UNO_QUERY)->getMetaData();
456     if (!xMeta.is() && !xMeta->supportsBatchUpdates())
457         throwFunctionSequenceException(*this);
458 
459     Reference< XPreparedBatchExecution >(m_xAggregateAsSet, UNO_QUERY)->clearBatch();
460 }
461 
462 //------------------------------------------------------------------------------
executeBatch()463 Sequence< sal_Int32 > SAL_CALL OStatementBase::executeBatch(  ) throw(SQLException, RuntimeException)
464 {
465     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStatementBase::executeBatch" );
466     MutexGuard aGuard(m_aMutex);
467     ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed);
468 
469     // first check the meta data
470     Reference<XDatabaseMetaData> xMeta = Reference< XConnection > (m_xParent, UNO_QUERY)->getMetaData();
471     if (!xMeta.is() && !xMeta->supportsBatchUpdates())
472         throwFunctionSequenceException(*this);
473 
474     // free the previous results
475     disposeResultSet();
476 
477     return Reference< XPreparedBatchExecution >(m_xAggregateAsSet, UNO_QUERY)->executeBatch();
478 }
479 // -----------------------------------------------------------------------------
getGeneratedValues()480 Reference< XResultSet > SAL_CALL OStatementBase::getGeneratedValues(  ) throw (SQLException, RuntimeException)
481 {
482     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStatementBase::getGeneratedValues" );
483     MutexGuard aGuard(m_aMutex);
484     ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed);
485     Reference< XGeneratedResultSet > xGRes(m_xAggregateAsSet, UNO_QUERY);
486 
487     if ( xGRes.is() )
488         return xGRes->getGeneratedValues(  );
489     return Reference< XResultSet >();
490 }
491 
492 //************************************************************
493 //  OStatement
494 //************************************************************
495 //------------------------------------------------------------------------------
OStatement(const Reference<XConnection> & _xConn,const Reference<XInterface> & _xStatement)496 OStatement::OStatement( const Reference< XConnection >& _xConn, const Reference< XInterface > & _xStatement )
497     :OStatementBase( _xConn, _xStatement )
498     ,m_bAttemptedComposerCreation( false )
499 {
500     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStatement::OStatement" );
501     m_xAggregateStatement.set( _xStatement, UNO_QUERY_THROW );
502 }
503 
504 //------------------------------------------------------------------------------
505 IMPLEMENT_FORWARD_XINTERFACE2( OStatement, OStatementBase, OStatement_IFACE );
506 IMPLEMENT_FORWARD_XTYPEPROVIDER2( OStatement, OStatementBase, OStatement_IFACE );
507 
508 // XServiceInfo
509 //------------------------------------------------------------------------------
getImplementationName()510 rtl::OUString OStatement::getImplementationName(  ) throw(RuntimeException)
511 {
512     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStatement::getImplementationName" );
513     return rtl::OUString::createFromAscii("com.sun.star.sdb.OStatement");
514 }
515 
516 //------------------------------------------------------------------------------
supportsService(const::rtl::OUString & _rServiceName)517 sal_Bool OStatement::supportsService( const ::rtl::OUString& _rServiceName ) throw (RuntimeException)
518 {
519     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStatement::supportsService" );
520     return ::comphelper::findValue(getSupportedServiceNames(), _rServiceName, sal_True).getLength() != 0;
521 }
522 
523 //------------------------------------------------------------------------------
getSupportedServiceNames()524 Sequence< ::rtl::OUString > OStatement::getSupportedServiceNames(  ) throw (RuntimeException)
525 {
526     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStatement::getSupportedServiceNames" );
527     Sequence< ::rtl::OUString > aSNS( 1 );
528     aSNS.getArray()[0] = SERVICE_SDBC_STATEMENT;
529     return aSNS;
530 }
531 
532 // XStatement
533 //------------------------------------------------------------------------------
executeQuery(const rtl::OUString & _rSQL)534 Reference< XResultSet > OStatement::executeQuery( const rtl::OUString& _rSQL ) throw( SQLException, RuntimeException )
535 {
536     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStatement::executeQuery" );
537     MutexGuard aGuard(m_aMutex);
538     ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed);
539 
540     disposeResultSet();
541     Reference< XResultSet > xResultSet;
542 
543     ::rtl::OUString sSQL( impl_doEscapeProcessing_nothrow( _rSQL ) );
544 
545     Reference< XResultSet > xInnerResultSet = m_xAggregateStatement->executeQuery( sSQL );
546     Reference< XConnection > xConnection( m_xParent, UNO_QUERY_THROW );
547 
548     if ( xInnerResultSet.is() )
549     {
550         Reference< XDatabaseMetaData > xMeta = xConnection->getMetaData();
551         sal_Bool bCaseSensitive = xMeta.is() && xMeta->supportsMixedCaseQuotedIdentifiers();
552         xResultSet = new OResultSet( xInnerResultSet, *this, bCaseSensitive );
553 
554         // keep the resultset weak
555         m_aResultSet = xResultSet;
556     }
557 
558     return xResultSet;
559 }
560 
561 //------------------------------------------------------------------------------
executeUpdate(const rtl::OUString & _rSQL)562 sal_Int32 OStatement::executeUpdate( const rtl::OUString& _rSQL ) throw( SQLException, RuntimeException )
563 {
564     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStatement::executeUpdate" );
565     MutexGuard aGuard(m_aMutex);
566     ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed);
567 
568     disposeResultSet();
569 
570     ::rtl::OUString sSQL( impl_doEscapeProcessing_nothrow( _rSQL ) );
571     return m_xAggregateStatement->executeUpdate( sSQL );
572 }
573 
574 //------------------------------------------------------------------------------
execute(const rtl::OUString & _rSQL)575 sal_Bool OStatement::execute( const rtl::OUString& _rSQL ) throw( SQLException, RuntimeException )
576 {
577     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStatement::execute" );
578     MutexGuard aGuard(m_aMutex);
579     ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed);
580 
581     disposeResultSet();
582 
583     ::rtl::OUString sSQL( impl_doEscapeProcessing_nothrow( _rSQL ) );
584     return m_xAggregateStatement->execute( sSQL );
585 }
586 //------------------------------------------------------------------------------
addBatch(const rtl::OUString & _rSQL)587 void OStatement::addBatch( const rtl::OUString& _rSQL ) throw( SQLException, RuntimeException )
588 {
589     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStatement::execute" );
590     MutexGuard aGuard(m_aMutex);
591     ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed);
592 
593     // first check the meta data
594     Reference<XDatabaseMetaData> xMeta = Reference< XConnection > (m_xParent, UNO_QUERY)->getMetaData();
595     if (!xMeta.is() && !xMeta->supportsBatchUpdates())
596         throwFunctionSequenceException(*this);
597 
598     ::rtl::OUString sSQL( impl_doEscapeProcessing_nothrow( _rSQL ) );
599     Reference< XBatchExecution >(m_xAggregateAsSet, UNO_QUERY)->addBatch( sSQL );
600 }
601 //------------------------------------------------------------------------------
clearBatch()602 void OStatement::clearBatch( ) throw( SQLException, RuntimeException )
603 {
604     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStatement::execute" );
605     MutexGuard aGuard(m_aMutex);
606     ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed);
607     // first check the meta data
608     Reference<XDatabaseMetaData> xMeta = Reference< XConnection > (m_xParent, UNO_QUERY)->getMetaData();
609     if (!xMeta.is() && !xMeta->supportsBatchUpdates())
610         throwFunctionSequenceException(*this);
611 
612     Reference< XBatchExecution >(m_xAggregateAsSet, UNO_QUERY)->clearBatch();
613 }
614 //------------------------------------------------------------------------------
executeBatch()615 Sequence< sal_Int32 > OStatement::executeBatch( ) throw( SQLException, RuntimeException )
616 {
617     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStatement::execute" );
618     MutexGuard aGuard(m_aMutex);
619     ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed);
620     // first check the meta data
621     Reference<XDatabaseMetaData> xMeta = Reference< XConnection > (m_xParent, UNO_QUERY)->getMetaData();
622     if (!xMeta.is() && !xMeta->supportsBatchUpdates())
623         throwFunctionSequenceException(*this);
624     return Reference< XBatchExecution >(m_xAggregateAsSet, UNO_QUERY)->executeBatch( );
625 }
626 
627 //------------------------------------------------------------------------------
getConnection(void)628 Reference< XConnection > OStatement::getConnection(void) throw( SQLException, RuntimeException )
629 {
630     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStatement::getConnection" );
631     return Reference< XConnection >( m_xParent, UNO_QUERY );
632 }
633 
634 // -----------------------------------------------------------------------------
disposing()635 void SAL_CALL OStatement::disposing()
636 {
637     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStatement::disposing" );
638     OStatementBase::disposing();
639     m_xComposer.clear();
640     m_xAggregateStatement.clear();
641 }
642 
643 // -----------------------------------------------------------------------------
impl_doEscapeProcessing_nothrow(const::rtl::OUString & _rSQL) const644 ::rtl::OUString OStatement::impl_doEscapeProcessing_nothrow( const ::rtl::OUString& _rSQL ) const
645 {
646     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStatement::impl_doEscapeProcessing_nothrow" );
647     if ( !m_bEscapeProcessing )
648         return _rSQL;
649     try
650     {
651         if ( !impl_ensureComposer_nothrow() )
652             return _rSQL;
653 
654         bool bParseable = false;
655         try { m_xComposer->setQuery( _rSQL ); bParseable = true; }
656         catch( const SQLException& ) { }
657 
658         if ( !bParseable )
659             // if we cannot parse it, silently accept this. The driver is probably able to cope with it then
660             return _rSQL;
661 
662         ::rtl::OUString sLowLevelSQL = m_xComposer->getQueryWithSubstitution();
663         return sLowLevelSQL;
664     }
665     catch( const Exception& )
666     {
667         DBG_UNHANDLED_EXCEPTION();
668     }
669 
670     return _rSQL;
671 }
672 
673 // -----------------------------------------------------------------------------
impl_ensureComposer_nothrow() const674 bool OStatement::impl_ensureComposer_nothrow() const
675 {
676     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OStatement::impl_ensureComposer_nothrow" );
677     if ( m_bAttemptedComposerCreation )
678         return m_xComposer.is();
679 
680     const_cast< OStatement* >( this )->m_bAttemptedComposerCreation = true;
681     try
682     {
683         Reference< XMultiServiceFactory > xFactory( m_xParent, UNO_QUERY_THROW );
684         const_cast< OStatement* >( this )->m_xComposer.set( xFactory->createInstance( SERVICE_NAME_SINGLESELECTQUERYCOMPOSER ), UNO_QUERY_THROW );
685     }
686     catch( const Exception& )
687     {
688         DBG_UNHANDLED_EXCEPTION();
689     }
690 
691     return m_xComposer.is();
692 }
693