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