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