update credits
[LibreOffice.git] / connectivity / source / commontools / TTableHelper.cxx
blob3e29b7bbd5249594eba0c52dff616b3875d7c340
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 "connectivity/TTableHelper.hxx"
21 #include <com/sun/star/sdbc/XRow.hpp>
22 #include <com/sun/star/sdbc/XResultSet.hpp>
23 #include <com/sun/star/sdbcx/KeyType.hpp>
24 #include <com/sun/star/sdbc/KeyRule.hpp>
25 #include <cppuhelper/typeprovider.hxx>
26 #include <com/sun/star/lang/DisposedException.hpp>
27 #include <com/sun/star/sdbc/ColumnValue.hpp>
28 #include <comphelper/implementationreference.hxx>
29 #include <comphelper/sequence.hxx>
30 #include <comphelper/extract.hxx>
31 #include <comphelper/types.hxx>
32 #include "connectivity/dbtools.hxx"
33 #include "connectivity/sdbcx/VCollection.hxx"
34 #include <unotools/sharedunocomponent.hxx>
35 #include "TConnection.hxx"
37 #include <o3tl/compat_functional.hxx>
39 #include <iterator>
41 using namespace ::comphelper;
42 using namespace connectivity;
43 using namespace ::com::sun::star::uno;
44 using namespace ::com::sun::star::beans;
45 using namespace ::com::sun::star::sdbcx;
46 using namespace ::com::sun::star::sdbc;
47 using namespace ::com::sun::star::container;
48 using namespace ::com::sun::star::lang;
49 namespace
51 /// helper class for column property change events which holds the OComponentDefinition weak
52 typedef ::cppu::WeakImplHelper1 < XContainerListener > OTableContainerListener_BASE;
53 class OTableContainerListener : public OTableContainerListener_BASE
55 OTableHelper* m_pComponent;
56 ::std::map< OUString,bool> m_aRefNames;
58 OTableContainerListener(const OTableContainerListener&);
59 void operator =(const OTableContainerListener&);
60 protected:
61 virtual ~OTableContainerListener(){}
62 public:
63 OTableContainerListener(OTableHelper* _pComponent) : m_pComponent(_pComponent){}
64 virtual void SAL_CALL elementInserted( const ::com::sun::star::container::ContainerEvent& /*Event*/ ) throw (RuntimeException)
67 virtual void SAL_CALL elementRemoved( const ::com::sun::star::container::ContainerEvent& Event ) throw (RuntimeException)
69 OUString sName;
70 Event.Accessor >>= sName;
71 if ( m_aRefNames.find(sName) != m_aRefNames.end() )
72 m_pComponent->refreshKeys();
74 virtual void SAL_CALL elementReplaced( const ::com::sun::star::container::ContainerEvent& Event ) throw (RuntimeException)
76 OUString sOldComposedName,sNewComposedName;
77 Event.ReplacedElement >>= sOldComposedName;
78 Event.Accessor >>= sNewComposedName;
79 if ( sOldComposedName != sNewComposedName && m_aRefNames.find(sOldComposedName) != m_aRefNames.end() )
80 m_pComponent->refreshKeys();
82 // XEventListener
83 virtual void SAL_CALL disposing( const EventObject& /*_rSource*/ ) throw (RuntimeException)
86 void clear() { m_pComponent = NULL; }
87 inline void add(const OUString& _sRefName) { m_aRefNames.insert(::std::map< OUString,bool>::value_type(_sRefName,true)); }
90 namespace connectivity
92 OUString lcl_getServiceNameForSetting(const Reference< ::com::sun::star::sdbc::XConnection >& _xConnection,const OUString& i_sSetting)
94 OUString sSupportService;
95 Any aValue;
96 if ( ::dbtools::getDataSourceSetting(_xConnection,i_sSetting,aValue) )
98 aValue >>= sSupportService;
100 return sSupportService;
102 struct OTableHelperImpl
104 TKeyMap m_aKeys;
105 // helper services which can be provided by extensions
106 Reference< ::com::sun::star::sdb::tools::XTableRename> m_xRename;
107 Reference< ::com::sun::star::sdb::tools::XTableAlteration> m_xAlter;
108 Reference< ::com::sun::star::sdb::tools::XKeyAlteration> m_xKeyAlter;
109 Reference< ::com::sun::star::sdb::tools::XIndexAlteration> m_xIndexAlter;
111 Reference< ::com::sun::star::sdbc::XDatabaseMetaData > m_xMetaData;
112 Reference< ::com::sun::star::sdbc::XConnection > m_xConnection;
113 ::comphelper::ImplementationReference< OTableContainerListener,XContainerListener>
114 m_xTablePropertyListener;
115 ::std::vector< ColumnDesc > m_aColumnDesc;
116 OTableHelperImpl(const Reference< ::com::sun::star::sdbc::XConnection >& _xConnection)
117 : m_xConnection(_xConnection)
121 m_xMetaData = m_xConnection->getMetaData();
122 Reference<XMultiServiceFactory> xFac(_xConnection,UNO_QUERY);
123 if ( xFac.is() )
125 static const OUString s_sTableRename("TableRenameServiceName");
126 m_xRename.set(xFac->createInstance(lcl_getServiceNameForSetting(m_xConnection,s_sTableRename)),UNO_QUERY);
127 static const OUString s_sTableAlteration("TableAlterationServiceName");
128 m_xAlter.set(xFac->createInstance(lcl_getServiceNameForSetting(m_xConnection,s_sTableAlteration)),UNO_QUERY);
129 static const OUString s_sKeyAlteration("KeyAlterationServiceName");
130 m_xKeyAlter.set(xFac->createInstance(lcl_getServiceNameForSetting(m_xConnection,s_sKeyAlteration)),UNO_QUERY);
131 static const OUString s_sIndexAlteration("IndexAlterationServiceName");
132 m_xIndexAlter.set(xFac->createInstance(lcl_getServiceNameForSetting(m_xConnection,s_sIndexAlteration)),UNO_QUERY);
135 catch(const Exception&)
142 OTableHelper::OTableHelper( sdbcx::OCollection* _pTables,
143 const Reference< XConnection >& _xConnection,
144 sal_Bool _bCase)
145 :OTable_TYPEDEF(_pTables,_bCase)
146 ,m_pImpl(new OTableHelperImpl(_xConnection))
149 // -------------------------------------------------------------------------
150 OTableHelper::OTableHelper( sdbcx::OCollection* _pTables,
151 const Reference< XConnection >& _xConnection,
152 sal_Bool _bCase,
153 const OUString& _Name,
154 const OUString& _Type,
155 const OUString& _Description ,
156 const OUString& _SchemaName,
157 const OUString& _CatalogName
158 ) : OTable_TYPEDEF(_pTables,
159 _bCase,
160 _Name,
161 _Type,
162 _Description,
163 _SchemaName,
164 _CatalogName)
165 ,m_pImpl(new OTableHelperImpl(_xConnection))
168 // -----------------------------------------------------------------------------
169 OTableHelper::~OTableHelper()
172 // -----------------------------------------------------------------------------
173 void SAL_CALL OTableHelper::disposing()
175 ::osl::MutexGuard aGuard(m_aMutex);
176 if ( m_pImpl->m_xTablePropertyListener.is() )
178 m_pTables->removeContainerListener(m_pImpl->m_xTablePropertyListener.getRef());
179 m_pImpl->m_xTablePropertyListener->clear();
180 m_pImpl->m_xTablePropertyListener.dispose();
182 OTable_TYPEDEF::disposing();
184 m_pImpl->m_xConnection = NULL;
185 m_pImpl->m_xMetaData = NULL;
189 // -------------------------------------------------------------------------
190 namespace
192 /** collects ColumnDesc's from a resultset produced by XDatabaseMetaData::getColumns
194 void lcl_collectColumnDescs_throw( const Reference< XResultSet >& _rxResult, ::std::vector< ColumnDesc >& _out_rColumns )
196 Reference< XRow > xRow( _rxResult, UNO_QUERY_THROW );
197 OUString sName;
198 OrdinalPosition nOrdinalPosition( 0 );
199 while ( _rxResult->next() )
201 sName = xRow->getString( 4 ); // COLUMN_NAME
202 sal_Int32 nField5 = xRow->getInt(5);
203 OUString aField6 = xRow->getString(6);
204 sal_Int32 nField7 = xRow->getInt(7)
205 , nField9 = xRow->getInt(9)
206 , nField11= xRow->getInt(11);
207 OUString sField12 = xRow->getString(12)
208 ,sField13 = xRow->getString(13);
209 nOrdinalPosition = xRow->getInt( 17 ); // ORDINAL_POSITION
210 _out_rColumns.push_back( ColumnDesc( sName,nField5,aField6,nField7,nField9,nField11,sField12,sField13, nOrdinalPosition ) );
214 /** checks a given array of ColumnDesc's whether it has reasonable ordinal positions. If not,
215 they will be normalized to be the array index.
217 void lcl_sanitizeColumnDescs( ::std::vector< ColumnDesc >& _rColumns )
219 if ( _rColumns.empty() )
220 return;
222 // collect all used ordinals
223 ::std::set< OrdinalPosition > aUsedOrdinals;
224 for ( ::std::vector< ColumnDesc >::iterator collect = _rColumns.begin();
225 collect != _rColumns.end();
226 ++collect
228 aUsedOrdinals.insert( collect->nOrdinalPosition );
230 // we need to have as much different ordinals as we have different columns
231 bool bDuplicates = aUsedOrdinals.size() != _rColumns.size();
232 // and it needs to be a continuous range
233 size_t nOrdinalsRange = *aUsedOrdinals.rbegin() - *aUsedOrdinals.begin() + 1;
234 bool bGaps = nOrdinalsRange != _rColumns.size();
236 // if that's not the case, normalize it
237 if ( bGaps || bDuplicates )
239 OSL_FAIL( "lcl_sanitizeColumnDescs: database did provide invalid ORDINAL_POSITION values!" );
241 OrdinalPosition nNormalizedPosition = 1;
242 for ( ::std::vector< ColumnDesc >::iterator normalize = _rColumns.begin();
243 normalize != _rColumns.end();
244 ++normalize
246 normalize->nOrdinalPosition = nNormalizedPosition++;
247 return;
250 // what's left is that the range might not be from 1 to <column count>, but for instance
251 // 0 to <column count>-1.
252 size_t nOffset = *aUsedOrdinals.begin() - 1;
253 for ( ::std::vector< ColumnDesc >::iterator offset = _rColumns.begin();
254 offset != _rColumns.end();
255 ++offset
257 offset->nOrdinalPosition -= nOffset;
261 // -------------------------------------------------------------------------
262 void OTableHelper::refreshColumns()
264 TStringVector aVector;
265 if(!isNew())
267 Any aCatalog;
268 if ( !m_CatalogName.isEmpty() )
269 aCatalog <<= m_CatalogName;
271 ::utl::SharedUNOComponent< XResultSet > xResult( getMetaData()->getColumns(
272 aCatalog,
273 m_SchemaName,
274 m_Name,
275 OUString("%")
276 ) );
278 // collect the column names, together with their ordinal position
279 m_pImpl->m_aColumnDesc.clear();
280 lcl_collectColumnDescs_throw( xResult, m_pImpl->m_aColumnDesc );
282 // ensure that the ordinal positions as obtained from the meta data do make sense
283 lcl_sanitizeColumnDescs( m_pImpl->m_aColumnDesc );
285 // sort by ordinal position
286 ::std::map< OrdinalPosition, OUString > aSortedColumns;
287 for ( ::std::vector< ColumnDesc >::const_iterator copy = m_pImpl->m_aColumnDesc.begin();
288 copy != m_pImpl->m_aColumnDesc.end();
289 ++copy
291 aSortedColumns[ copy->nOrdinalPosition ] = copy->sName;
293 // copy them to aVector, now that we have the proper ordering
294 ::std::transform(
295 aSortedColumns.begin(),
296 aSortedColumns.end(),
297 ::std::insert_iterator< TStringVector >( aVector, aVector.begin() ),
298 ::o3tl::select2nd< ::std::map< OrdinalPosition, OUString >::value_type >()
302 if(m_pColumns)
303 m_pColumns->reFill(aVector);
304 else
305 m_pColumns = createColumns(aVector);
307 // -----------------------------------------------------------------------------
308 const ColumnDesc* OTableHelper::getColumnDescription(const OUString& _sName) const
310 const ColumnDesc* pRet = NULL;
311 ::std::vector< ColumnDesc >::const_iterator aEnd = m_pImpl->m_aColumnDesc.end();
312 for (::std::vector< ColumnDesc >::const_iterator aIter = m_pImpl->m_aColumnDesc.begin();aIter != aEnd;++aIter)
314 if ( aIter->sName == _sName )
316 pRet = &*aIter;
317 break;
319 } // for (::std::vector< ColumnDesc >::const_iterator aIter = m_pImpl->m_aColumnDesc.begin();aIter != aEnd;++aIter)
320 return pRet;
322 // -------------------------------------------------------------------------
323 void OTableHelper::refreshPrimaryKeys(TStringVector& _rNames)
325 Any aCatalog;
326 if ( !m_CatalogName.isEmpty() )
327 aCatalog <<= m_CatalogName;
328 Reference< XResultSet > xResult = getMetaData()->getPrimaryKeys(aCatalog,m_SchemaName,m_Name);
330 if ( xResult.is() )
332 sdbcx::TKeyProperties pKeyProps(new sdbcx::KeyProperties(OUString(),KeyType::PRIMARY,0,0));
333 OUString aPkName;
334 bool bAlreadyFetched = false;
335 const Reference< XRow > xRow(xResult,UNO_QUERY);
336 while ( xResult->next() )
338 pKeyProps->m_aKeyColumnNames.push_back(xRow->getString(4));
339 if ( !bAlreadyFetched )
341 aPkName = xRow->getString(6);
342 SAL_WARN_IF(xRow->wasNull(),"connectivity.commontools", "NULL Primary Key name");
343 SAL_WARN_IF(aPkName.isEmpty(),"connectivity.commontools", "empty Primary Key name");
344 bAlreadyFetched = true;
348 if(bAlreadyFetched)
350 SAL_WARN_IF(aPkName.isEmpty(),"connectivity.commontools", "empty Primary Key name");
351 SAL_WARN_IF(pKeyProps->m_aKeyColumnNames.size() == 0,"connectivity.commontools", "Primary Key has no columns");
352 m_pImpl->m_aKeys.insert(TKeyMap::value_type(aPkName,pKeyProps));
353 _rNames.push_back(aPkName);
355 } // if ( xResult.is() && xResult->next() )
356 ::comphelper::disposeComponent(xResult);
358 // -------------------------------------------------------------------------
359 void OTableHelper::refreshForeignKeys(TStringVector& _rNames)
361 Any aCatalog;
362 if ( !m_CatalogName.isEmpty() )
363 aCatalog <<= m_CatalogName;
364 Reference< XResultSet > xResult = getMetaData()->getImportedKeys(aCatalog,m_SchemaName,m_Name);
365 Reference< XRow > xRow(xResult,UNO_QUERY);
367 if ( xRow.is() )
369 sdbcx::TKeyProperties pKeyProps;
370 OUString aName,sCatalog,aSchema,sOldFKName;
371 while( xResult->next() )
373 // this must be outsid the "if" because we have to call in a right order
374 sCatalog = xRow->getString(1);
375 if ( xRow->wasNull() )
376 sCatalog = OUString();
377 aSchema = xRow->getString(2);
378 aName = xRow->getString(3);
380 const OUString sForeignKeyColumn = xRow->getString(8);
381 const sal_Int32 nUpdateRule = xRow->getInt(10);
382 const sal_Int32 nDeleteRule = xRow->getInt(11);
383 const OUString sFkName = xRow->getString(12);
385 if ( pKeyProps.get() )
390 if ( !sFkName.isEmpty() && !xRow->wasNull() )
392 if ( sOldFKName != sFkName )
394 if ( pKeyProps.get() )
395 m_pImpl->m_aKeys.insert(TKeyMap::value_type(sOldFKName,pKeyProps));
397 const OUString sReferencedName = ::dbtools::composeTableName(getMetaData(),sCatalog,aSchema,aName,sal_False,::dbtools::eInDataManipulation);
398 pKeyProps.reset(new sdbcx::KeyProperties(sReferencedName,KeyType::FOREIGN,nUpdateRule,nDeleteRule));
399 pKeyProps->m_aKeyColumnNames.push_back(sForeignKeyColumn);
400 _rNames.push_back(sFkName);
401 if ( m_pTables->hasByName(sReferencedName) )
403 if ( !m_pImpl->m_xTablePropertyListener.is() )
404 m_pImpl->m_xTablePropertyListener = ::comphelper::ImplementationReference< OTableContainerListener,XContainerListener>( new OTableContainerListener(this) );
405 m_pTables->addContainerListener(m_pImpl->m_xTablePropertyListener.getRef());
406 m_pImpl->m_xTablePropertyListener->add(sReferencedName);
407 } // if ( m_pTables->hasByName(sReferencedName) )
408 sOldFKName = sFkName;
409 } // if ( sOldFKName != sFkName )
410 else if ( pKeyProps.get() )
412 pKeyProps->m_aKeyColumnNames.push_back(sForeignKeyColumn);
415 } // while( xResult->next() )
416 if ( pKeyProps.get() )
417 m_pImpl->m_aKeys.insert(TKeyMap::value_type(sOldFKName,pKeyProps));
418 ::comphelper::disposeComponent(xResult);
421 // -------------------------------------------------------------------------
422 void OTableHelper::refreshKeys()
424 m_pImpl->m_aKeys.clear();
426 TStringVector aNames;
428 if(!isNew())
430 refreshPrimaryKeys(aNames);
431 refreshForeignKeys(aNames);
432 m_pKeys = createKeys(aNames);
433 } // if(!isNew())
434 else if (!m_pKeys )
435 m_pKeys = createKeys(aNames);
436 /*if(m_pKeys)
437 m_pKeys->reFill(aVector);
438 else*/
441 // -------------------------------------------------------------------------
442 void OTableHelper::refreshIndexes()
444 TStringVector aVector;
445 if(!isNew())
447 // fill indexes
448 Any aCatalog;
449 if ( !m_CatalogName.isEmpty() )
450 aCatalog <<= m_CatalogName;
451 Reference< XResultSet > xResult = getMetaData()->getIndexInfo(aCatalog,m_SchemaName,m_Name,sal_False,sal_False);
453 if(xResult.is())
455 Reference< XRow > xRow(xResult,UNO_QUERY);
456 OUString aName;
457 OUString sCatalogSep = getMetaData()->getCatalogSeparator();
458 OUString sPreviousRoundName;
459 while( xResult->next() )
461 aName = xRow->getString(5);
462 if(!aName.isEmpty())
463 aName += sCatalogSep;
464 aName += xRow->getString(6);
465 if ( !aName.isEmpty() )
467 // don't insert the name if the last one we inserted was the same
468 if (sPreviousRoundName != aName)
469 aVector.push_back(aName);
471 sPreviousRoundName = aName;
473 ::comphelper::disposeComponent(xResult);
477 if(m_pIndexes)
478 m_pIndexes->reFill(aVector);
479 else
480 m_pIndexes = createIndexes(aVector);
482 // -----------------------------------------------------------------------------
483 OUString OTableHelper::getRenameStart() const
485 OUString sSql("RENAME ");
486 if ( m_Type == OUString("VIEW") )
487 sSql += OUString(" VIEW ");
488 else
489 sSql += OUString(" TABLE ");
491 return sSql;
493 // -------------------------------------------------------------------------
494 // XRename
495 void SAL_CALL OTableHelper::rename( const OUString& newName ) throw(SQLException, ElementExistException, RuntimeException)
497 ::osl::MutexGuard aGuard(m_aMutex);
498 checkDisposed(
499 #ifdef __GNUC__
500 ::connectivity::sdbcx::OTableDescriptor_BASE::rBHelper.bDisposed
501 #else
502 rBHelper.bDisposed
503 #endif
506 if(!isNew())
508 if ( m_pImpl->m_xRename.is() )
510 m_pImpl->m_xRename->rename(this,newName);
512 else
514 OUString sSql = getRenameStart();
516 OUString sCatalog,sSchema,sTable;
517 ::dbtools::qualifiedNameComponents(getMetaData(),newName,sCatalog,sSchema,sTable,::dbtools::eInDataManipulation);
519 OUString sComposedName;
520 sComposedName = ::dbtools::composeTableName(getMetaData(),m_CatalogName,m_SchemaName,m_Name,sal_True,::dbtools::eInDataManipulation);
521 sSql += sComposedName
522 + OUString(" TO ");
523 sComposedName = ::dbtools::composeTableName(getMetaData(),sCatalog,sSchema,sTable,sal_True,::dbtools::eInDataManipulation);
524 sSql += sComposedName;
526 Reference< XStatement > xStmt = m_pImpl->m_xConnection->createStatement( );
527 if ( xStmt.is() )
529 xStmt->execute(sSql);
530 ::comphelper::disposeComponent(xStmt);
534 OTable_TYPEDEF::rename(newName);
536 else
537 ::dbtools::qualifiedNameComponents(getMetaData(),newName,m_CatalogName,m_SchemaName,m_Name,::dbtools::eInTableDefinitions);
539 // -----------------------------------------------------------------------------
540 Reference< XDatabaseMetaData> OTableHelper::getMetaData() const
542 return m_pImpl->m_xMetaData;
544 // -------------------------------------------------------------------------
545 void SAL_CALL OTableHelper::alterColumnByIndex( sal_Int32 index, const Reference< XPropertySet >& descriptor ) throw(SQLException, ::com::sun::star::lang::IndexOutOfBoundsException, RuntimeException)
547 ::osl::MutexGuard aGuard(m_aMutex);
548 checkDisposed(
549 #ifdef __GNUC__
550 ::connectivity::sdbcx::OTableDescriptor_BASE::rBHelper.bDisposed
551 #else
552 rBHelper.bDisposed
553 #endif
556 Reference< XPropertySet > xOld;
557 if(::cppu::extractInterface(xOld,m_pColumns->getByIndex(index)) && xOld.is())
558 alterColumnByName(getString(xOld->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_NAME))),descriptor);
561 // -------------------------------------------------------------------------
562 OUString SAL_CALL OTableHelper::getName() throw(RuntimeException)
564 OUString sComposedName;
565 sComposedName = ::dbtools::composeTableName(getMetaData(),m_CatalogName,m_SchemaName,m_Name,sal_False,::dbtools::eInDataManipulation);
566 return sComposedName;
568 // -----------------------------------------------------------------------------
569 void SAL_CALL OTableHelper::acquire() throw()
571 OTable_TYPEDEF::acquire();
573 // -----------------------------------------------------------------------------
574 void SAL_CALL OTableHelper::release() throw()
576 OTable_TYPEDEF::release();
578 // -----------------------------------------------------------------------------
579 sdbcx::TKeyProperties OTableHelper::getKeyProperties(const OUString& _sName) const
581 sdbcx::TKeyProperties pKeyProps;
582 TKeyMap::const_iterator aFind = m_pImpl->m_aKeys.find(_sName);
583 if ( aFind != m_pImpl->m_aKeys.end() )
585 pKeyProps = aFind->second;
587 else // only a fall back
589 OSL_FAIL("No key with the given name found");
590 pKeyProps.reset(new sdbcx::KeyProperties());
593 return pKeyProps;
595 // -----------------------------------------------------------------------------
596 void OTableHelper::addKey(const OUString& _sName,const sdbcx::TKeyProperties& _aKeyProperties)
598 m_pImpl->m_aKeys.insert(TKeyMap::value_type(_sName,_aKeyProperties));
600 // -----------------------------------------------------------------------------
601 OUString OTableHelper::getTypeCreatePattern() const
603 return OUString();
605 // -----------------------------------------------------------------------------
606 Reference< XConnection> OTableHelper::getConnection() const
608 return m_pImpl->m_xConnection;
610 // -----------------------------------------------------------------------------
611 Reference< ::com::sun::star::sdb::tools::XTableRename> OTableHelper::getRenameService() const
613 return m_pImpl->m_xRename;
615 // -----------------------------------------------------------------------------
616 Reference< ::com::sun::star::sdb::tools::XTableAlteration> OTableHelper::getAlterService() const
618 return m_pImpl->m_xAlter;
620 // -----------------------------------------------------------------------------
621 Reference< ::com::sun::star::sdb::tools::XKeyAlteration> OTableHelper::getKeyService() const
623 return m_pImpl->m_xKeyAlter;
625 // -----------------------------------------------------------------------------
626 Reference< ::com::sun::star::sdb::tools::XIndexAlteration> OTableHelper::getIndexService() const
628 return m_pImpl->m_xIndexAlter;
630 // -----------------------------------------------------------------------------
632 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */