1*96de5490SAndrew Rist /**************************************************************
2cdf0e10cSrcweir *
3*96de5490SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one
4*96de5490SAndrew Rist * or more contributor license agreements. See the NOTICE file
5*96de5490SAndrew Rist * distributed with this work for additional information
6*96de5490SAndrew Rist * regarding copyright ownership. The ASF licenses this file
7*96de5490SAndrew Rist * to you under the Apache License, Version 2.0 (the
8*96de5490SAndrew Rist * "License"); you may not use this file except in compliance
9*96de5490SAndrew Rist * with the License. You may obtain a copy of the License at
10cdf0e10cSrcweir *
11*96de5490SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir *
13*96de5490SAndrew Rist * Unless required by applicable law or agreed to in writing,
14*96de5490SAndrew Rist * software distributed under the License is distributed on an
15*96de5490SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*96de5490SAndrew Rist * KIND, either express or implied. See the License for the
17*96de5490SAndrew Rist * specific language governing permissions and limitations
18*96de5490SAndrew Rist * under the License.
19cdf0e10cSrcweir *
20*96de5490SAndrew Rist *************************************************************/
21*96de5490SAndrew Rist
22*96de5490SAndrew Rist
23cdf0e10cSrcweir
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_dbaccess.hxx"
26cdf0e10cSrcweir #include "dbu_reghelper.hxx"
27cdf0e10cSrcweir #include <sfx2/sfxsids.hrc>
28cdf0e10cSrcweir #include "dbu_rel.hrc"
29cdf0e10cSrcweir #include <vcl/svapp.hxx>
30cdf0e10cSrcweir #include "browserids.hxx"
31cdf0e10cSrcweir #include <comphelper/types.hxx>
32cdf0e10cSrcweir #include "dbustrings.hrc"
33cdf0e10cSrcweir #include <connectivity/dbtools.hxx>
34cdf0e10cSrcweir #include <com/sun/star/frame/FrameSearchFlag.hpp>
35cdf0e10cSrcweir #include <comphelper/extract.hxx>
36cdf0e10cSrcweir #include <com/sun/star/container/XChild.hpp>
37cdf0e10cSrcweir #include <com/sun/star/container/XNameContainer.hpp>
38cdf0e10cSrcweir #include <com/sun/star/sdbcx/XDataDescriptorFactory.hpp>
39cdf0e10cSrcweir #include <com/sun/star/sdbcx/XTablesSupplier.hpp>
40cdf0e10cSrcweir #include <com/sun/star/sdbcx/KeyType.hpp>
41cdf0e10cSrcweir #include <com/sun/star/sdbcx/XDrop.hpp>
42cdf0e10cSrcweir #include <com/sun/star/sdbcx/XAlterTable.hpp>
43cdf0e10cSrcweir #include <com/sun/star/sdbcx/XAppend.hpp>
44cdf0e10cSrcweir #include <com/sun/star/sdbcx/XKeysSupplier.hpp>
45cdf0e10cSrcweir #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
46cdf0e10cSrcweir #include <com/sun/star/sdb/SQLContext.hpp>
47cdf0e10cSrcweir #include <com/sun/star/sdbc/SQLWarning.hpp>
48cdf0e10cSrcweir #include <com/sun/star/sdbc/ColumnValue.hpp>
49cdf0e10cSrcweir #include <com/sun/star/sdbc/XRow.hpp>
50cdf0e10cSrcweir #include <connectivity/dbexception.hxx>
51cdf0e10cSrcweir #include <connectivity/dbmetadata.hxx>
52cdf0e10cSrcweir #include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
53cdf0e10cSrcweir #include <comphelper/streamsection.hxx>
54cdf0e10cSrcweir #include <comphelper/basicio.hxx>
55cdf0e10cSrcweir #include <comphelper/seqstream.hxx>
56cdf0e10cSrcweir #include <com/sun/star/io/XActiveDataSource.hpp>
57cdf0e10cSrcweir #include <com/sun/star/io/XActiveDataSink.hpp>
58cdf0e10cSrcweir #include "sqlmessage.hxx"
59cdf0e10cSrcweir #include "RelationController.hxx"
60cdf0e10cSrcweir #include <vcl/msgbox.hxx>
61cdf0e10cSrcweir #include "TableWindowData.hxx"
62cdf0e10cSrcweir #include "dbustrings.hrc"
63cdf0e10cSrcweir #include "UITools.hxx"
64cdf0e10cSrcweir #include "RTableConnectionData.hxx"
65cdf0e10cSrcweir #include "RelationTableView.hxx"
66cdf0e10cSrcweir #include "RelationDesignView.hxx"
67cdf0e10cSrcweir #include <tools/debug.hxx>
68cdf0e10cSrcweir #include <tools/diagnose_ex.h>
69cdf0e10cSrcweir #include <vcl/waitobj.hxx>
70cdf0e10cSrcweir #include <osl/thread.hxx>
71cdf0e10cSrcweir #include <vos/mutex.hxx>
72cdf0e10cSrcweir
73cdf0e10cSrcweir
74cdf0e10cSrcweir #define MAX_THREADS 10
75cdf0e10cSrcweir
createRegistryInfo_ORelationControl()76cdf0e10cSrcweir extern "C" void SAL_CALL createRegistryInfo_ORelationControl()
77cdf0e10cSrcweir {
78cdf0e10cSrcweir static ::dbaui::OMultiInstanceAutoRegistration< ::dbaui::ORelationController > aAutoRegistration;
79cdf0e10cSrcweir }
80cdf0e10cSrcweir
81cdf0e10cSrcweir
82cdf0e10cSrcweir using namespace ::com::sun::star::uno;
83cdf0e10cSrcweir using namespace ::com::sun::star::io;
84cdf0e10cSrcweir using namespace ::com::sun::star::beans;
85cdf0e10cSrcweir using namespace ::com::sun::star::frame;
86cdf0e10cSrcweir using namespace ::com::sun::star::util;
87cdf0e10cSrcweir using namespace ::com::sun::star::lang;
88cdf0e10cSrcweir using namespace ::com::sun::star::container;
89cdf0e10cSrcweir using namespace ::com::sun::star::sdbcx;
90cdf0e10cSrcweir using namespace ::com::sun::star::sdbc;
91cdf0e10cSrcweir using namespace ::com::sun::star::sdb;
92cdf0e10cSrcweir using namespace ::com::sun::star::ui::dialogs;
93cdf0e10cSrcweir using namespace ::com::sun::star::util;
94cdf0e10cSrcweir // using namespace ::com::sun::star::sdbcx;
95cdf0e10cSrcweir // using namespace ::connectivity;
96cdf0e10cSrcweir using namespace ::dbtools;
97cdf0e10cSrcweir using namespace ::dbaui;
98cdf0e10cSrcweir using namespace ::comphelper;
99cdf0e10cSrcweir using namespace ::osl;
100cdf0e10cSrcweir
101cdf0e10cSrcweir //------------------------------------------------------------------------------
getImplementationName()102cdf0e10cSrcweir ::rtl::OUString SAL_CALL ORelationController::getImplementationName() throw( RuntimeException )
103cdf0e10cSrcweir {
104cdf0e10cSrcweir return getImplementationName_Static();
105cdf0e10cSrcweir }
106cdf0e10cSrcweir
107cdf0e10cSrcweir //------------------------------------------------------------------------------
getImplementationName_Static()108cdf0e10cSrcweir ::rtl::OUString ORelationController::getImplementationName_Static() throw( RuntimeException )
109cdf0e10cSrcweir {
110cdf0e10cSrcweir return ::rtl::OUString::createFromAscii("org.openoffice.comp.dbu.ORelationDesign");
111cdf0e10cSrcweir }
112cdf0e10cSrcweir //------------------------------------------------------------------------------
getSupportedServiceNames_Static(void)113cdf0e10cSrcweir Sequence< ::rtl::OUString> ORelationController::getSupportedServiceNames_Static(void) throw( RuntimeException )
114cdf0e10cSrcweir {
115cdf0e10cSrcweir Sequence< ::rtl::OUString> aSupported(1);
116cdf0e10cSrcweir aSupported.getArray()[0] = ::rtl::OUString::createFromAscii("com.sun.star.sdb.RelationDesign");
117cdf0e10cSrcweir return aSupported;
118cdf0e10cSrcweir }
119cdf0e10cSrcweir //-------------------------------------------------------------------------
getSupportedServiceNames()120cdf0e10cSrcweir Sequence< ::rtl::OUString> SAL_CALL ORelationController::getSupportedServiceNames() throw(RuntimeException)
121cdf0e10cSrcweir {
122cdf0e10cSrcweir return getSupportedServiceNames_Static();
123cdf0e10cSrcweir }
124cdf0e10cSrcweir // -------------------------------------------------------------------------
Create(const Reference<XMultiServiceFactory> & _rxFactory)125cdf0e10cSrcweir Reference< XInterface > SAL_CALL ORelationController::Create(const Reference<XMultiServiceFactory >& _rxFactory)
126cdf0e10cSrcweir {
127cdf0e10cSrcweir return *(new ORelationController(_rxFactory));
128cdf0e10cSrcweir }
129cdf0e10cSrcweir DBG_NAME(ORelationController);
130cdf0e10cSrcweir // -----------------------------------------------------------------------------
ORelationController(const Reference<XMultiServiceFactory> & _rM)131cdf0e10cSrcweir ORelationController::ORelationController(const Reference< XMultiServiceFactory >& _rM)
132cdf0e10cSrcweir : OJoinController(_rM)
133cdf0e10cSrcweir ,m_nThreadEvent(0)
134cdf0e10cSrcweir ,m_bRelationsPossible(sal_True)
135cdf0e10cSrcweir {
136cdf0e10cSrcweir DBG_CTOR(ORelationController,NULL);
137cdf0e10cSrcweir InvalidateAll();
138cdf0e10cSrcweir }
139cdf0e10cSrcweir // -----------------------------------------------------------------------------
~ORelationController()140cdf0e10cSrcweir ORelationController::~ORelationController()
141cdf0e10cSrcweir {
142cdf0e10cSrcweir DBG_DTOR(ORelationController,NULL);
143cdf0e10cSrcweir }
144cdf0e10cSrcweir // -----------------------------------------------------------------------------
GetState(sal_uInt16 _nId) const145cdf0e10cSrcweir FeatureState ORelationController::GetState(sal_uInt16 _nId) const
146cdf0e10cSrcweir {
147cdf0e10cSrcweir FeatureState aReturn;
148cdf0e10cSrcweir aReturn.bEnabled = m_bRelationsPossible;
149cdf0e10cSrcweir switch (_nId)
150cdf0e10cSrcweir {
151cdf0e10cSrcweir case SID_RELATION_ADD_RELATION:
152cdf0e10cSrcweir aReturn.bEnabled = !m_vTableData.empty() && isConnected() && isEditable();
153cdf0e10cSrcweir aReturn.bChecked = false;
154cdf0e10cSrcweir break;
155cdf0e10cSrcweir case ID_BROWSER_SAVEDOC:
156cdf0e10cSrcweir aReturn.bEnabled = haveDataSource() && impl_isModified();
157cdf0e10cSrcweir break;
158cdf0e10cSrcweir default:
159cdf0e10cSrcweir aReturn = OJoinController::GetState(_nId);
160cdf0e10cSrcweir break;
161cdf0e10cSrcweir }
162cdf0e10cSrcweir return aReturn;
163cdf0e10cSrcweir }
164cdf0e10cSrcweir // -----------------------------------------------------------------------------
Execute(sal_uInt16 _nId,const Sequence<PropertyValue> & aArgs)165cdf0e10cSrcweir void ORelationController::Execute(sal_uInt16 _nId, const Sequence< PropertyValue >& aArgs)
166cdf0e10cSrcweir {
167cdf0e10cSrcweir switch(_nId)
168cdf0e10cSrcweir {
169cdf0e10cSrcweir case ID_BROWSER_SAVEDOC:
170cdf0e10cSrcweir {
171cdf0e10cSrcweir OSL_ENSURE(isEditable(),"Slot ID_BROWSER_SAVEDOC should not be enabled!");
172cdf0e10cSrcweir if(!::dbaui::checkDataSourceAvailable(::comphelper::getString(getDataSource()->getPropertyValue(PROPERTY_NAME)),getORB()))
173cdf0e10cSrcweir {
174cdf0e10cSrcweir String aMessage(ModuleRes(STR_DATASOURCE_DELETED));
175cdf0e10cSrcweir OSQLWarningBox( getView(), aMessage ).Execute();
176cdf0e10cSrcweir }
177cdf0e10cSrcweir else
178cdf0e10cSrcweir {
179cdf0e10cSrcweir // now we save the layout information
180cdf0e10cSrcweir // create the output stream
181cdf0e10cSrcweir try
182cdf0e10cSrcweir {
183cdf0e10cSrcweir if ( haveDataSource() && getDataSource()->getPropertySetInfo()->hasPropertyByName(PROPERTY_LAYOUTINFORMATION) )
184cdf0e10cSrcweir {
185cdf0e10cSrcweir ::comphelper::NamedValueCollection aWindowsData;
186cdf0e10cSrcweir saveTableWindows( aWindowsData );
187cdf0e10cSrcweir getDataSource()->setPropertyValue( PROPERTY_LAYOUTINFORMATION, makeAny( aWindowsData.getPropertyValues() ) );
188cdf0e10cSrcweir setModified(sal_False);
189cdf0e10cSrcweir }
190cdf0e10cSrcweir }
191cdf0e10cSrcweir catch ( const Exception& )
192cdf0e10cSrcweir {
193cdf0e10cSrcweir DBG_UNHANDLED_EXCEPTION();
194cdf0e10cSrcweir }
195cdf0e10cSrcweir }
196cdf0e10cSrcweir }
197cdf0e10cSrcweir break;
198cdf0e10cSrcweir case SID_RELATION_ADD_RELATION:
199cdf0e10cSrcweir static_cast<ORelationTableView*>(static_cast<ORelationDesignView*>( getView() )->getTableView())->AddNewRelation();
200cdf0e10cSrcweir break;
201cdf0e10cSrcweir default:
202cdf0e10cSrcweir OJoinController::Execute(_nId,aArgs);
203cdf0e10cSrcweir return;
204cdf0e10cSrcweir }
205cdf0e10cSrcweir InvalidateFeature(_nId);
206cdf0e10cSrcweir }
207cdf0e10cSrcweir // -----------------------------------------------------------------------------
impl_initialize()208cdf0e10cSrcweir void ORelationController::impl_initialize()
209cdf0e10cSrcweir {
210cdf0e10cSrcweir OJoinController::impl_initialize();
211cdf0e10cSrcweir
212cdf0e10cSrcweir if( !getSdbMetaData().supportsRelations() )
213cdf0e10cSrcweir {// check if this database supports relations
214cdf0e10cSrcweir
215cdf0e10cSrcweir setEditable(sal_False);
216cdf0e10cSrcweir m_bRelationsPossible = sal_False;
217cdf0e10cSrcweir {
218cdf0e10cSrcweir String sTitle(ModuleRes(STR_RELATIONDESIGN));
219cdf0e10cSrcweir sTitle.Erase(0,3);
220cdf0e10cSrcweir OSQLMessageBox aDlg(NULL,sTitle,ModuleRes(STR_RELATIONDESIGN_NOT_AVAILABLE));
221cdf0e10cSrcweir aDlg.Execute();
222cdf0e10cSrcweir }
223cdf0e10cSrcweir disconnect();
224cdf0e10cSrcweir throw SQLException();
225cdf0e10cSrcweir }
226cdf0e10cSrcweir
227cdf0e10cSrcweir if(!m_bRelationsPossible)
228cdf0e10cSrcweir InvalidateAll();
229cdf0e10cSrcweir
230cdf0e10cSrcweir // we need a datasource
231cdf0e10cSrcweir OSL_ENSURE(haveDataSource(),"ORelationController::initialize: need a datasource!");
232cdf0e10cSrcweir
233cdf0e10cSrcweir Reference<XTablesSupplier> xSup(getConnection(),UNO_QUERY);
234cdf0e10cSrcweir OSL_ENSURE(xSup.is(),"Connection isn't a XTablesSupplier!");
235cdf0e10cSrcweir if(xSup.is())
236cdf0e10cSrcweir m_xTables = xSup->getTables();
237cdf0e10cSrcweir // load the layoutInformation
238cdf0e10cSrcweir loadLayoutInformation();
239cdf0e10cSrcweir try
240cdf0e10cSrcweir {
241cdf0e10cSrcweir loadData();
242cdf0e10cSrcweir if ( !m_nThreadEvent )
243cdf0e10cSrcweir Application::PostUserEvent(LINK(this, ORelationController, OnThreadFinished));
244cdf0e10cSrcweir }
245cdf0e10cSrcweir catch( const Exception& )
246cdf0e10cSrcweir {
247cdf0e10cSrcweir DBG_UNHANDLED_EXCEPTION();
248cdf0e10cSrcweir }
249cdf0e10cSrcweir
250cdf0e10cSrcweir }
251cdf0e10cSrcweir // -----------------------------------------------------------------------------
getPrivateTitle() const252cdf0e10cSrcweir ::rtl::OUString ORelationController::getPrivateTitle( ) const
253cdf0e10cSrcweir {
254cdf0e10cSrcweir ::rtl::OUString sName = getDataSourceName();
255cdf0e10cSrcweir return ::dbaui::getStrippedDatabaseName(getDataSource(),sName);
256cdf0e10cSrcweir }
257cdf0e10cSrcweir // -----------------------------------------------------------------------------
Construct(Window * pParent)258cdf0e10cSrcweir sal_Bool ORelationController::Construct(Window* pParent)
259cdf0e10cSrcweir {
260cdf0e10cSrcweir setView( * new ORelationDesignView( pParent, *this, getORB() ) );
261cdf0e10cSrcweir OJoinController::Construct(pParent);
262cdf0e10cSrcweir return sal_True;
263cdf0e10cSrcweir }
264cdf0e10cSrcweir // -----------------------------------------------------------------------------
saveModified()265cdf0e10cSrcweir short ORelationController::saveModified()
266cdf0e10cSrcweir {
267cdf0e10cSrcweir short nSaved = RET_YES;
268cdf0e10cSrcweir if(haveDataSource() && isModified())
269cdf0e10cSrcweir {
270cdf0e10cSrcweir QueryBox aQry(getView(), ModuleRes(RELATION_DESIGN_SAVEMODIFIED));
271cdf0e10cSrcweir nSaved = aQry.Execute();
272cdf0e10cSrcweir if(nSaved == RET_YES)
273cdf0e10cSrcweir Execute(ID_BROWSER_SAVEDOC,Sequence<PropertyValue>());
274cdf0e10cSrcweir }
275cdf0e10cSrcweir return nSaved;
276cdf0e10cSrcweir }
277cdf0e10cSrcweir // -----------------------------------------------------------------------------
describeSupportedFeatures()278cdf0e10cSrcweir void ORelationController::describeSupportedFeatures()
279cdf0e10cSrcweir {
280cdf0e10cSrcweir OJoinController::describeSupportedFeatures();
281cdf0e10cSrcweir implDescribeSupportedFeature( ".uno:DBAddRelation", SID_RELATION_ADD_RELATION, CommandGroup::EDIT );
282cdf0e10cSrcweir }
283cdf0e10cSrcweir namespace
284cdf0e10cSrcweir {
285cdf0e10cSrcweir class RelationLoader : public ::osl::Thread
286cdf0e10cSrcweir {
287cdf0e10cSrcweir DECLARE_STL_MAP(::rtl::OUString,::boost::shared_ptr<OTableWindowData>,::comphelper::UStringMixLess,TTableDataHelper);
288cdf0e10cSrcweir TTableDataHelper m_aTableData;
289cdf0e10cSrcweir TTableConnectionData m_vTableConnectionData;
290cdf0e10cSrcweir const Sequence< ::rtl::OUString> m_aTableList;
291cdf0e10cSrcweir ORelationController* m_pParent;
292cdf0e10cSrcweir const Reference< XDatabaseMetaData> m_xMetaData;
293cdf0e10cSrcweir const Reference< XNameAccess > m_xTables;
294cdf0e10cSrcweir const sal_Int32 m_nStartIndex;
295cdf0e10cSrcweir const sal_Int32 m_nEndIndex;
296cdf0e10cSrcweir
297cdf0e10cSrcweir public:
RelationLoader(ORelationController * _pParent,const Reference<XDatabaseMetaData> & _xMetaData,const Reference<XNameAccess> & _xTables,const Sequence<::rtl::OUString> & _aTableList,const sal_Int32 _nStartIndex,const sal_Int32 _nEndIndex)298cdf0e10cSrcweir RelationLoader(ORelationController* _pParent
299cdf0e10cSrcweir ,const Reference< XDatabaseMetaData>& _xMetaData
300cdf0e10cSrcweir ,const Reference< XNameAccess >& _xTables
301cdf0e10cSrcweir ,const Sequence< ::rtl::OUString>& _aTableList
302cdf0e10cSrcweir ,const sal_Int32 _nStartIndex
303cdf0e10cSrcweir ,const sal_Int32 _nEndIndex)
304cdf0e10cSrcweir :m_aTableData(_xMetaData.is() && _xMetaData->supportsMixedCaseQuotedIdentifiers())
305cdf0e10cSrcweir ,m_aTableList(_aTableList)
306cdf0e10cSrcweir ,m_pParent(_pParent)
307cdf0e10cSrcweir ,m_xMetaData(_xMetaData)
308cdf0e10cSrcweir ,m_xTables(_xTables)
309cdf0e10cSrcweir ,m_nStartIndex(_nStartIndex)
310cdf0e10cSrcweir ,m_nEndIndex(_nEndIndex)
311cdf0e10cSrcweir {
312cdf0e10cSrcweir }
313cdf0e10cSrcweir
314cdf0e10cSrcweir /// Working method which should be overridden.
315cdf0e10cSrcweir virtual void SAL_CALL run();
316cdf0e10cSrcweir virtual void SAL_CALL onTerminated();
317cdf0e10cSrcweir protected:
~RelationLoader()318cdf0e10cSrcweir virtual ~RelationLoader(){}
319cdf0e10cSrcweir
320cdf0e10cSrcweir void loadTableData(const Any& _aTable);
321cdf0e10cSrcweir };
322cdf0e10cSrcweir
run()323cdf0e10cSrcweir void SAL_CALL RelationLoader::run()
324cdf0e10cSrcweir {
325cdf0e10cSrcweir const ::rtl::OUString* pIter = m_aTableList.getConstArray() + m_nStartIndex;
326cdf0e10cSrcweir for(sal_Int32 i = m_nStartIndex; i < m_nEndIndex;++i,++pIter)
327cdf0e10cSrcweir {
328cdf0e10cSrcweir ::rtl::OUString sCatalog,sSchema,sTable;
329cdf0e10cSrcweir ::dbtools::qualifiedNameComponents(m_xMetaData,
330cdf0e10cSrcweir *pIter,
331cdf0e10cSrcweir sCatalog,
332cdf0e10cSrcweir sSchema,
333cdf0e10cSrcweir sTable,
334cdf0e10cSrcweir ::dbtools::eInDataManipulation);
335cdf0e10cSrcweir Any aCatalog;
336cdf0e10cSrcweir if ( sCatalog.getLength() )
337cdf0e10cSrcweir aCatalog <<= sCatalog;
338cdf0e10cSrcweir
339cdf0e10cSrcweir try
340cdf0e10cSrcweir {
341cdf0e10cSrcweir Reference< XResultSet > xResult = m_xMetaData->getImportedKeys(aCatalog, sSchema,sTable);
342cdf0e10cSrcweir if ( xResult.is() && xResult->next() )
343cdf0e10cSrcweir {
344cdf0e10cSrcweir ::comphelper::disposeComponent(xResult);
345cdf0e10cSrcweir loadTableData(m_xTables->getByName(*pIter));
346cdf0e10cSrcweir } // if ( xResult.is() && xResult->next() )
347cdf0e10cSrcweir }
348cdf0e10cSrcweir catch( const Exception& )
349cdf0e10cSrcweir {
350cdf0e10cSrcweir DBG_UNHANDLED_EXCEPTION();
351cdf0e10cSrcweir }
352cdf0e10cSrcweir }
353cdf0e10cSrcweir }
onTerminated()354cdf0e10cSrcweir void SAL_CALL RelationLoader::onTerminated()
355cdf0e10cSrcweir {
356cdf0e10cSrcweir m_pParent->mergeData(m_vTableConnectionData);
357cdf0e10cSrcweir delete this;
358cdf0e10cSrcweir }
359cdf0e10cSrcweir
loadTableData(const Any & _aTable)360cdf0e10cSrcweir void RelationLoader::loadTableData(const Any& _aTable)
361cdf0e10cSrcweir {
362cdf0e10cSrcweir Reference<XPropertySet> xTableProp(_aTable,UNO_QUERY);
363cdf0e10cSrcweir const ::rtl::OUString sSourceName = ::dbtools::composeTableName( m_xMetaData, xTableProp, ::dbtools::eInTableDefinitions, false, false, false );
364cdf0e10cSrcweir TTableDataHelper::iterator aFind = m_aTableData.find(sSourceName);
365cdf0e10cSrcweir bool bNotFound = true, bAdded = false;
366cdf0e10cSrcweir if ( aFind == m_aTableData.end() )
367cdf0e10cSrcweir {
368cdf0e10cSrcweir aFind = m_aTableData.insert(TTableDataHelper::value_type(sSourceName,::boost::shared_ptr<OTableWindowData>(new OTableWindowData(xTableProp,sSourceName, sSourceName)))).first;
369cdf0e10cSrcweir aFind->second->ShowAll(sal_False);
370cdf0e10cSrcweir bAdded = true;
371cdf0e10cSrcweir }
372cdf0e10cSrcweir TTableWindowData::value_type pReferencingTable = aFind->second;
373cdf0e10cSrcweir Reference<XIndexAccess> xKeys = pReferencingTable->getKeys();
374cdf0e10cSrcweir const Reference<XKeysSupplier> xKeySup(xTableProp,UNO_QUERY);
375cdf0e10cSrcweir
376cdf0e10cSrcweir if ( !xKeys.is() && xKeySup.is() )
377cdf0e10cSrcweir {
378cdf0e10cSrcweir xKeys = xKeySup->getKeys();
379cdf0e10cSrcweir }
380cdf0e10cSrcweir
381cdf0e10cSrcweir if ( xKeys.is() )
382cdf0e10cSrcweir {
383cdf0e10cSrcweir Reference<XPropertySet> xKey;
384cdf0e10cSrcweir const sal_Int32 nCount = xKeys->getCount();
385cdf0e10cSrcweir for(sal_Int32 i = 0 ; i < nCount ; ++i)
386cdf0e10cSrcweir {
387cdf0e10cSrcweir xKeys->getByIndex(i) >>= xKey;
388cdf0e10cSrcweir sal_Int32 nKeyType = 0;
389cdf0e10cSrcweir xKey->getPropertyValue(PROPERTY_TYPE) >>= nKeyType;
390cdf0e10cSrcweir if ( KeyType::FOREIGN == nKeyType )
391cdf0e10cSrcweir {
392cdf0e10cSrcweir bNotFound = false;
393cdf0e10cSrcweir ::rtl::OUString sReferencedTable;
394cdf0e10cSrcweir xKey->getPropertyValue(PROPERTY_REFERENCEDTABLE) >>= sReferencedTable;
395cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////
396cdf0e10cSrcweir // insert windows
397cdf0e10cSrcweir TTableDataHelper::iterator aRefFind = m_aTableData.find(sReferencedTable);
398cdf0e10cSrcweir if ( aRefFind == m_aTableData.end() )
399cdf0e10cSrcweir {
400cdf0e10cSrcweir if ( m_xTables->hasByName(sReferencedTable) )
401cdf0e10cSrcweir {
402cdf0e10cSrcweir Reference<XPropertySet> xReferencedTable(m_xTables->getByName(sReferencedTable),UNO_QUERY);
403cdf0e10cSrcweir aRefFind = m_aTableData.insert(TTableDataHelper::value_type(sReferencedTable,::boost::shared_ptr<OTableWindowData>(new OTableWindowData(xReferencedTable,sReferencedTable, sReferencedTable)))).first;
404cdf0e10cSrcweir aRefFind->second->ShowAll(sal_False);
405cdf0e10cSrcweir }
406cdf0e10cSrcweir else
407cdf0e10cSrcweir continue; // table name could not be found so we do not show this table releation
408cdf0e10cSrcweir } // if ( aFind == m_aTableData.end() )
409cdf0e10cSrcweir TTableWindowData::value_type pReferencedTable = aRefFind->second;
410cdf0e10cSrcweir
411cdf0e10cSrcweir ::rtl::OUString sKeyName;
412cdf0e10cSrcweir xKey->getPropertyValue(PROPERTY_NAME) >>= sKeyName;
413cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////
414cdf0e10cSrcweir // insert connection
415cdf0e10cSrcweir ORelationTableConnectionData* pTabConnData = new ORelationTableConnectionData( pReferencingTable, pReferencedTable, sKeyName );
416cdf0e10cSrcweir m_vTableConnectionData.push_back(TTableConnectionData::value_type(pTabConnData));
417cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////
418cdf0e10cSrcweir // insert columns
419cdf0e10cSrcweir const Reference<XColumnsSupplier> xColsSup(xKey,UNO_QUERY);
420cdf0e10cSrcweir OSL_ENSURE(xColsSup.is(),"Key is no XColumnsSupplier!");
421cdf0e10cSrcweir const Reference<XNameAccess> xColumns = xColsSup->getColumns();
422cdf0e10cSrcweir const Sequence< ::rtl::OUString> aNames = xColumns->getElementNames();
423cdf0e10cSrcweir const ::rtl::OUString* pIter = aNames.getConstArray();
424cdf0e10cSrcweir const ::rtl::OUString* pEnd = pIter + aNames.getLength();
425cdf0e10cSrcweir ::rtl::OUString sColumnName,sRelatedName;
426cdf0e10cSrcweir for(sal_uInt16 j=0;pIter != pEnd;++pIter,++j)
427cdf0e10cSrcweir {
428cdf0e10cSrcweir const Reference<XPropertySet> xPropSet(xColumns->getByName(*pIter),UNO_QUERY);
429cdf0e10cSrcweir OSL_ENSURE(xPropSet.is(),"Invalid column found in KeyColumns!");
430cdf0e10cSrcweir if ( xPropSet.is() )
431cdf0e10cSrcweir {
432cdf0e10cSrcweir xPropSet->getPropertyValue(PROPERTY_NAME) >>= sColumnName;
433cdf0e10cSrcweir xPropSet->getPropertyValue(PROPERTY_RELATEDCOLUMN) >>= sRelatedName;
434cdf0e10cSrcweir }
435cdf0e10cSrcweir pTabConnData->SetConnLine( j, sColumnName, sRelatedName );
436cdf0e10cSrcweir }
437cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////
438cdf0e10cSrcweir // Update/Del-Flags setzen
439cdf0e10cSrcweir sal_Int32 nUpdateRule = 0;
440cdf0e10cSrcweir sal_Int32 nDeleteRule = 0;
441cdf0e10cSrcweir xKey->getPropertyValue(PROPERTY_UPDATERULE) >>= nUpdateRule;
442cdf0e10cSrcweir xKey->getPropertyValue(PROPERTY_DELETERULE) >>= nDeleteRule;
443cdf0e10cSrcweir
444cdf0e10cSrcweir pTabConnData->SetUpdateRules( nUpdateRule );
445cdf0e10cSrcweir pTabConnData->SetDeleteRules( nDeleteRule );
446cdf0e10cSrcweir
447cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////
448cdf0e10cSrcweir // Kardinalitaet setzen
449cdf0e10cSrcweir pTabConnData->SetCardinality();
450cdf0e10cSrcweir }
451cdf0e10cSrcweir }
452cdf0e10cSrcweir } // if ( xKeys.is() )
453cdf0e10cSrcweir }
454cdf0e10cSrcweir }
455cdf0e10cSrcweir
mergeData(const TTableConnectionData & _aConnectionData)456cdf0e10cSrcweir void ORelationController::mergeData(const TTableConnectionData& _aConnectionData)
457cdf0e10cSrcweir {
458cdf0e10cSrcweir ::osl::MutexGuard aGuard( getMutex() );
459cdf0e10cSrcweir
460cdf0e10cSrcweir ::std::copy( _aConnectionData.begin(), _aConnectionData.end(), ::std::back_inserter( m_vTableConnectionData ));
461cdf0e10cSrcweir //const Reference< XDatabaseMetaData> xMetaData = getConnection()->getMetaData();
462cdf0e10cSrcweir const sal_Bool bCase = sal_True;//xMetaData.is() && xMetaData->supportsMixedCaseQuotedIdentifiers();
463cdf0e10cSrcweir // here we are finished, so we can collect the table from connection data
464cdf0e10cSrcweir TTableConnectionData::iterator aConnDataIter = m_vTableConnectionData.begin();
465cdf0e10cSrcweir TTableConnectionData::iterator aConnDataEnd = m_vTableConnectionData.end();
466cdf0e10cSrcweir for(;aConnDataIter != aConnDataEnd;++aConnDataIter)
467cdf0e10cSrcweir {
468cdf0e10cSrcweir if ( !existsTable((*aConnDataIter)->getReferencingTable()->GetComposedName(),bCase) )
469cdf0e10cSrcweir {
470cdf0e10cSrcweir m_vTableData.push_back((*aConnDataIter)->getReferencingTable());
471cdf0e10cSrcweir }
472cdf0e10cSrcweir if ( !existsTable((*aConnDataIter)->getReferencedTable()->GetComposedName(),bCase) )
473cdf0e10cSrcweir {
474cdf0e10cSrcweir m_vTableData.push_back((*aConnDataIter)->getReferencedTable());
475cdf0e10cSrcweir }
476cdf0e10cSrcweir } // for(;aConnDataIter != aConnDataEnd;++aConnDataIter)
477cdf0e10cSrcweir if ( m_nThreadEvent )
478cdf0e10cSrcweir {
479cdf0e10cSrcweir --m_nThreadEvent;
480cdf0e10cSrcweir if ( !m_nThreadEvent )
481cdf0e10cSrcweir Application::PostUserEvent(LINK(this, ORelationController, OnThreadFinished));
482cdf0e10cSrcweir }
483cdf0e10cSrcweir }
484cdf0e10cSrcweir // -----------------------------------------------------------------------------
485cdf0e10cSrcweir IMPL_LINK( ORelationController, OnThreadFinished, void*, /*NOTINTERESTEDIN*/ )
486cdf0e10cSrcweir {
487cdf0e10cSrcweir vos::OGuard aSolarGuard( Application::GetSolarMutex() );
488cdf0e10cSrcweir ::osl::MutexGuard aGuard( getMutex() );
489cdf0e10cSrcweir try
490cdf0e10cSrcweir {
491cdf0e10cSrcweir getView()->initialize(); // show the windows and fill with our informations
492cdf0e10cSrcweir getView()->Invalidate(INVALIDATE_NOERASE);
493cdf0e10cSrcweir ClearUndoManager();
494cdf0e10cSrcweir setModified(sal_False); // and we are not modified yet
495cdf0e10cSrcweir
496cdf0e10cSrcweir if(m_vTableData.empty())
497cdf0e10cSrcweir Execute(ID_BROWSER_ADDTABLE,Sequence<PropertyValue>());
498cdf0e10cSrcweir }
499cdf0e10cSrcweir catch( const Exception& )
500cdf0e10cSrcweir {
501cdf0e10cSrcweir DBG_UNHANDLED_EXCEPTION();
502cdf0e10cSrcweir }
503cdf0e10cSrcweir m_pWaitObject.reset();
504cdf0e10cSrcweir return 0L;
505cdf0e10cSrcweir }
506cdf0e10cSrcweir // -----------------------------------------------------------------------------
loadData()507cdf0e10cSrcweir void ORelationController::loadData()
508cdf0e10cSrcweir {
509cdf0e10cSrcweir m_pWaitObject.reset( new WaitObject(getView()) );
510cdf0e10cSrcweir try
511cdf0e10cSrcweir {
512cdf0e10cSrcweir if ( !m_xTables.is() )
513cdf0e10cSrcweir return;
514cdf0e10cSrcweir DatabaseMetaData aMeta(getConnection());
515cdf0e10cSrcweir // this may take some time
516cdf0e10cSrcweir const Reference< XDatabaseMetaData> xMetaData = getConnection()->getMetaData();
517cdf0e10cSrcweir const Sequence< ::rtl::OUString> aNames = m_xTables->getElementNames();
518cdf0e10cSrcweir const sal_Int32 nCount = aNames.getLength();
519cdf0e10cSrcweir if ( aMeta.supportsThreads() )
520cdf0e10cSrcweir {
521cdf0e10cSrcweir const sal_Int32 nMaxElements = (nCount / MAX_THREADS) +1;
522cdf0e10cSrcweir sal_Int32 nStart = 0,nEnd = ::std::min(nMaxElements,nCount);
523cdf0e10cSrcweir while(nStart != nEnd)
524cdf0e10cSrcweir {
525cdf0e10cSrcweir ++m_nThreadEvent;
526cdf0e10cSrcweir RelationLoader* pThread = new RelationLoader(this,xMetaData,m_xTables,aNames,nStart,nEnd);
527cdf0e10cSrcweir pThread->createSuspended();
528cdf0e10cSrcweir pThread->setPriority(osl_Thread_PriorityBelowNormal);
529cdf0e10cSrcweir pThread->resume();
530cdf0e10cSrcweir nStart = nEnd;
531cdf0e10cSrcweir nEnd += nMaxElements;
532cdf0e10cSrcweir nEnd = ::std::min(nEnd,nCount);
533cdf0e10cSrcweir } // for(;pIter != pEnd;++pIter)
534cdf0e10cSrcweir } // if ( aMeta.supportsThreads() )
535cdf0e10cSrcweir else
536cdf0e10cSrcweir {
537cdf0e10cSrcweir RelationLoader* pThread = new RelationLoader(this,xMetaData,m_xTables,aNames,0,nCount);
538cdf0e10cSrcweir pThread->run();
539cdf0e10cSrcweir pThread->onTerminated();
540cdf0e10cSrcweir }
541cdf0e10cSrcweir }
542cdf0e10cSrcweir catch(SQLException& e)
543cdf0e10cSrcweir {
544cdf0e10cSrcweir showError(SQLExceptionInfo(e));
545cdf0e10cSrcweir }
546cdf0e10cSrcweir catch(const Exception&)
547cdf0e10cSrcweir {
548cdf0e10cSrcweir DBG_UNHANDLED_EXCEPTION();
549cdf0e10cSrcweir }
550cdf0e10cSrcweir }
551cdf0e10cSrcweir // -----------------------------------------------------------------------------
existsTable(const::rtl::OUString & _rComposedTableName,sal_Bool _bCase) const552cdf0e10cSrcweir TTableWindowData::value_type ORelationController::existsTable(const ::rtl::OUString& _rComposedTableName,sal_Bool _bCase) const
553cdf0e10cSrcweir {
554cdf0e10cSrcweir ::comphelper::UStringMixEqual bCase(_bCase);
555cdf0e10cSrcweir TTableWindowData::const_iterator aIter = m_vTableData.begin();
556cdf0e10cSrcweir TTableWindowData::const_iterator aEnd = m_vTableData.end();
557cdf0e10cSrcweir for(;aIter != aEnd;++aIter)
558cdf0e10cSrcweir {
559cdf0e10cSrcweir if(bCase((*aIter)->GetComposedName(),_rComposedTableName))
560cdf0e10cSrcweir break;
561cdf0e10cSrcweir }
562cdf0e10cSrcweir return ( aIter != aEnd) ? *aIter : TTableWindowData::value_type();
563cdf0e10cSrcweir }
564cdf0e10cSrcweir // -----------------------------------------------------------------------------
loadLayoutInformation()565cdf0e10cSrcweir void ORelationController::loadLayoutInformation()
566cdf0e10cSrcweir {
567cdf0e10cSrcweir try
568cdf0e10cSrcweir {
569cdf0e10cSrcweir OSL_ENSURE(haveDataSource(),"We need a datasource from our connection!");
570cdf0e10cSrcweir if ( haveDataSource() )
571cdf0e10cSrcweir {
572cdf0e10cSrcweir if ( getDataSource()->getPropertySetInfo()->hasPropertyByName(PROPERTY_LAYOUTINFORMATION) )
573cdf0e10cSrcweir {
574cdf0e10cSrcweir Sequence<PropertyValue> aWindows;
575cdf0e10cSrcweir getDataSource()->getPropertyValue(PROPERTY_LAYOUTINFORMATION) >>= aWindows;
576cdf0e10cSrcweir loadTableWindows(aWindows);
577cdf0e10cSrcweir }
578cdf0e10cSrcweir }
579cdf0e10cSrcweir }
580cdf0e10cSrcweir catch(Exception&)
581cdf0e10cSrcweir {
582cdf0e10cSrcweir }
583cdf0e10cSrcweir }
584cdf0e10cSrcweir // -----------------------------------------------------------------------------
reset()585cdf0e10cSrcweir void ORelationController::reset()
586cdf0e10cSrcweir {
587cdf0e10cSrcweir loadLayoutInformation();
588cdf0e10cSrcweir ODataView* pView = getView();
589cdf0e10cSrcweir OSL_ENSURE(pView,"No current view!");
590cdf0e10cSrcweir if(pView)
591cdf0e10cSrcweir {
592cdf0e10cSrcweir pView->initialize();
593cdf0e10cSrcweir pView->Invalidate(INVALIDATE_NOERASE);
594cdf0e10cSrcweir }
595cdf0e10cSrcweir }
596cdf0e10cSrcweir
597cdf0e10cSrcweir // -----------------------------------------------------------------------------
allowViews() const598cdf0e10cSrcweir bool ORelationController::allowViews() const
599cdf0e10cSrcweir {
600cdf0e10cSrcweir return false;
601cdf0e10cSrcweir }
602cdf0e10cSrcweir
603cdf0e10cSrcweir // -----------------------------------------------------------------------------
allowQueries() const604cdf0e10cSrcweir bool ORelationController::allowQueries() const
605cdf0e10cSrcweir {
606cdf0e10cSrcweir return false;
607cdf0e10cSrcweir }
608cdf0e10cSrcweir
609cdf0e10cSrcweir // -----------------------------------------------------------------------------
610cdf0e10cSrcweir
611cdf0e10cSrcweir
612