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 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 //-------------------------------------------------------------------------- 93 OStatementBase::~OStatementBase() 94 { 95 DBG_DTOR(OStatementBase, NULL); 96 } 97 98 // com::sun::star::lang::XTypeProvider 99 //-------------------------------------------------------------------------- 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 //-------------------------------------------------------------------------- 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 //-------------------------------------------------------------------------- 151 void OStatementBase::acquire() throw () 152 { 153 OSubComponent::acquire(); 154 } 155 156 //-------------------------------------------------------------------------- 157 void OStatementBase::release() throw () 158 { 159 OSubComponent::release(); 160 } 161 162 //------------------------------------------------------------------------------ 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 //------------------------------------------------------------------------------ 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 //------------------------------------------------------------------------------ 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 //------------------------------------------------------------------------------ 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 //------------------------------------------------------------------------------ 229 ::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 //------------------------------------------------------------------------------ 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 //------------------------------------------------------------------------------ 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 //------------------------------------------------------------------------------ 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 //------------------------------------------------------------------------------ 322 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 //------------------------------------------------------------------------------ 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 //------------------------------------------------------------------------------ 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 //------------------------------------------------------------------------------ 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 //------------------------------------------------------------------------------ 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 //------------------------------------------------------------------------------ 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 //------------------------------------------------------------------------------ 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 //------------------------------------------------------------------------------ 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 //------------------------------------------------------------------------------ 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 //------------------------------------------------------------------------------ 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 // ----------------------------------------------------------------------------- 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 //------------------------------------------------------------------------------ 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 //------------------------------------------------------------------------------ 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 //------------------------------------------------------------------------------ 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 //------------------------------------------------------------------------------ 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 //------------------------------------------------------------------------------ 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 //------------------------------------------------------------------------------ 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 //------------------------------------------------------------------------------ 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 //------------------------------------------------------------------------------ 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 //------------------------------------------------------------------------------ 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 //------------------------------------------------------------------------------ 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 //------------------------------------------------------------------------------ 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 // ----------------------------------------------------------------------------- 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 // ----------------------------------------------------------------------------- 644 ::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 // ----------------------------------------------------------------------------- 674 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