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 //------------------------------------------------------------------------------
getImplementationName()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 //------------------------------------------------------------------------------
supportsService(const::rtl::OUString & _rServiceName)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 //------------------------------------------------------------------------------
getSupportedServiceNames()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 //------------------------------------------------------------------------------
close(void)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 //------------------------------------------------------------------------------
isClosed(void)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 //------------------------------------------------------------------------------
createStatement(void)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 //------------------------------------------------------------------------------
prepareStatement(const rtl::OUString & sql)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 //------------------------------------------------------------------------------
prepareCall(const rtl::OUString & sql)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 //------------------------------------------------------------------------------
nativeSQL(const rtl::OUString & sql)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 //------------------------------------------------------------------------------
setAutoCommit(sal_Bool autoCommit)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 //------------------------------------------------------------------------------
getAutoCommit(void)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 //------------------------------------------------------------------------------
commit(void)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 //------------------------------------------------------------------------------
rollback(void)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 //------------------------------------------------------------------------------
getMetaData(void)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 //------------------------------------------------------------------------------
setReadOnly(sal_Bool readOnly)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 //------------------------------------------------------------------------------
isReadOnly(void)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 //------------------------------------------------------------------------------
setCatalog(const rtl::OUString & catalog)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 //------------------------------------------------------------------------------
getCatalog(void)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 //------------------------------------------------------------------------------
setTransactionIsolation(sal_Int32 level)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 //------------------------------------------------------------------------------
getTransactionIsolation(void)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 //------------------------------------------------------------------------------
getTypeMap(void)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 //------------------------------------------------------------------------------
setTypeMap(const Reference<XNameAccess> & typeMap)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 //==========================================================================
DBG_NAME(OConnection)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 //--------------------------------------------------------------------------
~OConnection()418 OConnection::~OConnection()
419 {
420 delete m_pTables;
421 delete m_pViews;
422 DBG_DTOR(OConnection,NULL);
423 }
424
425
426 // XWarningsSupplier
427 //--------------------------------------------------------------------------
getWarnings()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 //--------------------------------------------------------------------------
clearWarnings()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 {
operator ()dbaccess::__anon20fe79c20111::CompareTypeByName450 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
lcl_copyTypes(TypeBag & _out_rTypes,const Sequence<Type> & _rTypes)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 //--------------------------------------------------------------------------
getTypes()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 //--------------------------------------------------------------------------
getImplementationId()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 //--------------------------------------------------------------------------
queryInterface(const Type & rType)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 //--------------------------------------------------------------------------
acquire()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 //--------------------------------------------------------------------------
release()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 //------------------------------------------------------------------------------
disposing()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 //------------------------------------------------------------------------------
getParent(void)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 //------------------------------------------------------------------------------
setParent(const Reference<XInterface> &)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 //------------------------------------------------------------------------------
createQueryComposer(void)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 // -----------------------------------------------------------------------------
impl_fillTableFilter()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 // -----------------------------------------------------------------------------
refresh(const Reference<XNameAccess> & _rToBeRefreshed)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 //------------------------------------------------------------------------------
getTables()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 // -----------------------------------------------------------------------------
getViews()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 //------------------------------------------------------------------------------
getQueries(void)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 //------------------------------------------------------------------------------
prepareCommand(const::rtl::OUString & command,sal_Int32 commandType)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 // -----------------------------------------------------------------------------
createInstance(const::rtl::OUString & _sServiceSpecifier)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 // -----------------------------------------------------------------------------
createInstanceWithArguments(const::rtl::OUString & _sServiceSpecifier,const Sequence<Any> &)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 // -----------------------------------------------------------------------------
getAvailableServiceNames()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 // -----------------------------------------------------------------------------
getMasterTables()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
getUsers()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
getGroups()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 // -----------------------------------------------------------------------------
impl_loadConnectionTools_throw()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 // -----------------------------------------------------------------------------
createTableName()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 // -----------------------------------------------------------------------------
getObjectNames()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 // -----------------------------------------------------------------------------
getDataSourceMetaData()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 // -----------------------------------------------------------------------------
getFieldsByCommandDescriptor(::sal_Int32 commandType,const::rtl::OUString & command,::com::sun::star::uno::Reference<::com::sun::star::lang::XComponent> & keepFieldsAlive)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 //--------------------------------------------------------------------
getComposer(::sal_Int32 commandType,const::rtl::OUString & command)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 // -----------------------------------------------------------------------------
impl_checkTableQueryNames_nothrow()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 // -----------------------------------------------------------------------------
getTableIcon(const::rtl::OUString & _TableName,::sal_Int32 _ColorMode)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 // -----------------------------------------------------------------------------
getTableEditor(const Reference<XDatabaseDocumentUI> & _DocumentUI,const::rtl::OUString & _TableName)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
947