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