xref: /AOO41X/main/connectivity/source/commontools/TTableHelper.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_connectivity.hxx"
30 #include "connectivity/TTableHelper.hxx"
31 #include <com/sun/star/sdbc/XRow.hpp>
32 #include <com/sun/star/sdbc/XResultSet.hpp>
33 #include <com/sun/star/sdbcx/KeyType.hpp>
34 #include <com/sun/star/sdbc/KeyRule.hpp>
35 #include <cppuhelper/typeprovider.hxx>
36 #include <com/sun/star/lang/DisposedException.hpp>
37 #include <com/sun/star/sdbc/ColumnValue.hpp>
38 #include <comphelper/implementationreference.hxx>
39 #include <comphelper/sequence.hxx>
40 #include <comphelper/extract.hxx>
41 #include <comphelper/types.hxx>
42 #include "connectivity/dbtools.hxx"
43 #include "connectivity/sdbcx/VCollection.hxx"
44 #include <unotools/sharedunocomponent.hxx>
45 #include "TConnection.hxx"
46 
47 using namespace ::comphelper;
48 using namespace connectivity;
49 using namespace ::com::sun::star::uno;
50 using namespace ::com::sun::star::beans;
51 using namespace ::com::sun::star::sdbcx;
52 using namespace ::com::sun::star::sdbc;
53 using namespace ::com::sun::star::container;
54 using namespace ::com::sun::star::lang;
55 namespace
56 {
57     /// helper class for column property change events which holds the OComponentDefinition weak
58 typedef ::cppu::WeakImplHelper1	< XContainerListener > OTableContainerListener_BASE;
59 class OTableContainerListener : public OTableContainerListener_BASE
60 {
61     OTableHelper* m_pComponent;
62     ::std::map< ::rtl::OUString,bool> m_aRefNames;
63 
64     OTableContainerListener(const OTableContainerListener&);
65     void operator =(const OTableContainerListener&);
66 protected:
67     virtual ~OTableContainerListener(){}
68 public:
69     OTableContainerListener(OTableHelper* _pComponent) : m_pComponent(_pComponent){}
70     virtual void SAL_CALL elementInserted( const ::com::sun::star::container::ContainerEvent& /*Event*/ ) throw (RuntimeException)
71     {
72     }
73     virtual void SAL_CALL elementRemoved( const ::com::sun::star::container::ContainerEvent& Event ) throw (RuntimeException)
74     {
75         ::rtl::OUString sName;
76 		Event.Accessor	>>= sName;
77         if ( m_aRefNames.find(sName) != m_aRefNames.end() )
78             m_pComponent->refreshKeys();
79     }
80     virtual void SAL_CALL elementReplaced( const ::com::sun::star::container::ContainerEvent& Event ) throw (RuntimeException)
81 	{
82         ::rtl::OUString sOldComposedName,sNewComposedName;
83 		Event.ReplacedElement	>>= sOldComposedName;
84 		Event.Accessor			>>= sNewComposedName;
85         if ( sOldComposedName != sNewComposedName && m_aRefNames.find(sOldComposedName) != m_aRefNames.end() )
86             m_pComponent->refreshKeys();
87     }
88 	// XEventListener
89 	virtual void SAL_CALL disposing( const EventObject& /*_rSource*/ ) throw (RuntimeException)
90     {
91     }
92     void clear() { m_pComponent = NULL; }
93     inline void add(const ::rtl::OUString& _sRefName) { m_aRefNames.insert(::std::map< ::rtl::OUString,bool>::value_type(_sRefName,true)); }
94 };
95 }
96 namespace connectivity
97 {
98     ::rtl::OUString lcl_getServiceNameForSetting(const Reference< ::com::sun::star::sdbc::XConnection >& _xConnection,const ::rtl::OUString& i_sSetting)
99     {
100         ::rtl::OUString sSupportService;
101         Any aValue;
102         if ( ::dbtools::getDataSourceSetting(_xConnection,i_sSetting,aValue) )
103         {
104             aValue >>= sSupportService;
105         }
106         return sSupportService;
107     }
108     struct OTableHelperImpl
109     {
110         TKeyMap  m_aKeys;
111         // helper services which can be provided by extensions
112         Reference< ::com::sun::star::sdb::tools::XTableRename>      m_xRename;
113         Reference< ::com::sun::star::sdb::tools::XTableAlteration>  m_xAlter;
114         Reference< ::com::sun::star::sdb::tools::XKeyAlteration>    m_xKeyAlter;
115         Reference< ::com::sun::star::sdb::tools::XIndexAlteration>  m_xIndexAlter;
116 
117         Reference< ::com::sun::star::sdbc::XDatabaseMetaData >	    m_xMetaData;
118 		Reference< ::com::sun::star::sdbc::XConnection >			m_xConnection;
119         ::comphelper::ImplementationReference< OTableContainerListener,XContainerListener>
120                                     m_xTablePropertyListener;
121         ::std::vector< ColumnDesc > m_aColumnDesc;
122         OTableHelperImpl(const Reference< ::com::sun::star::sdbc::XConnection >& _xConnection)
123             : m_xConnection(_xConnection)
124         {
125             try
126 	        {
127 		        m_xMetaData = m_xConnection->getMetaData();
128                 Reference<XMultiServiceFactory> xFac(_xConnection,UNO_QUERY);
129                 if ( xFac.is() )
130                 {
131                     static const ::rtl::OUString s_sTableRename(RTL_CONSTASCII_USTRINGPARAM("TableRenameServiceName"));
132                     m_xRename.set(xFac->createInstance(lcl_getServiceNameForSetting(m_xConnection,s_sTableRename)),UNO_QUERY);
133                     static const ::rtl::OUString s_sTableAlteration(RTL_CONSTASCII_USTRINGPARAM("TableAlterationServiceName"));
134                     m_xAlter.set(xFac->createInstance(lcl_getServiceNameForSetting(m_xConnection,s_sTableAlteration)),UNO_QUERY);
135                     static const ::rtl::OUString s_sKeyAlteration(RTL_CONSTASCII_USTRINGPARAM("KeyAlterationServiceName"));
136                     m_xKeyAlter.set(xFac->createInstance(lcl_getServiceNameForSetting(m_xConnection,s_sKeyAlteration)),UNO_QUERY);
137                     static const ::rtl::OUString s_sIndexAlteration(RTL_CONSTASCII_USTRINGPARAM("IndexAlterationServiceName"));
138                     m_xIndexAlter.set(xFac->createInstance(lcl_getServiceNameForSetting(m_xConnection,s_sIndexAlteration)),UNO_QUERY);
139                 }
140 	        }
141 	        catch(const Exception&)
142 	        {
143 	        }
144         }
145     };
146 }
147 
148 OTableHelper::OTableHelper(	sdbcx::OCollection* _pTables,
149 						   const Reference< XConnection >& _xConnection,
150 						   sal_Bool _bCase)
151 	:OTable_TYPEDEF(_pTables,_bCase)
152     ,m_pImpl(new OTableHelperImpl(_xConnection))
153 {
154 }
155 // -------------------------------------------------------------------------
156 OTableHelper::OTableHelper(	sdbcx::OCollection* _pTables,
157 							const Reference< XConnection >& _xConnection,
158 							sal_Bool _bCase,
159 							const ::rtl::OUString& _Name,
160 							const ::rtl::OUString& _Type,
161 							const ::rtl::OUString& _Description ,
162 							const ::rtl::OUString& _SchemaName,
163 							const ::rtl::OUString& _CatalogName
164 						) : OTable_TYPEDEF(_pTables,
165 											_bCase,
166 											_Name,
167 										  _Type,
168 										  _Description,
169 										  _SchemaName,
170 										  _CatalogName)
171 						,m_pImpl(new OTableHelperImpl(_xConnection))
172 {
173 }
174 // -----------------------------------------------------------------------------
175 OTableHelper::~OTableHelper()
176 {
177 }
178 // -----------------------------------------------------------------------------
179 void SAL_CALL OTableHelper::disposing()
180 {
181     ::osl::MutexGuard aGuard(m_aMutex);
182     if ( m_pImpl->m_xTablePropertyListener.is() )
183     {
184         m_pTables->removeContainerListener(m_pImpl->m_xTablePropertyListener.getRef());
185         m_pImpl->m_xTablePropertyListener->clear();
186         m_pImpl->m_xTablePropertyListener.dispose();
187     }
188 	OTable_TYPEDEF::disposing();
189 
190 	m_pImpl->m_xConnection	= NULL;
191 	m_pImpl->m_xMetaData	= NULL;
192 
193 }
194 
195 // -------------------------------------------------------------------------
196 namespace
197 {
198     /** collects ColumnDesc's from a resultset produced by XDatabaseMetaData::getColumns
199     */
200     void lcl_collectColumnDescs_throw( const Reference< XResultSet >& _rxResult, ::std::vector< ColumnDesc >& _out_rColumns )
201     {
202         Reference< XRow > xRow( _rxResult, UNO_QUERY_THROW );
203         ::rtl::OUString sName;
204         OrdinalPosition nOrdinalPosition( 0 );
205 	    while ( _rxResult->next() )
206         {
207             sName = xRow->getString( 4 );           // COLUMN_NAME
208             sal_Int32		nField5	= xRow->getInt(5);
209 			::rtl::OUString aField6 = xRow->getString(6);
210 			sal_Int32		nField7 = xRow->getInt(7)
211 						,	nField9 = xRow->getInt(9)
212 						,	nField11= xRow->getInt(11);
213 			::rtl::OUString  sField12 = xRow->getString(12)
214                             ,sField13 = xRow->getString(13);
215             nOrdinalPosition = xRow->getInt( 17 );  // ORDINAL_POSITION
216             _out_rColumns.push_back( ColumnDesc( sName,nField5,aField6,nField7,nField9,nField11,sField12,sField13, nOrdinalPosition ) );
217         }
218     }
219 
220     /** checks a given array of ColumnDesc's whether it has reasonable ordinal positions. If not,
221         they will be normalized to be the array index.
222     */
223     void lcl_sanitizeColumnDescs( ::std::vector< ColumnDesc >& _rColumns )
224     {
225         if ( _rColumns.empty() )
226             return;
227 
228         // collect all used ordinals
229         ::std::set< OrdinalPosition > aUsedOrdinals;
230         for (   ::std::vector< ColumnDesc >::iterator collect = _rColumns.begin();
231                 collect != _rColumns.end();
232                 ++collect
233             )
234             aUsedOrdinals.insert( collect->nOrdinalPosition );
235 
236         // we need to have as much different ordinals as we have different columns
237         bool bDuplicates = aUsedOrdinals.size() != _rColumns.size();
238         // and it needs to be a continuous range
239         size_t nOrdinalsRange = *aUsedOrdinals.rbegin() - *aUsedOrdinals.begin() + 1;
240         bool bGaps = nOrdinalsRange != _rColumns.size();
241 
242         // if that's not the case, normalize it
243         if ( bGaps || bDuplicates )
244         {
245             OSL_ENSURE( false, "lcl_sanitizeColumnDescs: database did provide invalid ORDINAL_POSITION values!" );
246 
247             OrdinalPosition nNormalizedPosition = 1;
248             for (   ::std::vector< ColumnDesc >::iterator normalize = _rColumns.begin();
249                     normalize != _rColumns.end();
250                     ++normalize
251                 )
252                 normalize->nOrdinalPosition = nNormalizedPosition++;
253             return;
254         }
255 
256         // what's left is that the range might not be from 1 to <column count>, but for instance
257         // 0 to <column count>-1.
258         size_t nOffset = *aUsedOrdinals.begin() - 1;
259         for (   ::std::vector< ColumnDesc >::iterator offset = _rColumns.begin();
260                 offset != _rColumns.end();
261                 ++offset
262             )
263             offset->nOrdinalPosition -= nOffset;
264     }
265 }
266 
267 // -------------------------------------------------------------------------
268 void OTableHelper::refreshColumns()
269 {
270 	TStringVector aVector;
271 	if(!isNew())
272 	{
273 		Any aCatalog;
274 		if ( m_CatalogName.getLength() )
275 			aCatalog <<= m_CatalogName;
276 
277         ::utl::SharedUNOComponent< XResultSet > xResult( getMetaData()->getColumns(
278             aCatalog,
279             m_SchemaName,
280             m_Name,
281             ::rtl::OUString::createFromAscii("%")
282         ) );
283 
284         // collect the column names, together with their ordinal position
285         m_pImpl->m_aColumnDesc.clear();
286         lcl_collectColumnDescs_throw( xResult, m_pImpl->m_aColumnDesc );
287 
288         // ensure that the ordinal positions as obtained from the meta data do make sense
289         lcl_sanitizeColumnDescs( m_pImpl->m_aColumnDesc );
290 
291         // sort by ordinal position
292         ::std::map< OrdinalPosition, ::rtl::OUString > aSortedColumns;
293         for (   ::std::vector< ColumnDesc >::const_iterator copy = m_pImpl->m_aColumnDesc.begin();
294                 copy != m_pImpl->m_aColumnDesc.end();
295                 ++copy
296             )
297             aSortedColumns[ copy->nOrdinalPosition ] = copy->sName;
298 
299         // copy them to aVector, now that we have the proper ordering
300         ::std::transform(
301             aSortedColumns.begin(),
302             aSortedColumns.end(),
303             ::std::insert_iterator< TStringVector >( aVector, aVector.begin() ),
304             ::std::select2nd< ::std::map< OrdinalPosition, ::rtl::OUString >::value_type >()
305         );
306 	}
307 
308 	if(m_pColumns)
309 		m_pColumns->reFill(aVector);
310 	else
311 		m_pColumns	= createColumns(aVector);
312 }
313 // -----------------------------------------------------------------------------
314 const ColumnDesc* OTableHelper::getColumnDescription(const ::rtl::OUString& _sName) const
315 {
316     const ColumnDesc* pRet = NULL;
317     ::std::vector< ColumnDesc >::const_iterator aEnd = m_pImpl->m_aColumnDesc.end();
318     for (::std::vector< ColumnDesc >::const_iterator aIter = m_pImpl->m_aColumnDesc.begin();aIter != aEnd;++aIter)
319     {
320         if ( aIter->sName == _sName )
321         {
322             pRet = &*aIter;
323             break;
324         }
325     } // for (::std::vector< ColumnDesc >::const_iterator aIter = m_pImpl->m_aColumnDesc.begin();aIter != aEnd;++aIter)
326     return pRet;
327 }
328 // -------------------------------------------------------------------------
329 void OTableHelper::refreshPrimaryKeys(TStringVector& _rNames)
330 {
331 	Any aCatalog;
332 	if ( m_CatalogName.getLength() )
333 		aCatalog <<= m_CatalogName;
334     Reference< XResultSet > xResult = getMetaData()->getPrimaryKeys(aCatalog,m_SchemaName,m_Name);
335 
336 	if ( xResult.is() )
337 	{
338         sdbcx::TKeyProperties pKeyProps(new sdbcx::KeyProperties(::rtl::OUString(),KeyType::PRIMARY,0,0));
339         ::rtl::OUString aPkName;
340         bool bAlreadyFetched = false;
341         const Reference< XRow > xRow(xResult,UNO_QUERY);
342         while ( xResult->next() )
343         {
344             pKeyProps->m_aKeyColumnNames.push_back(xRow->getString(4));
345             if ( !bAlreadyFetched )
346             {
347 		        aPkName = xRow->getString(6);
348                 bAlreadyFetched = true;
349             }
350         }
351 
352         m_pImpl->m_aKeys.insert(TKeyMap::value_type(aPkName,pKeyProps));
353         _rNames.push_back(aPkName);
354 	} // if ( xResult.is() && xResult->next() )
355     ::comphelper::disposeComponent(xResult);
356 }
357 // -------------------------------------------------------------------------
358 void OTableHelper::refreshForgeinKeys(TStringVector& _rNames)
359 {
360 	Any aCatalog;
361 	if ( m_CatalogName.getLength() )
362 		aCatalog <<= m_CatalogName;
363 	Reference< XResultSet > xResult = getMetaData()->getImportedKeys(aCatalog,m_SchemaName,m_Name);
364 	Reference< XRow > xRow(xResult,UNO_QUERY);
365 
366 	if ( xRow.is() )
367 	{
368         sdbcx::TKeyProperties pKeyProps;
369         ::rtl::OUString aName,sCatalog,aSchema,sOldFKName;
370 		while( xResult->next() )
371 		{
372             // this must be outsid the "if" because we have to call in a right order
373 			sCatalog	= xRow->getString(1);
374 			if ( xRow->wasNull() )
375 				sCatalog = ::rtl::OUString();
376 			aSchema		= xRow->getString(2);
377 			aName		= xRow->getString(3);
378 
379             const ::rtl::OUString sForeignKeyColumn = xRow->getString(8);
380 			const sal_Int32 nUpdateRule = xRow->getInt(10);
381 			const sal_Int32 nDeleteRule = xRow->getInt(11);
382             const ::rtl::OUString sFkName = xRow->getString(12);
383 
384                 if ( pKeyProps.get() )
385                 {
386                 }
387 
388 
389 			if ( sFkName.getLength() && !xRow->wasNull() )
390             {
391                 if ( sOldFKName != sFkName )
392                 {
393                     if ( pKeyProps.get() )
394                         m_pImpl->m_aKeys.insert(TKeyMap::value_type(sOldFKName,pKeyProps));
395 
396                     const ::rtl::OUString sReferencedName = ::dbtools::composeTableName(getMetaData(),sCatalog,aSchema,aName,sal_False,::dbtools::eInDataManipulation);
397                     pKeyProps.reset(new sdbcx::KeyProperties(sReferencedName,KeyType::FOREIGN,nUpdateRule,nDeleteRule));
398                     pKeyProps->m_aKeyColumnNames.push_back(sForeignKeyColumn);
399                     _rNames.push_back(sFkName);
400                     if ( m_pTables->hasByName(sReferencedName) )
401                     {
402                         if ( !m_pImpl->m_xTablePropertyListener.is() )
403                             m_pImpl->m_xTablePropertyListener = ::comphelper::ImplementationReference< OTableContainerListener,XContainerListener>( new OTableContainerListener(this) );
404                         m_pTables->addContainerListener(m_pImpl->m_xTablePropertyListener.getRef());
405                         m_pImpl->m_xTablePropertyListener->add(sReferencedName);
406                     } // if ( m_pTables->hasByName(sReferencedName) )
407                     sOldFKName = sFkName;
408                 } // if ( sOldFKName != sFkName )
409                 else if ( pKeyProps.get() )
410                 {
411                     pKeyProps->m_aKeyColumnNames.push_back(sForeignKeyColumn);
412                 }
413             }
414 		} // while( xResult->next() )
415         if ( pKeyProps.get() )
416             m_pImpl->m_aKeys.insert(TKeyMap::value_type(sOldFKName,pKeyProps));
417 		::comphelper::disposeComponent(xResult);
418 	}
419 }
420 // -------------------------------------------------------------------------
421 void OTableHelper::refreshKeys()
422 {
423 	m_pImpl->m_aKeys.clear();
424 
425     TStringVector aNames;
426 
427 	if(!isNew())
428 	{
429 		refreshPrimaryKeys(aNames);
430 		refreshForgeinKeys(aNames);
431         m_pKeys	= createKeys(aNames);
432 	} // if(!isNew())
433     else if (!m_pKeys )
434         m_pKeys	= createKeys(aNames);
435 	/*if(m_pKeys)
436 		m_pKeys->reFill(aVector);
437 	else*/
438 
439 }
440 // -------------------------------------------------------------------------
441 void OTableHelper::refreshIndexes()
442 {
443 	TStringVector aVector;
444 	if(!isNew())
445 	{
446 		// fill indexes
447 		Any aCatalog;
448 		if ( m_CatalogName.getLength() )
449 			aCatalog <<= m_CatalogName;
450 		Reference< XResultSet > xResult = getMetaData()->getIndexInfo(aCatalog,m_SchemaName,m_Name,sal_False,sal_False);
451 
452 		if(xResult.is())
453 		{
454 			Reference< XRow > xRow(xResult,UNO_QUERY);
455 			::rtl::OUString aName;
456 			::rtl::OUString sCatalogSep = getMetaData()->getCatalogSeparator();
457 			::rtl::OUString sPreviousRoundName;
458 			while( xResult->next() )
459 			{
460 				aName = xRow->getString(5);
461 				if(aName.getLength())
462 					aName += sCatalogSep;
463 				aName += xRow->getString(6);
464 				if ( aName.getLength() )
465 				{
466 					// don't insert the name if the last one we inserted was the same
467 					if (sPreviousRoundName != aName)
468 						aVector.push_back(aName);
469 				}
470 				sPreviousRoundName = aName;
471 			}
472 			::comphelper::disposeComponent(xResult);
473 		}
474 	}
475 
476 	if(m_pIndexes)
477 		m_pIndexes->reFill(aVector);
478 	else
479 		m_pIndexes	= createIndexes(aVector);
480 }
481 // -----------------------------------------------------------------------------
482 ::rtl::OUString OTableHelper::getRenameStart() const
483 {
484     ::rtl::OUString sSql(RTL_CONSTASCII_USTRINGPARAM("RENAME "));
485     if ( m_Type == ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("VIEW")) )
486 	    sSql += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" VIEW "));
487     else
488 	    sSql += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" TABLE "));
489 
490     return sSql;
491 }
492 // -------------------------------------------------------------------------
493 // XRename
494 void SAL_CALL OTableHelper::rename( const ::rtl::OUString& newName ) throw(SQLException, ElementExistException, RuntimeException)
495 {
496 	::osl::MutexGuard aGuard(m_aMutex);
497 	checkDisposed(
498 #ifdef GCC
499 		::connectivity::sdbcx::OTableDescriptor_BASE::rBHelper.bDisposed
500 #else
501 		rBHelper.bDisposed
502 #endif
503 		);
504 
505 	if(!isNew())
506 	{
507         if ( m_pImpl->m_xRename.is() )
508         {
509             m_pImpl->m_xRename->rename(this,newName);
510         }
511         else
512         {
513 		    ::rtl::OUString sSql = getRenameStart();
514 		    ::rtl::OUString sQuote = getMetaData()->getIdentifierQuoteString(  );
515 
516 		    ::rtl::OUString sCatalog,sSchema,sTable;
517 		    ::dbtools::qualifiedNameComponents(getMetaData(),newName,sCatalog,sSchema,sTable,::dbtools::eInDataManipulation);
518 
519 		    ::rtl::OUString sComposedName;
520 		    sComposedName = ::dbtools::composeTableName(getMetaData(),m_CatalogName,m_SchemaName,m_Name,sal_True,::dbtools::eInDataManipulation);
521 		    sSql += sComposedName
522 			     + ::rtl::OUString::createFromAscii(" TO ");
523 		    sComposedName = ::dbtools::composeTableName(getMetaData(),sCatalog,sSchema,sTable,sal_True,::dbtools::eInDataManipulation);
524 		    sSql += sComposedName;
525 
526 		    Reference< XStatement > xStmt = m_pImpl->m_xConnection->createStatement(  );
527 		    if ( xStmt.is() )
528 		    {
529 			    xStmt->execute(sSql);
530 			    ::comphelper::disposeComponent(xStmt);
531 		    }
532         }
533 
534 		OTable_TYPEDEF::rename(newName);
535 	}
536 	else
537 		::dbtools::qualifiedNameComponents(getMetaData(),newName,m_CatalogName,m_SchemaName,m_Name,::dbtools::eInTableDefinitions);
538 }
539 // -----------------------------------------------------------------------------
540 Reference< XDatabaseMetaData> OTableHelper::getMetaData() const
541 {
542 	return m_pImpl->m_xMetaData;
543 }
544 // -------------------------------------------------------------------------
545 void SAL_CALL OTableHelper::alterColumnByIndex( sal_Int32 index, const Reference< XPropertySet >& descriptor ) throw(SQLException, ::com::sun::star::lang::IndexOutOfBoundsException, RuntimeException)
546 {
547 	::osl::MutexGuard aGuard(m_aMutex);
548 	checkDisposed(
549 #ifdef GCC
550 		::connectivity::sdbcx::OTableDescriptor_BASE::rBHelper.bDisposed
551 #else
552 		rBHelper.bDisposed
553 #endif
554 		);
555 
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);
559 }
560 
561 // -------------------------------------------------------------------------
562 ::rtl::OUString SAL_CALL OTableHelper::getName() throw(RuntimeException)
563 {
564 	::rtl::OUString sComposedName;
565 	sComposedName = ::dbtools::composeTableName(getMetaData(),m_CatalogName,m_SchemaName,m_Name,sal_False,::dbtools::eInDataManipulation);
566 	return sComposedName;
567 }
568 // -----------------------------------------------------------------------------
569 void SAL_CALL OTableHelper::acquire() throw()
570 {
571 	OTable_TYPEDEF::acquire();
572 }
573 // -----------------------------------------------------------------------------
574 void SAL_CALL OTableHelper::release() throw()
575 {
576 	OTable_TYPEDEF::release();
577 }
578 // -----------------------------------------------------------------------------
579 sdbcx::TKeyProperties OTableHelper::getKeyProperties(const ::rtl::OUString& _sName) const
580 {
581     sdbcx::TKeyProperties pKeyProps;
582     TKeyMap::const_iterator aFind = m_pImpl->m_aKeys.find(_sName);
583     if ( aFind != m_pImpl->m_aKeys.end() )
584     {
585         pKeyProps = aFind->second;
586     }
587     else // only a fall back
588     {
589         OSL_ENSURE(0,"No key with the given name found");
590         pKeyProps.reset(new sdbcx::KeyProperties());
591     }
592 
593     return pKeyProps;
594 }
595 // -----------------------------------------------------------------------------
596 void OTableHelper::addKey(const ::rtl::OUString& _sName,const sdbcx::TKeyProperties& _aKeyProperties)
597 {
598     m_pImpl->m_aKeys.insert(TKeyMap::value_type(_sName,_aKeyProperties));
599 }
600 // -----------------------------------------------------------------------------
601 ::rtl::OUString OTableHelper::getTypeCreatePattern() const
602 {
603     return ::rtl::OUString();
604 }
605 // -----------------------------------------------------------------------------
606 Reference< XConnection> OTableHelper::getConnection() const
607 {
608     return m_pImpl->m_xConnection;
609 }
610 // -----------------------------------------------------------------------------
611 Reference< ::com::sun::star::sdb::tools::XTableRename>      OTableHelper::getRenameService() const
612 {
613     return m_pImpl->m_xRename;
614 }
615 // -----------------------------------------------------------------------------
616 Reference< ::com::sun::star::sdb::tools::XTableAlteration>  OTableHelper::getAlterService() const
617 {
618     return m_pImpl->m_xAlter;
619 }
620 // -----------------------------------------------------------------------------
621 Reference< ::com::sun::star::sdb::tools::XKeyAlteration>  OTableHelper::getKeyService() const
622 {
623     return m_pImpl->m_xKeyAlter;
624 }
625 // -----------------------------------------------------------------------------
626 Reference< ::com::sun::star::sdb::tools::XIndexAlteration>  OTableHelper::getIndexService() const
627 {
628     return m_pImpl->m_xIndexAlter;
629 }
630 // -----------------------------------------------------------------------------
631