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