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