1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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>
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
;
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
;
96 void OConnection::close()
98 // being closed is the same as being disposed
102 sal_Bool
OConnection::isClosed()
104 MutexGuard
aGuard(m_aMutex
);
105 return !m_xMasterConnection
.is();
109 Reference
< XStatement
> OConnection::createStatement()
111 MutexGuard
aGuard(m_aMutex
);
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
);
124 Reference
< XPreparedStatement
> OConnection::prepareStatement(const OUString
& sql
)
126 MutexGuard
aGuard(m_aMutex
);
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
);
140 Reference
< XPreparedStatement
> OConnection::prepareCall(const OUString
& sql
)
142 MutexGuard
aGuard(m_aMutex
);
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
);
155 OUString
OConnection::nativeSQL(const OUString
& sql
)
157 MutexGuard
aGuard(m_aMutex
);
159 return m_xMasterConnection
->nativeSQL(sql
);
162 void OConnection::setAutoCommit(sal_Bool autoCommit
)
164 MutexGuard
aGuard(m_aMutex
);
166 m_xMasterConnection
->setAutoCommit(autoCommit
);
169 sal_Bool
OConnection::getAutoCommit()
171 MutexGuard
aGuard(m_aMutex
);
173 return m_xMasterConnection
->getAutoCommit();
176 void OConnection::commit()
178 MutexGuard
aGuard(m_aMutex
);
180 m_xMasterConnection
->commit();
183 void OConnection::rollback()
185 MutexGuard
aGuard(m_aMutex
);
187 m_xMasterConnection
->rollback();
190 Reference
< XDatabaseMetaData
> OConnection::getMetaData()
192 MutexGuard
aGuard(m_aMutex
);
194 return m_xMasterConnection
->getMetaData();
197 void OConnection::setReadOnly(sal_Bool readOnly
)
199 MutexGuard
aGuard(m_aMutex
);
201 m_xMasterConnection
->setReadOnly(readOnly
);
204 sal_Bool
OConnection::isReadOnly()
206 MutexGuard
aGuard(m_aMutex
);
208 return m_xMasterConnection
->isReadOnly();
211 void OConnection::setCatalog(const OUString
& catalog
)
213 MutexGuard
aGuard(m_aMutex
);
215 m_xMasterConnection
->setCatalog(catalog
);
218 OUString
OConnection::getCatalog()
220 MutexGuard
aGuard(m_aMutex
);
222 return m_xMasterConnection
->getCatalog();
225 void OConnection::setTransactionIsolation(sal_Int32 level
)
227 MutexGuard
aGuard(m_aMutex
);
229 m_xMasterConnection
->setTransactionIsolation(level
);
232 sal_Int32
OConnection::getTransactionIsolation()
234 MutexGuard
aGuard(m_aMutex
);
236 return m_xMasterConnection
->getTransactionIsolation();
239 Reference
< XNameAccess
> OConnection::getTypeMap()
241 MutexGuard
aGuard(m_aMutex
);
243 return m_xMasterConnection
->getTypeMap();
246 void OConnection::setTypeMap(const Reference
< XNameAccess
> & typeMap
)
248 MutexGuard
aGuard(m_aMutex
);
250 m_xMasterConnection
->setTypeMap(typeMap
);
255 OConnection::OConnection(ODatabaseSource
& _rDB
256 , Reference
< XConnection
> const & _rxMaster
257 , const Reference
< XComponentContext
>& _rxORB
)
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
) )
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
);
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();
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
305 Reference
<XResultSet
> xRes
= xMeta
->getTableTypes();
308 Reference
<XRow
> xRow(xRes
,UNO_QUERY
);
311 OUString sValue
= xRow
->getString(1);
312 if( !xRow
->wasNull() && sValue
== "VIEW")
314 m_bSupportsViews
= true;
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;
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()
361 Any SAL_CALL
OConnection::getWarnings()
363 MutexGuard
aGuard(m_aMutex
);
365 return m_aWarnings
.getWarnings();
368 void SAL_CALL
OConnection::clearWarnings( )
370 MutexGuard
aGuard(m_aMutex
);
372 m_aWarnings
.clearWarnings();
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() ) )
415 else if ( !m_bSupportsUsers
&& rType
.equals( cppu::UnoType
<XUsersSupplier
>::get() ) )
417 else if ( !m_bSupportsGroups
&& rType
.equals( cppu::UnoType
<XGroupsSupplier
>::get() ) )
419 return OConnection_Base::queryInterface( rType
);
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;
438 m_pTables
->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;
464 Reference
< XInterface
> OConnection::getParent()
466 MutexGuard
aGuard(m_aMutex
);
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
);
482 // Reference< XNumberFormatsSupplier > xSupplier = pParent->getNumberFormatsSupplier();
483 Reference
< XSQLQueryComposer
> xComposer( new OQueryComposer( this ) );
484 m_aComposers
.emplace_back(xComposer
);
488 void OConnection::impl_fillTableFilter()
490 Reference
<XPropertySet
> xProp(getParent(),UNO_QUERY
);
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
508 if (m_xMasterTables
.is() && m_xMasterTables
->getTables().is())
509 { // yes -> wrap them
510 m_pTables
->construct(m_xMasterTables
->getTables(),m_aTableFilter
, m_aTableTypeFilter
);
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
);
529 m_pViews
->construct(m_aTableFilter
, m_aTableTypeFilter
);
535 Reference
< XNameAccess
> OConnection::getTables()
537 MutexGuard
aGuard(m_aMutex
);
540 refresh(m_pTables
.get());
542 return m_pTables
.get();
545 Reference
< XNameAccess
> SAL_CALL
OConnection::getViews( )
547 MutexGuard
aGuard(m_aMutex
);
550 refresh(m_pViews
.get());
552 return m_pViews
.get();
556 Reference
< XNameAccess
> OConnection::getQueries()
558 MutexGuard
aGuard(m_aMutex
);
564 // css::sdb::XCommandPreparation
565 Reference
< XPreparedStatement
> SAL_CALL
OConnection::prepareCommand( const OUString
& command
, sal_Int32 commandType
)
567 MutexGuard
aGuard(m_aMutex
);
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
);
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
;
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
);
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(
615 m_aContext
->getServiceManager()->createInstanceWithArgumentsAndContext(_sServiceSpecifier
, aArgs
, m_aContext
)
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
};
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();
644 m_xMasterTables
= ::dbtools::getDataDefinitionByURLAndConnection( xMeta
->getURL(), m_xMasterConnection
, m_aContext
);
646 catch(const SQLException
&)
650 return m_xMasterTables
;
654 Reference
< XNameAccess
> SAL_CALL
OConnection::getUsers( )
656 MutexGuard
aGuard(m_aMutex
);
659 Reference
<XUsersSupplier
> xUsr(getMasterTables(),UNO_QUERY
);
660 return xUsr
.is() ? xUsr
->getUsers() : Reference
< XNameAccess
>();
664 Reference
< XNameAccess
> SAL_CALL
OConnection::getGroups( )
666 MutexGuard
aGuard(m_aMutex
);
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
);
681 impl_loadConnectionTools_throw();
683 return m_xConnectionTools
->createTableName();
686 Reference
< XObjectNames
> SAL_CALL
OConnection::getObjectNames( )
688 MutexGuard
aGuard(m_aMutex
);
690 impl_loadConnectionTools_throw();
692 return m_xConnectionTools
->getObjectNames();
695 Reference
< XDataSourceMetaData
> SAL_CALL
OConnection::getDataSourceMetaData( )
697 MutexGuard
aGuard(m_aMutex
);
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
);
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
);
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() )
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
;
758 if ( m_xTableUIProvider
.is() )
759 xReturn
= m_xTableUIProvider
->getTableIcon( TableName
, ColorMode
);
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.
769 Reference
< XInterface
> SAL_CALL
OConnection::getTableEditor( const Reference
< XDatabaseDocumentUI
>& DocumentUI
, const OUString
& TableName
)
771 Reference
< XInterface
> xReturn
;
774 if ( m_xTableUIProvider
.is() )
775 xReturn
= m_xTableUIProvider
->getTableEditor( DocumentUI
, TableName
);
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.
785 } // namespace dbaccess
787 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */