Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 :
21 : #include "connection.hxx"
22 : #include "dbastrings.hrc"
23 : #include "datasource.hxx"
24 : #include "core_resource.hrc"
25 : #include "core_resource.hxx"
26 : #include "statement.hxx"
27 : #include "preparedstatement.hxx"
28 : #include "callablestatement.hxx"
29 : #include "ContainerMediator.hxx"
30 : #include "SingleSelectQueryComposer.hxx"
31 : #include "querycomposer.hxx"
32 : #include "sdbcoretools.hxx"
33 :
34 : #include <com/sun/star/sdb/CommandType.hpp>
35 : #include <com/sun/star/sdbc/XDriverAccess.hpp>
36 : #include <com/sun/star/sdbcx/XDataDefinitionSupplier.hpp>
37 : #include <com/sun/star/reflection/ProxyFactory.hpp>
38 : #include <com/sun/star/beans/NamedValue.hpp>
39 : #include <connectivity/dbtools.hxx>
40 : #include <connectivity/dbmetadata.hxx>
41 : #include <connectivity/dbexception.hxx>
42 : #include <tools/debug.hxx>
43 : #include <tools/diagnose_ex.h>
44 : #include <osl/diagnose.h>
45 : #include <comphelper/extract.hxx>
46 : #include <comphelper/uno3.hxx>
47 : #include <comphelper/sequence.hxx>
48 : #include <cppuhelper/typeprovider.hxx>
49 : #include <rtl/logfile.hxx>
50 :
51 : using namespace ::com::sun::star::uno;
52 : using namespace ::com::sun::star::lang;
53 : using namespace ::com::sun::star::util;
54 : using namespace ::com::sun::star::sdb;
55 : using namespace ::com::sun::star::sdb::application;
56 : using namespace ::com::sun::star::sdbc;
57 : using namespace ::com::sun::star::sdbcx;
58 : using namespace ::com::sun::star::beans;
59 : using namespace ::com::sun::star::reflection;
60 : using namespace ::com::sun::star::container;
61 : using namespace ::com::sun::star::graphic;
62 : using namespace ::osl;
63 : using namespace ::comphelper;
64 : using namespace ::cppu;
65 : using namespace ::dbtools;
66 :
67 : using ::com::sun::star::sdb::tools::XTableName;
68 : using ::com::sun::star::sdb::tools::XObjectNames;
69 : using ::com::sun::star::sdb::tools::XDataSourceMetaData;
70 :
71 : namespace dbaccess
72 : {
73 :
74 : //==========================================================================
75 : // XServiceInfo
76 0 : rtl::OUString OConnection::getImplementationName( ) throw(RuntimeException)
77 : {
78 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::getImplementationName" );
79 0 : return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.dbaccess.Connection"));
80 : }
81 :
82 0 : sal_Bool OConnection::supportsService( const ::rtl::OUString& _rServiceName ) throw (RuntimeException)
83 : {
84 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::supportsService" );
85 0 : return findValue(getSupportedServiceNames(), _rServiceName, sal_True).getLength() != 0;
86 : }
87 :
88 0 : Sequence< ::rtl::OUString > OConnection::getSupportedServiceNames( ) throw (RuntimeException)
89 : {
90 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::getSupportedServiceNames" );
91 0 : Sequence< ::rtl::OUString > aSupported = OConnectionWrapper::getSupportedServiceNames();
92 :
93 0 : if ( 0 == findValue( aSupported, SERVICE_SDB_CONNECTION, sal_True ).getLength() )
94 : {
95 0 : sal_Int32 nLen = aSupported.getLength();
96 0 : aSupported.realloc( nLen + 1 );
97 0 : aSupported[ nLen ] = SERVICE_SDB_CONNECTION;
98 : }
99 :
100 0 : return aSupported;
101 : }
102 :
103 : // XCloseable
104 0 : void OConnection::close(void) throw( SQLException, RuntimeException )
105 : {
106 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::close" );
107 : // being closed is the same as being disposed
108 0 : dispose();
109 0 : }
110 :
111 0 : sal_Bool OConnection::isClosed(void) throw( SQLException, RuntimeException )
112 : {
113 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::isClosed" );
114 0 : MutexGuard aGuard(m_aMutex);
115 0 : return !m_xMasterConnection.is();
116 : }
117 :
118 : // XConnection
119 0 : Reference< XStatement > OConnection::createStatement(void) throw( SQLException, RuntimeException )
120 : {
121 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::createStatement" );
122 0 : MutexGuard aGuard(m_aMutex);
123 0 : checkDisposed();
124 :
125 0 : Reference< XStatement > xStatement;
126 0 : Reference< XStatement > xMasterStatement = m_xMasterConnection->createStatement();
127 0 : if ( xMasterStatement.is() )
128 : {
129 0 : xStatement = new OStatement(this, xMasterStatement);
130 0 : m_aStatements.push_back(WeakReferenceHelper(xStatement));
131 : }
132 0 : return xStatement;
133 : }
134 0 : Reference< XPreparedStatement > OConnection::prepareStatement(const rtl::OUString& sql) throw( SQLException, RuntimeException )
135 : {
136 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::prepareStatement" );
137 0 : MutexGuard aGuard(m_aMutex);
138 0 : checkDisposed();
139 :
140 : // TODO convert the SQL to SQL the driver understands
141 0 : Reference< XPreparedStatement > xStatement;
142 0 : Reference< XPreparedStatement > xMasterStatement = m_xMasterConnection->prepareStatement(sql);
143 0 : if ( xMasterStatement.is() )
144 : {
145 0 : xStatement = new OPreparedStatement(this, xMasterStatement);
146 0 : m_aStatements.push_back(WeakReferenceHelper(xStatement));
147 : }
148 0 : return xStatement;
149 : }
150 :
151 0 : Reference< XPreparedStatement > OConnection::prepareCall(const rtl::OUString& sql) throw( SQLException, RuntimeException )
152 : {
153 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::prepareCall" );
154 0 : MutexGuard aGuard(m_aMutex);
155 0 : checkDisposed();
156 :
157 0 : Reference< XPreparedStatement > xStatement;
158 0 : Reference< XPreparedStatement > xMasterStatement = m_xMasterConnection->prepareCall(sql);
159 0 : if ( xMasterStatement.is() )
160 : {
161 0 : xStatement = new OCallableStatement(this, xMasterStatement);
162 0 : m_aStatements.push_back(WeakReferenceHelper(xStatement));
163 : }
164 0 : return xStatement;
165 : }
166 :
167 0 : rtl::OUString OConnection::nativeSQL(const rtl::OUString& sql) throw( SQLException, RuntimeException )
168 : {
169 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::nativeSQL" );
170 0 : MutexGuard aGuard(m_aMutex);
171 0 : checkDisposed();
172 0 : return m_xMasterConnection->nativeSQL(sql);
173 : }
174 :
175 0 : void OConnection::setAutoCommit(sal_Bool autoCommit) throw( SQLException, RuntimeException )
176 : {
177 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::setAutoCommit" );
178 0 : MutexGuard aGuard(m_aMutex);
179 0 : checkDisposed();
180 0 : m_xMasterConnection->setAutoCommit(autoCommit);
181 0 : }
182 :
183 0 : sal_Bool OConnection::getAutoCommit(void) throw( SQLException, RuntimeException )
184 : {
185 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::getAutoCommit" );
186 0 : MutexGuard aGuard(m_aMutex);
187 0 : checkDisposed();
188 0 : return m_xMasterConnection->getAutoCommit();
189 : }
190 :
191 0 : void OConnection::commit(void) throw( SQLException, RuntimeException )
192 : {
193 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::commit" );
194 0 : MutexGuard aGuard(m_aMutex);
195 0 : checkDisposed();
196 0 : m_xMasterConnection->commit();
197 0 : }
198 :
199 0 : void OConnection::rollback(void) throw( SQLException, RuntimeException )
200 : {
201 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::rollback" );
202 0 : MutexGuard aGuard(m_aMutex);
203 0 : checkDisposed();
204 0 : m_xMasterConnection->rollback();
205 0 : }
206 :
207 0 : Reference< XDatabaseMetaData > OConnection::getMetaData(void) throw( SQLException, RuntimeException )
208 : {
209 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::getMetaData" );
210 0 : MutexGuard aGuard(m_aMutex);
211 0 : checkDisposed();
212 0 : return m_xMasterConnection->getMetaData();
213 : }
214 :
215 0 : void OConnection::setReadOnly(sal_Bool readOnly) throw( SQLException, RuntimeException )
216 : {
217 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::setReadOnly" );
218 0 : MutexGuard aGuard(m_aMutex);
219 0 : checkDisposed();
220 0 : m_xMasterConnection->setReadOnly(readOnly);
221 0 : }
222 :
223 0 : sal_Bool OConnection::isReadOnly(void) throw( SQLException, RuntimeException )
224 : {
225 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::isReadOnly" );
226 0 : MutexGuard aGuard(m_aMutex);
227 0 : checkDisposed();
228 0 : return m_xMasterConnection->isReadOnly();
229 : }
230 :
231 0 : void OConnection::setCatalog(const rtl::OUString& catalog) throw( SQLException, RuntimeException )
232 : {
233 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::setCatalog" );
234 0 : MutexGuard aGuard(m_aMutex);
235 0 : checkDisposed();
236 0 : m_xMasterConnection->setCatalog(catalog);
237 0 : }
238 :
239 0 : rtl::OUString OConnection::getCatalog(void) throw( SQLException, RuntimeException )
240 : {
241 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::getCatalog" );
242 0 : MutexGuard aGuard(m_aMutex);
243 0 : checkDisposed();
244 0 : return m_xMasterConnection->getCatalog();
245 : }
246 :
247 0 : void OConnection::setTransactionIsolation(sal_Int32 level) throw( SQLException, RuntimeException )
248 : {
249 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::setTransactionIsolation" );
250 0 : MutexGuard aGuard(m_aMutex);
251 0 : checkDisposed();
252 0 : m_xMasterConnection->setTransactionIsolation(level);
253 0 : }
254 :
255 0 : sal_Int32 OConnection::getTransactionIsolation(void) throw( SQLException, RuntimeException )
256 : {
257 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::getTransactionIsolation" );
258 0 : MutexGuard aGuard(m_aMutex);
259 0 : checkDisposed();
260 0 : return m_xMasterConnection->getTransactionIsolation();
261 : }
262 :
263 0 : Reference< XNameAccess > OConnection::getTypeMap(void) throw( SQLException, RuntimeException )
264 : {
265 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::getTypeMap" );
266 0 : MutexGuard aGuard(m_aMutex);
267 0 : checkDisposed();
268 0 : return m_xMasterConnection->getTypeMap();
269 : }
270 :
271 0 : void OConnection::setTypeMap(const Reference< XNameAccess > & typeMap) throw( SQLException, RuntimeException )
272 : {
273 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::setTypeMap" );
274 0 : MutexGuard aGuard(m_aMutex);
275 0 : checkDisposed();
276 0 : m_xMasterConnection->setTypeMap(typeMap);
277 0 : }
278 : //==========================================================================
279 : //= OConnection
280 : //==========================================================================
281 : DBG_NAME(OConnection)
282 :
283 0 : OConnection::OConnection(ODatabaseSource& _rDB
284 : , Reference< XConnection >& _rxMaster
285 : , const Reference< XMultiServiceFactory >& _rxORB)
286 : :OSubComponent(m_aMutex, static_cast< OWeakObject* >(&_rDB))
287 : // as the queries reroute their refcounting to us, this m_aMutex is okey. If the queries
288 : // container would do it's own refcounting, it would have to aquire m_pMutex
289 : // same for tables
290 0 : ,m_aTableFilter(_rDB.m_pImpl->m_aTableFilter)
291 0 : ,m_aTableTypeFilter(_rDB.m_pImpl->m_aTableTypeFilter)
292 : ,m_aContext( _rxORB )
293 : ,m_xMasterConnection(_rxMaster)
294 : ,m_pTables(NULL)
295 : ,m_pViews(NULL)
296 : ,m_aWarnings( Reference< XWarningsSupplier >( _rxMaster, UNO_QUERY ) )
297 : ,m_nInAppend(0)
298 : ,m_bSupportsViews(sal_False)
299 : ,m_bSupportsUsers(sal_False)
300 0 : ,m_bSupportsGroups(sal_False)
301 : {
302 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::OConnection" );
303 : DBG_CTOR(OConnection,NULL);
304 0 : osl_atomic_increment(&m_refCount);
305 :
306 : try
307 : {
308 : Reference< XProxyFactory > xProxyFactory =
309 0 : ProxyFactory::create( m_aContext.getUNOContext() );
310 0 : Reference<XAggregation> xAgg = xProxyFactory->createProxy(_rxMaster.get());
311 0 : setDelegation(xAgg,m_refCount);
312 0 : OSL_ENSURE(m_xConnection.is(), "OConnection::OConnection : invalid master connection !");
313 : }
314 0 : catch(const Exception&)
315 : {
316 : DBG_UNHANDLED_EXCEPTION();
317 : }
318 :
319 0 : m_xTableUIProvider = m_xTableUIProvider.query( m_xMasterConnection );
320 :
321 : try
322 : {
323 0 : m_xQueries = new OQueryContainer(Reference< XNameContainer >(_rDB.getQueryDefinitions( ),UNO_QUERY), this,_rxORB, &m_aWarnings);
324 :
325 0 : sal_Bool bCase = sal_True;
326 0 : Reference<XDatabaseMetaData> xMeta;
327 : try
328 : {
329 0 : xMeta = getMetaData();
330 0 : bCase = xMeta.is() && xMeta->supportsMixedCaseQuotedIdentifiers();
331 : }
332 0 : catch(const SQLException&)
333 : {
334 : }
335 0 : Reference< XNameContainer > xTableDefinitions(_rDB.getTables(),UNO_QUERY);
336 0 : m_pTables = new OTableContainer( *this, m_aMutex, this, bCase, xTableDefinitions, this, &m_aWarnings,m_nInAppend );
337 :
338 : // check if we supports types
339 0 : if ( xMeta.is() )
340 : {
341 0 : Reference<XResultSet> xRes = xMeta->getTableTypes();
342 0 : if(xRes.is())
343 : {
344 0 : ::rtl::OUString sView(RTL_CONSTASCII_USTRINGPARAM("VIEW"));
345 0 : Reference<XRow> xRow(xRes,UNO_QUERY);
346 0 : while(xRes->next())
347 : {
348 0 : ::rtl::OUString sValue = xRow->getString(1);
349 0 : if( !xRow->wasNull() && sValue == sView)
350 : {
351 0 : m_bSupportsViews = sal_True;
352 : break;
353 : }
354 0 : }
355 : }
356 : // some dbs don't support this type so we should ask if a XViewsSupplier is supported
357 0 : if(!m_bSupportsViews)
358 : {
359 0 : Reference< XViewsSupplier > xMaster(getMasterTables(),UNO_QUERY);
360 :
361 0 : if (xMaster.is() && xMaster->getViews().is())
362 0 : m_bSupportsViews = sal_True;
363 : }
364 0 : if(m_bSupportsViews)
365 : {
366 0 : m_pViews = new OViewContainer(*this, m_aMutex, this, bCase,this,&m_aWarnings,m_nInAppend);
367 0 : m_pViews->addContainerListener(m_pTables);
368 0 : m_pTables->addContainerListener(m_pViews);
369 : }
370 0 : m_bSupportsUsers = Reference< XUsersSupplier> (getMasterTables(),UNO_QUERY).is();
371 0 : m_bSupportsGroups = Reference< XGroupsSupplier> (getMasterTables(),UNO_QUERY).is();
372 :
373 0 : impl_checkTableQueryNames_nothrow();
374 0 : }
375 : }
376 0 : catch(const Exception& )
377 : {
378 : DBG_UNHANDLED_EXCEPTION();
379 : }
380 0 : osl_atomic_decrement( &m_refCount );
381 0 : }
382 :
383 0 : OConnection::~OConnection()
384 : {
385 0 : delete m_pTables;
386 0 : delete m_pViews;
387 : DBG_DTOR(OConnection,NULL);
388 0 : }
389 :
390 : // XWarningsSupplier
391 0 : Any SAL_CALL OConnection::getWarnings() throw(SQLException, RuntimeException)
392 : {
393 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::getWarnings" );
394 0 : MutexGuard aGuard(m_aMutex);
395 0 : checkDisposed();
396 0 : return m_aWarnings.getWarnings();
397 : }
398 :
399 0 : void SAL_CALL OConnection::clearWarnings( ) throw(SQLException, RuntimeException)
400 : {
401 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::clearWarnings" );
402 0 : MutexGuard aGuard(m_aMutex);
403 0 : checkDisposed();
404 0 : m_aWarnings.clearWarnings();
405 0 : }
406 :
407 : namespace
408 : {
409 : struct CompareTypeByName : public ::std::binary_function< Type, Type, bool >
410 : {
411 0 : bool operator() ( const Type& _rLHS, const Type& _rRHS ) const
412 : {
413 0 : return _rLHS.getTypeName() < _rRHS.getTypeName();
414 : }
415 : };
416 : typedef ::std::set< Type, CompareTypeByName > TypeBag;
417 :
418 0 : void lcl_copyTypes( TypeBag& _out_rTypes, const Sequence< Type >& _rTypes )
419 : {
420 0 : ::std::copy( _rTypes.getConstArray(), _rTypes.getConstArray() + _rTypes.getLength(),
421 0 : ::std::insert_iterator< TypeBag >( _out_rTypes, _out_rTypes.begin() ) );
422 0 : }
423 : }
424 :
425 : // com::sun::star::lang::XTypeProvider
426 0 : Sequence< Type > OConnection::getTypes() throw (RuntimeException)
427 : {
428 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::getTypes" );
429 0 : TypeBag aNormalizedTypes;
430 :
431 0 : lcl_copyTypes( aNormalizedTypes, OSubComponent::getTypes() );
432 0 : lcl_copyTypes( aNormalizedTypes, OConnection_Base::getTypes() );
433 0 : lcl_copyTypes( aNormalizedTypes, ::connectivity::OConnectionWrapper::getTypes() );
434 :
435 0 : if ( !m_bSupportsViews )
436 0 : aNormalizedTypes.erase( XViewsSupplier::static_type() );
437 0 : if ( !m_bSupportsUsers )
438 0 : aNormalizedTypes.erase( XUsersSupplier::static_type() );
439 0 : if ( !m_bSupportsGroups )
440 0 : aNormalizedTypes.erase( XGroupsSupplier::static_type() );
441 :
442 0 : Sequence< Type > aSupportedTypes( aNormalizedTypes.size() );
443 0 : ::std::copy( aNormalizedTypes.begin(), aNormalizedTypes.end(), aSupportedTypes.getArray() );
444 0 : return aSupportedTypes;
445 : }
446 :
447 0 : Sequence< sal_Int8 > OConnection::getImplementationId() throw (RuntimeException)
448 : {
449 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::getImplementationId" );
450 0 : return getUnoTunnelImplementationId();
451 : }
452 :
453 : // com::sun::star::uno::XInterface
454 0 : Any OConnection::queryInterface( const Type & rType ) throw (RuntimeException)
455 : {
456 0 : if ( !m_bSupportsViews && rType.equals( XViewsSupplier::static_type() ) )
457 0 : return Any();
458 0 : else if ( !m_bSupportsUsers && rType.equals( XUsersSupplier::static_type() ) )
459 0 : return Any();
460 0 : else if ( !m_bSupportsGroups && rType.equals( XGroupsSupplier::static_type() ) )
461 0 : return Any();
462 0 : Any aReturn = OSubComponent::queryInterface( rType );
463 0 : if (!aReturn.hasValue())
464 : {
465 0 : aReturn = OConnection_Base::queryInterface( rType );
466 0 : if (!aReturn.hasValue())
467 0 : aReturn = OConnectionWrapper::queryInterface( rType );
468 : }
469 0 : return aReturn;
470 : }
471 :
472 0 : void OConnection::acquire() throw ()
473 : {
474 : // include this one when you want to see who calls it (call graph)
475 0 : OSubComponent::acquire();
476 0 : }
477 :
478 0 : void OConnection::release() throw ()
479 : {
480 : // include this one when you want to see who calls it (call graph)
481 0 : OSubComponent::release();
482 0 : }
483 :
484 : // OSubComponent
485 0 : void OConnection::disposing()
486 : {
487 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::disposing" );
488 0 : MutexGuard aGuard(m_aMutex);
489 :
490 0 : OSubComponent::disposing();
491 0 : OConnectionWrapper::disposing();
492 :
493 0 : OWeakRefArrayIterator aEnd = m_aStatements.end();
494 0 : for (OWeakRefArrayIterator i = m_aStatements.begin(); aEnd != i; ++i)
495 : {
496 0 : Reference<XComponent> xComp(i->get(),UNO_QUERY);
497 0 : ::comphelper::disposeComponent(xComp);
498 0 : }
499 0 : m_aStatements.clear();
500 0 : m_xMasterTables = NULL;
501 :
502 0 : if(m_pTables)
503 0 : m_pTables->dispose();
504 0 : if(m_pViews)
505 0 : m_pViews->dispose();
506 :
507 0 : ::comphelper::disposeComponent(m_xQueries);
508 :
509 0 : OWeakRefArrayIterator aComposerEnd = m_aComposers.end();
510 0 : for (OWeakRefArrayIterator j = m_aComposers.begin(); aComposerEnd != j; ++j)
511 : {
512 0 : Reference<XComponent> xComp(j->get(),UNO_QUERY);
513 0 : ::comphelper::disposeComponent(xComp);
514 0 : }
515 :
516 0 : m_aComposers.clear();
517 :
518 : try
519 : {
520 0 : if (m_xMasterConnection.is())
521 0 : m_xMasterConnection->close();
522 : }
523 0 : catch(const Exception&)
524 : {
525 : }
526 0 : m_xMasterConnection = NULL;
527 0 : }
528 :
529 : // XChild
530 0 : Reference< XInterface > OConnection::getParent(void) throw( RuntimeException )
531 : {
532 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::getParent" );
533 0 : MutexGuard aGuard(m_aMutex);
534 0 : checkDisposed();
535 0 : return m_xParent;
536 : }
537 :
538 0 : void OConnection::setParent(const Reference< XInterface > & /*Parent*/) throw( NoSupportException, RuntimeException )
539 : {
540 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::setParent" );
541 0 : throw NoSupportException();
542 : }
543 :
544 : // XSQLQueryComposerFactory
545 0 : Reference< XSQLQueryComposer > OConnection::createQueryComposer(void) throw( RuntimeException )
546 : {
547 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::createQueryComposer" );
548 0 : MutexGuard aGuard(m_aMutex);
549 0 : checkDisposed();
550 :
551 : // Reference< XNumberFormatsSupplier > xSupplier = pParent->getNumberFormatsSupplier();
552 0 : Reference< XSQLQueryComposer > xComposer( new OQueryComposer( this ) );
553 0 : m_aComposers.push_back(WeakReferenceHelper(xComposer));
554 0 : return xComposer;
555 : }
556 :
557 0 : void OConnection::impl_fillTableFilter()
558 : {
559 0 : Reference<XPropertySet> xProp(getParent(),UNO_QUERY);
560 0 : if ( xProp.is() )
561 : {
562 0 : xProp->getPropertyValue(PROPERTY_TABLEFILTER) >>= m_aTableFilter;
563 0 : xProp->getPropertyValue(PROPERTY_TABLETYPEFILTER) >>= m_aTableTypeFilter;
564 0 : }
565 0 : }
566 :
567 0 : void OConnection::refresh(const Reference< XNameAccess >& _rToBeRefreshed)
568 : {
569 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::refresh" );
570 0 : if ( _rToBeRefreshed == Reference< XNameAccess >(m_pTables) )
571 : {
572 0 : if (m_pTables && !m_pTables->isInitialized())
573 : {
574 0 : impl_fillTableFilter();
575 : // check if our "master connection" can supply tables
576 0 : getMasterTables();
577 :
578 0 : if (m_xMasterTables.is() && m_xMasterTables->getTables().is())
579 : { // yes -> wrap them
580 0 : m_pTables->construct(m_xMasterTables->getTables(),m_aTableFilter, m_aTableTypeFilter);
581 : }
582 : else
583 : { // no -> use an own container
584 0 : m_pTables->construct(m_aTableFilter, m_aTableTypeFilter);
585 : }
586 : }
587 : }
588 0 : else if ( _rToBeRefreshed == Reference< XNameAccess >(m_pViews) )
589 : {
590 0 : if (m_pViews && !m_pViews->isInitialized())
591 : {
592 0 : impl_fillTableFilter();
593 : // check if our "master connection" can supply tables
594 0 : Reference< XViewsSupplier > xMaster(getMasterTables(),UNO_QUERY);
595 :
596 0 : if (xMaster.is() && xMaster->getViews().is())
597 0 : m_pViews->construct(xMaster->getViews(),m_aTableFilter, m_aTableTypeFilter);
598 : else
599 0 : m_pViews->construct(m_aTableFilter, m_aTableTypeFilter);
600 : }
601 : }
602 0 : }
603 :
604 : // XTablesSupplier
605 0 : Reference< XNameAccess > OConnection::getTables() throw( RuntimeException )
606 : {
607 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::getTables" );
608 0 : MutexGuard aGuard(m_aMutex);
609 0 : checkDisposed();
610 :
611 0 : refresh(m_pTables);
612 :
613 0 : return m_pTables;
614 : }
615 :
616 0 : Reference< XNameAccess > SAL_CALL OConnection::getViews( ) throw(RuntimeException)
617 : {
618 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::getViews" );
619 0 : MutexGuard aGuard(m_aMutex);
620 0 : checkDisposed();
621 :
622 0 : refresh(m_pViews);
623 :
624 0 : return m_pViews;
625 : }
626 : // XQueriesSupplier
627 0 : Reference< XNameAccess > OConnection::getQueries(void) throw( RuntimeException )
628 : {
629 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::getQueries" );
630 0 : MutexGuard aGuard(m_aMutex);
631 0 : checkDisposed();
632 :
633 0 : return m_xQueries;
634 : }
635 :
636 : // ::com::sun::star::sdb::XCommandPreparation
637 0 : Reference< XPreparedStatement > SAL_CALL OConnection::prepareCommand( const ::rtl::OUString& command, sal_Int32 commandType ) throw(::com::sun::star::sdbc::SQLException, RuntimeException)
638 : {
639 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::prepareCommand" );
640 0 : MutexGuard aGuard(m_aMutex);
641 0 : checkDisposed();
642 :
643 0 : rtl::OUString aStatement;
644 0 : switch (commandType)
645 : {
646 : case CommandType::TABLE:
647 : {
648 0 : aStatement = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SELECT * FROM "));
649 :
650 0 : ::rtl::OUString sCatalog, sSchema, sTable;
651 0 : ::dbtools::qualifiedNameComponents( getMetaData(), command, sCatalog, sSchema, sTable, ::dbtools::eInDataManipulation );
652 0 : aStatement += ::dbtools::composeTableNameForSelect( this, sCatalog, sSchema, sTable );
653 : }
654 0 : break;
655 : case CommandType::QUERY:
656 0 : if ( m_xQueries->hasByName(command) )
657 : {
658 0 : Reference< XPropertySet > xQuery(m_xQueries->getByName(command),UNO_QUERY);
659 0 : xQuery->getPropertyValue(PROPERTY_COMMAND) >>= aStatement;
660 : }
661 0 : break;
662 : default:
663 0 : aStatement = command;
664 : }
665 : // TODO EscapeProcessing
666 0 : return prepareStatement(aStatement);
667 : }
668 :
669 0 : Reference< XInterface > SAL_CALL OConnection::createInstance( const ::rtl::OUString& _sServiceSpecifier ) throw (Exception, RuntimeException)
670 : {
671 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::createInstance" );
672 0 : Reference< XServiceInfo > xRet;
673 0 : if ( SERVICE_NAME_SINGLESELECTQUERYCOMPOSER == _sServiceSpecifier || _sServiceSpecifier == "com.sun.star.sdb.SingleSelectQueryAnalyzer" )
674 : {
675 0 : xRet = new OSingleSelectQueryComposer( getTables(),this, m_aContext );
676 0 : m_aComposers.push_back(WeakReferenceHelper(xRet));
677 : }
678 : else
679 : {
680 0 : if ( !_sServiceSpecifier.isEmpty() )
681 : {
682 0 : TSupportServices::iterator aFind = m_aSupportServices.find(_sServiceSpecifier);
683 0 : if ( aFind == m_aSupportServices.end() )
684 : {
685 0 : Sequence<Any> aArgs(1);
686 0 : Reference<XConnection> xMy(this);
687 0 : aArgs[0] <<= NamedValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ActiveConnection")),makeAny(xMy));
688 0 : aFind = m_aSupportServices.insert(TSupportServices::value_type(_sServiceSpecifier,m_aContext.createComponentWithArguments(_sServiceSpecifier,aArgs))).first;
689 : }
690 0 : return aFind->second;
691 : }
692 : }
693 0 : return Reference< XInterface >(xRet,UNO_QUERY);
694 : }
695 :
696 0 : Reference< XInterface > SAL_CALL OConnection::createInstanceWithArguments( const ::rtl::OUString& _sServiceSpecifier, const Sequence< Any >& /*Arguments*/ ) throw (Exception, RuntimeException)
697 : {
698 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::createInstanceWithArguments" );
699 0 : return createInstance(_sServiceSpecifier);
700 : }
701 :
702 0 : Sequence< ::rtl::OUString > SAL_CALL OConnection::getAvailableServiceNames( ) throw (RuntimeException)
703 : {
704 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::getAvailableServiceNames" );
705 0 : Sequence< ::rtl::OUString > aRet(1);
706 0 : aRet[0] = SERVICE_NAME_SINGLESELECTQUERYCOMPOSER;
707 0 : return aRet;
708 : }
709 :
710 0 : Reference< XTablesSupplier > OConnection::getMasterTables()
711 : {
712 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::getMasterTables" );
713 : // check if out "master connection" can supply tables
714 0 : if(!m_xMasterTables.is())
715 : {
716 : try
717 : {
718 0 : Reference<XDatabaseMetaData> xMeta = getMetaData();
719 0 : if ( xMeta.is() )
720 0 : m_xMasterTables = ::dbtools::getDataDefinitionByURLAndConnection( xMeta->getURL(), m_xMasterConnection, m_aContext.getUNOContext() );
721 : }
722 0 : catch(const SQLException&)
723 : {
724 : }
725 : }
726 0 : return m_xMasterTables;
727 : }
728 :
729 : // XUsersSupplier
730 0 : Reference< XNameAccess > SAL_CALL OConnection::getUsers( ) throw(RuntimeException)
731 : {
732 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::getUsers" );
733 0 : MutexGuard aGuard(m_aMutex);
734 0 : checkDisposed();
735 :
736 0 : Reference<XUsersSupplier> xUsr(getMasterTables(),UNO_QUERY);
737 0 : return xUsr.is() ? xUsr->getUsers() : Reference< XNameAccess >();
738 : }
739 :
740 : // XGroupsSupplier
741 0 : Reference< XNameAccess > SAL_CALL OConnection::getGroups( ) throw(RuntimeException)
742 : {
743 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::getGroups" );
744 0 : MutexGuard aGuard(m_aMutex);
745 0 : checkDisposed();
746 0 : Reference<XGroupsSupplier> xGrp(getMasterTables(),UNO_QUERY);
747 0 : return xGrp.is() ? xGrp->getGroups() : Reference< XNameAccess >();
748 : }
749 :
750 0 : void OConnection::impl_loadConnectionTools_throw()
751 : {
752 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::impl_loadConnectionTools_throw" );
753 0 : Sequence< Any > aArguments( 1 );
754 0 : aArguments[0] <<= NamedValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Connection" ) ), makeAny( Reference< XConnection >( this ) ) );
755 :
756 0 : if ( !m_aContext.createComponentWithArguments( "com.sun.star.sdb.tools.ConnectionTools", aArguments, m_xConnectionTools ) )
757 0 : throw RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "service not registered: com.sun.star.sdb.tools.ConnectionTools" ) ), *this );
758 0 : }
759 :
760 0 : Reference< XTableName > SAL_CALL OConnection::createTableName( ) throw (RuntimeException)
761 : {
762 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::createTableName" );
763 0 : MutexGuard aGuard(m_aMutex);
764 0 : checkDisposed();
765 0 : impl_loadConnectionTools_throw();
766 :
767 0 : return m_xConnectionTools->createTableName();
768 : }
769 :
770 0 : Reference< XObjectNames > SAL_CALL OConnection::getObjectNames( ) throw (RuntimeException)
771 : {
772 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::getObjectNames" );
773 0 : MutexGuard aGuard(m_aMutex);
774 0 : checkDisposed();
775 0 : impl_loadConnectionTools_throw();
776 :
777 0 : return m_xConnectionTools->getObjectNames();
778 : }
779 :
780 0 : Reference< XDataSourceMetaData > SAL_CALL OConnection::getDataSourceMetaData( ) throw (RuntimeException)
781 : {
782 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::getDataSourceMetaData" );
783 0 : MutexGuard aGuard(m_aMutex);
784 0 : checkDisposed();
785 0 : impl_loadConnectionTools_throw();
786 :
787 0 : return m_xConnectionTools->getDataSourceMetaData();
788 : }
789 :
790 0 : Reference< ::com::sun::star::container::XNameAccess > SAL_CALL OConnection::getFieldsByCommandDescriptor( ::sal_Int32 commandType, const ::rtl::OUString& command, ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent >& keepFieldsAlive ) throw (::com::sun::star::sdbc::SQLException, RuntimeException)
791 : {
792 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::getFieldsByCommandDescriptor" );
793 0 : MutexGuard aGuard(m_aMutex);
794 0 : checkDisposed();
795 0 : impl_loadConnectionTools_throw();
796 :
797 0 : return m_xConnectionTools->getFieldsByCommandDescriptor(commandType,command,keepFieldsAlive);
798 : }
799 :
800 0 : Reference< XSingleSelectQueryComposer > SAL_CALL OConnection::getComposer( ::sal_Int32 commandType, const ::rtl::OUString& command ) throw (::com::sun::star::uno::RuntimeException)
801 : {
802 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::getComposer" );
803 0 : MutexGuard aGuard(m_aMutex);
804 0 : checkDisposed();
805 0 : impl_loadConnectionTools_throw();
806 :
807 0 : return m_xConnectionTools->getComposer(commandType,command);
808 : }
809 :
810 0 : void OConnection::impl_checkTableQueryNames_nothrow()
811 : {
812 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::impl_checkTableQueryNames_nothrow" );
813 0 : DatabaseMetaData aMeta( static_cast< XConnection* >( this ) );
814 0 : if ( !aMeta.supportsSubqueriesInFrom() )
815 : // nothing to do
816 0 : return;
817 :
818 : try
819 : {
820 0 : Reference< XNameAccess > xTables( getTables() );
821 0 : Sequence< ::rtl::OUString > aTableNames( xTables->getElementNames() );
822 0 : ::std::set< ::rtl::OUString > aSortedTableNames( aTableNames.getConstArray(), aTableNames.getConstArray() + aTableNames.getLength() );
823 :
824 0 : Reference< XNameAccess > xQueries( getQueries() );
825 0 : Sequence< ::rtl::OUString > aQueryNames( xQueries->getElementNames() );
826 :
827 0 : for ( const ::rtl::OUString* pQueryName = aQueryNames.getConstArray();
828 0 : pQueryName != aQueryNames.getConstArray() + aQueryNames.getLength();
829 : ++pQueryName
830 : )
831 : {
832 0 : if ( aSortedTableNames.find( *pQueryName ) != aSortedTableNames.end() )
833 : {
834 0 : ::rtl::OUString sConflictWarning( DBACORE_RESSTRING( RID_STR_CONFLICTING_NAMES ) );
835 0 : m_aWarnings.appendWarning( sConflictWarning, "01SB0", *this );
836 : }
837 0 : }
838 : }
839 0 : catch( const Exception& )
840 : {
841 : DBG_UNHANDLED_EXCEPTION();
842 0 : }
843 : }
844 :
845 0 : Reference< XGraphic > SAL_CALL OConnection::getTableIcon( const ::rtl::OUString& _TableName, ::sal_Int32 _ColorMode ) throw (RuntimeException)
846 : {
847 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::getTableIcon" );
848 0 : Reference< XGraphic > xReturn;
849 :
850 : // ask our aggregate
851 0 : if ( m_xTableUIProvider.is() )
852 0 : xReturn = m_xTableUIProvider->getTableIcon( _TableName, _ColorMode );
853 :
854 : // ask ourself
855 : // well, we don't have own functionality here ...
856 : // In the future, we might decide to delegate the complete handling to this interface.
857 : // In this case, we would need to load the icon here.
858 :
859 0 : return xReturn;
860 : }
861 :
862 0 : Reference< XInterface > SAL_CALL OConnection::getTableEditor( const Reference< XDatabaseDocumentUI >& _DocumentUI, const ::rtl::OUString& _TableName ) throw (IllegalArgumentException, WrappedTargetException, RuntimeException)
863 : {
864 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::getTableEditor" );
865 0 : Reference< XInterface > xReturn;
866 :
867 : // ask our aggregate
868 0 : if ( m_xTableUIProvider.is() )
869 0 : xReturn = m_xTableUIProvider->getTableEditor( _DocumentUI, _TableName );
870 :
871 : // ask ourself
872 : // well, we don't have own functionality here ...
873 : // In the future, we might decide to delegate the complete handling to this interface.
874 : // In this case, we would need to instantiate an css.sdb.TableDesign here.
875 :
876 0 : return xReturn;
877 : }
878 :
879 : } // namespace dbaccess
880 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|