merge the formfield patch from ooo-build
[ooovba.git] / dbaccess / source / ui / misc / indexcollection.cxx
blob1770a10fa3ed5df10c0351d1068596a1aee86c16
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: indexcollection.cxx,v $
10 * $Revision: 1.8.254.2 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_dbaccess.hxx"
34 #ifndef _DBAUI_INDEXCOLLECTION_HXX_
35 #include "indexcollection.hxx"
36 #endif
37 #ifndef TOOLS_DIAGNOSE_EX_H
38 #include <tools/diagnose_ex.h>
39 #endif
40 #ifndef _COM_SUN_STAR_SDBCX_XAPPEND_HPP_
41 #include <com/sun/star/sdbcx/XAppend.hpp>
42 #endif
43 #ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
44 #include <com/sun/star/beans/XPropertySet.hpp>
45 #endif
46 #ifndef _COM_SUN_STAR_SDBCX_XCOLUMNSSUPPLIER_HPP_
47 #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
48 #endif
49 #ifndef _COM_SUN_STAR_SDBCX_XDATADESCRIPTORFACTORY_HPP_
50 #include <com/sun/star/sdbcx/XDataDescriptorFactory.hpp>
51 #endif
52 #ifndef _COMPHELPER_EXTRACT_HXX_
53 #include <comphelper/extract.hxx>
54 #endif
55 #ifndef _COM_SUN_STAR_SDBCX_XDROP_HPP_
56 #include <com/sun/star/sdbcx/XDrop.hpp>
57 #endif
58 #ifndef _COM_SUN_STAR_CONTAINER_XNAMECONTAINER_HPP_
59 #include <com/sun/star/container/XNameContainer.hpp>
60 #endif
62 //......................................................................
63 namespace dbaui
65 //......................................................................
67 using namespace ::com::sun::star::uno;
68 using namespace ::com::sun::star::container;
69 using namespace ::com::sun::star::beans;
70 using namespace ::com::sun::star::sdbcx;
71 using namespace ::com::sun::star::sdbc;
73 //==================================================================
74 //= OIndexCollection
75 //==================================================================
76 //------------------------------------------------------------------
77 OIndexCollection::OIndexCollection()
81 //------------------------------------------------------------------
82 OIndexCollection::OIndexCollection(const OIndexCollection& _rSource)
84 *this = _rSource;
87 //------------------------------------------------------------------
88 // OIndexCollection::OIndexCollection(const Reference< XNameAccess >& _rxIndexes)
89 // {
90 // implConstructFrom(_rxIndexes);
91 // }
93 //------------------------------------------------------------------
94 const OIndexCollection& OIndexCollection::operator=(const OIndexCollection& _rSource)
96 detach();
97 m_xIndexes = _rSource.m_xIndexes;
98 m_aIndexes = _rSource.m_aIndexes;
99 return *this;
102 //------------------------------------------------------------------
103 void OIndexCollection::attach(const Reference< XNameAccess >& _rxIndexes)
105 implConstructFrom(_rxIndexes);
108 //------------------------------------------------------------------
109 void OIndexCollection::detach()
111 m_xIndexes.clear();
112 m_aIndexes.clear();
115 //------------------------------------------------------------------
116 Indexes::const_iterator OIndexCollection::find(const String& _rName) const
118 ::rtl::OUString sNameCompare(_rName);
120 // loop'n'compare
121 Indexes::const_iterator aSearch = m_aIndexes.begin();
122 Indexes::const_iterator aEnd = m_aIndexes.end();
123 for (; aSearch != aEnd; ++aSearch)
124 if (aSearch->sName == sNameCompare)
125 break;
127 return aSearch;
130 //------------------------------------------------------------------
131 Indexes::iterator OIndexCollection::find(const String& _rName)
133 ::rtl::OUString sNameCompare(_rName);
135 // loop'n'compare
136 Indexes::iterator aSearch = m_aIndexes.begin();
137 Indexes::iterator aEnd = m_aIndexes.end();
138 for (; aSearch != aEnd; ++aSearch)
139 if (aSearch->sName == sNameCompare)
140 break;
142 return aSearch;
145 //------------------------------------------------------------------
146 Indexes::const_iterator OIndexCollection::findOriginal(const String& _rName) const
148 ::rtl::OUString sNameCompare(_rName);
150 // loop'n'compare
151 Indexes::const_iterator aSearch = m_aIndexes.begin();
152 Indexes::const_iterator aEnd = m_aIndexes.end();
153 for (; aSearch != aEnd; ++aSearch)
154 if (aSearch->getOriginalName() == sNameCompare)
155 break;
157 return aSearch;
160 //------------------------------------------------------------------
161 Indexes::iterator OIndexCollection::findOriginal(const String& _rName)
163 ::rtl::OUString sNameCompare(_rName);
165 // loop'n'compare
166 Indexes::iterator aSearch = m_aIndexes.begin();
167 Indexes::iterator aEnd = m_aIndexes.end();
168 for (; aSearch != aEnd; ++aSearch)
169 if (aSearch->getOriginalName() == sNameCompare)
170 break;
172 return aSearch;
175 //------------------------------------------------------------------
176 void OIndexCollection::commitNewIndex(const Indexes::iterator& _rPos) SAL_THROW((SQLException))
178 OSL_ENSURE(_rPos->isNew(), "OIndexCollection::commitNewIndex: index must be new!");
182 Reference< XDataDescriptorFactory > xIndexFactory(m_xIndexes, UNO_QUERY);
183 Reference< XAppend > xAppendIndex(xIndexFactory, UNO_QUERY);
184 if (!xAppendIndex.is())
186 OSL_ENSURE(sal_False, "OIndexCollection::commitNewIndex: missing an interface of the index container!");
187 return;
190 Reference< XPropertySet > xIndexDescriptor = xIndexFactory->createDataDescriptor();
191 Reference< XColumnsSupplier > xColsSupp(xIndexDescriptor, UNO_QUERY);
192 Reference< XNameAccess > xCols;
193 if (xColsSupp.is())
194 xCols = xColsSupp->getColumns();
196 Reference< XDataDescriptorFactory > xColumnFactory(xCols, UNO_QUERY);
197 Reference< XAppend > xAppendCols(xColumnFactory, UNO_QUERY);
198 if (!xAppendCols.is())
200 OSL_ENSURE(sal_False, "OIndexCollection::commitNewIndex: invalid index descriptor returned!");
201 return;
204 // set the properties
205 static const ::rtl::OUString s_sUniquePropertyName = ::rtl::OUString::createFromAscii("IsUnique");
206 static const ::rtl::OUString s_sSortPropertyName = ::rtl::OUString::createFromAscii("IsAscending");
207 static const ::rtl::OUString s_sNamePropertyName = ::rtl::OUString::createFromAscii("Name");
208 // the index' own props
209 xIndexDescriptor->setPropertyValue(s_sUniquePropertyName, ::cppu::bool2any(_rPos->bUnique));
210 xIndexDescriptor->setPropertyValue(s_sNamePropertyName, makeAny(_rPos->sName));
212 // the fields
213 for ( ConstIndexFieldsIterator aFieldLoop = _rPos->aFields.begin();
214 aFieldLoop != _rPos->aFields.end();
215 ++aFieldLoop
218 OSL_ENSURE(!xCols->hasByName(aFieldLoop->sFieldName), "OIndexCollection::commitNewIndex: double column name (need to prevent this outside)!");
220 Reference< XPropertySet > xColDescriptor = xColumnFactory->createDataDescriptor();
221 OSL_ENSURE(xColDescriptor.is(), "OIndexCollection::commitNewIndex: invalid column descriptor!");
222 if (xColDescriptor.is())
224 xColDescriptor->setPropertyValue(s_sSortPropertyName, ::cppu::bool2any(aFieldLoop->bSortAscending));
225 xColDescriptor->setPropertyValue(s_sNamePropertyName, makeAny(::rtl::OUString(aFieldLoop->sFieldName)));
226 xAppendCols->appendByDescriptor(xColDescriptor);
230 xAppendIndex->appendByDescriptor(xIndexDescriptor);
232 _rPos->flagAsCommitted(GrantIndexAccess());
233 _rPos->clearModified();
235 catch(SQLException&)
236 { // allowed to pass
237 throw;
239 catch( const Exception& )
241 DBG_UNHANDLED_EXCEPTION();
245 //------------------------------------------------------------------
246 sal_Bool OIndexCollection::dropNoRemove(const Indexes::iterator& _rPos) SAL_THROW((SQLException))
250 OSL_ENSURE(m_xIndexes->hasByName(_rPos->getOriginalName()), "OIndexCollection::drop: invalid name!");
252 Reference< XDrop > xDropIndex(m_xIndexes, UNO_QUERY);
253 if (!xDropIndex.is())
255 OSL_ENSURE(sal_False, "OIndexCollection::drop: no XDrop interface!");
256 return sal_False;
259 xDropIndex->dropByName(_rPos->getOriginalName());
261 catch(SQLException&)
262 { // allowed to pass
263 throw;
265 catch( const Exception& )
267 DBG_UNHANDLED_EXCEPTION();
268 return sal_False;
271 // adjust the OIndex structure
272 Indexes::iterator aDropped = findOriginal(_rPos->getOriginalName());
273 OSL_ENSURE(aDropped != m_aIndexes.end(), "OIndexCollection::drop: invalid original name, but successfull commit?!");
274 aDropped->flagAsNew(GrantIndexAccess());
276 return sal_True;
279 //------------------------------------------------------------------
280 sal_Bool OIndexCollection::drop(const Indexes::iterator& _rPos) SAL_THROW((SQLException))
282 OSL_ENSURE((_rPos >= m_aIndexes.begin()) && (_rPos < m_aIndexes.end()),
283 "OIndexCollection::drop: invalid position (fasten your seatbelt .... this will crash)!");
285 if (!_rPos->isNew())
286 if (!dropNoRemove(_rPos))
287 return sal_False;
289 // adjust the index array
290 m_aIndexes.erase(_rPos);
291 return sal_True;
294 //------------------------------------------------------------------
295 void OIndexCollection::implFillIndexInfo(OIndex& _rIndex) SAL_THROW((Exception))
297 // get the UNO descriptor for the index
298 Reference< XPropertySet > xIndex;
299 m_xIndexes->getByName(_rIndex.getOriginalName()) >>= xIndex;
300 if (!xIndex.is())
302 OSL_ENSURE(sal_False, "OIndexCollection::implFillIndexInfo: got an invalid index object!");
304 else
305 implFillIndexInfo(_rIndex, xIndex);
308 //------------------------------------------------------------------
309 void OIndexCollection::implFillIndexInfo(OIndex& _rIndex, Reference< XPropertySet > _rxDescriptor) SAL_THROW((Exception))
311 static const ::rtl::OUString s_sPrimaryIndexPropertyName = ::rtl::OUString::createFromAscii("IsPrimaryKeyIndex");
312 static const ::rtl::OUString s_sUniquePropertyName = ::rtl::OUString::createFromAscii("IsUnique");
313 static const ::rtl::OUString s_sSortPropertyName = ::rtl::OUString::createFromAscii("IsAscending");
314 static const ::rtl::OUString s_sCatalogPropertyName = ::rtl::OUString::createFromAscii("Catalog");
316 _rIndex.bPrimaryKey = ::cppu::any2bool(_rxDescriptor->getPropertyValue(s_sPrimaryIndexPropertyName));
317 _rIndex.bUnique = ::cppu::any2bool(_rxDescriptor->getPropertyValue(s_sUniquePropertyName));
318 _rxDescriptor->getPropertyValue(s_sCatalogPropertyName) >>= _rIndex.sDescription;
320 // the columns
321 Reference< XColumnsSupplier > xSuppCols(_rxDescriptor, UNO_QUERY);
322 Reference< XNameAccess > xCols;
323 if (xSuppCols.is())
324 xCols = xSuppCols->getColumns();
325 OSL_ENSURE(xCols.is(), "OIndexCollection::implFillIndexInfo: the index does not have columns!");
326 if (xCols.is())
328 Sequence< ::rtl::OUString > aFieldNames = xCols->getElementNames();
329 _rIndex.aFields.resize(aFieldNames.getLength());
331 const ::rtl::OUString* pFieldNames = aFieldNames.getConstArray();
332 const ::rtl::OUString* pFieldNamesEnd = pFieldNames + aFieldNames.getLength();
333 IndexFields::iterator aCopyTo = _rIndex.aFields.begin();
335 Reference< XPropertySet > xIndexColumn;
336 for (;pFieldNames < pFieldNamesEnd; ++pFieldNames, ++aCopyTo)
338 // extract the column
339 xIndexColumn.clear();
340 xCols->getByName(*pFieldNames) >>= xIndexColumn;
341 if (!xIndexColumn.is())
343 OSL_ENSURE(sal_False, "OIndexCollection::implFillIndexInfo: invalid index column!");
344 --aCopyTo;
345 continue;
348 // get the relevant properties
349 aCopyTo->sFieldName = *pFieldNames;
350 aCopyTo->bSortAscending = ::cppu::any2bool(xIndexColumn->getPropertyValue(s_sSortPropertyName));
353 _rIndex.aFields.resize(aCopyTo - _rIndex.aFields.begin());
354 // (just in case some fields were invalid ...)
358 //------------------------------------------------------------------
359 void OIndexCollection::resetIndex(const Indexes::iterator& _rPos) SAL_THROW((SQLException))
361 OSL_ENSURE(_rPos >= m_aIndexes.begin() && _rPos < m_aIndexes.end(),
362 "OIndexCollection::resetIndex: invalid position!");
366 _rPos->sName = _rPos->getOriginalName();
367 implFillIndexInfo(*_rPos);
369 _rPos->clearModified();
370 _rPos->flagAsCommitted(GrantIndexAccess());
372 catch(SQLException&)
373 { // allowed to pass
374 throw;
376 catch( const Exception& )
378 DBG_UNHANDLED_EXCEPTION();
382 //------------------------------------------------------------------
383 Indexes::iterator OIndexCollection::insert(const String& _rName)
385 OSL_ENSURE(end() == find(_rName), "OIndexCollection::insert: invalid new name!");
386 String tmpName;
387 OIndex aNewIndex(tmpName); // the empty string indicates the index is a new one
388 aNewIndex.sName = _rName;
389 m_aIndexes.push_back(aNewIndex);
390 return m_aIndexes.end() - 1; // the last element is the new one ...
393 //------------------------------------------------------------------
394 void OIndexCollection::implConstructFrom(const Reference< XNameAccess >& _rxIndexes)
396 detach();
398 m_xIndexes = _rxIndexes;
399 if (m_xIndexes.is())
401 // loop through all the indexes
402 Sequence< ::rtl::OUString > aNames = m_xIndexes->getElementNames();
403 const ::rtl::OUString* pNames = aNames.getConstArray();
404 const ::rtl::OUString* pEnd = pNames + aNames.getLength();
405 for (; pNames < pEnd; ++pNames)
407 // extract the index object
408 Reference< XPropertySet > xIndex;
409 m_xIndexes->getByName(*pNames) >>= xIndex;
410 if (!xIndex.is())
412 OSL_ENSURE(sal_False, "OIndexCollection::implConstructFrom: got an invalid index object ... ignoring!");
413 continue;
416 // fill the OIndex structure
417 OIndex aCurrentIndex(*pNames);
418 implFillIndexInfo(aCurrentIndex);
419 m_aIndexes.push_back(aCurrentIndex);
424 //......................................................................
425 } // namespace dbaui
426 //......................................................................