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