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