Update ooo320-m1
[ooovba.git] / dbaccess / source / core / dataaccess / connection.cxx
blob4eded6a82cabdf9899f5bac4d8954b6e51fd43aa
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: connection.cxx,v $
10 * $Revision: 1.56 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_dbaccess.hxx"
34 #include "connection.hxx"
35 #include "dbastrings.hrc"
36 #include "datasource.hxx"
37 #include "core_resource.hrc"
38 #include "core_resource.hxx"
39 #include "statement.hxx"
40 #include "preparedstatement.hxx"
41 #include "callablestatement.hxx"
42 #include "ContainerMediator.hxx"
43 #include "SingleSelectQueryComposer.hxx"
44 #include "querycomposer.hxx"
46 /** === begin UNO includes === **/
47 #include <com/sun/star/sdb/CommandType.hpp>
48 #include <com/sun/star/sdbc/XDriverAccess.hpp>
49 #include <com/sun/star/sdbcx/XDataDefinitionSupplier.hpp>
50 #include <com/sun/star/reflection/XProxyFactory.hpp>
51 #include <com/sun/star/beans/NamedValue.hpp>
52 /** === end UNO includes === **/
53 #include <connectivity/dbtools.hxx>
54 #include <connectivity/dbmetadata.hxx>
55 #include <connectivity/dbexception.hxx>
56 #include <tools/debug.hxx>
57 #include <tools/diagnose_ex.h>
58 #include <comphelper/extract.hxx>
59 #include <comphelper/uno3.hxx>
60 #include <comphelper/sequence.hxx>
61 #include <cppuhelper/typeprovider.hxx>
62 #include <rtl/logfile.hxx>
64 using namespace ::com::sun::star::uno;
65 using namespace ::com::sun::star::lang;
66 using namespace ::com::sun::star::util;
67 using namespace ::com::sun::star::sdb;
68 using namespace ::com::sun::star::sdb::application;
69 using namespace ::com::sun::star::sdbc;
70 using namespace ::com::sun::star::sdbcx;
71 using namespace ::com::sun::star::beans;
72 using namespace ::com::sun::star::reflection;
73 using namespace ::com::sun::star::container;
74 using namespace ::com::sun::star::graphic;
75 using namespace ::osl;
76 using namespace ::comphelper;
77 using namespace ::cppu;
78 using namespace ::dbtools;
80 //........................................................................
81 namespace dbaccess
83 //........................................................................
85 //==========================================================================
86 // XServiceInfo
87 //------------------------------------------------------------------------------
88 rtl::OUString OConnection::getImplementationName( ) throw(RuntimeException)
90 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::getImplementationName" );
91 return rtl::OUString::createFromAscii("com.sun.star.comp.dbaccess.Connection");
93 //------------------------------------------------------------------------------
94 sal_Bool OConnection::supportsService( const ::rtl::OUString& _rServiceName ) throw (RuntimeException)
96 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::supportsService" );
97 return findValue(getSupportedServiceNames(), _rServiceName, sal_True).getLength() != 0;
100 //------------------------------------------------------------------------------
101 Sequence< ::rtl::OUString > OConnection::getSupportedServiceNames( ) throw (RuntimeException)
103 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::getSupportedServiceNames" );
104 Sequence< ::rtl::OUString > aSupported = OConnectionWrapper::getSupportedServiceNames();
106 if ( 0 == findValue( aSupported, SERVICE_SDB_CONNECTION, sal_True ).getLength() )
108 sal_Int32 nLen = aSupported.getLength();
109 aSupported.realloc( nLen + 1 );
110 aSupported[ nLen ] = SERVICE_SDB_CONNECTION;
113 return aSupported;
116 // XCloseable
117 //------------------------------------------------------------------------------
118 void OConnection::close(void) throw( SQLException, RuntimeException )
120 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::close" );
121 // being closed is the same as being disposed
122 dispose();
125 //------------------------------------------------------------------------------
126 sal_Bool OConnection::isClosed(void) throw( SQLException, RuntimeException )
128 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::isClosed" );
129 MutexGuard aGuard(m_aMutex);
130 return !m_xMasterConnection.is();
133 // XConnection
134 //------------------------------------------------------------------------------
135 Reference< XStatement > OConnection::createStatement(void) throw( SQLException, RuntimeException )
137 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::createStatement" );
138 MutexGuard aGuard(m_aMutex);
139 checkDisposed();
141 Reference< XStatement > xStatement;
142 Reference< XStatement > xMasterStatement = m_xMasterConnection->createStatement();
143 if ( xMasterStatement.is() )
145 xStatement = new OStatement(this, xMasterStatement);
146 m_aStatements.push_back(WeakReferenceHelper(xStatement));
148 return xStatement;
150 //------------------------------------------------------------------------------
151 Reference< XPreparedStatement > OConnection::prepareStatement(const rtl::OUString& sql) throw( SQLException, RuntimeException )
153 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::prepareStatement" );
154 MutexGuard aGuard(m_aMutex);
155 checkDisposed();
157 // TODO convert the SQL to SQL the driver understands
158 Reference< XPreparedStatement > xStatement;
159 Reference< XPreparedStatement > xMasterStatement = m_xMasterConnection->prepareStatement(sql);
160 if ( xMasterStatement.is() )
162 xStatement = new OPreparedStatement(this, xMasterStatement);
163 m_aStatements.push_back(WeakReferenceHelper(xStatement));
165 return xStatement;
168 //------------------------------------------------------------------------------
169 Reference< XPreparedStatement > OConnection::prepareCall(const rtl::OUString& sql) throw( SQLException, RuntimeException )
171 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::prepareCall" );
172 MutexGuard aGuard(m_aMutex);
173 checkDisposed();
175 Reference< XPreparedStatement > xStatement;
176 Reference< XPreparedStatement > xMasterStatement = m_xMasterConnection->prepareCall(sql);
177 if ( xMasterStatement.is() )
179 xStatement = new OCallableStatement(this, xMasterStatement);
180 m_aStatements.push_back(WeakReferenceHelper(xStatement));
182 return xStatement;
185 //------------------------------------------------------------------------------
186 rtl::OUString OConnection::nativeSQL(const rtl::OUString& sql) throw( SQLException, RuntimeException )
188 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::nativeSQL" );
189 MutexGuard aGuard(m_aMutex);
190 checkDisposed();
191 return m_xMasterConnection->nativeSQL(sql);
194 //------------------------------------------------------------------------------
195 void OConnection::setAutoCommit(sal_Bool autoCommit) throw( SQLException, RuntimeException )
197 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::setAutoCommit" );
198 MutexGuard aGuard(m_aMutex);
199 checkDisposed();
200 m_xMasterConnection->setAutoCommit(autoCommit);
203 //------------------------------------------------------------------------------
204 sal_Bool OConnection::getAutoCommit(void) throw( SQLException, RuntimeException )
206 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::getAutoCommit" );
207 MutexGuard aGuard(m_aMutex);
208 checkDisposed();
209 return m_xMasterConnection->getAutoCommit();
212 //------------------------------------------------------------------------------
213 void OConnection::commit(void) throw( SQLException, RuntimeException )
215 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::commit" );
216 MutexGuard aGuard(m_aMutex);
217 checkDisposed();
218 m_xMasterConnection->commit();
221 //------------------------------------------------------------------------------
222 void OConnection::rollback(void) throw( SQLException, RuntimeException )
224 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::rollback" );
225 MutexGuard aGuard(m_aMutex);
226 checkDisposed();
227 m_xMasterConnection->rollback();
230 //------------------------------------------------------------------------------
231 Reference< XDatabaseMetaData > OConnection::getMetaData(void) throw( SQLException, RuntimeException )
233 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::getMetaData" );
234 MutexGuard aGuard(m_aMutex);
235 checkDisposed();
236 return m_xMasterConnection->getMetaData();
239 //------------------------------------------------------------------------------
240 void OConnection::setReadOnly(sal_Bool readOnly) throw( SQLException, RuntimeException )
242 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::setReadOnly" );
243 MutexGuard aGuard(m_aMutex);
244 checkDisposed();
245 m_xMasterConnection->setReadOnly(readOnly);
248 //------------------------------------------------------------------------------
249 sal_Bool OConnection::isReadOnly(void) throw( SQLException, RuntimeException )
251 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::isReadOnly" );
252 MutexGuard aGuard(m_aMutex);
253 checkDisposed();
254 return m_xMasterConnection->isReadOnly();
257 //------------------------------------------------------------------------------
258 void OConnection::setCatalog(const rtl::OUString& catalog) throw( SQLException, RuntimeException )
260 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::setCatalog" );
261 MutexGuard aGuard(m_aMutex);
262 checkDisposed();
263 m_xMasterConnection->setCatalog(catalog);
266 //------------------------------------------------------------------------------
267 rtl::OUString OConnection::getCatalog(void) throw( SQLException, RuntimeException )
269 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::getCatalog" );
270 MutexGuard aGuard(m_aMutex);
271 checkDisposed();
272 return m_xMasterConnection->getCatalog();
275 //------------------------------------------------------------------------------
276 void OConnection::setTransactionIsolation(sal_Int32 level) throw( SQLException, RuntimeException )
278 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::setTransactionIsolation" );
279 MutexGuard aGuard(m_aMutex);
280 checkDisposed();
281 m_xMasterConnection->setTransactionIsolation(level);
284 //------------------------------------------------------------------------------
285 sal_Int32 OConnection::getTransactionIsolation(void) throw( SQLException, RuntimeException )
287 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::getTransactionIsolation" );
288 MutexGuard aGuard(m_aMutex);
289 checkDisposed();
290 return m_xMasterConnection->getTransactionIsolation();
293 //------------------------------------------------------------------------------
294 Reference< XNameAccess > OConnection::getTypeMap(void) throw( SQLException, RuntimeException )
296 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::getTypeMap" );
297 MutexGuard aGuard(m_aMutex);
298 checkDisposed();
299 return m_xMasterConnection->getTypeMap();
302 //------------------------------------------------------------------------------
303 void OConnection::setTypeMap(const Reference< XNameAccess > & typeMap) throw( SQLException, RuntimeException )
305 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::setTypeMap" );
306 MutexGuard aGuard(m_aMutex);
307 checkDisposed();
308 m_xMasterConnection->setTypeMap(typeMap);
310 //==========================================================================
311 //= OConnection
312 //==========================================================================
313 DBG_NAME(OConnection)
314 //--------------------------------------------------------------------------
315 OConnection::OConnection(ODatabaseSource& _rDB
316 , Reference< XConnection >& _rxMaster
317 , const Reference< XMultiServiceFactory >& _rxORB)
318 :OSubComponent(m_aMutex, static_cast< OWeakObject* >(&_rDB))
319 // as the queries reroute their refcounting to us, this m_aMutex is okey. If the queries
320 // container would do it's own refcounting, it would have to aquire m_pMutex
321 // same for tables
322 ,m_aTableFilter(_rDB.m_pImpl->m_aTableFilter)
323 ,m_aTableTypeFilter(_rDB.m_pImpl->m_aTableTypeFilter)
324 ,m_aContext( _rxORB )
325 ,m_xMasterConnection(_rxMaster)
326 ,m_pTables(NULL)
327 ,m_pViews(NULL)
328 ,m_aWarnings( Reference< XWarningsSupplier >( _rxMaster, UNO_QUERY ) )
329 ,m_nInAppend(0)
330 ,m_bSupportsViews(sal_False)
331 ,m_bSupportsUsers(sal_False)
332 ,m_bSupportsGroups(sal_False)
334 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::OConnection" );
335 DBG_CTOR(OConnection,NULL);
336 osl_incrementInterlockedCount(&m_refCount);
340 Reference< XProxyFactory > xProxyFactory(
341 _rxORB->createInstance(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.reflection.ProxyFactory"))),UNO_QUERY);
342 Reference<XAggregation> xAgg = xProxyFactory->createProxy(_rxMaster.get());
343 setDelegation(xAgg,m_refCount);
344 DBG_ASSERT(m_xConnection.is(), "OConnection::OConnection : invalid master connection !");
346 catch(const Exception&)
348 DBG_UNHANDLED_EXCEPTION();
351 m_xTableUIProvider = m_xTableUIProvider.query( m_xMasterConnection );
355 m_xQueries = new OQueryContainer(Reference< XNameContainer >(_rDB.getQueryDefinitions( ),UNO_QUERY), this,_rxORB, &m_aWarnings);
357 sal_Bool bCase = sal_True;
358 Reference<XDatabaseMetaData> xMeta;
361 xMeta = getMetaData();
362 bCase = xMeta.is() && xMeta->supportsMixedCaseQuotedIdentifiers();
364 catch(SQLException&)
367 Reference< XNameContainer > xTableDefinitions(_rDB.getTables(),UNO_QUERY);
368 m_pTables = new OTableContainer( *this, m_aMutex, this, bCase, xTableDefinitions, this, &m_aWarnings,m_nInAppend );
370 // check if we supports types
371 if ( xMeta.is() )
373 Reference<XResultSet> xRes = xMeta->getTableTypes();
374 if(xRes.is())
376 ::rtl::OUString sView(RTL_CONSTASCII_USTRINGPARAM("VIEW"));
377 Reference<XRow> xRow(xRes,UNO_QUERY);
378 while(xRes->next())
380 ::rtl::OUString sValue = xRow->getString(1);
381 if( !xRow->wasNull() && sValue == sView)
383 m_bSupportsViews = sal_True;
384 break;
388 // some dbs don't support this type so we should ask if a XViewsSupplier is supported
389 if(!m_bSupportsViews)
391 Reference< XViewsSupplier > xMaster(getMasterTables(),UNO_QUERY);
393 if (xMaster.is() && xMaster->getViews().is())
394 m_bSupportsViews = sal_True;
396 if(m_bSupportsViews)
398 m_pViews = new OViewContainer(*this, m_aMutex, this, bCase,this,&m_aWarnings,m_nInAppend);
399 m_pViews->addContainerListener(m_pTables);
400 m_pTables->addContainerListener(m_pViews);
402 m_bSupportsUsers = Reference< XUsersSupplier> (getMasterTables(),UNO_QUERY).is();
403 m_bSupportsGroups = Reference< XGroupsSupplier> (getMasterTables(),UNO_QUERY).is();
405 impl_checkTableQueryNames_nothrow();
408 catch(const Exception& )
410 DBG_UNHANDLED_EXCEPTION();
412 osl_decrementInterlockedCount( &m_refCount );
415 //--------------------------------------------------------------------------
416 OConnection::~OConnection()
418 delete m_pTables;
419 delete m_pViews;
420 DBG_DTOR(OConnection,NULL);
424 // XWarningsSupplier
425 //--------------------------------------------------------------------------
426 Any SAL_CALL OConnection::getWarnings() throw(SQLException, RuntimeException)
428 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::getWarnings" );
429 MutexGuard aGuard(m_aMutex);
430 checkDisposed();
431 return m_aWarnings.getWarnings();
434 //--------------------------------------------------------------------------
435 void SAL_CALL OConnection::clearWarnings( ) throw(SQLException, RuntimeException)
437 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::clearWarnings" );
438 MutexGuard aGuard(m_aMutex);
439 checkDisposed();
440 m_aWarnings.clearWarnings();
443 //--------------------------------------------------------------------------
444 namespace
446 struct CompareTypeByName : public ::std::binary_function< Type, Type, bool >
448 bool operator() ( const Type& _rLHS, const Type& _rRHS ) const
450 return _rLHS.getTypeName() < _rRHS.getTypeName();
453 typedef ::std::set< Type, CompareTypeByName > TypeBag;
455 void lcl_copyTypes( TypeBag& _out_rTypes, const Sequence< Type >& _rTypes )
457 ::std::copy( _rTypes.getConstArray(), _rTypes.getConstArray() + _rTypes.getLength(),
458 ::std::insert_iterator< TypeBag >( _out_rTypes, _out_rTypes.begin() ) );
461 // com::sun::star::lang::XTypeProvider
462 //--------------------------------------------------------------------------
463 Sequence< Type > OConnection::getTypes() throw (RuntimeException)
465 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::getTypes" );
466 TypeBag aNormalizedTypes;
468 lcl_copyTypes( aNormalizedTypes, OSubComponent::getTypes() );
469 lcl_copyTypes( aNormalizedTypes, OConnection_Base::getTypes() );
470 lcl_copyTypes( aNormalizedTypes, ::connectivity::OConnectionWrapper::getTypes() );
472 if ( !m_bSupportsViews )
473 aNormalizedTypes.erase( XViewsSupplier::static_type() );
474 if ( !m_bSupportsUsers )
475 aNormalizedTypes.erase( XUsersSupplier::static_type() );
476 if ( !m_bSupportsGroups )
477 aNormalizedTypes.erase( XGroupsSupplier::static_type() );
479 Sequence< Type > aSupportedTypes( aNormalizedTypes.size() );
480 ::std::copy( aNormalizedTypes.begin(), aNormalizedTypes.end(), aSupportedTypes.getArray() );
481 return aSupportedTypes;
484 //--------------------------------------------------------------------------
485 Sequence< sal_Int8 > OConnection::getImplementationId() throw (RuntimeException)
487 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::getImplementationId" );
488 return getUnoTunnelImplementationId();
491 // com::sun::star::uno::XInterface
492 //--------------------------------------------------------------------------
493 Any OConnection::queryInterface( const Type & rType ) throw (RuntimeException)
495 if ( !m_bSupportsViews && rType.equals( XViewsSupplier::static_type() ) )
496 return Any();
497 else if ( !m_bSupportsUsers && rType.equals( XUsersSupplier::static_type() ) )
498 return Any();
499 else if ( !m_bSupportsGroups && rType.equals( XGroupsSupplier::static_type() ) )
500 return Any();
501 Any aReturn = OSubComponent::queryInterface( rType );
502 if (!aReturn.hasValue())
504 aReturn = OConnection_Base::queryInterface( rType );
505 if (!aReturn.hasValue())
506 aReturn = OConnectionWrapper::queryInterface( rType );
508 return aReturn;
511 //--------------------------------------------------------------------------
512 void OConnection::acquire() throw ()
514 // include this one when you want to see who calls it (call graph)
515 //RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::acquire" );
516 OSubComponent::acquire();
519 //--------------------------------------------------------------------------
520 void OConnection::release() throw ()
522 // include this one when you want to see who calls it (call graph)
523 //RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::release" );
524 OSubComponent::release();
527 // OSubComponent
528 //------------------------------------------------------------------------------
529 void OConnection::disposing()
531 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::disposing" );
532 MutexGuard aGuard(m_aMutex);
534 OSubComponent::disposing();
535 OConnectionWrapper::disposing();
537 OWeakRefArrayIterator aEnd = m_aStatements.end();
538 for (OWeakRefArrayIterator i = m_aStatements.begin(); aEnd != i; ++i)
540 Reference<XComponent> xComp(i->get(),UNO_QUERY);
541 ::comphelper::disposeComponent(xComp);
543 m_aStatements.clear();
544 m_xMasterTables = NULL;
546 if(m_pTables)
547 m_pTables->dispose();
548 if(m_pViews)
549 m_pViews->dispose();
551 ::comphelper::disposeComponent(m_xQueries);
553 OWeakRefArrayIterator aComposerEnd = m_aComposers.end();
554 for (OWeakRefArrayIterator j = m_aComposers.begin(); aComposerEnd != j; ++j)
556 Reference<XComponent> xComp(j->get(),UNO_QUERY);
557 ::comphelper::disposeComponent(xComp);
560 m_aComposers.clear();
564 if (m_xMasterConnection.is())
565 m_xMasterConnection->close();
567 catch(Exception)
570 m_xMasterConnection = NULL;
573 // XChild
574 //------------------------------------------------------------------------------
575 Reference< XInterface > OConnection::getParent(void) throw( RuntimeException )
577 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::getParent" );
578 MutexGuard aGuard(m_aMutex);
579 checkDisposed();
580 return m_xParent;
583 //------------------------------------------------------------------------------
584 void OConnection::setParent(const Reference< XInterface > & /*Parent*/) throw( NoSupportException, RuntimeException )
586 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::setParent" );
587 throw NoSupportException();
590 // XSQLQueryComposerFactory
591 //------------------------------------------------------------------------------
592 Reference< XSQLQueryComposer > OConnection::createQueryComposer(void) throw( RuntimeException )
594 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::createQueryComposer" );
595 MutexGuard aGuard(m_aMutex);
596 checkDisposed();
598 // Reference< XNumberFormatsSupplier > xSupplier = pParent->getNumberFormatsSupplier();
599 Reference< XSQLQueryComposer > xComposer( new OQueryComposer( this ) );
600 m_aComposers.push_back(WeakReferenceHelper(xComposer));
601 return xComposer;
603 // -----------------------------------------------------------------------------
604 void OConnection::refresh(const Reference< XNameAccess >& _rToBeRefreshed)
606 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::refresh" );
607 if ( _rToBeRefreshed == Reference< XNameAccess >(m_pTables) )
609 if (!m_pTables->isInitialized())
611 // check if our "master connection" can supply tables
612 getMasterTables();
614 if (m_xMasterTables.is() && m_xMasterTables->getTables().is())
615 { // yes -> wrap them
616 m_pTables->construct(m_xMasterTables->getTables(),m_aTableFilter, m_aTableTypeFilter);
618 else
619 { // no -> use an own container
620 m_pTables->construct(m_aTableFilter, m_aTableTypeFilter);
624 else if ( _rToBeRefreshed == Reference< XNameAccess >(m_pViews) )
626 if (!m_pViews->isInitialized())
628 // check if our "master connection" can supply tables
629 Reference< XViewsSupplier > xMaster(getMasterTables(),UNO_QUERY);
631 if (xMaster.is() && xMaster->getViews().is())
632 m_pViews->construct(xMaster->getViews(),m_aTableFilter, m_aTableTypeFilter);
633 else
634 m_pViews->construct(m_aTableFilter, m_aTableTypeFilter);
638 // -----------------------------------------------------------------------------
640 // XTablesSupplier
641 //------------------------------------------------------------------------------
642 Reference< XNameAccess > OConnection::getTables() throw( RuntimeException )
644 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::getTables" );
645 MutexGuard aGuard(m_aMutex);
646 checkDisposed();
648 refresh(m_pTables);
650 return m_pTables;
652 // -----------------------------------------------------------------------------
653 Reference< XNameAccess > SAL_CALL OConnection::getViews( ) throw(RuntimeException)
655 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::getViews" );
656 MutexGuard aGuard(m_aMutex);
657 checkDisposed();
659 refresh(m_pViews);
661 return m_pViews;
663 // XQueriesSupplier
664 //------------------------------------------------------------------------------
665 Reference< XNameAccess > OConnection::getQueries(void) throw( RuntimeException )
667 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::getQueries" );
668 MutexGuard aGuard(m_aMutex);
669 checkDisposed();
671 return m_xQueries;
674 // ::com::sun::star::sdb::XCommandPreparation
675 //------------------------------------------------------------------------------
676 Reference< XPreparedStatement > SAL_CALL OConnection::prepareCommand( const ::rtl::OUString& command, sal_Int32 commandType ) throw(::com::sun::star::sdbc::SQLException, RuntimeException)
678 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::prepareCommand" );
679 MutexGuard aGuard(m_aMutex);
680 checkDisposed();
682 rtl::OUString aStatement;
683 switch (commandType)
685 case CommandType::TABLE:
687 aStatement = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SELECT * FROM "));
689 ::rtl::OUString sCatalog, sSchema, sTable;
690 ::dbtools::qualifiedNameComponents( getMetaData(), command, sCatalog, sSchema, sTable, ::dbtools::eInDataManipulation );
691 aStatement += ::dbtools::composeTableNameForSelect( this, sCatalog, sSchema, sTable );
693 break;
694 case CommandType::QUERY:
695 if ( m_xQueries->hasByName(command) )
697 Reference< XPropertySet > xQuery(m_xQueries->getByName(command),UNO_QUERY);
698 xQuery->getPropertyValue(PROPERTY_COMMAND) >>= aStatement;
700 break;
701 default:
702 aStatement = command;
704 // TODO EscapeProcessing
705 return prepareStatement(aStatement);
707 // -----------------------------------------------------------------------------
708 Reference< XInterface > SAL_CALL OConnection::createInstance( const ::rtl::OUString& _sServiceSpecifier ) throw (Exception, RuntimeException)
710 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::createInstance" );
711 Reference< XServiceInfo > xRet;
712 if ( ( SERVICE_NAME_SINGLESELECTQUERYCOMPOSER == _sServiceSpecifier )
713 || ( _sServiceSpecifier.equalsAscii( "com.sun.star.sdb.SingleSelectQueryAnalyzer" ) )
716 xRet = new OSingleSelectQueryComposer( getTables(),this, m_aContext );
717 m_aComposers.push_back(WeakReferenceHelper(xRet));
719 return Reference< XInterface >(xRet,UNO_QUERY);
721 // -----------------------------------------------------------------------------
722 Reference< XInterface > SAL_CALL OConnection::createInstanceWithArguments( const ::rtl::OUString& _sServiceSpecifier, const Sequence< Any >& /*Arguments*/ ) throw (Exception, RuntimeException)
724 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::createInstanceWithArguments" );
725 return createInstance(_sServiceSpecifier);
727 // -----------------------------------------------------------------------------
728 Sequence< ::rtl::OUString > SAL_CALL OConnection::getAvailableServiceNames( ) throw (RuntimeException)
730 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::getAvailableServiceNames" );
731 Sequence< ::rtl::OUString > aRet(1);
732 aRet[0] = SERVICE_NAME_SINGLESELECTQUERYCOMPOSER;
733 return aRet;
735 // -----------------------------------------------------------------------------
736 Reference< XTablesSupplier > OConnection::getMasterTables()
738 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::getMasterTables" );
739 // check if out "master connection" can supply tables
740 if(!m_xMasterTables.is())
744 Reference<XDatabaseMetaData> xMeta = getMetaData();
745 if ( xMeta.is() )
746 m_xMasterTables = ::dbtools::getDataDefinitionByURLAndConnection( xMeta->getURL(), m_xMasterConnection, m_aContext.getLegacyServiceFactory() );
748 catch(SQLException&)
752 return m_xMasterTables;
754 // -----------------------------------------------------------------------------
755 // XUsersSupplier
756 Reference< XNameAccess > SAL_CALL OConnection::getUsers( ) throw(RuntimeException)
758 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::getUsers" );
759 MutexGuard aGuard(m_aMutex);
760 checkDisposed();
762 Reference<XUsersSupplier> xUsr(getMasterTables(),UNO_QUERY);
763 return xUsr.is() ? xUsr->getUsers() : Reference< XNameAccess >();
765 // -----------------------------------------------------------------------------
766 // XGroupsSupplier
767 Reference< XNameAccess > SAL_CALL OConnection::getGroups( ) throw(RuntimeException)
769 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::getGroups" );
770 MutexGuard aGuard(m_aMutex);
771 checkDisposed();
772 Reference<XGroupsSupplier> xGrp(getMasterTables(),UNO_QUERY);
773 return xGrp.is() ? xGrp->getGroups() : Reference< XNameAccess >();
776 // -----------------------------------------------------------------------------
777 void OConnection::impl_loadConnectionTools_throw()
779 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::impl_loadConnectionTools_throw" );
780 Sequence< Any > aArguments( 1 );
781 aArguments[0] <<= NamedValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Connection" ) ), makeAny( Reference< XConnection >( this ) ) );
783 if ( !m_aContext.createComponentWithArguments( "com.sun.star.sdb.tools.ConnectionTools", aArguments, m_xConnectionTools ) )
784 throw RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "service not registered: com.sun.star.sdb.tools.ConnectionTools" ) ), *this );
787 // -----------------------------------------------------------------------------
788 Reference< tools::XTableName > SAL_CALL OConnection::createTableName( ) throw (RuntimeException)
790 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::createTableName" );
791 MutexGuard aGuard(m_aMutex);
792 checkDisposed();
793 impl_loadConnectionTools_throw();
795 return m_xConnectionTools->createTableName();
798 // -----------------------------------------------------------------------------
799 Reference< tools::XObjectNames > SAL_CALL OConnection::getObjectNames( ) throw (RuntimeException)
801 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::getObjectNames" );
802 MutexGuard aGuard(m_aMutex);
803 checkDisposed();
804 impl_loadConnectionTools_throw();
806 return m_xConnectionTools->getObjectNames();
809 // -----------------------------------------------------------------------------
810 Reference< tools::XDataSourceMetaData > SAL_CALL OConnection::getDataSourceMetaData( ) throw (RuntimeException)
812 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::getDataSourceMetaData" );
813 MutexGuard aGuard(m_aMutex);
814 checkDisposed();
815 impl_loadConnectionTools_throw();
817 return m_xConnectionTools->getDataSourceMetaData();
819 // -----------------------------------------------------------------------------
820 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)
822 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::getFieldsByCommandDescriptor" );
823 MutexGuard aGuard(m_aMutex);
824 checkDisposed();
825 impl_loadConnectionTools_throw();
827 return m_xConnectionTools->getFieldsByCommandDescriptor(commandType,command,keepFieldsAlive);
829 //--------------------------------------------------------------------
830 Reference< XSingleSelectQueryComposer > SAL_CALL OConnection::getComposer( ::sal_Int32 commandType, const ::rtl::OUString& command ) throw (::com::sun::star::uno::RuntimeException)
832 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::getComposer" );
833 MutexGuard aGuard(m_aMutex);
834 checkDisposed();
835 impl_loadConnectionTools_throw();
837 return m_xConnectionTools->getComposer(commandType,command);
840 // -----------------------------------------------------------------------------
841 void OConnection::impl_checkTableQueryNames_nothrow()
843 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::impl_checkTableQueryNames_nothrow" );
844 DatabaseMetaData aMeta( static_cast< XConnection* >( this ) );
845 if ( !aMeta.supportsSubqueriesInFrom() )
846 // nothing to do
847 return;
851 Reference< XNameAccess > xTables( getTables() );
852 Sequence< ::rtl::OUString > aTableNames( xTables->getElementNames() );
853 ::std::set< ::rtl::OUString > aSortedTableNames( aTableNames.getConstArray(), aTableNames.getConstArray() + aTableNames.getLength() );
855 Reference< XNameAccess > xQueries( getQueries() );
856 Sequence< ::rtl::OUString > aQueryNames( xQueries->getElementNames() );
858 for ( const ::rtl::OUString* pQueryName = aQueryNames.getConstArray();
859 pQueryName != aQueryNames.getConstArray() + aQueryNames.getLength();
860 ++pQueryName
863 if ( aSortedTableNames.find( *pQueryName ) != aSortedTableNames.end() )
865 ::rtl::OUString sConflictWarning( DBACORE_RESSTRING( RID_STR_CONFLICTING_NAMES ) );
866 m_aWarnings.appendWarning( sConflictWarning, "01SB0", *this );
870 catch( const Exception& )
872 DBG_UNHANDLED_EXCEPTION();
876 // -----------------------------------------------------------------------------
877 Reference< XGraphic > SAL_CALL OConnection::getTableIcon( const ::rtl::OUString& _TableName, ::sal_Int32 _ColorMode ) throw (RuntimeException)
879 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::getTableIcon" );
880 Reference< XGraphic > xReturn;
882 // ask our aggregate
883 if ( m_xTableUIProvider.is() )
884 xReturn = m_xTableUIProvider->getTableIcon( _TableName, _ColorMode );
886 // ask ourself
887 // well, we don't have own functionality here ...
888 // In the future, we might decide to delegate the complete handling to this interface.
889 // In this case, we would need to load the icon here.
891 return xReturn;
894 // -----------------------------------------------------------------------------
895 Reference< XInterface > SAL_CALL OConnection::getTableEditor( const Reference< XDatabaseDocumentUI >& _DocumentUI, const ::rtl::OUString& _TableName ) throw (IllegalArgumentException, WrappedTargetException, RuntimeException)
897 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dataaccess", "Ocke.Janssen@sun.com", "OConnection::getTableEditor" );
898 Reference< XInterface > xReturn;
900 // ask our aggregate
901 if ( m_xTableUIProvider.is() )
902 xReturn = m_xTableUIProvider->getTableEditor( _DocumentUI, _TableName );
904 // ask ourself
905 // well, we don't have own functionality here ...
906 // In the future, we might decide to delegate the complete handling to this interface.
907 // In this case, we would need to instantiate an css.sdb.TableDesign here.
909 return xReturn;
913 //........................................................................
914 } // namespace dbaccess
915 //........................................................................