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 31 #include "RowSet.hxx" 32 #include "dbastrings.hrc" 33 #include "sdbcoretools.hxx" 34 #include "SingleSelectQueryComposer.hxx" 35 #include "module_dba.hxx" 36 #include "sdbcoretools.hxx" 37 #include "CRowSetColumn.hxx" 38 #include "CRowSetDataColumn.hxx" 39 #include "RowSetCache.hxx" 40 #include "core_resource.hrc" 41 #include "core_resource.hxx" 42 #include "tablecontainer.hxx" 43 44 /** === begin UNO includes === **/ 45 #include <com/sun/star/beans/PropertyAttribute.hpp> 46 #include <com/sun/star/container/XChild.hpp> 47 #include <com/sun/star/lang/DisposedException.hpp> 48 #include <com/sun/star/sdb/CommandType.hpp> 49 #include <com/sun/star/sdb/ErrorCondition.hpp> 50 #include <com/sun/star/sdb/RowChangeAction.hpp> 51 #include <com/sun/star/sdb/RowSetVetoException.hpp> 52 #include <com/sun/star/sdb/XCompletedConnection.hpp> 53 #include <com/sun/star/sdb/XParametersSupplier.hpp> 54 #include <com/sun/star/sdb/XQueriesSupplier.hpp> 55 #include <com/sun/star/sdbc/FetchDirection.hpp> 56 #include <com/sun/star/sdbc/ResultSetConcurrency.hpp> 57 #include <com/sun/star/sdbc/XDataSource.hpp> 58 #include <com/sun/star/sdbc/XDriverAccess.hpp> 59 #include <com/sun/star/sdbcx/CompareBookmark.hpp> 60 #include <com/sun/star/sdbcx/Privilege.hpp> 61 #include <com/sun/star/sdbcx/XDataDefinitionSupplier.hpp> 62 #include <com/sun/star/uno/XNamingService.hpp> 63 #include <com/sun/star/util/XNumberFormatsSupplier.hpp> 64 /** === end UNO includes === **/ 65 66 #include <comphelper/componentcontext.hxx> 67 #include <comphelper/extract.hxx> 68 #include <comphelper/interaction.hxx> 69 #include <comphelper/property.hxx> 70 #include <comphelper/seqstream.hxx> 71 #include <comphelper/sequence.hxx> 72 #include <comphelper/types.hxx> 73 #include <comphelper/uno3.hxx> 74 #include <connectivity/BlobHelper.hxx> 75 #include <connectivity/dbconversion.hxx> 76 #include <connectivity/dbexception.hxx> 77 #include <connectivity/dbtools.hxx> 78 #include <cppuhelper/exc_hlp.hxx> 79 #include <cppuhelper/interfacecontainer.h> 80 #include <cppuhelper/typeprovider.hxx> 81 #include <rtl/logfile.hxx> 82 #include <unotools/syslocale.hxx> 83 #include <tools/debug.hxx> 84 #include <tools/diagnose_ex.h> 85 #include <unotools/configmgr.hxx> 86 87 using namespace utl; 88 using namespace dbaccess; 89 using namespace connectivity; 90 using namespace comphelper; 91 using namespace dbtools; 92 using namespace ::com::sun::star; 93 using namespace ::com::sun::star::uno; 94 using namespace ::com::sun::star::beans; 95 using namespace ::com::sun::star::sdbc; 96 using namespace ::com::sun::star::sdb; 97 using namespace ::com::sun::star::sdbcx; 98 using namespace ::com::sun::star::container; 99 using namespace ::com::sun::star::lang; 100 using namespace ::com::sun::star::task; 101 using namespace ::com::sun::star::util; 102 using namespace ::cppu; 103 using namespace ::osl; 104 105 //-------------------------------------------------------------------------- 106 extern "C" void SAL_CALL createRegistryInfo_ORowSet() 107 { 108 static ::dba::OAutoRegistration< ORowSet > aAutoRegistration; 109 } 110 // ----------------------------------------------------------------------------- 111 112 #define NOTIFY_LISTERNERS_CHECK(_rListeners,T,method) \ 113 Sequence< Reference< XInterface > > aListenerSeq = _rListeners.getElements(); \ 114 \ 115 const Reference< XInterface >* pxIntBegin = aListenerSeq.getConstArray(); \ 116 const Reference< XInterface >* pxInt = pxIntBegin + aListenerSeq.getLength(); \ 117 \ 118 _rGuard.clear(); \ 119 sal_Bool bCheck = sal_True; \ 120 while( pxInt > pxIntBegin && bCheck ) \ 121 { \ 122 try \ 123 { \ 124 while( pxInt > pxIntBegin && bCheck ) \ 125 { \ 126 --pxInt; \ 127 bCheck = static_cast< T* >( pxInt->get() )->method(aEvt); \ 128 } \ 129 } \ 130 catch( RuntimeException& ) \ 131 { \ 132 } \ 133 } \ 134 _rGuard.reset(); 135 136 137 //.................................................................. 138 namespace dbaccess 139 { 140 //.................................................................. 141 //-------------------------------------------------------------------------- 142 Reference< XInterface > ORowSet_CreateInstance(const Reference< XMultiServiceFactory >& _rxFactory) 143 { 144 return *(new ORowSet(_rxFactory)); 145 } 146 //-------------------------------------------------------------------------- 147 ORowSet::ORowSet( const Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxORB ) 148 :ORowSet_BASE1(m_aMutex) 149 ,ORowSetBase( _rxORB, ORowSet_BASE1::rBHelper, &m_aMutex ) 150 ,m_pParameters( NULL ) 151 ,m_aRowsetListeners(*m_pMutex) 152 ,m_aApproveListeners(*m_pMutex) 153 ,m_aRowsChangeListener(*m_pMutex) 154 ,m_pTables(NULL) 155 ,m_nFetchDirection(FetchDirection::FORWARD) 156 ,m_nFetchSize(50) 157 ,m_nMaxFieldSize(0) 158 ,m_nMaxRows(0) 159 ,m_nQueryTimeOut(0) 160 ,m_nCommandType(CommandType::COMMAND) 161 ,m_nTransactionIsolation(0) 162 ,m_nPrivileges(0) 163 ,m_nInAppend(0) 164 ,m_bUseEscapeProcessing(sal_True) 165 ,m_bApplyFilter(sal_False) 166 ,m_bCommandFacetsDirty( sal_True ) 167 ,m_bModified(sal_False) 168 ,m_bRebuildConnOnExecute(sal_False) 169 ,m_bIsBookmarable(sal_True) 170 ,m_bNew(sal_False) 171 ,m_bCanUpdateInsertedRows(sal_True) 172 ,m_bOwnConnection(sal_False) 173 { 174 m_nResultSetType = ResultSetType::SCROLL_SENSITIVE; 175 m_nResultSetConcurrency = ResultSetConcurrency::UPDATABLE; 176 m_pMySelf = this; 177 m_aActiveConnection <<= m_xActiveConnection; 178 179 sal_Int32 nRBT = PropertyAttribute::READONLY | PropertyAttribute::BOUND | PropertyAttribute::TRANSIENT; 180 sal_Int32 nRT = PropertyAttribute::READONLY | PropertyAttribute::TRANSIENT; 181 sal_Int32 nBT = PropertyAttribute::BOUND | PropertyAttribute::TRANSIENT; 182 183 m_aPrematureParamValues.get().resize( 0 ); 184 185 // sdb.RowSet Properties 186 registerMayBeVoidProperty(PROPERTY_ACTIVE_CONNECTION,PROPERTY_ID_ACTIVE_CONNECTION, PropertyAttribute::MAYBEVOID|PropertyAttribute::TRANSIENT|PropertyAttribute::BOUND, &m_aActiveConnection, ::getCppuType(reinterpret_cast< Reference< XConnection >* >(NULL))); 187 registerProperty(PROPERTY_DATASOURCENAME, PROPERTY_ID_DATASOURCENAME, PropertyAttribute::BOUND, &m_aDataSourceName, ::getCppuType(reinterpret_cast< ::rtl::OUString*>(NULL))); 188 registerProperty(PROPERTY_COMMAND, PROPERTY_ID_COMMAND, PropertyAttribute::BOUND, &m_aCommand, ::getCppuType(reinterpret_cast< ::rtl::OUString*>(NULL))); 189 registerProperty(PROPERTY_COMMAND_TYPE, PROPERTY_ID_COMMAND_TYPE, PropertyAttribute::BOUND, &m_nCommandType, ::getCppuType(reinterpret_cast< sal_Int32*>(NULL))); 190 registerProperty(PROPERTY_ACTIVECOMMAND, PROPERTY_ID_ACTIVECOMMAND, nRBT, &m_aActiveCommand, ::getCppuType(reinterpret_cast< ::rtl::OUString*>(NULL))); 191 registerProperty(PROPERTY_IGNORERESULT, PROPERTY_ID_IGNORERESULT, PropertyAttribute::BOUND, &m_bIgnoreResult, ::getBooleanCppuType()); 192 registerProperty(PROPERTY_FILTER, PROPERTY_ID_FILTER, PropertyAttribute::BOUND, &m_aFilter, ::getCppuType(reinterpret_cast< ::rtl::OUString*>(NULL))); 193 registerProperty(PROPERTY_HAVING_CLAUSE, PROPERTY_ID_HAVING_CLAUSE, PropertyAttribute::BOUND, &m_aHavingClause, ::getCppuType(reinterpret_cast< ::rtl::OUString*>(NULL))); 194 registerProperty(PROPERTY_GROUP_BY, PROPERTY_ID_GROUP_BY, PropertyAttribute::BOUND, &m_aGroupBy, ::getCppuType(reinterpret_cast< ::rtl::OUString*>(NULL))); 195 registerProperty(PROPERTY_APPLYFILTER, PROPERTY_ID_APPLYFILTER, PropertyAttribute::BOUND, &m_bApplyFilter, ::getBooleanCppuType()); 196 registerProperty(PROPERTY_ORDER, PROPERTY_ID_ORDER, PropertyAttribute::BOUND, &m_aOrder, ::getCppuType(reinterpret_cast< ::rtl::OUString*>(NULL))); 197 registerProperty(PROPERTY_PRIVILEGES, PROPERTY_ID_PRIVILEGES, nRT, &m_nPrivileges, ::getCppuType(reinterpret_cast< sal_Int32*>(NULL))); 198 registerProperty(PROPERTY_ISMODIFIED, PROPERTY_ID_ISMODIFIED, nBT, &m_bModified, ::getBooleanCppuType()); 199 registerProperty(PROPERTY_ISNEW, PROPERTY_ID_ISNEW, nRBT, &m_bNew, ::getBooleanCppuType()); 200 registerProperty(PROPERTY_SINGLESELECTQUERYCOMPOSER,PROPERTY_ID_SINGLESELECTQUERYCOMPOSER, nRT, &m_xComposer, ::getCppuType(reinterpret_cast< Reference< XSingleSelectQueryComposer >* >(NULL))); 201 202 // sdbcx.ResultSet Properties 203 registerProperty(PROPERTY_ISBOOKMARKABLE, PROPERTY_ID_ISBOOKMARKABLE, nRT, &m_bIsBookmarable, ::getBooleanCppuType()); 204 registerProperty(PROPERTY_CANUPDATEINSERTEDROWS,PROPERTY_ID_CANUPDATEINSERTEDROWS, nRT, &m_bCanUpdateInsertedRows, ::getBooleanCppuType()); 205 // sdbc.ResultSet Properties 206 registerProperty(PROPERTY_RESULTSETCONCURRENCY, PROPERTY_ID_RESULTSETCONCURRENCY, PropertyAttribute::TRANSIENT, &m_nResultSetConcurrency,::getCppuType(reinterpret_cast< sal_Int32*>(NULL))); 207 registerProperty(PROPERTY_RESULTSETTYPE, PROPERTY_ID_RESULTSETTYPE, PropertyAttribute::TRANSIENT, &m_nResultSetType, ::getCppuType(reinterpret_cast< sal_Int32*>(NULL))); 208 registerProperty(PROPERTY_FETCHDIRECTION, PROPERTY_ID_FETCHDIRECTION, PropertyAttribute::TRANSIENT, &m_nFetchDirection, ::getCppuType(reinterpret_cast< sal_Int32*>(NULL))); 209 registerProperty(PROPERTY_FETCHSIZE, PROPERTY_ID_FETCHSIZE, PropertyAttribute::TRANSIENT, &m_nFetchSize, ::getCppuType(reinterpret_cast< sal_Int32*>(NULL))); 210 211 // sdbc.RowSet Properties 212 registerProperty(PROPERTY_URL, PROPERTY_ID_URL, 0, &m_aURL, ::getCppuType(reinterpret_cast< ::rtl::OUString*>(NULL))); 213 registerProperty(PROPERTY_TRANSACTIONISOLATION, PROPERTY_ID_TRANSACTIONISOLATION, PropertyAttribute::TRANSIENT, &m_nTransactionIsolation,::getCppuType(reinterpret_cast< sal_Int32*>(NULL))); 214 registerMayBeVoidProperty(PROPERTY_TYPEMAP, PROPERTY_ID_TYPEMAP, PropertyAttribute::MAYBEVOID|PropertyAttribute::TRANSIENT, &m_aTypeMap, ::getCppuType(reinterpret_cast< Reference< XNameAccess >* >(NULL))); 215 registerProperty(PROPERTY_ESCAPE_PROCESSING,PROPERTY_ID_ESCAPE_PROCESSING, PropertyAttribute::BOUND, &m_bUseEscapeProcessing,::getBooleanCppuType() ); 216 registerProperty(PROPERTY_QUERYTIMEOUT, PROPERTY_ID_QUERYTIMEOUT, PropertyAttribute::TRANSIENT, &m_nQueryTimeOut, ::getCppuType(reinterpret_cast< sal_Int32*>(NULL))); 217 registerProperty(PROPERTY_MAXFIELDSIZE, PROPERTY_ID_MAXFIELDSIZE, PropertyAttribute::TRANSIENT, &m_nMaxFieldSize, ::getCppuType(reinterpret_cast< sal_Int32*>(NULL))); 218 registerProperty(PROPERTY_MAXROWS, PROPERTY_ID_MAXROWS, 0, &m_nMaxRows, ::getCppuType(reinterpret_cast< sal_Int32*>(NULL)) ); 219 registerProperty(PROPERTY_USER, PROPERTY_ID_USER, PropertyAttribute::TRANSIENT, &m_aUser, ::getCppuType(reinterpret_cast< ::rtl::OUString*>(NULL))); 220 registerProperty(PROPERTY_PASSWORD, PROPERTY_ID_PASSWORD, PropertyAttribute::TRANSIENT, &m_aPassword, ::getCppuType(reinterpret_cast< ::rtl::OUString*>(NULL))); 221 222 registerProperty(PROPERTY_UPDATE_CATALOGNAME, PROPERTY_ID_UPDATE_CATALOGNAME, PropertyAttribute::BOUND, &m_aUpdateCatalogName, ::getCppuType(reinterpret_cast< ::rtl::OUString*>(NULL))); 223 registerProperty(PROPERTY_UPDATE_SCHEMANAME, PROPERTY_ID_UPDATE_SCHEMANAME, PropertyAttribute::BOUND, &m_aUpdateSchemaName, ::getCppuType(reinterpret_cast< ::rtl::OUString*>(NULL))); 224 registerProperty(PROPERTY_UPDATE_TABLENAME, PROPERTY_ID_UPDATE_TABLENAME, PropertyAttribute::BOUND, &m_aUpdateTableName, ::getCppuType(reinterpret_cast< ::rtl::OUString*>(NULL))); 225 } 226 227 ORowSet::~ORowSet() 228 { 229 if ( !m_rBHelper.bDisposed && !m_rBHelper.bInDispose ) 230 { 231 OSL_ENSURE(0, "Please check who doesn't dispose this component!"); 232 osl_incrementInterlockedCount( &m_refCount ); 233 dispose(); 234 } 235 } 236 237 // ----------------------------------------------------------------------------- 238 void ORowSet::getPropertyDefaultByHandle( sal_Int32 _nHandle, Any& _rDefault ) const 239 { 240 switch( _nHandle ) 241 { 242 case PROPERTY_ID_COMMAND_TYPE: 243 _rDefault <<= static_cast<sal_Int32>(CommandType::COMMAND); 244 break; 245 case PROPERTY_ID_IGNORERESULT: 246 _rDefault <<= sal_False; 247 break; 248 case PROPERTY_ID_APPLYFILTER: 249 _rDefault <<= sal_False; 250 break; 251 case PROPERTY_ID_ISMODIFIED: 252 _rDefault <<= sal_False; 253 break; 254 case PROPERTY_ID_ISBOOKMARKABLE: 255 _rDefault <<= sal_True; 256 break; 257 case PROPERTY_ID_CANUPDATEINSERTEDROWS: 258 _rDefault <<= sal_True; 259 break; 260 case PROPERTY_ID_RESULTSETTYPE: 261 _rDefault <<= ResultSetType::SCROLL_INSENSITIVE; 262 break; 263 case PROPERTY_ID_RESULTSETCONCURRENCY: 264 _rDefault <<= ResultSetConcurrency::UPDATABLE; 265 break; 266 case PROPERTY_ID_FETCHDIRECTION: 267 _rDefault <<= FetchDirection::FORWARD; 268 break; 269 case PROPERTY_ID_FETCHSIZE: 270 _rDefault <<= static_cast<sal_Int32>(1); 271 break; 272 case PROPERTY_ID_ESCAPE_PROCESSING: 273 _rDefault <<= sal_True; 274 break; 275 case PROPERTY_ID_MAXROWS: 276 _rDefault <<= sal_Int32( 0 ); 277 break; 278 case PROPERTY_ID_FILTER: 279 case PROPERTY_ID_HAVING_CLAUSE: 280 case PROPERTY_ID_GROUP_BY: 281 case PROPERTY_ID_ORDER: 282 case PROPERTY_ID_UPDATE_CATALOGNAME: 283 case PROPERTY_ID_UPDATE_SCHEMANAME: 284 case PROPERTY_ID_UPDATE_TABLENAME: 285 _rDefault <<= ::rtl::OUString(); 286 break; 287 } 288 } 289 // ------------------------------------------------------------------------- 290 // typedef ::comphelper::OPropertyArrayUsageHelper<ORowSet> ORowSet_Prop; 291 292 void SAL_CALL ORowSet::setFastPropertyValue_NoBroadcast(sal_Int32 nHandle,const Any& rValue) throw (Exception) 293 { 294 switch(nHandle) 295 { 296 case PROPERTY_ID_ISMODIFIED: 297 m_bModified = cppu::any2bool(rValue); 298 break; 299 case PROPERTY_ID_FETCHDIRECTION: 300 if( m_nResultSetType == ResultSetType::FORWARD_ONLY) 301 throw Exception(); // else run through 302 default: 303 OPropertyStateContainer::setFastPropertyValue_NoBroadcast(nHandle,rValue); 304 } 305 306 if ( ( nHandle == PROPERTY_ID_ACTIVE_CONNECTION ) 307 || ( nHandle == PROPERTY_ID_DATASOURCENAME ) 308 || ( nHandle == PROPERTY_ID_COMMAND ) 309 || ( nHandle == PROPERTY_ID_COMMAND_TYPE ) 310 || ( nHandle == PROPERTY_ID_IGNORERESULT ) 311 || ( nHandle == PROPERTY_ID_FILTER ) 312 || ( nHandle == PROPERTY_ID_HAVING_CLAUSE ) 313 || ( nHandle == PROPERTY_ID_GROUP_BY ) 314 || ( nHandle == PROPERTY_ID_APPLYFILTER ) 315 || ( nHandle == PROPERTY_ID_ORDER ) 316 || ( nHandle == PROPERTY_ID_URL ) 317 || ( nHandle == PROPERTY_ID_USER ) 318 ) 319 { 320 m_bCommandFacetsDirty = sal_True; 321 } 322 323 324 switch(nHandle) 325 { 326 case PROPERTY_ID_ACTIVE_CONNECTION: 327 // the new connection 328 { 329 Reference< XConnection > xNewConnection(m_aActiveConnection,UNO_QUERY); 330 setActiveConnection(xNewConnection, sal_False); 331 } 332 333 m_bOwnConnection = sal_False; 334 m_bRebuildConnOnExecute = sal_False; 335 break; 336 337 case PROPERTY_ID_DATASOURCENAME: 338 if(!m_xStatement.is()) 339 { 340 Reference< XConnection > xNewConn; 341 Any aNewConn; 342 aNewConn <<= xNewConn; 343 setFastPropertyValue(PROPERTY_ID_ACTIVE_CONNECTION, aNewConn); 344 } 345 else 346 m_bRebuildConnOnExecute = sal_True; 347 break; 348 case PROPERTY_ID_FETCHSIZE: 349 if(m_pCache) 350 { 351 m_pCache->setFetchSize(m_nFetchSize); 352 fireRowcount(); 353 } 354 break; 355 case PROPERTY_ID_URL: 356 // is the connection-to-be-built determined by the url (which is the case if m_aDataSourceName is empty) ? 357 if (!m_aDataSourceName.getLength()) 358 { 359 // are we active at the moment ? 360 if (m_xStatement.is()) 361 // yes -> the next execute needs to rebuild our connection because of this new property 362 m_bRebuildConnOnExecute = sal_True; 363 else 364 { // no -> drop our active connection (if we have one) as it doesn't correspond to this new property value anymore 365 Reference< XConnection > xNewConn; 366 Any aNewConn; 367 aNewConn <<= xNewConn; 368 setFastPropertyValue(PROPERTY_ID_ACTIVE_CONNECTION, aNewConn); 369 } 370 } 371 m_bOwnConnection = sal_True; 372 break; 373 case PROPERTY_ID_TYPEMAP: 374 ::cppu::extractInterface(m_xTypeMap,m_aTypeMap); 375 break; 376 default: 377 break; 378 }; 379 } 380 // ------------------------------------------------------------------------- 381 void SAL_CALL ORowSet::getFastPropertyValue(Any& rValue,sal_Int32 nHandle) const 382 { 383 if(m_pCache) 384 { 385 switch(nHandle) 386 { 387 case PROPERTY_ID_ISMODIFIED: 388 rValue.setValue(&m_bModified,::getCppuBooleanType()); 389 break; 390 case PROPERTY_ID_ISNEW: 391 rValue.setValue(&m_bNew,::getCppuBooleanType()); 392 break; 393 case PROPERTY_ID_PRIVILEGES: 394 rValue <<= m_pCache->m_nPrivileges; 395 break; 396 case PROPERTY_ID_ACTIVE_CONNECTION: 397 rValue <<= m_xActiveConnection; 398 break; 399 case PROPERTY_ID_TYPEMAP: 400 rValue <<= m_xTypeMap; 401 break; 402 default: 403 ORowSetBase::getFastPropertyValue(rValue,nHandle); 404 }; 405 } 406 else 407 { 408 switch(nHandle) 409 { 410 case PROPERTY_ID_ACTIVE_CONNECTION: 411 rValue <<= m_xActiveConnection; 412 break; 413 case PROPERTY_ID_TYPEMAP: 414 rValue <<= m_xTypeMap; 415 break; 416 default: 417 ORowSetBase::getFastPropertyValue(rValue,nHandle); 418 } 419 } 420 } 421 // ------------------------------------------------------------------------- 422 // com::sun::star::XTypeProvider 423 Sequence< Type > SAL_CALL ORowSet::getTypes() throw (RuntimeException) 424 { 425 OTypeCollection aTypes(::getCppuType( (const Reference< XPropertySet > *)0 ), 426 ::getCppuType( (const Reference< XFastPropertySet > *)0 ), 427 ::getCppuType( (const Reference< XMultiPropertySet > *)0 ), 428 ::comphelper::concatSequences(ORowSet_BASE1::getTypes(),ORowSetBase::getTypes())); 429 return aTypes.getTypes(); 430 } 431 // ------------------------------------------------------------------------- 432 Sequence< sal_Int8 > SAL_CALL ORowSet::getImplementationId() throw (RuntimeException) 433 { 434 static OImplementationId * pId = 0; 435 if (! pId) 436 { 437 MutexGuard aGuard( Mutex::getGlobalMutex() ); 438 if (! pId) 439 { 440 static OImplementationId aId; 441 pId = &aId; 442 } 443 } 444 return pId->getImplementationId(); 445 } 446 // ------------------------------------------------------------------------- 447 448 // com::sun::star::XInterface 449 Any SAL_CALL ORowSet::queryInterface( const Type & rType ) throw (RuntimeException) 450 { 451 return ORowSet_BASE1::queryInterface( rType); 452 } 453 // ------------------------------------------------------------------------- 454 void SAL_CALL ORowSet::acquire() throw() 455 { 456 ORowSet_BASE1::acquire(); 457 } 458 // ------------------------------------------------------------------------- 459 void SAL_CALL ORowSet::release() throw() 460 { 461 ORowSet_BASE1::release(); 462 } 463 // ------------------------------------------------------------------------- 464 465 // com::sun::star::XUnoTunnel 466 sal_Int64 SAL_CALL ORowSet::getSomething( const Sequence< sal_Int8 >& rId ) throw(RuntimeException) 467 { 468 if (rId.getLength() == 16 && 0 == rtl_compareMemory(getImplementationId().getConstArray(), rId.getConstArray(), 16 ) ) 469 return reinterpret_cast<sal_Int64>(this); 470 471 return 0; 472 } 473 // ------------------------------------------------------------------------- 474 // com::sun::star::XAggregation 475 Any SAL_CALL ORowSet::queryAggregation( const Type& rType ) throw(RuntimeException) 476 { 477 Any aRet(ORowSetBase::queryInterface(rType)); 478 if (!aRet.hasValue()) 479 aRet = ORowSet_BASE1::queryAggregation(rType); 480 return aRet; 481 } 482 //------------------------------------------------------------------------------ 483 rtl::OUString ORowSet::getImplementationName_static( ) throw(RuntimeException) 484 { 485 return rtl::OUString::createFromAscii("com.sun.star.comp.dba.ORowSet"); 486 } 487 // ------------------------------------------------------------------------- 488 // ::com::sun::star::XServiceInfo 489 ::rtl::OUString SAL_CALL ORowSet::getImplementationName( ) throw(RuntimeException) 490 { 491 return getImplementationName_static(); 492 } 493 // ------------------------------------------------------------------------- 494 sal_Bool SAL_CALL ORowSet::supportsService( const ::rtl::OUString& _rServiceName ) throw(RuntimeException) 495 { 496 return ::comphelper::findValue(getSupportedServiceNames(), _rServiceName, sal_True).getLength() != 0; 497 } 498 //------------------------------------------------------------------------------ 499 Sequence< ::rtl::OUString > ORowSet::getSupportedServiceNames_static( ) throw (RuntimeException) 500 { 501 Sequence< rtl::OUString > aSNS( 5 ); 502 aSNS[0] = SERVICE_SDBC_RESULTSET; 503 aSNS[1] = SERVICE_SDBC_ROWSET; 504 aSNS[2] = SERVICE_SDBCX_RESULTSET; 505 aSNS[3] = SERVICE_SDB_RESULTSET; 506 aSNS[4] = SERVICE_SDB_ROWSET; 507 return aSNS; 508 } 509 // ------------------------------------------------------------------------- 510 Sequence< ::rtl::OUString > SAL_CALL ORowSet::getSupportedServiceNames( ) throw(RuntimeException) 511 { 512 return getSupportedServiceNames_static(); 513 } 514 //------------------------------------------------------------------------------ 515 Reference< XInterface > ORowSet::Create(const Reference< XComponentContext >& _rxContext) 516 { 517 ::comphelper::ComponentContext aContext( _rxContext ); 518 return ORowSet_CreateInstance( aContext.getLegacyServiceFactory() ); 519 } 520 // ------------------------------------------------------------------------- 521 // OComponentHelper 522 void SAL_CALL ORowSet::disposing() 523 { 524 OPropertyStateContainer::disposing(); 525 526 MutexGuard aGuard(m_aMutex); 527 EventObject aDisposeEvent; 528 aDisposeEvent.Source = static_cast< XComponent* >(this); 529 m_aRowsetListeners.disposeAndClear( aDisposeEvent ); 530 m_aApproveListeners.disposeAndClear( aDisposeEvent ); 531 m_aRowsChangeListener.disposeAndClear( aDisposeEvent ); 532 533 freeResources( true ); 534 535 // remove myself as dispose listener 536 Reference< XComponent > xComponent(m_xActiveConnection, UNO_QUERY); 537 if (xComponent.is()) 538 { 539 Reference<XEventListener> xEvt; 540 query_aggregation(this,xEvt); 541 xComponent->removeEventListener(xEvt); 542 } 543 544 m_aActiveConnection = Any(); // the any conatains a reference too 545 if(m_bOwnConnection) 546 ::comphelper::disposeComponent(m_xActiveConnection); 547 m_xActiveConnection = NULL; 548 549 550 ORowSetBase::disposing(); 551 } 552 // ------------------------------------------------------------------------- 553 void ORowSet::freeResources( bool _bComplete ) 554 { 555 MutexGuard aGuard(m_aMutex); 556 557 // free all clones 558 connectivity::OWeakRefArray::iterator aEnd = m_aClones.end(); 559 for (connectivity::OWeakRefArray::iterator i = m_aClones.begin(); aEnd != i; i++) 560 { 561 Reference< XComponent > xComp(i->get(), UNO_QUERY); 562 if (xComp.is()) 563 xComp->dispose(); 564 } 565 m_aClones.clear(); 566 567 if ( _bComplete ) 568 { 569 // the columns must be disposed before the querycomposer is disposed because 570 // their owner can be the composer 571 TDataColumns().swap(m_aDataColumns);// clear and resize capacity 572 m_xColumns = NULL; 573 if ( m_pColumns ) 574 m_pColumns->disposing(); 575 // dispose the composer to avoid that everbody knows that the querycomposer is eol 576 try { ::comphelper::disposeComponent( m_xComposer ); } 577 catch(Exception&) 578 { 579 DBG_UNHANDLED_EXCEPTION(); 580 m_xComposer = NULL; 581 } 582 583 // let our warnings container forget the reference to the (possibly disposed) old result set 584 m_aWarnings.setExternalWarnings( NULL ); 585 586 DELETEZ(m_pCache); 587 588 impl_resetTables_nothrow(); 589 590 m_xStatement = NULL; 591 m_xTypeMap = NULL; 592 593 m_aBookmark = Any(); 594 m_bBeforeFirst = sal_True; 595 m_bAfterLast = sal_False; 596 m_bNew = sal_False; 597 m_bModified = sal_False; 598 m_bIsInsertRow = sal_False; 599 m_bLastKnownRowCountFinal = sal_False; 600 m_nLastKnownRowCount = 0; 601 if ( m_aOldRow.isValid() ) 602 m_aOldRow->clearRow(); 603 604 impl_disposeParametersContainer_nothrow(); 605 606 m_bCommandFacetsDirty = sal_True; 607 } 608 } 609 610 // ------------------------------------------------------------------------- 611 void ORowSet::setActiveConnection( Reference< XConnection >& _rxNewConn, sal_Bool _bFireEvent ) 612 { 613 if (_rxNewConn.get() == m_xActiveConnection.get()) 614 // nothing to do 615 return; 616 617 // remove the event listener for the old connection 618 Reference< XComponent > xComponent(m_xActiveConnection, UNO_QUERY); 619 if (xComponent.is()) 620 { 621 Reference<XEventListener> xListener; 622 query_aggregation(this, xListener); 623 xComponent->removeEventListener(xListener); 624 } 625 626 // if we owned the connection, remember it for later disposing 627 if(m_bOwnConnection) 628 m_xOldConnection = m_xActiveConnection; 629 630 // for firing the PropertyChangeEvent 631 sal_Int32 nHandle = PROPERTY_ID_ACTIVE_CONNECTION; 632 Any aOldConnection; aOldConnection <<= m_xActiveConnection; 633 Any aNewConnection; aNewConnection <<= _rxNewConn; 634 635 // set the new connection 636 m_xActiveConnection = _rxNewConn; 637 if (m_xActiveConnection.is()) 638 m_aActiveConnection <<= m_xActiveConnection; 639 else 640 m_aActiveConnection.clear(); 641 642 // fire the event 643 if (_bFireEvent) 644 fire(&nHandle, &aNewConnection, &aOldConnection, 1, sal_False); 645 646 // register as event listener for the new connection 647 xComponent.set(m_xActiveConnection,UNO_QUERY); 648 if (xComponent.is()) 649 { 650 Reference<XEventListener> xListener; 651 query_aggregation(this, xListener); 652 xComponent->addEventListener(xListener); 653 } 654 } 655 656 // ------------------------------------------------------------------------- 657 // ::com::sun::star::XEventListener 658 void SAL_CALL ORowSet::disposing( const ::com::sun::star::lang::EventObject& Source ) throw(RuntimeException) 659 { 660 // close rowset because the connection is going to be deleted (someone told me :-) 661 Reference<XConnection> xCon(Source.Source,UNO_QUERY); 662 if(m_xActiveConnection == xCon) 663 { 664 close(); 665 { 666 MutexGuard aGuard( m_aMutex ); 667 Reference< XConnection > xXConnection; 668 setActiveConnection( xXConnection ); 669 } 670 } 671 } 672 // ------------------------------------------------------------------------- 673 674 // XCloseable 675 void SAL_CALL ORowSet::close( ) throw(SQLException, RuntimeException) 676 { 677 { 678 MutexGuard aGuard( m_aMutex ); 679 ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed); 680 } 681 // additionals things to set 682 freeResources( true ); 683 } 684 // ------------------------------------------------------------------------- 685 // comphelper::OPropertyArrayUsageHelper 686 ::cppu::IPropertyArrayHelper* ORowSet::createArrayHelper( ) const 687 { 688 Sequence< Property > aProps; 689 describeProperties(aProps); 690 return new ::cppu::OPropertyArrayHelper(aProps); 691 } 692 // ------------------------------------------------------------------------- 693 // cppu::OPropertySetHelper 694 ::cppu::IPropertyArrayHelper& SAL_CALL ORowSet::getInfoHelper() 695 { 696 typedef ::comphelper::OPropertyArrayUsageHelper<ORowSet> ORowSet_PROP; 697 return *ORowSet_PROP::getArrayHelper(); 698 } 699 // ----------------------------------------------------------------------------- 700 void ORowSet::updateValue(sal_Int32 columnIndex,const ORowSetValue& x) 701 { 702 ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed); 703 704 ::osl::MutexGuard aGuard( *m_pMutex ); 705 checkUpdateConditions(columnIndex); 706 checkUpdateIterator(); 707 708 ORowSetValueVector::Vector& rRow = ((*m_aCurrentRow)->get()); 709 ORowSetNotifier aNotify(this,rRow); 710 m_pCache->updateValue(columnIndex,x,rRow,aNotify.getChangedColumns()); 711 m_bModified = m_bModified || !aNotify.getChangedColumns().empty(); 712 aNotify.firePropertyChange(); 713 } 714 // ------------------------------------------------------------------------- 715 // XRowUpdate 716 void SAL_CALL ORowSet::updateNull( sal_Int32 columnIndex ) throw(SQLException, RuntimeException) 717 { 718 ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed); 719 720 ::osl::MutexGuard aGuard( *m_pMutex ); 721 checkUpdateConditions(columnIndex); 722 checkUpdateIterator(); 723 724 ORowSetValueVector::Vector& rRow = ((*m_aCurrentRow)->get()); 725 ORowSetNotifier aNotify(this,rRow); 726 m_pCache->updateNull(columnIndex,rRow,aNotify.getChangedColumns()); 727 m_bModified = m_bModified || !aNotify.getChangedColumns().empty(); 728 aNotify.firePropertyChange(); 729 } 730 // ------------------------------------------------------------------------- 731 void SAL_CALL ORowSet::updateBoolean( sal_Int32 columnIndex, sal_Bool x ) throw(SQLException, RuntimeException) 732 { 733 updateValue(columnIndex,x); 734 } 735 // ------------------------------------------------------------------------- 736 void SAL_CALL ORowSet::updateByte( sal_Int32 columnIndex, sal_Int8 x ) throw(SQLException, RuntimeException) 737 { 738 updateValue(columnIndex,x); 739 } 740 // ------------------------------------------------------------------------- 741 void SAL_CALL ORowSet::updateShort( sal_Int32 columnIndex, sal_Int16 x ) throw(SQLException, RuntimeException) 742 { 743 updateValue(columnIndex,x); 744 } 745 // ------------------------------------------------------------------------- 746 void SAL_CALL ORowSet::updateInt( sal_Int32 columnIndex, sal_Int32 x ) throw(SQLException, RuntimeException) 747 { 748 updateValue(columnIndex,x); 749 } 750 // ------------------------------------------------------------------------- 751 void SAL_CALL ORowSet::updateLong( sal_Int32 columnIndex, sal_Int64 x ) throw(SQLException, RuntimeException) 752 { 753 updateValue(columnIndex,x); 754 } 755 // ------------------------------------------------------------------------- 756 void SAL_CALL ORowSet::updateFloat( sal_Int32 columnIndex, float x ) throw(SQLException, RuntimeException) 757 { 758 updateValue(columnIndex,x); 759 } 760 // ------------------------------------------------------------------------- 761 void SAL_CALL ORowSet::updateDouble( sal_Int32 columnIndex, double x ) throw(SQLException, RuntimeException) 762 { 763 updateValue(columnIndex,x); 764 } 765 // ------------------------------------------------------------------------- 766 void SAL_CALL ORowSet::updateString( sal_Int32 columnIndex, const ::rtl::OUString& x ) throw(SQLException, RuntimeException) 767 { 768 updateValue(columnIndex,x); 769 } 770 // ------------------------------------------------------------------------- 771 void SAL_CALL ORowSet::updateBytes( sal_Int32 columnIndex, const Sequence< sal_Int8 >& x ) throw(SQLException, RuntimeException) 772 { 773 updateValue(columnIndex,x); 774 } 775 // ------------------------------------------------------------------------- 776 void SAL_CALL ORowSet::updateDate( sal_Int32 columnIndex, const ::com::sun::star::util::Date& x ) throw(SQLException, RuntimeException) 777 { 778 updateValue(columnIndex,x); 779 } 780 // ------------------------------------------------------------------------- 781 void SAL_CALL ORowSet::updateTime( sal_Int32 columnIndex, const ::com::sun::star::util::Time& x ) throw(SQLException, RuntimeException) 782 { 783 updateValue(columnIndex,x); 784 } 785 // ------------------------------------------------------------------------- 786 void SAL_CALL ORowSet::updateTimestamp( sal_Int32 columnIndex, const ::com::sun::star::util::DateTime& x ) throw(SQLException, RuntimeException) 787 { 788 updateValue(columnIndex,x); 789 } 790 // ------------------------------------------------------------------------- 791 void SAL_CALL ORowSet::updateBinaryStream( sal_Int32 columnIndex, const Reference< ::com::sun::star::io::XInputStream >& x, sal_Int32 length ) throw(SQLException, RuntimeException) 792 { 793 ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed); 794 ::osl::MutexGuard aGuard( *m_pMutex ); 795 checkUpdateConditions(columnIndex); 796 checkUpdateIterator(); 797 798 //if(((*m_aCurrentRow)->get())[columnIndex].getTypeKind() == DataType::BLOB) 799 //{ 800 // ::connectivity::ORowSetValue aOldValue = ((*m_aCurrentRow)->get())[columnIndex]; 801 // m_pCache->updateBinaryStream(columnIndex,x,length); 802 // ((*m_aCurrentRow)->get())[columnIndex] = makeAny(x); 803 // ((*m_aCurrentRow)->get())[columnIndex].setTypeKind(DataType::BLOB); 804 // firePropertyChange(columnIndex-1 ,aOldValue); 805 // fireProperty(PROPERTY_ID_ISMODIFIED,sal_True,sal_False); 806 //} 807 //else 808 { 809 Sequence<sal_Int8> aSeq; 810 if(x.is()) 811 x->readBytes(aSeq,length); 812 updateValue(columnIndex,aSeq); 813 } 814 } 815 // ------------------------------------------------------------------------- 816 void SAL_CALL ORowSet::updateCharacterStream( sal_Int32 columnIndex, const Reference< ::com::sun::star::io::XInputStream >& x, sal_Int32 length ) throw(SQLException, RuntimeException) 817 { 818 ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed); 819 ::osl::MutexGuard aGuard( *m_pMutex ); 820 checkUpdateConditions(columnIndex); 821 checkUpdateIterator(); 822 ORowSetValueVector::Vector& rRow = ((*m_aCurrentRow)->get()); 823 ORowSetNotifier aNotify(this,rRow); 824 m_pCache->updateCharacterStream(columnIndex,x,length,rRow,aNotify.getChangedColumns()); 825 m_bModified = m_bModified || !aNotify.getChangedColumns().empty(); 826 aNotify.firePropertyChange(); 827 } 828 // ------------------------------------------------------------------------- 829 void SAL_CALL ORowSet::updateObject( sal_Int32 columnIndex, const Any& x ) throw(SQLException, RuntimeException) 830 { 831 ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed); 832 ::osl::MutexGuard aGuard( *m_pMutex ); 833 checkUpdateConditions(columnIndex); 834 checkUpdateIterator(); 835 836 Any aNewValue = x; 837 838 if ( m_pColumns ) 839 { 840 Reference<XPropertySet> xColumn(m_pColumns->getByIndex(columnIndex-1),UNO_QUERY); 841 sal_Int32 nColType = 0; 842 xColumn->getPropertyValue(PROPERTY_TYPE) >>= nColType; 843 switch( nColType ) 844 { 845 case DataType::DATE: 846 case DataType::TIME: 847 case DataType::TIMESTAMP: 848 { 849 double nValue = 0; 850 if ( x >>= nValue ) 851 { 852 if ( DataType::TIMESTAMP == nColType ) 853 aNewValue <<= dbtools::DBTypeConversion::toDateTime( nValue ); 854 else if ( DataType::DATE == nColType ) 855 aNewValue <<= dbtools::DBTypeConversion::toDate( nValue ); 856 else 857 aNewValue <<= dbtools::DBTypeConversion::toTime( nValue ); 858 } 859 break; 860 } 861 } 862 } 863 864 if (!::dbtools::implUpdateObject(this, columnIndex, aNewValue)) 865 { // there is no other updateXXX call which can handle the value in x 866 ORowSetValueVector::Vector& rRow = ((*m_aCurrentRow)->get()); 867 ORowSetNotifier aNotify(this,rRow); 868 m_pCache->updateObject(columnIndex,aNewValue,rRow,aNotify.getChangedColumns()); 869 m_bModified = m_bModified || !aNotify.getChangedColumns().empty(); 870 aNotify.firePropertyChange(); 871 } 872 } 873 // ------------------------------------------------------------------------- 874 void SAL_CALL ORowSet::updateNumericObject( sal_Int32 columnIndex, const Any& x, sal_Int32 scale ) throw(SQLException, RuntimeException) 875 { 876 ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed); 877 ::osl::MutexGuard aGuard( *m_pMutex ); 878 checkUpdateConditions(columnIndex); 879 checkUpdateIterator(); 880 ORowSetValueVector::Vector& rRow = ((*m_aCurrentRow)->get()); 881 ORowSetNotifier aNotify(this,rRow); 882 m_pCache->updateNumericObject(columnIndex,x,scale,rRow,aNotify.getChangedColumns()); 883 m_bModified = m_bModified || !aNotify.getChangedColumns().empty(); 884 aNotify.firePropertyChange(); 885 } 886 // ------------------------------------------------------------------------- 887 888 // XResultSetUpdate 889 void SAL_CALL ORowSet::insertRow( ) throw(SQLException, RuntimeException) 890 { 891 ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed); 892 // insertRow is not allowd when 893 // standing not on the insert row nor 894 // when the row isn't modified 895 // or the concurency is read only 896 ::osl::ResettableMutexGuard aGuard( *m_pMutex ); 897 898 if(!m_pCache || !m_bNew || !m_bModified || m_nResultSetConcurrency == ResultSetConcurrency::READ_ONLY) 899 throwFunctionSequenceException(*this); 900 901 // remember old value for fire 902 sal_Bool bOld = m_bNew; 903 904 ORowSetRow aOldValues; 905 if ( !m_aCurrentRow.isNull() ) 906 aOldValues = new ORowSetValueVector( m_aCurrentRow->getBody() ); 907 Sequence<Any> aChangedBookmarks; 908 RowsChangeEvent aEvt(*this,RowChangeAction::INSERT,1,aChangedBookmarks); 909 notifyAllListenersRowBeforeChange(aGuard,aEvt); 910 911 ::std::vector< Any > aBookmarks; 912 sal_Bool bInserted = m_pCache->insertRow(aBookmarks); 913 914 // make sure that our row is set to the new inserted row before clearing the insert flags in the cache 915 m_pCache->resetInsertRow(bInserted); 916 917 // notification order 918 // - column values 919 setCurrentRow( sal_False, sal_True, aOldValues, aGuard ); // we don't move here 920 921 // read-only flag restored 922 impl_restoreDataColumnsWriteable_throw(); 923 924 // - rowChanged 925 notifyAllListenersRowChanged(aGuard,aEvt); 926 927 if ( !aBookmarks.empty() ) 928 { 929 RowsChangeEvent aUpEvt(*this,RowChangeAction::UPDATE,aBookmarks.size(),Sequence<Any>(&(*aBookmarks.begin()),aBookmarks.size())); 930 notifyAllListenersRowChanged(aGuard,aUpEvt); 931 } 932 933 // - IsModified 934 if(!m_bModified) 935 fireProperty(PROPERTY_ID_ISMODIFIED,sal_False,sal_True); 936 OSL_ENSURE( !m_bModified, "ORowSet::insertRow: just updated, but _still_ modified?" ); 937 938 // - IsNew 939 if(m_bNew != bOld) 940 fireProperty(PROPERTY_ID_ISNEW,m_bNew,bOld); 941 942 // - RowCount/IsRowCountFinal 943 fireRowcount(); 944 } 945 // ------------------------------------------------------------------------- 946 sal_Int32 SAL_CALL ORowSet::getRow( ) throw(SQLException, RuntimeException) 947 { 948 ::osl::MutexGuard aGuard( *m_pMutex ); 949 checkCache(); 950 951 // check if we are inserting a row 952 return (m_pCache && isInsertRow()) ? 0 : ORowSetBase::getRow(); 953 } 954 // ------------------------------------------------------------------------- 955 void SAL_CALL ORowSet::updateRow( ) throw(SQLException, RuntimeException) 956 { 957 ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed); 958 // not allowed when standing on insert row 959 ::osl::ResettableMutexGuard aGuard( *m_pMutex ); 960 if ( !m_pCache || m_nResultSetConcurrency == ResultSetConcurrency::READ_ONLY || m_bNew || ((m_pCache->m_nPrivileges & Privilege::UPDATE ) != Privilege::UPDATE) ) 961 throwFunctionSequenceException(*this); 962 963 964 if(m_bModified) 965 { 966 ORowSetRow aOldValues; 967 if ( !m_aCurrentRow.isNull() ) 968 aOldValues = new ORowSetValueVector( m_aCurrentRow->getBody() ); 969 970 Sequence<Any> aChangedBookmarks; 971 RowsChangeEvent aEvt(*this,RowChangeAction::UPDATE,1,aChangedBookmarks); 972 notifyAllListenersRowBeforeChange(aGuard,aEvt); 973 974 ::std::vector< Any > aBookmarks; 975 m_pCache->updateRow(m_aCurrentRow.operator ->(),aBookmarks); 976 if ( !aBookmarks.empty() ) 977 aEvt.Bookmarks = Sequence<Any>(&(*aBookmarks.begin()),aBookmarks.size()); 978 aEvt.Rows += aBookmarks.size(); 979 m_aBookmark = m_pCache->getBookmark(); 980 m_aCurrentRow = m_pCache->m_aMatrixIter; 981 m_bIsInsertRow = sal_False; 982 if ( m_pCache->m_aMatrixIter != m_pCache->getEnd() && (*m_pCache->m_aMatrixIter).isValid() ) 983 { 984 if ( m_pCache->isResultSetChanged() ) 985 { 986 impl_rebuild_throw(aGuard); 987 } 988 else 989 { 990 m_aOldRow->setRow(new ORowSetValueVector(m_aCurrentRow->getBody())); 991 992 // notification order 993 // - column values 994 ORowSetBase::firePropertyChange(aOldValues); 995 } 996 // - rowChanged 997 notifyAllListenersRowChanged(aGuard,aEvt); 998 999 // - IsModified 1000 if(!m_bModified) 1001 fireProperty(PROPERTY_ID_ISMODIFIED,sal_False,sal_True); 1002 OSL_ENSURE( !m_bModified, "ORowSet::updateRow: just updated, but _still_ modified?" ); 1003 1004 // - RowCount/IsRowCountFinal 1005 fireRowcount(); 1006 } 1007 else if ( !m_bAfterLast ) // the update went rong 1008 { 1009 ::dbtools::throwSQLException( DBACORE_RESSTRING( RID_STR_UPDATE_FAILED ), SQL_INVALID_CURSOR_POSITION, *this ); 1010 } 1011 } 1012 } 1013 // ------------------------------------------------------------------------- 1014 void SAL_CALL ORowSet::deleteRow( ) throw(SQLException, RuntimeException) 1015 { 1016 ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed); 1017 1018 ::osl::ResettableMutexGuard aGuard( *m_pMutex ); 1019 checkCache(); 1020 1021 if ( m_bBeforeFirst || m_bAfterLast ) 1022 ::dbtools::throwSQLException( DBACORE_RESSTRING( RID_STR_NO_DELETE_BEFORE_AFTER ), SQL_INVALID_CURSOR_POSITION, *this ); 1023 if ( m_bNew ) 1024 ::dbtools::throwSQLException( DBACORE_RESSTRING( RID_STR_NO_DELETE_INSERT_ROW ), SQL_INVALID_CURSOR_POSITION, *this ); 1025 if ( m_nResultSetConcurrency == ResultSetConcurrency::READ_ONLY ) 1026 ::dbtools::throwSQLException( DBACORE_RESSTRING( RID_STR_RESULT_IS_READONLY ), SQL_FUNCTION_SEQUENCE_ERROR, *this ); 1027 if ( ( m_pCache->m_nPrivileges & Privilege::DELETE ) != Privilege::DELETE ) 1028 ::dbtools::throwSQLException( DBACORE_RESSTRING( RID_STR_NO_DELETE_PRIVILEGE ), SQL_FUNCTION_SEQUENCE_ERROR, *this ); 1029 if ( rowDeleted() ) 1030 ::dbtools::throwSQLException( DBACORE_RESSTRING( RID_STR_ROW_ALREADY_DELETED ), SQL_FUNCTION_SEQUENCE_ERROR, *this ); 1031 1032 // this call position the cache indirect 1033 Any aBookmarkToDelete( m_aBookmark ); 1034 positionCache( MOVE_NONE_REFRESH_ONLY ); 1035 sal_Int32 nDeletePosition = m_pCache->getRow(); 1036 1037 notifyRowSetAndClonesRowDelete( aBookmarkToDelete ); 1038 1039 ORowSetRow aOldValues; 1040 if ( m_pCache->m_aMatrixIter != m_pCache->getEnd() && m_pCache->m_aMatrixIter->isValid() ) 1041 aOldValues = new ORowSetValueVector( m_pCache->m_aMatrixIter->getBody() ); 1042 1043 Sequence<Any> aChangedBookmarks; 1044 RowsChangeEvent aEvt(*this,RowChangeAction::DELETE,1,aChangedBookmarks); 1045 notifyAllListenersRowBeforeChange(aGuard,aEvt); 1046 1047 m_pCache->deleteRow(); 1048 notifyRowSetAndClonesRowDeleted( aBookmarkToDelete, nDeletePosition ); 1049 1050 ORowSetNotifier aNotifier( this ); 1051 // this will call cancelRowModification on the cache if necessary 1052 1053 // notification order 1054 // - rowChanged 1055 notifyAllListenersRowChanged(aGuard,aEvt); 1056 1057 // - IsModified 1058 // - IsNew 1059 aNotifier.fire( ); 1060 1061 // - RowCount/IsRowCountFinal 1062 fireRowcount(); 1063 } 1064 1065 // ------------------------------------------------------------------------- 1066 void ORowSet::implCancelRowUpdates( sal_Bool _bNotifyModified ) SAL_THROW( ( SQLException, RuntimeException ) ) 1067 { 1068 ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed); 1069 1070 ::osl::MutexGuard aGuard( *m_pMutex ); 1071 if ( m_bBeforeFirst || m_bAfterLast || rowDeleted() ) 1072 return; // nothing to do so return 1073 1074 checkCache(); 1075 // cancelRowUpdates is not allowed when: 1076 // - standing on the insert row 1077 // - the concurrency is read only 1078 // - the current row is deleted 1079 if ( m_bNew || m_nResultSetConcurrency == ResultSetConcurrency::READ_ONLY ) 1080 throwFunctionSequenceException(*this); 1081 1082 positionCache( MOVE_NONE_REFRESH_ONLY ); 1083 1084 ORowSetRow aOldValues; 1085 if ( !m_bModified && _bNotifyModified && !m_aCurrentRow.isNull() ) 1086 aOldValues = new ORowSetValueVector( m_aCurrentRow->getBody() ); 1087 1088 m_pCache->cancelRowUpdates(); 1089 1090 m_aBookmark = m_pCache->getBookmark(); 1091 m_aCurrentRow = m_pCache->m_aMatrixIter; 1092 m_bIsInsertRow = sal_False; 1093 m_aCurrentRow.setBookmark(m_aBookmark); 1094 1095 // notification order 1096 // IsModified 1097 if( !m_bModified && _bNotifyModified ) 1098 { 1099 // - column values 1100 ORowSetBase::firePropertyChange(aOldValues); 1101 fireProperty(PROPERTY_ID_ISMODIFIED,sal_False,sal_True); 1102 } 1103 } 1104 1105 // ------------------------------------------------------------------------- 1106 void SAL_CALL ORowSet::cancelRowUpdates( ) throw(SQLException, RuntimeException) 1107 { 1108 implCancelRowUpdates( sal_True ); 1109 } 1110 1111 // ------------------------------------------------------------------------- 1112 void SAL_CALL ORowSet::addRowSetListener( const Reference< XRowSetListener >& listener ) throw(RuntimeException) 1113 { 1114 ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed); 1115 1116 ::osl::MutexGuard aGuard( m_aColumnsMutex ); 1117 if(listener.is()) 1118 m_aRowsetListeners.addInterface(listener); 1119 } 1120 // ------------------------------------------------------------------------- 1121 void SAL_CALL ORowSet::removeRowSetListener( const Reference< XRowSetListener >& listener ) throw(RuntimeException) 1122 { 1123 ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed); 1124 1125 ::osl::MutexGuard aGuard( m_aColumnsMutex ); 1126 if(listener.is()) 1127 m_aRowsetListeners.removeInterface(listener); 1128 } 1129 // ----------------------------------------------------------------------------- 1130 void ORowSet::notifyAllListeners(::osl::ResettableMutexGuard& _rGuard) 1131 { 1132 EventObject aEvt(*m_pMySelf); 1133 _rGuard.clear(); 1134 m_aRowsetListeners.notifyEach( &XRowSetListener::rowSetChanged, aEvt ); 1135 _rGuard.reset(); 1136 } 1137 // ------------------------------------------------------------------------- 1138 void ORowSet::notifyAllListenersCursorMoved(::osl::ResettableMutexGuard& _rGuard) 1139 { 1140 EventObject aEvt(*m_pMySelf); 1141 _rGuard.clear(); 1142 m_aRowsetListeners.notifyEach( &XRowSetListener::cursorMoved, aEvt ); 1143 _rGuard.reset(); 1144 } 1145 // ------------------------------------------------------------------------- 1146 void ORowSet::notifyAllListenersRowChanged(::osl::ResettableMutexGuard& _rGuard, const RowsChangeEvent& aEvt) 1147 { 1148 _rGuard.clear(); 1149 m_aRowsetListeners.notifyEach( &XRowSetListener::rowChanged, (EventObject)aEvt ); 1150 m_aRowsChangeListener.notifyEach( &XRowsChangeListener::rowsChanged, aEvt ); 1151 _rGuard.reset(); 1152 } 1153 // ------------------------------------------------------------------------- 1154 sal_Bool ORowSet::notifyAllListenersCursorBeforeMove(::osl::ResettableMutexGuard& _rGuard) 1155 { 1156 EventObject aEvt(*m_pMySelf); 1157 NOTIFY_LISTERNERS_CHECK(m_aApproveListeners,XRowSetApproveListener,approveCursorMove); 1158 return bCheck; 1159 } 1160 // ------------------------------------------------------------------------- 1161 void ORowSet::notifyAllListenersRowBeforeChange(::osl::ResettableMutexGuard& _rGuard,const RowChangeEvent &aEvt) 1162 { 1163 NOTIFY_LISTERNERS_CHECK(m_aApproveListeners,XRowSetApproveListener,approveRowChange); 1164 if ( !bCheck ) 1165 m_aErrors.raiseTypedException( sdb::ErrorCondition::ROW_SET_OPERATION_VETOED, *this, ::cppu::UnoType< RowSetVetoException >::get() ); 1166 } 1167 // ------------------------------------------------------------------------- 1168 void ORowSet::fireRowcount() 1169 { 1170 sal_Int32 nCurrentRowCount( impl_getRowCount() ); 1171 sal_Bool bCurrentRowCountFinal( m_pCache->m_bRowCountFinal ); 1172 1173 if ( m_nLastKnownRowCount != nCurrentRowCount ) 1174 { 1175 sal_Int32 nHandle = PROPERTY_ID_ROWCOUNT; 1176 Any aNew,aOld; 1177 aNew <<= nCurrentRowCount; aOld <<= m_nLastKnownRowCount; 1178 fire(&nHandle,&aNew,&aOld,1,sal_False); 1179 m_nLastKnownRowCount = nCurrentRowCount; 1180 } 1181 if ( !m_bLastKnownRowCountFinal && ( m_bLastKnownRowCountFinal != bCurrentRowCountFinal ) ) 1182 { 1183 sal_Int32 nHandle = PROPERTY_ID_ISROWCOUNTFINAL; 1184 Any aNew,aOld; 1185 aNew <<= bCurrentRowCountFinal; 1186 aOld <<= m_bLastKnownRowCountFinal; 1187 fire(&nHandle,&aNew,&aOld,1,sal_False); 1188 m_bLastKnownRowCountFinal = bCurrentRowCountFinal; 1189 } 1190 } 1191 // ------------------------------------------------------------------------- 1192 void SAL_CALL ORowSet::moveToInsertRow( ) throw(SQLException, RuntimeException) 1193 { 1194 ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed); 1195 1196 ::osl::ResettableMutexGuard aGuard( *m_pMutex ); 1197 checkPositioningAllowed(); 1198 if ( ( m_pCache->m_nPrivileges & Privilege::INSERT ) != Privilege::INSERT ) 1199 ::dbtools::throwSQLException( DBACORE_RESSTRING( RID_STR_NO_INSERT_PRIVILEGE ), SQL_GENERAL_ERROR, *this ); 1200 1201 if ( notifyAllListenersCursorBeforeMove( aGuard ) ) 1202 { 1203 // remember old value for fire 1204 ORowSetRow aOldValues; 1205 if ( rowDeleted() ) 1206 { 1207 positionCache( MOVE_FORWARD ); 1208 m_pCache->next(); 1209 setCurrentRow( sal_True, sal_False, aOldValues, aGuard); 1210 } 1211 else 1212 positionCache( MOVE_NONE_REFRESH_ONLY ); 1213 1214 // check before because the resultset could be empty 1215 if ( !m_bBeforeFirst 1216 && !m_bAfterLast 1217 && m_pCache->m_aMatrixIter != m_pCache->getEnd() 1218 && m_pCache->m_aMatrixIter->isValid() 1219 ) 1220 aOldValues = new ORowSetValueVector( m_pCache->m_aMatrixIter->getBody() ); 1221 1222 const sal_Bool bNewState = m_bNew; 1223 const sal_Bool bModState = m_bModified; 1224 1225 m_pCache->moveToInsertRow(); 1226 m_aCurrentRow = m_pCache->m_aInsertRow; 1227 m_bIsInsertRow = sal_True; 1228 1229 // set read-only flag to false 1230 impl_setDataColumnsWriteable_throw(); 1231 1232 // notification order 1233 // - column values 1234 ORowSetBase::firePropertyChange(aOldValues); 1235 1236 // - cursorMoved 1237 notifyAllListenersCursorMoved(aGuard); 1238 1239 // - IsModified 1240 if ( bModState != m_bModified ) 1241 fireProperty( PROPERTY_ID_ISMODIFIED, m_bModified, bModState ); 1242 1243 // - IsNew 1244 if ( bNewState != m_bNew ) 1245 fireProperty( PROPERTY_ID_ISNEW, m_bNew, bNewState ); 1246 1247 // - RowCount/IsRowCountFinal 1248 fireRowcount(); 1249 } 1250 } 1251 // ------------------------------------------------------------------------- 1252 void ORowSet::impl_setDataColumnsWriteable_throw() 1253 { 1254 impl_restoreDataColumnsWriteable_throw(); 1255 TDataColumns::iterator aIter = m_aDataColumns.begin(); 1256 m_aReadOnlyDataColumns.resize(m_aDataColumns.size(),false); 1257 ::std::bit_vector::iterator aReadIter = m_aReadOnlyDataColumns.begin(); 1258 for(;aIter != m_aDataColumns.end();++aIter,++aReadIter) 1259 { 1260 sal_Bool bReadOnly = sal_False; 1261 (*aIter)->getPropertyValue(PROPERTY_ISREADONLY) >>= bReadOnly; 1262 *aReadIter = bReadOnly; 1263 1264 (*aIter)->setPropertyValue(PROPERTY_ISREADONLY,makeAny(sal_False)); 1265 } 1266 } 1267 // ------------------------------------------------------------------------- 1268 void ORowSet::impl_restoreDataColumnsWriteable_throw() 1269 { 1270 TDataColumns::iterator aIter = m_aDataColumns.begin(); 1271 ::std::bit_vector::iterator aReadIter = m_aReadOnlyDataColumns.begin(); 1272 for(;aReadIter != m_aReadOnlyDataColumns.end();++aIter,++aReadIter) 1273 { 1274 (*aIter)->setPropertyValue(PROPERTY_ISREADONLY,makeAny((sal_Bool)*aReadIter )); 1275 } 1276 m_aReadOnlyDataColumns.clear(); 1277 } 1278 // ------------------------------------------------------------------------- 1279 void SAL_CALL ORowSet::moveToCurrentRow( ) throw(SQLException, RuntimeException) 1280 { 1281 ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed); 1282 1283 ::osl::ResettableMutexGuard aGuard( *m_pMutex ); 1284 checkPositioningAllowed(); 1285 1286 if ( !m_pCache->m_bNew && !m_bModified ) 1287 // nothing to do if we're not on the insertion row, and not modified otherwise 1288 return; 1289 1290 if ( rowDeleted() ) 1291 // this would perhaps even justify a RuntimeException .... 1292 // if the current row is deleted, then no write access to this row should be possible. So, 1293 // m_bModified should be true. Also, as soon as somebody calls moveToInsertRow, 1294 // our current row should not be deleted anymore. So, we should not have survived the above 1295 // check "if ( !m_pCache->m_bNew && !m_bModified )" 1296 ::dbtools::throwSQLException( DBACORE_RESSTRING( RID_STR_ROW_ALREADY_DELETED ), SQL_FUNCTION_SEQUENCE_ERROR, *this ); 1297 1298 if ( notifyAllListenersCursorBeforeMove( aGuard ) ) 1299 { 1300 positionCache( MOVE_NONE_REFRESH_ONLY ); 1301 1302 ORowSetNotifier aNotifier( this ); 1303 1304 // notification order 1305 // - cursorMoved 1306 notifyAllListenersCursorMoved(aGuard); 1307 1308 // - IsModified 1309 // - IsNew 1310 aNotifier.fire(); 1311 } 1312 } 1313 // ------------------------------------------------------------------------- 1314 // XRow 1315 sal_Bool SAL_CALL ORowSet::wasNull( ) throw(SQLException, RuntimeException) 1316 { 1317 ::osl::MutexGuard aGuard( *m_pMutex ); 1318 checkCache(); 1319 1320 return ( m_pCache && isInsertRow() ) ? ((*m_pCache->m_aInsertRow)->get())[m_nLastColumnIndex].isNull() : ORowSetBase::wasNull(); 1321 } 1322 // ----------------------------------------------------------------------------- 1323 const ORowSetValue& ORowSet::getInsertValue(sal_Int32 columnIndex) 1324 { 1325 checkCache(); 1326 1327 if ( m_pCache && isInsertRow() ) 1328 return ((*m_pCache->m_aInsertRow)->get())[m_nLastColumnIndex = columnIndex]; 1329 1330 return getValue(columnIndex); 1331 } 1332 // ------------------------------------------------------------------------- 1333 ::rtl::OUString SAL_CALL ORowSet::getString( sal_Int32 columnIndex ) throw(SQLException, RuntimeException) 1334 { 1335 ::osl::MutexGuard aGuard( *m_pMutex ); 1336 return getInsertValue(columnIndex); 1337 } 1338 // ------------------------------------------------------------------------- 1339 sal_Bool SAL_CALL ORowSet::getBoolean( sal_Int32 columnIndex ) throw(SQLException, RuntimeException) 1340 { 1341 ::osl::MutexGuard aGuard( *m_pMutex ); 1342 return getInsertValue(columnIndex); 1343 } 1344 // ------------------------------------------------------------------------- 1345 sal_Int8 SAL_CALL ORowSet::getByte( sal_Int32 columnIndex ) throw(SQLException, RuntimeException) 1346 { 1347 ::osl::MutexGuard aGuard( *m_pMutex ); 1348 return getInsertValue(columnIndex); 1349 } 1350 // ------------------------------------------------------------------------- 1351 sal_Int16 SAL_CALL ORowSet::getShort( sal_Int32 columnIndex ) throw(SQLException, RuntimeException) 1352 { 1353 ::osl::MutexGuard aGuard( *m_pMutex ); 1354 return getInsertValue(columnIndex); 1355 } 1356 // ------------------------------------------------------------------------- 1357 sal_Int32 SAL_CALL ORowSet::getInt( sal_Int32 columnIndex ) throw(SQLException, RuntimeException) 1358 { 1359 ::osl::MutexGuard aGuard( *m_pMutex ); 1360 return getInsertValue(columnIndex); 1361 } 1362 // ------------------------------------------------------------------------- 1363 sal_Int64 SAL_CALL ORowSet::getLong( sal_Int32 columnIndex ) throw(SQLException, RuntimeException) 1364 { 1365 ::osl::MutexGuard aGuard( *m_pMutex ); 1366 return getInsertValue(columnIndex); 1367 } 1368 // ------------------------------------------------------------------------- 1369 float SAL_CALL ORowSet::getFloat( sal_Int32 columnIndex ) throw(SQLException, RuntimeException) 1370 { 1371 ::osl::MutexGuard aGuard( *m_pMutex ); 1372 return getInsertValue(columnIndex); 1373 } 1374 // ------------------------------------------------------------------------- 1375 double SAL_CALL ORowSet::getDouble( sal_Int32 columnIndex ) throw(SQLException, RuntimeException) 1376 { 1377 ::osl::MutexGuard aGuard( *m_pMutex ); 1378 return getInsertValue(columnIndex); 1379 } 1380 // ------------------------------------------------------------------------- 1381 Sequence< sal_Int8 > SAL_CALL ORowSet::getBytes( sal_Int32 columnIndex ) throw(SQLException, RuntimeException) 1382 { 1383 ::osl::MutexGuard aGuard( *m_pMutex ); 1384 return getInsertValue(columnIndex); 1385 } 1386 // ------------------------------------------------------------------------- 1387 ::com::sun::star::util::Date SAL_CALL ORowSet::getDate( sal_Int32 columnIndex ) throw(SQLException, RuntimeException) 1388 { 1389 ::osl::MutexGuard aGuard( *m_pMutex ); 1390 return getInsertValue(columnIndex); 1391 } 1392 // ------------------------------------------------------------------------- 1393 ::com::sun::star::util::Time SAL_CALL ORowSet::getTime( sal_Int32 columnIndex ) throw(SQLException, RuntimeException) 1394 { 1395 ::osl::MutexGuard aGuard( *m_pMutex ); 1396 return getInsertValue(columnIndex); 1397 } 1398 // ------------------------------------------------------------------------- 1399 ::com::sun::star::util::DateTime SAL_CALL ORowSet::getTimestamp( sal_Int32 columnIndex ) throw(SQLException, RuntimeException) 1400 { 1401 ::osl::MutexGuard aGuard( *m_pMutex ); 1402 return getInsertValue(columnIndex); 1403 } 1404 // ------------------------------------------------------------------------- 1405 Reference< ::com::sun::star::io::XInputStream > SAL_CALL ORowSet::getBinaryStream( sal_Int32 columnIndex ) throw(SQLException, RuntimeException) 1406 { 1407 ::osl::MutexGuard aGuard( *m_pMutex ); 1408 if ( m_pCache && isInsertRow() ) 1409 { 1410 checkCache(); 1411 return new ::comphelper::SequenceInputStream(((*m_pCache->m_aInsertRow)->get())[m_nLastColumnIndex = columnIndex].getSequence()); 1412 } 1413 1414 return ORowSetBase::getBinaryStream(columnIndex); 1415 } 1416 // ------------------------------------------------------------------------- 1417 Reference< ::com::sun::star::io::XInputStream > SAL_CALL ORowSet::getCharacterStream( sal_Int32 columnIndex ) throw(SQLException, RuntimeException) 1418 { 1419 ::osl::MutexGuard aGuard( *m_pMutex ); 1420 if(m_pCache && isInsertRow() ) 1421 { 1422 checkCache(); 1423 return new ::comphelper::SequenceInputStream(((*m_pCache->m_aInsertRow)->get())[m_nLastColumnIndex = columnIndex].getSequence()); 1424 } 1425 1426 return ORowSetBase::getCharacterStream(columnIndex); 1427 } 1428 // ------------------------------------------------------------------------- 1429 Any SAL_CALL ORowSet::getObject( sal_Int32 columnIndex, const Reference< XNameAccess >& /*typeMap*/ ) throw(SQLException, RuntimeException) 1430 { 1431 ::osl::MutexGuard aGuard( *m_pMutex ); 1432 return getInsertValue(columnIndex).makeAny(); 1433 } 1434 // ------------------------------------------------------------------------- 1435 Reference< XRef > SAL_CALL ORowSet::getRef( sal_Int32 /*columnIndex*/ ) throw(SQLException, RuntimeException) 1436 { 1437 return Reference< XRef >(); 1438 } 1439 // ------------------------------------------------------------------------- 1440 Reference< XBlob > SAL_CALL ORowSet::getBlob( sal_Int32 columnIndex ) throw(SQLException, RuntimeException) 1441 { 1442 if ( m_pCache && isInsertRow() ) 1443 { 1444 checkCache(); 1445 return new ::connectivity::BlobHelper(((*m_pCache->m_aInsertRow)->get())[m_nLastColumnIndex = columnIndex].getSequence()); 1446 } 1447 return ORowSetBase::getBlob(columnIndex); 1448 } 1449 // ------------------------------------------------------------------------- 1450 Reference< XClob > SAL_CALL ORowSet::getClob( sal_Int32 columnIndex ) throw(SQLException, RuntimeException) 1451 { 1452 return Reference< XClob >(getInsertValue(columnIndex).makeAny(),UNO_QUERY); 1453 } 1454 // ------------------------------------------------------------------------- 1455 Reference< XArray > SAL_CALL ORowSet::getArray( sal_Int32 /*columnIndex*/ ) throw(SQLException, RuntimeException) 1456 { 1457 return Reference< XArray >(); 1458 } 1459 // ------------------------------------------------------------------------- 1460 void SAL_CALL ORowSet::executeWithCompletion( const Reference< XInteractionHandler >& _rxHandler ) throw(SQLException, RuntimeException) 1461 { 1462 if (!_rxHandler.is()) 1463 execute(); 1464 1465 ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed); 1466 1467 // tell everybody that we will change the result set 1468 approveExecution(); 1469 1470 ResettableMutexGuard aGuard( m_aMutex ); 1471 1472 try 1473 { 1474 freeResources( m_bCommandFacetsDirty ); 1475 1476 // calc the connection to be used 1477 if (m_xActiveConnection.is() && m_bRebuildConnOnExecute) 1478 { 1479 // there was a setProperty(ActiveConnection), but a setProperty(DataSource) _after_ that, too 1480 Reference< XConnection > xXConnection; 1481 setActiveConnection( xXConnection ); 1482 } 1483 calcConnection( _rxHandler ); 1484 m_bRebuildConnOnExecute = sal_False; 1485 1486 Reference< XSingleSelectQueryComposer > xComposer = getCurrentSettingsComposer( this, m_aContext.getLegacyServiceFactory() ); 1487 Reference<XParametersSupplier> xParameters(xComposer, UNO_QUERY); 1488 1489 Reference<XIndexAccess> xParamsAsIndicies = xParameters.is() ? xParameters->getParameters() : Reference<XIndexAccess>(); 1490 const sal_Int32 nParamCount = xParamsAsIndicies.is() ? xParamsAsIndicies->getCount() : 0; 1491 if ( m_aParametersSet.size() < (size_t)nParamCount ) 1492 m_aParametersSet.resize( nParamCount ,false); 1493 1494 ::dbtools::askForParameters( xComposer, this, m_xActiveConnection, _rxHandler,m_aParametersSet ); 1495 } 1496 // ensure that only the allowed exceptions leave this block 1497 catch(SQLException&) 1498 { 1499 throw; 1500 } 1501 catch(RuntimeException&) 1502 { 1503 throw; 1504 } 1505 catch(Exception&) 1506 { 1507 DBG_ERROR("ORowSet::executeWithCompletion: caught an unexpected exception type while filling in the parameters!"); 1508 } 1509 1510 // we're done with the parameters, now for the real execution 1511 1512 // do the real execute 1513 execute_NoApprove_NoNewConn(aGuard); 1514 } 1515 1516 // ------------------------------------------------------------------------- 1517 Reference< XIndexAccess > SAL_CALL ORowSet::getParameters( ) throw (RuntimeException) 1518 { 1519 ::osl::MutexGuard aGuard( *m_pMutex ); 1520 ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed); 1521 1522 if ( m_bCommandFacetsDirty ) 1523 // need to rebuild the parameters, since some property which contributes to the 1524 // complete command, and thus the parameters, changed 1525 impl_disposeParametersContainer_nothrow(); 1526 1527 if ( !m_pParameters.get() && m_aCommand.getLength() ) 1528 { 1529 try 1530 { 1531 ::rtl::OUString sNotInterestedIn; 1532 impl_initComposer_throw( sNotInterestedIn ); 1533 } 1534 catch( const Exception& ) 1535 { 1536 // silence it 1537 } 1538 } 1539 1540 return m_pParameters.get(); 1541 } 1542 1543 // ------------------------------------------------------------------------- 1544 void ORowSet::approveExecution() throw (RowSetVetoException, RuntimeException) 1545 { 1546 ::osl::MutexGuard aGuard( m_aColumnsMutex ); 1547 EventObject aEvt(*this); 1548 1549 OInterfaceIteratorHelper aApproveIter( m_aApproveListeners ); 1550 while ( aApproveIter.hasMoreElements() ) 1551 { 1552 Reference< XRowSetApproveListener > xListener( static_cast< XRowSetApproveListener* >( aApproveIter.next() ) ); 1553 try 1554 { 1555 if ( xListener.is() && !xListener->approveRowSetChange( aEvt ) ) 1556 throw RowSetVetoException(); 1557 } 1558 catch ( const DisposedException& e ) 1559 { 1560 if ( e.Context == xListener ) 1561 aApproveIter.remove(); 1562 } 1563 catch ( const RuntimeException& ) { throw; } 1564 catch ( const RowSetVetoException& ) { throw; } 1565 catch ( const Exception& ) 1566 { 1567 DBG_UNHANDLED_EXCEPTION(); 1568 } 1569 } 1570 } 1571 // ------------------------------------------------------------------------- 1572 // XRowSet 1573 // ------------------------------------------------------------------------- 1574 void SAL_CALL ORowSet::execute( ) throw(SQLException, RuntimeException) 1575 { 1576 ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed); 1577 1578 // tell everybody that we will change the result set 1579 approveExecution(); 1580 1581 ResettableMutexGuard aGuard( m_aMutex ); 1582 freeResources( m_bCommandFacetsDirty ); 1583 1584 // calc the connection to be used 1585 if (m_xActiveConnection.is() && m_bRebuildConnOnExecute) { 1586 // there was a setProperty(ActiveConnection), but a setProperty(DataSource) _after_ that, too 1587 Reference< XConnection> xXConnection; 1588 setActiveConnection( xXConnection ); 1589 } 1590 1591 calcConnection(NULL); 1592 m_bRebuildConnOnExecute = sal_False; 1593 1594 // do the real execute 1595 execute_NoApprove_NoNewConn(aGuard); 1596 } 1597 1598 //------------------------------------------------------------------------------ 1599 void ORowSet::setStatementResultSetType( const Reference< XPropertySet >& _rxStatement, sal_Int32 _nDesiredResultSetType, sal_Int32 _nDesiredResultSetConcurrency ) 1600 { 1601 OSL_ENSURE( _rxStatement.is(), "ORowSet::setStatementResultSetType: invalid statement - this will crash!" ); 1602 1603 sal_Int32 nResultSetType( _nDesiredResultSetType ); 1604 sal_Int32 nResultSetConcurrency( _nDesiredResultSetConcurrency ); 1605 1606 // there *might* be a data source setting which tells use to be more defensive with those settings 1607 // #i15113# / 2005-02-10 / frank.schoenheit@sun.com 1608 sal_Bool bRespectDriverRST = sal_False; 1609 Any aSetting; 1610 if ( getDataSourceSetting( ::dbaccess::getDataSource( m_xActiveConnection ), "RespectDriverResultSetType", aSetting ) ) 1611 { 1612 OSL_VERIFY( aSetting >>= bRespectDriverRST ); 1613 } 1614 1615 if ( bRespectDriverRST ) 1616 { 1617 // try type/concurrency settings with decreasing usefullness, and rely on what the connection claims 1618 // to support 1619 Reference< XDatabaseMetaData > xMeta( m_xActiveConnection->getMetaData() ); 1620 1621 sal_Int32 nCharacteristics[5][2] = 1622 { { ResultSetType::SCROLL_SENSITIVE, ResultSetConcurrency::UPDATABLE }, 1623 { ResultSetType::SCROLL_INSENSITIVE, ResultSetConcurrency::UPDATABLE }, 1624 { ResultSetType::SCROLL_SENSITIVE, ResultSetConcurrency::READ_ONLY }, 1625 { ResultSetType::SCROLL_INSENSITIVE, ResultSetConcurrency::READ_ONLY }, 1626 { ResultSetType::FORWARD_ONLY, ResultSetConcurrency::READ_ONLY } 1627 }; 1628 sal_Int32 i=0; 1629 if ( m_xActiveConnection->getMetaData()->isReadOnly() ) 1630 i = 2; // if the database is read-only we only should use read-only concurrency 1631 1632 for ( ; i<5; ++i ) 1633 { 1634 nResultSetType = nCharacteristics[i][0]; 1635 nResultSetConcurrency = nCharacteristics[i][1]; 1636 1637 // don't try type/concurrency pairs which are more featured than what our caller requested 1638 if ( nResultSetType > _nDesiredResultSetType ) 1639 continue; 1640 if ( nResultSetConcurrency > _nDesiredResultSetConcurrency ) 1641 continue; 1642 1643 if ( xMeta.is() && xMeta->supportsResultSetConcurrency( nResultSetType, nResultSetConcurrency ) ) 1644 break; 1645 } 1646 } 1647 1648 _rxStatement->setPropertyValue( PROPERTY_RESULTSETTYPE, makeAny( nResultSetType ) ); 1649 _rxStatement->setPropertyValue( PROPERTY_RESULTSETCONCURRENCY, makeAny( nResultSetConcurrency ) ); 1650 } 1651 1652 // ----------------------------------------------------------------------------- 1653 Reference< XResultSet > ORowSet::impl_prepareAndExecute_throw() 1654 { 1655 ::rtl::OUString sCommandToExecute; 1656 sal_Bool bUseEscapeProcessing = impl_initComposer_throw( sCommandToExecute ); 1657 1658 Reference< XResultSet> xResultSet; 1659 try 1660 { 1661 m_xStatement = m_xActiveConnection->prepareStatement( sCommandToExecute ); 1662 if ( !m_xStatement.is() ) 1663 { 1664 ::dbtools::throwSQLException( DBACORE_RESSTRING( RID_STR_INTERNAL_ERROR ), SQL_GENERAL_ERROR, *this ); 1665 } 1666 1667 Reference< XPropertySet > xStatementProps( m_xStatement, UNO_QUERY_THROW ); 1668 // set the result set type and concurrency 1669 try 1670 { 1671 xStatementProps->setPropertyValue( PROPERTY_USEBOOKMARKS, makeAny( sal_True ) ); 1672 xStatementProps->setPropertyValue( PROPERTY_MAXROWS, makeAny( m_nMaxRows ) ); 1673 1674 setStatementResultSetType( xStatementProps, m_nResultSetType, m_nResultSetConcurrency ); 1675 } 1676 catch ( const Exception& ) 1677 { 1678 // this exception doesn't matter here because when we catch an exception 1679 // then the driver doesn't support this feature 1680 } 1681 m_aParameterValueForCache.get().resize(1); 1682 Reference< XParameters > xParam( m_xStatement, UNO_QUERY_THROW ); 1683 size_t nParamCount( m_pParameters.is() ? m_pParameters->size() : m_aPrematureParamValues.get().size() ); 1684 for ( size_t i=1; i<=nParamCount; ++i ) 1685 { 1686 ORowSetValue& rParamValue( getParameterStorage( (sal_Int32)i ) ); 1687 ::dbtools::setObjectWithInfo( xParam, i, rParamValue.makeAny(), rParamValue.getTypeKind() ); 1688 m_aParameterValueForCache.get().push_back(rParamValue); 1689 } 1690 1691 xResultSet = m_xStatement->executeQuery(); 1692 } 1693 catch( const SQLException& ) 1694 { 1695 SQLExceptionInfo aError( ::cppu::getCaughtException() ); 1696 OSL_ENSURE( aError.isValid(), "ORowSet::impl_prepareAndExecute_throw: caught an SQLException which we cannot analyze!" ); 1697 1698 // append information about what we were actually going to execute 1699 try 1700 { 1701 String sQuery = bUseEscapeProcessing && m_xComposer.is() ? m_xComposer->getQuery() : m_aActiveCommand; 1702 String sInfo( DBA_RES_PARAM( RID_STR_COMMAND_LEADING_TO_ERROR, "$command$", sQuery ) ); 1703 aError.append( SQLExceptionInfo::SQL_CONTEXT, sInfo ); 1704 } 1705 catch( const Exception& ) { DBG_UNHANDLED_EXCEPTION(); } 1706 1707 // propagate 1708 aError.doThrow(); 1709 } 1710 1711 return xResultSet; 1712 } 1713 1714 // ----------------------------------------------------------------------------- 1715 void ORowSet::impl_initializeColumnSettings_nothrow( const Reference< XPropertySet >& _rxTemplateColumn, const Reference< XPropertySet >& _rxRowSetColumn ) 1716 { 1717 OSL_ENSURE( _rxTemplateColumn.is() && _rxRowSetColumn.is(), 1718 "ORowSet::impl_initializeColumnSettings_nothrow: this will crash!" ); 1719 1720 bool bHaveAnyColumnSetting = false; 1721 try 1722 { 1723 Reference< XPropertySetInfo > xInfo( _rxTemplateColumn->getPropertySetInfo(), UNO_QUERY_THROW ); 1724 1725 // a number of properties is plain copied 1726 const ::rtl::OUString aPropertyNames[] = { 1727 PROPERTY_ALIGN, PROPERTY_RELATIVEPOSITION, PROPERTY_WIDTH, PROPERTY_HIDDEN, PROPERTY_CONTROLMODEL, 1728 PROPERTY_HELPTEXT, PROPERTY_CONTROLDEFAULT 1729 }; 1730 for ( size_t i=0; i<sizeof( aPropertyNames ) / sizeof( aPropertyNames[0] ); ++i ) 1731 { 1732 if ( xInfo->hasPropertyByName( aPropertyNames[i] ) ) 1733 { 1734 _rxRowSetColumn->setPropertyValue( aPropertyNames[i], _rxTemplateColumn->getPropertyValue( aPropertyNames[i] ) ); 1735 bHaveAnyColumnSetting = true; 1736 } 1737 } 1738 1739 // the format key is slightly more complex 1740 sal_Int32 nFormatKey = 0; 1741 if( xInfo->hasPropertyByName( PROPERTY_NUMBERFORMAT ) ) 1742 { 1743 _rxTemplateColumn->getPropertyValue( PROPERTY_NUMBERFORMAT ) >>= nFormatKey; 1744 bHaveAnyColumnSetting = true; 1745 } 1746 if ( !nFormatKey && m_xNumberFormatTypes.is() ) 1747 nFormatKey = ::dbtools::getDefaultNumberFormat( _rxTemplateColumn, m_xNumberFormatTypes, SvtSysLocale().GetLocaleData().getLocale() ); 1748 _rxRowSetColumn->setPropertyValue( PROPERTY_NUMBERFORMAT, makeAny( nFormatKey ) ); 1749 } 1750 catch(Exception&) 1751 { 1752 DBG_UNHANDLED_EXCEPTION(); 1753 return; 1754 } 1755 1756 if ( bHaveAnyColumnSetting ) 1757 return; 1758 1759 // the template column could not provide *any* setting. Okay, probably it's a parser column, which 1760 // does not offer those. However, perhaps the template column referes to a table column, which we 1761 // can use as new template column 1762 try 1763 { 1764 Reference< XPropertySetInfo > xInfo( _rxTemplateColumn->getPropertySetInfo(), UNO_QUERY_THROW ); 1765 if ( !xInfo->hasPropertyByName( PROPERTY_TABLENAME ) ) 1766 // no chance 1767 return; 1768 1769 ::rtl::OUString sTableName; 1770 OSL_VERIFY( _rxTemplateColumn->getPropertyValue( PROPERTY_TABLENAME ) >>= sTableName ); 1771 1772 Reference< XNameAccess > xTables( impl_getTables_throw(), UNO_QUERY_THROW ); 1773 if ( !xTables->hasByName( sTableName ) ) 1774 // no chance 1775 return; 1776 1777 Reference< XColumnsSupplier > xTableColSup( xTables->getByName( sTableName ), UNO_QUERY_THROW ); 1778 Reference< XNameAccess > xTableCols( xTableColSup->getColumns(), UNO_QUERY_THROW ); 1779 1780 ::rtl::OUString sTableColumnName; 1781 1782 // get the "Name" or (preferred) "RealName" property of the column 1783 ::rtl::OUString sNamePropertyName( PROPERTY_NAME ); 1784 if ( xInfo->hasPropertyByName( PROPERTY_REALNAME ) ) 1785 sNamePropertyName = PROPERTY_REALNAME; 1786 OSL_VERIFY( _rxTemplateColumn->getPropertyValue( sNamePropertyName ) >>= sTableColumnName ); 1787 1788 if ( !xTableCols->hasByName( sTableColumnName ) ) 1789 return; 1790 1791 Reference< XPropertySet > xTableColumn( xTableCols->getByName( sTableColumnName ), UNO_QUERY_THROW ); 1792 impl_initializeColumnSettings_nothrow( xTableColumn, _rxRowSetColumn ); 1793 } 1794 catch( const Exception& ) 1795 { 1796 DBG_UNHANDLED_EXCEPTION(); 1797 } 1798 } 1799 1800 // ----------------------------------------------------------------------------- 1801 void ORowSet::execute_NoApprove_NoNewConn(ResettableMutexGuard& _rClearForNotification) 1802 { 1803 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "frank.schoenheit@sun.com", "ORowSet::execute_NoApprove_NoNewConn" ); 1804 1805 // now we can dispose our old connection 1806 ::comphelper::disposeComponent(m_xOldConnection); 1807 m_xOldConnection = NULL; 1808 1809 // do we need a new statement 1810 if ( m_bCommandFacetsDirty ) 1811 { 1812 m_xStatement = NULL; 1813 m_xComposer = NULL; 1814 1815 Reference< XResultSet > xResultSet( impl_prepareAndExecute_throw() ); 1816 1817 // let our warnings container forget the reference to the (possibly disposed) old result set 1818 m_aWarnings.setExternalWarnings( NULL ); 1819 // clear all current warnings 1820 m_aWarnings.clearWarnings(); 1821 // let the warnings container know about the new "external warnings" 1822 m_aWarnings.setExternalWarnings( Reference< XWarningsSupplier >( xResultSet, UNO_QUERY ) ); 1823 1824 ::rtl::OUString aComposedUpdateTableName; 1825 if ( m_aUpdateTableName.getLength() ) 1826 aComposedUpdateTableName = composeTableName( m_xActiveConnection->getMetaData(), m_aUpdateCatalogName, m_aUpdateSchemaName, m_aUpdateTableName, sal_False, ::dbtools::eInDataManipulation ); 1827 1828 { 1829 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "frank.schoenheit@sun.com", "ORowSet::execute_NoApprove_NoNewConn: creating cache" ); 1830 m_pCache = new ORowSetCache( xResultSet, m_xComposer.get(), m_aContext, aComposedUpdateTableName, m_bModified, m_bNew,m_aParameterValueForCache,m_aFilter,m_nMaxRows ); 1831 if ( m_nResultSetConcurrency == ResultSetConcurrency::READ_ONLY ) 1832 { 1833 m_nPrivileges = Privilege::SELECT; 1834 m_pCache->m_nPrivileges = Privilege::SELECT; 1835 } 1836 m_pCache->setFetchSize(m_nFetchSize); 1837 m_aCurrentRow = m_pCache->createIterator(this); 1838 m_bIsInsertRow = sal_False; 1839 m_aOldRow = m_pCache->registerOldRow(); 1840 } 1841 1842 // get the locale 1843 // ConfigManager* pConfigMgr = ConfigManager::GetConfigManager(); 1844 Locale aLocale = SvtSysLocale().GetLocaleData().getLocale(); 1845 // pConfigMgr->GetDirectConfigProperty(ConfigManager::LOCALE) >>= aLocale; 1846 1847 // get the numberformatTypes 1848 OSL_ENSURE(m_xActiveConnection.is(),"No ActiveConnection"); 1849 Reference< XNumberFormatTypes> xNumberFormatTypes; 1850 Reference< XNumberFormatsSupplier> xNumberFormat = ::dbtools::getNumberFormats(m_xActiveConnection); 1851 if ( xNumberFormat.is() ) 1852 m_xNumberFormatTypes.set(xNumberFormat->getNumberFormats(),UNO_QUERY); 1853 1854 ::vos::ORef< ::connectivity::OSQLColumns> aColumns = new ::connectivity::OSQLColumns(); 1855 ::std::vector< ::rtl::OUString> aNames; 1856 ::rtl::OUString aDescription; 1857 sal_Int32 nFormatKey = 0; 1858 1859 const ::std::map<sal_Int32,sal_Int32>& rKeyColumns = m_pCache->getKeyColumns(); 1860 if(!m_xColumns.is()) 1861 { 1862 RTL_LOGFILE_CONTEXT_AUTHOR( aColumnCreateLog, "dbaccess", "frank.schoenheit@sun.com", "ORowSet::execute_NoApprove_NoNewConn::creating columns" ); 1863 // use the meta data 1864 Reference<XResultSetMetaDataSupplier> xMetaSup(m_xStatement,UNO_QUERY); 1865 try 1866 { 1867 Reference<XResultSetMetaData> xMetaData = xMetaSup->getMetaData(); 1868 if ( xMetaData.is() ) 1869 { 1870 sal_Int32 nCount = xMetaData->getColumnCount(); 1871 m_aDataColumns.reserve(nCount+1); 1872 aColumns->get().reserve(nCount+1); 1873 DECLARE_STL_USTRINGACCESS_MAP(int,StringMap); 1874 StringMap aColumnMap; 1875 for (sal_Int32 i = 0 ; i < nCount; ++i) 1876 { 1877 // retrieve the name of the column 1878 ::rtl::OUString sName = xMetaData->getColumnName(i + 1); 1879 // check for duplicate entries 1880 if(aColumnMap.find(sName) != aColumnMap.end()) 1881 { 1882 ::rtl::OUString sAlias(sName); 1883 sal_Int32 searchIndex=1; 1884 while(aColumnMap.find(sAlias) != aColumnMap.end()) 1885 { 1886 (sAlias = sName) += ::rtl::OUString::valueOf(searchIndex++); 1887 } 1888 sName = sAlias; 1889 } 1890 ORowSetDataColumn* pColumn = new ORowSetDataColumn( getMetaData(), 1891 this, 1892 this, 1893 i+1, 1894 m_xActiveConnection->getMetaData(), 1895 aDescription, 1896 ::rtl::OUString(), 1897 m_aCurrentRow); 1898 aColumnMap.insert(StringMap::value_type(sName,0)); 1899 aColumns->get().push_back(pColumn); 1900 pColumn->setName(sName); 1901 aNames.push_back(sName); 1902 m_aDataColumns.push_back(pColumn); 1903 1904 pColumn->setFastPropertyValue_NoBroadcast(PROPERTY_ID_ISREADONLY,makeAny(rKeyColumns.find(i+1) != rKeyColumns.end())); 1905 1906 try 1907 { 1908 nFormatKey = 0; 1909 if(m_xNumberFormatTypes.is()) 1910 nFormatKey = ::dbtools::getDefaultNumberFormat(pColumn,m_xNumberFormatTypes,aLocale); 1911 1912 1913 pColumn->setFastPropertyValue_NoBroadcast(PROPERTY_ID_NUMBERFORMAT,makeAny(nFormatKey)); 1914 pColumn->setFastPropertyValue_NoBroadcast(PROPERTY_ID_RELATIVEPOSITION,makeAny(sal_Int32(i+1))); 1915 pColumn->setFastPropertyValue_NoBroadcast(PROPERTY_ID_WIDTH,makeAny(sal_Int32(227))); 1916 pColumn->setFastPropertyValue_NoBroadcast(PROPERTY_ID_ALIGN,makeAny((sal_Int32)0)); 1917 pColumn->setFastPropertyValue_NoBroadcast(PROPERTY_ID_HIDDEN,::cppu::bool2any(sal_False)); 1918 } 1919 catch(Exception&) 1920 { 1921 } 1922 } 1923 } 1924 } 1925 catch (SQLException&) 1926 { 1927 } 1928 } 1929 else 1930 { 1931 // create the rowset columns 1932 Reference< XResultSetMetaData > xMeta( getMetaData(), UNO_QUERY_THROW ); 1933 sal_Int32 nCount = xMeta->getColumnCount(); 1934 m_aDataColumns.reserve(nCount+1); 1935 aColumns->get().reserve(nCount+1); 1936 ::std::set< Reference< XPropertySet > > aAllColumns; 1937 1938 for(sal_Int32 i=1; i <= nCount ;++i) 1939 { 1940 ::rtl::OUString sName = xMeta->getColumnName(i); 1941 ::rtl::OUString sColumnLabel = xMeta->getColumnLabel(i); 1942 1943 // retrieve the column number |i| 1944 Reference<XPropertySet> xColumn; 1945 { 1946 sal_Bool bReFetchName = sal_False; 1947 if (m_xColumns->hasByName(sColumnLabel)) 1948 m_xColumns->getByName(sColumnLabel) >>= xColumn; 1949 if (!xColumn.is() && m_xColumns->hasByName(sName)) 1950 m_xColumns->getByName(sName) >>= xColumn; 1951 1952 // check if column already in the list we need another 1953 if ( aAllColumns.find( xColumn ) != aAllColumns.end() ) 1954 { 1955 xColumn = NULL; 1956 bReFetchName = sal_True; 1957 sColumnLabel = ::rtl::OUString(); 1958 } 1959 if(!xColumn.is()) 1960 { 1961 // no column found so we could look at the position i 1962 //bReFetchName = sal_True; 1963 //sColumnLabel = ::rtl::OUString(); 1964 Reference<XIndexAccess> xIndexAccess(m_xColumns,UNO_QUERY); 1965 if(xIndexAccess.is() && i <= xIndexAccess->getCount()) 1966 { 1967 xIndexAccess->getByIndex(i-1) >>= xColumn; 1968 } 1969 else 1970 { 1971 Sequence< ::rtl::OUString> aSeq = m_xColumns->getElementNames(); 1972 if( i <= aSeq.getLength()) 1973 { 1974 m_xColumns->getByName(aSeq.getConstArray()[i-1]) >>= xColumn; 1975 } 1976 } 1977 } 1978 if(bReFetchName && xColumn.is()) 1979 xColumn->getPropertyValue(PROPERTY_NAME) >>= sName; 1980 aAllColumns.insert( xColumn ); 1981 } 1982 1983 // create a RowSetDataColumn 1984 { 1985 Reference<XPropertySetInfo> xInfo = xColumn.is() ? xColumn->getPropertySetInfo() : Reference<XPropertySetInfo>(); 1986 if(xInfo.is() && xInfo->hasPropertyByName(PROPERTY_DESCRIPTION)) 1987 aDescription = comphelper::getString(xColumn->getPropertyValue(PROPERTY_DESCRIPTION)); 1988 1989 ::rtl::OUString sParseLabel; 1990 if ( xColumn.is() ) 1991 { 1992 xColumn->getPropertyValue(PROPERTY_LABEL) >>= sParseLabel; 1993 } 1994 ORowSetDataColumn* pColumn = new ORowSetDataColumn( getMetaData(), 1995 this, 1996 this, 1997 i, 1998 m_xActiveConnection->getMetaData(), 1999 aDescription, 2000 sParseLabel, 2001 m_aCurrentRow); 2002 aColumns->get().push_back(pColumn); 2003 2004 pColumn->setFastPropertyValue_NoBroadcast(PROPERTY_ID_ISREADONLY,makeAny(rKeyColumns.find(i) != rKeyColumns.end())); 2005 2006 if(!sColumnLabel.getLength()) 2007 { 2008 if(xColumn.is()) 2009 xColumn->getPropertyValue(PROPERTY_NAME) >>= sColumnLabel; 2010 else 2011 sColumnLabel = DBACORE_RESSTRING( RID_STR_EXPRESSION1 ); 2012 } 2013 pColumn->setName(sColumnLabel); 2014 aNames.push_back(sColumnLabel); 2015 m_aDataColumns.push_back(pColumn); 2016 2017 if ( xColumn.is() ) 2018 impl_initializeColumnSettings_nothrow( xColumn, pColumn ); 2019 } 2020 } 2021 } 2022 // now create the columns we need 2023 if(m_pColumns) 2024 m_pColumns->assign(aColumns,aNames); 2025 else 2026 { 2027 Reference<XDatabaseMetaData> xMeta = m_xActiveConnection->getMetaData(); 2028 m_pColumns = new ORowSetDataColumns(xMeta.is() && xMeta->supportsMixedCaseQuotedIdentifiers(), 2029 aColumns,*this,m_aColumnsMutex,aNames); 2030 } 2031 } 2032 checkCache(); 2033 // notify the rowset listeners 2034 notifyAllListeners(_rClearForNotification); 2035 } 2036 // ------------------------------------------------------------------------- 2037 // XRowSetApproveBroadcaster 2038 void SAL_CALL ORowSet::addRowSetApproveListener( const Reference< XRowSetApproveListener >& listener ) throw(RuntimeException) 2039 { 2040 ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed); 2041 2042 ::osl::MutexGuard aGuard( m_aColumnsMutex ); 2043 2044 m_aApproveListeners.addInterface(listener); 2045 } 2046 // ------------------------------------------------------------------------- 2047 void SAL_CALL ORowSet::removeRowSetApproveListener( const Reference< XRowSetApproveListener >& listener ) throw(RuntimeException) 2048 { 2049 ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed); 2050 2051 ::osl::MutexGuard aGuard( m_aColumnsMutex ); 2052 2053 m_aApproveListeners.removeInterface(listener); 2054 } 2055 // XRowsChangeBroadcaster 2056 void SAL_CALL ORowSet::addRowsChangeListener( const Reference< XRowsChangeListener >& listener ) throw(RuntimeException) 2057 { 2058 ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed); 2059 2060 ::osl::MutexGuard aGuard( m_aColumnsMutex ); 2061 2062 m_aRowsChangeListener.addInterface(listener); 2063 } 2064 // ------------------------------------------------------------------------- 2065 void SAL_CALL ORowSet::removeRowsChangeListener( const Reference< XRowsChangeListener >& listener ) throw(RuntimeException) 2066 { 2067 ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed); 2068 2069 ::osl::MutexGuard aGuard( m_aColumnsMutex ); 2070 2071 m_aRowsChangeListener.removeInterface(listener); 2072 } 2073 // ------------------------------------------------------------------------- 2074 2075 // XResultSetAccess 2076 Reference< XResultSet > SAL_CALL ORowSet::createResultSet( ) throw(SQLException, RuntimeException) 2077 { 2078 ::osl::MutexGuard aGuard( m_aColumnsMutex ); 2079 2080 if(m_xStatement.is()) 2081 { 2082 ORowSetClone* pClone = new ORowSetClone( m_aContext, *this, m_pMutex ); 2083 Reference< XResultSet > xRet(pClone); 2084 m_aClones.push_back(WeakReferenceHelper(xRet)); 2085 return xRet; 2086 } 2087 return Reference< XResultSet >(); 2088 } 2089 // ------------------------------------------------------------------------- 2090 2091 // ::com::sun::star::util::XCancellable 2092 void SAL_CALL ORowSet::cancel( ) throw(RuntimeException) 2093 { 2094 ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed); 2095 } 2096 // ------------------------------------------------------------------------- 2097 2098 // ::com::sun::star::sdbcx::XDeleteRows 2099 Sequence< sal_Int32 > SAL_CALL ORowSet::deleteRows( const Sequence< Any >& rows ) throw(SQLException, RuntimeException) 2100 { 2101 ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed); 2102 2103 if(!m_pCache || m_nResultSetConcurrency == ResultSetConcurrency::READ_ONLY) 2104 throwFunctionSequenceException(*this); 2105 2106 ::osl::ResettableMutexGuard aGuard( *m_pMutex ); 2107 2108 Sequence<Any> aChangedBookmarks; 2109 RowsChangeEvent aEvt(*this,RowChangeAction::DELETE,rows.getLength(),aChangedBookmarks); 2110 // notify the rowset listeners 2111 notifyAllListenersRowBeforeChange(aGuard,aEvt); 2112 2113 Sequence< sal_Int32 > aResults( rows.getLength() ); 2114 const Any* row = rows.getConstArray(); 2115 const Any* rowEnd = rows.getConstArray() + rows.getLength(); 2116 sal_Int32* result = aResults.getArray(); 2117 for ( ; row != rowEnd; ++row, ++result ) 2118 { 2119 *result = 0; 2120 if ( !m_pCache->moveToBookmark( *row ) ) 2121 continue; 2122 sal_Int32 nDeletePosition = m_pCache->getRow(); 2123 2124 // first notify the clones so that they can save their position 2125 notifyRowSetAndClonesRowDelete( *row ); 2126 2127 // now delete the row 2128 if ( !m_pCache->deleteRow() ) 2129 continue; 2130 *result = 1; 2131 // now notify that we have deleted 2132 notifyRowSetAndClonesRowDeleted( *row, nDeletePosition ); 2133 } 2134 aEvt.Rows = aResults.getLength(); 2135 2136 // we have to check if we stand on the insert row and if so we have to reset it 2137 ORowSetNotifier aNotifier( this ); 2138 // this will call cancelRowModification on the cache if necessary 2139 // notification order 2140 // - rowChanged 2141 notifyAllListenersRowChanged(aGuard,aEvt); 2142 2143 // - IsModified 2144 // - IsNew 2145 aNotifier.fire(); 2146 2147 // - RowCount/IsRowCountFinal 2148 fireRowcount(); 2149 2150 return aResults; 2151 } 2152 // ----------------------------------------------------------------------------- 2153 void ORowSet::notifyRowSetAndClonesRowDelete( const Any& _rBookmark ) 2154 { 2155 // notify ourself 2156 onDeleteRow( _rBookmark ); 2157 // notify the clones 2158 connectivity::OWeakRefArray::iterator aEnd = m_aClones.end(); 2159 for (connectivity::OWeakRefArray::iterator i = m_aClones.begin(); aEnd != i; i++) 2160 { 2161 Reference< XUnoTunnel > xTunnel(i->get(),UNO_QUERY); 2162 if(xTunnel.is()) 2163 { 2164 ORowSetClone* pClone = reinterpret_cast<ORowSetClone*>(xTunnel->getSomething(ORowSetClone::getUnoTunnelImplementationId())); 2165 if(pClone) 2166 pClone->onDeleteRow( _rBookmark ); 2167 } 2168 } 2169 } 2170 //------------------------------------------------------------------------------ 2171 void ORowSet::notifyRowSetAndClonesRowDeleted( const Any& _rBookmark, sal_Int32 _nPos ) 2172 { 2173 // notify ourself 2174 onDeletedRow( _rBookmark, _nPos ); 2175 // notify the clones 2176 connectivity::OWeakRefArray::iterator aEnd = m_aClones.end(); 2177 for (connectivity::OWeakRefArray::iterator i = m_aClones.begin(); aEnd != i; i++) 2178 { 2179 Reference< XUnoTunnel > xTunnel(i->get(),UNO_QUERY); 2180 if(xTunnel.is()) 2181 { 2182 ORowSetClone* pClone = reinterpret_cast<ORowSetClone*>(xTunnel->getSomething(ORowSetClone::getUnoTunnelImplementationId())); 2183 if(pClone) 2184 pClone->onDeletedRow( _rBookmark, _nPos ); 2185 } 2186 } 2187 } 2188 //------------------------------------------------------------------------------ 2189 Reference< XConnection > ORowSet::calcConnection(const Reference< XInteractionHandler >& _rxHandler) throw( SQLException, RuntimeException ) 2190 { 2191 MutexGuard aGuard(m_aMutex); 2192 if (!m_xActiveConnection.is()) 2193 { 2194 Reference< XConnection > xNewConn; 2195 if ( m_aDataSourceName.getLength() ) 2196 { 2197 Reference< XNameAccess > xDatabaseContext( 2198 m_aContext.createComponent( (::rtl::OUString)SERVICE_SDB_DATABASECONTEXT ), 2199 UNO_QUERY_THROW ); 2200 try 2201 { 2202 Reference< XDataSource > xDataSource( xDatabaseContext->getByName( m_aDataSourceName ), UNO_QUERY_THROW ); 2203 2204 // try connecting with the interaction handler 2205 Reference< XCompletedConnection > xComplConn( xDataSource, UNO_QUERY ); 2206 if ( _rxHandler.is() && xComplConn.is() ) 2207 { 2208 xNewConn = xComplConn->connectWithCompletion( _rxHandler ); 2209 } 2210 else 2211 { 2212 xNewConn = xDataSource->getConnection( m_aUser, m_aPassword ); 2213 } 2214 } 2215 catch ( const SQLException& e ) 2216 { 2217 throw; 2218 } 2219 catch ( const Exception& e ) 2220 { 2221 Any aError = ::cppu::getCaughtException(); 2222 ::rtl::OUString sMessage = ResourceManager::loadString( RID_NO_SUCH_DATA_SOURCE, 2223 "$name$", m_aDataSourceName, "$error$", extractExceptionMessage( m_aContext, aError ) ); 2224 ::dbtools::throwGenericSQLException( sMessage, *this ); 2225 } 2226 } 2227 setActiveConnection(xNewConn); 2228 m_bOwnConnection = sal_True; 2229 } 2230 return m_xActiveConnection; 2231 } 2232 //------------------------------------------------------------------------------ 2233 Reference< XNameAccess > ORowSet::impl_getTables_throw() 2234 { 2235 Reference< XNameAccess > xTables; 2236 2237 Reference< XTablesSupplier > xTablesAccess( m_xActiveConnection, UNO_QUERY ); 2238 if ( xTablesAccess.is() ) 2239 { 2240 xTables.set( xTablesAccess->getTables(), UNO_QUERY_THROW ); 2241 } 2242 else if ( m_pTables ) 2243 { 2244 xTables = m_pTables; 2245 } 2246 else 2247 { 2248 if ( !m_xActiveConnection.is() ) 2249 throw SQLException(DBA_RES(RID_STR_CONNECTION_INVALID),*this,SQLSTATE_GENERAL,1000,Any() ); 2250 2251 sal_Bool bCase = sal_True; 2252 try 2253 { 2254 Reference<XDatabaseMetaData> xMeta = m_xActiveConnection->getMetaData(); 2255 bCase = xMeta.is() && xMeta->supportsMixedCaseQuotedIdentifiers(); 2256 } 2257 catch(SQLException&) 2258 { 2259 DBG_UNHANDLED_EXCEPTION(); 2260 } 2261 2262 m_pTables = new OTableContainer(*this,m_aMutex,m_xActiveConnection,bCase,NULL,NULL,NULL,m_nInAppend); 2263 xTables = m_pTables; 2264 Sequence< ::rtl::OUString> aTableFilter(1); 2265 aTableFilter[0] = ::rtl::OUString::createFromAscii("%"); 2266 m_pTables->construct(aTableFilter,Sequence< ::rtl::OUString>()); 2267 } 2268 2269 return xTables; 2270 } 2271 2272 //------------------------------------------------------------------------------ 2273 void ORowSet::impl_resetTables_nothrow() 2274 { 2275 if ( !m_pTables ) 2276 return; 2277 2278 try 2279 { 2280 m_pTables->dispose(); 2281 } 2282 catch( const Exception& ) 2283 { 2284 DBG_UNHANDLED_EXCEPTION(); 2285 } 2286 2287 DELETEZ( m_pTables ); 2288 } 2289 2290 //------------------------------------------------------------------------------ 2291 sal_Bool ORowSet::impl_initComposer_throw( ::rtl::OUString& _out_rCommandToExecute ) 2292 { 2293 sal_Bool bUseEscapeProcessing = impl_buildActiveCommand_throw( ); 2294 _out_rCommandToExecute = m_aActiveCommand; 2295 if ( !bUseEscapeProcessing ) 2296 return bUseEscapeProcessing; 2297 2298 Reference< XMultiServiceFactory > xFactory( m_xActiveConnection, UNO_QUERY ); 2299 if ( xFactory.is() ) 2300 { 2301 try 2302 { 2303 ::comphelper::disposeComponent( m_xComposer ); 2304 m_xComposer.set( xFactory->createInstance( SERVICE_NAME_SINGLESELECTQUERYCOMPOSER ), UNO_QUERY_THROW ); 2305 } 2306 catch (const Exception& ) { m_xComposer = NULL; } 2307 } 2308 if ( !m_xComposer.is() ) 2309 m_xComposer = new OSingleSelectQueryComposer( impl_getTables_throw(), m_xActiveConnection, m_aContext ); 2310 2311 m_xComposer->setCommand( m_aCommand,m_nCommandType ); 2312 m_aActiveCommand = m_xComposer->getQuery(); 2313 2314 m_xComposer->setFilter( m_bApplyFilter ? m_aFilter : ::rtl::OUString() ); 2315 m_xComposer->setHavingClause( m_bApplyFilter ? m_aHavingClause : ::rtl::OUString() ); 2316 2317 if ( m_bIgnoreResult ) 2318 { // append a "0=1" filter 2319 // don't simply overwrite an existent filter, this would lead to problems if this existent 2320 // filter contains paramters (since a keyset may add parameters itself) 2321 // 2003-12-12 - #23418# - fs@openoffice.org 2322 m_xComposer->setElementaryQuery( m_xComposer->getQuery( ) ); 2323 m_xComposer->setFilter( ::rtl::OUString::createFromAscii( "0 = 1" ) ); 2324 } 2325 2326 m_xComposer->setOrder( m_aOrder ); 2327 m_xComposer->setGroup( m_aGroupBy ); 2328 2329 if ( !m_xColumns.is() ) 2330 { 2331 Reference< XColumnsSupplier > xCols( m_xComposer, UNO_QUERY_THROW ); 2332 m_xColumns = xCols->getColumns(); 2333 } 2334 2335 impl_initParametersContainer_nothrow(); 2336 2337 _out_rCommandToExecute = m_xComposer->getQueryWithSubstitution(); 2338 2339 return bUseEscapeProcessing; 2340 } 2341 2342 //------------------------------------------------------------------------------ 2343 sal_Bool ORowSet::impl_buildActiveCommand_throw() 2344 { 2345 // create the sql command 2346 // from a table name or get the command out of a query (not a view) 2347 // the last use the command as it is 2348 sal_Bool bDoEscapeProcessing = m_bUseEscapeProcessing; 2349 2350 m_aActiveCommand = ::rtl::OUString(); 2351 ::rtl::OUString sCommand; 2352 2353 if ( !m_aCommand.getLength() ) 2354 return bDoEscapeProcessing; 2355 2356 switch (m_nCommandType) 2357 { 2358 case CommandType::TABLE: 2359 { 2360 impl_resetTables_nothrow(); 2361 if ( bDoEscapeProcessing ) 2362 { 2363 Reference< XNameAccess > xTables( impl_getTables_throw() ); 2364 if ( xTables->hasByName(m_aCommand) ) 2365 { 2366 /* 2367 Reference< XPropertySet > xTable; 2368 try 2369 { 2370 xTables->getByName( m_aCommand ) >>= xTable; 2371 } 2372 catch(const WrappedTargetException& e) 2373 { 2374 SQLException e2; 2375 if ( e.TargetException >>= e2 ) 2376 throw e2; 2377 } 2378 catch(Exception&) 2379 { 2380 DBG_UNHANDLED_EXCEPTION(); 2381 } 2382 2383 Reference<XColumnsSupplier> xSup(xTable,UNO_QUERY); 2384 if ( xSup.is() ) 2385 m_xColumns = xSup->getColumns(); 2386 2387 sCommand = rtl::OUString::createFromAscii("SELECT * FROM "); 2388 ::rtl::OUString sCatalog, sSchema, sTable; 2389 ::dbtools::qualifiedNameComponents( m_xActiveConnection->getMetaData(), m_aCommand, sCatalog, sSchema, sTable, ::dbtools::eInDataManipulation ); 2390 sCommand += ::dbtools::composeTableNameForSelect( m_xActiveConnection, sCatalog, sSchema, sTable ); 2391 */ 2392 } 2393 else 2394 { 2395 String sMessage( DBACORE_RESSTRING( RID_STR_TABLE_DOES_NOT_EXIST ) ); 2396 sMessage.SearchAndReplaceAscii( "$table$", m_aCommand ); 2397 throwGenericSQLException(sMessage,*this); 2398 } 2399 } 2400 else 2401 { 2402 sCommand = rtl::OUString::createFromAscii("SELECT * FROM "); 2403 ::rtl::OUString sCatalog, sSchema, sTable; 2404 ::dbtools::qualifiedNameComponents( m_xActiveConnection->getMetaData(), m_aCommand, sCatalog, sSchema, sTable, ::dbtools::eInDataManipulation ); 2405 sCommand += ::dbtools::composeTableNameForSelect( m_xActiveConnection, sCatalog, sSchema, sTable ); 2406 } 2407 } 2408 break; 2409 2410 case CommandType::QUERY: 2411 { 2412 Reference< XQueriesSupplier > xQueriesAccess(m_xActiveConnection, UNO_QUERY); 2413 if (xQueriesAccess.is()) 2414 { 2415 Reference< ::com::sun::star::container::XNameAccess > xQueries(xQueriesAccess->getQueries()); 2416 if (xQueries->hasByName(m_aCommand)) 2417 { 2418 Reference< XPropertySet > xQuery(xQueries->getByName(m_aCommand),UNO_QUERY); 2419 OSL_ENSURE(xQuery.is(),"ORowSet::impl_buildActiveCommand_throw: Query is NULL!"); 2420 if ( xQuery.is() ) 2421 { 2422 xQuery->getPropertyValue(PROPERTY_COMMAND) >>= sCommand; 2423 xQuery->getPropertyValue(PROPERTY_ESCAPE_PROCESSING) >>= bDoEscapeProcessing; 2424 if ( bDoEscapeProcessing != m_bUseEscapeProcessing ) 2425 { 2426 sal_Bool bOldValue = m_bUseEscapeProcessing; 2427 m_bUseEscapeProcessing = bDoEscapeProcessing; 2428 fireProperty(PROPERTY_ID_ESCAPE_PROCESSING,bOldValue,bDoEscapeProcessing); 2429 } 2430 2431 ::rtl::OUString aCatalog,aSchema,aTable; 2432 xQuery->getPropertyValue(PROPERTY_UPDATE_CATALOGNAME) >>= aCatalog; 2433 xQuery->getPropertyValue(PROPERTY_UPDATE_SCHEMANAME) >>= aSchema; 2434 xQuery->getPropertyValue(PROPERTY_UPDATE_TABLENAME) >>= aTable; 2435 if(aTable.getLength()) 2436 m_aUpdateTableName = composeTableName( m_xActiveConnection->getMetaData(), aCatalog, aSchema, aTable, sal_False, ::dbtools::eInDataManipulation ); 2437 /* 2438 Reference<XColumnsSupplier> xSup(xQuery,UNO_QUERY); 2439 if(xSup.is()) 2440 m_xColumns = xSup->getColumns(); 2441 */ 2442 } 2443 } 2444 else 2445 { 2446 String sMessage( DBACORE_RESSTRING( RID_STR_QUERY_DOES_NOT_EXIST ) ); 2447 sMessage.SearchAndReplaceAscii( "$table$", m_aCommand ); 2448 throwGenericSQLException(sMessage,*this); 2449 } 2450 } 2451 else 2452 throw SQLException(DBA_RES(RID_STR_NO_XQUERIESSUPPLIER),*this,::rtl::OUString(),0,Any()); 2453 } 2454 break; 2455 2456 default: 2457 sCommand = m_aCommand; 2458 break; 2459 } 2460 2461 m_aActiveCommand = sCommand; 2462 2463 if ( !m_aActiveCommand.getLength() && !bDoEscapeProcessing ) 2464 ::dbtools::throwSQLException( DBACORE_RESSTRING( RID_STR_NO_SQL_COMMAND ), SQL_FUNCTION_SEQUENCE_ERROR, *this ); 2465 2466 return bDoEscapeProcessing; 2467 } 2468 2469 //------------------------------------------------------------------------------ 2470 void ORowSet::impl_initParametersContainer_nothrow() 2471 { 2472 OSL_PRECOND( !m_pParameters.is(), "ORowSet::impl_initParametersContainer_nothrow: already initialized the parameters!" ); 2473 2474 m_pParameters = new param::ParameterWrapperContainer( m_xComposer.get() ); 2475 // copy the premature parameters into the final ones 2476 size_t nParamCount( ::std::min( m_pParameters->size(), m_aPrematureParamValues.get().size() ) ); 2477 for ( size_t i=0; i<nParamCount; ++i ) 2478 { 2479 (*m_pParameters)[i] = m_aPrematureParamValues.get()[i]; 2480 } 2481 } 2482 2483 //------------------------------------------------------------------------------ 2484 void ORowSet::impl_disposeParametersContainer_nothrow() 2485 { 2486 if ( !m_pParameters.is() ) 2487 return; 2488 2489 // copy the actual values to our "premature" ones, to preserve them for later use 2490 size_t nParamCount( m_pParameters->size() ); 2491 m_aPrematureParamValues.get().resize( nParamCount ); 2492 for ( size_t i=0; i<nParamCount; ++i ) 2493 { 2494 m_aPrematureParamValues.get()[i] = (*m_pParameters)[i]; 2495 } 2496 2497 m_pParameters->dispose(); 2498 m_pParameters = NULL; 2499 } 2500 2501 // ----------------------------------------------------------------------------- 2502 ORowSetValue& ORowSet::getParameterStorage(sal_Int32 parameterIndex) 2503 { 2504 ::connectivity::checkDisposed( ORowSet_BASE1::rBHelper.bDisposed ); 2505 if ( parameterIndex < 1 ) 2506 throwInvalidIndexException( *this ); 2507 2508 if ( m_aParametersSet.size() < (size_t)parameterIndex ) 2509 m_aParametersSet.resize( parameterIndex ,false); 2510 m_aParametersSet[parameterIndex - 1] = true; 2511 2512 if ( m_aParametersSet.size() < (size_t)parameterIndex ) 2513 m_aParametersSet.resize( parameterIndex ,false); 2514 m_aParametersSet[parameterIndex - 1] = true; 2515 2516 if ( m_pParameters.is() ) 2517 { 2518 if ( m_bCommandFacetsDirty ) 2519 // need to rebuild the parameters, since some property which contributes to the 2520 // complete command, and thus the parameters, changed 2521 impl_disposeParametersContainer_nothrow(); 2522 if ( m_pParameters.is() ) 2523 { 2524 if ( (size_t)parameterIndex > m_pParameters->size() ) 2525 throwInvalidIndexException( *this ); 2526 return (*m_pParameters)[ parameterIndex - 1 ]; 2527 } 2528 } 2529 2530 if ( m_aPrematureParamValues.get().size() < (size_t)parameterIndex ) 2531 m_aPrematureParamValues.get().resize( parameterIndex ); 2532 return m_aPrematureParamValues.get()[ parameterIndex - 1 ]; 2533 } 2534 // ------------------------------------------------------------------------- 2535 // XParameters 2536 void SAL_CALL ORowSet::setNull( sal_Int32 parameterIndex, sal_Int32 /*sqlType*/ ) throw(SQLException, RuntimeException) 2537 { 2538 ::osl::MutexGuard aGuard( m_aColumnsMutex ); 2539 2540 getParameterStorage( parameterIndex ).setNull(); 2541 } 2542 // ------------------------------------------------------------------------- 2543 void SAL_CALL ORowSet::setObjectNull( sal_Int32 parameterIndex, sal_Int32 sqlType, const ::rtl::OUString& /*typeName*/ ) throw(SQLException, RuntimeException) 2544 { 2545 setNull( parameterIndex, sqlType ); 2546 } 2547 // ----------------------------------------------------------------------------- 2548 void ORowSet::setParameter(sal_Int32 parameterIndex, const ORowSetValue& x) 2549 { 2550 ::osl::MutexGuard aGuard( m_aColumnsMutex ); 2551 2552 getParameterStorage( parameterIndex ) = x; 2553 } 2554 2555 // ------------------------------------------------------------------------- 2556 void SAL_CALL ORowSet::setBoolean( sal_Int32 parameterIndex, sal_Bool x ) throw(SQLException, RuntimeException) 2557 { 2558 setParameter(parameterIndex,x); 2559 } 2560 // ------------------------------------------------------------------------- 2561 void SAL_CALL ORowSet::setByte( sal_Int32 parameterIndex, sal_Int8 x ) throw(SQLException, RuntimeException) 2562 { 2563 setParameter(parameterIndex,x); 2564 } 2565 // ------------------------------------------------------------------------- 2566 void SAL_CALL ORowSet::setShort( sal_Int32 parameterIndex, sal_Int16 x ) throw(SQLException, RuntimeException) 2567 { 2568 setParameter(parameterIndex,x); 2569 } 2570 // ------------------------------------------------------------------------- 2571 void SAL_CALL ORowSet::setInt( sal_Int32 parameterIndex, sal_Int32 x ) throw(SQLException, RuntimeException) 2572 { 2573 setParameter(parameterIndex,x); 2574 } 2575 // ------------------------------------------------------------------------- 2576 void SAL_CALL ORowSet::setLong( sal_Int32 parameterIndex, sal_Int64 x ) throw(SQLException, RuntimeException) 2577 { 2578 setParameter(parameterIndex,x); 2579 } 2580 // ------------------------------------------------------------------------- 2581 void SAL_CALL ORowSet::setFloat( sal_Int32 parameterIndex, float x ) throw(SQLException, RuntimeException) 2582 { 2583 setParameter(parameterIndex,x); 2584 } 2585 // ------------------------------------------------------------------------- 2586 void SAL_CALL ORowSet::setDouble( sal_Int32 parameterIndex, double x ) throw(SQLException, RuntimeException) 2587 { 2588 setParameter(parameterIndex,x); 2589 } 2590 // ------------------------------------------------------------------------- 2591 void SAL_CALL ORowSet::setString( sal_Int32 parameterIndex, const ::rtl::OUString& x ) throw(SQLException, RuntimeException) 2592 { 2593 setParameter(parameterIndex,x); 2594 } 2595 // ------------------------------------------------------------------------- 2596 void SAL_CALL ORowSet::setBytes( sal_Int32 parameterIndex, const Sequence< sal_Int8 >& x ) throw(SQLException, RuntimeException) 2597 { 2598 setParameter(parameterIndex,x); 2599 } 2600 // ------------------------------------------------------------------------- 2601 void SAL_CALL ORowSet::setDate( sal_Int32 parameterIndex, const ::com::sun::star::util::Date& x ) throw(SQLException, RuntimeException) 2602 { 2603 setParameter(parameterIndex,x); 2604 } 2605 // ------------------------------------------------------------------------- 2606 void SAL_CALL ORowSet::setTime( sal_Int32 parameterIndex, const ::com::sun::star::util::Time& x ) throw(SQLException, RuntimeException) 2607 { 2608 setParameter(parameterIndex,x); 2609 } 2610 // ------------------------------------------------------------------------- 2611 void SAL_CALL ORowSet::setTimestamp( sal_Int32 parameterIndex, const ::com::sun::star::util::DateTime& x ) throw(SQLException, RuntimeException) 2612 { 2613 setParameter(parameterIndex,x); 2614 } 2615 // ------------------------------------------------------------------------- 2616 void SAL_CALL ORowSet::setBinaryStream( sal_Int32 parameterIndex, const Reference< ::com::sun::star::io::XInputStream >& x, sal_Int32 length ) throw(SQLException, RuntimeException) 2617 { 2618 ::osl::MutexGuard aGuard( m_aColumnsMutex ); 2619 ORowSetValue& rParamValue( getParameterStorage( parameterIndex ) ); 2620 2621 try 2622 { 2623 Sequence <sal_Int8> aData; 2624 x->readBytes(aData, length); 2625 rParamValue = aData; 2626 x->closeInput(); 2627 } 2628 catch( Exception& ) 2629 { 2630 throw SQLException(); 2631 } 2632 } 2633 // ------------------------------------------------------------------------- 2634 void SAL_CALL ORowSet::setCharacterStream( sal_Int32 parameterIndex, const Reference< ::com::sun::star::io::XInputStream >& x, sal_Int32 length ) throw(SQLException, RuntimeException) 2635 { 2636 ::osl::MutexGuard aGuard( m_aColumnsMutex ); 2637 ORowSetValue& rParamValue( getParameterStorage( parameterIndex ) ); 2638 try 2639 { 2640 Sequence <sal_Int8> aData; 2641 rtl::OUString aDataStr; 2642 // the data is given as character data and the length defines the character length 2643 sal_Int32 nSize = x->readBytes(aData, length * sizeof(sal_Unicode)); 2644 if (nSize / sizeof(sal_Unicode)) 2645 aDataStr = rtl::OUString((sal_Unicode*)aData.getConstArray(), nSize / sizeof(sal_Unicode)); 2646 rParamValue = aDataStr; 2647 rParamValue.setTypeKind( DataType::LONGVARCHAR ); 2648 x->closeInput(); 2649 } 2650 catch( Exception& ) 2651 { 2652 throw SQLException(); 2653 } 2654 } 2655 // ------------------------------------------------------------------------- 2656 void SAL_CALL ORowSet::setObject( sal_Int32 parameterIndex, const Any& x ) throw(SQLException, RuntimeException) 2657 { 2658 if ( !::dbtools::implSetObject( this, parameterIndex, x ) ) 2659 { // there is no other setXXX call which can handle the value in x 2660 throw SQLException(); 2661 } 2662 } 2663 // ------------------------------------------------------------------------- 2664 void SAL_CALL ORowSet::setObjectWithInfo( sal_Int32 parameterIndex, const Any& x, sal_Int32 targetSqlType, sal_Int32 /*scale*/ ) throw(SQLException, RuntimeException) 2665 { 2666 ::osl::MutexGuard aGuard( m_aColumnsMutex ); 2667 ORowSetValue& rParamValue( getParameterStorage( parameterIndex ) ); 2668 setObject( parameterIndex, x ); 2669 rParamValue.setTypeKind( targetSqlType ); 2670 } 2671 // ------------------------------------------------------------------------- 2672 void SAL_CALL ORowSet::setRef( sal_Int32 /*parameterIndex*/, const Reference< XRef >& /*x*/ ) throw(SQLException, RuntimeException) 2673 { 2674 ::dbtools::throwFeatureNotImplementedException( "XParameters::setRef", *this ); 2675 } 2676 // ------------------------------------------------------------------------- 2677 void SAL_CALL ORowSet::setBlob( sal_Int32 /*parameterIndex*/, const Reference< XBlob >& /*x*/ ) throw(SQLException, RuntimeException) 2678 { 2679 ::dbtools::throwFeatureNotImplementedException( "XParameters::setBlob", *this ); 2680 } 2681 // ------------------------------------------------------------------------- 2682 void SAL_CALL ORowSet::setClob( sal_Int32 /*parameterIndex*/, const Reference< XClob >& /*x*/ ) throw(SQLException, RuntimeException) 2683 { 2684 ::dbtools::throwFeatureNotImplementedException( "XParameters::setClob", *this ); 2685 } 2686 // ------------------------------------------------------------------------- 2687 void SAL_CALL ORowSet::setArray( sal_Int32 /*parameterIndex*/, const Reference< XArray >& /*x*/ ) throw(SQLException, RuntimeException) 2688 { 2689 ::dbtools::throwFeatureNotImplementedException( "XParameters::setArray", *this ); 2690 } 2691 // ------------------------------------------------------------------------- 2692 void SAL_CALL ORowSet::clearParameters( ) throw(SQLException, RuntimeException) 2693 { 2694 ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed); 2695 2696 ::osl::MutexGuard aGuard( m_aColumnsMutex ); 2697 2698 size_t nParamCount( m_pParameters.is() ? m_pParameters->size() : m_aPrematureParamValues.get().size() ); 2699 for ( size_t i=1; i<=nParamCount; ++i ) 2700 getParameterStorage( (sal_Int32)i ).setNull(); 2701 m_aParametersSet.clear(); 2702 } 2703 2704 // ------------------------------------------------------------------------- 2705 Any SAL_CALL ORowSet::getWarnings( ) throw (SQLException, RuntimeException) 2706 { 2707 return m_aWarnings.getWarnings(); 2708 } 2709 2710 // ------------------------------------------------------------------------- 2711 void SAL_CALL ORowSet::clearWarnings( ) throw (SQLException, RuntimeException) 2712 { 2713 m_aWarnings.clearWarnings(); 2714 } 2715 // ----------------------------------------------------------------------------- 2716 void ORowSet::doCancelModification( ) 2717 { 2718 //OSL_ENSURE( isModification(), "ORowSet::doCancelModification: invalid call (no cache!)!" ); 2719 if ( isModification() ) 2720 { 2721 // read-only flag restored 2722 impl_restoreDataColumnsWriteable_throw(); 2723 m_pCache->cancelRowModification(); 2724 } 2725 m_bModified = sal_False; 2726 m_bIsInsertRow = sal_False; 2727 } 2728 2729 // ----------------------------------------------------------------------------- 2730 sal_Bool ORowSet::isModification( ) 2731 { 2732 return isNew(); 2733 } 2734 2735 // ----------------------------------------------------------------------------- 2736 sal_Bool ORowSet::isModified( ) 2737 { 2738 return m_bModified; 2739 } 2740 2741 // ----------------------------------------------------------------------------- 2742 sal_Bool ORowSet::isNew( ) 2743 { 2744 return m_bNew; 2745 } 2746 2747 // ----------------------------------------------------------------------------- 2748 void ORowSet::checkUpdateIterator() 2749 { 2750 if(!m_bIsInsertRow) 2751 { 2752 m_pCache->setUpdateIterator(m_aCurrentRow); 2753 m_aCurrentRow = m_pCache->m_aInsertRow; 2754 m_bIsInsertRow = sal_True; 2755 } 2756 } 2757 // ----------------------------------------------------------------------------- 2758 void ORowSet::checkUpdateConditions(sal_Int32 columnIndex) 2759 { 2760 checkCache(); 2761 if ( m_nResultSetConcurrency == ResultSetConcurrency::READ_ONLY) 2762 ::dbtools::throwSQLException( DBACORE_RESSTRING( RID_STR_RESULT_IS_READONLY ), SQL_GENERAL_ERROR, *this ); 2763 2764 if ( rowDeleted() ) 2765 ::dbtools::throwSQLException( DBACORE_RESSTRING( RID_STR_ROW_ALREADY_DELETED ), SQL_INVALID_CURSOR_POSITION, *this ); 2766 2767 if ( m_aCurrentRow.isNull() ) 2768 ::dbtools::throwSQLException( DBACORE_RESSTRING( RID_STR_INVALID_CURSOR_STATE ), SQL_INVALID_CURSOR_STATE, *this ); 2769 2770 if ( columnIndex <= 0 || sal_Int32((*m_aCurrentRow)->get().size()) <= columnIndex ) 2771 ::dbtools::throwSQLException( DBACORE_RESSTRING( RID_STR_INVALID_INDEX ), SQL_INVALID_DESCRIPTOR_INDEX, *this ); 2772 } 2773 // ----------------------------------------------------------------------------- 2774 void SAL_CALL ORowSet::refreshRow( ) throw(SQLException, RuntimeException) 2775 { 2776 2777 ORowSetNotifier aNotifier( this ); 2778 // this will call cancelRowModification on the cache if necessary 2779 2780 // notification order: 2781 if ( m_bModified && m_pCache ) 2782 implCancelRowUpdates( sal_False ); // do _not_ notify the IsModify - will do this ourself below 2783 2784 // - column values 2785 ORowSetBase::refreshRow(); 2786 2787 // - IsModified 2788 // - IsNew 2789 aNotifier.fire( ); 2790 } 2791 // ----------------------------------------------------------------------------- 2792 void ORowSet::impl_rebuild_throw(::osl::ResettableMutexGuard& _rGuard) 2793 { 2794 Reference< XResultSet > xResultSet( m_xStatement->executeQuery() ); 2795 m_aWarnings.setExternalWarnings( Reference< XWarningsSupplier >( xResultSet, UNO_QUERY ) ); 2796 m_pCache->reset(xResultSet); 2797 notifyAllListeners(_rGuard); 2798 } 2799 // *********************************************************** 2800 // ORowSetClone 2801 // *********************************************************** 2802 DBG_NAME(ORowSetClone); 2803 //-------------------------------------------------------------------------- 2804 ORowSetClone::ORowSetClone( const ::comphelper::ComponentContext& _rContext, ORowSet& rParent, ::osl::Mutex* _pMutex ) 2805 :OSubComponent(m_aMutex, rParent) 2806 ,ORowSetBase( _rContext, OComponentHelper::rBHelper, _pMutex ) 2807 ,m_pParent(&rParent) 2808 ,m_nFetchDirection(rParent.m_nFetchDirection) 2809 ,m_nFetchSize(rParent.m_nFetchSize) 2810 ,m_bIsBookmarable(sal_True) 2811 { 2812 DBG_CTOR(ORowSetClone, NULL); 2813 2814 m_nResultSetType = rParent.m_nResultSetType; 2815 m_nResultSetConcurrency = ResultSetConcurrency::READ_ONLY; 2816 m_pMySelf = this; 2817 m_bClone = sal_True; 2818 m_bBeforeFirst = rParent.m_bBeforeFirst; 2819 m_bAfterLast = rParent.m_bAfterLast; 2820 m_pCache = rParent.m_pCache; 2821 m_aBookmark = rParent.m_aBookmark; 2822 m_aCurrentRow = m_pCache->createIterator(this); 2823 m_xNumberFormatTypes = rParent.m_xNumberFormatTypes; 2824 2825 m_aOldRow = m_pCache->registerOldRow(); 2826 2827 ::vos::ORef< ::connectivity::OSQLColumns> aColumns = new ::connectivity::OSQLColumns(); 2828 ::std::vector< ::rtl::OUString> aNames; 2829 2830 ::rtl::OUString aDescription; 2831 // ConfigManager* pConfigMgr = ConfigManager::GetConfigManager(); 2832 // Locale aLocale; 2833 // pConfigMgr->GetDirectConfigProperty(ConfigManager::LOCALE) >>= aLocale; 2834 Locale aLocale = SvtSysLocale().GetLocaleData().getLocale(); 2835 2836 if ( rParent.m_pColumns ) 2837 { 2838 Sequence< ::rtl::OUString> aSeq = rParent.m_pColumns->getElementNames(); 2839 const ::rtl::OUString* pIter = aSeq.getConstArray(); 2840 const ::rtl::OUString* pEnd = pIter + aSeq.getLength(); 2841 aColumns->get().reserve(aSeq.getLength()+1); 2842 for(sal_Int32 i=1;pIter != pEnd ;++pIter,++i) 2843 { 2844 Reference<XPropertySet> xColumn; 2845 rParent.m_pColumns->getByName(*pIter) >>= xColumn; 2846 if(xColumn->getPropertySetInfo()->hasPropertyByName(PROPERTY_DESCRIPTION)) 2847 aDescription = comphelper::getString(xColumn->getPropertyValue(PROPERTY_DESCRIPTION)); 2848 2849 ::rtl::OUString sParseLabel; 2850 xColumn->getPropertyValue(PROPERTY_LABEL) >>= sParseLabel; 2851 ORowSetColumn* pColumn = new ORowSetColumn( rParent.getMetaData(), 2852 this, 2853 i, 2854 rParent.m_xActiveConnection->getMetaData(), 2855 aDescription, 2856 sParseLabel, 2857 m_aCurrentRow); 2858 aColumns->get().push_back(pColumn); 2859 pColumn->setName(*pIter); 2860 aNames.push_back(*pIter); 2861 m_aDataColumns.push_back(pColumn); 2862 2863 pColumn->setFastPropertyValue_NoBroadcast(PROPERTY_ID_ALIGN,xColumn->getPropertyValue(PROPERTY_ALIGN)); 2864 sal_Int32 nFormatKey = 0; 2865 xColumn->getPropertyValue(PROPERTY_NUMBERFORMAT) >>= nFormatKey; 2866 if(!nFormatKey && xColumn.is() && m_xNumberFormatTypes.is()) 2867 nFormatKey = ::dbtools::getDefaultNumberFormat(xColumn,m_xNumberFormatTypes,aLocale); 2868 pColumn->setFastPropertyValue_NoBroadcast(PROPERTY_ID_NUMBERFORMAT,makeAny(nFormatKey)); 2869 pColumn->setFastPropertyValue_NoBroadcast(PROPERTY_ID_RELATIVEPOSITION,xColumn->getPropertyValue(PROPERTY_RELATIVEPOSITION)); 2870 pColumn->setFastPropertyValue_NoBroadcast(PROPERTY_ID_WIDTH,xColumn->getPropertyValue(PROPERTY_WIDTH)); 2871 pColumn->setFastPropertyValue_NoBroadcast(PROPERTY_ID_HIDDEN,xColumn->getPropertyValue(PROPERTY_HIDDEN)); 2872 pColumn->setFastPropertyValue_NoBroadcast(PROPERTY_ID_CONTROLMODEL,xColumn->getPropertyValue(PROPERTY_CONTROLMODEL)); 2873 pColumn->setFastPropertyValue_NoBroadcast(PROPERTY_ID_HELPTEXT,xColumn->getPropertyValue(PROPERTY_HELPTEXT)); 2874 pColumn->setFastPropertyValue_NoBroadcast(PROPERTY_ID_CONTROLDEFAULT,xColumn->getPropertyValue(PROPERTY_CONTROLDEFAULT)); 2875 2876 } // for(sal_Int32 i=1;pIter != pEnd ;++pIter,++i) 2877 } 2878 Reference<XDatabaseMetaData> xMeta = rParent.m_xActiveConnection->getMetaData(); 2879 m_pColumns = new ORowSetDataColumns(xMeta.is() && xMeta->supportsMixedCaseQuotedIdentifiers(), 2880 aColumns,*this,m_aMutex,aNames); 2881 2882 sal_Int32 nRT = PropertyAttribute::READONLY | PropertyAttribute::TRANSIENT; 2883 2884 // sdb.RowSet Properties 2885 // registerProperty(PROPERTY_CURSORNAME, PROPERTY_ID_CURSORNAME, PropertyAttribute::READONLY, &m_aDataSourceName, ::getCppuType(reinterpret_cast< ::rtl::OUString*>(NULL))); 2886 registerMayBeVoidProperty(PROPERTY_ACTIVE_CONNECTION,PROPERTY_ID_ACTIVE_CONNECTION, PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, &rParent.m_aActiveConnection, ::getCppuType(reinterpret_cast< Reference< XConnection >* >(NULL))); 2887 registerProperty(PROPERTY_RESULTSETCONCURRENCY, PROPERTY_ID_RESULTSETCONCURRENCY, PropertyAttribute::READONLY, &m_nResultSetConcurrency,::getCppuType(reinterpret_cast< sal_Int32*>(NULL))); 2888 registerProperty(PROPERTY_RESULTSETTYPE, PROPERTY_ID_RESULTSETTYPE, PropertyAttribute::READONLY, &m_nResultSetType, ::getCppuType(reinterpret_cast< sal_Int32*>(NULL))); 2889 registerProperty(PROPERTY_FETCHDIRECTION, PROPERTY_ID_FETCHDIRECTION, PropertyAttribute::TRANSIENT, &m_nFetchDirection, ::getCppuType(reinterpret_cast< sal_Int32*>(NULL))); 2890 registerProperty(PROPERTY_FETCHSIZE, PROPERTY_ID_FETCHSIZE, PropertyAttribute::TRANSIENT, &m_nFetchSize, ::getCppuType(reinterpret_cast< sal_Int32*>(NULL))); 2891 registerProperty(PROPERTY_ISBOOKMARKABLE, PROPERTY_ID_ISBOOKMARKABLE, nRT, &m_bIsBookmarable, ::getBooleanCppuType()); 2892 } 2893 2894 //-------------------------------------------------------------------------- 2895 ORowSetClone::~ORowSetClone() 2896 { 2897 DBG_DTOR(ORowSetClone, NULL); 2898 } 2899 // com::sun::star::XTypeProvider 2900 //-------------------------------------------------------------------------- 2901 Sequence< Type > ORowSetClone::getTypes() throw (RuntimeException) 2902 { 2903 return ::comphelper::concatSequences(OSubComponent::getTypes(),ORowSetBase::getTypes()); 2904 } 2905 // com::sun::star::XInterface 2906 //-------------------------------------------------------------------------- 2907 Any ORowSetClone::queryInterface( const Type & rType ) throw (RuntimeException) 2908 { 2909 Any aRet = ORowSetBase::queryInterface(rType); 2910 if(!aRet.hasValue()) 2911 aRet = OSubComponent::queryInterface(rType); 2912 return aRet; 2913 } 2914 //------------------------------------------------------------------------------ 2915 void ORowSetClone::acquire() throw() 2916 { 2917 OSubComponent::acquire(); 2918 } 2919 2920 //------------------------------------------------------------------------------ 2921 void ORowSetClone::release() throw() 2922 { 2923 OSubComponent::release(); 2924 } 2925 2926 // XServiceInfo 2927 //------------------------------------------------------------------------------ 2928 rtl::OUString ORowSetClone::getImplementationName( ) throw(RuntimeException) 2929 { 2930 return rtl::OUString::createFromAscii("com.sun.star.sdb.ORowSetClone"); 2931 } 2932 2933 //------------------------------------------------------------------------------ 2934 sal_Bool ORowSetClone::supportsService( const ::rtl::OUString& _rServiceName ) throw (RuntimeException) 2935 { 2936 return ::comphelper::findValue(getSupportedServiceNames(), _rServiceName, sal_True).getLength() != 0; 2937 } 2938 2939 //------------------------------------------------------------------------------ 2940 Sequence< ::rtl::OUString > ORowSetClone::getSupportedServiceNames( ) throw (RuntimeException) 2941 { 2942 Sequence< ::rtl::OUString > aSNS( 2 ); 2943 aSNS[0] = SERVICE_SDBC_RESULTSET; 2944 aSNS[1] = SERVICE_SDB_RESULTSET; 2945 return aSNS; 2946 } 2947 2948 // OComponentHelper 2949 //------------------------------------------------------------------------------ 2950 void ORowSetClone::disposing() 2951 { 2952 MutexGuard aGuard( m_aMutex ); 2953 ORowSetBase::disposing(); 2954 2955 m_pParent = NULL; 2956 m_pMutex = &m_aMutex; // this must be done here because someone could hold a ref to us and try to do something 2957 OSubComponent::disposing(); 2958 } 2959 2960 // XCloseable 2961 //------------------------------------------------------------------------------ 2962 void ORowSetClone::close(void) throw( SQLException, RuntimeException ) 2963 { 2964 { 2965 MutexGuard aGuard( m_aMutex ); 2966 if (OComponentHelper::rBHelper.bDisposed) 2967 throw DisposedException(); 2968 } 2969 dispose(); 2970 } 2971 // ------------------------------------------------------------------------- 2972 2973 // comphelper::OPropertyArrayUsageHelper 2974 ::cppu::IPropertyArrayHelper* ORowSetClone::createArrayHelper( ) const 2975 { 2976 Sequence< Property > aProps; 2977 describeProperties(aProps); 2978 return new ::cppu::OPropertyArrayHelper(aProps); 2979 } 2980 // ------------------------------------------------------------------------- 2981 2982 // cppu::OPropertySetHelper 2983 ::cppu::IPropertyArrayHelper& SAL_CALL ORowSetClone::getInfoHelper() 2984 { 2985 typedef ::comphelper::OPropertyArrayUsageHelper<ORowSetClone> ORowSetClone_PROP; 2986 return *ORowSetClone_PROP::getArrayHelper(); 2987 } 2988 // ------------------------------------------------------------------------- 2989 //-------------------------------------------------------------------------- 2990 Sequence< sal_Int8 > ORowSetClone::getUnoTunnelImplementationId() 2991 { 2992 static ::cppu::OImplementationId * pId = 0; 2993 if (! pId) 2994 { 2995 ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); 2996 if (! pId) 2997 { 2998 static ::cppu::OImplementationId aId; 2999 pId = &aId; 3000 } 3001 } 3002 return pId->getImplementationId(); 3003 } 3004 // ----------------------------------------------------------------------------- 3005 // com::sun::star::XUnoTunnel 3006 sal_Int64 SAL_CALL ORowSetClone::getSomething( const Sequence< sal_Int8 >& rId ) throw(RuntimeException) 3007 { 3008 if (rId.getLength() == 16 && 0 == rtl_compareMemory(getUnoTunnelImplementationId().getConstArray(), rId.getConstArray(), 16 ) ) 3009 return reinterpret_cast<sal_Int64>(this); 3010 3011 return 0; 3012 } 3013 // ----------------------------------------------------------------------------- 3014 void SAL_CALL ORowSetClone::setFastPropertyValue_NoBroadcast(sal_Int32 nHandle,const Any& rValue) throw (Exception) 3015 { 3016 if ( nHandle == PROPERTY_ID_FETCHSIZE ) 3017 { 3018 if ( m_pParent ) 3019 m_pParent->setFastPropertyValue_NoBroadcast( nHandle, rValue ); 3020 } 3021 3022 OPropertyStateContainer::setFastPropertyValue_NoBroadcast(nHandle,rValue); 3023 } 3024 3025 // ----------------------------------------------------------------------------- 3026 void ORowSetClone::doCancelModification( ) 3027 { 3028 //OSL_ENSURE( sal_False, "ORowSetClone::doCancelModification: invalid call!" ); 3029 } 3030 3031 // ----------------------------------------------------------------------------- 3032 sal_Bool ORowSetClone::isModification( ) 3033 { 3034 return sal_False; 3035 } 3036 3037 // ----------------------------------------------------------------------------- 3038 sal_Bool ORowSetClone::isModified( ) 3039 { 3040 return sal_False; 3041 } 3042 3043 // ----------------------------------------------------------------------------- 3044 sal_Bool ORowSetClone::isNew( ) 3045 { 3046 return sal_False; 3047 } 3048 3049 // ------------------------------------------------------------------------- 3050 void SAL_CALL ORowSetClone::execute( ) throw(SQLException, RuntimeException) 3051 { 3052 throwFunctionNotSupportedException( "RowSetClone::XRowSet::execute", *this ); 3053 } 3054 3055 // ------------------------------------------------------------------------- 3056 void SAL_CALL ORowSetClone::addRowSetListener( const Reference< XRowSetListener >& ) throw(RuntimeException) 3057 { 3058 throwFunctionNotSupportedException( "RowSetClone::XRowSet", *this ); 3059 } 3060 3061 // ------------------------------------------------------------------------- 3062 void SAL_CALL ORowSetClone::removeRowSetListener( const Reference< XRowSetListener >& ) throw(RuntimeException) 3063 { 3064 throwFunctionNotSupportedException( "RowSetClone::XRowSet", *this ); 3065 } 3066 3067 } // dbaccess 3068