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