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