Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include "dbu_reghelper.hxx"
21 : #include "dbu_resource.hrc"
22 : #include "dbu_uno.hrc"
23 : #include "dbustrings.hrc"
24 : #include "moduledbu.hxx"
25 : #include "sqlmessage.hxx"
26 : #include "WCopyTable.hxx"
27 :
28 : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
29 : #include <com/sun/star/sdb/application/XCopyTableWizard.hpp>
30 : #include <com/sun/star/sdb/application/CopyTableContinuation.hpp>
31 : #include <com/sun/star/sdb/application/CopyTableOperation.hpp>
32 : #include <com/sun/star/ucb/AlreadyInitializedException.hpp>
33 : #include <com/sun/star/lang/NotInitializedException.hpp>
34 : #include <com/sun/star/sdbc/XDataSource.hpp>
35 : #include <com/sun/star/sdbc/DataType.hpp>
36 : #include <com/sun/star/container/XNameAccess.hpp>
37 : #include <com/sun/star/container/XChild.hpp>
38 : #include <com/sun/star/task/InteractionHandler.hpp>
39 : #include <com/sun/star/frame/XModel.hpp>
40 : #include <com/sun/star/sdb/DatabaseContext.hpp>
41 : #include <com/sun/star/sdb/XDocumentDataSource.hpp>
42 : #include <com/sun/star/sdb/XCompletedConnection.hpp>
43 : #include <com/sun/star/sdb/CommandType.hpp>
44 : #include <com/sun/star/sdbcx/XTablesSupplier.hpp>
45 : #include <com/sun/star/sdb/XQueriesSupplier.hpp>
46 : #include <com/sun/star/lang/DisposedException.hpp>
47 : #include <com/sun/star/sdb/XSingleSelectQueryComposer.hpp>
48 : #include <com/sun/star/sdbc/XParameters.hpp>
49 : #include <com/sun/star/sdbc/XRow.hpp>
50 : #include <com/sun/star/sdbc/XBlob.hpp>
51 : #include <com/sun/star/sdbc/XClob.hpp>
52 : #include <com/sun/star/sdbcx/XRowLocate.hpp>
53 : #include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp>
54 : #include <com/sun/star/sdb/SQLContext.hpp>
55 : #include <com/sun/star/sdbc/DriverManager.hpp>
56 : #include <com/sun/star/sdbc/ConnectionPool.hpp>
57 :
58 : #include <comphelper/componentcontext.hxx>
59 : #include <comphelper/interaction.hxx>
60 : #include <comphelper/namedvaluecollection.hxx>
61 : #include <comphelper/proparrhlp.hxx>
62 : #include <connectivity/dbexception.hxx>
63 : #include <connectivity/dbtools.hxx>
64 : #include <cppuhelper/exc_hlp.hxx>
65 : #include <cppuhelper/implbase1.hxx>
66 : #include <rtl/ustrbuf.hxx>
67 : #include <rtl/logfile.hxx>
68 : #include <svtools/genericunodialog.hxx>
69 : #include <tools/diagnose_ex.h>
70 : #include <unotools/sharedunocomponent.hxx>
71 : #include <vcl/msgbox.hxx>
72 : #include <vcl/waitobj.hxx>
73 :
74 : //........................................................................
75 : namespace dbaui
76 : {
77 : //........................................................................
78 :
79 : /** === begin UNO using === **/
80 : using ::com::sun::star::uno::Reference;
81 : using ::com::sun::star::uno::XInterface;
82 : using ::com::sun::star::uno::UNO_QUERY;
83 : using ::com::sun::star::uno::UNO_QUERY_THROW;
84 : using ::com::sun::star::uno::UNO_SET_THROW;
85 : using ::com::sun::star::uno::Exception;
86 : using ::com::sun::star::uno::RuntimeException;
87 : using ::com::sun::star::uno::Any;
88 : using ::com::sun::star::uno::makeAny;
89 : using ::com::sun::star::uno::Sequence;
90 : using ::com::sun::star::beans::XPropertySetInfo;
91 : using ::com::sun::star::lang::XMultiServiceFactory;
92 : using ::com::sun::star::beans::Property;
93 : using ::com::sun::star::sdb::application::XCopyTableWizard;
94 : using ::com::sun::star::sdb::application::XCopyTableListener;
95 : using ::com::sun::star::sdb::application::CopyTableRowEvent;
96 : using ::com::sun::star::beans::Optional;
97 : using ::com::sun::star::lang::IllegalArgumentException;
98 : using ::com::sun::star::ucb::AlreadyInitializedException;
99 : using ::com::sun::star::beans::XPropertySet;
100 : using ::com::sun::star::lang::NotInitializedException;
101 : using ::com::sun::star::lang::XServiceInfo;
102 : using ::com::sun::star::sdbc::XConnection;
103 : using ::com::sun::star::sdbc::XDataSource;
104 : using ::com::sun::star::container::XNameAccess;
105 : using ::com::sun::star::container::XChild;
106 : using ::com::sun::star::task::InteractionHandler;
107 : using ::com::sun::star::task::XInteractionHandler;
108 : using ::com::sun::star::frame::XModel;
109 : using ::com::sun::star::sdb::DatabaseContext;
110 : using ::com::sun::star::sdb::XDatabaseContext;
111 : using ::com::sun::star::sdb::XDocumentDataSource;
112 : using ::com::sun::star::sdb::XCompletedConnection;
113 : using ::com::sun::star::lang::WrappedTargetException;
114 : using ::com::sun::star::sdbcx::XTablesSupplier;
115 : using ::com::sun::star::sdb::XQueriesSupplier;
116 : using ::com::sun::star::lang::DisposedException;
117 : using ::com::sun::star::sdbc::XPreparedStatement;
118 : using ::com::sun::star::sdb::XSingleSelectQueryComposer;
119 : using ::com::sun::star::sdbc::XDatabaseMetaData;
120 : using ::com::sun::star::sdbcx::XColumnsSupplier;
121 : using ::com::sun::star::sdbc::XParameters;
122 : using ::com::sun::star::sdbc::XResultSet;
123 : using ::com::sun::star::sdbc::XRow;
124 : using ::com::sun::star::sdbc::XBlob;
125 : using ::com::sun::star::sdbc::XClob;
126 : using ::com::sun::star::sdbcx::XRowLocate;
127 : using ::com::sun::star::sdbc::XResultSetMetaDataSupplier;
128 : using ::com::sun::star::sdbc::XResultSetMetaData;
129 : using ::com::sun::star::sdbc::SQLException;
130 : using ::com::sun::star::sdb::SQLContext;
131 : using ::com::sun::star::sdbc::ConnectionPool;
132 : using ::com::sun::star::sdbc::XConnectionPool;
133 : using ::com::sun::star::sdbc::XDriverManager;
134 : using ::com::sun::star::sdbc::DriverManager;
135 : using ::com::sun::star::beans::PropertyValue;
136 : /** === end UNO using === **/
137 : namespace CopyTableOperation = ::com::sun::star::sdb::application::CopyTableOperation;
138 : namespace CopyTableContinuation = ::com::sun::star::sdb::application::CopyTableContinuation;
139 : namespace CommandType = ::com::sun::star::sdb::CommandType;
140 : namespace DataType = ::com::sun::star::sdbc::DataType;
141 :
142 : typedef ::utl::SharedUNOComponent< XConnection > SharedConnection;
143 :
144 : //=========================================================================
145 : //= CopyTableWizard
146 : //=========================================================================
147 : typedef ::svt::OGenericUnoDialog CopyTableWizard_DialogBase;
148 : typedef ::cppu::ImplInheritanceHelper1 < CopyTableWizard_DialogBase
149 : , XCopyTableWizard
150 : > CopyTableWizard_Base;
151 : class CopyTableWizard
152 : :public CopyTableWizard_Base
153 : ,public ::comphelper::OPropertyArrayUsageHelper< CopyTableWizard >
154 : {
155 : public:
156 : // XServiceInfo
157 : virtual ::rtl::OUString SAL_CALL getImplementationName() throw(RuntimeException);
158 : virtual ::comphelper::StringSequence SAL_CALL getSupportedServiceNames() throw(RuntimeException);
159 :
160 : // XServiceInfo - static methods
161 : static Sequence< ::rtl::OUString > getSupportedServiceNames_Static(void) throw( RuntimeException );
162 : static ::rtl::OUString getImplementationName_Static(void) throw( RuntimeException );
163 : static Reference< XInterface > Create( const Reference< XMultiServiceFactory >& );
164 :
165 : // XCopyTableWizard
166 : virtual ::sal_Int16 SAL_CALL getOperation() throw (RuntimeException);
167 : virtual void SAL_CALL setOperation( ::sal_Int16 _operation ) throw (IllegalArgumentException, RuntimeException);
168 : virtual ::rtl::OUString SAL_CALL getDestinationTableName() throw (RuntimeException);
169 : virtual void SAL_CALL setDestinationTableName( const ::rtl::OUString& _destinationTableName ) throw (RuntimeException);
170 : virtual Optional< ::rtl::OUString > SAL_CALL getCreatePrimaryKey() throw (RuntimeException);
171 : virtual void SAL_CALL setCreatePrimaryKey( const Optional< ::rtl::OUString >& _newPrimaryKey ) throw (IllegalArgumentException, RuntimeException);
172 : virtual sal_Bool SAL_CALL getUseHeaderLineAsColumnNames() throw (RuntimeException);
173 : virtual void SAL_CALL setUseHeaderLineAsColumnNames( sal_Bool _bUseHeaderLineAsColumnNames ) throw (RuntimeException);
174 : virtual void SAL_CALL addCopyTableListener( const Reference< XCopyTableListener >& Listener ) throw (RuntimeException);
175 : virtual void SAL_CALL removeCopyTableListener( const Reference< XCopyTableListener >& Listener ) throw (RuntimeException);
176 :
177 : // XCopyTableWizard::XExecutableDialog
178 : virtual void SAL_CALL setTitle( const ::rtl::OUString& aTitle ) throw (RuntimeException);
179 : virtual ::sal_Int16 SAL_CALL execute( ) throw (RuntimeException);
180 :
181 : // XInitialization
182 : virtual void SAL_CALL initialize( const Sequence< Any >& aArguments ) throw (Exception, RuntimeException);
183 :
184 : // XPropertySet
185 : virtual Reference< XPropertySetInfo > SAL_CALL getPropertySetInfo() throw(RuntimeException);
186 : virtual ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper();
187 :
188 : // OPropertyArrayUsageHelper
189 : virtual ::cppu::IPropertyArrayHelper* createArrayHelper( ) const;
190 :
191 : public:
192 0 : ::osl::Mutex& getMutex() { return m_aMutex; }
193 0 : bool isInitialized() const { return m_xSourceConnection.is() && m_pSourceObject.get() && m_xDestConnection.is(); }
194 :
195 : protected:
196 : CopyTableWizard( const Reference< XMultiServiceFactory >& _rxORB );
197 : ~CopyTableWizard();
198 :
199 : // OGenericUnoDialog overridables
200 : virtual Dialog* createDialog( Window* _pParent );
201 : virtual void executedDialog( sal_Int16 _nExecutionResult );
202 :
203 : private:
204 : /// ensures our current attribute values are reflected in the dialog
205 : void impl_attributesToDialog_nothrow( OCopyTableWizard& _rDialog ) const;
206 :
207 : /// ensures the current dialog settings are reflected in our attributes
208 : void impl_dialogToAttributes_nothrow( const OCopyTableWizard& _rDialog );
209 :
210 : /** returns our typed dialog
211 :
212 : @throws ::com::sun::star::uno::RuntimeException
213 : if we don't have a dialog at the moment the method is called
214 : */
215 : OCopyTableWizard&
216 : impl_getDialog_throw();
217 :
218 : /** returns our typed dialog
219 :
220 : @throws ::com::sun::star::uno::RuntimeException
221 : if we don't have a dialog at the moment the method is called
222 : */
223 : const OCopyTableWizard&
224 : impl_getDialog_throw() const;
225 :
226 : /** ensures the given argument sequence contains a valid data access descriptor at the given position
227 : @param _rAllArgs
228 : the arguments as passed to ->initialize
229 : @param _nArgPos
230 : the position within ->_rAllArgs which contains the data access descriptor
231 : @param _out_rxConnection
232 : will, upon successful return, contain the connection for the data source
233 : @param _out_rxDocInteractionHandler
234 : will, upon successful return, contain the interaction handler which could
235 : be deduced from database document described by the descriptor, if any.
236 : (It is possible that the descriptor does not allow to deduce a database document,
237 : in which case <code>_out_rxDocInteractionHandler</code> will be <NULL/>.)
238 : @return the data access descriptor
239 : */
240 : Reference< XPropertySet >
241 : impl_ensureDataAccessDescriptor_throw(
242 : const Sequence< Any >& _rAllArgs,
243 : const sal_Int16 _nArgPos,
244 : SharedConnection& _out_rxConnection,
245 : Reference< XInteractionHandler >& _out_rxDocInteractionHandler
246 : ) const;
247 :
248 : /** extracts the source object (table or query) described by the given descriptor,
249 : relative to m_xSourceConnection
250 : */
251 : SAL_WNODEPRECATED_DECLARATIONS_PUSH
252 : ::std::auto_ptr< ICopyTableSourceObject >
253 : impl_extractSourceObject_throw(
254 : const Reference< XPropertySet >& _rxDescriptor,
255 : sal_Int32& _out_rCommandType
256 : ) const;
257 : SAL_WNODEPRECATED_DECLARATIONS_POP
258 :
259 : /** extracts the result set to copy records from, and the selection-related aspects, if any.
260 :
261 : Effectively, this method extracts m_xSourceResultSet, m_aSourceSelection, and m_bSourceSelectionBookmarks.
262 :
263 : If an inconsistent/insufficent sub set of those properties is present in the descriptor, and exception
264 : is thrown.
265 : */
266 : void impl_extractSourceResultSet_throw(
267 : const Reference< XPropertySet >& i_rDescriptor
268 : );
269 :
270 : /** checks whether the given copy source descriptor contains settings which are not
271 : supported (yet)
272 :
273 : Throws an IllegalArgumentException if the descriptor contains a valid setting, which is
274 : not yet supported.
275 : */
276 : void impl_checkForUnsupportedSettings_throw(
277 : const Reference< XPropertySet >& _rxSourceDescriptor ) const;
278 :
279 : /** obtaines the connection described by the given data access descriptor
280 :
281 : If needed and possible, the method will ask the user, using the interaction
282 : handler associated with the database described by the descriptor.
283 :
284 : All errors are handled with the InteractionHandler associated with the data source,
285 : if there is one. Else, they will be silenced (but asserted in non-product builds).
286 :
287 : @param _rxDataSourceDescriptor
288 : the data access descriptor describing the data source whose connection
289 : should be obtained. Must not be <NULL/>.
290 : @param _out_rxDocInteractionHandler
291 : the interaction handler which could be deduced from the descriptor
292 :
293 : @throws RuntimeException
294 : if anything goes seriously wrong.
295 : */
296 : SharedConnection
297 : impl_extractConnection_throw(
298 : const Reference< XPropertySet >& _rxDataSourceDescriptor,
299 : Reference< XInteractionHandler >& _out_rxDocInteractionHandler
300 : ) const;
301 :
302 : /** actually copies the table
303 :
304 : This method is called after the dialog has been successfully executed.
305 : */
306 : void impl_doCopy_nothrow();
307 :
308 : /** creates the INSERT INTO statement
309 : @param _xTable The destination table.
310 : */
311 : ::rtl::OUString impl_getServerSideCopyStatement_throw( const Reference< XPropertySet >& _xTable );
312 :
313 : /** creates the statement which, when executed, will produce the source data to copy
314 :
315 : If the source object refers to a query which contains parameters, those parameters
316 : are filled in, using an interaction handler.
317 : */
318 : ::utl::SharedUNOComponent< XPreparedStatement >
319 : impl_createSourceStatement_throw() const;
320 :
321 : /** copies the data rows from the given source result set to the given destination table
322 : */
323 : void impl_copyRows_throw(
324 : const Reference< XResultSet >& _rxSourceResultSet,
325 : const Reference< XPropertySet >& _rxDestTable
326 : );
327 :
328 : /** processes an error which occurred during copying
329 :
330 : First, all listeners are ask. If a listener tells to cancel or continue copying, this is reported to the
331 : method's caller. If a listener tells to ask the user, this is done, and the user's decision is
332 : reported to the method's caller.
333 :
334 : @return
335 : <TRUE/> if and only if copying should be continued.
336 : */
337 : bool impl_processCopyError_nothrow(
338 : const CopyTableRowEvent& _rEvent );
339 :
340 : private:
341 : ::comphelper::ComponentContext m_aContext;
342 :
343 : // attributes
344 : sal_Int16 m_nOperation;
345 : ::rtl::OUString m_sDestinationTable;
346 : Optional< ::rtl::OUString > m_aPrimaryKeyName;
347 : sal_Bool m_bUseHeaderLineAsColumnNames;
348 :
349 : // source
350 : SharedConnection m_xSourceConnection;
351 : sal_Int32 m_nCommandType;
352 : SAL_WNODEPRECATED_DECLARATIONS_PUSH
353 : ::std::auto_ptr< ICopyTableSourceObject >
354 : m_pSourceObject;
355 : SAL_WNODEPRECATED_DECLARATIONS_POP
356 : Reference< XResultSet > m_xSourceResultSet;
357 : Sequence< Any > m_aSourceSelection;
358 : sal_Bool m_bSourceSelectionBookmarks;
359 :
360 : // destination
361 : SharedConnection m_xDestConnection;
362 :
363 : // other
364 : Reference< XInteractionHandler > m_xInteractionHandler;
365 : ::cppu::OInterfaceContainerHelper
366 : m_aCopyTableListeners;
367 : sal_Int16 m_nOverrideExecutionResult;
368 : };
369 :
370 : //=========================================================================
371 : //= MethodGuard
372 : //=========================================================================
373 : class CopyTableAccessGuard
374 : {
375 : public:
376 0 : CopyTableAccessGuard( CopyTableWizard& _rWizard )
377 0 : :m_rWizard( _rWizard )
378 : {
379 0 : m_rWizard.getMutex().acquire();
380 0 : if ( !m_rWizard.isInitialized() )
381 0 : throw NotInitializedException();
382 0 : }
383 :
384 0 : ~CopyTableAccessGuard()
385 : {
386 0 : m_rWizard.getMutex().release();
387 0 : }
388 :
389 : private:
390 : CopyTableWizard& m_rWizard;
391 : };
392 :
393 : //=========================================================================
394 : //-------------------------------------------------------------------------
395 0 : CopyTableWizard::CopyTableWizard( const Reference< XMultiServiceFactory >& _rxORB )
396 : :CopyTableWizard_Base( _rxORB )
397 : ,m_aContext( _rxORB )
398 : ,m_nOperation( CopyTableOperation::CopyDefinitionAndData )
399 : ,m_sDestinationTable()
400 : ,m_aPrimaryKeyName( sal_False, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ID" ) ))
401 : ,m_bUseHeaderLineAsColumnNames( sal_True )
402 : ,m_xSourceConnection()
403 : ,m_nCommandType( CommandType::COMMAND )
404 : ,m_pSourceObject()
405 : ,m_xSourceResultSet()
406 : ,m_aSourceSelection()
407 : ,m_bSourceSelectionBookmarks( sal_True )
408 : ,m_xDestConnection()
409 : ,m_aCopyTableListeners( m_aMutex )
410 0 : ,m_nOverrideExecutionResult( -1 )
411 : {
412 0 : }
413 :
414 : //-------------------------------------------------------------------------
415 0 : CopyTableWizard::~CopyTableWizard()
416 : {
417 0 : acquire();
418 :
419 : // protect some members whose dtor might potentially throw
420 0 : try { m_xSourceConnection.clear(); }
421 0 : catch( const Exception& ) { DBG_UNHANDLED_EXCEPTION(); }
422 0 : try { m_xDestConnection.clear(); }
423 0 : catch( const Exception& ) { DBG_UNHANDLED_EXCEPTION(); }
424 :
425 : // TODO: shouldn't we have explicit disposal support? If a listener is registered
426 : // at our instance, and perhaps holds this our instance by a hard ref, then we'll never
427 : // be destroyed.
428 : // However, adding XComponent support to the GenericUNODialog probably requires
429 : // some thinking - would it break existing clients which do not call a dispose, then?
430 0 : }
431 :
432 : //-------------------------------------------------------------------------
433 0 : Reference< XInterface > CopyTableWizard::Create( const Reference< XMultiServiceFactory >& _rxFactory )
434 : {
435 0 : return *( new CopyTableWizard( _rxFactory ) );
436 : }
437 :
438 : //-------------------------------------------------------------------------
439 0 : ::rtl::OUString SAL_CALL CopyTableWizard::getImplementationName() throw(RuntimeException)
440 : {
441 0 : return getImplementationName_Static();
442 : }
443 :
444 : //-------------------------------------------------------------------------
445 0 : ::rtl::OUString CopyTableWizard::getImplementationName_Static() throw(RuntimeException)
446 : {
447 0 : return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "org.openoffice.comp.dbu.CopyTableWizard" ) );
448 : }
449 :
450 : //-------------------------------------------------------------------------
451 0 : ::comphelper::StringSequence SAL_CALL CopyTableWizard::getSupportedServiceNames() throw(RuntimeException)
452 : {
453 0 : return getSupportedServiceNames_Static();
454 : }
455 :
456 : //-------------------------------------------------------------------------
457 0 : ::comphelper::StringSequence CopyTableWizard::getSupportedServiceNames_Static() throw(RuntimeException)
458 : {
459 0 : ::comphelper::StringSequence aSupported(1);
460 0 : aSupported.getArray()[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sdb.application.CopyTableWizard" ) );
461 0 : return aSupported;
462 : }
463 :
464 : //-------------------------------------------------------------------------
465 0 : Reference< XPropertySetInfo > SAL_CALL CopyTableWizard::getPropertySetInfo() throw(RuntimeException)
466 : {
467 0 : Reference< XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) );
468 0 : return xInfo;
469 : }
470 :
471 : //--------------------------------------------------------------------
472 0 : ::sal_Int16 SAL_CALL CopyTableWizard::getOperation() throw (RuntimeException)
473 : {
474 0 : CopyTableAccessGuard aGuard( *this );
475 0 : return m_nOperation;
476 : }
477 :
478 : //--------------------------------------------------------------------
479 0 : void SAL_CALL CopyTableWizard::setOperation( ::sal_Int16 _operation ) throw (IllegalArgumentException, RuntimeException)
480 : {
481 0 : CopyTableAccessGuard aGuard( *this );
482 :
483 0 : if ( ( _operation != CopyTableOperation::CopyDefinitionAndData )
484 : && ( _operation != CopyTableOperation::CopyDefinitionOnly )
485 : && ( _operation != CopyTableOperation::CreateAsView )
486 : && ( _operation != CopyTableOperation::AppendData )
487 : )
488 0 : throw IllegalArgumentException( ::rtl::OUString(), *this, 1 );
489 :
490 0 : if ( ( _operation == CopyTableOperation::CreateAsView )
491 0 : && !OCopyTableWizard::supportsViews( m_xDestConnection )
492 : )
493 : throw IllegalArgumentException(
494 : String( ModuleRes( STR_CTW_NO_VIEWS_SUPPORT ) ),
495 : *this,
496 : 1
497 0 : );
498 :
499 0 : m_nOperation = _operation;
500 0 : }
501 :
502 : //--------------------------------------------------------------------
503 0 : ::rtl::OUString SAL_CALL CopyTableWizard::getDestinationTableName() throw (RuntimeException)
504 : {
505 0 : CopyTableAccessGuard aGuard( *this );
506 0 : return m_sDestinationTable;
507 : }
508 :
509 : //--------------------------------------------------------------------
510 0 : void SAL_CALL CopyTableWizard::setDestinationTableName( const ::rtl::OUString& _destinationTableName ) throw (RuntimeException)
511 : {
512 0 : CopyTableAccessGuard aGuard( *this );
513 0 : m_sDestinationTable = _destinationTableName;
514 0 : }
515 :
516 : //--------------------------------------------------------------------
517 0 : Optional< ::rtl::OUString > SAL_CALL CopyTableWizard::getCreatePrimaryKey() throw (RuntimeException)
518 : {
519 0 : CopyTableAccessGuard aGuard( *this );
520 0 : return m_aPrimaryKeyName;
521 : }
522 :
523 : //--------------------------------------------------------------------
524 0 : void SAL_CALL CopyTableWizard::setCreatePrimaryKey( const Optional< ::rtl::OUString >& _newPrimaryKey ) throw (IllegalArgumentException, RuntimeException)
525 : {
526 0 : CopyTableAccessGuard aGuard( *this );
527 :
528 0 : if ( _newPrimaryKey.IsPresent && !OCopyTableWizard::supportsPrimaryKey( m_xDestConnection ) )
529 : throw IllegalArgumentException(
530 : String( ModuleRes( STR_CTW_NO_PRIMARY_KEY_SUPPORT ) ),
531 : *this,
532 : 1
533 0 : );
534 :
535 0 : m_aPrimaryKeyName = _newPrimaryKey;
536 0 : }
537 : // -----------------------------------------------------------------------------
538 0 : sal_Bool SAL_CALL CopyTableWizard::getUseHeaderLineAsColumnNames() throw (RuntimeException)
539 : {
540 0 : CopyTableAccessGuard aGuard( *this );
541 0 : return m_bUseHeaderLineAsColumnNames;
542 : }
543 : // -----------------------------------------------------------------------------
544 0 : void SAL_CALL CopyTableWizard::setUseHeaderLineAsColumnNames( sal_Bool _bUseHeaderLineAsColumnNames ) throw (RuntimeException)
545 : {
546 0 : CopyTableAccessGuard aGuard( *this );
547 0 : m_bUseHeaderLineAsColumnNames = _bUseHeaderLineAsColumnNames;
548 0 : }
549 : //--------------------------------------------------------------------
550 0 : void SAL_CALL CopyTableWizard::addCopyTableListener( const Reference< XCopyTableListener >& _rxListener ) throw (RuntimeException)
551 : {
552 0 : CopyTableAccessGuard aGuard( *this );
553 0 : if ( _rxListener.is() )
554 0 : m_aCopyTableListeners.addInterface( _rxListener );
555 0 : }
556 :
557 : //--------------------------------------------------------------------
558 0 : void SAL_CALL CopyTableWizard::removeCopyTableListener( const Reference< XCopyTableListener >& _rxListener ) throw (RuntimeException)
559 : {
560 0 : CopyTableAccessGuard aGuard( *this );
561 0 : if ( _rxListener.is() )
562 0 : m_aCopyTableListeners.removeInterface( _rxListener );
563 0 : }
564 :
565 : //--------------------------------------------------------------------
566 0 : void SAL_CALL CopyTableWizard::setTitle( const ::rtl::OUString& _rTitle ) throw (RuntimeException)
567 : {
568 0 : CopyTableAccessGuard aGuard( *this );
569 0 : CopyTableWizard_DialogBase::setTitle( _rTitle );
570 0 : }
571 :
572 : //--------------------------------------------------------------------
573 0 : ::sal_Int16 SAL_CALL CopyTableWizard::execute( ) throw (RuntimeException)
574 : {
575 0 : CopyTableAccessGuard aGuard( *this );
576 :
577 0 : m_nOverrideExecutionResult = -1;
578 0 : sal_Int16 nExecutionResult = CopyTableWizard_DialogBase::execute();
579 0 : if ( m_nOverrideExecutionResult )
580 0 : nExecutionResult = m_nOverrideExecutionResult;
581 :
582 0 : return nExecutionResult;
583 : }
584 :
585 : //-------------------------------------------------------------------------
586 0 : OCopyTableWizard& CopyTableWizard::impl_getDialog_throw()
587 : {
588 0 : OCopyTableWizard* pWizard = dynamic_cast< OCopyTableWizard* >( m_pDialog );
589 0 : if ( !pWizard )
590 0 : throw DisposedException( ::rtl::OUString(), *this );
591 0 : return *pWizard;
592 : }
593 :
594 : //-------------------------------------------------------------------------
595 0 : const OCopyTableWizard& CopyTableWizard::impl_getDialog_throw() const
596 : {
597 0 : const OCopyTableWizard* pWizard = dynamic_cast< const OCopyTableWizard* >( m_pDialog );
598 0 : if ( !pWizard )
599 0 : throw DisposedException( ::rtl::OUString(), *const_cast< CopyTableWizard* >( this ) );
600 0 : return *pWizard;
601 : }
602 :
603 : //-------------------------------------------------------------------------
604 0 : void CopyTableWizard::impl_attributesToDialog_nothrow( OCopyTableWizard& _rDialog ) const
605 : {
606 : // primary key column
607 0 : _rDialog.setCreatePrimaryKey( m_aPrimaryKeyName.IsPresent, m_aPrimaryKeyName.Value );
608 0 : _rDialog.setUseHeaderLine(m_bUseHeaderLineAsColumnNames);
609 :
610 : // everything else was passed at construction time already
611 0 : }
612 :
613 : //-------------------------------------------------------------------------
614 0 : void CopyTableWizard::impl_dialogToAttributes_nothrow( const OCopyTableWizard& _rDialog )
615 : {
616 0 : m_aPrimaryKeyName.IsPresent = _rDialog.shouldCreatePrimaryKey();
617 0 : if ( m_aPrimaryKeyName.IsPresent )
618 0 : m_aPrimaryKeyName.Value = _rDialog.getPrimaryKeyName();
619 : else
620 0 : m_aPrimaryKeyName.Value = ::rtl::OUString();
621 :
622 0 : m_sDestinationTable = _rDialog.getName();
623 :
624 0 : m_nOperation = _rDialog.getOperation();
625 0 : m_bUseHeaderLineAsColumnNames = _rDialog.UseHeaderLine();
626 0 : }
627 :
628 : //-------------------------------------------------------------------------
629 : namespace
630 : {
631 : //.....................................................................
632 : /** tries to obtain the InteractionHandler associated with a given data source
633 :
634 : If the data source is a sdb-level data source, it will have a DatabaseDocument associated
635 : with it. This doocument may have an InteractionHandler used while loading it.
636 :
637 : @throws RuntimeException
638 : if it occures during invoking any of the data source's methods, or if any of the involved
639 : components violates its contract by not providing the required interfaces
640 : */
641 0 : Reference< XInteractionHandler > lcl_getInteractionHandler_throw( const Reference< XDataSource >& _rxDataSource, const Reference< XInteractionHandler >& _rFallback )
642 : {
643 0 : Reference< XInteractionHandler > xHandler( _rFallback );
644 :
645 : // try to obtain the document model
646 0 : Reference< XModel > xDocumentModel;
647 0 : Reference< XDocumentDataSource > xDocDataSource( _rxDataSource, UNO_QUERY );
648 0 : if ( xDocDataSource.is() )
649 0 : xDocumentModel.set( xDocDataSource->getDatabaseDocument(), UNO_QUERY_THROW );
650 :
651 : // see whether the document model can provide a handler
652 0 : if ( xDocumentModel.is() )
653 : {
654 0 : ::comphelper::NamedValueCollection aModelArgs( xDocumentModel->getArgs() );
655 0 : xHandler = aModelArgs.getOrDefault( "InteractionHandler", xHandler );
656 : }
657 :
658 0 : return xHandler;
659 : }
660 : //.....................................................................
661 : /** tries to obtain the InteractionHandler associated with a given connection
662 :
663 : If the connection belongs to a sdb-level data source, then this data source
664 : is examined for an interaction handler. Else, <NULL/> is returned.
665 :
666 : @throws RuntimeException
667 : if it occures during invoking any of the data source's methods, or if any of the involved
668 : components violates its contract by not providing the required interfaces
669 : */
670 0 : Reference< XInteractionHandler > lcl_getInteractionHandler_throw( const Reference< XConnection >& _rxConnection, const Reference< XInteractionHandler >& _rFallback )
671 : {
672 : // try whether there is a data source which the connection belongs to
673 0 : Reference< XDataSource > xDataSource;
674 0 : Reference< XChild > xAsChild( _rxConnection, UNO_QUERY );
675 0 : if ( xAsChild.is() )
676 0 : xDataSource = xDataSource.query( xAsChild->getParent() );
677 :
678 0 : if ( xDataSource.is() )
679 0 : return lcl_getInteractionHandler_throw( xDataSource, _rFallback );
680 :
681 0 : return _rFallback;
682 : }
683 : }
684 :
685 : //-------------------------------------------------------------------------
686 0 : Reference< XPropertySet > CopyTableWizard::impl_ensureDataAccessDescriptor_throw(
687 : const Sequence< Any >& _rAllArgs, const sal_Int16 _nArgPos, SharedConnection& _out_rxConnection,
688 : Reference< XInteractionHandler >& _out_rxDocInteractionHandler ) const
689 : {
690 0 : Reference< XPropertySet > xDescriptor;
691 0 : _rAllArgs[ _nArgPos ] >>= xDescriptor;
692 :
693 : // the descriptor must be non-NULL, of course
694 0 : bool bIsValid = xDescriptor.is();
695 :
696 : // it must support the proper service
697 0 : if ( bIsValid )
698 : {
699 0 : Reference< XServiceInfo > xSI( xDescriptor, UNO_QUERY );
700 0 : bIsValid = ( xSI.is()
701 0 : && xSI->supportsService( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sdb.DataAccessDescriptor" ) ) )
702 0 : );
703 : }
704 :
705 : // it must be able to provide a connection
706 0 : if ( bIsValid )
707 : {
708 0 : _out_rxConnection = impl_extractConnection_throw( xDescriptor, _out_rxDocInteractionHandler );
709 0 : bIsValid = _out_rxConnection.is();
710 : }
711 :
712 0 : if ( !bIsValid )
713 : {
714 : throw IllegalArgumentException(
715 : String( ModuleRes( STR_CTW_INVALID_DATA_ACCESS_DESCRIPTOR ) ),
716 : *const_cast< CopyTableWizard* >( this ),
717 : _nArgPos + 1
718 0 : );
719 : }
720 :
721 0 : return xDescriptor;
722 : }
723 :
724 : //-------------------------------------------------------------------------
725 : namespace
726 : {
727 0 : bool lcl_hasNonEmptyStringValue_throw( const Reference< XPropertySet >& _rxDescriptor,
728 : const Reference< XPropertySetInfo > _rxPSI, const ::rtl::OUString& _rPropertyName )
729 : {
730 0 : ::rtl::OUString sValue;
731 0 : if ( _rxPSI->hasPropertyByName( _rPropertyName ) )
732 : {
733 0 : OSL_VERIFY( _rxDescriptor->getPropertyValue( _rPropertyName ) >>= sValue );
734 : }
735 0 : return !sValue.isEmpty();
736 : }
737 : }
738 :
739 : //-------------------------------------------------------------------------
740 0 : void CopyTableWizard::impl_checkForUnsupportedSettings_throw( const Reference< XPropertySet >& _rxSourceDescriptor ) const
741 : {
742 : OSL_PRECOND( _rxSourceDescriptor.is(), "CopyTableWizard::impl_checkForUnsupportedSettings_throw: illegal argument!" );
743 0 : Reference< XPropertySetInfo > xPSI( _rxSourceDescriptor->getPropertySetInfo(), UNO_SET_THROW );
744 0 : ::rtl::OUString sUnsupportedSetting;
745 :
746 : const ::rtl::OUString aSettings[] = {
747 : PROPERTY_FILTER, PROPERTY_ORDER, PROPERTY_HAVING_CLAUSE, PROPERTY_GROUP_BY
748 0 : };
749 0 : for ( size_t i=0; i < sizeof( aSettings ) / sizeof( aSettings[0] ); ++i )
750 : {
751 0 : if ( lcl_hasNonEmptyStringValue_throw( _rxSourceDescriptor, xPSI, aSettings[i] ) )
752 : {
753 0 : sUnsupportedSetting = aSettings[i];
754 0 : break;
755 : }
756 : }
757 :
758 0 : if ( !sUnsupportedSetting.isEmpty() )
759 : {
760 : ::rtl::OUString sMessage(
761 : rtl::OUString(String(ModuleRes(STR_CTW_ERROR_UNSUPPORTED_SETTING))).
762 0 : replaceFirst("$name$", sUnsupportedSetting));
763 : throw IllegalArgumentException(
764 : sMessage,
765 : *const_cast< CopyTableWizard* >( this ),
766 : 1
767 0 : );
768 0 : }
769 :
770 0 : }
771 :
772 : //-------------------------------------------------------------------------
773 : SAL_WNODEPRECATED_DECLARATIONS_PUSH
774 0 : ::std::auto_ptr< ICopyTableSourceObject > CopyTableWizard::impl_extractSourceObject_throw( const Reference< XPropertySet >& _rxDescriptor, sal_Int32& _out_rCommandType ) const
775 : {
776 : OSL_PRECOND( _rxDescriptor.is() && m_xSourceConnection.is(), "CopyTableWizard::impl_extractSourceObject_throw: illegal arguments!" );
777 :
778 0 : Reference< XPropertySetInfo > xPSI( _rxDescriptor->getPropertySetInfo(), UNO_SET_THROW );
779 0 : if ( !xPSI->hasPropertyByName( PROPERTY_COMMAND )
780 0 : || !xPSI->hasPropertyByName( PROPERTY_COMMAND_TYPE )
781 : )
782 : throw IllegalArgumentException(
783 : ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Expecting a table or query specification." ) ),
784 : // TODO: resource
785 : *const_cast< CopyTableWizard* >( this ),
786 : 1
787 0 : );
788 :
789 0 : ::rtl::OUString sCommand;
790 0 : _out_rCommandType = CommandType::COMMAND;
791 0 : OSL_VERIFY( _rxDescriptor->getPropertyValue( PROPERTY_COMMAND ) >>= sCommand );
792 0 : OSL_VERIFY( _rxDescriptor->getPropertyValue( PROPERTY_COMMAND_TYPE ) >>= _out_rCommandType );
793 :
794 0 : ::std::auto_ptr< ICopyTableSourceObject > pSourceObject;
795 0 : Reference< XNameAccess > xContainer;
796 0 : switch ( _out_rCommandType )
797 : {
798 : case CommandType::TABLE:
799 : {
800 0 : Reference< XTablesSupplier > xSuppTables( m_xSourceConnection.getTyped(), UNO_QUERY );
801 0 : if ( xSuppTables.is() )
802 0 : xContainer.set( xSuppTables->getTables(), UNO_SET_THROW );
803 : }
804 0 : break;
805 : case CommandType::QUERY:
806 : {
807 0 : Reference< XQueriesSupplier > xSuppQueries( m_xSourceConnection.getTyped(), UNO_QUERY );
808 0 : if ( xSuppQueries.is() )
809 0 : xContainer.set( xSuppQueries->getQueries(), UNO_SET_THROW );
810 : }
811 0 : break;
812 : default:
813 : throw IllegalArgumentException(
814 : String( ModuleRes( STR_CTW_ONLY_TABLES_AND_QUERIES_SUPPORT ) ),
815 : *const_cast< CopyTableWizard* >( this ),
816 : 1
817 0 : );
818 : }
819 :
820 0 : if ( xContainer.is() )
821 : {
822 : pSourceObject.reset( new ObjectCopySource( m_xSourceConnection,
823 0 : Reference< XPropertySet >( xContainer->getByName( sCommand ), UNO_QUERY_THROW ) ) );
824 : }
825 : else
826 : {
827 : // our source connection is an SDBC level connection only, not a SDBCX level one
828 : // Which means it cannot provide the to-be-copied object as component.
829 :
830 0 : if ( _out_rCommandType == CommandType::QUERY )
831 : // we cannot copy a query if the connection cannot provide it ...
832 : throw IllegalArgumentException(
833 : String(ModuleRes( STR_CTW_ERROR_NO_QUERY )),
834 : *const_cast< CopyTableWizard* >( this ),
835 : 1
836 0 : );
837 0 : pSourceObject.reset( new NamedTableCopySource( m_xSourceConnection, sCommand ) );
838 : }
839 :
840 0 : return pSourceObject;
841 : }
842 : SAL_WNODEPRECATED_DECLARATIONS_POP
843 :
844 : //-------------------------------------------------------------------------
845 0 : void CopyTableWizard::impl_extractSourceResultSet_throw( const Reference< XPropertySet >& i_rDescriptor )
846 : {
847 0 : Reference< XPropertySetInfo > xPSI( i_rDescriptor->getPropertySetInfo(), UNO_SET_THROW );
848 :
849 : // extract relevant settings
850 0 : if ( xPSI->hasPropertyByName( PROPERTY_RESULT_SET ) )
851 0 : m_xSourceResultSet.set( i_rDescriptor->getPropertyValue( PROPERTY_RESULT_SET ), UNO_QUERY );
852 :
853 0 : if ( xPSI->hasPropertyByName( PROPERTY_SELECTION ) )
854 0 : OSL_VERIFY( i_rDescriptor->getPropertyValue( PROPERTY_SELECTION ) >>= m_aSourceSelection );
855 :
856 0 : if ( xPSI->hasPropertyByName( PROPERTY_BOOKMARK_SELECTION ) )
857 0 : OSL_VERIFY( i_rDescriptor->getPropertyValue( PROPERTY_BOOKMARK_SELECTION ) >>= m_bSourceSelectionBookmarks );
858 :
859 : // sanity checks
860 0 : const bool bHasResultSet = m_xSourceResultSet.is();
861 0 : const bool bHasSelection = ( m_aSourceSelection.getLength() != 0 );
862 0 : if ( bHasSelection && !bHasResultSet )
863 : throw IllegalArgumentException(
864 : ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "A result set is needed when specifying a selection to copy." ) ),
865 : // TODO: resource
866 : *this,
867 : 1
868 0 : );
869 :
870 0 : if ( bHasSelection && m_bSourceSelectionBookmarks )
871 : {
872 0 : Reference< XRowLocate > xRowLocate( m_xSourceResultSet, UNO_QUERY );
873 0 : if ( !xRowLocate.is() )
874 : {
875 : ::dbtools::throwGenericSQLException(
876 : String( ModuleRes( STR_CTW_COPY_SOURCE_NEEDS_BOOKMARKS ) ),
877 : *this
878 0 : );
879 0 : }
880 0 : }
881 0 : }
882 :
883 : //-------------------------------------------------------------------------
884 0 : SharedConnection CopyTableWizard::impl_extractConnection_throw( const Reference< XPropertySet >& _rxDataSourceDescriptor,
885 : Reference< XInteractionHandler >& _out_rxDocInteractionHandler ) const
886 : {
887 0 : SharedConnection xConnection;
888 :
889 : OSL_PRECOND( _rxDataSourceDescriptor.is(), "CopyTableWizard::impl_extractConnection_throw: no descriptor!" );
890 0 : if ( !_rxDataSourceDescriptor.is() )
891 : return xConnection;
892 :
893 0 : Reference< XInteractionHandler > xInteractionHandler;
894 :
895 : do
896 : {
897 0 : Reference< XPropertySetInfo > xPSI( _rxDataSourceDescriptor->getPropertySetInfo(), UNO_SET_THROW );
898 :
899 : // if there's an ActiveConnection, use it
900 0 : if ( xPSI->hasPropertyByName( PROPERTY_ACTIVE_CONNECTION ) )
901 : {
902 0 : Reference< XConnection > xPure;
903 0 : OSL_VERIFY( _rxDataSourceDescriptor->getPropertyValue( PROPERTY_ACTIVE_CONNECTION ) >>= xPure );
904 0 : xConnection.reset( xPure, SharedConnection::NoTakeOwnership );
905 : }
906 0 : if ( xConnection.is() )
907 : {
908 0 : xInteractionHandler = lcl_getInteractionHandler_throw( xConnection.getTyped(), m_xInteractionHandler );
909 : OSL_POSTCOND( xInteractionHandler.is(), "CopyTableWizard::impl_extractConnection_throw: lcl_getInteractionHandler_throw returned nonsense!" );
910 : break;
911 : }
912 :
913 : // there could be a DataSourceName or a DatabaseLocation, describing the css.sdb.DataSource
914 0 : ::rtl::OUString sDataSource, sDatabaseLocation;
915 0 : if ( xPSI->hasPropertyByName( PROPERTY_DATASOURCENAME ) )
916 0 : OSL_VERIFY( _rxDataSourceDescriptor->getPropertyValue( PROPERTY_DATASOURCENAME ) >>= sDataSource );
917 0 : if ( xPSI->hasPropertyByName( PROPERTY_DATABASE_LOCATION ) )
918 0 : OSL_VERIFY( _rxDataSourceDescriptor->getPropertyValue( PROPERTY_DATABASE_LOCATION ) >>= sDatabaseLocation );
919 :
920 : // need a DatabaseContext for loading the data source
921 0 : Reference< XDatabaseContext > xDatabaseContext = DatabaseContext::create( m_aContext.getUNOContext() );
922 0 : Reference< XDataSource > xDataSource;
923 0 : if ( !sDataSource.isEmpty() )
924 0 : xDataSource.set( xDatabaseContext->getByName( sDataSource ), UNO_QUERY_THROW );
925 0 : if ( !xDataSource.is() && !sDatabaseLocation.isEmpty() )
926 0 : xDataSource.set( xDatabaseContext->getByName( sDatabaseLocation ), UNO_QUERY_THROW );
927 :
928 0 : if ( xDataSource.is() )
929 : {
930 : // first, try connecting with completion
931 0 : xInteractionHandler = lcl_getInteractionHandler_throw( xDataSource, m_xInteractionHandler );
932 : OSL_POSTCOND( xInteractionHandler.is(), "CopyTableWizard::impl_extractConnection_throw: lcl_getInteractionHandler_throw returned nonsense!" );
933 0 : if ( xInteractionHandler.is() )
934 : {
935 0 : Reference< XCompletedConnection > xInteractiveConnection( xDataSource, UNO_QUERY );
936 0 : if ( xInteractiveConnection.is() )
937 0 : xConnection.reset( xInteractiveConnection->connectWithCompletion( xInteractionHandler ), SharedConnection::TakeOwnership );
938 : }
939 :
940 : // interactively connecting was not successful or possible -> connect without interaction
941 0 : if ( !xConnection.is() )
942 : {
943 0 : xConnection.reset( xDataSource->getConnection( ::rtl::OUString(), ::rtl::OUString() ), SharedConnection::TakeOwnership );
944 : }
945 : }
946 :
947 0 : if ( xConnection.is() )
948 : break;
949 :
950 : // finally, there could be a ConnectionResource/ConnectionInfo
951 0 : ::rtl::OUString sConnectionResource;
952 0 : Sequence< PropertyValue > aConnectionInfo;
953 0 : if ( xPSI->hasPropertyByName( PROPERTY_CONNECTION_RESOURCE ) )
954 0 : OSL_VERIFY( _rxDataSourceDescriptor->getPropertyValue( PROPERTY_CONNECTION_RESOURCE ) >>= sConnectionResource );
955 0 : if ( xPSI->hasPropertyByName( PROPERTY_CONNECTION_INFO ) )
956 0 : OSL_VERIFY( _rxDataSourceDescriptor->getPropertyValue( PROPERTY_CONNECTION_INFO ) >>= aConnectionInfo );
957 :
958 0 : Reference< XDriverManager > xDriverManager;
959 : try {
960 0 : xDriverManager.set( ConnectionPool::create( m_aContext.getUNOContext() ), UNO_QUERY_THROW );
961 0 : } catch( const Exception& ) { }
962 0 : if ( !xDriverManager.is() )
963 : // no connection pool installed
964 0 : xDriverManager.set( DriverManager::create(m_aContext.getUNOContext() ), UNO_QUERY_THROW );
965 :
966 0 : if ( aConnectionInfo.getLength() )
967 0 : xConnection.set( xDriverManager->getConnectionWithInfo( sConnectionResource, aConnectionInfo ), UNO_SET_THROW );
968 : else
969 0 : xConnection.set( xDriverManager->getConnection( sConnectionResource ), UNO_SET_THROW );
970 : }
971 : while ( false );
972 :
973 0 : if ( xInteractionHandler != m_xInteractionHandler )
974 0 : _out_rxDocInteractionHandler = xInteractionHandler;
975 :
976 0 : return xConnection;
977 : }
978 :
979 : //-------------------------------------------------------------------------
980 0 : ::utl::SharedUNOComponent< XPreparedStatement > CopyTableWizard::impl_createSourceStatement_throw() const
981 : {
982 : OSL_PRECOND( m_xSourceConnection.is(), "CopyTableWizard::impl_createSourceStatement_throw: illegal call!" );
983 0 : if ( !m_xSourceConnection.is() )
984 0 : throw RuntimeException( "CopyTableWizard::impl_createSourceStatement_throw: illegal call!", *const_cast< CopyTableWizard* >( this ));
985 :
986 0 : ::utl::SharedUNOComponent< XPreparedStatement > xStatement;
987 0 : switch ( m_nCommandType )
988 : {
989 : case CommandType::TABLE:
990 0 : xStatement.set( m_pSourceObject->getPreparedSelectStatement(), UNO_SET_THROW );
991 0 : break;
992 :
993 : case CommandType::QUERY:
994 : {
995 0 : ::rtl::OUString sQueryCommand( m_pSourceObject->getSelectStatement() );
996 0 : xStatement.set( m_pSourceObject->getPreparedSelectStatement(), UNO_SET_THROW );
997 :
998 : // check whether we have to fill in parameter values
999 : // create and fill a composer
1000 :
1001 0 : Reference< XMultiServiceFactory > xFactory( m_xSourceConnection, UNO_QUERY );
1002 0 : ::utl::SharedUNOComponent< XSingleSelectQueryComposer > xComposer;
1003 0 : if ( xFactory.is() )
1004 : // note: connections below the sdb-level are allowed to not support the XMultiServiceFactory interface
1005 0 : xComposer.set( xFactory->createInstance( SERVICE_NAME_SINGLESELECTQUERYCOMPOSER ), UNO_QUERY );
1006 :
1007 0 : if ( xComposer.is() )
1008 : {
1009 0 : xComposer->setQuery( sQueryCommand );
1010 :
1011 0 : Reference< XParameters > xStatementParams( xStatement, UNO_QUERY );
1012 : OSL_ENSURE( xStatementParams.is(), "CopyTableWizard::impl_createSourceStatement_throw: no access to the statement's parameters!" );
1013 : // the statement should be a css.sdbc.PreparedStatement (this is what
1014 : // we created), and a prepared statement is required to support XParameters
1015 0 : if ( xStatementParams.is() )
1016 : {
1017 : OSL_ENSURE( m_xInteractionHandler.is(),
1018 : "CopyTableWizard::impl_createSourceStatement_throw: no interaction handler for the parameters request!" );
1019 : // we should always have an interaction handler - as last fallback, we create an own one in ::initialize
1020 :
1021 0 : if ( m_xInteractionHandler.is() )
1022 0 : ::dbtools::askForParameters( xComposer, xStatementParams, m_xSourceConnection, m_xInteractionHandler );
1023 0 : }
1024 0 : }
1025 : }
1026 0 : break;
1027 :
1028 : default:
1029 : // this should not have survived initialization phase
1030 0 : throw RuntimeException("No case matched, this should not have survived the initialization phase", *const_cast< CopyTableWizard* >( this ));
1031 : }
1032 :
1033 0 : return xStatement;
1034 : }
1035 :
1036 : //-------------------------------------------------------------------------
1037 : namespace
1038 : {
1039 0 : class ValueTransfer
1040 : {
1041 : public:
1042 0 : ValueTransfer( const sal_Int32& _rSourcePos, const sal_Int32& _rDestPos, const ::std::vector< sal_Int32 >& _rColTypes,
1043 : const Reference< XRow >& _rxSource, const Reference< XParameters >& _rxDest )
1044 : :m_rSourcePos( _rSourcePos )
1045 : ,m_rDestPos( _rDestPos )
1046 : ,m_rColTypes( _rColTypes )
1047 : ,m_xSource( _rxSource )
1048 0 : ,m_xDest( _rxDest )
1049 : {
1050 0 : }
1051 :
1052 : template< typename VALUE_TYPE >
1053 0 : void transferValue( VALUE_TYPE ( SAL_CALL XRow::*_pGetter )( sal_Int32 ),
1054 : void (SAL_CALL XParameters::*_pSetter)( sal_Int32, VALUE_TYPE ) )
1055 : {
1056 0 : VALUE_TYPE value( (m_xSource.get()->*_pGetter)( m_rSourcePos ) );
1057 0 : if ( m_xSource->wasNull() )
1058 0 : m_xDest->setNull( m_rDestPos, m_rColTypes[ m_rSourcePos ] );
1059 : else
1060 0 : (m_xDest.get()->*_pSetter)( m_rDestPos, value );
1061 0 : }
1062 : template< typename VALUE_TYPE >
1063 0 : void transferComplexValue( VALUE_TYPE ( SAL_CALL XRow::*_pGetter )( sal_Int32 ),
1064 : void (SAL_CALL XParameters::*_pSetter)( sal_Int32, const VALUE_TYPE& ) )
1065 : {
1066 0 : const VALUE_TYPE value( (m_xSource.get()->*_pGetter)( m_rSourcePos ) );
1067 : {
1068 0 : if ( m_xSource->wasNull() )
1069 0 : m_xDest->setNull( m_rDestPos, m_rColTypes[ m_rSourcePos ] );
1070 : else
1071 0 : (m_xDest.get()->*_pSetter)( m_rDestPos, value );
1072 : }
1073 0 : }
1074 : private:
1075 : const sal_Int32& m_rSourcePos;
1076 : const sal_Int32& m_rDestPos;
1077 : const ::std::vector< sal_Int32 > m_rColTypes;
1078 : const Reference< XRow > m_xSource;
1079 : const Reference< XParameters > m_xDest;
1080 : };
1081 : }
1082 :
1083 : //-------------------------------------------------------------------------
1084 0 : bool CopyTableWizard::impl_processCopyError_nothrow( const CopyTableRowEvent& _rEvent )
1085 : {
1086 0 : Reference< XCopyTableListener > xListener;
1087 : try
1088 : {
1089 0 : ::cppu::OInterfaceIteratorHelper aIter( m_aCopyTableListeners );
1090 0 : while ( aIter.hasMoreElements() )
1091 : {
1092 0 : xListener.set( aIter.next(), UNO_QUERY_THROW );
1093 0 : sal_Int16 nListenerChoice = xListener->copyRowError( _rEvent );
1094 0 : switch ( nListenerChoice )
1095 : {
1096 0 : case CopyTableContinuation::Proceed: return true; // continue copying
1097 0 : case CopyTableContinuation::CallNextHandler: continue; // continue the loop, ask next listener
1098 0 : case CopyTableContinuation::Cancel: return false; // cancel copying
1099 0 : case CopyTableContinuation::AskUser: break; // stop asking the listeners, ask the user
1100 :
1101 : default:
1102 : OSL_FAIL( "CopyTableWizard::impl_processCopyError_nothrow: invalid listener response!" );
1103 : // ask next listener
1104 0 : continue;
1105 : }
1106 0 : }
1107 : }
1108 0 : catch( const Exception& )
1109 : {
1110 : DBG_UNHANDLED_EXCEPTION();
1111 : }
1112 :
1113 : // no listener felt responsible for the error, or a listener told to ask the user
1114 :
1115 : try
1116 : {
1117 0 : SQLContext aError;
1118 0 : aError.Context = *this;
1119 0 : aError.Message = String( ModuleRes( STR_ERROR_OCCURRED_WHILE_COPYING ) );
1120 :
1121 0 : ::dbtools::SQLExceptionInfo aInfo( _rEvent.Error );
1122 0 : if ( aInfo.isValid() )
1123 0 : aError.NextException = _rEvent.Error;
1124 : else
1125 : {
1126 : // a non-SQL exception happend
1127 0 : Exception aException;
1128 0 : OSL_VERIFY( _rEvent.Error >>= aException );
1129 0 : SQLContext aContext;
1130 0 : aContext.Context = aException.Context;
1131 0 : aContext.Message = aException.Message;
1132 0 : aContext.Details = _rEvent.Error.getValueTypeName();
1133 0 : aError.NextException <<= aContext;
1134 : }
1135 :
1136 0 : ::rtl::Reference< ::comphelper::OInteractionRequest > xRequest( new ::comphelper::OInteractionRequest( makeAny( aError ) ) );
1137 :
1138 0 : ::rtl::Reference< ::comphelper::OInteractionApprove > xYes = new ::comphelper::OInteractionApprove;
1139 0 : xRequest->addContinuation( xYes.get() );
1140 0 : xRequest->addContinuation( new ::comphelper::OInteractionDisapprove );
1141 :
1142 : OSL_ENSURE( m_xInteractionHandler.is(),
1143 : "CopyTableWizard::impl_processCopyError_nothrow: we always should have an interaction handler!" );
1144 0 : if ( m_xInteractionHandler.is() )
1145 0 : m_xInteractionHandler->handle( xRequest.get() );
1146 :
1147 0 : if ( xYes->wasSelected() )
1148 : // continue copying
1149 0 : return true;
1150 : }
1151 0 : catch( const Exception& )
1152 : {
1153 : DBG_UNHANDLED_EXCEPTION();
1154 : }
1155 :
1156 : // cancel copying
1157 0 : return false;
1158 : }
1159 :
1160 : //-------------------------------------------------------------------------
1161 0 : void CopyTableWizard::impl_copyRows_throw( const Reference< XResultSet >& _rxSourceResultSet,
1162 : const Reference< XPropertySet >& _rxDestTable )
1163 : {
1164 : OSL_PRECOND( m_xDestConnection.is(), "CopyTableWizard::impl_copyRows_throw: illegal call!" );
1165 0 : if ( !m_xDestConnection.is() )
1166 0 : throw RuntimeException( "m_xDestConnection is set to null, CopyTableWizard::impl_copyRows_throw: illegal call!", *this );
1167 :
1168 0 : Reference< XDatabaseMetaData > xDestMetaData( m_xDestConnection->getMetaData(), UNO_QUERY_THROW );
1169 :
1170 0 : const OCopyTableWizard& rWizard = impl_getDialog_throw();
1171 0 : ODatabaseExport::TPositions aColumnMapping = rWizard.GetColumnPositions();
1172 0 : bool bAutoIncrement = rWizard.shouldCreatePrimaryKey();
1173 :
1174 0 : Reference< XRow > xRow ( _rxSourceResultSet, UNO_QUERY_THROW );
1175 0 : Reference< XRowLocate > xRowLocate ( _rxSourceResultSet, UNO_QUERY_THROW );
1176 :
1177 0 : Reference< XResultSetMetaDataSupplier > xSuppResMeta( _rxSourceResultSet, UNO_QUERY_THROW );
1178 0 : Reference< XResultSetMetaData> xMeta( xSuppResMeta->getMetaData() );
1179 :
1180 : // we need a vector which all types
1181 0 : sal_Int32 nCount = xMeta->getColumnCount();
1182 0 : ::std::vector< sal_Int32 > aSourceColTypes;
1183 0 : aSourceColTypes.reserve( nCount + 1 );
1184 0 : aSourceColTypes.push_back( -1 ); // just to avoid a everytime i-1 call
1185 :
1186 0 : ::std::vector< sal_Int32 > aSourcePrec;
1187 0 : aSourcePrec.reserve( nCount + 1 );
1188 0 : aSourcePrec.push_back( -1 ); // just to avoid a everytime i-1 call
1189 :
1190 0 : for ( sal_Int32 k=1; k <= nCount; ++k )
1191 : {
1192 0 : aSourceColTypes.push_back( xMeta->getColumnType( k ) );
1193 0 : aSourcePrec.push_back( xMeta->getPrecision( k ) );
1194 : }
1195 :
1196 : // now create, fill and execute the prepared statement
1197 0 : Reference< XPreparedStatement > xStatement( ODatabaseExport::createPreparedStatment( xDestMetaData, _rxDestTable, aColumnMapping ), UNO_SET_THROW );
1198 0 : Reference< XParameters > xStatementParams( xStatement, UNO_QUERY_THROW );
1199 :
1200 0 : const bool bSelectedRecordsOnly = m_aSourceSelection.getLength() != 0;
1201 0 : const Any* pSelectedRow = m_aSourceSelection.getConstArray();
1202 0 : const Any* pSelEnd = pSelectedRow + m_aSourceSelection.getLength();
1203 :
1204 0 : sal_Int32 nRowCount = 0;
1205 0 : bool bContinue = false;
1206 :
1207 0 : CopyTableRowEvent aCopyEvent;
1208 0 : aCopyEvent.Source = *this;
1209 0 : aCopyEvent.SourceData = _rxSourceResultSet;
1210 :
1211 0 : do // loop as long as there are more rows or the selection ends
1212 : {
1213 0 : bContinue = false;
1214 0 : if ( bSelectedRecordsOnly )
1215 : {
1216 0 : if ( pSelectedRow != pSelEnd )
1217 : {
1218 0 : if ( m_bSourceSelectionBookmarks )
1219 : {
1220 0 : bContinue = xRowLocate->moveToBookmark( *pSelectedRow );
1221 : }
1222 : else
1223 : {
1224 0 : sal_Int32 nPos = 0;
1225 0 : OSL_VERIFY( *pSelectedRow >>= nPos );
1226 0 : bContinue = _rxSourceResultSet->absolute( nPos );
1227 : }
1228 0 : ++pSelectedRow;
1229 : }
1230 : }
1231 : else
1232 0 : bContinue = _rxSourceResultSet->next();
1233 :
1234 0 : if ( !bContinue )
1235 : {
1236 : break;
1237 : }
1238 :
1239 0 : ++nRowCount;
1240 0 : sal_Bool bInsertAutoIncrement = sal_True;
1241 0 : ODatabaseExport::TPositions::const_iterator aPosIter = aColumnMapping.begin();
1242 0 : ODatabaseExport::TPositions::const_iterator aPosEnd = aColumnMapping.end();
1243 :
1244 0 : aCopyEvent.Error.clear();
1245 : try
1246 : {
1247 : // notify listeners
1248 0 : m_aCopyTableListeners.notifyEach( &XCopyTableListener::copyingRow, aCopyEvent );
1249 :
1250 0 : sal_Int32 nDestColumn( 0 );
1251 0 : sal_Int32 nSourceColumn( 1 );
1252 0 : ValueTransfer aTransfer( nSourceColumn, nDestColumn, aSourceColTypes, xRow, xStatementParams );
1253 :
1254 0 : for ( ; aPosIter != aPosEnd; ++aPosIter )
1255 : {
1256 0 : nDestColumn = aPosIter->first;
1257 0 : if ( nDestColumn == COLUMN_POSITION_NOT_FOUND )
1258 : {
1259 0 : ++nSourceColumn;
1260 : // otherwise we don't get the correct value when only the 2nd source column was selected
1261 0 : continue;
1262 : }
1263 :
1264 0 : if ( bAutoIncrement && bInsertAutoIncrement )
1265 : {
1266 0 : xStatementParams->setInt( 1, nRowCount );
1267 0 : bInsertAutoIncrement = sal_False;
1268 0 : continue;
1269 : }
1270 :
1271 0 : if ( ( nSourceColumn < 1 ) || ( nSourceColumn >= (sal_Int32)aSourceColTypes.size() ) )
1272 : { // ( we have to check here against 1 because the parameters are 1 based)
1273 : ::dbtools::throwSQLException(
1274 : ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Internal error: invalid column type index." ) ),
1275 : ::dbtools::SQL_INVALID_DESCRIPTOR_INDEX,
1276 : *this
1277 0 : );
1278 : }
1279 :
1280 0 : switch ( aSourceColTypes[ nSourceColumn ] )
1281 : {
1282 : case DataType::DOUBLE:
1283 : case DataType::REAL:
1284 0 : aTransfer.transferValue( &XRow::getDouble, &XParameters::setDouble );
1285 0 : break;
1286 :
1287 : case DataType::CHAR:
1288 : case DataType::VARCHAR:
1289 : case DataType::LONGVARCHAR:
1290 : case DataType::DECIMAL:
1291 : case DataType::NUMERIC:
1292 0 : aTransfer.transferComplexValue( &XRow::getString, &XParameters::setString );
1293 0 : break;
1294 :
1295 : case DataType::BIGINT:
1296 0 : aTransfer.transferValue( &XRow::getLong, &XParameters::setLong );
1297 0 : break;
1298 :
1299 : case DataType::FLOAT:
1300 0 : aTransfer.transferValue( &XRow::getFloat, &XParameters::setFloat );
1301 0 : break;
1302 :
1303 : case DataType::LONGVARBINARY:
1304 : case DataType::BINARY:
1305 : case DataType::VARBINARY:
1306 0 : aTransfer.transferComplexValue( &XRow::getBytes, &XParameters::setBytes );
1307 0 : break;
1308 :
1309 : case DataType::DATE:
1310 0 : aTransfer.transferComplexValue( &XRow::getDate, &XParameters::setDate );
1311 0 : break;
1312 :
1313 : case DataType::TIME:
1314 0 : aTransfer.transferComplexValue( &XRow::getTime, &XParameters::setTime );
1315 0 : break;
1316 :
1317 : case DataType::TIMESTAMP:
1318 0 : aTransfer.transferComplexValue( &XRow::getTimestamp, &XParameters::setTimestamp );
1319 0 : break;
1320 :
1321 : case DataType::BIT:
1322 0 : if ( aSourcePrec[nSourceColumn] > 1 )
1323 : {
1324 0 : aTransfer.transferComplexValue( &XRow::getBytes, &XParameters::setBytes );
1325 0 : break;
1326 : }
1327 : // run through
1328 : case DataType::BOOLEAN:
1329 0 : aTransfer.transferValue( &XRow::getBoolean, &XParameters::setBoolean );
1330 0 : break;
1331 :
1332 : case DataType::TINYINT:
1333 0 : aTransfer.transferValue( &XRow::getByte, &XParameters::setByte );
1334 0 : break;
1335 :
1336 : case DataType::SMALLINT:
1337 0 : aTransfer.transferValue( &XRow::getShort, &XParameters::setShort );
1338 0 : break;
1339 :
1340 : case DataType::INTEGER:
1341 0 : aTransfer.transferValue( &XRow::getInt, &XParameters::setInt );
1342 0 : break;
1343 :
1344 : case DataType::BLOB:
1345 0 : aTransfer.transferComplexValue( &XRow::getBlob, &XParameters::setBlob );
1346 0 : break;
1347 :
1348 : case DataType::CLOB:
1349 0 : aTransfer.transferComplexValue( &XRow::getClob, &XParameters::setClob );
1350 0 : break;
1351 :
1352 : default:
1353 : {
1354 0 : ::rtl::OUString aMessage( String( ModuleRes( STR_CTW_UNSUPPORTED_COLUMN_TYPE ) ) );
1355 :
1356 0 : aMessage = aMessage.replaceAt( aMessage.indexOfAsciiL( "$type$", 6 ), 6, ::rtl::OUString::valueOf( aSourceColTypes[ nSourceColumn ] ) );
1357 0 : aMessage = aMessage.replaceAt( aMessage.indexOfAsciiL( "$pos$", 5 ), 5, ::rtl::OUString::valueOf( nSourceColumn ) );
1358 :
1359 : ::dbtools::throwSQLException(
1360 : aMessage,
1361 : ::dbtools::SQL_INVALID_SQL_DATA_TYPE,
1362 : *this
1363 0 : );
1364 : }
1365 : }
1366 0 : ++nSourceColumn;
1367 : }
1368 0 : xStatement->executeUpdate();
1369 :
1370 : // notify listeners
1371 0 : m_aCopyTableListeners.notifyEach( &XCopyTableListener::copiedRow, aCopyEvent );
1372 : }
1373 0 : catch( const Exception& )
1374 : {
1375 0 : aCopyEvent.Error = ::cppu::getCaughtException();
1376 : }
1377 :
1378 0 : if ( aCopyEvent.Error.hasValue() )
1379 0 : bContinue = impl_processCopyError_nothrow( aCopyEvent );
1380 : }
1381 0 : while( bContinue );
1382 0 : }
1383 : //-------------------------------------------------------------------------
1384 0 : void CopyTableWizard::impl_doCopy_nothrow()
1385 : {
1386 0 : Any aError;
1387 :
1388 : try
1389 : {
1390 0 : OCopyTableWizard& rWizard( impl_getDialog_throw() );
1391 :
1392 0 : WaitObject aWO( rWizard.GetParent() );
1393 0 : Reference< XPropertySet > xTable;
1394 :
1395 0 : switch ( rWizard.getOperation() )
1396 : {
1397 : case CopyTableOperation::CopyDefinitionOnly:
1398 : case CopyTableOperation::CopyDefinitionAndData:
1399 : {
1400 0 : xTable = rWizard.createTable();
1401 :
1402 0 : if( !xTable.is() )
1403 : {
1404 : OSL_FAIL( "CopyTableWizard::impl_doCopy_nothrow: createTable should throw here, shouldn't it?" );
1405 0 : break;
1406 : }
1407 :
1408 0 : if( CopyTableOperation::CopyDefinitionOnly == rWizard.getOperation() )
1409 0 : break;
1410 : }
1411 : // run through
1412 :
1413 : case CopyTableOperation::AppendData:
1414 : {
1415 :
1416 0 : if ( !xTable.is() )
1417 : {
1418 0 : xTable = rWizard.createTable();
1419 0 : if ( !xTable.is() )
1420 : {
1421 : OSL_FAIL( "CopyTableWizard::impl_doCopy_nothrow: createTable should throw here, shouldn't it?" );
1422 : break;
1423 : }
1424 : }
1425 :
1426 0 : ::utl::SharedUNOComponent< XPreparedStatement > xSourceStatement;
1427 0 : ::utl::SharedUNOComponent< XResultSet > xSourceResultSet;
1428 :
1429 0 : if ( m_xSourceResultSet.is() )
1430 : {
1431 0 : xSourceResultSet.reset( m_xSourceResultSet, ::utl::SharedUNOComponent< XResultSet >::NoTakeOwnership );
1432 : }
1433 : else
1434 : {
1435 0 : const bool bIsSameConnection = ( m_xSourceConnection.getTyped() == m_xDestConnection.getTyped() );
1436 0 : const bool bIsTable = ( CommandType::TABLE == m_nCommandType );
1437 0 : bool bDone = false;
1438 0 : if ( bIsSameConnection && bIsTable )
1439 : {
1440 : // try whether the server supports copying via SQL
1441 : try
1442 : {
1443 0 : m_xDestConnection->createStatement()->executeUpdate( impl_getServerSideCopyStatement_throw(xTable) );
1444 0 : bDone = true;
1445 : }
1446 0 : catch( const Exception& )
1447 : {
1448 : // this is allowed.
1449 : }
1450 : }
1451 :
1452 0 : if ( !bDone )
1453 : {
1454 0 : xSourceStatement.set( impl_createSourceStatement_throw(), UNO_SET_THROW );
1455 0 : xSourceResultSet.set( xSourceStatement->executeQuery(), UNO_SET_THROW );
1456 : }
1457 : }
1458 :
1459 0 : if ( xSourceResultSet.is() )
1460 0 : impl_copyRows_throw( xSourceResultSet, xTable );
1461 : }
1462 0 : break;
1463 :
1464 : case CopyTableOperation::CreateAsView:
1465 0 : rWizard.createView();
1466 0 : break;
1467 :
1468 : default:
1469 : OSL_FAIL( "CopyTableWizard::impl_doCopy_nothrow: What operation, please?" );
1470 0 : break;
1471 0 : }
1472 : }
1473 0 : catch( const Exception& )
1474 : {
1475 0 : aError = ::cppu::getCaughtException();
1476 :
1477 : // silence the error of the user cancelling the parameter's dialog
1478 0 : SQLException aSQLError;
1479 0 : if ( ( aError >>= aSQLError ) && ( aSQLError.ErrorCode == ::dbtools::ParameterInteractionCancelled ) )
1480 : {
1481 0 : aError.clear();
1482 0 : m_nOverrideExecutionResult = RET_CANCEL;
1483 0 : }
1484 : }
1485 :
1486 0 : if ( aError.hasValue() && m_xInteractionHandler.is() )
1487 : {
1488 : try
1489 : {
1490 0 : ::rtl::Reference< ::comphelper::OInteractionRequest > xRequest( new ::comphelper::OInteractionRequest( aError ) );
1491 0 : m_xInteractionHandler->handle( xRequest.get() );
1492 : }
1493 0 : catch( const Exception& )
1494 : {
1495 : DBG_UNHANDLED_EXCEPTION();
1496 : }
1497 0 : }
1498 0 : }
1499 : // -----------------------------------------------------------------------------
1500 0 : ::rtl::OUString CopyTableWizard::impl_getServerSideCopyStatement_throw(const Reference< XPropertySet >& _xTable)
1501 : {
1502 0 : const Reference<XColumnsSupplier> xDestColsSup(_xTable,UNO_QUERY_THROW);
1503 0 : const Sequence< ::rtl::OUString> aDestColumnNames = xDestColsSup->getColumns()->getElementNames();
1504 0 : const Sequence< ::rtl::OUString > aColumnNames = m_pSourceObject->getColumnNames();
1505 0 : const Reference< XDatabaseMetaData > xDestMetaData( m_xDestConnection->getMetaData(), UNO_QUERY_THROW );
1506 0 : const ::rtl::OUString sQuote = xDestMetaData->getIdentifierQuoteString();
1507 0 : ::rtl::OUStringBuffer sColumns;
1508 : // 1st check if the columns matching
1509 0 : const OCopyTableWizard& rWizard = impl_getDialog_throw();
1510 0 : ODatabaseExport::TPositions aColumnMapping = rWizard.GetColumnPositions();
1511 0 : ODatabaseExport::TPositions::const_iterator aPosIter = aColumnMapping.begin();
1512 0 : for ( sal_Int32 i = 0; aPosIter != aColumnMapping.end() ; ++aPosIter,++i )
1513 : {
1514 0 : if ( COLUMN_POSITION_NOT_FOUND != aPosIter->second )
1515 : {
1516 0 : if ( sColumns.getLength() )
1517 0 : sColumns.appendAscii(",");
1518 0 : sColumns.append(sQuote);
1519 0 : sColumns.append(aDestColumnNames[aPosIter->second - 1]);
1520 0 : sColumns.append(sQuote);
1521 : }
1522 : }
1523 0 : ::rtl::OUStringBuffer sSql;
1524 0 : sSql.appendAscii("INSERT INTO ");
1525 0 : const ::rtl::OUString sComposedTableName = ::dbtools::composeTableName( xDestMetaData, _xTable, ::dbtools::eInDataManipulation, false, false, true );
1526 0 : sSql.append( sComposedTableName );
1527 0 : sSql.appendAscii(" ( ");
1528 0 : sSql.append( sColumns.makeStringAndClear() );
1529 0 : sSql.appendAscii(" ) ( ");
1530 0 : sSql.append( m_pSourceObject->getSelectStatement());
1531 0 : sSql.appendAscii(" )");
1532 :
1533 0 : return sSql.makeStringAndClear();
1534 : }
1535 : //-------------------------------------------------------------------------
1536 0 : void SAL_CALL CopyTableWizard::initialize( const Sequence< Any >& _rArguments ) throw (Exception, RuntimeException)
1537 : {
1538 0 : ::osl::MutexGuard aGuard( m_aMutex );
1539 0 : if ( isInitialized() )
1540 0 : throw AlreadyInitializedException( ::rtl::OUString(), *this );
1541 :
1542 0 : sal_Int32 nArgCount( _rArguments.getLength() );
1543 0 : if ( ( nArgCount != 2 ) && ( nArgCount != 3 ) )
1544 : throw IllegalArgumentException(
1545 : String( ModuleRes( STR_CTW_ILLEGAL_PARAMETER_COUNT ) ),
1546 : *this,
1547 : 1
1548 0 : );
1549 :
1550 : try
1551 : {
1552 0 : if ( nArgCount == 3 )
1553 : { // ->createWithInteractionHandler
1554 0 : if ( !( _rArguments[2] >>= m_xInteractionHandler ) )
1555 : throw IllegalArgumentException(
1556 : String(ModuleRes( STR_CTW_ERROR_INVALID_INTERACTIONHANDLER )),
1557 : *this,
1558 : 3
1559 0 : );
1560 : }
1561 0 : if ( !m_xInteractionHandler.is() )
1562 0 : m_xInteractionHandler.set( InteractionHandler::createWithParent(m_aContext.getUNOContext(), 0), UNO_QUERY );
1563 :
1564 0 : Reference< XInteractionHandler > xSourceDocHandler;
1565 0 : Reference< XPropertySet > xSourceDescriptor( impl_ensureDataAccessDescriptor_throw( _rArguments, 0, m_xSourceConnection, xSourceDocHandler ) );
1566 0 : impl_checkForUnsupportedSettings_throw( xSourceDescriptor );
1567 0 : m_pSourceObject = impl_extractSourceObject_throw( xSourceDescriptor, m_nCommandType );
1568 0 : impl_extractSourceResultSet_throw( xSourceDescriptor );
1569 :
1570 0 : Reference< XInteractionHandler > xDestDocHandler;
1571 0 : impl_ensureDataAccessDescriptor_throw( _rArguments, 1, m_xDestConnection, xDestDocHandler );
1572 :
1573 0 : if ( xDestDocHandler.is() && !m_xInteractionHandler.is() )
1574 0 : m_xInteractionHandler = xDestDocHandler;
1575 : }
1576 0 : catch( const RuntimeException& ) { throw; }
1577 0 : catch( const SQLException& ) { throw; }
1578 0 : catch( const Exception& )
1579 : {
1580 : throw WrappedTargetException(
1581 : String( ModuleRes( STR_CTW_ERROR_DURING_INITIALIZATION ) ),
1582 : *this,
1583 : ::cppu::getCaughtException()
1584 0 : );
1585 0 : }
1586 0 : }
1587 :
1588 : //-------------------------------------------------------------------------
1589 0 : ::cppu::IPropertyArrayHelper& CopyTableWizard::getInfoHelper()
1590 : {
1591 0 : return *getArrayHelper();
1592 : }
1593 :
1594 : //------------------------------------------------------------------------------
1595 0 : ::cppu::IPropertyArrayHelper* CopyTableWizard::createArrayHelper( ) const
1596 : {
1597 0 : Sequence< Property > aProps;
1598 0 : describeProperties( aProps );
1599 0 : return new ::cppu::OPropertyArrayHelper( aProps );
1600 : }
1601 :
1602 : //------------------------------------------------------------------------------
1603 0 : Dialog* CopyTableWizard::createDialog( Window* _pParent )
1604 : {
1605 : OSL_PRECOND( isInitialized(), "CopyTableWizard::createDialog: not initialized!" );
1606 : // this should have been prevented in ::execute already
1607 :
1608 : OCopyTableWizard* pWizard = new OCopyTableWizard(
1609 : _pParent,
1610 : m_sDestinationTable,
1611 : m_nOperation,
1612 0 : *m_pSourceObject,
1613 0 : m_xSourceConnection.getTyped(),
1614 0 : m_xDestConnection.getTyped(),
1615 : m_aContext.getUNOContext(),
1616 : m_xInteractionHandler
1617 0 : );
1618 :
1619 0 : impl_attributesToDialog_nothrow( *pWizard );
1620 :
1621 0 : return pWizard;
1622 : }
1623 :
1624 : //------------------------------------------------------------------------------
1625 0 : void CopyTableWizard::executedDialog( sal_Int16 _nExecutionResult )
1626 : {
1627 0 : CopyTableWizard_DialogBase::executedDialog( _nExecutionResult );
1628 :
1629 0 : if ( _nExecutionResult == RET_OK )
1630 0 : impl_doCopy_nothrow();
1631 :
1632 : // do this after impl_doCopy_nothrow: The attributes may change during copying, for instance
1633 : // if the user entered an unqualified table name
1634 0 : impl_dialogToAttributes_nothrow( impl_getDialog_throw() );
1635 0 : }
1636 :
1637 : //........................................................................
1638 : } // namespace dbaui
1639 : //........................................................................
1640 :
1641 0 : extern "C" void SAL_CALL createRegistryInfo_CopyTableWizard()
1642 : {
1643 0 : static ::dbaui::OMultiInstanceAutoRegistration< ::dbaui::CopyTableWizard > aAutoRegistration;
1644 0 : }
1645 :
1646 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|