Bug Summary

File:home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/datasource.cxx
Warning:line 145, column 5
Access to field 'm_refCount' results in a dereference of a null pointer

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name datasource.cxx -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -mframe-pointer=all -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/11.0.0 -D BOOST_ERROR_CODE_HEADER_ONLY -D BOOST_SYSTEM_NO_DEPRECATED -D CPPU_ENV=gcc3 -D LINUX -D OSL_DEBUG_LEVEL=1 -D SAL_LOG_INFO -D SAL_LOG_WARN -D UNIX -D UNX -D X86_64 -D _PTHREADS -D _REENTRANT -D OOO_DLLIMPLEMENTATION_DBA -D EXCEPTIONS_ON -D LIBO_INTERNAL_ONLY -I /home/maarten/src/libreoffice/core/external/boost/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/boost -I /home/maarten/src/libreoffice/core/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include/linux -I /home/maarten/src/libreoffice/core/config_host -I /home/maarten/src/libreoffice/core/dbaccess/inc -I /home/maarten/src/libreoffice/core/dbaccess/source/inc -I /home/maarten/src/libreoffice/core/dbaccess/source/core/inc -I /home/maarten/src/libreoffice/core/dbaccess/source/filter/hsqldb -I /home/maarten/src/libreoffice/core/workdir/YaccTarget/connectivity/source/parse -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/udkapi/normal -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/offapi/normal -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10 -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/x86_64-redhat-linux -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/11.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O0 -Wno-missing-braces -std=c++17 -fdeprecated-macro -fdebug-compilation-dir /home/maarten/src/libreoffice/core -ferror-limit 19 -fvisibility hidden -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcxx-exceptions -fexceptions -debug-info-kind=constructor -analyzer-output=html -faddrsig -o /home/maarten/tmp/wis/scan-build-libreoffice/output/report/2020-10-07-141433-9725-1 -x c++ /home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/datasource.cxx
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 "datasource.hxx"
21#include "commandcontainer.hxx"
22#include <stringconstants.hxx>
23#include <core_resource.hxx>
24#include <strings.hrc>
25#include "connection.hxx"
26#include "SharedConnection.hxx"
27#include "databasedocument.hxx"
28#include <OAuthenticationContinuation.hxx>
29
30#include <hsqlimport.hxx>
31#include <migrwarndlg.hxx>
32
33#include <com/sun/star/beans/NamedValue.hpp>
34#include <com/sun/star/beans/PropertyAttribute.hpp>
35#include <com/sun/star/beans/PropertyState.hpp>
36#include <com/sun/star/document/XDocumentSubStorageSupplier.hpp>
37#include <com/sun/star/lang/DisposedException.hpp>
38#include <com/sun/star/reflection/ProxyFactory.hpp>
39#include <com/sun/star/sdb/DatabaseContext.hpp>
40#include <com/sun/star/sdb/SQLContext.hpp>
41#include <com/sun/star/sdbc/ConnectionPool.hpp>
42#include <com/sun/star/sdbc/XDriverAccess.hpp>
43#include <com/sun/star/sdbc/XDriverManager.hpp>
44#include <com/sun/star/sdbc/DriverManager.hpp>
45#include <com/sun/star/ucb/AuthenticationRequest.hpp>
46#include <com/sun/star/ucb/XInteractionSupplyAuthentication.hpp>
47
48#include <cppuhelper/implbase.hxx>
49#include <comphelper/interaction.hxx>
50#include <comphelper/property.hxx>
51#include <comphelper/sequence.hxx>
52#include <comphelper/types.hxx>
53#include <cppuhelper/supportsservice.hxx>
54#include <connectivity/dbexception.hxx>
55#include <connectivity/dbtools.hxx>
56#include <cppuhelper/typeprovider.hxx>
57#include <tools/diagnose_ex.h>
58#include <osl/diagnose.h>
59#include <osl/process.h>
60#include <sal/log.hxx>
61#include <svtools/miscopt.hxx>
62#include <tools/urlobj.hxx>
63#include <unotools/sharedunocomponent.hxx>
64#include <rtl/digest.h>
65
66#include <algorithm>
67#include <iterator>
68#include <set>
69
70#include <config_firebird.h>
71
72using namespace ::com::sun::star::sdbc;
73using namespace ::com::sun::star::sdbcx;
74using namespace ::com::sun::star::sdb;
75using namespace ::com::sun::star::beans;
76using namespace ::com::sun::star::uno;
77using namespace ::com::sun::star::lang;
78using namespace ::com::sun::star::embed;
79using namespace ::com::sun::star::container;
80using namespace ::com::sun::star::util;
81using namespace ::com::sun::star::io;
82using namespace ::com::sun::star::task;
83using namespace ::com::sun::star::ucb;
84using namespace ::com::sun::star::frame;
85using namespace ::com::sun::star::reflection;
86using namespace ::cppu;
87using namespace ::osl;
88using namespace ::dbtools;
89using namespace ::comphelper;
90
91namespace dbaccess
92{
93
94namespace {
95
96/** helper class which implements a XFlushListener, and forwards all
97 notification events to another XFlushListener
98
99 The speciality is that the foreign XFlushListener instance, to which
100 the notifications are forwarded, is held weak.
101
102 Thus, the class can be used with XFlushable instance which hold
103 their listeners with a hard reference, if you simply do not *want*
104 to be held hard-ref-wise.
105*/
106class FlushNotificationAdapter : public ::cppu::WeakImplHelper< XFlushListener >
107{
108private:
109 WeakReference< XFlushable > m_aBroadcaster;
110 WeakReference< XFlushListener > m_aListener;
111
112public:
113 static void installAdapter( const Reference< XFlushable >& _rxBroadcaster, const Reference< XFlushListener >& _rxListener )
114 {
115 new FlushNotificationAdapter( _rxBroadcaster, _rxListener );
24
Calling constructor for 'FlushNotificationAdapter'
116 }
117
118protected:
119 FlushNotificationAdapter( const Reference< XFlushable >& _rxBroadcaster, const Reference< XFlushListener >& _rxListener );
120 virtual ~FlushNotificationAdapter() override;
121
122 void impl_dispose();
123
124protected:
125 // XFlushListener
126 virtual void SAL_CALL flushed( const css::lang::EventObject& rEvent ) override;
127 // XEventListener
128 virtual void SAL_CALL disposing( const css::lang::EventObject& Source ) override;
129};
130
131}
132
133FlushNotificationAdapter::FlushNotificationAdapter( const Reference< XFlushable >& _rxBroadcaster, const Reference< XFlushListener >& _rxListener )
134 :m_aBroadcaster( _rxBroadcaster )
135 ,m_aListener( _rxListener )
136{
137 OSL_ENSURE( _rxBroadcaster.is(), "FlushNotificationAdapter::FlushNotificationAdapter: invalid flushable!" )do { if (true && (!(_rxBroadcaster.is()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/datasource.cxx"
":" "137" ": "), "%s", "FlushNotificationAdapter::FlushNotificationAdapter: invalid flushable!"
); } } while (false)
;
25
Taking false branch
26
Loop condition is false. Exiting loop
138
139 osl_atomic_increment( &m_refCount )__sync_add_and_fetch((&m_refCount), 1);
140 {
141 if ( _rxBroadcaster.is() )
27
Taking true branch
142 _rxBroadcaster->addFlushListener( this );
143 }
144 osl_atomic_decrement( &m_refCount )__sync_sub_and_fetch((&m_refCount), 1);
145 OSL_ENSURE( m_refCount == 1, "FlushNotificationAdapter::FlushNotificationAdapter: broadcaster isn't holding by hard ref!?" )do { if (true && (!(m_refCount == 1))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/datasource.cxx"
":" "145" ": "), "%s", "FlushNotificationAdapter::FlushNotificationAdapter: broadcaster isn't holding by hard ref!?"
); } } while (false)
;
28
Access to field 'm_refCount' results in a dereference of a null pointer
146}
147
148FlushNotificationAdapter::~FlushNotificationAdapter()
149{
150}
151
152void FlushNotificationAdapter::impl_dispose()
153{
154 Reference< XFlushListener > xKeepAlive( this );
155
156 Reference< XFlushable > xFlushable( m_aBroadcaster );
157 if ( xFlushable.is() )
158 xFlushable->removeFlushListener( this );
159
160 m_aListener.clear();
161 m_aBroadcaster.clear();
162}
163
164void SAL_CALL FlushNotificationAdapter::flushed( const EventObject& rEvent )
165{
166 Reference< XFlushListener > xListener( m_aListener );
167 if ( xListener.is() )
168 xListener->flushed( rEvent );
169 else
170 impl_dispose();
171}
172
173void SAL_CALL FlushNotificationAdapter::disposing( const EventObject& Source )
174{
175 Reference< XFlushListener > xListener( m_aListener );
176 if ( xListener.is() )
177 xListener->disposing( Source );
178
179 impl_dispose();
180}
181
182OAuthenticationContinuation::OAuthenticationContinuation()
183 :m_bRememberPassword(true), // TODO: a meaningful default
184 m_bCanSetUserName(true)
185{
186}
187
188sal_Bool SAL_CALL OAuthenticationContinuation::canSetRealm( )
189{
190 return false;
191}
192
193void SAL_CALL OAuthenticationContinuation::setRealm( const OUString& /*Realm*/ )
194{
195 SAL_WARN("dbaccess","OAuthenticationContinuation::setRealm: not supported!")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "dbaccess")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "OAuthenticationContinuation::setRealm: not supported!"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("dbaccess"
), ("/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/datasource.cxx"
":" "195" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "OAuthenticationContinuation::setRealm: not supported!"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "OAuthenticationContinuation::setRealm: not supported!"
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("dbaccess"
), ("/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/datasource.cxx"
":" "195" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "OAuthenticationContinuation::setRealm: not supported!"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("dbaccess"
), ("/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/datasource.cxx"
":" "195" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "OAuthenticationContinuation::setRealm: not supported!"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "OAuthenticationContinuation::setRealm: not supported!"
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("dbaccess"
), ("/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/datasource.cxx"
":" "195" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
196}
197
198sal_Bool SAL_CALL OAuthenticationContinuation::canSetUserName( )
199{
200 // we always allow this, even if the database document is read-only. In this case,
201 // it's simply that the user cannot store the new user name.
202 return m_bCanSetUserName;
203}
204
205void SAL_CALL OAuthenticationContinuation::setUserName( const OUString& _rUser )
206{
207 m_sUser = _rUser;
208}
209
210sal_Bool SAL_CALL OAuthenticationContinuation::canSetPassword( )
211{
212 return true;
213}
214
215void SAL_CALL OAuthenticationContinuation::setPassword( const OUString& _rPassword )
216{
217 m_sPassword = _rPassword;
218}
219
220Sequence< RememberAuthentication > SAL_CALL OAuthenticationContinuation::getRememberPasswordModes( RememberAuthentication& _reDefault )
221{
222 Sequence< RememberAuthentication > aReturn(1);
223 _reDefault = aReturn[0] = RememberAuthentication_SESSION;
224 return aReturn;
225}
226
227void SAL_CALL OAuthenticationContinuation::setRememberPassword( RememberAuthentication _eRemember )
228{
229 m_bRememberPassword = (RememberAuthentication_NO != _eRemember);
230}
231
232sal_Bool SAL_CALL OAuthenticationContinuation::canSetAccount( )
233{
234 return false;
235}
236
237void SAL_CALL OAuthenticationContinuation::setAccount( const OUString& )
238{
239 SAL_WARN("dbaccess","OAuthenticationContinuation::setAccount: not supported!")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "dbaccess")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "OAuthenticationContinuation::setAccount: not supported!"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("dbaccess"
), ("/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/datasource.cxx"
":" "239" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "OAuthenticationContinuation::setAccount: not supported!"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "OAuthenticationContinuation::setAccount: not supported!"
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("dbaccess"
), ("/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/datasource.cxx"
":" "239" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "OAuthenticationContinuation::setAccount: not supported!"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("dbaccess"
), ("/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/datasource.cxx"
":" "239" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "OAuthenticationContinuation::setAccount: not supported!"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "OAuthenticationContinuation::setAccount: not supported!"
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("dbaccess"
), ("/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/datasource.cxx"
":" "239" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
240}
241
242Sequence< RememberAuthentication > SAL_CALL OAuthenticationContinuation::getRememberAccountModes( RememberAuthentication& _reDefault )
243{
244 Sequence < RememberAuthentication > aReturn(1);
245 aReturn[0] = RememberAuthentication_NO;
246 _reDefault = RememberAuthentication_NO;
247 return aReturn;
248}
249
250void SAL_CALL OAuthenticationContinuation::setRememberAccount( RememberAuthentication /*Remember*/ )
251{
252 SAL_WARN("dbaccess","OAuthenticationContinuation::setRememberAccount: not supported!")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "dbaccess")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "OAuthenticationContinuation::setRememberAccount: not supported!"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("dbaccess"
), ("/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/datasource.cxx"
":" "252" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "OAuthenticationContinuation::setRememberAccount: not supported!"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "OAuthenticationContinuation::setRememberAccount: not supported!"
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("dbaccess"
), ("/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/datasource.cxx"
":" "252" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "OAuthenticationContinuation::setRememberAccount: not supported!"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("dbaccess"
), ("/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/datasource.cxx"
":" "252" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "OAuthenticationContinuation::setRememberAccount: not supported!"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "OAuthenticationContinuation::setRememberAccount: not supported!"
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("dbaccess"
), ("/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/datasource.cxx"
":" "252" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
253}
254
255namespace {
256
257/** The class OSharedConnectionManager implements a structure to share connections.
258 It owns the master connections which will be disposed when the last connection proxy is gone.
259*/
260// need to hold the digest
261struct TDigestHolder
262{
263 sal_uInt8 m_pBuffer[RTL_DIGEST_LENGTH_SHA120];
264 TDigestHolder()
265 {
266 m_pBuffer[0] = 0;
267 }
268
269};
270
271}
272
273class OSharedConnectionManager : public ::cppu::WeakImplHelper< XEventListener >
274{
275
276 // contains the currently used master connections
277 struct TConnectionHolder
278 {
279 Reference< XConnection > xMasterConnection;
280 oslInterlockedCount nALiveCount;
281 };
282
283 // the less-compare functor, used for the stl::map
284 struct TDigestLess
285 {
286 bool operator() (const TDigestHolder& x, const TDigestHolder& y) const
287 {
288 sal_uInt32 i;
289 for(i=0;i < RTL_DIGEST_LENGTH_SHA120 && (x.m_pBuffer[i] >= y.m_pBuffer[i]); ++i)
290 ;
291 return i < RTL_DIGEST_LENGTH_SHA120;
292 }
293 };
294
295 typedef std::map< TDigestHolder,TConnectionHolder,TDigestLess> TConnectionMap; // holds the master connections
296 typedef std::map< Reference< XConnection >,TConnectionMap::iterator> TSharedConnectionMap;// holds the shared connections
297
298 ::osl::Mutex m_aMutex;
299 TConnectionMap m_aConnections; // remember the master connection in conjunction with the digest
300 TSharedConnectionMap m_aSharedConnection; // the shared connections with conjunction with an iterator into the connections map
301 Reference< XProxyFactory > m_xProxyFactory;
302
303protected:
304 virtual ~OSharedConnectionManager() override;
305
306public:
307 explicit OSharedConnectionManager(const Reference< XComponentContext >& _rxContext);
308
309 void SAL_CALL disposing( const css::lang::EventObject& Source ) override;
310 Reference<XConnection> getConnection( const OUString& url,
311 const OUString& user,
312 const OUString& password,
313 const Sequence< PropertyValue >& _aInfo,
314 ODatabaseSource* _pDataSource);
315 void addEventListener(const Reference<XConnection>& _rxConnection, TConnectionMap::iterator const & _rIter);
316};
317
318OSharedConnectionManager::OSharedConnectionManager(const Reference< XComponentContext >& _rxContext)
319{
320 m_xProxyFactory.set( ProxyFactory::create( _rxContext ) );
321}
322
323OSharedConnectionManager::~OSharedConnectionManager()
324{
325}
326
327void SAL_CALL OSharedConnectionManager::disposing( const css::lang::EventObject& Source )
328{
329 MutexGuard aGuard(m_aMutex);
330 Reference<XConnection> xConnection(Source.Source,UNO_QUERY);
331 TSharedConnectionMap::const_iterator aFind = m_aSharedConnection.find(xConnection);
332 if ( m_aSharedConnection.end() != aFind )
333 {
334 osl_atomic_decrement(&aFind->second->second.nALiveCount)__sync_sub_and_fetch((&aFind->second->second.nALiveCount
), 1)
;
335 if ( !aFind->second->second.nALiveCount )
336 {
337 ::comphelper::disposeComponent(aFind->second->second.xMasterConnection);
338 m_aConnections.erase(aFind->second);
339 }
340 m_aSharedConnection.erase(aFind);
341 }
342}
343
344Reference<XConnection> OSharedConnectionManager::getConnection( const OUString& url,
345 const OUString& user,
346 const OUString& password,
347 const Sequence< PropertyValue >& _aInfo,
348 ODatabaseSource* _pDataSource)
349{
350 MutexGuard aGuard(m_aMutex);
351 TConnectionMap::key_type nId;
352 Sequence< PropertyValue > aInfoCopy(_aInfo);
353 sal_Int32 nPos = aInfoCopy.getLength();
354 aInfoCopy.realloc( nPos + 2 );
355 aInfoCopy[nPos].Name = "TableFilter";
356 aInfoCopy[nPos++].Value <<= _pDataSource->m_pImpl->m_aTableFilter;
357 aInfoCopy[nPos].Name = "TableTypeFilter";
358 aInfoCopy[nPos++].Value <<= _pDataSource->m_pImpl->m_aTableTypeFilter;
359
360 OUString sUser = user;
361 OUString sPassword = password;
362 if ((sUser.isEmpty()) && (sPassword.isEmpty()) && (!_pDataSource->m_pImpl->m_sUser.isEmpty()))
363 { // ease the usage of this method. data source which are intended to have a user automatically
364 // fill in the user/password combination if the caller of this method does not specify otherwise
365 sUser = _pDataSource->m_pImpl->m_sUser;
366 if (!_pDataSource->m_pImpl->m_aPassword.isEmpty())
367 sPassword = _pDataSource->m_pImpl->m_aPassword;
368 }
369
370 ::connectivity::OConnectionWrapper::createUniqueId(url,aInfoCopy,nId.m_pBuffer,sUser,sPassword);
371 TConnectionMap::iterator aIter = m_aConnections.find(nId);
372
373 if ( m_aConnections.end() == aIter )
374 {
375 TConnectionHolder aHolder;
376 aHolder.nALiveCount = 0; // will be incremented by addListener
377 aHolder.xMasterConnection = _pDataSource->buildIsolatedConnection(user,password);
378 aIter = m_aConnections.emplace(nId,aHolder).first;
379 }
380
381 Reference<XConnection> xRet;
382 if ( aIter->second.xMasterConnection.is() )
383 {
384 Reference< XAggregation > xConProxy = m_xProxyFactory->createProxy(aIter->second.xMasterConnection.get());
385 xRet = new OSharedConnection(xConProxy);
386 m_aSharedConnection.emplace(xRet,aIter);
387 addEventListener(xRet,aIter);
388 }
389
390 return xRet;
391}
392
393void OSharedConnectionManager::addEventListener(const Reference<XConnection>& _rxConnection, TConnectionMap::iterator const & _rIter)
394{
395 Reference<XComponent> xComp(_rxConnection,UNO_QUERY);
396 xComp->addEventListener(this);
397 OSL_ENSURE( m_aConnections.end() != _rIter , "Iterator is end!")do { if (true && (!(m_aConnections.end() != _rIter)))
{ sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"
), ("/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/datasource.cxx"
":" "397" ": "), "%s", "Iterator is end!"); } } while (false
)
;
398 osl_atomic_increment(&_rIter->second.nALiveCount)__sync_add_and_fetch((&_rIter->second.nALiveCount), 1);
399}
400
401namespace
402{
403 Sequence< PropertyValue > lcl_filterDriverProperties( const Reference< XDriver >& _xDriver, const OUString& _sUrl,
404 const Sequence< PropertyValue >& _rDataSourceSettings, const AsciiPropertyValue* _pKnownSettings )
405 {
406 if ( _xDriver.is() )
407 {
408 Sequence< DriverPropertyInfo > aDriverInfo(_xDriver->getPropertyInfo(_sUrl,_rDataSourceSettings));
409
410 const PropertyValue* pDataSourceSetting = _rDataSourceSettings.getConstArray();
411 const PropertyValue* pEnd = pDataSourceSetting + _rDataSourceSettings.getLength();
412
413 std::vector< PropertyValue > aRet;
414
415 for ( ; pDataSourceSetting != pEnd ; ++pDataSourceSetting )
416 {
417 bool bAllowSetting = false;
418 const AsciiPropertyValue* pSetting = _pKnownSettings;
419 for ( ; pSetting->AsciiName; ++pSetting )
420 {
421 if ( pDataSourceSetting->Name.equalsAscii( pSetting->AsciiName ) )
422 { // the particular data source setting is known
423
424 const DriverPropertyInfo* pAllowedDriverSetting = aDriverInfo.getConstArray();
425 const DriverPropertyInfo* pDriverSettingsEnd = pAllowedDriverSetting + aDriverInfo.getLength();
426 for ( ; pAllowedDriverSetting != pDriverSettingsEnd; ++pAllowedDriverSetting )
427 {
428 if ( pAllowedDriverSetting->Name.equalsAscii( pSetting->AsciiName ) )
429 { // the driver also allows this setting
430 bAllowSetting = true;
431 break;
432 }
433 }
434 break;
435 }
436 }
437 if ( bAllowSetting || !pSetting->AsciiName )
438 { // if the driver allows this particular setting, or if the setting is completely unknown,
439 // we pass it to the driver
440 aRet.push_back( *pDataSourceSetting );
441 }
442 }
443 if ( !aRet.empty() )
444 return comphelper::containerToSequence(aRet);
445 }
446 return Sequence< PropertyValue >();
447 }
448
449 typedef std::map< OUString, sal_Int32 > PropertyAttributeCache;
450
451 struct IsDefaultAndNotRemoveable
452 {
453 private:
454 const PropertyAttributeCache& m_rAttribs;
455
456 public:
457 explicit IsDefaultAndNotRemoveable( const PropertyAttributeCache& _rAttribs ) : m_rAttribs( _rAttribs ) { }
458
459 bool operator()( const PropertyValue& _rProp )
460 {
461 if ( _rProp.State != PropertyState_DEFAULT_VALUE )
462 return false;
463
464 bool bRemoveable = true;
465
466 PropertyAttributeCache::const_iterator pos = m_rAttribs.find( _rProp.Name );
467 OSL_ENSURE( pos != m_rAttribs.end(), "IsDefaultAndNotRemoveable: illegal property name!" )do { if (true && (!(pos != m_rAttribs.end()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/datasource.cxx"
":" "467" ": "), "%s", "IsDefaultAndNotRemoveable: illegal property name!"
); } } while (false)
;
468 if ( pos != m_rAttribs.end() )
469 bRemoveable = ( ( pos->second & PropertyAttribute::REMOVABLE ) != 0 );
470
471 return !bRemoveable;
472 }
473 };
474}
475
476
477ODatabaseSource::ODatabaseSource(const ::rtl::Reference<ODatabaseModelImpl>& _pImpl)
478 :ModelDependentComponent( _pImpl )
479 ,ODatabaseSource_Base( getMutex() )
480 ,OPropertySetHelper( ODatabaseSource_Base::rBHelper )
481 , m_Bookmarks(*this, getMutex())
482 ,m_aFlushListeners( getMutex() )
483{
484 // some kind of default
485 SAL_INFO("dbaccess", "DS: ctor: " << std::hex << this << ": " << std::hex << m_pImpl.get() )do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "dbaccess")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "DS: ctor: " <<
std::hex << this << ": " << std::hex <<
m_pImpl.get()) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("dbaccess"), ("/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/datasource.cxx"
":" "485" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "DS: ctor: " << std::hex <<
this << ": " << std::hex << m_pImpl.get())
, 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "DS: ctor: " << std::hex << this <<
": " << std::hex << m_pImpl.get(); ::sal::detail
::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("dbaccess"), ("/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/datasource.cxx"
":" "485" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "DS: ctor: " << std::hex << this <<
": " << std::hex << m_pImpl.get()) == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("dbaccess"), ("/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/datasource.cxx"
":" "485" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "DS: ctor: " << std::hex <<
this << ": " << std::hex << m_pImpl.get())
, 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "DS: ctor: " << std::hex << this <<
": " << std::hex << m_pImpl.get(); ::sal::detail
::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("dbaccess"), ("/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/datasource.cxx"
":" "485" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
486}
487
488ODatabaseSource::~ODatabaseSource()
489{
490 SAL_INFO("dbaccess", "DS: dtor: " << std::hex << this << ": " << std::hex << m_pImpl.get() )do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "dbaccess")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "DS: dtor: " <<
std::hex << this << ": " << std::hex <<
m_pImpl.get()) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("dbaccess"), ("/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/datasource.cxx"
":" "490" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "DS: dtor: " << std::hex <<
this << ": " << std::hex << m_pImpl.get())
, 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "DS: dtor: " << std::hex << this <<
": " << std::hex << m_pImpl.get(); ::sal::detail
::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("dbaccess"), ("/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/datasource.cxx"
":" "490" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "DS: dtor: " << std::hex << this <<
": " << std::hex << m_pImpl.get()) == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("dbaccess"), ("/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/datasource.cxx"
":" "490" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "DS: dtor: " << std::hex <<
this << ": " << std::hex << m_pImpl.get())
, 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "DS: dtor: " << std::hex << this <<
": " << std::hex << m_pImpl.get(); ::sal::detail
::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("dbaccess"), ("/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/datasource.cxx"
":" "490" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
491 if ( !ODatabaseSource_Base::rBHelper.bInDispose && !ODatabaseSource_Base::rBHelper.bDisposed )
492 {
493 acquire();
494 dispose();
495 }
496}
497
498void ODatabaseSource::setName( const Reference< XDocumentDataSource >& _rxDocument, const OUString& _rNewName, DBContextAccess )
499{
500 ODatabaseSource& rModelImpl = dynamic_cast< ODatabaseSource& >( *_rxDocument );
501
502 SolarMutexGuard g;
503 if ( rModelImpl.m_pImpl.is() )
504 rModelImpl.m_pImpl->m_sName = _rNewName;
505}
506
507// css::lang::XTypeProvider
508Sequence< Type > ODatabaseSource::getTypes()
509{
510 OTypeCollection aPropertyHelperTypes( cppu::UnoType<XFastPropertySet>::get(),
511 cppu::UnoType<XPropertySet>::get(),
512 cppu::UnoType<XMultiPropertySet>::get());
513
514 return ::comphelper::concatSequences(
515 ODatabaseSource_Base::getTypes(),
516 aPropertyHelperTypes.getTypes()
517 );
518}
519
520Sequence< sal_Int8 > ODatabaseSource::getImplementationId()
521{
522 return css::uno::Sequence<sal_Int8>();
523}
524
525// css::uno::XInterface
526Any ODatabaseSource::queryInterface( const Type & rType )
527{
528 Any aIface = ODatabaseSource_Base::queryInterface( rType );
529 if ( !aIface.hasValue() )
530 aIface = ::cppu::OPropertySetHelper::queryInterface( rType );
531 return aIface;
532}
533
534void ODatabaseSource::acquire() throw ()
535{
536 ODatabaseSource_Base::acquire();
537}
538
539void ODatabaseSource::release() throw ()
540{
541 ODatabaseSource_Base::release();
542}
543
544void SAL_CALL ODatabaseSource::disposing( const css::lang::EventObject& Source )
545{
546 if ( m_pImpl.is() )
547 m_pImpl->disposing(Source);
548}
549
550// XServiceInfo
551OUString ODatabaseSource::getImplementationName( )
552{
553 return "com.sun.star.comp.dba.ODatabaseSource";
554}
555
556Sequence< OUString > ODatabaseSource::getSupportedServiceNames( )
557{
558 return { SERVICE_SDB_DATASOURCE"com.sun.star.sdb.DataSource", "com.sun.star.sdb.DocumentDataSource" };
559}
560
561sal_Bool ODatabaseSource::supportsService( const OUString& _rServiceName )
562{
563 return cppu::supportsService(this, _rServiceName);
564}
565
566// OComponentHelper
567void ODatabaseSource::disposing()
568{
569 SAL_INFO("dbaccess", "DS: disp: " << std::hex << this << ", " << std::hex << m_pImpl.get() )do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "dbaccess")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "DS: disp: " <<
std::hex << this << ", " << std::hex <<
m_pImpl.get()) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("dbaccess"), ("/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/datasource.cxx"
":" "569" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "DS: disp: " << std::hex <<
this << ", " << std::hex << m_pImpl.get())
, 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "DS: disp: " << std::hex << this <<
", " << std::hex << m_pImpl.get(); ::sal::detail
::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("dbaccess"), ("/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/datasource.cxx"
":" "569" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "DS: disp: " << std::hex << this <<
", " << std::hex << m_pImpl.get()) == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("dbaccess"), ("/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/datasource.cxx"
":" "569" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "DS: disp: " << std::hex <<
this << ", " << std::hex << m_pImpl.get())
, 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "DS: disp: " << std::hex << this <<
", " << std::hex << m_pImpl.get(); ::sal::detail
::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("dbaccess"), ("/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/datasource.cxx"
":" "569" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
570 ODatabaseSource_Base::WeakComponentImplHelperBase::disposing();
571 OPropertySetHelper::disposing();
572
573 EventObject aDisposeEvent(static_cast<XWeak*>(this));
574 m_aFlushListeners.disposeAndClear( aDisposeEvent );
575
576 ODatabaseDocument::clearObjectContainer(m_pImpl->m_xCommandDefinitions);
577 ODatabaseDocument::clearObjectContainer(m_pImpl->m_xTableDefinitions);
578 m_pImpl.clear();
579}
580
581weld::Window* ODatabaseModelImpl::GetFrameWeld()
582{
583 if (m_xDialogParent.is())
584 return Application::GetFrameWeld(m_xDialogParent);
585
586 Reference<XModel> xModel = getModel_noCreate();
587 if (!xModel.is())
588 return nullptr;
589 Reference<XController> xController(xModel->getCurrentController());
590 if (!xController.is())
591 return nullptr;
592 Reference<XFrame> xFrame(xController->getFrame());
593 if (!xFrame.is())
594 return nullptr;
595 Reference<css::awt::XWindow> xWindow(xFrame->getContainerWindow());
596 return Application::GetFrameWeld(xWindow);
597}
598
599Reference< XConnection > ODatabaseSource::buildLowLevelConnection(const OUString& _rUid, const OUString& _rPwd)
600{
601 Reference< XConnection > xReturn;
602
603 Reference< XDriverManager > xManager;
604
605#if ENABLE_FIREBIRD_SDBC1
606 bool bIgnoreMigration = false;
607 bool bNeedMigration = false;
608 Reference< XModel > xModel = m_pImpl->getModel_noCreate();
609 if ( xModel)
5
Taking false branch
610 {
611 //See ODbTypeWizDialogSetup::SaveDatabaseDocument
612 ::comphelper::NamedValueCollection aArgs( xModel->getArgs() );
613 aArgs.get("IgnoreFirebirdMigration") >>= bIgnoreMigration;
614 }
615 else
616 {
617 //ignore when we don't have a model. E.g. Mailmerge, data sources, fields...
618 bIgnoreMigration = true;
619 }
620 SvtMiscOptions aMiscOptions;
621
622 if (!aMiscOptions.IsExperimentalMode())
6
Assuming the condition is false
7
Taking false branch
623 bIgnoreMigration = true;
624
625 if(!bIgnoreMigration
7.1
'bIgnoreMigration' is true
&& m_pImpl->m_sConnectURL == "sdbc:embedded:hsqldb")
626 {
627 Reference<XStorage> const xRootStorage = m_pImpl->getOrCreateRootStorage();
628 OUString sMigrEnvVal;
629 osl_getEnvironment(OUString("DBACCESS_HSQL_MIGRATION").pData,
630 &sMigrEnvVal.pData);
631 if(!sMigrEnvVal.isEmpty())
632 bNeedMigration = true;
633 else
634 {
635 Reference<XPropertySet> const xPropSet(xRootStorage, UNO_QUERY_THROW);
636 sal_Int32 nOpenMode(0);
637 if ((xPropSet->getPropertyValue("OpenMode") >>= nOpenMode)
638 && (nOpenMode & css::embed::ElementModes::WRITE)
639 && (!Application::IsHeadlessModeEnabled()))
640 {
641 MigrationWarnDialog aWarnDlg(m_pImpl->GetFrameWeld());
642 bNeedMigration = aWarnDlg.run() == RET_OK;
643 }
644 }
645 if (bNeedMigration)
646 {
647 // back up content xml file if migration was successful
648 constexpr char BACKUP_XML_NAME[] = "content_before_migration.xml";
649 try
650 {
651 if(xRootStorage->isStreamElement(BACKUP_XML_NAME))
652 xRootStorage->removeElement(BACKUP_XML_NAME);
653 }
654 catch (NoSuchElementException&)
655 {
656 SAL_INFO("dbaccess", "No file content_before_migration.xml found" )do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "dbaccess")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "No file content_before_migration.xml found"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("dbaccess"
), ("/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/datasource.cxx"
":" "656" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "No file content_before_migration.xml found"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "No file content_before_migration.xml found"; ::sal
::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("dbaccess"), (
"/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/datasource.cxx"
":" "656" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "No file content_before_migration.xml found") == 1
) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("dbaccess"
), ("/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/datasource.cxx"
":" "656" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "No file content_before_migration.xml found"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "No file content_before_migration.xml found"; ::sal
::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("dbaccess"), (
"/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/datasource.cxx"
":" "656" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
657 }
658 xRootStorage->copyElementTo("content.xml", xRootStorage,
659 BACKUP_XML_NAME);
660
661 m_pImpl->m_sConnectURL = "sdbc:embedded:firebird";
662 }
663 }
664#endif
665
666 try {
667 xManager.set( ConnectionPool::create( m_pImpl->m_aContext ), UNO_QUERY_THROW );
668 } catch( const Exception& ) { }
669 if ( !xManager.is() )
8
Taking false branch
670 // no connection pool installed, fall back to driver manager
671 xManager.set( DriverManager::create(m_pImpl->m_aContext ), UNO_QUERY_THROW );
672
673 OUString sUser(_rUid);
674 OUString sPwd(_rPwd);
675 if ((sUser.isEmpty()) && (sPwd.isEmpty()) && (!m_pImpl->m_sUser.isEmpty()))
9
Taking true branch
676 { // ease the usage of this method. data source which are intended to have a user automatically
677 // fill in the user/password combination if the caller of this method does not specify otherwise
678 sUser = m_pImpl->m_sUser;
679 if (!m_pImpl->m_aPassword.isEmpty())
10
Taking true branch
680 sPwd = m_pImpl->m_aPassword;
681 }
682
683 const char* pExceptionMessageId = RID_STR_COULDNOTCONNECT_UNSPECIFIEDreinterpret_cast<char const *>("RID_STR_COULDNOTCONNECT_UNSPECIFIED"
"\004" u8"The connection to the external data source could not be established. An unknown error occurred. The driver is probably defective."
)
;
684 if (xManager.is())
11
Taking true branch
685 {
686 sal_Int32 nAdditionalArgs(0);
687 if (!sUser.isEmpty()) ++nAdditionalArgs;
12
Taking false branch
688 if (!sPwd.isEmpty()) ++nAdditionalArgs;
13
Taking false branch
689
690 Sequence< PropertyValue > aUserPwd(nAdditionalArgs);
691 sal_Int32 nArgPos = 0;
692 if (!sUser.isEmpty())
14
Taking false branch
693 {
694 aUserPwd[ nArgPos ].Name = "user";
695 aUserPwd[ nArgPos ].Value <<= sUser;
696 ++nArgPos;
697 }
698 if (!sPwd.isEmpty())
15
Taking false branch
699 {
700 aUserPwd[ nArgPos ].Name = "password";
701 aUserPwd[ nArgPos ].Value <<= sPwd;
702 }
703 Reference< XDriver > xDriver;
704 try
705 {
706
707 // choose driver
708 Reference< XDriverAccess > xAccessDrivers( xManager, UNO_QUERY );
709 if ( xAccessDrivers.is() )
16
Taking true branch
710 xDriver = xAccessDrivers->getDriverByURL( m_pImpl->m_sConnectURL );
711 }
712 catch( const Exception& )
713 {
714 TOOLS_WARN_EXCEPTION("dbaccess", "ODatabaseSource::buildLowLevelConnection: got a strange exception while analyzing the error" )do { css::uno::Any tools_warn_exception( DbgGetCaughtException
() ); do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "dbaccess")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "ODatabaseSource::buildLowLevelConnection: got a strange exception while analyzing the error"
<< " " << exceptionToString(tools_warn_exception
)) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), (
"dbaccess"), ("/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/datasource.cxx"
":" "714" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "ODatabaseSource::buildLowLevelConnection: got a strange exception while analyzing the error"
<< " " << exceptionToString(tools_warn_exception
)), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "ODatabaseSource::buildLowLevelConnection: got a strange exception while analyzing the error"
<< " " << exceptionToString(tools_warn_exception
); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("dbaccess"
), ("/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/datasource.cxx"
":" "714" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "ODatabaseSource::buildLowLevelConnection: got a strange exception while analyzing the error"
<< " " << exceptionToString(tools_warn_exception
)) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), (
"dbaccess"), ("/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/datasource.cxx"
":" "714" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "ODatabaseSource::buildLowLevelConnection: got a strange exception while analyzing the error"
<< " " << exceptionToString(tools_warn_exception
)), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "ODatabaseSource::buildLowLevelConnection: got a strange exception while analyzing the error"
<< " " << exceptionToString(tools_warn_exception
); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("dbaccess"
), ("/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/datasource.cxx"
":" "714" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false); } while (false)
;
715 }
716 if ( !xDriver.is() || !xDriver->acceptsURL( m_pImpl->m_sConnectURL ) )
17
Assuming the condition is false
18
Taking false branch
717 {
718 // Nowadays, it's allowed for a driver to be registered for a given URL, but actually not to accept it.
719 // This is because registration nowadays happens at compile time (by adding respective configuration data),
720 // but acceptance is decided at runtime.
721 pExceptionMessageId = RID_STR_COULDNOTCONNECT_NODRIVERreinterpret_cast<char const *>("RID_STR_COULDNOTCONNECT_NODRIVER"
"\004" u8"The connection to the external data source could not be established. No SDBC driver was found for the URL '$name$'."
)
;
722 }
723 else
724 {
725 Sequence< PropertyValue > aDriverInfo = lcl_filterDriverProperties(
726 xDriver,
727 m_pImpl->m_sConnectURL,
728 m_pImpl->m_xSettings->getPropertyValues(),
729 dbaccess::ODatabaseModelImpl::getDefaultDataSourceSettings()
730 );
731
732 if ( m_pImpl->isEmbeddedDatabase() )
19
Taking false branch
733 {
734 sal_Int32 nCount = aDriverInfo.getLength();
735 aDriverInfo.realloc(nCount + 3 );
736
737 aDriverInfo[nCount].Name = "URL";
738 aDriverInfo[nCount++].Value <<= m_pImpl->getURL();
739
740 aDriverInfo[nCount].Name = "Storage";
741 Reference< css::document::XDocumentSubStorageSupplier> xDocSup( m_pImpl->getDocumentSubStorageSupplier() );
742 aDriverInfo[nCount++].Value <<= xDocSup->getDocumentSubStorage("database",ElementModes::READWRITE);
743
744 aDriverInfo[nCount].Name = "Document";
745 aDriverInfo[nCount++].Value <<= getDatabaseDocument();
746 }
747 if (nAdditionalArgs
19.1
'nAdditionalArgs' is 0
)
20
Taking false branch
748 xReturn = xManager->getConnectionWithInfo(m_pImpl->m_sConnectURL, ::comphelper::concatSequences(aUserPwd,aDriverInfo));
749 else
750 xReturn = xManager->getConnectionWithInfo(m_pImpl->m_sConnectURL,aDriverInfo);
751
752 if ( m_pImpl->isEmbeddedDatabase() )
21
Taking true branch
753 {
754 // see ODatabaseSource::flushed for comment on why we register as FlushListener
755 // at the connection
756 Reference< XFlushable > xFlushable( xReturn, UNO_QUERY );
757 if ( xFlushable.is() )
22
Taking true branch
758 FlushNotificationAdapter::installAdapter( xFlushable, this );
23
Calling 'FlushNotificationAdapter::installAdapter'
759 }
760 }
761 }
762 else
763 pExceptionMessageId = RID_STR_COULDNOTLOAD_MANAGERreinterpret_cast<char const *>("RID_STR_COULDNOTLOAD_MANAGER"
"\004" u8"The connection to the external data source could not be established. The SDBC driver manager could not be loaded."
)
;
764
765 if ( !xReturn.is() )
766 {
767 OUString sMessage = DBA_RES(pExceptionMessageId)::dbaccess::ResourceManager::loadString( pExceptionMessageId )
768 .replaceAll("$name$", m_pImpl->m_sConnectURL);
769
770 SQLContext aContext;
771 aContext.Message = DBA_RES(RID_STR_CONNECTION_REQUEST)::dbaccess::ResourceManager::loadString( reinterpret_cast<
char const *>("RID_STR_CONNECTION_REQUEST" "\004" u8"A connection for the following URL was requested \"$name$\"."
) )
.
772 replaceFirst("$name$", m_pImpl->m_sConnectURL);
773
774 throwGenericSQLException( sMessage, static_cast< XDataSource* >( this ), makeAny( aContext ) );
775 }
776
777#if ENABLE_FIREBIRD_SDBC1
778 if( bNeedMigration )
779 {
780 Reference< css::document::XDocumentSubStorageSupplier> xDocSup(
781 m_pImpl->getDocumentSubStorageSupplier() );
782 dbahsql::HsqlImporter importer(xReturn,
783 xDocSup->getDocumentSubStorage("database",ElementModes::READWRITE) );
784 importer.importHsqlDatabase(m_pImpl->GetFrameWeld());
785 }
786#endif
787
788 return xReturn;
789}
790
791// OPropertySetHelper
792Reference< XPropertySetInfo > ODatabaseSource::getPropertySetInfo()
793{
794 return createPropertySetInfo( getInfoHelper() ) ;
795}
796
797// comphelper::OPropertyArrayUsageHelper
798::cppu::IPropertyArrayHelper* ODatabaseSource::createArrayHelper( ) const
799{
800 BEGIN_PROPERTY_HELPER(13)css::uno::Sequence< css::beans::Property> aDescriptor(13
); css::beans::Property* pDesc = aDescriptor.getArray(); sal_Int32
nPos = 0;
801 DECL_PROP1(INFO, Sequence< PropertyValue >, BOUND)pDesc[nPos++] = css::beans::Property("Info", 4, cppu::UnoType
<Sequence< PropertyValue > >::get(), css::beans::
PropertyAttribute::BOUND)
;
802 DECL_PROP1_BOOL(ISPASSWORDREQUIRED, BOUND)pDesc[nPos++] = css::beans::Property("IsPasswordRequired", 5,
cppu::UnoType<bool>::get(), css::beans::PropertyAttribute
::BOUND)
;
803 DECL_PROP1_BOOL(ISREADONLY, READONLY)pDesc[nPos++] = css::beans::Property("IsReadOnly", 37, cppu::
UnoType<bool>::get(), css::beans::PropertyAttribute::READONLY
)
;
804 DECL_PROP1(LAYOUTINFORMATION, Sequence< PropertyValue >, BOUND)pDesc[nPos++] = css::beans::Property("LayoutInformation", 93,
cppu::UnoType<Sequence< PropertyValue > >::get()
, css::beans::PropertyAttribute::BOUND)
;
805 DECL_PROP1(NAME, OUString, READONLY)pDesc[nPos++] = css::beans::Property("Name", 7, cppu::UnoType
<OUString>::get(), css::beans::PropertyAttribute::READONLY
)
;
806 DECL_PROP2_IFACE(NUMBERFORMATSSUPPLIER, XNumberFormatsSupplier, READONLY, TRANSIENT)pDesc[nPos++] = css::beans::Property("NumberFormatsSupplier",
48, cppu::UnoType<XNumberFormatsSupplier>::get(), css::
beans::PropertyAttribute::READONLY | css::beans::PropertyAttribute
::TRANSIENT)
;
807 DECL_PROP1(PASSWORD, OUString, TRANSIENT)pDesc[nPos++] = css::beans::Property("Password", 54, cppu::UnoType
<OUString>::get(), css::beans::PropertyAttribute::TRANSIENT
)
;
808 DECL_PROP2_IFACE(SETTINGS, XPropertySet, BOUND, READONLY)pDesc[nPos++] = css::beans::Property("Settings", 129, cppu::UnoType
<XPropertySet>::get(), css::beans::PropertyAttribute::BOUND
| css::beans::PropertyAttribute::READONLY)
;
809 DECL_PROP1_BOOL(SUPPRESSVERSIONCL, BOUND)pDesc[nPos++] = css::beans::Property("SuppressVersionColumns"
, 92, cppu::UnoType<bool>::get(), css::beans::PropertyAttribute
::BOUND)
;
810 DECL_PROP1(TABLEFILTER, Sequence< OUString >,BOUND)pDesc[nPos++] = css::beans::Property("TableFilter", 6, cppu::
UnoType<Sequence< OUString > >::get(), css::beans
::PropertyAttribute::BOUND)
;
811 DECL_PROP1(TABLETYPEFILTER, Sequence< OUString >,BOUND)pDesc[nPos++] = css::beans::Property("TableTypeFilter", 70, cppu
::UnoType<Sequence< OUString > >::get(), css::beans
::PropertyAttribute::BOUND)
;
812 DECL_PROP1(URL, OUString, BOUND)pDesc[nPos++] = css::beans::Property("URL", 2, cppu::UnoType<
OUString>::get(), css::beans::PropertyAttribute::BOUND)
;
813 DECL_PROP1(USER, OUString, BOUND)pDesc[nPos++] = css::beans::Property("User", 53, cppu::UnoType
<OUString>::get(), css::beans::PropertyAttribute::BOUND
)
;
814 END_PROPERTY_HELPER()do { if (true && (!(nPos == aDescriptor.getLength()))
) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"
), ("/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/datasource.cxx"
":" "814" ": "), "%s", "forgot to adjust the count ?"); } } while
(false); return new ::cppu::OPropertyArrayHelper(aDescriptor
);
;
815}
816
817// cppu::OPropertySetHelper
818::cppu::IPropertyArrayHelper& ODatabaseSource::getInfoHelper()
819{
820 return *getArrayHelper();
821}
822
823sal_Bool ODatabaseSource::convertFastPropertyValue(Any & rConvertedValue, Any & rOldValue, sal_Int32 nHandle, const Any& rValue )
824{
825 bool bModified(false);
826 if ( m_pImpl.is() )
827 {
828 switch (nHandle)
829 {
830 case PROPERTY_ID_TABLEFILTER6:
831 bModified = ::comphelper::tryPropertyValue(rConvertedValue, rOldValue, rValue, m_pImpl->m_aTableFilter);
832 break;
833 case PROPERTY_ID_TABLETYPEFILTER70:
834 bModified = ::comphelper::tryPropertyValue(rConvertedValue, rOldValue, rValue, m_pImpl->m_aTableTypeFilter);
835 break;
836 case PROPERTY_ID_USER53:
837 bModified = ::comphelper::tryPropertyValue(rConvertedValue, rOldValue, rValue, m_pImpl->m_sUser);
838 break;
839 case PROPERTY_ID_PASSWORD54:
840 bModified = ::comphelper::tryPropertyValue(rConvertedValue, rOldValue, rValue, m_pImpl->m_aPassword);
841 break;
842 case PROPERTY_ID_ISPASSWORDREQUIRED5:
843 bModified = ::comphelper::tryPropertyValue(rConvertedValue, rOldValue, rValue, m_pImpl->m_bPasswordRequired);
844 break;
845 case PROPERTY_ID_SUPPRESSVERSIONCL92:
846 bModified = ::comphelper::tryPropertyValue(rConvertedValue, rOldValue, rValue, m_pImpl->m_bSuppressVersionColumns);
847 break;
848 case PROPERTY_ID_LAYOUTINFORMATION93:
849 bModified = ::comphelper::tryPropertyValue(rConvertedValue, rOldValue, rValue, m_pImpl->m_aLayoutInformation);
850 break;
851 case PROPERTY_ID_URL2:
852 {
853 bModified = ::comphelper::tryPropertyValue(rConvertedValue, rOldValue, rValue, m_pImpl->m_sConnectURL);
854 } break;
855 case PROPERTY_ID_INFO4:
856 {
857 Sequence<PropertyValue> aValues;
858 if (!(rValue >>= aValues))
859 throw IllegalArgumentException();
860
861 for ( auto const & checkName : std::as_const(aValues) )
862 {
863 if ( checkName.Name.isEmpty() )
864 throw IllegalArgumentException();
865 }
866
867 Sequence< PropertyValue > aSettings = m_pImpl->m_xSettings->getPropertyValues();
868 bModified = aSettings.getLength() != aValues.getLength();
869 if ( !bModified )
870 {
871 const PropertyValue* pInfoIter = aSettings.getConstArray();
872 const PropertyValue* checkValue = aValues.getConstArray();
873 for ( ;!bModified && checkValue != aValues.end() ; ++checkValue,++pInfoIter)
874 {
875 bModified = checkValue->Name != pInfoIter->Name;
876 if ( !bModified )
877 {
878 bModified = checkValue->Value != pInfoIter->Value;
879 }
880 }
881 }
882
883 rConvertedValue = rValue;
884 rOldValue <<= aSettings;
885 }
886 break;
887 default:
888 SAL_WARN("dbaccess", "ODatabaseSource::convertFastPropertyValue: unknown or readonly Property!" )do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "dbaccess")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "ODatabaseSource::convertFastPropertyValue: unknown or readonly Property!"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("dbaccess"
), ("/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/datasource.cxx"
":" "888" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "ODatabaseSource::convertFastPropertyValue: unknown or readonly Property!"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "ODatabaseSource::convertFastPropertyValue: unknown or readonly Property!"
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("dbaccess"
), ("/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/datasource.cxx"
":" "888" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "ODatabaseSource::convertFastPropertyValue: unknown or readonly Property!"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("dbaccess"
), ("/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/datasource.cxx"
":" "888" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "ODatabaseSource::convertFastPropertyValue: unknown or readonly Property!"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "ODatabaseSource::convertFastPropertyValue: unknown or readonly Property!"
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("dbaccess"
), ("/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/datasource.cxx"
":" "888" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
889 }
890 }
891 return bModified;
892}
893
894namespace
895{
896 struct SelectPropertyName
897 {
898 public:
899 const OUString& operator()( const PropertyValue& _lhs )
900 {
901 return _lhs.Name;
902 }
903 };
904
905 /** sets a new set of property values for a given property bag instance
906
907 The method takes a property bag, and a sequence of property values to set for this bag.
908 Upon return, every property which is not part of the given sequence is
909 <ul><li>removed from the bag, if it's a removable property</li>
910 <li><em>or</em>reset to its default value, if it's not a removable property</li>
911 </ul>.
912
913 @param _rxPropertyBag
914 the property bag to operate on
915 @param _rAllNewPropertyValues
916 the new property values to set for the bag
917 */
918 void lcl_setPropertyValues_resetOrRemoveOther( const Reference< XPropertyBag >& _rxPropertyBag, const Sequence< PropertyValue >& _rAllNewPropertyValues )
919 {
920 // sequences are ugly to operate on
921 std::set<OUString> aToBeSetPropertyNames;
922 std::transform(
923 _rAllNewPropertyValues.begin(),
924 _rAllNewPropertyValues.end(),
925 std::inserter( aToBeSetPropertyNames, aToBeSetPropertyNames.end() ),
926 SelectPropertyName()
927 );
928
929 try
930 {
931 // obtain all properties currently known at the bag
932 Reference< XPropertySetInfo > xPSI( _rxPropertyBag->getPropertySetInfo(), UNO_SET_THROW );
933 const Sequence< Property > aAllExistentProperties( xPSI->getProperties() );
934
935 Reference< XPropertyState > xPropertyState( _rxPropertyBag, UNO_QUERY_THROW );
936
937 // loop through them, and reset resp. default properties which are not to be set
938 for ( auto const & existentProperty : aAllExistentProperties )
939 {
940 if ( aToBeSetPropertyNames.find( existentProperty.Name ) != aToBeSetPropertyNames.end() )
941 continue;
942
943 // this property is not to be set, but currently exists in the bag.
944 // -> Remove it, or reset it to the default.
945 if ( ( existentProperty.Attributes & PropertyAttribute::REMOVABLE ) != 0 )
946 _rxPropertyBag->removeProperty( existentProperty.Name );
947 else
948 xPropertyState->setPropertyToDefault( existentProperty.Name );
949 }
950
951 // finally, set the new property values
952 _rxPropertyBag->setPropertyValues( _rAllNewPropertyValues );
953 }
954 catch( const Exception& )
955 {
956 DBG_UNHANDLED_EXCEPTION("dbaccess")DbgUnhandledException( DbgGetCaughtException(), __func__, "/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/datasource.cxx"
":" "956" ": ", "dbaccess" );
;
957 }
958 }
959}
960
961void ODatabaseSource::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const Any& rValue )
962{
963 if ( !m_pImpl.is() )
964 return;
965
966 switch(nHandle)
967 {
968 case PROPERTY_ID_TABLEFILTER6:
969 rValue >>= m_pImpl->m_aTableFilter;
970 break;
971 case PROPERTY_ID_TABLETYPEFILTER70:
972 rValue >>= m_pImpl->m_aTableTypeFilter;
973 break;
974 case PROPERTY_ID_USER53:
975 rValue >>= m_pImpl->m_sUser;
976 // if the user name has changed, reset the password
977 m_pImpl->m_aPassword.clear();
978 break;
979 case PROPERTY_ID_PASSWORD54:
980 rValue >>= m_pImpl->m_aPassword;
981 break;
982 case PROPERTY_ID_ISPASSWORDREQUIRED5:
983 m_pImpl->m_bPasswordRequired = any2bool(rValue);
984 break;
985 case PROPERTY_ID_SUPPRESSVERSIONCL92:
986 m_pImpl->m_bSuppressVersionColumns = any2bool(rValue);
987 break;
988 case PROPERTY_ID_URL2:
989 rValue >>= m_pImpl->m_sConnectURL;
990 break;
991 case PROPERTY_ID_INFO4:
992 {
993 Sequence< PropertyValue > aInfo;
994 OSL_VERIFY( rValue >>= aInfo )do { if (!(rValue >>= aInfo)) do { if (true && (
!(0))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"
), ("/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/datasource.cxx"
":" "994" ": "), "OSL_ASSERT: %s", "0"); } } while (false); }
while (0)
;
995 lcl_setPropertyValues_resetOrRemoveOther( m_pImpl->m_xSettings, aInfo );
996 }
997 break;
998 case PROPERTY_ID_LAYOUTINFORMATION93:
999 rValue >>= m_pImpl->m_aLayoutInformation;
1000 break;
1001 }
1002 m_pImpl->setModified(true);
1003}
1004
1005void ODatabaseSource::getFastPropertyValue( Any& rValue, sal_Int32 nHandle ) const
1006{
1007 if ( !m_pImpl.is() )
1008 return;
1009
1010 switch (nHandle)
1011 {
1012 case PROPERTY_ID_TABLEFILTER6:
1013 rValue <<= m_pImpl->m_aTableFilter;
1014 break;
1015 case PROPERTY_ID_TABLETYPEFILTER70:
1016 rValue <<= m_pImpl->m_aTableTypeFilter;
1017 break;
1018 case PROPERTY_ID_USER53:
1019 rValue <<= m_pImpl->m_sUser;
1020 break;
1021 case PROPERTY_ID_PASSWORD54:
1022 rValue <<= m_pImpl->m_aPassword;
1023 break;
1024 case PROPERTY_ID_ISPASSWORDREQUIRED5:
1025 rValue <<= m_pImpl->m_bPasswordRequired;
1026 break;
1027 case PROPERTY_ID_SUPPRESSVERSIONCL92:
1028 rValue <<= m_pImpl->m_bSuppressVersionColumns;
1029 break;
1030 case PROPERTY_ID_ISREADONLY37:
1031 rValue <<= m_pImpl->m_bReadOnly;
1032 break;
1033 case PROPERTY_ID_INFO4:
1034 {
1035 try
1036 {
1037 // collect the property attributes of all current settings
1038 Reference< XPropertySet > xSettingsAsProps( m_pImpl->m_xSettings, UNO_QUERY_THROW );
1039 Reference< XPropertySetInfo > xPST( xSettingsAsProps->getPropertySetInfo(), UNO_SET_THROW );
1040 const Sequence< Property > aSettings( xPST->getProperties() );
1041 std::map< OUString, sal_Int32 > aPropertyAttributes;
1042 for ( auto const & setting : aSettings )
1043 {
1044 aPropertyAttributes[ setting.Name ] = setting.Attributes;
1045 }
1046
1047 // get all current settings with their values
1048 Sequence< PropertyValue > aValues( m_pImpl->m_xSettings->getPropertyValues() );
1049
1050 // transform them so that only property values which fulfill certain
1051 // criteria survive
1052 Sequence< PropertyValue > aNonDefaultOrUserDefined( aValues.getLength() );
1053 const PropertyValue* pCopyEnd = std::remove_copy_if(
1054 aValues.begin(),
1055 aValues.end(),
1056 aNonDefaultOrUserDefined.getArray(),
1057 IsDefaultAndNotRemoveable( aPropertyAttributes )
1058 );
1059 aNonDefaultOrUserDefined.realloc( pCopyEnd - aNonDefaultOrUserDefined.getArray() );
1060 rValue <<= aNonDefaultOrUserDefined;
1061 }
1062 catch( const Exception& )
1063 {
1064 DBG_UNHANDLED_EXCEPTION("dbaccess")DbgUnhandledException( DbgGetCaughtException(), __func__, "/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/datasource.cxx"
":" "1064" ": ", "dbaccess" );
;
1065 }
1066 }
1067 break;
1068 case PROPERTY_ID_SETTINGS129:
1069 rValue <<= m_pImpl->m_xSettings;
1070 break;
1071 case PROPERTY_ID_URL2:
1072 rValue <<= m_pImpl->m_sConnectURL;
1073 break;
1074 case PROPERTY_ID_NUMBERFORMATSSUPPLIER48:
1075 rValue <<= m_pImpl->getNumberFormatsSupplier();
1076 break;
1077 case PROPERTY_ID_NAME7:
1078 rValue <<= m_pImpl->m_sName;
1079 break;
1080 case PROPERTY_ID_LAYOUTINFORMATION93:
1081 rValue <<= m_pImpl->m_aLayoutInformation;
1082 break;
1083 default:
1084 SAL_WARN("dbaccess","unknown Property")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "dbaccess")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "unknown Property") ==
1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("dbaccess"
), ("/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/datasource.cxx"
":" "1084" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "unknown Property"), 0); } else { ::
std::ostringstream sal_detail_stream; sal_detail_stream <<
"unknown Property"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("dbaccess"), ("/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/datasource.cxx"
":" "1084" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "unknown Property") == 1) { ::sal_detail_log( (::
SAL_DETAIL_LOG_LEVEL_WARN), ("dbaccess"), ("/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/datasource.cxx"
":" "1084" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "unknown Property"), 0); } else { ::
std::ostringstream sal_detail_stream; sal_detail_stream <<
"unknown Property"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("dbaccess"), ("/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/datasource.cxx"
":" "1084" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
1085 }
1086}
1087
1088// XDataSource
1089void ODatabaseSource::setLoginTimeout(sal_Int32 seconds)
1090{
1091 ModelMethodGuard aGuard( *this );
1092 m_pImpl->m_nLoginTimeout = seconds;
1093}
1094
1095sal_Int32 ODatabaseSource::getLoginTimeout()
1096{
1097 ModelMethodGuard aGuard( *this );
1098 return m_pImpl->m_nLoginTimeout;
1099}
1100
1101// XCompletedConnection
1102Reference< XConnection > SAL_CALL ODatabaseSource::connectWithCompletion( const Reference< XInteractionHandler >& _rxHandler )
1103{
1104 return connectWithCompletion(_rxHandler,false);
1105}
1106
1107Reference< XConnection > ODatabaseSource::getConnection(const OUString& user, const OUString& password)
1108{
1109 return getConnection(user,password,false);
1110}
1111
1112Reference< XConnection > SAL_CALL ODatabaseSource::getIsolatedConnection( const OUString& user, const OUString& password )
1113{
1114 return getConnection(user,password,true);
1
Calling 'ODatabaseSource::getConnection'
1115}
1116
1117Reference< XConnection > SAL_CALL ODatabaseSource::getIsolatedConnectionWithCompletion( const Reference< XInteractionHandler >& _rxHandler )
1118{
1119 return connectWithCompletion(_rxHandler,true);
1120}
1121
1122Reference< XConnection > ODatabaseSource::connectWithCompletion( const Reference< XInteractionHandler >& _rxHandler,bool _bIsolated )
1123{
1124 ModelMethodGuard aGuard( *this );
1125
1126 if (!_rxHandler.is())
1127 {
1128 SAL_WARN("dbaccess","ODatabaseSource::connectWithCompletion: invalid interaction handler!")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "dbaccess")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "ODatabaseSource::connectWithCompletion: invalid interaction handler!"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("dbaccess"
), ("/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/datasource.cxx"
":" "1128" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "ODatabaseSource::connectWithCompletion: invalid interaction handler!"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "ODatabaseSource::connectWithCompletion: invalid interaction handler!"
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("dbaccess"
), ("/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/datasource.cxx"
":" "1128" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "ODatabaseSource::connectWithCompletion: invalid interaction handler!"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("dbaccess"
), ("/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/datasource.cxx"
":" "1128" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "ODatabaseSource::connectWithCompletion: invalid interaction handler!"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "ODatabaseSource::connectWithCompletion: invalid interaction handler!"
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("dbaccess"
), ("/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/datasource.cxx"
":" "1128" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
1129 return getConnection(m_pImpl->m_sUser, m_pImpl->m_aPassword,_bIsolated);
1130 }
1131
1132 OUString sUser(m_pImpl->m_sUser), sPassword(m_pImpl->m_aPassword);
1133 bool bNewPasswordGiven = false;
1134
1135 if (m_pImpl->m_bPasswordRequired && sPassword.isEmpty())
1136 { // we need a password, but don't have one yet.
1137 // -> ask the user
1138
1139 // build an interaction request
1140 // two continuations (Ok and Cancel)
1141 OInteractionAbort* pAbort = new OInteractionAbort;
1142 OAuthenticationContinuation* pAuthenticate = new OAuthenticationContinuation;
1143
1144 // the name which should be referred in the login dialog
1145 OUString sServerName( m_pImpl->m_sName );
1146 INetURLObject aURLCheck( sServerName );
1147 if ( aURLCheck.GetProtocol() != INetProtocol::NotValid )
1148 sServerName = aURLCheck.getBase( INetURLObject::LAST_SEGMENT, true, INetURLObject::DecodeMechanism::Unambiguous );
1149
1150 // the request
1151 AuthenticationRequest aRequest;
1152 aRequest.ServerName = sServerName;
1153 aRequest.HasRealm = aRequest.HasAccount = false;
1154 aRequest.HasUserName = aRequest.HasPassword = true;
1155 aRequest.UserName = m_pImpl->m_sUser;
1156 aRequest.Password = m_pImpl->m_sFailedPassword.isEmpty() ? m_pImpl->m_aPassword : m_pImpl->m_sFailedPassword;
1157 OInteractionRequest* pRequest = new OInteractionRequest(makeAny(aRequest));
1158 Reference< XInteractionRequest > xRequest(pRequest);
1159 // some knittings
1160 pRequest->addContinuation(pAbort);
1161 pRequest->addContinuation(pAuthenticate);
1162
1163 // handle the request
1164 try
1165 {
1166 _rxHandler->handle(xRequest);
1167 }
1168 catch(Exception&)
1169 {
1170 DBG_UNHANDLED_EXCEPTION("dbaccess")DbgUnhandledException( DbgGetCaughtException(), __func__, "/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/datasource.cxx"
":" "1170" ": ", "dbaccess" );
;
1171 }
1172
1173 if (!pAuthenticate->wasSelected())
1174 return Reference< XConnection >();
1175
1176 // get the result
1177 sUser = m_pImpl->m_sUser = pAuthenticate->getUser();
1178 sPassword = pAuthenticate->getPassword();
1179
1180 if (pAuthenticate->getRememberPassword())
1181 {
1182 m_pImpl->m_aPassword = pAuthenticate->getPassword();
1183 bNewPasswordGiven = true;
1184 }
1185 m_pImpl->m_sFailedPassword.clear();
1186 }
1187
1188 try
1189 {
1190 return getConnection(sUser, sPassword,_bIsolated);
1191 }
1192 catch(Exception&)
1193 {
1194 if (bNewPasswordGiven)
1195 {
1196 m_pImpl->m_sFailedPassword = m_pImpl->m_aPassword;
1197 // assume that we had an authentication problem. Without this we may, after an unsuccessful connect, while
1198 // the user gave us a password and the order to remember it, never allow a password input again (at least
1199 // not without restarting the session)
1200 m_pImpl->m_aPassword.clear();
1201 }
1202 throw;
1203 }
1204}
1205
1206Reference< XConnection > ODatabaseSource::buildIsolatedConnection(const OUString& user, const OUString& password)
1207{
1208 Reference< XConnection > xConn;
1209 Reference< XConnection > xSdbcConn = buildLowLevelConnection(user, password);
4
Calling 'ODatabaseSource::buildLowLevelConnection'
1210 OSL_ENSURE( xSdbcConn.is(), "ODatabaseSource::buildIsolatedConnection: invalid return value of buildLowLevelConnection!" )do { if (true && (!(xSdbcConn.is()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/datasource.cxx"
":" "1210" ": "), "%s", "ODatabaseSource::buildIsolatedConnection: invalid return value of buildLowLevelConnection!"
); } } while (false)
;
1211 // buildLowLevelConnection is expected to always succeed
1212 if ( xSdbcConn.is() )
1213 {
1214 // build a connection server and return it (no stubs)
1215 xConn = new OConnection(*this, xSdbcConn, m_pImpl->m_aContext);
1216 }
1217 return xConn;
1218}
1219
1220Reference< XConnection > ODatabaseSource::getConnection(const OUString& user, const OUString& password,bool _bIsolated)
1221{
1222 ModelMethodGuard aGuard( *this );
1223
1224 Reference< XConnection > xConn;
1225 if ( _bIsolated
1.1
'_bIsolated' is true
)
2
Taking true branch
1226 {
1227 xConn = buildIsolatedConnection(user,password);
3
Calling 'ODatabaseSource::buildIsolatedConnection'
1228 }
1229 else
1230 { // create a new proxy for the connection
1231 if ( !m_pImpl->m_xSharedConnectionManager.is() )
1232 {
1233 m_pImpl->m_pSharedConnectionManager = new OSharedConnectionManager( m_pImpl->m_aContext );
1234 m_pImpl->m_xSharedConnectionManager = m_pImpl->m_pSharedConnectionManager;
1235 }
1236 xConn = m_pImpl->m_pSharedConnectionManager->getConnection(
1237 m_pImpl->m_sConnectURL, user, password, m_pImpl->m_xSettings->getPropertyValues(), this );
1238 }
1239
1240 if ( xConn.is() )
1241 {
1242 Reference< XComponent> xComp(xConn,UNO_QUERY);
1243 if ( xComp.is() )
1244 xComp->addEventListener( static_cast< XContainerListener* >( this ) );
1245 m_pImpl->m_aConnections.emplace_back(xConn);
1246 }
1247
1248 return xConn;
1249}
1250
1251Reference< XNameAccess > SAL_CALL ODatabaseSource::getBookmarks( )
1252{
1253 ModelMethodGuard aGuard( *this );
1254 // tdf#114596 this may look nutty but see OBookmarkContainer::acquire()
1255 return static_cast<XNameContainer*>(&m_Bookmarks);
1256}
1257
1258Reference< XNameAccess > SAL_CALL ODatabaseSource::getQueryDefinitions( )
1259{
1260 ModelMethodGuard aGuard( *this );
1261
1262 Reference< XNameAccess > xContainer = m_pImpl->m_xCommandDefinitions;
1263 if ( !xContainer.is() )
1264 {
1265 Any aValue;
1266 css::uno::Reference< css::uno::XInterface > xMy(*this);
1267 if ( dbtools::getDataSourceSetting(xMy,"CommandDefinitions",aValue) )
1268 {
1269 OUString sSupportService;
1270 aValue >>= sSupportService;
1271 if ( !sSupportService.isEmpty() )
1272 {
1273 Sequence<Any> aArgs(1);
1274 aArgs[0] <<= NamedValue("DataSource",makeAny(xMy));
1275 xContainer.set( m_pImpl->m_aContext->getServiceManager()->createInstanceWithArgumentsAndContext(sSupportService, aArgs, m_pImpl->m_aContext), UNO_QUERY);
1276 }
1277 }
1278 if ( !xContainer.is() )
1279 {
1280 TContentPtr& rContainerData( m_pImpl->getObjectContainer( ODatabaseModelImpl::E_QUERY ) );
1281 xContainer = new OCommandContainer( m_pImpl->m_aContext, *this, rContainerData, false );
1282 }
1283 m_pImpl->m_xCommandDefinitions = xContainer;
1284 }
1285 return xContainer;
1286}
1287
1288// XTablesSupplier
1289Reference< XNameAccess > ODatabaseSource::getTables()
1290{
1291 ModelMethodGuard aGuard( *this );
1292
1293 Reference< XNameAccess > xContainer = m_pImpl->m_xTableDefinitions;
1294 if ( !xContainer.is() )
1295 {
1296 TContentPtr& rContainerData( m_pImpl->getObjectContainer( ODatabaseModelImpl::E_TABLE ) );
1297 xContainer = new OCommandContainer( m_pImpl->m_aContext, *this, rContainerData, true );
1298 m_pImpl->m_xTableDefinitions = xContainer;
1299 }
1300 return xContainer;
1301}
1302
1303void SAL_CALL ODatabaseSource::flush( )
1304{
1305 try
1306 {
1307 // SYNCHRONIZED ->
1308 {
1309 ModelMethodGuard aGuard( *this );
1310
1311 typedef ::utl::SharedUNOComponent< XModel, ::utl::CloseableComponent > SharedModel;
1312 SharedModel xModel( m_pImpl->getModel_noCreate(), SharedModel::NoTakeOwnership );
1313
1314 if ( !xModel.is() )
1315 xModel.reset( m_pImpl->createNewModel_deliverOwnership(), SharedModel::TakeOwnership );
1316
1317 Reference< css::frame::XStorable> xStorable( xModel, UNO_QUERY_THROW );
1318 xStorable->store();
1319 }
1320 // <- SYNCHRONIZED
1321
1322 css::lang::EventObject aFlushedEvent(*this);
1323 m_aFlushListeners.notifyEach( &XFlushListener::flushed, aFlushedEvent );
1324 }
1325 catch( const Exception& )
1326 {
1327 DBG_UNHANDLED_EXCEPTION("dbaccess")DbgUnhandledException( DbgGetCaughtException(), __func__, "/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/datasource.cxx"
":" "1327" ": ", "dbaccess" );
;
1328 }
1329}
1330
1331void SAL_CALL ODatabaseSource::flushed( const EventObject& /*rEvent*/ )
1332{
1333 ModelMethodGuard aGuard( *this );
1334
1335 // Okay, this is some hack.
1336 //
1337 // In general, we have the problem that embedded databases write into their underlying storage, which
1338 // logically is one of our sub storage, and practically is a temporary file maintained by the
1339 // package implementation. As long as we did not commit this storage and our main storage,
1340 // the changes made by the embedded database engine are not really reflected in the database document
1341 // file. This is Bad (TM) for a "real" database application - imagine somebody entering some
1342 // data, and then crashing: For a database application, you would expect that the data still is present
1343 // when you connect to the database next time.
1344 //
1345 // Since this is a conceptual problem as long as we do use those ZIP packages (in fact, we *cannot*
1346 // provide the desired functionality as long as we do not have a package format which allows O(1) writes),
1347 // we cannot completely fix this. However, we can relax the problem by committing more often - often
1348 // enough so that data loss is more seldom, and seldom enough so that there's no noticeable performance
1349 // decrease.
1350 //
1351 // For this, we introduced a few places which XFlushable::flush their connections, and register as
1352 // XFlushListener at the embedded connection (which needs to provide the XFlushable functionality).
1353 // Then, when the connection is flushed, we commit both the database storage and our main storage.
1354 //
1355 // #i55274#
1356
1357 OSL_ENSURE( m_pImpl->isEmbeddedDatabase(), "ODatabaseSource::flushed: no embedded database?!" )do { if (true && (!(m_pImpl->isEmbeddedDatabase())
)) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"
), ("/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/datasource.cxx"
":" "1357" ": "), "%s", "ODatabaseSource::flushed: no embedded database?!"
); } } while (false)
;
1358 bool bWasModified = m_pImpl->m_bModified;
1359 m_pImpl->commitEmbeddedStorage();
1360 m_pImpl->setModified( bWasModified );
1361}
1362
1363void SAL_CALL ODatabaseSource::addFlushListener( const Reference< css::util::XFlushListener >& _xListener )
1364{
1365 m_aFlushListeners.addInterface(_xListener);
1366}
1367
1368void SAL_CALL ODatabaseSource::removeFlushListener( const Reference< css::util::XFlushListener >& _xListener )
1369{
1370 m_aFlushListeners.removeInterface(_xListener);
1371}
1372
1373void SAL_CALL ODatabaseSource::elementInserted( const ContainerEvent& /*Event*/ )
1374{
1375 ModelMethodGuard aGuard( *this );
1376 if ( m_pImpl.is() )
1377 m_pImpl->setModified(true);
1378}
1379
1380void SAL_CALL ODatabaseSource::elementRemoved( const ContainerEvent& /*Event*/ )
1381{
1382 ModelMethodGuard aGuard( *this );
1383 if ( m_pImpl.is() )
1384 m_pImpl->setModified(true);
1385}
1386
1387void SAL_CALL ODatabaseSource::elementReplaced( const ContainerEvent& /*Event*/ )
1388{
1389 ModelMethodGuard aGuard( *this );
1390 if ( m_pImpl.is() )
1391 m_pImpl->setModified(true);
1392}
1393
1394// XDocumentDataSource
1395Reference< XOfficeDatabaseDocument > SAL_CALL ODatabaseSource::getDatabaseDocument()
1396{
1397 ModelMethodGuard aGuard( *this );
1398
1399 Reference< XModel > xModel( m_pImpl->getModel_noCreate() );
1400 if ( !xModel.is() )
1401 xModel = m_pImpl->createNewModel_deliverOwnership();
1402
1403 return Reference< XOfficeDatabaseDocument >( xModel, UNO_QUERY_THROW );
1404}
1405
1406void SAL_CALL ODatabaseSource::initialize( css::uno::Sequence< css::uno::Any > const & rArguments)
1407{
1408 ::comphelper::NamedValueCollection aProperties( rArguments );
1409 if (aProperties.has("ParentWindow"))
1410 aProperties.get("ParentWindow") >>= m_pImpl->m_xDialogParent;
1411}
1412
1413Reference< XInterface > ODatabaseSource::getThis() const
1414{
1415 return *const_cast< ODatabaseSource* >( this );
1416}
1417
1418} // namespace dbaccess
1419
1420extern "C" SAL_DLLPUBLIC_EXPORT__attribute__ ((visibility("default"))) css::uno::XInterface*
1421com_sun_star_comp_dba_ODatabaseSource(css::uno::XComponentContext* context,
1422 css::uno::Sequence<css::uno::Any> const &)
1423{
1424 css::uno::Reference<XInterface> inst(
1425 DatabaseContext::create(context)->createInstance());
1426 inst->acquire();
1427 return inst.get();
1428}
1429
1430/* vim:set shiftwidth=4 softtabstop=4 expandtab: */