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