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