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