Update git submodules
[LibreOffice.git] / dbaccess / source / core / dataaccess / connection.cxx
blobd1543a36c0366a1b11ef6f4094118ace08e71876
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <sal/config.h>
22 #include <iterator>
24 #include <connection.hxx>
25 #include "datasource.hxx"
26 #include <strings.hrc>
27 #include <strings.hxx>
28 #include <core_resource.hxx>
29 #include <statement.hxx>
30 #include <preparedstatement.hxx>
31 #include <callablestatement.hxx>
32 #include <SingleSelectQueryComposer.hxx>
33 #include <querycomposer.hxx>
35 #include <com/sun/star/lang/NoSupportException.hpp>
36 #include <com/sun/star/sdb/CommandType.hpp>
37 #include <com/sun/star/sdb/tools/ConnectionTools.hpp>
38 #include <com/sun/star/reflection/ProxyFactory.hpp>
39 #include <com/sun/star/beans/NamedValue.hpp>
40 #include <connectivity/dbtools.hxx>
41 #include <connectivity/dbmetadata.hxx>
42 #include <comphelper/diagnose_ex.hxx>
43 #include <osl/diagnose.h>
44 #include <comphelper/sequence.hxx>
45 #include <comphelper/types.hxx>
46 #include <cppuhelper/supportsservice.hxx>
48 using namespace ::com::sun::star::uno;
49 using namespace ::com::sun::star::lang;
50 using namespace ::com::sun::star::sdb;
51 using namespace ::com::sun::star::sdb::application;
52 using namespace ::com::sun::star::sdbc;
53 using namespace ::com::sun::star::sdbcx;
54 using namespace ::com::sun::star::beans;
55 using namespace ::com::sun::star::reflection;
56 using namespace ::com::sun::star::container;
57 using namespace ::com::sun::star::graphic;
58 using namespace ::osl;
59 using namespace ::comphelper;
60 using namespace ::cppu;
61 using namespace ::dbtools;
63 using ::com::sun::star::sdb::tools::XTableName;
64 using ::com::sun::star::sdb::tools::XObjectNames;
65 using ::com::sun::star::sdb::tools::XDataSourceMetaData;
67 namespace dbaccess
70 // XServiceInfo
71 OUString OConnection::getImplementationName( )
73 return u"com.sun.star.comp.dbaccess.Connection"_ustr;
76 sal_Bool OConnection::supportsService( const OUString& _rServiceName )
78 return cppu::supportsService(this, _rServiceName);
81 Sequence< OUString > OConnection::getSupportedServiceNames( )
83 Sequence< OUString > aSupported = OConnectionWrapper::getSupportedServiceNames();
85 if ( comphelper::findValue( aSupported, SERVICE_SDB_CONNECTION ) == -1 )
87 sal_Int32 nLen = aSupported.getLength();
88 aSupported.realloc( nLen + 1 );
89 aSupported.getArray()[ nLen ] = SERVICE_SDB_CONNECTION;
92 return aSupported;
95 // XCloseable
96 void OConnection::close()
98 // being closed is the same as being disposed
99 dispose();
102 sal_Bool OConnection::isClosed()
104 MutexGuard aGuard(m_aMutex);
105 return !m_xMasterConnection.is();
108 // XConnection
109 Reference< XStatement > OConnection::createStatement()
111 MutexGuard aGuard(m_aMutex);
112 checkDisposed();
114 Reference< XStatement > xStatement;
115 Reference< XStatement > xMasterStatement = m_xMasterConnection->createStatement();
116 if ( xMasterStatement.is() )
118 xStatement = new OStatement(this, xMasterStatement);
119 m_aStatements.emplace_back(xStatement);
121 return xStatement;
124 Reference< XPreparedStatement > OConnection::prepareStatement(const OUString& sql)
126 MutexGuard aGuard(m_aMutex);
127 checkDisposed();
129 // TODO convert the SQL to SQL the driver understands
130 Reference< XPreparedStatement > xStatement;
131 Reference< XPreparedStatement > xMasterStatement = m_xMasterConnection->prepareStatement(sql);
132 if ( xMasterStatement.is() )
134 xStatement = new OPreparedStatement(this, xMasterStatement);
135 m_aStatements.emplace_back(xStatement);
137 return xStatement;
140 Reference< XPreparedStatement > OConnection::prepareCall(const OUString& sql)
142 MutexGuard aGuard(m_aMutex);
143 checkDisposed();
145 Reference< XPreparedStatement > xStatement;
146 Reference< XPreparedStatement > xMasterStatement = m_xMasterConnection->prepareCall(sql);
147 if ( xMasterStatement.is() )
149 xStatement = new OCallableStatement(this, xMasterStatement);
150 m_aStatements.emplace_back(xStatement);
152 return xStatement;
155 OUString OConnection::nativeSQL(const OUString& sql)
157 MutexGuard aGuard(m_aMutex);
158 checkDisposed();
159 return m_xMasterConnection->nativeSQL(sql);
162 void OConnection::setAutoCommit(sal_Bool autoCommit)
164 MutexGuard aGuard(m_aMutex);
165 checkDisposed();
166 m_xMasterConnection->setAutoCommit(autoCommit);
169 sal_Bool OConnection::getAutoCommit()
171 MutexGuard aGuard(m_aMutex);
172 checkDisposed();
173 return m_xMasterConnection->getAutoCommit();
176 void OConnection::commit()
178 MutexGuard aGuard(m_aMutex);
179 checkDisposed();
180 m_xMasterConnection->commit();
183 void OConnection::rollback()
185 MutexGuard aGuard(m_aMutex);
186 checkDisposed();
187 m_xMasterConnection->rollback();
190 Reference< XDatabaseMetaData > OConnection::getMetaData()
192 MutexGuard aGuard(m_aMutex);
193 checkDisposed();
194 return m_xMasterConnection->getMetaData();
197 void OConnection::setReadOnly(sal_Bool readOnly)
199 MutexGuard aGuard(m_aMutex);
200 checkDisposed();
201 m_xMasterConnection->setReadOnly(readOnly);
204 sal_Bool OConnection::isReadOnly()
206 MutexGuard aGuard(m_aMutex);
207 checkDisposed();
208 return m_xMasterConnection->isReadOnly();
211 void OConnection::setCatalog(const OUString& catalog)
213 MutexGuard aGuard(m_aMutex);
214 checkDisposed();
215 m_xMasterConnection->setCatalog(catalog);
218 OUString OConnection::getCatalog()
220 MutexGuard aGuard(m_aMutex);
221 checkDisposed();
222 return m_xMasterConnection->getCatalog();
225 void OConnection::setTransactionIsolation(sal_Int32 level)
227 MutexGuard aGuard(m_aMutex);
228 checkDisposed();
229 m_xMasterConnection->setTransactionIsolation(level);
232 sal_Int32 OConnection::getTransactionIsolation()
234 MutexGuard aGuard(m_aMutex);
235 checkDisposed();
236 return m_xMasterConnection->getTransactionIsolation();
239 Reference< XNameAccess > OConnection::getTypeMap()
241 MutexGuard aGuard(m_aMutex);
242 checkDisposed();
243 return m_xMasterConnection->getTypeMap();
246 void OConnection::setTypeMap(const Reference< XNameAccess > & typeMap)
248 MutexGuard aGuard(m_aMutex);
249 checkDisposed();
250 m_xMasterConnection->setTypeMap(typeMap);
253 // OConnection
255 OConnection::OConnection(ODatabaseSource& _rDB
256 , Reference< XConnection > const & _rxMaster
257 , const Reference< XComponentContext >& _rxORB)
258 :m_xParent(&_rDB)
259 ,m_aTableFilter(_rDB.m_pImpl->m_aTableFilter)
260 ,m_aTableTypeFilter(_rDB.m_pImpl->m_aTableTypeFilter)
261 ,m_aContext( _rxORB )
262 ,m_xMasterConnection(_rxMaster)
263 ,m_aWarnings( Reference< XWarningsSupplier >( _rxMaster, UNO_QUERY ) )
264 ,m_nInAppend(0)
265 ,m_bSupportsViews(false)
266 ,m_bSupportsUsers(false)
267 ,m_bSupportsGroups(false)
269 osl_atomic_increment(&m_refCount);
273 Reference< XProxyFactory > xProxyFactory = ProxyFactory::create( m_aContext );
274 Reference<XAggregation> xAgg = xProxyFactory->createProxy(_rxMaster);
275 setDelegation(xAgg);
276 OSL_ENSURE(m_xConnection.is(), "OConnection::OConnection : invalid master connection !");
278 catch(const Exception&)
280 DBG_UNHANDLED_EXCEPTION("dbaccess");
283 m_xTableUIProvider.set(m_xMasterConnection, css::uno::UNO_QUERY);
287 m_xQueries = OQueryContainer::create(Reference< XNameContainer >(_rDB.getQueryDefinitions(), UNO_QUERY), this, _rxORB, &m_aWarnings).get();
289 bool bCase = true;
290 Reference<XDatabaseMetaData> xMeta;
293 xMeta = getMetaData();
294 bCase = xMeta.is() && xMeta->supportsMixedCaseQuotedIdentifiers();
296 catch(const SQLException&)
299 Reference< XNameContainer > xTableDefinitions(_rDB.getTables(),UNO_QUERY);
300 m_pTables.reset( new OTableContainer( *this, m_aMutex, this, bCase, xTableDefinitions, this, m_nInAppend ) );
302 // check if we support types
303 if ( xMeta.is() )
305 Reference<XResultSet> xRes = xMeta->getTableTypes();
306 if(xRes.is())
308 Reference<XRow> xRow(xRes,UNO_QUERY);
309 while(xRes->next())
311 OUString sValue = xRow->getString(1);
312 if( !xRow->wasNull() && sValue == "VIEW")
314 m_bSupportsViews = true;
315 break;
319 // tdf#130564: getTableTypes retrieves only the table types of the current database and not all the possible table types
320 // provided by the DBMS. JDBC would need a new function, something like "supportsViews()"
321 // do the same for MySQL/MariaDB since we're on it
322 OUString strDbProductName = xMeta->getDatabaseProductName();
323 if (!m_bSupportsViews && xMeta->getURL().startsWith("sdbc:odbc:") &&
324 (strDbProductName == "PostgreSQL" || strDbProductName == "MySQL")
327 m_bSupportsViews = true;
329 // some dbs don't support this type so we should ask if a XViewsSupplier is supported
330 if(!m_bSupportsViews)
332 Reference< XViewsSupplier > xMaster(getMasterTables(),UNO_QUERY);
334 if (xMaster.is() && xMaster->getViews().is())
335 m_bSupportsViews = true;
337 if(m_bSupportsViews)
339 m_pViews.reset( new OViewContainer(*this, m_aMutex, this, bCase, this, m_nInAppend) );
340 m_pViews->addContainerListener(m_pTables.get());
341 m_pTables->addContainerListener(m_pViews.get());
343 m_bSupportsUsers = Reference< XUsersSupplier> (getMasterTables(),UNO_QUERY).is();
344 m_bSupportsGroups = Reference< XGroupsSupplier> (getMasterTables(),UNO_QUERY).is();
346 impl_checkTableQueryNames_nothrow();
349 catch(const Exception& )
351 DBG_UNHANDLED_EXCEPTION("dbaccess");
353 osl_atomic_decrement( &m_refCount );
356 OConnection::~OConnection()
360 // XWarningsSupplier
361 Any SAL_CALL OConnection::getWarnings()
363 MutexGuard aGuard(m_aMutex);
364 checkDisposed();
365 return m_aWarnings.getWarnings();
368 void SAL_CALL OConnection::clearWarnings( )
370 MutexGuard aGuard(m_aMutex);
371 checkDisposed();
372 m_aWarnings.clearWarnings();
375 namespace
377 struct CompareTypeByName
379 bool operator() ( const Type& _rLHS, const Type& _rRHS ) const
381 return _rLHS.getTypeName() < _rRHS.getTypeName();
384 typedef std::set< Type, CompareTypeByName > TypeBag;
386 void lcl_copyTypes( TypeBag& _out_rTypes, const Sequence< Type >& _rTypes )
388 std::copy( _rTypes.begin(), _rTypes.end(),
389 std::insert_iterator< TypeBag >( _out_rTypes, _out_rTypes.begin() ) );
393 // css::lang::XTypeProvider
394 Sequence< Type > OConnection::getTypes()
396 TypeBag aNormalizedTypes;
398 lcl_copyTypes( aNormalizedTypes, OConnection_Base::getTypes() );
400 if ( !m_bSupportsViews )
401 aNormalizedTypes.erase( cppu::UnoType<XViewsSupplier>::get() );
402 if ( !m_bSupportsUsers )
403 aNormalizedTypes.erase( cppu::UnoType<XUsersSupplier>::get() );
404 if ( !m_bSupportsGroups )
405 aNormalizedTypes.erase( cppu::UnoType<XGroupsSupplier>::get() );
407 return comphelper::containerToSequence(aNormalizedTypes);
410 // css::uno::XInterface
411 Any OConnection::queryInterface( const Type & rType )
413 if ( !m_bSupportsViews && rType.equals( cppu::UnoType<XViewsSupplier>::get() ) )
414 return Any();
415 else if ( !m_bSupportsUsers && rType.equals( cppu::UnoType<XUsersSupplier>::get() ) )
416 return Any();
417 else if ( !m_bSupportsGroups && rType.equals( cppu::UnoType<XGroupsSupplier>::get() ) )
418 return Any();
419 return OConnection_Base::queryInterface( rType );
422 // OConnection_Base
423 void OConnection::disposing()
425 MutexGuard aGuard(m_aMutex);
427 OConnection_Base::disposing();
429 for (auto const& statement : m_aStatements)
431 Reference<XComponent> xComp(statement.get(),UNO_QUERY);
432 ::comphelper::disposeComponent(xComp);
434 m_aStatements.clear();
435 m_xMasterTables = nullptr;
437 if(m_pTables)
438 m_pTables->dispose();
439 if(m_pViews)
440 m_pViews->dispose();
442 ::comphelper::disposeComponent(m_xQueries);
444 for (auto const& composer : m_aComposers)
446 Reference<XComponent> xComp(composer.get(),UNO_QUERY);
447 ::comphelper::disposeComponent(xComp);
450 m_aComposers.clear();
454 if (m_xMasterConnection.is())
455 m_xMasterConnection->close();
457 catch(const Exception&)
460 m_xMasterConnection = nullptr;
463 // XChild
464 Reference< XInterface > OConnection::getParent()
466 MutexGuard aGuard(m_aMutex);
467 checkDisposed();
468 return static_cast<OWeakObject*>(m_xParent.get().get());
471 void OConnection::setParent(const Reference< XInterface > & /*Parent*/)
473 throw NoSupportException();
476 // XSQLQueryComposerFactory
477 Reference< XSQLQueryComposer > OConnection::createQueryComposer()
479 MutexGuard aGuard(m_aMutex);
480 checkDisposed();
482 // Reference< XNumberFormatsSupplier > xSupplier = pParent->getNumberFormatsSupplier();
483 Reference< XSQLQueryComposer > xComposer( new OQueryComposer( this ) );
484 m_aComposers.emplace_back(xComposer);
485 return xComposer;
488 void OConnection::impl_fillTableFilter()
490 Reference<XPropertySet> xProp(getParent(),UNO_QUERY);
491 if ( xProp.is() )
493 xProp->getPropertyValue(PROPERTY_TABLEFILTER) >>= m_aTableFilter;
494 xProp->getPropertyValue(PROPERTY_TABLETYPEFILTER) >>= m_aTableTypeFilter;
498 void OConnection::refresh(const Reference< XNameAccess >& _rToBeRefreshed)
500 if ( _rToBeRefreshed == Reference< XNameAccess >(m_pTables.get()) )
502 if (m_pTables && !m_pTables->isInitialized())
504 impl_fillTableFilter();
505 // check if our "master connection" can supply tables
506 getMasterTables();
508 if (m_xMasterTables.is() && m_xMasterTables->getTables().is())
509 { // yes -> wrap them
510 m_pTables->construct(m_xMasterTables->getTables(),m_aTableFilter, m_aTableTypeFilter);
512 else
513 { // no -> use an own container
514 m_pTables->construct(m_aTableFilter, m_aTableTypeFilter);
518 else if ( _rToBeRefreshed == Reference< XNameAccess >(m_pViews.get()) )
520 if (m_pViews && !m_pViews->isInitialized())
522 impl_fillTableFilter();
523 // check if our "master connection" can supply tables
524 Reference< XViewsSupplier > xMaster(getMasterTables(),UNO_QUERY);
526 if (xMaster.is() && xMaster->getViews().is())
527 m_pViews->construct(xMaster->getViews(),m_aTableFilter, m_aTableTypeFilter);
528 else
529 m_pViews->construct(m_aTableFilter, m_aTableTypeFilter);
534 // XTablesSupplier
535 Reference< XNameAccess > OConnection::getTables()
537 MutexGuard aGuard(m_aMutex);
538 checkDisposed();
540 refresh(m_pTables.get());
542 return m_pTables.get();
545 Reference< XNameAccess > SAL_CALL OConnection::getViews( )
547 MutexGuard aGuard(m_aMutex);
548 checkDisposed();
550 refresh(m_pViews.get());
552 return m_pViews.get();
555 // XQueriesSupplier
556 Reference< XNameAccess > OConnection::getQueries()
558 MutexGuard aGuard(m_aMutex);
559 checkDisposed();
561 return m_xQueries;
564 // css::sdb::XCommandPreparation
565 Reference< XPreparedStatement > SAL_CALL OConnection::prepareCommand( const OUString& command, sal_Int32 commandType )
567 MutexGuard aGuard(m_aMutex);
568 checkDisposed();
570 OUString aStatement;
571 switch (commandType)
573 case CommandType::TABLE:
575 aStatement = "SELECT * FROM ";
577 OUString sCatalog, sSchema, sTable;
578 ::dbtools::qualifiedNameComponents( getMetaData(), command, sCatalog, sSchema, sTable, ::dbtools::EComposeRule::InDataManipulation );
579 aStatement += ::dbtools::composeTableNameForSelect( this, sCatalog, sSchema, sTable );
581 break;
582 case CommandType::QUERY:
583 if ( m_xQueries->hasByName(command) )
585 Reference< XPropertySet > xQuery(m_xQueries->getByName(command),UNO_QUERY);
586 xQuery->getPropertyValue(PROPERTY_COMMAND) >>= aStatement;
588 break;
589 default:
590 aStatement = command;
592 // TODO EscapeProcessing
593 return prepareStatement(aStatement);
596 Reference< XInterface > SAL_CALL OConnection::createInstance( const OUString& _sServiceSpecifier )
598 Reference< XServiceInfo > xRet;
599 if ( SERVICE_NAME_SINGLESELECTQUERYCOMPOSER == _sServiceSpecifier || _sServiceSpecifier == "com.sun.star.sdb.SingleSelectQueryAnalyzer" )
601 xRet = new OSingleSelectQueryComposer( getTables(),this, m_aContext );
602 m_aComposers.emplace_back(xRet);
604 else
606 if ( !_sServiceSpecifier.isEmpty() )
608 TSupportServices::const_iterator aFind = m_aSupportServices.find(_sServiceSpecifier);
609 if ( aFind == m_aSupportServices.end() )
611 Reference<XConnection> xMy(this);
612 Sequence<Any> aArgs{ Any(NamedValue(u"ActiveConnection"_ustr,Any(xMy))) };
613 aFind = m_aSupportServices.emplace(
614 _sServiceSpecifier,
615 m_aContext->getServiceManager()->createInstanceWithArgumentsAndContext(_sServiceSpecifier, aArgs, m_aContext)
616 ).first;
618 return aFind->second;
621 return Reference<XInterface>(xRet, UNO_QUERY);
624 Reference< XInterface > SAL_CALL OConnection::createInstanceWithArguments( const OUString& _sServiceSpecifier, const Sequence< Any >& /*Arguments*/ )
626 return createInstance(_sServiceSpecifier);
629 Sequence< OUString > SAL_CALL OConnection::getAvailableServiceNames( )
631 Sequence< OUString > aRet { SERVICE_NAME_SINGLESELECTQUERYCOMPOSER };
632 return aRet;
635 Reference< XTablesSupplier > const & OConnection::getMasterTables()
637 // check if out "master connection" can supply tables
638 if(!m_xMasterTables.is())
642 Reference<XDatabaseMetaData> xMeta = getMetaData();
643 if ( xMeta.is() )
644 m_xMasterTables = ::dbtools::getDataDefinitionByURLAndConnection( xMeta->getURL(), m_xMasterConnection, m_aContext );
646 catch(const SQLException&)
650 return m_xMasterTables;
653 // XUsersSupplier
654 Reference< XNameAccess > SAL_CALL OConnection::getUsers( )
656 MutexGuard aGuard(m_aMutex);
657 checkDisposed();
659 Reference<XUsersSupplier> xUsr(getMasterTables(),UNO_QUERY);
660 return xUsr.is() ? xUsr->getUsers() : Reference< XNameAccess >();
663 // XGroupsSupplier
664 Reference< XNameAccess > SAL_CALL OConnection::getGroups( )
666 MutexGuard aGuard(m_aMutex);
667 checkDisposed();
668 Reference<XGroupsSupplier> xGrp(getMasterTables(),UNO_QUERY);
669 return xGrp.is() ? xGrp->getGroups() : Reference< XNameAccess >();
672 void OConnection::impl_loadConnectionTools_throw()
674 m_xConnectionTools = css::sdb::tools::ConnectionTools::createWithConnection( m_aContext, this );
677 Reference< XTableName > SAL_CALL OConnection::createTableName( )
679 MutexGuard aGuard(m_aMutex);
680 checkDisposed();
681 impl_loadConnectionTools_throw();
683 return m_xConnectionTools->createTableName();
686 Reference< XObjectNames > SAL_CALL OConnection::getObjectNames( )
688 MutexGuard aGuard(m_aMutex);
689 checkDisposed();
690 impl_loadConnectionTools_throw();
692 return m_xConnectionTools->getObjectNames();
695 Reference< XDataSourceMetaData > SAL_CALL OConnection::getDataSourceMetaData( )
697 MutexGuard aGuard(m_aMutex);
698 checkDisposed();
699 impl_loadConnectionTools_throw();
701 return m_xConnectionTools->getDataSourceMetaData();
704 Reference< css::container::XNameAccess > SAL_CALL OConnection::getFieldsByCommandDescriptor( ::sal_Int32 commandType, const OUString& command, css::uno::Reference< css::lang::XComponent >& keepFieldsAlive )
706 MutexGuard aGuard(m_aMutex);
707 checkDisposed();
708 impl_loadConnectionTools_throw();
710 return m_xConnectionTools->getFieldsByCommandDescriptor(commandType,command,keepFieldsAlive);
713 Reference< XSingleSelectQueryComposer > SAL_CALL OConnection::getComposer( ::sal_Int32 commandType, const OUString& command )
715 MutexGuard aGuard(m_aMutex);
716 checkDisposed();
717 impl_loadConnectionTools_throw();
719 return m_xConnectionTools->getComposer(commandType,command);
722 void OConnection::impl_checkTableQueryNames_nothrow()
724 DatabaseMetaData aMeta( static_cast< XConnection* >( this ) );
725 if ( !aMeta.supportsSubqueriesInFrom() )
726 // nothing to do
727 return;
731 Reference< XNameAccess > xTables( getTables() );
732 const Sequence< OUString > aTableNames( xTables->getElementNames() );
733 std::set< OUString > aSortedTableNames( aTableNames.begin(), aTableNames.end() );
735 Reference< XNameAccess > xQueries( getQueries() );
736 const Sequence< OUString > aQueryNames( xQueries->getElementNames() );
738 for ( auto const & queryName : aQueryNames )
740 if ( aSortedTableNames.find( queryName ) != aSortedTableNames.end() )
742 OUString sConflictWarning( DBA_RES( RID_STR_CONFLICTING_NAMES ) );
743 m_aWarnings.appendWarning( sConflictWarning, "01SB0", *this );
747 catch( const Exception& )
749 DBG_UNHANDLED_EXCEPTION("dbaccess");
753 Reference< XGraphic > SAL_CALL OConnection::getTableIcon( const OUString& TableName, ::sal_Int32 ColorMode )
755 Reference< XGraphic > xReturn;
757 // ask our aggregate
758 if ( m_xTableUIProvider.is() )
759 xReturn = m_xTableUIProvider->getTableIcon( TableName, ColorMode );
761 // ask ourself
762 // well, we don't have own functionality here ...
763 // In the future, we might decide to delegate the complete handling to this interface.
764 // In this case, we would need to load the icon here.
766 return xReturn;
769 Reference< XInterface > SAL_CALL OConnection::getTableEditor( const Reference< XDatabaseDocumentUI >& DocumentUI, const OUString& TableName )
771 Reference< XInterface > xReturn;
773 // ask our aggregate
774 if ( m_xTableUIProvider.is() )
775 xReturn = m_xTableUIProvider->getTableEditor( DocumentUI, TableName );
777 // ask ourself
778 // well, we don't have own functionality here ...
779 // In the future, we might decide to delegate the complete handling to this interface.
780 // In this case, we would need to instantiate a css.sdb.TableDesign here.
782 return xReturn;
785 } // namespace dbaccess
787 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */