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