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