Bump version to 5.0-14
[LibreOffice.git] / dbaccess / source / core / api / RowSet.cxx
blobdcbacf4770efc03c1b3a4230531b26f061ddccb0
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "sal/config.h"
22 #include <map>
23 #include <utility>
24 #include <boost/bind.hpp>
26 #include <string.h>
27 #include "RowSet.hxx"
28 #include "dbastrings.hrc"
29 #include "sdbcoretools.hxx"
30 #include "services.hxx"
31 #include "SingleSelectQueryComposer.hxx"
32 #include "module_dba.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"
40 #include <com/sun/star/beans/PropertyAttribute.hpp>
41 #include <com/sun/star/container/XChild.hpp>
42 #include <com/sun/star/lang/DisposedException.hpp>
43 #include <com/sun/star/sdb/CommandType.hpp>
44 #include <com/sun/star/sdb/DatabaseContext.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>
61 #include <comphelper/processfactory.hxx>
62 #include <comphelper/interaction.hxx>
63 #include <comphelper/property.hxx>
64 #include <comphelper/seqstream.hxx>
65 #include <comphelper/sequence.hxx>
66 #include <comphelper/types.hxx>
67 #include <comphelper/uno3.hxx>
68 #include <connectivity/BlobHelper.hxx>
69 #include <connectivity/dbconversion.hxx>
70 #include <connectivity/dbexception.hxx>
71 #include <connectivity/dbtools.hxx>
72 #include <cppuhelper/exc_hlp.hxx>
73 #include <cppuhelper/interfacecontainer.h>
74 #include <cppuhelper/supportsservice.hxx>
75 #include <cppuhelper/typeprovider.hxx>
76 #include <unotools/syslocale.hxx>
77 #include <tools/debug.hxx>
78 #include <tools/diagnose_ex.h>
79 #include <unotools/configmgr.hxx>
81 using namespace utl;
82 using namespace dbaccess;
83 using namespace connectivity;
84 using namespace comphelper;
85 using namespace dbtools;
86 using namespace ::com::sun::star;
87 using namespace ::com::sun::star::uno;
88 using namespace ::com::sun::star::beans;
89 using namespace ::com::sun::star::sdbc;
90 using namespace ::com::sun::star::sdb;
91 using namespace ::com::sun::star::sdbcx;
92 using namespace ::com::sun::star::container;
93 using namespace ::com::sun::star::lang;
94 using namespace ::com::sun::star::task;
95 using namespace ::com::sun::star::util;
96 using namespace ::cppu;
97 using namespace ::osl;
99 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* SAL_CALL
100 com_sun_star_comp_dba_ORowSet_get_implementation(css::uno::XComponentContext* context,
101 css::uno::Sequence<css::uno::Any> const &)
103 return cppu::acquire(new ORowSet(context));
106 #define NOTIFY_LISTERNERS_CHECK(_rListeners,T,method) \
107 Sequence< Reference< XInterface > > aListenerSeq = _rListeners.getElements(); \
109 const Reference< XInterface >* pxIntBegin = aListenerSeq.getConstArray(); \
110 const Reference< XInterface >* pxInt = pxIntBegin + aListenerSeq.getLength(); \
112 _rGuard.clear(); \
113 bool bCheck = true; \
114 while( pxInt > pxIntBegin && bCheck ) \
116 try \
118 while( pxInt > pxIntBegin && bCheck ) \
120 --pxInt; \
121 bCheck = static_cast< T* >( pxInt->get() )->method(aEvt); \
124 catch( RuntimeException& ) \
128 _rGuard.reset();
131 namespace dbaccess
133 ORowSet::ORowSet( const Reference< ::com::sun::star::uno::XComponentContext >& _rxContext )
134 :ORowSet_BASE1(m_aMutex)
135 ,ORowSetBase( _rxContext, ORowSet_BASE1::rBHelper, &m_aMutex )
136 ,m_pParameters( NULL )
137 ,m_aRowsetListeners(*m_pMutex)
138 ,m_aApproveListeners(*m_pMutex)
139 ,m_aRowsChangeListener(*m_pMutex)
140 ,m_pTables(NULL)
141 ,m_nFetchDirection(FetchDirection::FORWARD)
142 ,m_nFetchSize(50)
143 ,m_nMaxFieldSize(0)
144 ,m_nMaxRows(0)
145 ,m_nQueryTimeOut(0)
146 ,m_nCommandType(CommandType::COMMAND)
147 ,m_nTransactionIsolation(0)
148 ,m_nPrivileges(0)
149 ,m_nLastKnownRowCount(0)
150 ,m_nInAppend(0)
151 ,m_bLastKnownRowCountFinal(false)
152 ,m_bUseEscapeProcessing(true)
153 ,m_bApplyFilter(false)
154 ,m_bCommandFacetsDirty( true )
155 ,m_bParametersDirty( true )
156 ,m_bModified(false)
157 ,m_bRebuildConnOnExecute(false)
158 ,m_bIsBookmarkable(true)
159 ,m_bNew(false)
160 ,m_bCanUpdateInsertedRows(true)
161 ,m_bOwnConnection(false)
162 ,m_bPropChangeNotifyEnabled(true)
164 m_nResultSetType = ResultSetType::SCROLL_SENSITIVE;
165 m_nResultSetConcurrency = ResultSetConcurrency::UPDATABLE;
166 m_pMySelf = this;
167 m_aActiveConnection <<= m_xActiveConnection;
169 sal_Int32 nRBT = PropertyAttribute::READONLY | PropertyAttribute::BOUND | PropertyAttribute::TRANSIENT;
170 sal_Int32 nRT = PropertyAttribute::READONLY | PropertyAttribute::TRANSIENT;
171 sal_Int32 nBT = PropertyAttribute::BOUND | PropertyAttribute::TRANSIENT;
173 m_aPrematureParamValues.get().resize( 0 );
175 // sdb.RowSet Properties
176 registerMayBeVoidProperty(PROPERTY_ACTIVE_CONNECTION,PROPERTY_ID_ACTIVE_CONNECTION, PropertyAttribute::MAYBEVOID|PropertyAttribute::TRANSIENT|PropertyAttribute::BOUND, &m_aActiveConnection, cppu::UnoType<XConnection>::get());
177 registerProperty(PROPERTY_DATASOURCENAME, PROPERTY_ID_DATASOURCENAME, PropertyAttribute::BOUND, &m_aDataSourceName, ::cppu::UnoType<OUString>::get());
178 registerProperty(PROPERTY_COMMAND, PROPERTY_ID_COMMAND, PropertyAttribute::BOUND, &m_aCommand, ::cppu::UnoType<OUString>::get());
179 registerProperty(PROPERTY_COMMAND_TYPE, PROPERTY_ID_COMMAND_TYPE, PropertyAttribute::BOUND, &m_nCommandType, ::cppu::UnoType<sal_Int32>::get());
180 registerProperty(PROPERTY_ACTIVECOMMAND, PROPERTY_ID_ACTIVECOMMAND, nRBT, &m_aActiveCommand, ::cppu::UnoType<OUString>::get());
181 registerProperty(PROPERTY_IGNORERESULT, PROPERTY_ID_IGNORERESULT, PropertyAttribute::BOUND, &m_bIgnoreResult, cppu::UnoType<bool>::get());
182 registerProperty(PROPERTY_FILTER, PROPERTY_ID_FILTER, PropertyAttribute::BOUND, &m_aFilter, ::cppu::UnoType<OUString>::get());
183 registerProperty(PROPERTY_HAVING_CLAUSE, PROPERTY_ID_HAVING_CLAUSE, PropertyAttribute::BOUND, &m_aHavingClause, ::cppu::UnoType<OUString>::get());
184 registerProperty(PROPERTY_GROUP_BY, PROPERTY_ID_GROUP_BY, PropertyAttribute::BOUND, &m_aGroupBy, ::cppu::UnoType<OUString>::get());
185 registerProperty(PROPERTY_APPLYFILTER, PROPERTY_ID_APPLYFILTER, PropertyAttribute::BOUND, &m_bApplyFilter, cppu::UnoType<bool>::get());
186 registerProperty(PROPERTY_ORDER, PROPERTY_ID_ORDER, PropertyAttribute::BOUND, &m_aOrder, ::cppu::UnoType<OUString>::get());
187 registerProperty(PROPERTY_PRIVILEGES, PROPERTY_ID_PRIVILEGES, nRT, &m_nPrivileges, ::cppu::UnoType<sal_Int32>::get());
188 registerProperty(PROPERTY_ISMODIFIED, PROPERTY_ID_ISMODIFIED, nBT, &m_bModified, cppu::UnoType<bool>::get());
189 registerProperty(PROPERTY_ISNEW, PROPERTY_ID_ISNEW, nRBT, &m_bNew, cppu::UnoType<bool>::get());
190 registerProperty(PROPERTY_SINGLESELECTQUERYCOMPOSER,PROPERTY_ID_SINGLESELECTQUERYCOMPOSER, nRT, &m_xComposer, cppu::UnoType<XSingleSelectQueryComposer>::get());
192 // sdbcx.ResultSet Properties
193 registerProperty(PROPERTY_ISBOOKMARKABLE, PROPERTY_ID_ISBOOKMARKABLE, nRT, &m_bIsBookmarkable, cppu::UnoType<bool>::get());
194 registerProperty(PROPERTY_CANUPDATEINSERTEDROWS,PROPERTY_ID_CANUPDATEINSERTEDROWS, nRT, &m_bCanUpdateInsertedRows, cppu::UnoType<bool>::get());
195 // sdbc.ResultSet Properties
196 registerProperty(PROPERTY_RESULTSETCONCURRENCY, PROPERTY_ID_RESULTSETCONCURRENCY, PropertyAttribute::TRANSIENT, &m_nResultSetConcurrency,::cppu::UnoType<sal_Int32>::get());
197 registerProperty(PROPERTY_RESULTSETTYPE, PROPERTY_ID_RESULTSETTYPE, PropertyAttribute::TRANSIENT, &m_nResultSetType, ::cppu::UnoType<sal_Int32>::get());
198 registerProperty(PROPERTY_FETCHDIRECTION, PROPERTY_ID_FETCHDIRECTION, PropertyAttribute::TRANSIENT, &m_nFetchDirection, ::cppu::UnoType<sal_Int32>::get());
199 registerProperty(PROPERTY_FETCHSIZE, PROPERTY_ID_FETCHSIZE, PropertyAttribute::TRANSIENT, &m_nFetchSize, ::cppu::UnoType<sal_Int32>::get());
201 // sdbc.RowSet Properties
202 registerProperty(PROPERTY_URL, PROPERTY_ID_URL, 0, &m_aURL, ::cppu::UnoType<OUString>::get());
203 registerProperty(PROPERTY_TRANSACTIONISOLATION, PROPERTY_ID_TRANSACTIONISOLATION, PropertyAttribute::TRANSIENT, &m_nTransactionIsolation,::cppu::UnoType<sal_Int32>::get());
204 registerMayBeVoidProperty(PROPERTY_TYPEMAP, PROPERTY_ID_TYPEMAP, PropertyAttribute::MAYBEVOID|PropertyAttribute::TRANSIENT, &m_aTypeMap, cppu::UnoType<XNameAccess>::get());
205 registerProperty(PROPERTY_ESCAPE_PROCESSING,PROPERTY_ID_ESCAPE_PROCESSING, PropertyAttribute::BOUND, &m_bUseEscapeProcessing,cppu::UnoType<bool>::get() );
206 registerProperty(PROPERTY_QUERYTIMEOUT, PROPERTY_ID_QUERYTIMEOUT, PropertyAttribute::TRANSIENT, &m_nQueryTimeOut, ::cppu::UnoType<sal_Int32>::get());
207 registerProperty(PROPERTY_MAXFIELDSIZE, PROPERTY_ID_MAXFIELDSIZE, PropertyAttribute::TRANSIENT, &m_nMaxFieldSize, ::cppu::UnoType<sal_Int32>::get());
208 registerProperty(PROPERTY_MAXROWS, PROPERTY_ID_MAXROWS, 0, &m_nMaxRows, ::cppu::UnoType<sal_Int32>::get() );
209 registerProperty(PROPERTY_USER, PROPERTY_ID_USER, PropertyAttribute::TRANSIENT, &m_aUser, ::cppu::UnoType<OUString>::get());
210 registerProperty(PROPERTY_PASSWORD, PROPERTY_ID_PASSWORD, PropertyAttribute::TRANSIENT, &m_aPassword, ::cppu::UnoType<OUString>::get());
212 registerProperty(PROPERTY_UPDATE_CATALOGNAME, PROPERTY_ID_UPDATE_CATALOGNAME, PropertyAttribute::BOUND, &m_aUpdateCatalogName, ::cppu::UnoType<OUString>::get());
213 registerProperty(PROPERTY_UPDATE_SCHEMANAME, PROPERTY_ID_UPDATE_SCHEMANAME, PropertyAttribute::BOUND, &m_aUpdateSchemaName, ::cppu::UnoType<OUString>::get());
214 registerProperty(PROPERTY_UPDATE_TABLENAME, PROPERTY_ID_UPDATE_TABLENAME, PropertyAttribute::BOUND, &m_aUpdateTableName, ::cppu::UnoType<OUString>::get());
216 // ???
217 registerProperty(PROPERTY_CHANGE_NOTIFICATION_ENABLED, PROPERTY_ID_PROPCHANGE_NOTIFY, PropertyAttribute::BOUND, &m_bPropChangeNotifyEnabled, cppu::UnoType<bool>::get());
220 ORowSet::~ORowSet()
222 if ( !m_rBHelper.bDisposed && !m_rBHelper.bInDispose )
224 SAL_WARN("dbaccess", "Please check who doesn't dispose this component!");
225 osl_atomic_increment( &m_refCount );
226 dispose();
230 void ORowSet::getPropertyDefaultByHandle( sal_Int32 _nHandle, Any& _rDefault ) const
232 switch( _nHandle )
234 case PROPERTY_ID_COMMAND_TYPE:
235 _rDefault <<= static_cast<sal_Int32>(CommandType::COMMAND);
236 break;
237 case PROPERTY_ID_IGNORERESULT:
238 _rDefault <<= sal_False;
239 break;
240 case PROPERTY_ID_APPLYFILTER:
241 _rDefault <<= sal_False;
242 break;
243 case PROPERTY_ID_ISMODIFIED:
244 _rDefault <<= sal_False;
245 break;
246 case PROPERTY_ID_ISBOOKMARKABLE:
247 _rDefault <<= sal_True;
248 break;
249 case PROPERTY_ID_CANUPDATEINSERTEDROWS:
250 _rDefault <<= sal_True;
251 break;
252 case PROPERTY_ID_RESULTSETTYPE:
253 _rDefault <<= ResultSetType::SCROLL_INSENSITIVE;
254 break;
255 case PROPERTY_ID_RESULTSETCONCURRENCY:
256 _rDefault <<= ResultSetConcurrency::UPDATABLE;
257 break;
258 case PROPERTY_ID_FETCHDIRECTION:
259 _rDefault <<= FetchDirection::FORWARD;
260 break;
261 case PROPERTY_ID_FETCHSIZE:
262 _rDefault <<= static_cast<sal_Int32>(1);
263 break;
264 case PROPERTY_ID_ESCAPE_PROCESSING:
265 _rDefault <<= sal_True;
266 break;
267 case PROPERTY_ID_MAXROWS:
268 _rDefault <<= sal_Int32( 0 );
269 break;
270 case PROPERTY_ID_FILTER:
271 case PROPERTY_ID_HAVING_CLAUSE:
272 case PROPERTY_ID_GROUP_BY:
273 case PROPERTY_ID_ORDER:
274 case PROPERTY_ID_UPDATE_CATALOGNAME:
275 case PROPERTY_ID_UPDATE_SCHEMANAME:
276 case PROPERTY_ID_UPDATE_TABLENAME:
277 _rDefault <<= OUString();
278 break;
282 // typedef ::comphelper::OPropertyArrayUsageHelper<ORowSet> ORowSet_Prop;
283 void SAL_CALL ORowSet::setFastPropertyValue_NoBroadcast(sal_Int32 nHandle,const Any& rValue) throw (Exception, std::exception)
285 switch(nHandle)
287 case PROPERTY_ID_ISMODIFIED:
288 m_bModified = cppu::any2bool(rValue);
289 break;
290 case PROPERTY_ID_FETCHDIRECTION:
291 if( m_nResultSetType == ResultSetType::FORWARD_ONLY)
292 throw Exception(); // else run through
293 default:
294 OPropertyStateContainer::setFastPropertyValue_NoBroadcast(nHandle,rValue);
297 if ( ( nHandle == PROPERTY_ID_ACTIVE_CONNECTION )
298 || ( nHandle == PROPERTY_ID_DATASOURCENAME )
299 || ( nHandle == PROPERTY_ID_COMMAND )
300 || ( nHandle == PROPERTY_ID_COMMAND_TYPE )
301 || ( nHandle == PROPERTY_ID_IGNORERESULT )
302 || ( nHandle == PROPERTY_ID_FILTER )
303 || ( nHandle == PROPERTY_ID_HAVING_CLAUSE )
304 || ( nHandle == PROPERTY_ID_GROUP_BY )
305 || ( nHandle == PROPERTY_ID_APPLYFILTER )
306 || ( nHandle == PROPERTY_ID_ORDER )
307 || ( nHandle == PROPERTY_ID_URL )
308 || ( nHandle == PROPERTY_ID_USER )
311 m_bCommandFacetsDirty = true;
315 switch(nHandle)
317 case PROPERTY_ID_ACTIVE_CONNECTION:
318 // the new connection
320 assert(m_aActiveConnection == rValue);
321 Reference< XConnection > xNewConnection(m_aActiveConnection,UNO_QUERY);
322 setActiveConnection(xNewConnection, false);
325 m_bOwnConnection = false;
326 m_bRebuildConnOnExecute = false;
327 break;
329 case PROPERTY_ID_DATASOURCENAME:
330 if(!m_xStatement.is())
332 Reference< XConnection > xNewConn;
333 Any aNewConn;
334 aNewConn <<= xNewConn;
335 setFastPropertyValue(PROPERTY_ID_ACTIVE_CONNECTION, aNewConn);
337 else
338 m_bRebuildConnOnExecute = true;
339 break;
340 case PROPERTY_ID_FETCHSIZE:
341 if(m_pCache)
343 m_pCache->setFetchSize(m_nFetchSize);
344 fireRowcount();
346 break;
347 case PROPERTY_ID_URL:
348 // is the connection-to-be-built determined by the url (which is the case if m_aDataSourceName is empty) ?
349 if (m_aDataSourceName.isEmpty())
351 // are we active at the moment ?
352 if (m_xStatement.is())
353 // yes -> the next execute needs to rebuild our connection because of this new property
354 m_bRebuildConnOnExecute = true;
355 else
356 { // no -> drop our active connection (if we have one) as it doesn't correspond to this new property value anymore
357 Reference< XConnection > xNewConn;
358 Any aNewConn;
359 aNewConn <<= xNewConn;
360 setFastPropertyValue(PROPERTY_ID_ACTIVE_CONNECTION, aNewConn);
363 m_bOwnConnection = true;
364 break;
365 case PROPERTY_ID_TYPEMAP:
366 m_xTypeMap.set(m_aTypeMap, css::uno::UNO_QUERY);
367 break;
368 case PROPERTY_ID_PROPCHANGE_NOTIFY:
369 m_bPropChangeNotifyEnabled = ::cppu::any2bool(rValue);
370 break;
371 default:
372 break;
376 void SAL_CALL ORowSet::getFastPropertyValue(Any& rValue,sal_Int32 nHandle) const
378 if(m_pCache)
380 switch(nHandle)
382 case PROPERTY_ID_ISMODIFIED:
383 rValue.setValue(&m_bModified,cppu::UnoType<bool>::get());
384 break;
385 case PROPERTY_ID_ISNEW:
386 rValue.setValue(&m_bNew,cppu::UnoType<bool>::get());
387 break;
388 case PROPERTY_ID_PRIVILEGES:
389 rValue <<= m_pCache->m_nPrivileges;
390 break;
391 case PROPERTY_ID_ACTIVE_CONNECTION:
392 rValue <<= m_xActiveConnection;
393 break;
394 case PROPERTY_ID_TYPEMAP:
395 rValue <<= m_xTypeMap;
396 break;
397 default:
398 ORowSetBase::getFastPropertyValue(rValue,nHandle);
401 else
403 switch(nHandle)
405 case PROPERTY_ID_ACTIVE_CONNECTION:
406 rValue <<= m_xActiveConnection;
407 break;
408 case PROPERTY_ID_TYPEMAP:
409 rValue <<= m_xTypeMap;
410 break;
411 case PROPERTY_ID_PROPCHANGE_NOTIFY:
412 rValue <<= m_bPropChangeNotifyEnabled;
413 break;
414 default:
415 ORowSetBase::getFastPropertyValue(rValue,nHandle);
420 // com::sun::star::XTypeProvider
421 Sequence< Type > SAL_CALL ORowSet::getTypes() throw (RuntimeException, std::exception)
423 OTypeCollection aTypes(cppu::UnoType<XPropertySet>::get(),
424 cppu::UnoType<XFastPropertySet>::get(),
425 cppu::UnoType<XMultiPropertySet>::get(),
426 ::comphelper::concatSequences(ORowSet_BASE1::getTypes(),ORowSetBase::getTypes()));
427 return aTypes.getTypes();
430 Sequence< sal_Int8 > SAL_CALL ORowSet::getImplementationId() throw (RuntimeException, std::exception)
432 return css::uno::Sequence<sal_Int8>();
435 // com::sun::star::XInterface
436 Any SAL_CALL ORowSet::queryInterface( const Type & rType ) throw (RuntimeException, std::exception)
438 return ORowSet_BASE1::queryInterface( rType);
441 void SAL_CALL ORowSet::acquire() throw()
443 ORowSet_BASE1::acquire();
446 void SAL_CALL ORowSet::release() throw()
448 ORowSet_BASE1::release();
451 // com::sun::star::XUnoTunnel
452 sal_Int64 SAL_CALL ORowSet::getSomething( const Sequence< sal_Int8 >& rId ) throw(RuntimeException, std::exception)
454 if (rId.getLength() == 16 && 0 == memcmp(getUnoTunnelImplementationId().getConstArray(), rId.getConstArray(), 16 ) )
455 return reinterpret_cast<sal_Int64>(this);
457 return 0;
460 Sequence< sal_Int8 > ORowSet::getUnoTunnelImplementationId()
462 static ::cppu::OImplementationId * pId = 0;
463 if (! pId)
465 ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
466 if (! pId)
468 static ::cppu::OImplementationId aId;
469 pId = &aId;
472 return pId->getImplementationId();
475 // com::sun::star::XAggregation
476 Any SAL_CALL ORowSet::queryAggregation( const Type& rType ) throw(RuntimeException, std::exception)
478 Any aRet(ORowSetBase::queryInterface(rType));
479 if (!aRet.hasValue())
480 aRet = ORowSet_BASE1::queryAggregation(rType);
481 return aRet;
484 OUString ORowSet::getImplementationName_static( ) throw(RuntimeException)
486 return OUString("com.sun.star.comp.dba.ORowSet");
489 // ::com::sun::star::XServiceInfo
490 OUString SAL_CALL ORowSet::getImplementationName( ) throw(RuntimeException, std::exception)
492 return getImplementationName_static();
495 sal_Bool SAL_CALL ORowSet::supportsService( const OUString& _rServiceName ) throw(RuntimeException, std::exception)
497 return cppu::supportsService(this, _rServiceName);
500 Sequence< OUString > ORowSet::getSupportedServiceNames_static( ) throw (RuntimeException)
502 Sequence< OUString > aSNS( 5 );
503 aSNS[0] = SERVICE_SDBC_RESULTSET;
504 aSNS[1] = SERVICE_SDBC_ROWSET;
505 aSNS[2] = SERVICE_SDBCX_RESULTSET;
506 aSNS[3] = SERVICE_SDB_RESULTSET;
507 aSNS[4] = SERVICE_SDB_ROWSET;
508 return aSNS;
511 Sequence< OUString > SAL_CALL ORowSet::getSupportedServiceNames( ) throw(RuntimeException, std::exception)
513 return getSupportedServiceNames_static();
516 // OComponentHelper
517 void SAL_CALL ORowSet::disposing()
519 OPropertyStateContainer::disposing();
521 MutexGuard aGuard(m_aMutex);
522 EventObject aDisposeEvent;
523 aDisposeEvent.Source = static_cast< XComponent* >(this);
524 m_aRowsetListeners.disposeAndClear( aDisposeEvent );
525 m_aApproveListeners.disposeAndClear( aDisposeEvent );
526 m_aRowsChangeListener.disposeAndClear( aDisposeEvent );
528 freeResources( true );
530 // remove myself as dispose listener
531 Reference< XComponent > xComponent(m_xActiveConnection, UNO_QUERY);
532 if (xComponent.is())
534 Reference<XEventListener> xEvt;
535 query_aggregation(this,xEvt);
536 xComponent->removeEventListener(xEvt);
539 m_aActiveConnection = Any(); // the any conatains a reference too
540 if(m_bOwnConnection)
541 ::comphelper::disposeComponent(m_xActiveConnection);
542 m_xActiveConnection = NULL;
545 ORowSetBase::disposing();
548 void ORowSet::freeResources( bool _bComplete )
550 MutexGuard aGuard(m_aMutex);
552 // free all clones
553 connectivity::OWeakRefArray::iterator aEnd = m_aClones.end();
554 for (connectivity::OWeakRefArray::iterator i = m_aClones.begin(); aEnd != i; ++i)
556 Reference< XComponent > xComp(i->get(), UNO_QUERY);
557 if (xComp.is())
558 xComp->dispose();
560 m_aClones.clear();
562 doCancelModification();
564 m_aBookmark = Any();
565 m_bBeforeFirst = true;
566 m_bAfterLast = false;
567 m_bNew = false;
568 m_bModified = false;
569 m_bIsInsertRow = false;
570 m_bLastKnownRowCountFinal = false;
571 m_nLastKnownRowCount = 0;
573 if ( _bComplete )
575 // the columns must be disposed before the querycomposer is disposed because
576 // their owner can be the composer
577 TDataColumns().swap(m_aDataColumns);// clear and resize capacity
578 ::std::vector<bool>().swap(m_aReadOnlyDataColumns);
580 m_xColumns = NULL;
581 if ( m_pColumns )
582 m_pColumns->disposing();
583 // dispose the composer to avoid that everbody knows that the querycomposer is eol
584 try { ::comphelper::disposeComponent( m_xComposer ); }
585 catch(Exception&)
587 DBG_UNHANDLED_EXCEPTION();
588 m_xComposer = NULL;
591 // let our warnings container forget the reference to the (possibly disposed) old result set
592 m_aWarnings.setExternalWarnings( NULL );
594 DELETEZ(m_pCache);
596 impl_resetTables_nothrow();
598 m_xStatement = NULL;
599 m_xTypeMap = NULL;
601 if ( m_aOldRow.is() )
602 m_aOldRow->clearRow();
604 impl_disposeParametersContainer_nothrow();
606 m_bCommandFacetsDirty = true;
610 void ORowSet::setActiveConnection( Reference< XConnection >& _rxNewConn, bool _bFireEvent )
612 if (_rxNewConn.get() == m_xActiveConnection.get())
613 // nothing to do
614 return;
616 // remove the event listener for the old connection
617 Reference< XComponent > xComponent(m_xActiveConnection, UNO_QUERY);
618 if (xComponent.is())
620 Reference<XEventListener> xListener;
621 query_aggregation(this, xListener);
622 xComponent->removeEventListener(xListener);
625 // if we owned the connection, remember it for later disposing
626 if(m_bOwnConnection)
627 m_xOldConnection = m_xActiveConnection;
629 // for firing the PropertyChangeEvent
630 sal_Int32 nHandle = PROPERTY_ID_ACTIVE_CONNECTION;
631 Any aOldConnection; aOldConnection <<= m_xActiveConnection;
632 Any aNewConnection; aNewConnection <<= _rxNewConn;
634 // set the new connection
635 m_xActiveConnection = _rxNewConn;
636 if (m_xActiveConnection.is())
637 m_aActiveConnection <<= m_xActiveConnection;
638 else
639 m_aActiveConnection.clear();
641 // fire the event
642 if (_bFireEvent)
643 fire(&nHandle, &aNewConnection, &aOldConnection, 1, sal_False);
645 // register as event listener for the new connection
646 xComponent.set(m_xActiveConnection,UNO_QUERY);
647 if (xComponent.is())
649 Reference<XEventListener> xListener;
650 query_aggregation(this, xListener);
651 xComponent->addEventListener(xListener);
655 // ::com::sun::star::XEventListener
656 void SAL_CALL ORowSet::disposing( const ::com::sun::star::lang::EventObject& Source ) throw(RuntimeException, std::exception)
658 // close rowset because the connection is going to be deleted (someone told me :-)
659 Reference<XConnection> xCon(Source.Source,UNO_QUERY);
660 if(m_xActiveConnection == xCon)
662 close();
664 MutexGuard aGuard( m_aMutex );
665 Reference< XConnection > xXConnection;
666 setActiveConnection( xXConnection );
671 // XCloseable
672 void SAL_CALL ORowSet::close( ) throw(SQLException, RuntimeException, std::exception)
675 MutexGuard aGuard( m_aMutex );
676 ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed);
678 // additionals things to set
679 freeResources( true );
682 // comphelper::OPropertyArrayUsageHelper
683 ::cppu::IPropertyArrayHelper* ORowSet::createArrayHelper( ) const
685 Sequence< Property > aProps;
686 describeProperties(aProps);
687 return new ::cppu::OPropertyArrayHelper(aProps);
690 // cppu::OPropertySetHelper
691 ::cppu::IPropertyArrayHelper& SAL_CALL ORowSet::getInfoHelper()
693 typedef ::comphelper::OPropertyArrayUsageHelper<ORowSet> ORowSet_PROP;
694 return *ORowSet_PROP::getArrayHelper();
697 void ORowSet::updateValue(sal_Int32 columnIndex,const ORowSetValue& x)
699 ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed);
701 ::osl::MutexGuard aGuard( *m_pMutex );
702 checkUpdateConditions(columnIndex);
703 checkUpdateIterator();
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();
712 // XRowUpdate
713 void SAL_CALL ORowSet::updateNull( sal_Int32 columnIndex ) throw(SQLException, RuntimeException, std::exception)
715 ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed);
717 ::osl::MutexGuard aGuard( *m_pMutex );
718 checkUpdateConditions(columnIndex);
719 checkUpdateIterator();
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();
728 void SAL_CALL ORowSet::updateBoolean( sal_Int32 columnIndex, sal_Bool x ) throw(SQLException, RuntimeException, std::exception)
730 updateValue(columnIndex, static_cast<bool>(x));
733 void SAL_CALL ORowSet::updateByte( sal_Int32 columnIndex, sal_Int8 x ) throw(SQLException, RuntimeException, std::exception)
735 updateValue(columnIndex,x);
738 void SAL_CALL ORowSet::updateShort( sal_Int32 columnIndex, sal_Int16 x ) throw(SQLException, RuntimeException, std::exception)
740 updateValue(columnIndex,x);
743 void SAL_CALL ORowSet::updateInt( sal_Int32 columnIndex, sal_Int32 x ) throw(SQLException, RuntimeException, std::exception)
745 updateValue(columnIndex,x);
748 void SAL_CALL ORowSet::updateLong( sal_Int32 columnIndex, sal_Int64 x ) throw(SQLException, RuntimeException, std::exception)
750 updateValue(columnIndex,x);
753 void SAL_CALL ORowSet::updateFloat( sal_Int32 columnIndex, float x ) throw(SQLException, RuntimeException, std::exception)
755 updateValue(columnIndex,x);
758 void SAL_CALL ORowSet::updateDouble( sal_Int32 columnIndex, double x ) throw(SQLException, RuntimeException, std::exception)
760 updateValue(columnIndex,x);
763 void SAL_CALL ORowSet::updateString( sal_Int32 columnIndex, const OUString& x ) throw(SQLException, RuntimeException, std::exception)
765 updateValue(columnIndex,x);
768 void SAL_CALL ORowSet::updateBytes( sal_Int32 columnIndex, const Sequence< sal_Int8 >& x ) throw(SQLException, RuntimeException, std::exception)
770 updateValue(columnIndex,x);
773 void SAL_CALL ORowSet::updateDate( sal_Int32 columnIndex, const ::com::sun::star::util::Date& x ) throw(SQLException, RuntimeException, std::exception)
775 updateValue(columnIndex,x);
778 void SAL_CALL ORowSet::updateTime( sal_Int32 columnIndex, const ::com::sun::star::util::Time& x ) throw(SQLException, RuntimeException, std::exception)
780 updateValue(columnIndex,x);
783 void SAL_CALL ORowSet::updateTimestamp( sal_Int32 columnIndex, const ::com::sun::star::util::DateTime& x ) throw(SQLException, RuntimeException, std::exception)
785 updateValue(columnIndex,x);
788 void SAL_CALL ORowSet::updateBinaryStream( sal_Int32 columnIndex, const Reference< ::com::sun::star::io::XInputStream >& x, sal_Int32 length ) throw(SQLException, RuntimeException, std::exception)
790 ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed);
791 ::osl::MutexGuard aGuard( *m_pMutex );
792 checkUpdateConditions(columnIndex);
793 checkUpdateIterator();
796 Sequence<sal_Int8> aSeq;
797 if(x.is())
798 x->readBytes(aSeq,length);
799 updateValue(columnIndex,aSeq);
803 void SAL_CALL ORowSet::updateCharacterStream( sal_Int32 columnIndex, const Reference< ::com::sun::star::io::XInputStream >& x, sal_Int32 length ) throw(SQLException, RuntimeException, std::exception)
805 ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed);
806 ::osl::MutexGuard aGuard( *m_pMutex );
807 checkUpdateConditions(columnIndex);
808 checkUpdateIterator();
809 ORowSetValueVector::Vector& rRow = ((*m_aCurrentRow)->get());
810 ORowSetNotifier aNotify(this,rRow);
811 m_pCache->updateCharacterStream(columnIndex,x,length,rRow,aNotify.getChangedColumns());
812 m_bModified = m_bModified || !aNotify.getChangedColumns().empty();
813 aNotify.firePropertyChange();
816 void SAL_CALL ORowSet::updateObject( sal_Int32 columnIndex, const Any& x ) throw(SQLException, RuntimeException, std::exception)
818 ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed);
819 ::osl::MutexGuard aGuard( *m_pMutex );
820 checkUpdateConditions(columnIndex);
821 checkUpdateIterator();
823 Any aNewValue = x;
825 if ( m_pColumns )
827 Reference<XPropertySet> xColumn(m_pColumns->getByIndex(columnIndex-1),UNO_QUERY);
828 sal_Int32 nColType = 0;
829 xColumn->getPropertyValue(PROPERTY_TYPE) >>= nColType;
830 switch( nColType )
832 case DataType::DATE:
833 case DataType::TIME:
834 case DataType::TIMESTAMP:
836 double nValue = 0;
837 if ( x >>= nValue )
839 if ( DataType::TIMESTAMP == nColType )
840 aNewValue <<= dbtools::DBTypeConversion::toDateTime( nValue );
841 else if ( DataType::DATE == nColType )
842 aNewValue <<= dbtools::DBTypeConversion::toDate( nValue );
843 else
844 aNewValue <<= dbtools::DBTypeConversion::toTime( nValue );
846 break;
851 if (!::dbtools::implUpdateObject(this, columnIndex, aNewValue))
852 { // there is no other updateXXX call which can handle the value in x
853 ORowSetValueVector::Vector& rRow = ((*m_aCurrentRow)->get());
854 ORowSetNotifier aNotify(this,rRow);
855 m_pCache->updateObject(columnIndex,aNewValue,rRow,aNotify.getChangedColumns());
856 m_bModified = m_bModified || !aNotify.getChangedColumns().empty();
857 aNotify.firePropertyChange();
861 void SAL_CALL ORowSet::updateNumericObject( sal_Int32 columnIndex, const Any& x, sal_Int32 scale ) throw(SQLException, RuntimeException, std::exception)
863 ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed);
864 ::osl::MutexGuard aGuard( *m_pMutex );
865 checkUpdateConditions(columnIndex);
866 checkUpdateIterator();
867 ORowSetValueVector::Vector& rRow = ((*m_aCurrentRow)->get());
868 ORowSetNotifier aNotify(this,rRow);
869 m_pCache->updateNumericObject(columnIndex,x,scale,rRow,aNotify.getChangedColumns());
870 m_bModified = m_bModified || !aNotify.getChangedColumns().empty();
871 aNotify.firePropertyChange();
874 // XResultSetUpdate
875 void SAL_CALL ORowSet::insertRow( ) throw(SQLException, RuntimeException, std::exception)
877 ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed);
878 // insertRow is not allowd when
879 // standing not on the insert row nor
880 // when the row isn't modified
881 // or the concurency is read only
882 ::osl::ResettableMutexGuard aGuard( *m_pMutex );
884 if(!m_pCache || !m_bNew || !m_bModified || m_nResultSetConcurrency == ResultSetConcurrency::READ_ONLY)
885 throwFunctionSequenceException(*this);
887 // remember old value for fire
888 bool bOld = m_bNew;
890 ORowSetRow aOldValues;
891 if ( !m_aCurrentRow.isNull() )
892 aOldValues = new ORowSetValueVector( *(*m_aCurrentRow));
893 Sequence<Any> aChangedBookmarks;
894 RowsChangeEvent aEvt(*this,RowChangeAction::INSERT,1,aChangedBookmarks);
895 notifyAllListenersRowBeforeChange(aGuard,aEvt);
897 ::std::vector< Any > aBookmarks;
898 bool bInserted = m_pCache->insertRow(aBookmarks);
900 // make sure that our row is set to the new inserted row before clearing the insert flags in the cache
901 m_pCache->resetInsertRow(bInserted);
903 // notification order
904 // - column values
905 setCurrentRow( false, true, aOldValues, aGuard ); // we don't move here
907 // read-only flag restored
908 impl_restoreDataColumnsWriteable_throw();
910 // - rowChanged
911 notifyAllListenersRowChanged(aGuard,aEvt);
913 if ( !aBookmarks.empty() )
915 RowsChangeEvent aUpEvt(*this,RowChangeAction::UPDATE,aBookmarks.size(),Sequence<Any>(&(*aBookmarks.begin()),aBookmarks.size()));
916 notifyAllListenersRowChanged(aGuard,aUpEvt);
919 // - IsModified
920 if(!m_bModified)
921 fireProperty(PROPERTY_ID_ISMODIFIED,false,true);
922 OSL_ENSURE( !m_bModified, "ORowSet::insertRow: just updated, but _still_ modified?" );
924 // - IsNew
925 if(m_bNew != bOld)
926 fireProperty(PROPERTY_ID_ISNEW,m_bNew,bOld);
928 // - RowCount/IsRowCountFinal
929 fireRowcount();
932 void SAL_CALL ORowSet::updateRow( ) throw(SQLException, RuntimeException, std::exception)
934 ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed);
935 // not allowed when standing on insert row
936 ::osl::ResettableMutexGuard aGuard( *m_pMutex );
937 if ( !m_pCache || m_nResultSetConcurrency == ResultSetConcurrency::READ_ONLY || m_bNew || ((m_pCache->m_nPrivileges & Privilege::UPDATE ) != Privilege::UPDATE) )
938 throwFunctionSequenceException(*this);
941 if(m_bModified)
943 ORowSetRow aOldValues;
944 if ( !m_aCurrentRow.isNull() )
945 aOldValues = new ORowSetValueVector( *(*m_aCurrentRow) );
947 Sequence<Any> aChangedBookmarks;
948 RowsChangeEvent aEvt(*this,RowChangeAction::UPDATE,1,aChangedBookmarks);
949 notifyAllListenersRowBeforeChange(aGuard,aEvt);
951 ::std::vector< Any > aBookmarks;
952 m_pCache->updateRow(m_aCurrentRow.operator ->(),aBookmarks);
953 if ( !aBookmarks.empty() )
954 aEvt.Bookmarks = Sequence<Any>(&(*aBookmarks.begin()),aBookmarks.size());
955 aEvt.Rows += aBookmarks.size();
956 m_aBookmark = m_pCache->getBookmark();
957 m_aCurrentRow = m_pCache->m_aMatrixIter;
958 m_bIsInsertRow = false;
959 if ( m_pCache->m_aMatrixIter != m_pCache->getEnd() && (*m_pCache->m_aMatrixIter).is() )
961 if ( m_pCache->isResultSetChanged() )
963 impl_rebuild_throw(aGuard);
965 else
967 m_aOldRow->setRow(new ORowSetValueVector(*(*m_aCurrentRow)));
969 // notification order
970 // - column values
971 ORowSetBase::firePropertyChange(aOldValues);
973 // - rowChanged
974 notifyAllListenersRowChanged(aGuard,aEvt);
976 // - IsModified
977 if(!m_bModified)
978 fireProperty(PROPERTY_ID_ISMODIFIED,false,true);
979 OSL_ENSURE( !m_bModified, "ORowSet::updateRow: just updated, but _still_ modified?" );
981 // - RowCount/IsRowCountFinal
982 fireRowcount();
984 else if ( !m_bAfterLast ) // the update went wrong
986 ::dbtools::throwSQLException( DBACORE_RESSTRING( RID_STR_UPDATE_FAILED ), SQL_INVALID_CURSOR_POSITION, *this );
991 void SAL_CALL ORowSet::deleteRow( ) throw(SQLException, RuntimeException, std::exception)
993 ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed);
995 ::osl::ResettableMutexGuard aGuard( *m_pMutex );
996 checkCache();
998 if ( m_bBeforeFirst || m_bAfterLast )
999 ::dbtools::throwSQLException( DBACORE_RESSTRING( RID_STR_NO_DELETE_BEFORE_AFTER ), SQL_INVALID_CURSOR_POSITION, *this );
1000 if ( m_bNew )
1001 ::dbtools::throwSQLException( DBACORE_RESSTRING( RID_STR_NO_DELETE_INSERT_ROW ), SQL_INVALID_CURSOR_POSITION, *this );
1002 if ( m_nResultSetConcurrency == ResultSetConcurrency::READ_ONLY )
1003 ::dbtools::throwSQLException( DBACORE_RESSTRING( RID_STR_RESULT_IS_READONLY ), SQL_FUNCTION_SEQUENCE_ERROR, *this );
1004 if ( ( m_pCache->m_nPrivileges & Privilege::DELETE ) != Privilege::DELETE )
1005 ::dbtools::throwSQLException( DBACORE_RESSTRING( RID_STR_NO_DELETE_PRIVILEGE ), SQL_FUNCTION_SEQUENCE_ERROR, *this );
1006 if ( rowDeleted() )
1007 ::dbtools::throwSQLException( DBACORE_RESSTRING( RID_STR_ROW_ALREADY_DELETED ), SQL_FUNCTION_SEQUENCE_ERROR, *this );
1009 // this call position the cache indirect
1010 Any aBookmarkToDelete( m_aBookmark );
1011 positionCache( MOVE_NONE );
1012 sal_Int32 nDeletePosition = m_pCache->getRow();
1014 notifyRowSetAndClonesRowDelete( aBookmarkToDelete );
1016 ORowSetRow aOldValues;
1017 if ( m_pCache->m_aMatrixIter != m_pCache->getEnd() && m_pCache->m_aMatrixIter->is() )
1018 aOldValues = new ORowSetValueVector( *(*(m_pCache->m_aMatrixIter)) );
1020 Sequence<Any> aChangedBookmarks;
1021 RowsChangeEvent aEvt(*this,RowChangeAction::DELETE,1,aChangedBookmarks);
1022 notifyAllListenersRowBeforeChange(aGuard,aEvt);
1024 m_pCache->deleteRow();
1025 notifyRowSetAndClonesRowDeleted( aBookmarkToDelete, nDeletePosition );
1027 ORowSetNotifier aNotifier( this );
1028 // this will call cancelRowModification on the cache if necessary
1030 // notification order
1031 // - rowChanged
1032 notifyAllListenersRowChanged(aGuard,aEvt);
1034 // - IsModified
1035 // - IsNew
1036 aNotifier.fire( );
1038 // - RowCount/IsRowCountFinal
1039 fireRowcount();
1042 void ORowSet::implCancelRowUpdates( bool _bNotifyModified )
1044 ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed);
1046 ::osl::MutexGuard aGuard( *m_pMutex );
1047 if ( m_bBeforeFirst || m_bAfterLast || rowDeleted() )
1048 return; // nothing to do so return
1050 checkCache();
1051 // cancelRowUpdates is not allowed when:
1052 // - standing on the insert row
1053 // - the concurrency is read only
1054 // - the current row is deleted
1055 if ( m_bNew || m_nResultSetConcurrency == ResultSetConcurrency::READ_ONLY )
1056 throwFunctionSequenceException(*this);
1058 positionCache( MOVE_NONE );
1060 ORowSetRow aOldValues;
1061 if ( !m_bModified && _bNotifyModified && !m_aCurrentRow.isNull() )
1062 aOldValues = new ORowSetValueVector( *(*m_aCurrentRow) );
1064 m_pCache->cancelRowUpdates();
1066 m_aBookmark = m_pCache->getBookmark();
1067 m_aCurrentRow = m_pCache->m_aMatrixIter;
1068 m_bIsInsertRow = false;
1069 m_aCurrentRow.setBookmark(m_aBookmark);
1071 // notification order
1072 // IsModified
1073 if( !m_bModified && _bNotifyModified )
1075 // - column values
1076 ORowSetBase::firePropertyChange(aOldValues);
1077 fireProperty(PROPERTY_ID_ISMODIFIED,false,true);
1081 void SAL_CALL ORowSet::cancelRowUpdates( ) throw(SQLException, RuntimeException, std::exception)
1083 implCancelRowUpdates( true );
1086 void SAL_CALL ORowSet::addRowSetListener( const Reference< XRowSetListener >& listener ) throw(RuntimeException, std::exception)
1088 ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed);
1090 ::osl::MutexGuard aGuard( m_aColumnsMutex );
1091 if(listener.is())
1092 m_aRowsetListeners.addInterface(listener);
1095 void SAL_CALL ORowSet::removeRowSetListener( const Reference< XRowSetListener >& listener ) throw(RuntimeException, std::exception)
1097 ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed);
1099 ::osl::MutexGuard aGuard( m_aColumnsMutex );
1100 if(listener.is())
1101 m_aRowsetListeners.removeInterface(listener);
1104 void ORowSet::notifyAllListeners(::osl::ResettableMutexGuard& _rGuard)
1106 EventObject aEvt(*m_pMySelf);
1107 _rGuard.clear();
1108 m_aRowsetListeners.notifyEach( &XRowSetListener::rowSetChanged, aEvt );
1109 _rGuard.reset();
1112 void ORowSet::notifyAllListenersCursorMoved(::osl::ResettableMutexGuard& _rGuard)
1114 EventObject aEvt(*m_pMySelf);
1115 _rGuard.clear();
1116 m_aRowsetListeners.notifyEach( &XRowSetListener::cursorMoved, aEvt );
1117 _rGuard.reset();
1120 void ORowSet::notifyAllListenersRowChanged(::osl::ResettableMutexGuard& _rGuard, const RowsChangeEvent& aEvt)
1122 _rGuard.clear();
1123 m_aRowsetListeners.notifyEach( &XRowSetListener::rowChanged, static_cast<EventObject>(aEvt) );
1124 m_aRowsChangeListener.notifyEach( &XRowsChangeListener::rowsChanged, aEvt );
1125 _rGuard.reset();
1128 bool ORowSet::notifyAllListenersCursorBeforeMove(::osl::ResettableMutexGuard& _rGuard)
1130 EventObject aEvt(*m_pMySelf);
1131 NOTIFY_LISTERNERS_CHECK(m_aApproveListeners,XRowSetApproveListener,approveCursorMove);
1132 return bCheck;
1135 void ORowSet::notifyAllListenersRowBeforeChange(::osl::ResettableMutexGuard& _rGuard,const RowChangeEvent &aEvt)
1137 NOTIFY_LISTERNERS_CHECK(m_aApproveListeners,XRowSetApproveListener,approveRowChange);
1138 if ( !bCheck )
1139 m_aErrors.raiseTypedException( sdb::ErrorCondition::ROW_SET_OPERATION_VETOED, *this, ::cppu::UnoType< RowSetVetoException >::get() );
1142 void ORowSet::fireRowcount()
1144 sal_Int32 nCurrentRowCount( impl_getRowCount() );
1145 bool bCurrentRowCountFinal( m_pCache->m_bRowCountFinal );
1147 if ( m_nLastKnownRowCount != nCurrentRowCount )
1149 sal_Int32 nHandle = PROPERTY_ID_ROWCOUNT;
1150 Any aNew,aOld;
1151 aNew <<= nCurrentRowCount; aOld <<= m_nLastKnownRowCount;
1152 fire(&nHandle,&aNew,&aOld,1,sal_False);
1153 m_nLastKnownRowCount = nCurrentRowCount;
1155 if ( !m_bLastKnownRowCountFinal && ( m_bLastKnownRowCountFinal != bCurrentRowCountFinal ) )
1157 sal_Int32 nHandle = PROPERTY_ID_ISROWCOUNTFINAL;
1158 Any aNew,aOld;
1159 aNew <<= bCurrentRowCountFinal;
1160 aOld <<= m_bLastKnownRowCountFinal;
1161 fire(&nHandle,&aNew,&aOld,1,sal_False);
1162 m_bLastKnownRowCountFinal = bCurrentRowCountFinal;
1166 void SAL_CALL ORowSet::moveToInsertRow( ) throw(SQLException, RuntimeException, std::exception)
1168 ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed);
1170 ::osl::ResettableMutexGuard aGuard( *m_pMutex );
1171 checkPositioningAllowed();
1172 if ( ( m_pCache->m_nPrivileges & Privilege::INSERT ) != Privilege::INSERT )
1173 ::dbtools::throwSQLException( DBACORE_RESSTRING( RID_STR_NO_INSERT_PRIVILEGE ), SQL_GENERAL_ERROR, *this );
1175 if ( notifyAllListenersCursorBeforeMove( aGuard ) )
1177 // remember old value for fire
1178 ORowSetRow aOldValues;
1179 if ( rowDeleted() )
1181 positionCache( MOVE_FORWARD );
1182 m_pCache->next();
1183 setCurrentRow( true, false, aOldValues, aGuard);
1185 else
1186 positionCache( MOVE_NONE );
1188 // check before because the resultset could be empty
1189 if ( !m_bBeforeFirst
1190 && !m_bAfterLast
1191 && m_pCache->m_aMatrixIter != m_pCache->getEnd()
1192 && m_pCache->m_aMatrixIter->is()
1194 aOldValues = new ORowSetValueVector( *(*(m_pCache->m_aMatrixIter)) );
1196 const bool bNewState = m_bNew;
1197 const bool bModState = m_bModified;
1199 m_pCache->moveToInsertRow();
1200 m_aCurrentRow = m_pCache->m_aInsertRow;
1201 m_bIsInsertRow = true;
1203 // set read-only flag to false
1204 impl_setDataColumnsWriteable_throw();
1206 // notification order
1207 // - column values
1208 ORowSetBase::firePropertyChange(aOldValues);
1210 // - cursorMoved
1211 notifyAllListenersCursorMoved(aGuard);
1213 // - IsModified
1214 if ( bModState != m_bModified )
1215 fireProperty( PROPERTY_ID_ISMODIFIED, m_bModified, bModState );
1217 // - IsNew
1218 if ( bNewState != m_bNew )
1219 fireProperty( PROPERTY_ID_ISNEW, m_bNew, bNewState );
1221 // - RowCount/IsRowCountFinal
1222 fireRowcount();
1226 void ORowSet::impl_setDataColumnsWriteable_throw()
1228 impl_restoreDataColumnsWriteable_throw();
1229 TDataColumns::iterator aIter = m_aDataColumns.begin();
1230 m_aReadOnlyDataColumns.resize(m_aDataColumns.size(),false);
1231 ::std::vector<bool, std::allocator<bool> >::iterator aReadIter = m_aReadOnlyDataColumns.begin();
1232 for(;aIter != m_aDataColumns.end();++aIter,++aReadIter)
1234 bool bReadOnly = false;
1235 (*aIter)->getPropertyValue(PROPERTY_ISREADONLY) >>= bReadOnly;
1236 *aReadIter = bReadOnly;
1238 (*aIter)->setPropertyValue(PROPERTY_ISREADONLY,makeAny(sal_False));
1242 void ORowSet::impl_restoreDataColumnsWriteable_throw()
1244 assert(m_aDataColumns.size() == m_aReadOnlyDataColumns.size() || m_aReadOnlyDataColumns.size() == 0 );
1245 TDataColumns::iterator aIter = m_aDataColumns.begin();
1246 ::std::vector<bool, std::allocator<bool> >::iterator aReadIter = m_aReadOnlyDataColumns.begin();
1247 for(;aReadIter != m_aReadOnlyDataColumns.end();++aIter,++aReadIter)
1249 (*aIter)->setPropertyValue(PROPERTY_ISREADONLY, makeAny( (bool)*aReadIter ) );
1251 m_aReadOnlyDataColumns.clear();
1254 void SAL_CALL ORowSet::moveToCurrentRow( ) throw(SQLException, RuntimeException, std::exception)
1256 ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed);
1258 ::osl::ResettableMutexGuard aGuard( *m_pMutex );
1259 checkPositioningAllowed();
1261 if ( !m_pCache->m_bNew && !m_bModified )
1262 // nothing to do if we're not on the insertion row, and not modified otherwise
1263 return;
1265 if ( rowDeleted() )
1266 // this would perhaps even justify a RuntimeException ....
1267 // if the current row is deleted, then no write access to this row should be possible. So,
1268 // m_bModified should be true. Also, as soon as somebody calls moveToInsertRow,
1269 // our current row should not be deleted anymore. So, we should not have survived the above
1270 // check "if ( !m_pCache->m_bNew && !m_bModified )"
1271 ::dbtools::throwSQLException( DBACORE_RESSTRING( RID_STR_ROW_ALREADY_DELETED ), SQL_FUNCTION_SEQUENCE_ERROR, *this );
1273 if ( notifyAllListenersCursorBeforeMove( aGuard ) )
1275 positionCache( MOVE_NONE_REFRESH );
1277 ORowSetNotifier aNotifier( this );
1279 // notification order
1280 // - cursorMoved
1281 notifyAllListenersCursorMoved(aGuard);
1283 // - IsModified
1284 // - IsNew
1285 aNotifier.fire();
1289 // XRow
1290 sal_Bool SAL_CALL ORowSet::wasNull( ) throw(SQLException, RuntimeException, std::exception)
1292 ::osl::MutexGuard aGuard( *m_pMutex );
1293 checkCache();
1295 return ( m_pCache && isInsertRow() ) ? ((*m_pCache->m_aInsertRow)->get())[m_nLastColumnIndex].isNull() : ORowSetBase::wasNull();
1298 const ORowSetValue& ORowSet::getInsertValue(sal_Int32 columnIndex)
1300 checkCache();
1302 if ( m_pCache && isInsertRow() )
1303 return ((*m_pCache->m_aInsertRow)->get())[m_nLastColumnIndex = columnIndex];
1305 return getValue(columnIndex);
1308 OUString SAL_CALL ORowSet::getString( sal_Int32 columnIndex ) throw(SQLException, RuntimeException, std::exception)
1310 ::osl::MutexGuard aGuard( *m_pMutex );
1311 return getInsertValue(columnIndex);
1314 sal_Bool SAL_CALL ORowSet::getBoolean( sal_Int32 columnIndex ) throw(SQLException, RuntimeException, std::exception)
1316 ::osl::MutexGuard aGuard( *m_pMutex );
1317 // the extra cast is to recognise the "true" or "false" strings
1318 return static_cast<bool>(getInsertValue(columnIndex));
1321 sal_Int8 SAL_CALL ORowSet::getByte( sal_Int32 columnIndex ) throw(SQLException, RuntimeException, std::exception)
1323 ::osl::MutexGuard aGuard( *m_pMutex );
1324 return getInsertValue(columnIndex);
1327 sal_Int16 SAL_CALL ORowSet::getShort( sal_Int32 columnIndex ) throw(SQLException, RuntimeException, std::exception)
1329 ::osl::MutexGuard aGuard( *m_pMutex );
1330 return getInsertValue(columnIndex);
1333 sal_Int32 SAL_CALL ORowSet::getInt( sal_Int32 columnIndex ) throw(SQLException, RuntimeException, std::exception)
1335 ::osl::MutexGuard aGuard( *m_pMutex );
1336 return getInsertValue(columnIndex);
1339 sal_Int64 SAL_CALL ORowSet::getLong( sal_Int32 columnIndex ) throw(SQLException, RuntimeException, std::exception)
1341 ::osl::MutexGuard aGuard( *m_pMutex );
1342 return getInsertValue(columnIndex);
1345 float SAL_CALL ORowSet::getFloat( sal_Int32 columnIndex ) throw(SQLException, RuntimeException, std::exception)
1347 ::osl::MutexGuard aGuard( *m_pMutex );
1348 return getInsertValue(columnIndex);
1351 double SAL_CALL ORowSet::getDouble( sal_Int32 columnIndex ) throw(SQLException, RuntimeException, std::exception)
1353 ::osl::MutexGuard aGuard( *m_pMutex );
1354 return getInsertValue(columnIndex);
1357 Sequence< sal_Int8 > SAL_CALL ORowSet::getBytes( sal_Int32 columnIndex ) throw(SQLException, RuntimeException, std::exception)
1359 ::osl::MutexGuard aGuard( *m_pMutex );
1360 return getInsertValue(columnIndex);
1363 ::com::sun::star::util::Date SAL_CALL ORowSet::getDate( sal_Int32 columnIndex ) throw(SQLException, RuntimeException, std::exception)
1365 ::osl::MutexGuard aGuard( *m_pMutex );
1366 return getInsertValue(columnIndex);
1369 ::com::sun::star::util::Time SAL_CALL ORowSet::getTime( sal_Int32 columnIndex ) throw(SQLException, RuntimeException, std::exception)
1371 ::osl::MutexGuard aGuard( *m_pMutex );
1372 return getInsertValue(columnIndex);
1375 ::com::sun::star::util::DateTime SAL_CALL ORowSet::getTimestamp( sal_Int32 columnIndex ) throw(SQLException, RuntimeException, std::exception)
1377 ::osl::MutexGuard aGuard( *m_pMutex );
1378 return getInsertValue(columnIndex);
1381 Reference< ::com::sun::star::io::XInputStream > SAL_CALL ORowSet::getBinaryStream( sal_Int32 columnIndex ) throw(SQLException, RuntimeException, std::exception)
1383 ::osl::MutexGuard aGuard( *m_pMutex );
1384 if ( m_pCache && isInsertRow() )
1386 checkCache();
1387 return new ::comphelper::SequenceInputStream(((*m_pCache->m_aInsertRow)->get())[m_nLastColumnIndex = columnIndex].getSequence());
1390 return ORowSetBase::getBinaryStream(columnIndex);
1393 Reference< ::com::sun::star::io::XInputStream > SAL_CALL ORowSet::getCharacterStream( sal_Int32 columnIndex ) throw(SQLException, RuntimeException, std::exception)
1395 ::osl::MutexGuard aGuard( *m_pMutex );
1396 if(m_pCache && isInsertRow() )
1398 checkCache();
1399 return new ::comphelper::SequenceInputStream(((*m_pCache->m_aInsertRow)->get())[m_nLastColumnIndex = columnIndex].getSequence());
1402 return ORowSetBase::getCharacterStream(columnIndex);
1405 Any SAL_CALL ORowSet::getObject( sal_Int32 columnIndex, const Reference< XNameAccess >& /*typeMap*/ ) throw(SQLException, RuntimeException, std::exception)
1407 ::osl::MutexGuard aGuard( *m_pMutex );
1408 return getInsertValue(columnIndex).makeAny();
1411 Reference< XRef > SAL_CALL ORowSet::getRef( sal_Int32 /*columnIndex*/ ) throw(SQLException, RuntimeException, std::exception)
1413 return Reference< XRef >();
1416 Reference< XBlob > SAL_CALL ORowSet::getBlob( sal_Int32 columnIndex ) throw(SQLException, RuntimeException, std::exception)
1418 if ( m_pCache && isInsertRow() )
1420 checkCache();
1421 return new ::connectivity::BlobHelper(((*m_pCache->m_aInsertRow)->get())[m_nLastColumnIndex = columnIndex].getSequence());
1423 return ORowSetBase::getBlob(columnIndex);
1426 Reference< XClob > SAL_CALL ORowSet::getClob( sal_Int32 columnIndex ) throw(SQLException, RuntimeException, std::exception)
1428 return Reference< XClob >(getInsertValue(columnIndex).makeAny(),UNO_QUERY);
1431 Reference< XArray > SAL_CALL ORowSet::getArray( sal_Int32 /*columnIndex*/ ) throw(SQLException, RuntimeException, std::exception)
1433 return Reference< XArray >();
1436 void SAL_CALL ORowSet::executeWithCompletion( const Reference< XInteractionHandler >& _rxHandler ) throw(SQLException, RuntimeException, std::exception)
1438 if (!_rxHandler.is())
1439 execute();
1441 ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed);
1443 // tell everybody that we will change the result set
1444 approveExecution();
1446 ResettableMutexGuard aGuard( m_aMutex );
1450 freeResources( m_bCommandFacetsDirty );
1452 // calc the connection to be used
1453 if (m_xActiveConnection.is() && m_bRebuildConnOnExecute)
1455 // there was a setProperty(ActiveConnection), but a setProperty(DataSource) _after_ that, too
1456 Reference< XConnection > xXConnection;
1457 setActiveConnection( xXConnection );
1459 calcConnection( _rxHandler );
1460 m_bRebuildConnOnExecute = false;
1462 Reference< XSingleSelectQueryComposer > xComposer = getCurrentSettingsComposer( this, m_aContext );
1463 Reference<XParametersSupplier> xParameters(xComposer, UNO_QUERY);
1465 Reference<XIndexAccess> xParamsAsIndicies = xParameters.is() ? xParameters->getParameters() : Reference<XIndexAccess>();
1466 const sal_Int32 nParamCount = xParamsAsIndicies.is() ? xParamsAsIndicies->getCount() : 0;
1467 if ( m_aParametersSet.size() < (size_t)nParamCount )
1468 m_aParametersSet.resize( nParamCount ,false);
1470 ::dbtools::askForParameters( xComposer, this, m_xActiveConnection, _rxHandler,m_aParametersSet );
1472 // ensure that only the allowed exceptions leave this block
1473 catch(SQLException&)
1475 throw;
1477 catch(RuntimeException&)
1479 throw;
1481 catch(Exception&)
1483 SAL_WARN("dbaccess", "ORowSet::executeWithCompletion: caught an unexpected exception type while filling in the parameters!");
1486 // we're done with the parameters, now for the real execution
1488 // do the real execute
1489 execute_NoApprove_NoNewConn(aGuard);
1492 Reference< XIndexAccess > SAL_CALL ORowSet::getParameters( ) throw (RuntimeException, std::exception)
1494 ::osl::MutexGuard aGuard( *m_pMutex );
1495 ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed);
1497 if ( m_bCommandFacetsDirty )
1498 // need to rebuild the parameters, since some property which contributes to the
1499 // complete command, and thus the parameters, changed
1500 impl_disposeParametersContainer_nothrow();
1502 if ( !m_pParameters.get() && !m_aCommand.isEmpty() )
1506 OUString sNotInterestedIn;
1507 impl_initComposer_throw( sNotInterestedIn );
1509 catch( const Exception& )
1511 DBG_UNHANDLED_EXCEPTION();
1515 // our caller could change our parameters at any time
1516 m_bParametersDirty = true;
1518 return m_pParameters.get();
1521 void ORowSet::approveExecution() throw (RowSetVetoException, RuntimeException)
1523 ::osl::MutexGuard aGuard( m_aColumnsMutex );
1524 EventObject aEvt(*this);
1526 OInterfaceIteratorHelper aApproveIter( m_aApproveListeners );
1527 while ( aApproveIter.hasMoreElements() )
1529 Reference< XRowSetApproveListener > xListener( static_cast< XRowSetApproveListener* >( aApproveIter.next() ) );
1532 if ( xListener.is() && !xListener->approveRowSetChange( aEvt ) )
1533 throw RowSetVetoException();
1535 catch ( const DisposedException& e )
1537 if ( e.Context == xListener )
1538 aApproveIter.remove();
1540 catch ( const RuntimeException& ) { throw; }
1541 catch ( const RowSetVetoException& ) { throw; }
1542 catch ( const Exception& )
1544 DBG_UNHANDLED_EXCEPTION();
1549 // XRowSet
1550 void SAL_CALL ORowSet::execute( ) throw(SQLException, RuntimeException, std::exception)
1552 ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed);
1554 // tell everybody that we will change the result set
1555 approveExecution();
1557 ResettableMutexGuard aGuard( m_aMutex );
1558 freeResources( m_bCommandFacetsDirty );
1560 // calc the connection to be used
1561 if (m_xActiveConnection.is() && m_bRebuildConnOnExecute) {
1562 // there was a setProperty(ActiveConnection), but a setProperty(DataSource) _after_ that, too
1563 Reference< XConnection> xXConnection;
1564 setActiveConnection( xXConnection );
1567 calcConnection(NULL);
1568 m_bRebuildConnOnExecute = false;
1570 // do the real execute
1571 execute_NoApprove_NoNewConn(aGuard);
1574 void ORowSet::setStatementResultSetType( const Reference< XPropertySet >& _rxStatement, sal_Int32 _nDesiredResultSetType, sal_Int32 _nDesiredResultSetConcurrency )
1576 OSL_ENSURE( _rxStatement.is(), "ORowSet::setStatementResultSetType: invalid statement - this will crash!" );
1578 sal_Int32 nResultSetType( _nDesiredResultSetType );
1579 sal_Int32 nResultSetConcurrency( _nDesiredResultSetConcurrency );
1581 // there *might* be a data source setting which tells use to be more defensive with those settings
1582 // #i15113#
1583 bool bRespectDriverRST = false;
1584 Any aSetting;
1585 if ( getDataSourceSetting( ::dbaccess::getDataSource( m_xActiveConnection ), "RespectDriverResultSetType", aSetting ) )
1587 OSL_VERIFY( aSetting >>= bRespectDriverRST );
1590 if ( bRespectDriverRST )
1592 // try type/concurrency settings with decreasing usefulness, and rely on what the connection claims
1593 // to support
1594 Reference< XDatabaseMetaData > xMeta( m_xActiveConnection->getMetaData() );
1596 sal_Int32 nCharacteristics[5][2] =
1597 { { ResultSetType::SCROLL_SENSITIVE, ResultSetConcurrency::UPDATABLE },
1598 { ResultSetType::SCROLL_INSENSITIVE, ResultSetConcurrency::UPDATABLE },
1599 { ResultSetType::SCROLL_SENSITIVE, ResultSetConcurrency::READ_ONLY },
1600 { ResultSetType::SCROLL_INSENSITIVE, ResultSetConcurrency::READ_ONLY },
1601 { ResultSetType::FORWARD_ONLY, ResultSetConcurrency::READ_ONLY }
1603 sal_Int32 i=0;
1604 if ( m_xActiveConnection->getMetaData()->isReadOnly() )
1605 i = 2; // if the database is read-only we only should use read-only concurrency
1607 for ( ; i<5; ++i )
1609 nResultSetType = nCharacteristics[i][0];
1610 nResultSetConcurrency = nCharacteristics[i][1];
1612 // don't try type/concurrency pairs which are more featured than what our caller requested
1613 if ( nResultSetType > _nDesiredResultSetType )
1614 continue;
1615 if ( nResultSetConcurrency > _nDesiredResultSetConcurrency )
1616 continue;
1618 if ( xMeta.is() && xMeta->supportsResultSetConcurrency( nResultSetType, nResultSetConcurrency ) )
1619 break;
1623 _rxStatement->setPropertyValue( PROPERTY_RESULTSETTYPE, makeAny( nResultSetType ) );
1624 _rxStatement->setPropertyValue( PROPERTY_RESULTSETCONCURRENCY, makeAny( nResultSetConcurrency ) );
1627 void ORowSet::impl_ensureStatement_throw()
1629 OUString sCommandToExecute;
1630 if(m_bCommandFacetsDirty)
1632 impl_initComposer_throw( sCommandToExecute );
1634 else
1636 sCommandToExecute = m_bUseEscapeProcessing ? m_xComposer->getQueryWithSubstitution() : m_aActiveCommand;
1641 m_xStatement = m_xActiveConnection->prepareStatement( sCommandToExecute );
1642 if ( !m_xStatement.is() )
1644 ::dbtools::throwSQLException( DBACORE_RESSTRING( RID_STR_INTERNAL_ERROR ), SQL_GENERAL_ERROR, *this );
1647 Reference< XPropertySet > xStatementProps( m_xStatement, UNO_QUERY_THROW );
1648 // set the result set type and concurrency
1651 xStatementProps->setPropertyValue( PROPERTY_USEBOOKMARKS, makeAny( sal_True ) );
1652 xStatementProps->setPropertyValue( PROPERTY_MAXROWS, makeAny( m_nMaxRows ) );
1654 setStatementResultSetType( xStatementProps, m_nResultSetType, m_nResultSetConcurrency );
1656 catch ( const Exception& )
1658 // this exception doesn't matter here because when we catch an exception
1659 // then the driver doesn't support this feature
1662 catch( const SQLException& )
1664 SQLExceptionInfo aError( ::cppu::getCaughtException() );
1665 OSL_ENSURE( aError.isValid(), "ORowSet::impl_makeNewStatement_throw: caught an SQLException which we cannot analyze!" );
1667 // append information about what we were actually going to execute
1670 OUString sInfo(DBA_RES_PARAM( RID_STR_COMMAND_LEADING_TO_ERROR, "$command$", sCommandToExecute ) );
1671 aError.append( SQLExceptionInfo::SQL_CONTEXT, sInfo );
1673 catch( const Exception& ) { DBG_UNHANDLED_EXCEPTION(); }
1675 // propagate
1676 aError.doThrow();
1680 Reference< XResultSet > ORowSet::impl_prepareAndExecute_throw()
1682 impl_ensureStatement_throw();
1684 m_aParameterValueForCache.get().resize(1);
1685 Reference< XParameters > xParam( m_xStatement, UNO_QUERY_THROW );
1686 size_t nParamCount( m_pParameters.is() ? m_pParameters->size() : m_aPrematureParamValues.get().size() );
1687 for ( size_t i=1; i<=nParamCount; ++i )
1689 ORowSetValue& rParamValue( getParameterStorage( (sal_Int32)i ) );
1690 ::dbtools::setObjectWithInfo( xParam, i, rParamValue.makeAny(), rParamValue.getTypeKind() );
1691 m_aParameterValueForCache.get().push_back(rParamValue);
1693 m_bParametersDirty = false;
1695 Reference< XResultSet > xResultSet(m_xStatement->executeQuery());
1697 OUString aComposedUpdateTableName;
1698 if ( !m_aUpdateTableName.isEmpty() )
1699 aComposedUpdateTableName = composeTableName( m_xActiveConnection->getMetaData(), m_aUpdateCatalogName, m_aUpdateSchemaName, m_aUpdateTableName, false, ::dbtools::eInDataManipulation );
1701 SAL_INFO("dbaccess", "ORowSet::impl_prepareAndExecute_throw: creating cache" );
1702 if(m_pCache)
1704 DELETEZ(m_pCache);
1706 m_pCache = new ORowSetCache( xResultSet, m_xComposer.get(), m_aContext, aComposedUpdateTableName, m_bModified, m_bNew,m_aParameterValueForCache,m_aFilter,m_nMaxRows );
1707 if ( m_nResultSetConcurrency == ResultSetConcurrency::READ_ONLY )
1709 m_nPrivileges = Privilege::SELECT;
1710 m_pCache->m_nPrivileges = Privilege::SELECT;
1712 m_pCache->setFetchSize(m_nFetchSize);
1713 m_aCurrentRow = m_pCache->createIterator(this);
1714 m_bIsInsertRow = false;
1715 m_aOldRow = m_pCache->registerOldRow();
1717 return xResultSet;
1720 void ORowSet::impl_initializeColumnSettings_nothrow( const Reference< XPropertySet >& _rxTemplateColumn, const Reference< XPropertySet >& _rxRowSetColumn )
1722 OSL_ENSURE( _rxTemplateColumn.is() && _rxRowSetColumn.is(),
1723 "ORowSet::impl_initializeColumnSettings_nothrow: this will crash!" );
1725 bool bHaveAnyColumnSetting = false;
1728 Reference< XPropertySetInfo > xInfo( _rxTemplateColumn->getPropertySetInfo(), UNO_QUERY_THROW );
1730 // a number of properties is plain copied
1731 const OUString aPropertyNames[] = {
1732 OUString(PROPERTY_ALIGN), OUString(PROPERTY_RELATIVEPOSITION), OUString(PROPERTY_WIDTH), OUString(PROPERTY_HIDDEN), OUString(PROPERTY_CONTROLMODEL),
1733 OUString(PROPERTY_HELPTEXT), OUString(PROPERTY_CONTROLDEFAULT)
1735 for ( size_t i=0; i<sizeof( aPropertyNames ) / sizeof( aPropertyNames[0] ); ++i )
1737 if ( xInfo->hasPropertyByName( aPropertyNames[i] ) )
1739 _rxRowSetColumn->setPropertyValue( aPropertyNames[i], _rxTemplateColumn->getPropertyValue( aPropertyNames[i] ) );
1740 bHaveAnyColumnSetting = true;
1744 // the format key is slightly more complex
1745 sal_Int32 nFormatKey = 0;
1746 if( xInfo->hasPropertyByName( PROPERTY_NUMBERFORMAT ) )
1748 _rxTemplateColumn->getPropertyValue( PROPERTY_NUMBERFORMAT ) >>= nFormatKey;
1749 bHaveAnyColumnSetting = true;
1751 if ( !nFormatKey && m_xNumberFormatTypes.is() )
1752 nFormatKey = ::dbtools::getDefaultNumberFormat( _rxTemplateColumn, m_xNumberFormatTypes, SvtSysLocale().GetLanguageTag().getLocale() );
1753 _rxRowSetColumn->setPropertyValue( PROPERTY_NUMBERFORMAT, makeAny( nFormatKey ) );
1755 catch(Exception&)
1757 DBG_UNHANDLED_EXCEPTION();
1758 return;
1761 if ( bHaveAnyColumnSetting )
1762 return;
1764 // the template column could not provide *any* setting. Okay, probably it's a parser column, which
1765 // does not offer those. However, perhaps the template column referes to a table column, which we
1766 // can use as new template column
1769 Reference< XPropertySetInfo > xInfo( _rxTemplateColumn->getPropertySetInfo(), UNO_QUERY_THROW );
1770 if ( !xInfo->hasPropertyByName( PROPERTY_TABLENAME ) )
1771 // no chance
1772 return;
1774 OUString sTableName;
1775 OSL_VERIFY( _rxTemplateColumn->getPropertyValue( PROPERTY_TABLENAME ) >>= sTableName );
1777 Reference< XNameAccess > xTables( impl_getTables_throw(), UNO_QUERY_THROW );
1778 if ( !xTables->hasByName( sTableName ) )
1779 // no chance
1780 return;
1782 Reference< XColumnsSupplier > xTableColSup( xTables->getByName( sTableName ), UNO_QUERY_THROW );
1783 Reference< XNameAccess > xTableCols( xTableColSup->getColumns(), UNO_QUERY_THROW );
1785 OUString sTableColumnName;
1787 // get the "Name" or (preferred) "RealName" property of the column
1788 OUString sNamePropertyName( PROPERTY_NAME );
1789 if ( xInfo->hasPropertyByName( PROPERTY_REALNAME ) )
1790 sNamePropertyName = PROPERTY_REALNAME;
1791 OSL_VERIFY( _rxTemplateColumn->getPropertyValue( sNamePropertyName ) >>= sTableColumnName );
1793 if ( !xTableCols->hasByName( sTableColumnName ) )
1794 return;
1796 Reference< XPropertySet > xTableColumn( xTableCols->getByName( sTableColumnName ), UNO_QUERY_THROW );
1797 impl_initializeColumnSettings_nothrow( xTableColumn, _rxRowSetColumn );
1799 catch( const Exception& )
1801 DBG_UNHANDLED_EXCEPTION();
1805 void ORowSet::execute_NoApprove_NoNewConn(ResettableMutexGuard& _rClearForNotification)
1807 // now we can dispose our old connection
1808 ::comphelper::disposeComponent(m_xOldConnection);
1809 m_xOldConnection = NULL;
1811 // do we need a new statement
1812 if ( m_bCommandFacetsDirty )
1814 m_xStatement = NULL;
1815 m_xComposer = NULL;
1817 Reference< XResultSet > xResultSet( impl_prepareAndExecute_throw() );
1819 // let our warnings container forget the reference to the (possibly disposed) old result set
1820 m_aWarnings.setExternalWarnings( NULL );
1821 // clear all current warnings
1822 m_aWarnings.clearWarnings();
1823 // let the warnings container know about the new "external warnings"
1824 m_aWarnings.setExternalWarnings( Reference< XWarningsSupplier >( xResultSet, UNO_QUERY ) );
1826 // get the locale
1827 Locale aLocale = SvtSysLocale().GetLanguageTag().getLocale();
1829 // get the numberformatTypes
1830 OSL_ENSURE(m_xActiveConnection.is(),"No ActiveConnection");
1831 Reference< XNumberFormatTypes> xNumberFormatTypes;
1832 Reference< XNumberFormatsSupplier> xNumberFormat = ::dbtools::getNumberFormats(m_xActiveConnection);
1833 if ( xNumberFormat.is() )
1834 m_xNumberFormatTypes.set(xNumberFormat->getNumberFormats(),UNO_QUERY);
1836 ::rtl::Reference< ::connectivity::OSQLColumns> aColumns = new ::connectivity::OSQLColumns();
1837 ::std::vector< OUString> aNames;
1838 OUString aDescription;
1840 const ::std::map<sal_Int32,sal_Int32>& rKeyColumns = m_pCache->getKeyColumns();
1841 if(!m_xColumns.is())
1843 SAL_INFO("dbaccess", "ORowSet::execute_NoApprove_NoNewConn::creating columns" );
1844 // use the meta data
1845 Reference<XResultSetMetaDataSupplier> xMetaSup(m_xStatement,UNO_QUERY);
1848 Reference<XResultSetMetaData> xMetaData = xMetaSup->getMetaData();
1849 if ( xMetaData.is() )
1851 sal_Int32 nCount = xMetaData->getColumnCount();
1852 m_aDataColumns.reserve(nCount+1);
1853 aColumns->get().reserve(nCount+1);
1854 std::map< OUString, int > aColumnMap;
1855 for (sal_Int32 i = 0 ; i < nCount; ++i)
1857 // retrieve the name of the column
1858 OUString sName = xMetaData->getColumnName(i + 1);
1859 // check for duplicate entries
1860 if(aColumnMap.find(sName) != aColumnMap.end())
1862 OUString sAlias(sName);
1863 sal_Int32 searchIndex=1;
1864 while(aColumnMap.find(sAlias) != aColumnMap.end())
1866 (sAlias = sName) += OUString::number(searchIndex++);
1868 sName = sAlias;
1870 ORowSetDataColumn* pColumn = new ORowSetDataColumn( getMetaData(),
1871 this,
1872 this,
1873 i+1,
1874 m_xActiveConnection->getMetaData(),
1875 aDescription,
1876 OUString(),
1877 boost::bind(&ORowSet::getInsertValue, this, _1));
1878 aColumnMap.insert(std::make_pair(sName,0));
1879 aColumns->get().push_back(pColumn);
1880 pColumn->setName(sName);
1881 aNames.push_back(sName);
1882 m_aDataColumns.push_back(pColumn);
1884 pColumn->setFastPropertyValue_NoBroadcast(PROPERTY_ID_ISREADONLY,makeAny(rKeyColumns.find(i+1) != rKeyColumns.end()));
1888 sal_Int32 nFormatKey = 0;
1889 if(m_xNumberFormatTypes.is())
1890 nFormatKey = ::dbtools::getDefaultNumberFormat(pColumn,m_xNumberFormatTypes,aLocale);
1893 pColumn->setFastPropertyValue_NoBroadcast(PROPERTY_ID_NUMBERFORMAT,makeAny(nFormatKey));
1894 pColumn->setFastPropertyValue_NoBroadcast(PROPERTY_ID_RELATIVEPOSITION,makeAny(sal_Int32(i+1)));
1895 pColumn->setFastPropertyValue_NoBroadcast(PROPERTY_ID_WIDTH,makeAny(sal_Int32(227)));
1896 pColumn->setFastPropertyValue_NoBroadcast(PROPERTY_ID_ALIGN,makeAny((sal_Int32)0));
1897 pColumn->setFastPropertyValue_NoBroadcast(PROPERTY_ID_HIDDEN, css::uno::Any(false));
1899 catch(Exception&)
1905 catch (SQLException&)
1909 else
1911 // create the rowset columns
1912 Reference< XResultSetMetaData > xMeta( getMetaData(), UNO_QUERY_THROW );
1913 sal_Int32 nCount = xMeta->getColumnCount();
1914 m_aDataColumns.reserve(nCount+1);
1915 aColumns->get().reserve(nCount+1);
1916 ::std::set< Reference< XPropertySet > > aAllColumns;
1918 for(sal_Int32 i=1; i <= nCount ;++i)
1920 OUString sName = xMeta->getColumnName(i);
1921 OUString sColumnLabel = xMeta->getColumnLabel(i);
1923 // retrieve the column number |i|
1924 Reference<XPropertySet> xColumn;
1926 bool bReFetchName = false;
1927 if (m_xColumns->hasByName(sColumnLabel))
1928 m_xColumns->getByName(sColumnLabel) >>= xColumn;
1929 if (!xColumn.is() && m_xColumns->hasByName(sName))
1930 m_xColumns->getByName(sName) >>= xColumn;
1932 // check if column already in the list we need another
1933 if ( aAllColumns.find( xColumn ) != aAllColumns.end() )
1935 xColumn = NULL;
1936 bReFetchName = true;
1937 sColumnLabel.clear();
1939 if(!xColumn.is())
1941 // no column found so we could look at the position i
1942 Reference<XIndexAccess> xIndexAccess(m_xColumns,UNO_QUERY);
1943 if(xIndexAccess.is() && i <= xIndexAccess->getCount())
1945 xIndexAccess->getByIndex(i-1) >>= xColumn;
1947 else
1949 Sequence< OUString> aSeq = m_xColumns->getElementNames();
1950 if( i <= aSeq.getLength())
1952 m_xColumns->getByName(aSeq.getConstArray()[i-1]) >>= xColumn;
1956 if(bReFetchName && xColumn.is())
1957 xColumn->getPropertyValue(PROPERTY_NAME) >>= sName;
1958 aAllColumns.insert( xColumn );
1961 // create a RowSetDataColumn
1963 Reference<XPropertySetInfo> xInfo = xColumn.is() ? xColumn->getPropertySetInfo() : Reference<XPropertySetInfo>();
1964 if(xInfo.is() && xInfo->hasPropertyByName(PROPERTY_DESCRIPTION))
1965 aDescription = comphelper::getString(xColumn->getPropertyValue(PROPERTY_DESCRIPTION));
1967 OUString sParseLabel;
1968 if ( xColumn.is() )
1970 xColumn->getPropertyValue(PROPERTY_LABEL) >>= sParseLabel;
1972 ORowSetDataColumn* pColumn = new ORowSetDataColumn( getMetaData(),
1973 this,
1974 this,
1976 m_xActiveConnection->getMetaData(),
1977 aDescription,
1978 sParseLabel,
1979 boost::bind(&ORowSet::getInsertValue, this, _1));
1980 aColumns->get().push_back(pColumn);
1982 pColumn->setFastPropertyValue_NoBroadcast(PROPERTY_ID_ISREADONLY,makeAny(rKeyColumns.find(i) != rKeyColumns.end()));
1984 if(sColumnLabel.isEmpty())
1986 if(xColumn.is())
1987 xColumn->getPropertyValue(PROPERTY_NAME) >>= sColumnLabel;
1988 else
1989 sColumnLabel = DBACORE_RESSTRING( RID_STR_EXPRESSION1 );
1991 pColumn->setName(sColumnLabel);
1992 aNames.push_back(sColumnLabel);
1993 m_aDataColumns.push_back(pColumn);
1995 if ( xColumn.is() )
1996 impl_initializeColumnSettings_nothrow( xColumn, pColumn );
2000 // now create the columns we need
2001 if(m_pColumns)
2002 m_pColumns->assign(aColumns,aNames);
2003 else
2005 Reference<XDatabaseMetaData> xMeta = m_xActiveConnection->getMetaData();
2006 m_pColumns = new ORowSetDataColumns(xMeta.is() && xMeta->supportsMixedCaseQuotedIdentifiers(),
2007 aColumns,*this,m_aColumnsMutex,aNames);
2010 else // !m_bCommandFacetsDirty
2012 Reference< XResultSet > xResultSet;
2013 if(m_bParametersDirty)
2015 xResultSet = impl_prepareAndExecute_throw();
2017 else
2019 xResultSet = m_xStatement->executeQuery();
2020 m_pCache->reset(xResultSet);
2022 // let our warnings container forget the reference to the (possibly disposed) old result set
2023 m_aWarnings.setExternalWarnings( NULL );
2024 // clear all current warnings
2025 m_aWarnings.clearWarnings();
2026 // let the warnings container know about the new "external warnings"
2027 m_aWarnings.setExternalWarnings( Reference< XWarningsSupplier >( xResultSet, UNO_QUERY ) );
2029 checkCache();
2030 // notify the rowset listeners
2031 notifyAllListeners(_rClearForNotification);
2034 // XRowSetApproveBroadcaster
2035 void SAL_CALL ORowSet::addRowSetApproveListener( const Reference< XRowSetApproveListener >& listener ) throw(RuntimeException, std::exception)
2037 ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed);
2039 ::osl::MutexGuard aGuard( m_aColumnsMutex );
2041 m_aApproveListeners.addInterface(listener);
2044 void SAL_CALL ORowSet::removeRowSetApproveListener( const Reference< XRowSetApproveListener >& listener ) throw(RuntimeException, std::exception)
2046 ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed);
2048 ::osl::MutexGuard aGuard( m_aColumnsMutex );
2050 m_aApproveListeners.removeInterface(listener);
2053 // XRowsChangeBroadcaster
2054 void SAL_CALL ORowSet::addRowsChangeListener( const Reference< XRowsChangeListener >& listener ) throw(RuntimeException, std::exception)
2056 ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed);
2058 ::osl::MutexGuard aGuard( m_aColumnsMutex );
2060 m_aRowsChangeListener.addInterface(listener);
2063 void SAL_CALL ORowSet::removeRowsChangeListener( const Reference< XRowsChangeListener >& listener ) throw(RuntimeException, std::exception)
2065 ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed);
2067 ::osl::MutexGuard aGuard( m_aColumnsMutex );
2069 m_aRowsChangeListener.removeInterface(listener);
2072 // XResultSetAccess
2073 Reference< XResultSet > SAL_CALL ORowSet::createResultSet( ) throw(SQLException, RuntimeException, std::exception)
2075 ::osl::MutexGuard aGuard( m_aColumnsMutex );
2077 if(m_xStatement.is())
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;
2084 return Reference< XResultSet >();
2087 // ::com::sun::star::util::XCancellable
2088 void SAL_CALL ORowSet::cancel( ) throw(RuntimeException, std::exception)
2090 ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed);
2093 // ::com::sun::star::sdbcx::XDeleteRows
2094 Sequence< sal_Int32 > SAL_CALL ORowSet::deleteRows( const Sequence< Any >& rows ) throw(SQLException, RuntimeException, std::exception)
2096 ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed);
2098 if(!m_pCache || m_nResultSetConcurrency == ResultSetConcurrency::READ_ONLY)
2099 throwFunctionSequenceException(*this);
2101 ::osl::ResettableMutexGuard aGuard( *m_pMutex );
2103 Sequence<Any> aChangedBookmarks;
2104 RowsChangeEvent aEvt(*this,RowChangeAction::DELETE,rows.getLength(),aChangedBookmarks);
2105 // notify the rowset listeners
2106 notifyAllListenersRowBeforeChange(aGuard,aEvt);
2108 Sequence< sal_Int32 > aResults( rows.getLength() );
2109 const Any* row = rows.getConstArray();
2110 const Any* rowEnd = rows.getConstArray() + rows.getLength();
2111 sal_Int32* result = aResults.getArray();
2112 for ( ; row != rowEnd; ++row, ++result )
2114 *result = 0;
2115 if ( !m_pCache->moveToBookmark( *row ) )
2116 continue;
2117 sal_Int32 nDeletePosition = m_pCache->getRow();
2119 // first notify the clones so that they can save their position
2120 notifyRowSetAndClonesRowDelete( *row );
2122 // now delete the row
2123 if ( !m_pCache->deleteRow() )
2124 continue;
2125 *result = 1;
2126 // now notify that we have deleted
2127 notifyRowSetAndClonesRowDeleted( *row, nDeletePosition );
2129 aEvt.Rows = aResults.getLength();
2131 // we have to check if we stand on the insert row and if so we have to reset it
2132 ORowSetNotifier aNotifier( this );
2133 // this will call cancelRowModification on the cache if necessary
2134 // notification order
2135 // - rowChanged
2136 notifyAllListenersRowChanged(aGuard,aEvt);
2138 // - IsModified
2139 // - IsNew
2140 aNotifier.fire();
2142 // - RowCount/IsRowCountFinal
2143 fireRowcount();
2145 return aResults;
2148 void ORowSet::notifyRowSetAndClonesRowDelete( const Any& _rBookmark )
2150 // notify ourself
2151 onDeleteRow( _rBookmark );
2152 // notify the clones
2153 connectivity::OWeakRefArray::iterator aEnd = m_aClones.end();
2154 for (connectivity::OWeakRefArray::iterator i = m_aClones.begin(); aEnd != i; ++i)
2156 Reference< XUnoTunnel > xTunnel(i->get(),UNO_QUERY);
2157 if(xTunnel.is())
2159 ORowSetClone* pClone = reinterpret_cast<ORowSetClone*>(xTunnel->getSomething(ORowSetClone::getUnoTunnelImplementationId()));
2160 if(pClone)
2161 pClone->onDeleteRow( _rBookmark );
2166 void ORowSet::notifyRowSetAndClonesRowDeleted( const Any& _rBookmark, sal_Int32 _nPos )
2168 // notify ourself
2169 onDeletedRow( _rBookmark, _nPos );
2170 // notify the clones
2171 connectivity::OWeakRefArray::iterator aEnd = m_aClones.end();
2172 for (connectivity::OWeakRefArray::iterator i = m_aClones.begin(); aEnd != i; ++i)
2174 Reference< XUnoTunnel > xTunnel(i->get(),UNO_QUERY);
2175 if(xTunnel.is())
2177 ORowSetClone* pClone = reinterpret_cast<ORowSetClone*>(xTunnel->getSomething(ORowSetClone::getUnoTunnelImplementationId()));
2178 if(pClone)
2179 pClone->onDeletedRow( _rBookmark, _nPos );
2184 Reference< XConnection > ORowSet::calcConnection(const Reference< XInteractionHandler >& _rxHandler) throw( SQLException, RuntimeException )
2186 MutexGuard aGuard(m_aMutex);
2187 if (!m_xActiveConnection.is())
2189 Reference< XConnection > xNewConn;
2190 if ( !m_aDataSourceName.isEmpty() )
2192 Reference< XDatabaseContext > xDatabaseContext( DatabaseContext::create(m_aContext) );
2195 Reference< XDataSource > xDataSource( xDatabaseContext->getByName( m_aDataSourceName ), UNO_QUERY_THROW );
2197 // try connecting with the interaction handler
2198 Reference< XCompletedConnection > xComplConn( xDataSource, UNO_QUERY );
2199 if ( _rxHandler.is() && xComplConn.is() )
2201 xNewConn = xComplConn->connectWithCompletion( _rxHandler );
2203 else
2205 xNewConn = xDataSource->getConnection( m_aUser, m_aPassword );
2208 catch ( const SQLException& )
2210 throw;
2212 catch ( const Exception& )
2214 Any aError = ::cppu::getCaughtException();
2215 OUString sMessage = ResourceManager::loadString( RID_NO_SUCH_DATA_SOURCE,
2216 "$name$", m_aDataSourceName, "$error$", extractExceptionMessage( m_aContext, aError ) );
2217 ::dbtools::throwGenericSQLException( sMessage, *this );
2220 setActiveConnection(xNewConn);
2221 m_bOwnConnection = true;
2223 return m_xActiveConnection;
2226 Reference< XNameAccess > ORowSet::impl_getTables_throw()
2228 Reference< XNameAccess > xTables;
2230 Reference< XTablesSupplier > xTablesAccess( m_xActiveConnection, UNO_QUERY );
2231 if ( xTablesAccess.is() )
2233 xTables.set( xTablesAccess->getTables(), UNO_QUERY_THROW );
2235 else if ( m_pTables )
2237 xTables = m_pTables;
2239 else
2241 if ( !m_xActiveConnection.is() )
2242 throw SQLException(DBA_RES(RID_STR_CONNECTION_INVALID),*this,SQLSTATE_GENERAL,1000,Any() );
2244 bool bCase = true;
2247 Reference<XDatabaseMetaData> xMeta = m_xActiveConnection->getMetaData();
2248 bCase = xMeta.is() && xMeta->supportsMixedCaseQuotedIdentifiers();
2250 catch(SQLException&)
2252 DBG_UNHANDLED_EXCEPTION();
2255 m_pTables = new OTableContainer(*this,m_aMutex,m_xActiveConnection,bCase,NULL,NULL,NULL,m_nInAppend);
2256 xTables = m_pTables;
2257 Sequence< OUString> aTableFilter(1);
2258 aTableFilter[0] = "%";
2259 m_pTables->construct(aTableFilter,Sequence< OUString>());
2262 return xTables;
2265 void ORowSet::impl_resetTables_nothrow()
2267 if ( !m_pTables )
2268 return;
2272 m_pTables->dispose();
2274 catch( const Exception& )
2276 DBG_UNHANDLED_EXCEPTION();
2279 DELETEZ( m_pTables );
2282 bool ORowSet::impl_initComposer_throw( OUString& _out_rCommandToExecute )
2284 bool bUseEscapeProcessing = impl_buildActiveCommand_throw( );
2285 _out_rCommandToExecute = m_aActiveCommand;
2286 if ( !bUseEscapeProcessing )
2287 return bUseEscapeProcessing;
2289 if (m_bCommandFacetsDirty)
2290 m_xComposer = NULL;
2292 Reference< XMultiServiceFactory > xFactory( m_xActiveConnection, UNO_QUERY );
2293 if ( !m_xComposer.is() && xFactory.is() )
2297 m_xComposer.set( xFactory->createInstance( SERVICE_NAME_SINGLESELECTQUERYCOMPOSER ), UNO_QUERY_THROW );
2299 catch (const Exception& ) { m_xComposer = NULL; }
2301 if ( !m_xComposer.is() )
2302 m_xComposer = new OSingleSelectQueryComposer( impl_getTables_throw(), m_xActiveConnection, m_aContext );
2304 m_xComposer->setCommand( m_aCommand,m_nCommandType );
2305 m_aActiveCommand = m_xComposer->getQuery();
2307 m_xComposer->setFilter( m_bApplyFilter ? m_aFilter : OUString() );
2308 m_xComposer->setHavingClause( m_bApplyFilter ? m_aHavingClause : OUString() );
2310 if ( m_bIgnoreResult )
2311 { // append a "0=1" filter
2312 // don't simply overwrite an existent filter, this would lead to problems if this existent
2313 // filter contains parameters (since a keyset may add parameters itself)
2314 m_xComposer->setElementaryQuery( m_xComposer->getQuery( ) );
2315 m_xComposer->setFilter( OUString("0 = 1" ) );
2318 m_xComposer->setOrder( m_aOrder );
2319 m_xComposer->setGroup( m_aGroupBy );
2321 if ( !m_xColumns.is() )
2323 Reference< XColumnsSupplier > xCols( m_xComposer, UNO_QUERY_THROW );
2324 m_xColumns = xCols->getColumns();
2327 impl_initParametersContainer_nothrow();
2329 _out_rCommandToExecute = m_xComposer->getQueryWithSubstitution();
2331 m_bCommandFacetsDirty = false;
2333 return bUseEscapeProcessing;
2336 bool ORowSet::impl_buildActiveCommand_throw()
2338 // create the sql command
2339 // from a table name or get the command out of a query (not a view)
2340 // the last use the command as it is
2341 bool bDoEscapeProcessing = m_bUseEscapeProcessing;
2343 m_aActiveCommand.clear();
2344 OUString sCommand;
2346 if ( m_aCommand.isEmpty() )
2347 return bDoEscapeProcessing;
2349 switch (m_nCommandType)
2351 case CommandType::TABLE:
2353 impl_resetTables_nothrow();
2354 if ( bDoEscapeProcessing )
2356 Reference< XNameAccess > xTables( impl_getTables_throw() );
2357 if ( xTables->hasByName(m_aCommand) )
2360 else
2362 OUString sMessage( DBACORE_RESSTRING( RID_STR_TABLE_DOES_NOT_EXIST ) );
2363 throwGenericSQLException(sMessage.replaceAll( "$table$", m_aCommand ),*this);
2366 else
2368 sCommand = "SELECT * FROM ";
2369 OUString sCatalog, sSchema, sTable;
2370 ::dbtools::qualifiedNameComponents( m_xActiveConnection->getMetaData(), m_aCommand, sCatalog, sSchema, sTable, ::dbtools::eInDataManipulation );
2371 sCommand += ::dbtools::composeTableNameForSelect( m_xActiveConnection, sCatalog, sSchema, sTable );
2374 break;
2376 case CommandType::QUERY:
2378 Reference< XQueriesSupplier > xQueriesAccess(m_xActiveConnection, UNO_QUERY);
2379 if (xQueriesAccess.is())
2381 Reference< ::com::sun::star::container::XNameAccess > xQueries(xQueriesAccess->getQueries());
2382 if (xQueries->hasByName(m_aCommand))
2384 Reference< XPropertySet > xQuery(xQueries->getByName(m_aCommand),UNO_QUERY);
2385 OSL_ENSURE(xQuery.is(),"ORowSet::impl_buildActiveCommand_throw: Query is NULL!");
2386 if ( xQuery.is() )
2388 xQuery->getPropertyValue(PROPERTY_COMMAND) >>= sCommand;
2389 xQuery->getPropertyValue(PROPERTY_ESCAPE_PROCESSING) >>= bDoEscapeProcessing;
2390 if ( bDoEscapeProcessing != m_bUseEscapeProcessing )
2392 bool bOldValue = m_bUseEscapeProcessing;
2393 m_bUseEscapeProcessing = bDoEscapeProcessing;
2394 fireProperty(PROPERTY_ID_ESCAPE_PROCESSING,bOldValue,bDoEscapeProcessing);
2397 OUString aCatalog,aSchema,aTable;
2398 xQuery->getPropertyValue(PROPERTY_UPDATE_CATALOGNAME) >>= aCatalog;
2399 xQuery->getPropertyValue(PROPERTY_UPDATE_SCHEMANAME) >>= aSchema;
2400 xQuery->getPropertyValue(PROPERTY_UPDATE_TABLENAME) >>= aTable;
2401 if(!aTable.isEmpty())
2402 m_aUpdateTableName = composeTableName( m_xActiveConnection->getMetaData(), aCatalog, aSchema, aTable, false, ::dbtools::eInDataManipulation );
2405 else
2407 OUString sMessage( DBACORE_RESSTRING( RID_STR_QUERY_DOES_NOT_EXIST ) );
2408 throwGenericSQLException(sMessage.replaceAll( "$table$", m_aCommand ),*this);
2411 else
2412 throw SQLException(DBA_RES(RID_STR_NO_XQUERIESSUPPLIER),*this,OUString(),0,Any());
2414 break;
2416 default:
2417 sCommand = m_aCommand;
2418 break;
2421 m_aActiveCommand = sCommand;
2423 if ( m_aActiveCommand.isEmpty() && !bDoEscapeProcessing )
2424 ::dbtools::throwSQLException( DBACORE_RESSTRING( RID_STR_NO_SQL_COMMAND ), SQL_FUNCTION_SEQUENCE_ERROR, *this );
2426 return bDoEscapeProcessing;
2429 void ORowSet::impl_initParametersContainer_nothrow()
2431 OSL_PRECOND( !m_pParameters.is(), "ORowSet::impl_initParametersContainer_nothrow: already initialized the parameters!" );
2433 m_pParameters = new param::ParameterWrapperContainer( m_xComposer.get() );
2434 // copy the premature parameters into the final ones
2435 size_t nParamCount( ::std::min( m_pParameters->size(), m_aPrematureParamValues.get().size() ) );
2436 for ( size_t i=0; i<nParamCount; ++i )
2438 (*m_pParameters)[i] = m_aPrematureParamValues.get()[i];
2442 void ORowSet::impl_disposeParametersContainer_nothrow()
2444 if ( !m_pParameters.is() )
2445 return;
2447 // copy the actual values to our "premature" ones, to preserve them for later use
2448 size_t nParamCount( m_pParameters->size() );
2449 m_aPrematureParamValues.get().resize( nParamCount );
2450 for ( size_t i=0; i<nParamCount; ++i )
2452 m_aPrematureParamValues.get()[i] = (*m_pParameters)[i];
2455 m_pParameters->dispose();
2456 m_pParameters = NULL;
2459 ORowSetValue& ORowSet::getParameterStorage(sal_Int32 parameterIndex)
2461 ::connectivity::checkDisposed( ORowSet_BASE1::rBHelper.bDisposed );
2462 if ( parameterIndex < 1 )
2463 throwInvalidIndexException( *this );
2465 if ( m_aParametersSet.size() < (size_t)parameterIndex )
2466 m_aParametersSet.resize( parameterIndex ,false);
2467 m_aParametersSet[parameterIndex - 1] = true;
2469 if ( m_pParameters.is() )
2471 if ( m_bCommandFacetsDirty )
2472 // need to rebuild the parameters, since some property which contributes to the
2473 // complete command, and thus the parameters, changed
2474 impl_disposeParametersContainer_nothrow();
2475 if ( m_pParameters.is() )
2477 if ( (size_t)parameterIndex > m_pParameters->size() )
2478 throwInvalidIndexException( *this );
2479 return (*m_pParameters)[ parameterIndex - 1 ];
2483 if ( m_aPrematureParamValues.get().size() < (size_t)parameterIndex )
2484 m_aPrematureParamValues.get().resize( parameterIndex );
2485 return m_aPrematureParamValues.get()[ parameterIndex - 1 ];
2488 // XParameters
2489 void SAL_CALL ORowSet::setNull( sal_Int32 parameterIndex, sal_Int32 /*sqlType*/ ) throw(SQLException, RuntimeException, std::exception)
2491 ::osl::MutexGuard aGuard( m_aColumnsMutex );
2493 getParameterStorage( parameterIndex ).setNull();
2494 m_bParametersDirty = true;
2497 void SAL_CALL ORowSet::setObjectNull( sal_Int32 parameterIndex, sal_Int32 sqlType, const OUString& /*typeName*/ ) throw(SQLException, RuntimeException, std::exception)
2499 setNull( parameterIndex, sqlType );
2502 void ORowSet::setParameter(sal_Int32 parameterIndex, const ORowSetValue& x)
2504 ::osl::MutexGuard aGuard( m_aColumnsMutex );
2506 getParameterStorage( parameterIndex ) = x;
2507 m_bParametersDirty = true;
2510 void SAL_CALL ORowSet::setBoolean( sal_Int32 parameterIndex, sal_Bool x ) throw(SQLException, RuntimeException, std::exception)
2512 setParameter(parameterIndex, static_cast<bool>(x));
2515 void SAL_CALL ORowSet::setByte( sal_Int32 parameterIndex, sal_Int8 x ) throw(SQLException, RuntimeException, std::exception)
2517 setParameter(parameterIndex,x);
2520 void SAL_CALL ORowSet::setShort( sal_Int32 parameterIndex, sal_Int16 x ) throw(SQLException, RuntimeException, std::exception)
2522 setParameter(parameterIndex,x);
2525 void SAL_CALL ORowSet::setInt( sal_Int32 parameterIndex, sal_Int32 x ) throw(SQLException, RuntimeException, std::exception)
2527 setParameter(parameterIndex,x);
2530 void SAL_CALL ORowSet::setLong( sal_Int32 parameterIndex, sal_Int64 x ) throw(SQLException, RuntimeException, std::exception)
2532 setParameter(parameterIndex,x);
2535 void SAL_CALL ORowSet::setFloat( sal_Int32 parameterIndex, float x ) throw(SQLException, RuntimeException, std::exception)
2537 setParameter(parameterIndex,x);
2540 void SAL_CALL ORowSet::setDouble( sal_Int32 parameterIndex, double x ) throw(SQLException, RuntimeException, std::exception)
2542 setParameter(parameterIndex,x);
2545 void SAL_CALL ORowSet::setString( sal_Int32 parameterIndex, const OUString& x ) throw(SQLException, RuntimeException, std::exception)
2547 setParameter(parameterIndex,x);
2550 void SAL_CALL ORowSet::setBytes( sal_Int32 parameterIndex, const Sequence< sal_Int8 >& x ) throw(SQLException, RuntimeException, std::exception)
2552 setParameter(parameterIndex,x);
2555 void SAL_CALL ORowSet::setDate( sal_Int32 parameterIndex, const ::com::sun::star::util::Date& x ) throw(SQLException, RuntimeException, std::exception)
2557 setParameter(parameterIndex,x);
2560 void SAL_CALL ORowSet::setTime( sal_Int32 parameterIndex, const ::com::sun::star::util::Time& x ) throw(SQLException, RuntimeException, std::exception)
2562 setParameter(parameterIndex,x);
2565 void SAL_CALL ORowSet::setTimestamp( sal_Int32 parameterIndex, const ::com::sun::star::util::DateTime& x ) throw(SQLException, RuntimeException, std::exception)
2567 setParameter(parameterIndex,x);
2570 void SAL_CALL ORowSet::setBinaryStream( sal_Int32 parameterIndex, const Reference< ::com::sun::star::io::XInputStream >& x, sal_Int32 length ) throw(SQLException, RuntimeException, std::exception)
2572 ::osl::MutexGuard aGuard( m_aColumnsMutex );
2573 ORowSetValue& rParamValue( getParameterStorage( parameterIndex ) );
2577 Sequence <sal_Int8> aData;
2578 x->readBytes(aData, length);
2579 rParamValue = aData;
2580 m_bParametersDirty = true;
2581 x->closeInput();
2583 catch( Exception& )
2585 throw SQLException();
2589 void SAL_CALL ORowSet::setCharacterStream( sal_Int32 parameterIndex, const Reference< ::com::sun::star::io::XInputStream >& x, sal_Int32 length ) throw(SQLException, RuntimeException, std::exception)
2591 ::osl::MutexGuard aGuard( m_aColumnsMutex );
2592 ORowSetValue& rParamValue( getParameterStorage( parameterIndex ) );
2595 Sequence <sal_Int8> aData;
2596 OUString aDataStr;
2597 // the data is given as character data and the length defines the character length
2598 sal_Int32 nSize = x->readBytes(aData, length * sizeof(sal_Unicode));
2599 if (nSize / sizeof(sal_Unicode))
2600 aDataStr = OUString(reinterpret_cast<sal_Unicode const *>(aData.getConstArray()), nSize / sizeof(sal_Unicode));
2601 m_bParametersDirty = true;
2602 rParamValue = aDataStr;
2603 rParamValue.setTypeKind( DataType::LONGVARCHAR );
2604 x->closeInput();
2606 catch( Exception& )
2608 throw SQLException();
2612 void SAL_CALL ORowSet::setObject( sal_Int32 parameterIndex, const Any& x ) throw(SQLException, RuntimeException, std::exception)
2614 if ( ::dbtools::implSetObject( this, parameterIndex, x ) )
2616 m_bParametersDirty = true;
2618 else
2619 { // there is no other setXXX call which can handle the value in x
2620 throw SQLException();
2624 void SAL_CALL ORowSet::setObjectWithInfo( sal_Int32 parameterIndex, const Any& x, sal_Int32 targetSqlType, sal_Int32 /*scale*/ ) throw(SQLException, RuntimeException, std::exception)
2626 ::osl::MutexGuard aGuard( m_aColumnsMutex );
2627 ORowSetValue& rParamValue( getParameterStorage( parameterIndex ) );
2628 setObject( parameterIndex, x );
2629 rParamValue.setTypeKind( targetSqlType );
2632 void SAL_CALL ORowSet::setRef( sal_Int32 /*parameterIndex*/, const Reference< XRef >& /*x*/ ) throw(SQLException, RuntimeException, std::exception)
2634 ::dbtools::throwFeatureNotImplementedSQLException( "XParameters::setRef", *this );
2637 void SAL_CALL ORowSet::setBlob( sal_Int32 /*parameterIndex*/, const Reference< XBlob >& /*x*/ ) throw(SQLException, RuntimeException, std::exception)
2639 ::dbtools::throwFeatureNotImplementedSQLException( "XParameters::setBlob", *this );
2642 void SAL_CALL ORowSet::setClob( sal_Int32 /*parameterIndex*/, const Reference< XClob >& /*x*/ ) throw(SQLException, RuntimeException, std::exception)
2644 ::dbtools::throwFeatureNotImplementedSQLException( "XParameters::setClob", *this );
2647 void SAL_CALL ORowSet::setArray( sal_Int32 /*parameterIndex*/, const Reference< XArray >& /*x*/ ) throw(SQLException, RuntimeException, std::exception)
2649 ::dbtools::throwFeatureNotImplementedSQLException( "XParameters::setArray", *this );
2652 void SAL_CALL ORowSet::clearParameters( ) throw(SQLException, RuntimeException, std::exception)
2654 ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed);
2656 ::osl::MutexGuard aGuard( m_aColumnsMutex );
2658 size_t nParamCount( m_pParameters.is() ? m_pParameters->size() : m_aPrematureParamValues.get().size() );
2659 for ( size_t i=1; i<=nParamCount; ++i )
2660 getParameterStorage( (sal_Int32)i ).setNull();
2661 m_aParametersSet.clear();
2664 Any SAL_CALL ORowSet::getWarnings( ) throw (SQLException, RuntimeException, std::exception)
2666 return m_aWarnings.getWarnings();
2669 void SAL_CALL ORowSet::clearWarnings( ) throw (SQLException, RuntimeException, std::exception)
2671 m_aWarnings.clearWarnings();
2674 void ORowSet::doCancelModification( )
2676 if ( isModification() )
2678 // read-only flag restored
2679 impl_restoreDataColumnsWriteable_throw();
2680 m_pCache->cancelRowModification();
2682 m_bModified = false;
2683 m_bIsInsertRow = false;
2686 bool ORowSet::isModification( )
2688 return isNew();
2691 bool ORowSet::isModified( )
2693 return m_bModified;
2696 bool ORowSet::isNew( )
2698 return m_bNew;
2701 bool ORowSet::isPropertyChangeNotificationEnabled() const
2703 return m_bPropChangeNotifyEnabled;
2706 void ORowSet::checkUpdateIterator()
2708 if(!m_bIsInsertRow)
2710 m_pCache->setUpdateIterator(m_aCurrentRow);
2711 m_aCurrentRow = m_pCache->m_aInsertRow;
2712 m_bIsInsertRow = true;
2716 void ORowSet::checkUpdateConditions(sal_Int32 columnIndex)
2718 checkCache();
2719 if ( m_nResultSetConcurrency == ResultSetConcurrency::READ_ONLY)
2720 ::dbtools::throwSQLException( DBACORE_RESSTRING( RID_STR_RESULT_IS_READONLY ), SQL_GENERAL_ERROR, *this );
2722 if ( rowDeleted() )
2723 ::dbtools::throwSQLException( DBACORE_RESSTRING( RID_STR_ROW_ALREADY_DELETED ), SQL_INVALID_CURSOR_POSITION, *this );
2725 if ( m_aCurrentRow.isNull() )
2726 ::dbtools::throwSQLException( DBACORE_RESSTRING( RID_STR_INVALID_CURSOR_STATE ), SQL_INVALID_CURSOR_STATE, *this );
2728 if ( columnIndex <= 0 || sal_Int32((*m_aCurrentRow)->get().size()) <= columnIndex )
2729 ::dbtools::throwSQLException( DBACORE_RESSTRING( RID_STR_INVALID_INDEX ), SQL_INVALID_DESCRIPTOR_INDEX, *this );
2732 void SAL_CALL ORowSet::refreshRow( ) throw(SQLException, RuntimeException, std::exception)
2735 ORowSetNotifier aNotifier( this );
2736 // this will call cancelRowModification on the cache if necessary
2738 // notification order:
2739 if ( m_bModified && m_pCache )
2740 implCancelRowUpdates( false ); // do _not_ notify the IsModify - will do this ourself below
2742 // - column values
2743 ORowSetBase::refreshRow();
2745 // - IsModified
2746 // - IsNew
2747 aNotifier.fire( );
2750 void ORowSet::impl_rebuild_throw(::osl::ResettableMutexGuard& _rGuard)
2752 Reference< XResultSet > xResultSet(m_xStatement->executeQuery());
2753 m_pCache->reset(xResultSet);
2754 m_aWarnings.setExternalWarnings( Reference< XWarningsSupplier >( xResultSet, UNO_QUERY ) );
2755 notifyAllListeners(_rGuard);
2758 // ***********************************************************
2759 // ORowSetClone
2760 // ***********************************************************
2762 ORowSetClone::ORowSetClone( const Reference<XComponentContext>& _rContext, ORowSet& rParent, ::osl::Mutex* _pMutex )
2763 :OSubComponent(m_aMutex, rParent)
2764 ,ORowSetBase( _rContext, OComponentHelper::rBHelper, _pMutex )
2765 ,m_pParent(&rParent)
2766 ,m_nFetchDirection(rParent.m_nFetchDirection)
2767 ,m_nFetchSize(rParent.m_nFetchSize)
2768 ,m_bIsBookmarkable(true)
2771 m_nResultSetType = rParent.m_nResultSetType;
2772 m_nResultSetConcurrency = ResultSetConcurrency::READ_ONLY;
2773 m_pMySelf = this;
2774 m_bClone = true;
2775 m_bBeforeFirst = rParent.m_bBeforeFirst;
2776 m_bAfterLast = rParent.m_bAfterLast;
2777 m_pCache = rParent.m_pCache;
2778 m_aBookmark = rParent.m_aBookmark;
2779 m_aCurrentRow = m_pCache->createIterator(this);
2780 m_xNumberFormatTypes = rParent.m_xNumberFormatTypes;
2782 m_aOldRow = m_pCache->registerOldRow();
2784 ::rtl::Reference< ::connectivity::OSQLColumns> aColumns = new ::connectivity::OSQLColumns();
2785 ::std::vector< OUString> aNames;
2787 OUString aDescription;
2788 Locale aLocale = SvtSysLocale().GetLanguageTag().getLocale();
2790 if ( rParent.m_pColumns )
2792 Sequence< OUString> aSeq = rParent.m_pColumns->getElementNames();
2793 const OUString* pIter = aSeq.getConstArray();
2794 const OUString* pEnd = pIter + aSeq.getLength();
2795 aColumns->get().reserve(aSeq.getLength()+1);
2796 for(sal_Int32 i=1;pIter != pEnd ;++pIter,++i)
2798 Reference<XPropertySet> xColumn;
2799 rParent.m_pColumns->getByName(*pIter) >>= xColumn;
2800 if(xColumn->getPropertySetInfo()->hasPropertyByName(PROPERTY_DESCRIPTION))
2801 aDescription = comphelper::getString(xColumn->getPropertyValue(PROPERTY_DESCRIPTION));
2803 OUString sParseLabel;
2804 xColumn->getPropertyValue(PROPERTY_LABEL) >>= sParseLabel;
2805 ORowSetColumn* pColumn = new ORowSetColumn( rParent.getMetaData(),
2806 this,
2808 rParent.m_xActiveConnection->getMetaData(),
2809 aDescription,
2810 sParseLabel,
2811 boost::bind(&ORowSetClone::getValue, this, _1));
2812 aColumns->get().push_back(pColumn);
2813 pColumn->setName(*pIter);
2814 aNames.push_back(*pIter);
2815 m_aDataColumns.push_back(pColumn);
2817 pColumn->setFastPropertyValue_NoBroadcast(PROPERTY_ID_ALIGN,xColumn->getPropertyValue(PROPERTY_ALIGN));
2818 sal_Int32 nFormatKey = 0;
2819 xColumn->getPropertyValue(PROPERTY_NUMBERFORMAT) >>= nFormatKey;
2820 if(!nFormatKey && xColumn.is() && m_xNumberFormatTypes.is())
2821 nFormatKey = ::dbtools::getDefaultNumberFormat(xColumn,m_xNumberFormatTypes,aLocale);
2822 pColumn->setFastPropertyValue_NoBroadcast(PROPERTY_ID_NUMBERFORMAT,makeAny(nFormatKey));
2823 pColumn->setFastPropertyValue_NoBroadcast(PROPERTY_ID_RELATIVEPOSITION,xColumn->getPropertyValue(PROPERTY_RELATIVEPOSITION));
2824 pColumn->setFastPropertyValue_NoBroadcast(PROPERTY_ID_WIDTH,xColumn->getPropertyValue(PROPERTY_WIDTH));
2825 pColumn->setFastPropertyValue_NoBroadcast(PROPERTY_ID_HIDDEN,xColumn->getPropertyValue(PROPERTY_HIDDEN));
2826 pColumn->setFastPropertyValue_NoBroadcast(PROPERTY_ID_CONTROLMODEL,xColumn->getPropertyValue(PROPERTY_CONTROLMODEL));
2827 pColumn->setFastPropertyValue_NoBroadcast(PROPERTY_ID_HELPTEXT,xColumn->getPropertyValue(PROPERTY_HELPTEXT));
2828 pColumn->setFastPropertyValue_NoBroadcast(PROPERTY_ID_CONTROLDEFAULT,xColumn->getPropertyValue(PROPERTY_CONTROLDEFAULT));
2832 Reference<XDatabaseMetaData> xMeta = rParent.m_xActiveConnection->getMetaData();
2833 m_pColumns = new ORowSetDataColumns(xMeta.is() && xMeta->supportsMixedCaseQuotedIdentifiers(),
2834 aColumns,*this,m_aMutex,aNames);
2836 sal_Int32 nRT = PropertyAttribute::READONLY | PropertyAttribute::TRANSIENT;
2838 // sdb.RowSet Properties
2839 registerMayBeVoidProperty(PROPERTY_ACTIVE_CONNECTION,PROPERTY_ID_ACTIVE_CONNECTION, PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, &rParent.m_aActiveConnection, cppu::UnoType<XConnection>::get());
2840 registerProperty(PROPERTY_RESULTSETCONCURRENCY, PROPERTY_ID_RESULTSETCONCURRENCY, PropertyAttribute::READONLY, &m_nResultSetConcurrency,::cppu::UnoType<sal_Int32>::get());
2841 registerProperty(PROPERTY_RESULTSETTYPE, PROPERTY_ID_RESULTSETTYPE, PropertyAttribute::READONLY, &m_nResultSetType, ::cppu::UnoType<sal_Int32>::get());
2842 registerProperty(PROPERTY_FETCHDIRECTION, PROPERTY_ID_FETCHDIRECTION, PropertyAttribute::TRANSIENT, &m_nFetchDirection, ::cppu::UnoType<sal_Int32>::get());
2843 registerProperty(PROPERTY_FETCHSIZE, PROPERTY_ID_FETCHSIZE, PropertyAttribute::TRANSIENT, &m_nFetchSize, ::cppu::UnoType<sal_Int32>::get());
2844 registerProperty(PROPERTY_ISBOOKMARKABLE, PROPERTY_ID_ISBOOKMARKABLE, nRT, &m_bIsBookmarkable, cppu::UnoType<bool>::get());
2847 ORowSetClone::~ORowSetClone()
2851 // com::sun::star::XTypeProvider
2852 Sequence< Type > ORowSetClone::getTypes() throw (RuntimeException, std::exception)
2854 return ::comphelper::concatSequences(OSubComponent::getTypes(),ORowSetBase::getTypes());
2857 // com::sun::star::XInterface
2858 Any ORowSetClone::queryInterface( const Type & rType ) throw (RuntimeException, std::exception)
2860 Any aRet = ORowSetBase::queryInterface(rType);
2861 if(!aRet.hasValue())
2862 aRet = OSubComponent::queryInterface(rType);
2863 return aRet;
2866 void ORowSetClone::acquire() throw()
2868 OSubComponent::acquire();
2871 void ORowSetClone::release() throw()
2873 OSubComponent::release();
2876 // XServiceInfo
2877 OUString ORowSetClone::getImplementationName( ) throw(RuntimeException, std::exception)
2879 return OUString("com.sun.star.sdb.ORowSetClone");
2882 sal_Bool ORowSetClone::supportsService( const OUString& _rServiceName ) throw (RuntimeException, std::exception)
2884 return cppu::supportsService(this, _rServiceName);
2887 Sequence< OUString > ORowSetClone::getSupportedServiceNames( ) throw (RuntimeException, std::exception)
2889 Sequence< OUString > aSNS( 2 );
2890 aSNS[0] = SERVICE_SDBC_RESULTSET;
2891 aSNS[1] = SERVICE_SDB_RESULTSET;
2892 return aSNS;
2895 // OComponentHelper
2896 void ORowSetClone::disposing()
2898 MutexGuard aGuard( m_aMutex );
2899 ORowSetBase::disposing();
2901 m_pParent = NULL;
2902 m_pMutex = &m_aMutex; // this must be done here because someone could hold a ref to us and try to do something
2903 OSubComponent::disposing();
2906 // XCloseable
2907 void ORowSetClone::close() throw( SQLException, RuntimeException, std::exception )
2910 MutexGuard aGuard( m_aMutex );
2911 if (OComponentHelper::rBHelper.bDisposed)
2912 throw DisposedException();
2914 dispose();
2917 // comphelper::OPropertyArrayUsageHelper
2918 ::cppu::IPropertyArrayHelper* ORowSetClone::createArrayHelper( ) const
2920 Sequence< Property > aProps;
2921 describeProperties(aProps);
2922 return new ::cppu::OPropertyArrayHelper(aProps);
2925 // cppu::OPropertySetHelper
2926 ::cppu::IPropertyArrayHelper& SAL_CALL ORowSetClone::getInfoHelper()
2928 typedef ::comphelper::OPropertyArrayUsageHelper<ORowSetClone> ORowSetClone_PROP;
2929 return *ORowSetClone_PROP::getArrayHelper();
2932 Sequence< sal_Int8 > ORowSetClone::getUnoTunnelImplementationId()
2934 static ::cppu::OImplementationId * pId = 0;
2935 if (! pId)
2937 ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
2938 if (! pId)
2940 static ::cppu::OImplementationId aId;
2941 pId = &aId;
2944 return pId->getImplementationId();
2947 // com::sun::star::XUnoTunnel
2948 sal_Int64 SAL_CALL ORowSetClone::getSomething( const Sequence< sal_Int8 >& rId ) throw(RuntimeException, std::exception)
2950 if (rId.getLength() == 16 && 0 == memcmp(getUnoTunnelImplementationId().getConstArray(), rId.getConstArray(), 16 ) )
2951 return reinterpret_cast<sal_Int64>(this);
2953 return 0;
2956 void SAL_CALL ORowSetClone::setFastPropertyValue_NoBroadcast(sal_Int32 nHandle,const Any& rValue) throw (Exception, std::exception)
2958 if ( nHandle == PROPERTY_ID_FETCHSIZE )
2960 if ( m_pParent )
2961 m_pParent->setFastPropertyValue_NoBroadcast( nHandle, rValue );
2964 OPropertyStateContainer::setFastPropertyValue_NoBroadcast(nHandle,rValue);
2967 void ORowSetClone::doCancelModification( )
2971 bool ORowSetClone::isModification( )
2973 return false;
2976 bool ORowSetClone::isModified( )
2978 return false;
2981 bool ORowSetClone::isNew( )
2983 return false;
2986 void SAL_CALL ORowSetClone::execute( ) throw(SQLException, RuntimeException, std::exception)
2988 throwFunctionNotSupportedSQLException( "RowSetClone::XRowSet::execute", *this );
2991 void SAL_CALL ORowSetClone::addRowSetListener( const Reference< XRowSetListener >& ) throw(RuntimeException, std::exception)
2993 throwFunctionNotSupportedRuntimeException( "RowSetClone::XRowSet", *this );
2996 void SAL_CALL ORowSetClone::removeRowSetListener( const Reference< XRowSetListener >& ) throw(RuntimeException, std::exception)
2998 throwFunctionNotSupportedRuntimeException( "RowSetClone::XRowSet", *this );
3001 } // dbaccess
3003 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */