196de5490SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
396de5490SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
496de5490SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
596de5490SAndrew Rist  * distributed with this work for additional information
696de5490SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
796de5490SAndrew Rist  * to you under the Apache License, Version 2.0 (the
896de5490SAndrew Rist  * "License"); you may not use this file except in compliance
996de5490SAndrew Rist  * with the License.  You may obtain a copy of the License at
1096de5490SAndrew Rist  *
1196de5490SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
1296de5490SAndrew Rist  *
1396de5490SAndrew Rist  * Unless required by applicable law or agreed to in writing,
1496de5490SAndrew Rist  * software distributed under the License is distributed on an
1596de5490SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1696de5490SAndrew Rist  * KIND, either express or implied.  See the License for the
1796de5490SAndrew Rist  * specific language governing permissions and limitations
1896de5490SAndrew Rist  * under the License.
1996de5490SAndrew Rist  *
2096de5490SAndrew Rist  *************************************************************/
2196de5490SAndrew Rist 
2296de5490SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25*b63233d8Sdamjan #include "precompiled_dbui.hxx"
26cdf0e10cSrcweir #include "RTableConnectionData.hxx"
27cdf0e10cSrcweir #include <tools/debug.hxx>
28cdf0e10cSrcweir #include <com/sun/star/sdbc/KeyRule.hpp>
29cdf0e10cSrcweir #include <com/sun/star/sdbcx/KeyType.hpp>
30cdf0e10cSrcweir #include <com/sun/star/sdbcx/XKeysSupplier.hpp>
31cdf0e10cSrcweir #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
32cdf0e10cSrcweir #include <com/sun/star/sdbcx/XDataDescriptorFactory.hpp>
33cdf0e10cSrcweir #include <com/sun/star/sdbcx/XAppend.hpp>
34cdf0e10cSrcweir #include <com/sun/star/sdbcx/XDrop.hpp>
35cdf0e10cSrcweir #include <com/sun/star/container/XIndexAccess.hpp>
36cdf0e10cSrcweir #include "dbustrings.hrc"
37cdf0e10cSrcweir #include "dbu_rel.hrc"
38cdf0e10cSrcweir #include "UITools.hxx"
39cdf0e10cSrcweir #include "moduledbu.hxx"
40cdf0e10cSrcweir #include <connectivity/dbexception.hxx>
41cdf0e10cSrcweir #include <connectivity/dbtools.hxx>
42cdf0e10cSrcweir 
43cdf0e10cSrcweir using namespace dbaui;
44cdf0e10cSrcweir using namespace ::com::sun::star::sdbc;
45cdf0e10cSrcweir using namespace ::com::sun::star::sdbcx;
46cdf0e10cSrcweir using namespace ::com::sun::star::uno;
47cdf0e10cSrcweir using namespace ::com::sun::star::beans;
48cdf0e10cSrcweir using namespace ::com::sun::star::container;
49cdf0e10cSrcweir using namespace ::com::sun::star::lang;
50cdf0e10cSrcweir 
DBG_NAME(ORelationTableConnectionData)51cdf0e10cSrcweir DBG_NAME(ORelationTableConnectionData)
52cdf0e10cSrcweir //========================================================================
53cdf0e10cSrcweir // class ORelationTableConnectionData
54cdf0e10cSrcweir //========================================================================
55cdf0e10cSrcweir //------------------------------------------------------------------------
56cdf0e10cSrcweir ORelationTableConnectionData::ORelationTableConnectionData()
57cdf0e10cSrcweir 	:OTableConnectionData()
58cdf0e10cSrcweir 	,m_nUpdateRules(KeyRule::NO_ACTION)
59cdf0e10cSrcweir 	,m_nDeleteRules(KeyRule::NO_ACTION)
60cdf0e10cSrcweir 	,m_nCardinality(CARDINAL_UNDEFINED)
61cdf0e10cSrcweir {
62cdf0e10cSrcweir 	DBG_CTOR(ORelationTableConnectionData,NULL);
63cdf0e10cSrcweir }
64cdf0e10cSrcweir //------------------------------------------------------------------------
ORelationTableConnectionData(const TTableWindowData::value_type & _pReferencingTable,const TTableWindowData::value_type & _pReferencedTable,const::rtl::OUString & rConnName)65cdf0e10cSrcweir ORelationTableConnectionData::ORelationTableConnectionData( const TTableWindowData::value_type& _pReferencingTable,
66cdf0e10cSrcweir                                                             const TTableWindowData::value_type& _pReferencedTable,
67cdf0e10cSrcweir 															const ::rtl::OUString& rConnName )
68cdf0e10cSrcweir     :OTableConnectionData( _pReferencingTable, _pReferencedTable )
69cdf0e10cSrcweir     ,m_nUpdateRules(KeyRule::NO_ACTION)
70cdf0e10cSrcweir     ,m_nDeleteRules(KeyRule::NO_ACTION)
71cdf0e10cSrcweir     ,m_nCardinality(CARDINAL_UNDEFINED)
72cdf0e10cSrcweir {
73cdf0e10cSrcweir 	DBG_CTOR(ORelationTableConnectionData,NULL);
74cdf0e10cSrcweir     m_aConnName = rConnName;
75cdf0e10cSrcweir 
76cdf0e10cSrcweir     if ( m_aConnName.Len() )
77cdf0e10cSrcweir 	    SetCardinality();
78cdf0e10cSrcweir }
79cdf0e10cSrcweir 
80cdf0e10cSrcweir //------------------------------------------------------------------------
ORelationTableConnectionData(const ORelationTableConnectionData & rConnData)81cdf0e10cSrcweir ORelationTableConnectionData::ORelationTableConnectionData( const ORelationTableConnectionData& rConnData )
82cdf0e10cSrcweir 	:OTableConnectionData( rConnData )
83cdf0e10cSrcweir {
84cdf0e10cSrcweir 	DBG_CTOR(ORelationTableConnectionData,NULL);
85cdf0e10cSrcweir 	*this = rConnData;
86cdf0e10cSrcweir }
87cdf0e10cSrcweir 
88cdf0e10cSrcweir //------------------------------------------------------------------------
~ORelationTableConnectionData()89cdf0e10cSrcweir ORelationTableConnectionData::~ORelationTableConnectionData()
90cdf0e10cSrcweir {
91cdf0e10cSrcweir 	DBG_DTOR(ORelationTableConnectionData,NULL);
92cdf0e10cSrcweir }
93cdf0e10cSrcweir 
94cdf0e10cSrcweir //------------------------------------------------------------------------
DropRelation()95cdf0e10cSrcweir sal_Bool ORelationTableConnectionData::DropRelation()
96cdf0e10cSrcweir {
97cdf0e10cSrcweir 	DBG_CHKTHIS(ORelationTableConnectionData,NULL);
98cdf0e10cSrcweir 	::osl::MutexGuard aGuard( m_aMutex );
99cdf0e10cSrcweir 	////////////////////////////////////////////////////////////
100cdf0e10cSrcweir 	// Relation loeschen
101cdf0e10cSrcweir 	Reference< XIndexAccess> xKeys = getReferencingTable()->getKeys();
102cdf0e10cSrcweir 	if( m_aConnName.Len() && xKeys.is() )
103cdf0e10cSrcweir 	{
104cdf0e10cSrcweir         const sal_Int32 nCount = xKeys->getCount();
105cdf0e10cSrcweir         for(sal_Int32 i = 0;i < nCount;++i)
106cdf0e10cSrcweir 		{
107cdf0e10cSrcweir             Reference< XPropertySet> xKey(xKeys->getByIndex(i),UNO_QUERY);
108cdf0e10cSrcweir 			OSL_ENSURE(xKey.is(),"Key is not valid!");
109cdf0e10cSrcweir 			if(xKey.is())
110cdf0e10cSrcweir 			{
111cdf0e10cSrcweir 				::rtl::OUString sName;
112cdf0e10cSrcweir 				xKey->getPropertyValue(PROPERTY_NAME) >>= sName;
113cdf0e10cSrcweir 				if(String(sName) == m_aConnName)
114cdf0e10cSrcweir 				{
115cdf0e10cSrcweir 					Reference< XDrop> xDrop(xKeys,UNO_QUERY);
116cdf0e10cSrcweir 					OSL_ENSURE(xDrop.is(),"can't drop key because we haven't a drop interface!");
117cdf0e10cSrcweir 					if(xDrop.is())
118cdf0e10cSrcweir 						xDrop->dropByIndex(i);
119cdf0e10cSrcweir 					break;
120cdf0e10cSrcweir 				}
121cdf0e10cSrcweir 			}
122cdf0e10cSrcweir 		}
123cdf0e10cSrcweir 	}
124cdf0e10cSrcweir 	return sal_True;
125cdf0e10cSrcweir }
126cdf0e10cSrcweir 
127cdf0e10cSrcweir //------------------------------------------------------------------------
ChangeOrientation()128cdf0e10cSrcweir void ORelationTableConnectionData::ChangeOrientation()
129cdf0e10cSrcweir {
130cdf0e10cSrcweir 	DBG_CHKTHIS(ORelationTableConnectionData,NULL);
131cdf0e10cSrcweir 	//////////////////////////////////////////////////////////////////////
132cdf0e10cSrcweir 	// Source- und DestFieldName der Linien austauschen
133cdf0e10cSrcweir 	::rtl::OUString sTempString;
134cdf0e10cSrcweir 	OConnectionLineDataVec::iterator aIter = m_vConnLineData.begin();
135cdf0e10cSrcweir     OConnectionLineDataVec::iterator aEnd = m_vConnLineData.end();
136cdf0e10cSrcweir 	for(;aIter != aEnd;++aIter)
137cdf0e10cSrcweir 	{
138cdf0e10cSrcweir 		sTempString = (*aIter)->GetSourceFieldName();
139cdf0e10cSrcweir 		(*aIter)->SetSourceFieldName( (*aIter)->GetDestFieldName() );
140cdf0e10cSrcweir 		(*aIter)->SetDestFieldName( sTempString );
141cdf0e10cSrcweir 	}
142cdf0e10cSrcweir 
143cdf0e10cSrcweir 	//////////////////////////////////////////////////////////////////////
144cdf0e10cSrcweir 	// Member anpassen
145cdf0e10cSrcweir     TTableWindowData::value_type pTemp = m_pReferencingTable;
146cdf0e10cSrcweir     m_pReferencingTable = m_pReferencedTable;
147cdf0e10cSrcweir     m_pReferencedTable = pTemp;
148cdf0e10cSrcweir }
149cdf0e10cSrcweir 
150cdf0e10cSrcweir //------------------------------------------------------------------------
SetCardinality()151cdf0e10cSrcweir void ORelationTableConnectionData::SetCardinality()
152cdf0e10cSrcweir {
153cdf0e10cSrcweir 	DBG_CHKTHIS(ORelationTableConnectionData,NULL);
154cdf0e10cSrcweir 	::osl::MutexGuard aGuard( m_aMutex );
155cdf0e10cSrcweir 	m_nCardinality = CARDINAL_UNDEFINED;
156cdf0e10cSrcweir 
157cdf0e10cSrcweir 	if( IsSourcePrimKey() )
158cdf0e10cSrcweir 	{
159cdf0e10cSrcweir 		if( IsDestPrimKey() )
160cdf0e10cSrcweir 			m_nCardinality = CARDINAL_ONE_ONE;
161cdf0e10cSrcweir 		else
162cdf0e10cSrcweir 			m_nCardinality = CARDINAL_ONE_MANY;
163cdf0e10cSrcweir 	}
164cdf0e10cSrcweir 
165cdf0e10cSrcweir 	if( IsDestPrimKey() )
166cdf0e10cSrcweir 	{
167cdf0e10cSrcweir 		if( !IsSourcePrimKey() )
168cdf0e10cSrcweir 			m_nCardinality = CARDINAL_MANY_ONE;
169cdf0e10cSrcweir 	}
170cdf0e10cSrcweir 
171cdf0e10cSrcweir }
172cdf0e10cSrcweir // -----------------------------------------------------------------------------
checkPrimaryKey(const Reference<XPropertySet> & i_xTable,EConnectionSide _eEConnectionSide) const173cdf0e10cSrcweir sal_Bool ORelationTableConnectionData::checkPrimaryKey(const Reference< XPropertySet>& i_xTable,EConnectionSide _eEConnectionSide) const
174cdf0e10cSrcweir {
175cdf0e10cSrcweir 	// check if Table has the primary key column dependig on _eEConnectionSide
176cdf0e10cSrcweir 	sal_uInt16	nPrimKeysCount		= 0,
177cdf0e10cSrcweir 			nValidLinesCount	= 0;
178cdf0e10cSrcweir     const Reference< XNameAccess> xKeyColumns = dbtools::getPrimaryKeyColumns_throw(i_xTable);
179cdf0e10cSrcweir 	if ( xKeyColumns.is() )
180cdf0e10cSrcweir 	{
181cdf0e10cSrcweir 		Sequence< ::rtl::OUString> aKeyColumns = xKeyColumns->getElementNames();
182cdf0e10cSrcweir 		const ::rtl::OUString* pKeyIter	= aKeyColumns.getConstArray();
183cdf0e10cSrcweir 		const ::rtl::OUString* pKeyEnd  = pKeyIter + aKeyColumns.getLength();
184cdf0e10cSrcweir 
185cdf0e10cSrcweir 		for(;pKeyIter != pKeyEnd;++pKeyIter)
186cdf0e10cSrcweir 		{
187cdf0e10cSrcweir 			OConnectionLineDataVec::const_iterator aIter = m_vConnLineData.begin();
188cdf0e10cSrcweir             OConnectionLineDataVec::const_iterator aEnd = m_vConnLineData.end();
189cdf0e10cSrcweir             for(;aIter != aEnd;++aIter)
190cdf0e10cSrcweir 			{
191cdf0e10cSrcweir 				++nValidLinesCount;
192cdf0e10cSrcweir 				if ( (*aIter)->GetFieldName(_eEConnectionSide) == *pKeyIter )
193cdf0e10cSrcweir 				{
194cdf0e10cSrcweir 					++nPrimKeysCount;
195cdf0e10cSrcweir 					break;
196cdf0e10cSrcweir 				}
197cdf0e10cSrcweir 			}
198cdf0e10cSrcweir 		}
199cdf0e10cSrcweir         if ( nPrimKeysCount != aKeyColumns.getLength() )
200cdf0e10cSrcweir 			return sal_False;
201cdf0e10cSrcweir 	}
202cdf0e10cSrcweir 	if ( !nPrimKeysCount || nPrimKeysCount != nValidLinesCount )
203cdf0e10cSrcweir 		return sal_False;
204cdf0e10cSrcweir 
205cdf0e10cSrcweir 	return sal_True;
206cdf0e10cSrcweir }
207cdf0e10cSrcweir //------------------------------------------------------------------------
IsConnectionPossible()208cdf0e10cSrcweir sal_Bool ORelationTableConnectionData::IsConnectionPossible()
209cdf0e10cSrcweir {
210cdf0e10cSrcweir 	DBG_CHKTHIS(ORelationTableConnectionData,NULL);
211cdf0e10cSrcweir 	::osl::MutexGuard aGuard( m_aMutex );
212cdf0e10cSrcweir 
213cdf0e10cSrcweir 	//////////////////////////////////////////////////////////////////////
214cdf0e10cSrcweir 	// Wenn die SourceFelder ein PrimKey sind, ist nur die Orientierung falsch
215cdf0e10cSrcweir 	if ( IsSourcePrimKey() && !IsDestPrimKey() )
216cdf0e10cSrcweir 		ChangeOrientation();
217cdf0e10cSrcweir 
218cdf0e10cSrcweir 	return sal_True;
219cdf0e10cSrcweir }
220cdf0e10cSrcweir 
221cdf0e10cSrcweir //------------------------------------------------------------------------
CreateLineDataObj()222cdf0e10cSrcweir OConnectionLineDataRef ORelationTableConnectionData::CreateLineDataObj()
223cdf0e10cSrcweir {
224cdf0e10cSrcweir 	return new OConnectionLineData();
225cdf0e10cSrcweir }
226cdf0e10cSrcweir 
227cdf0e10cSrcweir //------------------------------------------------------------------------
CreateLineDataObj(const OConnectionLineData & rConnLineData)228cdf0e10cSrcweir OConnectionLineDataRef ORelationTableConnectionData::CreateLineDataObj( const OConnectionLineData& rConnLineData )
229cdf0e10cSrcweir {
230cdf0e10cSrcweir 	return new OConnectionLineData( rConnLineData );
231cdf0e10cSrcweir }
232cdf0e10cSrcweir 
233cdf0e10cSrcweir //------------------------------------------------------------------------
CopyFrom(const OTableConnectionData & rSource)234cdf0e10cSrcweir void ORelationTableConnectionData::CopyFrom(const OTableConnectionData& rSource)
235cdf0e10cSrcweir {
236cdf0e10cSrcweir 	// wie in der Basisklasse zurueckziehen auf das (nicht-virtuelle) operator=
237cdf0e10cSrcweir 	*this = *static_cast<const ORelationTableConnectionData*>(&rSource);
238cdf0e10cSrcweir }
239cdf0e10cSrcweir 
240cdf0e10cSrcweir //------------------------------------------------------------------------
operator =(const ORelationTableConnectionData & rConnData)241cdf0e10cSrcweir ORelationTableConnectionData& ORelationTableConnectionData::operator=( const ORelationTableConnectionData& rConnData )
242cdf0e10cSrcweir {
243cdf0e10cSrcweir 	if (&rConnData == this)
244cdf0e10cSrcweir 		return *this;
245cdf0e10cSrcweir 
246cdf0e10cSrcweir 	OTableConnectionData::operator=( rConnData );
247cdf0e10cSrcweir 	m_nUpdateRules = rConnData.GetUpdateRules();
248cdf0e10cSrcweir 	m_nDeleteRules = rConnData.GetDeleteRules();
249cdf0e10cSrcweir 	m_nCardinality = rConnData.GetCardinality();
250cdf0e10cSrcweir 
251cdf0e10cSrcweir 	return *this;
252cdf0e10cSrcweir }
253cdf0e10cSrcweir namespace dbaui
254cdf0e10cSrcweir {
255cdf0e10cSrcweir //-------------------------------------------------------------------------
operator ==(const ORelationTableConnectionData & lhs,const ORelationTableConnectionData & rhs)256cdf0e10cSrcweir bool operator==(const ORelationTableConnectionData& lhs, const ORelationTableConnectionData& rhs)
257cdf0e10cSrcweir {
258cdf0e10cSrcweir 	bool bEqual = (lhs.m_nUpdateRules == rhs.m_nUpdateRules)
259cdf0e10cSrcweir         && (lhs.m_nDeleteRules == rhs.m_nDeleteRules)
260cdf0e10cSrcweir         && (lhs.m_nCardinality == rhs.m_nCardinality)
261cdf0e10cSrcweir         && (lhs.getReferencingTable() == rhs.getReferencingTable())
262cdf0e10cSrcweir         && (lhs.getReferencedTable() == rhs.getReferencedTable())
263cdf0e10cSrcweir         && (lhs.m_aConnName == rhs.m_aConnName)
264cdf0e10cSrcweir         && (lhs.m_vConnLineData.size() == rhs.m_vConnLineData.size());
265cdf0e10cSrcweir 
266cdf0e10cSrcweir     if ( bEqual )
267cdf0e10cSrcweir     {
268cdf0e10cSrcweir         std::vector< OConnectionLineDataRef >::const_iterator aIter = lhs.m_vConnLineData.begin();
269cdf0e10cSrcweir         std::vector< OConnectionLineDataRef >::const_iterator aEnd = lhs.m_vConnLineData.end();
270cdf0e10cSrcweir         for (sal_Int32 i = 0; aIter != aEnd; ++aIter,++i)
271cdf0e10cSrcweir         {
272cdf0e10cSrcweir             if ( *(rhs.m_vConnLineData[i]) != **aIter )
273cdf0e10cSrcweir                 break;
274cdf0e10cSrcweir         }
275cdf0e10cSrcweir         bEqual = aIter == aEnd;
276cdf0e10cSrcweir     }
277cdf0e10cSrcweir     return bEqual;
278cdf0e10cSrcweir }
279cdf0e10cSrcweir }
280cdf0e10cSrcweir //------------------------------------------------------------------------
Update()281cdf0e10cSrcweir sal_Bool ORelationTableConnectionData::Update()
282cdf0e10cSrcweir {
283cdf0e10cSrcweir 	::osl::MutexGuard aGuard( m_aMutex );
284cdf0e10cSrcweir 	////////////////////////////////////////////////////////////
285cdf0e10cSrcweir 	// Alte Relation loeschen
286cdf0e10cSrcweir 	{
287cdf0e10cSrcweir 		DropRelation();
288cdf0e10cSrcweir 		if( !IsConnectionPossible() )
289cdf0e10cSrcweir 			return sal_False;
290cdf0e10cSrcweir 	}
291cdf0e10cSrcweir 
292cdf0e10cSrcweir 	// reassign the keys because the orientaion could be changed
293cdf0e10cSrcweir 	Reference<XPropertySet> xTableProp(getReferencingTable()->getTable());
294cdf0e10cSrcweir 	Reference< XIndexAccess> xKeys ( getReferencingTable()->getKeys());
295cdf0e10cSrcweir 
296cdf0e10cSrcweir 	if ( !xKeys.is() )
297cdf0e10cSrcweir 		return sal_False;
298cdf0e10cSrcweir 	////////////////////////////////////////////////////////////
299cdf0e10cSrcweir 	// Neue Relation erzeugen
300cdf0e10cSrcweir 	Reference<XDataDescriptorFactory> xKeyFactory(xKeys,UNO_QUERY);
301cdf0e10cSrcweir 	OSL_ENSURE(xKeyFactory.is(),"No XDataDescriptorFactory Interface!");
302cdf0e10cSrcweir 	Reference<XAppend> xAppend(xKeyFactory,UNO_QUERY);
303cdf0e10cSrcweir 	OSL_ENSURE(xAppend.is(),"No XAppend Interface!");
304cdf0e10cSrcweir 
305cdf0e10cSrcweir 	Reference<XPropertySet> xKey = xKeyFactory->createDataDescriptor();
306cdf0e10cSrcweir 	OSL_ENSURE(xKey.is(),"Key is null!");
307cdf0e10cSrcweir 	if ( xKey.is() && xTableProp.is() )
308cdf0e10cSrcweir 	{
309cdf0e10cSrcweir 		// build a foreign key name
310cdf0e10cSrcweir 		::rtl::OUString sSourceName;
311cdf0e10cSrcweir         xTableProp->getPropertyValue(PROPERTY_NAME) >>= sSourceName;
312cdf0e10cSrcweir 		::rtl::OUString sKeyName = sSourceName;
313cdf0e10cSrcweir 		sKeyName += getReferencedTable()->GetTableName();
314cdf0e10cSrcweir 
315cdf0e10cSrcweir 		xKey->setPropertyValue(PROPERTY_NAME,makeAny(sKeyName));
316cdf0e10cSrcweir 		xKey->setPropertyValue(PROPERTY_TYPE,makeAny(KeyType::FOREIGN));
317cdf0e10cSrcweir 		xKey->setPropertyValue(PROPERTY_REFERENCEDTABLE,makeAny(::rtl::OUString(getReferencedTable()->GetTableName())));
318cdf0e10cSrcweir 		xKey->setPropertyValue(PROPERTY_UPDATERULE, makeAny(GetUpdateRules()));
319cdf0e10cSrcweir 		xKey->setPropertyValue(PROPERTY_DELETERULE, makeAny(GetDeleteRules()));
320cdf0e10cSrcweir 	}
321cdf0e10cSrcweir 
322cdf0e10cSrcweir 	Reference<XColumnsSupplier> xColSup(xKey,UNO_QUERY);
323cdf0e10cSrcweir 	if ( xColSup.is() )
324cdf0e10cSrcweir 	{
325cdf0e10cSrcweir 		Reference<XNameAccess> xColumns = xColSup->getColumns();
326cdf0e10cSrcweir 		Reference<XDataDescriptorFactory> xColumnFactory(xColumns,UNO_QUERY);
327cdf0e10cSrcweir 		Reference<XAppend> xColumnAppend(xColumns,UNO_QUERY);
328cdf0e10cSrcweir 		if ( xColumnFactory.is() )
329cdf0e10cSrcweir 		{
330cdf0e10cSrcweir 			OConnectionLineDataVec::iterator aIter = m_vConnLineData.begin();
331cdf0e10cSrcweir             OConnectionLineDataVec::iterator aEnd = m_vConnLineData.end();
332cdf0e10cSrcweir 	        for(;aIter != aEnd;++aIter)
333cdf0e10cSrcweir 			{
334cdf0e10cSrcweir 				if((*aIter)->GetSourceFieldName().getLength() && (*aIter)->GetDestFieldName().getLength())
335cdf0e10cSrcweir 				{
336cdf0e10cSrcweir 					Reference<XPropertySet> xColumn;
337cdf0e10cSrcweir 					xColumn = xColumnFactory->createDataDescriptor();
338cdf0e10cSrcweir 					if ( xColumn.is() )
339cdf0e10cSrcweir 					{
340cdf0e10cSrcweir 						xColumn->setPropertyValue(PROPERTY_NAME,makeAny((*aIter)->GetSourceFieldName()));
341cdf0e10cSrcweir 						xColumn->setPropertyValue(PROPERTY_RELATEDCOLUMN,makeAny((*aIter)->GetDestFieldName()));
342cdf0e10cSrcweir 						xColumnAppend->appendByDescriptor(xColumn);
343cdf0e10cSrcweir 					}
344cdf0e10cSrcweir 				}
345cdf0e10cSrcweir 			}
346cdf0e10cSrcweir 
347cdf0e10cSrcweir 			if ( xColumns->hasElements() )
348cdf0e10cSrcweir 				xAppend->appendByDescriptor(xKey);
349cdf0e10cSrcweir 		}
350cdf0e10cSrcweir 		// to get the key we have to reget it because after append it is no longer valid
351cdf0e10cSrcweir 	}
352cdf0e10cSrcweir 
353cdf0e10cSrcweir 	// get the name of foreign key // search for columns
354cdf0e10cSrcweir 	m_aConnName = ::rtl::OUString();
355cdf0e10cSrcweir xKey.clear();
356cdf0e10cSrcweir     bool bDropRelation = false;
357cdf0e10cSrcweir 	for(sal_Int32 i=0;i<xKeys->getCount();++i)
358cdf0e10cSrcweir 	{
359cdf0e10cSrcweir 		xKeys->getByIndex(i) >>= xKey;
360cdf0e10cSrcweir 		OSL_ENSURE(xKey.is(),"Key is not valid!");
361cdf0e10cSrcweir 		if ( xKey.is() )
362cdf0e10cSrcweir 		{
363cdf0e10cSrcweir 			sal_Int32 nType = 0;
364cdf0e10cSrcweir 			xKey->getPropertyValue(PROPERTY_TYPE) >>= nType;
365cdf0e10cSrcweir 			::rtl::OUString sReferencedTable;
366cdf0e10cSrcweir 			xKey->getPropertyValue(PROPERTY_REFERENCEDTABLE) >>= sReferencedTable;
367cdf0e10cSrcweir 			if ( sReferencedTable == ::rtl::OUString(getReferencedTable()->GetTableName()) )
368cdf0e10cSrcweir 			{
369cdf0e10cSrcweir                 xColSup.set(xKey,UNO_QUERY_THROW);
370cdf0e10cSrcweir                 try
371cdf0e10cSrcweir                 {
372cdf0e10cSrcweir                     Reference<XNameAccess> xColumns = xColSup->getColumns();
373cdf0e10cSrcweir 		            Sequence< ::rtl::OUString> aNames = xColumns->getElementNames();
374cdf0e10cSrcweir 		            const ::rtl::OUString* pIter = aNames.getConstArray();
375cdf0e10cSrcweir 		            const ::rtl::OUString* pEnd = pIter + aNames.getLength();
376cdf0e10cSrcweir 
377cdf0e10cSrcweir                     Reference<XPropertySet> xColumn;
378cdf0e10cSrcweir                     ::rtl::OUString sName,sRelatedColumn;
379cdf0e10cSrcweir                     for ( ; pIter != pEnd ; ++pIter )
380cdf0e10cSrcweir                     {
381cdf0e10cSrcweir                         xColumn.set(xColumns->getByName(*pIter),UNO_QUERY_THROW);
382cdf0e10cSrcweir                         xColumn->getPropertyValue(PROPERTY_NAME)			>>= sName;
383cdf0e10cSrcweir 				        xColumn->getPropertyValue(PROPERTY_RELATEDCOLUMN)	>>= sRelatedColumn;
384cdf0e10cSrcweir 
385cdf0e10cSrcweir                         OConnectionLineDataVec::iterator aIter = m_vConnLineData.begin();
386cdf0e10cSrcweir                         OConnectionLineDataVec::iterator aEnd = m_vConnLineData.end();
387cdf0e10cSrcweir 	                    for(;aIter != aEnd;++aIter)
388cdf0e10cSrcweir 			            {
389cdf0e10cSrcweir 				            if(    (*aIter)->GetSourceFieldName() == sName
390cdf0e10cSrcweir                                 && (*aIter)->GetDestFieldName() == sRelatedColumn )
391cdf0e10cSrcweir 				            {
392cdf0e10cSrcweir 				                break;
393cdf0e10cSrcweir                             }
394cdf0e10cSrcweir                         }
395cdf0e10cSrcweir                         if ( aIter == m_vConnLineData.end() )
396cdf0e10cSrcweir                             break;
397cdf0e10cSrcweir                     }
398cdf0e10cSrcweir                     if ( pIter == pEnd )
399cdf0e10cSrcweir                     {
400cdf0e10cSrcweir                         xKey->getPropertyValue(PROPERTY_NAME) >>= sName;
401cdf0e10cSrcweir 				        m_aConnName = sName;
402cdf0e10cSrcweir                         bDropRelation = aNames.getLength() == 0; // the key contains no column, so it isn't valid and we have to drop it
403cdf0e10cSrcweir                         //here we already know our column structure so we don't have to recreate the table connection data
404cdf0e10cSrcweir                         xColSup.clear();
405cdf0e10cSrcweir                         break;
406cdf0e10cSrcweir                     }
407cdf0e10cSrcweir                 }
408cdf0e10cSrcweir                 catch(Exception&)
409cdf0e10cSrcweir                 {
410cdf0e10cSrcweir                 }
411cdf0e10cSrcweir 			}
412cdf0e10cSrcweir 		}
413cdf0e10cSrcweir 	xKey.clear();
414cdf0e10cSrcweir 	} // for(sal_Int32 i=0;i<xKeys->getCount();++i)
415cdf0e10cSrcweir     if ( bDropRelation )
416cdf0e10cSrcweir     {
417cdf0e10cSrcweir         DropRelation();
418cdf0e10cSrcweir         String sError(ModuleRes(STR_QUERY_REL_COULD_NOT_CREATE));
419cdf0e10cSrcweir         ::dbtools::throwGenericSQLException(sError,NULL);
420cdf0e10cSrcweir     }
421cdf0e10cSrcweir 
422cdf0e10cSrcweir //	OSL_ENSURE(xKey.is(),"No key found have insertion!");
423cdf0e10cSrcweir 
424cdf0e10cSrcweir     // The fields the relation marks may not be the same as our LineDatas mark after the relation has been updated
425cdf0e10cSrcweir 	if ( xColSup.is() )
426cdf0e10cSrcweir 	{
427cdf0e10cSrcweir         OConnectionLineDataVec().swap(m_vConnLineData);
428cdf0e10cSrcweir 		Reference<XNameAccess> xColumns = xColSup->getColumns();
429cdf0e10cSrcweir 		Sequence< ::rtl::OUString> aNames = xColumns->getElementNames();
430cdf0e10cSrcweir 		const ::rtl::OUString* pIter = aNames.getConstArray();
431cdf0e10cSrcweir 		const ::rtl::OUString* pEnd = pIter + aNames.getLength();
432cdf0e10cSrcweir 
433cdf0e10cSrcweir 		m_vConnLineData.reserve( aNames.getLength() );
434cdf0e10cSrcweir 		Reference<XPropertySet> xColumn;
435cdf0e10cSrcweir 		::rtl::OUString sName,sRelatedColumn;
436cdf0e10cSrcweir 
437cdf0e10cSrcweir 		for(;pIter != pEnd;++pIter)
438cdf0e10cSrcweir 		{
439cdf0e10cSrcweir 			xColumns->getByName(*pIter) >>= xColumn;
440cdf0e10cSrcweir 			if ( xColumn.is() )
441cdf0e10cSrcweir 			{
442cdf0e10cSrcweir 				OConnectionLineDataRef pNewData = CreateLineDataObj();
443cdf0e10cSrcweir 
444cdf0e10cSrcweir 				xColumn->getPropertyValue(PROPERTY_NAME)			>>= sName;
445cdf0e10cSrcweir 				xColumn->getPropertyValue(PROPERTY_RELATEDCOLUMN)	>>= sRelatedColumn;
446cdf0e10cSrcweir 
447cdf0e10cSrcweir 				pNewData->SetSourceFieldName(sName);
448cdf0e10cSrcweir 				pNewData->SetDestFieldName(sRelatedColumn);
449cdf0e10cSrcweir 				m_vConnLineData.push_back(pNewData);
450cdf0e10cSrcweir 			}
451cdf0e10cSrcweir 		}
452cdf0e10cSrcweir 	} // if ( xColSup.is() )
453cdf0e10cSrcweir 	// NOTE : the caller is resposible for updating any other objects referencing the old LineDatas (for instance a ConnLine)
454cdf0e10cSrcweir 
455cdf0e10cSrcweir 	////////////////////////////////////////////////////////////
456cdf0e10cSrcweir 	// Kardinalitaet bestimmen
457cdf0e10cSrcweir 	SetCardinality();
458cdf0e10cSrcweir 
459cdf0e10cSrcweir 	return sal_True;
460cdf0e10cSrcweir }
461cdf0e10cSrcweir // -----------------------------------------------------------------------------
462cdf0e10cSrcweir 
463