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 |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
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 | ||||
72 | using namespace ::com::sun::star::sdbc; | |||
73 | using namespace ::com::sun::star::sdbcx; | |||
74 | using namespace ::com::sun::star::sdb; | |||
75 | using namespace ::com::sun::star::beans; | |||
76 | using namespace ::com::sun::star::uno; | |||
77 | using namespace ::com::sun::star::lang; | |||
78 | using namespace ::com::sun::star::embed; | |||
79 | using namespace ::com::sun::star::container; | |||
80 | using namespace ::com::sun::star::util; | |||
81 | using namespace ::com::sun::star::io; | |||
82 | using namespace ::com::sun::star::task; | |||
83 | using namespace ::com::sun::star::ucb; | |||
84 | using namespace ::com::sun::star::frame; | |||
85 | using namespace ::com::sun::star::reflection; | |||
86 | using namespace ::cppu; | |||
87 | using namespace ::osl; | |||
88 | using namespace ::dbtools; | |||
89 | using namespace ::comphelper; | |||
90 | ||||
91 | namespace dbaccess | |||
92 | { | |||
93 | ||||
94 | namespace { | |||
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 | */ | |||
106 | class FlushNotificationAdapter : public ::cppu::WeakImplHelper< XFlushListener > | |||
107 | { | |||
108 | private: | |||
109 | WeakReference< XFlushable > m_aBroadcaster; | |||
110 | WeakReference< XFlushListener > m_aListener; | |||
111 | ||||
112 | public: | |||
113 | static void installAdapter( const Reference< XFlushable >& _rxBroadcaster, const Reference< XFlushListener >& _rxListener ) | |||
114 | { | |||
115 | new FlushNotificationAdapter( _rxBroadcaster, _rxListener ); | |||
116 | } | |||
117 | ||||
118 | protected: | |||
119 | FlushNotificationAdapter( const Reference< XFlushable >& _rxBroadcaster, const Reference< XFlushListener >& _rxListener ); | |||
120 | virtual ~FlushNotificationAdapter() override; | |||
121 | ||||
122 | void impl_dispose(); | |||
123 | ||||
124 | protected: | |||
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 | ||||
133 | FlushNotificationAdapter::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); | |||
138 | ||||
139 | osl_atomic_increment( &m_refCount )__sync_add_and_fetch((&m_refCount), 1); | |||
140 | { | |||
141 | if ( _rxBroadcaster.is() ) | |||
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); | |||
| ||||
146 | } | |||
147 | ||||
148 | FlushNotificationAdapter::~FlushNotificationAdapter() | |||
149 | { | |||
150 | } | |||
151 | ||||
152 | void 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 | ||||
164 | void 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 | ||||
173 | void 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 | ||||
182 | OAuthenticationContinuation::OAuthenticationContinuation() | |||
183 | :m_bRememberPassword(true), // TODO: a meaningful default | |||
184 | m_bCanSetUserName(true) | |||
185 | { | |||
186 | } | |||
187 | ||||
188 | sal_Bool SAL_CALL OAuthenticationContinuation::canSetRealm( ) | |||
189 | { | |||
190 | return false; | |||
191 | } | |||
192 | ||||
193 | void 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 | ||||
198 | sal_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 | ||||
205 | void SAL_CALL OAuthenticationContinuation::setUserName( const OUString& _rUser ) | |||
206 | { | |||
207 | m_sUser = _rUser; | |||
208 | } | |||
209 | ||||
210 | sal_Bool SAL_CALL OAuthenticationContinuation::canSetPassword( ) | |||
211 | { | |||
212 | return true; | |||
213 | } | |||
214 | ||||
215 | void SAL_CALL OAuthenticationContinuation::setPassword( const OUString& _rPassword ) | |||
216 | { | |||
217 | m_sPassword = _rPassword; | |||
218 | } | |||
219 | ||||
220 | Sequence< RememberAuthentication > SAL_CALL OAuthenticationContinuation::getRememberPasswordModes( RememberAuthentication& _reDefault ) | |||
221 | { | |||
222 | Sequence< RememberAuthentication > aReturn(1); | |||
223 | _reDefault = aReturn[0] = RememberAuthentication_SESSION; | |||
224 | return aReturn; | |||
225 | } | |||
226 | ||||
227 | void SAL_CALL OAuthenticationContinuation::setRememberPassword( RememberAuthentication _eRemember ) | |||
228 | { | |||
229 | m_bRememberPassword = (RememberAuthentication_NO != _eRemember); | |||
230 | } | |||
231 | ||||
232 | sal_Bool SAL_CALL OAuthenticationContinuation::canSetAccount( ) | |||
233 | { | |||
234 | return false; | |||
235 | } | |||
236 | ||||
237 | void 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 | ||||
242 | Sequence< 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 | ||||
250 | void 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 | ||||
255 | namespace { | |||
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 | |||
261 | struct 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 | ||||
273 | class 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 | ||||
303 | protected: | |||
304 | virtual ~OSharedConnectionManager() override; | |||
305 | ||||
306 | public: | |||
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 | ||||
318 | OSharedConnectionManager::OSharedConnectionManager(const Reference< XComponentContext >& _rxContext) | |||
319 | { | |||
320 | m_xProxyFactory.set( ProxyFactory::create( _rxContext ) ); | |||
321 | } | |||
322 | ||||
323 | OSharedConnectionManager::~OSharedConnectionManager() | |||
324 | { | |||
325 | } | |||
326 | ||||
327 | void 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 | ||||
344 | Reference<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 | ||||
393 | void 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 | ||||
401 | namespace | |||
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 | ||||
477 | ODatabaseSource::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 | ||||
488 | ODatabaseSource::~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 | ||||
498 | void 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 | |||
508 | Sequence< 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 | ||||
520 | Sequence< sal_Int8 > ODatabaseSource::getImplementationId() | |||
521 | { | |||
522 | return css::uno::Sequence<sal_Int8>(); | |||
523 | } | |||
524 | ||||
525 | // css::uno::XInterface | |||
526 | Any 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 | ||||
534 | void ODatabaseSource::acquire() throw () | |||
535 | { | |||
536 | ODatabaseSource_Base::acquire(); | |||
537 | } | |||
538 | ||||
539 | void ODatabaseSource::release() throw () | |||
540 | { | |||
541 | ODatabaseSource_Base::release(); | |||
542 | } | |||
543 | ||||
544 | void SAL_CALL ODatabaseSource::disposing( const css::lang::EventObject& Source ) | |||
545 | { | |||
546 | if ( m_pImpl.is() ) | |||
547 | m_pImpl->disposing(Source); | |||
548 | } | |||
549 | ||||
550 | // XServiceInfo | |||
551 | OUString ODatabaseSource::getImplementationName( ) | |||
552 | { | |||
553 | return "com.sun.star.comp.dba.ODatabaseSource"; | |||
554 | } | |||
555 | ||||
556 | Sequence< OUString > ODatabaseSource::getSupportedServiceNames( ) | |||
557 | { | |||
558 | return { SERVICE_SDB_DATASOURCE"com.sun.star.sdb.DataSource", "com.sun.star.sdb.DocumentDataSource" }; | |||
559 | } | |||
560 | ||||
561 | sal_Bool ODatabaseSource::supportsService( const OUString& _rServiceName ) | |||
562 | { | |||
563 | return cppu::supportsService(this, _rServiceName); | |||
564 | } | |||
565 | ||||
566 | // OComponentHelper | |||
567 | void 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 | ||||
581 | weld::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 | ||||
599 | Reference< 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) | |||
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()) | |||
623 | bIgnoreMigration = true; | |||
624 | ||||
625 | if(!bIgnoreMigration
| |||
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() ) | |||
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())) | |||
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()) | |||
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()) | |||
685 | { | |||
686 | sal_Int32 nAdditionalArgs(0); | |||
687 | if (!sUser.isEmpty()) ++nAdditionalArgs; | |||
688 | if (!sPwd.isEmpty()) ++nAdditionalArgs; | |||
689 | ||||
690 | Sequence< PropertyValue > aUserPwd(nAdditionalArgs); | |||
691 | sal_Int32 nArgPos = 0; | |||
692 | if (!sUser.isEmpty()) | |||
693 | { | |||
694 | aUserPwd[ nArgPos ].Name = "user"; | |||
695 | aUserPwd[ nArgPos ].Value <<= sUser; | |||
696 | ++nArgPos; | |||
697 | } | |||
698 | if (!sPwd.isEmpty()) | |||
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() ) | |||
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 ) ) | |||
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() ) | |||
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
| |||
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() ) | |||
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() ) | |||
758 | FlushNotificationAdapter::installAdapter( xFlushable, this ); | |||
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 | |||
792 | Reference< 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 | ||||
823 | sal_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 | ||||
894 | namespace | |||
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 | ||||
961 | void 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 | ||||
1005 | void 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 | |||
1089 | void ODatabaseSource::setLoginTimeout(sal_Int32 seconds) | |||
1090 | { | |||
1091 | ModelMethodGuard aGuard( *this ); | |||
1092 | m_pImpl->m_nLoginTimeout = seconds; | |||
1093 | } | |||
1094 | ||||
1095 | sal_Int32 ODatabaseSource::getLoginTimeout() | |||
1096 | { | |||
1097 | ModelMethodGuard aGuard( *this ); | |||
1098 | return m_pImpl->m_nLoginTimeout; | |||
1099 | } | |||
1100 | ||||
1101 | // XCompletedConnection | |||
1102 | Reference< XConnection > SAL_CALL ODatabaseSource::connectWithCompletion( const Reference< XInteractionHandler >& _rxHandler ) | |||
1103 | { | |||
1104 | return connectWithCompletion(_rxHandler,false); | |||
1105 | } | |||
1106 | ||||
1107 | Reference< XConnection > ODatabaseSource::getConnection(const OUString& user, const OUString& password) | |||
1108 | { | |||
1109 | return getConnection(user,password,false); | |||
1110 | } | |||
1111 | ||||
1112 | Reference< XConnection > SAL_CALL ODatabaseSource::getIsolatedConnection( const OUString& user, const OUString& password ) | |||
1113 | { | |||
1114 | return getConnection(user,password,true); | |||
| ||||
1115 | } | |||
1116 | ||||
1117 | Reference< XConnection > SAL_CALL ODatabaseSource::getIsolatedConnectionWithCompletion( const Reference< XInteractionHandler >& _rxHandler ) | |||
1118 | { | |||
1119 | return connectWithCompletion(_rxHandler,true); | |||
1120 | } | |||
1121 | ||||
1122 | Reference< 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 | ||||
1206 | Reference< XConnection > ODatabaseSource::buildIsolatedConnection(const OUString& user, const OUString& password) | |||
1207 | { | |||
1208 | Reference< XConnection > xConn; | |||
1209 | Reference< XConnection > xSdbcConn = buildLowLevelConnection(user, password); | |||
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 | ||||
1220 | Reference< XConnection > ODatabaseSource::getConnection(const OUString& user, const OUString& password,bool _bIsolated) | |||
1221 | { | |||
1222 | ModelMethodGuard aGuard( *this ); | |||
1223 | ||||
1224 | Reference< XConnection > xConn; | |||
1225 | if ( _bIsolated
| |||
1226 | { | |||
1227 | xConn = buildIsolatedConnection(user,password); | |||
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 | ||||
1251 | Reference< 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 | ||||
1258 | Reference< 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 | |||
1289 | Reference< 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 | ||||
1303 | void 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 | ||||
1331 | void 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 | ||||
1363 | void SAL_CALL ODatabaseSource::addFlushListener( const Reference< css::util::XFlushListener >& _xListener ) | |||
1364 | { | |||
1365 | m_aFlushListeners.addInterface(_xListener); | |||
1366 | } | |||
1367 | ||||
1368 | void SAL_CALL ODatabaseSource::removeFlushListener( const Reference< css::util::XFlushListener >& _xListener ) | |||
1369 | { | |||
1370 | m_aFlushListeners.removeInterface(_xListener); | |||
1371 | } | |||
1372 | ||||
1373 | void SAL_CALL ODatabaseSource::elementInserted( const ContainerEvent& /*Event*/ ) | |||
1374 | { | |||
1375 | ModelMethodGuard aGuard( *this ); | |||
1376 | if ( m_pImpl.is() ) | |||
1377 | m_pImpl->setModified(true); | |||
1378 | } | |||
1379 | ||||
1380 | void SAL_CALL ODatabaseSource::elementRemoved( const ContainerEvent& /*Event*/ ) | |||
1381 | { | |||
1382 | ModelMethodGuard aGuard( *this ); | |||
1383 | if ( m_pImpl.is() ) | |||
1384 | m_pImpl->setModified(true); | |||
1385 | } | |||
1386 | ||||
1387 | void 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 | |||
1395 | Reference< 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 | ||||
1406 | void 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 | ||||
1413 | Reference< XInterface > ODatabaseSource::getThis() const | |||
1414 | { | |||
1415 | return *const_cast< ODatabaseSource* >( this ); | |||
1416 | } | |||
1417 | ||||
1418 | } // namespace dbaccess | |||
1419 | ||||
1420 | extern "C" SAL_DLLPUBLIC_EXPORT__attribute__ ((visibility("default"))) css::uno::XInterface* | |||
1421 | com_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: */ |