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