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