1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: copytablewizard.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 #include "dbu_reghelper.hxx"
32 #include "dbu_resource.hrc"
33 #include "dbu_uno.hrc"
34 #include "dbustrings.hrc"
35 #include "moduledbu.hxx"
36 #include "sqlmessage.hxx"
37 #include "WCopyTable.hxx"
39 /** === begin UNO includes === **/
40 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
41 #include <com/sun/star/sdb/application/XCopyTableWizard.hpp>
42 #include <com/sun/star/sdb/application/CopyTableContinuation.hpp>
43 #include <com/sun/star/sdb/application/CopyTableOperation.hpp>
44 #include <com/sun/star/ucb/AlreadyInitializedException.hpp>
45 #include <com/sun/star/lang/NotInitializedException.hpp>
46 #include <com/sun/star/sdbc/XDataSource.hpp>
47 #include <com/sun/star/sdbc/DataType.hpp>
48 #include <com/sun/star/container/XNameAccess.hpp>
49 #include <com/sun/star/container/XChild.hpp>
50 #include <com/sun/star/task/XInteractionHandler.hpp>
51 #include <com/sun/star/frame/XModel.hpp>
52 #include <com/sun/star/sdb/XDocumentDataSource.hpp>
53 #include <com/sun/star/sdb/XCompletedConnection.hpp>
54 #include <com/sun/star/sdb/CommandType.hpp>
55 #include <com/sun/star/sdbcx/XTablesSupplier.hpp>
56 #include <com/sun/star/sdb/XQueriesSupplier.hpp>
57 #include <com/sun/star/lang/DisposedException.hpp>
58 #include <com/sun/star/sdb/XSingleSelectQueryComposer.hpp>
59 #include <com/sun/star/sdbc/XParameters.hpp>
60 #include <com/sun/star/sdbc/XRow.hpp>
61 #include <com/sun/star/sdbcx/XRowLocate.hpp>
62 #include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp>
63 #include <com/sun/star/sdb/SQLContext.hpp>
64 #include <com/sun/star/sdbc/XDriverManager.hpp>
65 /** === end UNO includes === **/
67 #include <comphelper/componentcontext.hxx>
68 #include <comphelper/interaction.hxx>
69 #include <comphelper/namedvaluecollection.hxx>
70 #include <comphelper/proparrhlp.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>
83 //........................................................................
86 //........................................................................
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::sdbcx::XRowLocate
;
131 using ::com::sun::star::sdbc::XResultSetMetaDataSupplier
;
132 using ::com::sun::star::sdbc::XResultSetMetaData
;
133 using ::com::sun::star::sdbc::SQLException
;
134 using ::com::sun::star::sdb::SQLContext
;
135 using ::com::sun::star::sdbc::XDriverManager
;
136 using ::com::sun::star::beans::PropertyValue
;
137 /** === end UNO using === **/
138 namespace CopyTableOperation
= ::com::sun::star::sdb::application::CopyTableOperation
;
139 namespace CopyTableContinuation
= ::com::sun::star::sdb::application::CopyTableContinuation
;
140 namespace CommandType
= ::com::sun::star::sdb::CommandType
;
141 namespace DataType
= ::com::sun::star::sdbc::DataType
;
143 typedef ::utl::SharedUNOComponent
< XConnection
> SharedConnection
;
144 typedef Reference
< XInteractionHandler
> InteractionHandler
;
146 //=========================================================================
148 //=========================================================================
149 typedef ::svt::OGenericUnoDialog CopyTableWizard_DialogBase
;
150 typedef ::cppu::ImplInheritanceHelper1
< CopyTableWizard_DialogBase
152 > CopyTableWizard_Base
;
153 class CopyTableWizard
154 :public CopyTableWizard_Base
155 ,public ::comphelper::OPropertyArrayUsageHelper
< CopyTableWizard
>
159 virtual ::rtl::OUString SAL_CALL
getImplementationName() throw(RuntimeException
);
160 virtual ::comphelper::StringSequence SAL_CALL
getSupportedServiceNames() throw(RuntimeException
);
162 // XServiceInfo - static methods
163 static Sequence
< ::rtl::OUString
> getSupportedServiceNames_Static(void) throw( RuntimeException
);
164 static ::rtl::OUString
getImplementationName_Static(void) throw( RuntimeException
);
165 static Reference
< XInterface
> Create( const Reference
< XMultiServiceFactory
>& );
168 virtual ::sal_Int16 SAL_CALL
getOperation() throw (RuntimeException
);
169 virtual void SAL_CALL
setOperation( ::sal_Int16 _operation
) throw (IllegalArgumentException
, RuntimeException
);
170 virtual ::rtl::OUString SAL_CALL
getDestinationTableName() throw (RuntimeException
);
171 virtual void SAL_CALL
setDestinationTableName( const ::rtl::OUString
& _destinationTableName
) throw (RuntimeException
);
172 virtual Optional
< ::rtl::OUString
> SAL_CALL
getCreatePrimaryKey() throw (RuntimeException
);
173 virtual void SAL_CALL
setCreatePrimaryKey( const Optional
< ::rtl::OUString
>& _newPrimaryKey
) throw (IllegalArgumentException
, RuntimeException
);
174 virtual sal_Bool SAL_CALL
getUseHeaderLineAsColumnNames() throw (RuntimeException
);
175 virtual void SAL_CALL
setUseHeaderLineAsColumnNames( sal_Bool _bUseHeaderLineAsColumnNames
) throw (RuntimeException
);
176 virtual void SAL_CALL
addCopyTableListener( const Reference
< XCopyTableListener
>& Listener
) throw (RuntimeException
);
177 virtual void SAL_CALL
removeCopyTableListener( const Reference
< XCopyTableListener
>& Listener
) throw (RuntimeException
);
179 // XCopyTableWizard::XExecutableDialog
180 virtual void SAL_CALL
setTitle( const ::rtl::OUString
& aTitle
) throw (RuntimeException
);
181 virtual ::sal_Int16 SAL_CALL
execute( ) throw (RuntimeException
);
184 virtual void SAL_CALL
initialize( const Sequence
< Any
>& aArguments
) throw (Exception
, RuntimeException
);
187 virtual Reference
< XPropertySetInfo
> SAL_CALL
getPropertySetInfo() throw(RuntimeException
);
188 virtual ::cppu::IPropertyArrayHelper
& SAL_CALL
getInfoHelper();
190 // OPropertyArrayUsageHelper
191 virtual ::cppu::IPropertyArrayHelper
* createArrayHelper( ) const;
194 ::osl::Mutex
& getMutex() { return m_aMutex
; }
195 bool isInitialized() const { return m_xSourceConnection
.is() && m_pSourceObject
.get() && m_xDestConnection
.is(); }
198 CopyTableWizard( const Reference
< XMultiServiceFactory
>& _rxORB
);
201 // OGenericUnoDialog overridables
202 virtual Dialog
* createDialog( Window
* _pParent
);
203 virtual void executedDialog( sal_Int16 _nExecutionResult
);
206 /// ensures our current attribute values are reflected in the dialog
207 void impl_attributesToDialog_nothrow( OCopyTableWizard
& _rDialog
) const;
209 /// ensures the current dialog settings are reflected in our attributes
210 void impl_dialogToAttributes_nothrow( const OCopyTableWizard
& _rDialog
);
212 /** returns our typed dialog
214 @throws ::com::sun::star::uno::RuntimeException
215 if we don't have a dialog at the moment the method is called
218 impl_getDialog_throw();
220 /** returns our typed dialog
222 @throws ::com::sun::star::uno::RuntimeException
223 if we don't have a dialog at the moment the method is called
225 const OCopyTableWizard
&
226 impl_getDialog_throw() const;
228 /** ensures the given argument sequence contains a valid data access descriptor at the given position
230 the arguments as passed to ->initialize
232 the position within ->_rAllArgs which contains the data access descriptor
233 @param _out_rxConnection
234 will, upon successful return, contain the connection for the data source
235 @param _out_rxDocInteractionHandler
236 will, upon successful return, contain the interaction handler which could
237 be deduced from database document described by the descriptor, if any.
238 (It is possible that the descriptor does not allow to deduce a database document,
239 in which case <code>_out_rxDocInteractionHandler</code> will be <NULL/>.)
240 @return the data access descriptor
242 Reference
< XPropertySet
>
243 impl_ensureDataAccessDescriptor_throw(
244 const Sequence
< Any
>& _rAllArgs
,
245 const sal_Int16 _nArgPos
,
246 SharedConnection
& _out_rxConnection
,
247 InteractionHandler
& _out_rxDocInteractionHandler
250 /** extracts the source object (table or query) described by the given descriptor,
251 relative to m_xSourceConnection
253 ::std::auto_ptr
< ICopyTableSourceObject
>
254 impl_extractSourceObject_throw(
255 const Reference
< XPropertySet
>& _rxDescriptor
,
256 sal_Int32
& _out_rCommandType
259 /** checks whether the given copy source descriptor contains settings which are not
262 Throws an IllegalArgumentException if the descriptor contains a valid setting, which is
265 void impl_checkForUnsupportedSettings_throw(
266 const Reference
< XPropertySet
>& _rxSourceDescriptor
) const;
268 /** obtaines the connection described by the given data access descriptor
270 If needed and possible, the method will ask the user, using the interaction
271 handler associated with the database described by the descriptor.
273 All errors are handled with the InteractionHandler associated with the data source,
274 if there is one. Else, they will be silenced (but asserted in non-product builds).
276 @param _rxDataSourceDescriptor
277 the data access descriptor describing the data source whose connection
278 should be obtained. Must not be <NULL/>.
279 @param _out_rxDocInteractionHandler
280 the interaction handler which could be deduced from the descriptor
282 @throws RuntimeException
283 if anything goes seriously wrong.
286 impl_extractConnection_throw(
287 const Reference
< XPropertySet
>& _rxDataSourceDescriptor
,
288 InteractionHandler
& _out_rxDocInteractionHandler
291 /** actually copies the table
293 This method is called after the dialog has been successfully executed.
295 void impl_doCopy_nothrow();
297 /** creates the INSERT INTO statement
298 @param _xTable The destination table.
300 ::rtl::OUString
impl_getSelectStatement_nothrow(const Reference
< XPropertySet
>& _xTable
);
302 /** creates the statement which, when executed, will produce the source data to copy
304 If the source object refers to a query which contains parameters, those parameters
305 are filled in, using an interaction handler.
307 ::utl::SharedUNOComponent
< XPreparedStatement
>
308 impl_createSourceStatement_throw() const;
310 /** copies the data rows from the given source result set to the given destination table
312 void impl_copyRows_throw(
313 const Reference
< XResultSet
>& _rxSourceResultSet
,
314 const Reference
< XPropertySet
>& _rxDestTable
317 /** processes an error which occured during copying
319 First, all listeners are ask. If a listener tells to cancel or continue copying, this is reported to the
320 method's caller. If a listener tells to ask the user, this is done, and the user's decision is
321 reported to the method's caller.
324 <TRUE/> if and only if copying should be continued.
326 bool impl_processCopyError_nothrow(
327 const CopyTableRowEvent
& _rEvent
);
330 ::comphelper::ComponentContext m_aContext
;
333 sal_Int16 m_nOperation
;
334 ::rtl::OUString m_sDestinationTable
;
335 Optional
< ::rtl::OUString
> m_aPrimaryKeyName
;
336 sal_Bool m_bUseHeaderLineAsColumnNames
;
339 SharedConnection m_xSourceConnection
;
340 sal_Int32 m_nCommandType
;
341 ::std::auto_ptr
< ICopyTableSourceObject
>
343 Sequence
< Any
> m_aSourceSelection
;
344 bool m_bSourceSelectionBookmarks
;
347 SharedConnection m_xDestConnection
;
350 InteractionHandler m_xInteractionHandler
;
351 ::cppu::OInterfaceContainerHelper
352 m_aCopyTableListeners
;
353 sal_Int16 m_nOverrideExecutionResult
;
356 //=========================================================================
358 //=========================================================================
359 class CopyTableAccessGuard
362 CopyTableAccessGuard( CopyTableWizard
& _rWizard
)
363 :m_rWizard( _rWizard
)
365 m_rWizard
.getMutex().acquire();
366 if ( !m_rWizard
.isInitialized() )
367 throw NotInitializedException();
370 ~CopyTableAccessGuard()
372 m_rWizard
.getMutex().release();
376 CopyTableWizard
& m_rWizard
;
379 //=========================================================================
380 //-------------------------------------------------------------------------
381 CopyTableWizard::CopyTableWizard( const Reference
< XMultiServiceFactory
>& _rxORB
)
382 :CopyTableWizard_Base( _rxORB
)
383 ,m_aContext( _rxORB
)
384 ,m_nOperation( CopyTableOperation::CopyDefinitionAndData
)
385 ,m_sDestinationTable()
386 ,m_aPrimaryKeyName( sal_False
, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ID" ) ))
387 ,m_bUseHeaderLineAsColumnNames( sal_True
)
388 ,m_xSourceConnection()
389 ,m_nCommandType( CommandType::COMMAND
)
391 ,m_aSourceSelection()
392 ,m_bSourceSelectionBookmarks( true )
394 ,m_aCopyTableListeners( m_aMutex
)
395 ,m_nOverrideExecutionResult( -1 )
397 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "uno", "Ocke.Janssen@sun.com", "CopyTableWizard::CopyTableWizard" );
400 //-------------------------------------------------------------------------
401 CopyTableWizard::~CopyTableWizard()
405 // protect some members whose dtor might potentially throw
406 try { m_xSourceConnection
.clear(); }
407 catch( const Exception
& ) { DBG_UNHANDLED_EXCEPTION(); }
408 try { m_xDestConnection
.clear(); }
409 catch( const Exception
& ) { DBG_UNHANDLED_EXCEPTION(); }
411 // TODO: shouldn't we have explicit disposal support? If a listener is registered
412 // at our instance, and perhaps holds this our instance by a hard ref, then we'll never
414 // However, adding XComponent support to the GenericUNODialog probably requires
415 // some thinking - would it break existing clients which do not call a dispose, then?
418 //-------------------------------------------------------------------------
419 Reference
< XInterface
> CopyTableWizard::Create( const Reference
< XMultiServiceFactory
>& _rxFactory
)
421 return *( new CopyTableWizard( _rxFactory
) );
424 //-------------------------------------------------------------------------
425 ::rtl::OUString SAL_CALL
CopyTableWizard::getImplementationName() throw(RuntimeException
)
427 return getImplementationName_Static();
430 //-------------------------------------------------------------------------
431 ::rtl::OUString
CopyTableWizard::getImplementationName_Static() throw(RuntimeException
)
433 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "org.openoffice.comp.dbu.CopyTableWizard" ) );
436 //-------------------------------------------------------------------------
437 ::comphelper::StringSequence SAL_CALL
CopyTableWizard::getSupportedServiceNames() throw(RuntimeException
)
439 return getSupportedServiceNames_Static();
442 //-------------------------------------------------------------------------
443 ::comphelper::StringSequence
CopyTableWizard::getSupportedServiceNames_Static() throw(RuntimeException
)
445 ::comphelper::StringSequence
aSupported(1);
446 aSupported
.getArray()[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sdb.application.CopyTableWizard" ) );
450 //-------------------------------------------------------------------------
451 Reference
< XPropertySetInfo
> SAL_CALL
CopyTableWizard::getPropertySetInfo() throw(RuntimeException
)
453 Reference
< XPropertySetInfo
> xInfo( createPropertySetInfo( getInfoHelper() ) );
457 //--------------------------------------------------------------------
458 ::sal_Int16 SAL_CALL
CopyTableWizard::getOperation() throw (RuntimeException
)
460 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "uno", "Ocke.Janssen@sun.com", "CopyTableWizard::getOperation" );
461 CopyTableAccessGuard
aGuard( *this );
465 //--------------------------------------------------------------------
466 void SAL_CALL
CopyTableWizard::setOperation( ::sal_Int16 _operation
) throw (IllegalArgumentException
, RuntimeException
)
468 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "uno", "Ocke.Janssen@sun.com", "CopyTableWizard::setOperation" );
469 CopyTableAccessGuard
aGuard( *this );
471 if ( ( _operation
!= CopyTableOperation::CopyDefinitionAndData
)
472 && ( _operation
!= CopyTableOperation::CopyDefinitionOnly
)
473 && ( _operation
!= CopyTableOperation::CreateAsView
)
474 && ( _operation
!= CopyTableOperation::AppendData
)
476 throw IllegalArgumentException( ::rtl::OUString(), *this, 1 );
478 if ( ( _operation
== CopyTableOperation::CreateAsView
)
479 && !OCopyTableWizard::supportsViews( m_xDestConnection
)
481 throw IllegalArgumentException(
482 String( ModuleRes( STR_CTW_NO_VIEWS_SUPPORT
) ),
487 m_nOperation
= _operation
;
490 //--------------------------------------------------------------------
491 ::rtl::OUString SAL_CALL
CopyTableWizard::getDestinationTableName() throw (RuntimeException
)
493 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "uno", "Ocke.Janssen@sun.com", "CopyTableWizard::getDestinationTableName" );
494 CopyTableAccessGuard
aGuard( *this );
495 return m_sDestinationTable
;
498 //--------------------------------------------------------------------
499 void SAL_CALL
CopyTableWizard::setDestinationTableName( const ::rtl::OUString
& _destinationTableName
) throw (RuntimeException
)
501 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "uno", "Ocke.Janssen@sun.com", "CopyTableWizard::setDestinationTableName" );
502 CopyTableAccessGuard
aGuard( *this );
503 m_sDestinationTable
= _destinationTableName
;
506 //--------------------------------------------------------------------
507 Optional
< ::rtl::OUString
> SAL_CALL
CopyTableWizard::getCreatePrimaryKey() throw (RuntimeException
)
509 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "uno", "Ocke.Janssen@sun.com", "CopyTableWizard::getCreatePrimaryKey" );
510 CopyTableAccessGuard
aGuard( *this );
511 return m_aPrimaryKeyName
;
514 //--------------------------------------------------------------------
515 void SAL_CALL
CopyTableWizard::setCreatePrimaryKey( const Optional
< ::rtl::OUString
>& _newPrimaryKey
) throw (IllegalArgumentException
, RuntimeException
)
517 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "uno", "Ocke.Janssen@sun.com", "CopyTableWizard::setCreatePrimaryKey" );
518 CopyTableAccessGuard
aGuard( *this );
520 if ( _newPrimaryKey
.IsPresent
&& !OCopyTableWizard::supportsPrimaryKey( m_xDestConnection
) )
521 throw IllegalArgumentException(
522 String( ModuleRes( STR_CTW_NO_PRIMARY_KEY_SUPPORT
) ),
527 m_aPrimaryKeyName
= _newPrimaryKey
;
529 // -----------------------------------------------------------------------------
530 sal_Bool SAL_CALL
CopyTableWizard::getUseHeaderLineAsColumnNames() throw (RuntimeException
)
532 CopyTableAccessGuard
aGuard( *this );
533 return m_bUseHeaderLineAsColumnNames
;
535 // -----------------------------------------------------------------------------
536 void SAL_CALL
CopyTableWizard::setUseHeaderLineAsColumnNames( sal_Bool _bUseHeaderLineAsColumnNames
) throw (RuntimeException
)
538 CopyTableAccessGuard
aGuard( *this );
539 m_bUseHeaderLineAsColumnNames
= _bUseHeaderLineAsColumnNames
;
541 //--------------------------------------------------------------------
542 void SAL_CALL
CopyTableWizard::addCopyTableListener( const Reference
< XCopyTableListener
>& _rxListener
) throw (RuntimeException
)
544 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "uno", "Ocke.Janssen@sun.com", "CopyTableWizard::addCopyTableListener" );
545 CopyTableAccessGuard
aGuard( *this );
546 if ( _rxListener
.is() )
547 m_aCopyTableListeners
.addInterface( _rxListener
);
550 //--------------------------------------------------------------------
551 void SAL_CALL
CopyTableWizard::removeCopyTableListener( const Reference
< XCopyTableListener
>& _rxListener
) throw (RuntimeException
)
553 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "uno", "Ocke.Janssen@sun.com", "CopyTableWizard::removeCopyTableListener" );
554 CopyTableAccessGuard
aGuard( *this );
555 if ( _rxListener
.is() )
556 m_aCopyTableListeners
.removeInterface( _rxListener
);
559 //--------------------------------------------------------------------
560 void SAL_CALL
CopyTableWizard::setTitle( const ::rtl::OUString
& _rTitle
) throw (RuntimeException
)
562 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "uno", "Ocke.Janssen@sun.com", "CopyTableWizard::setTitle" );
563 CopyTableAccessGuard
aGuard( *this );
564 CopyTableWizard_DialogBase::setTitle( _rTitle
);
567 //--------------------------------------------------------------------
568 ::sal_Int16 SAL_CALL
CopyTableWizard::execute( ) throw (RuntimeException
)
570 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "uno", "Ocke.Janssen@sun.com", "CopyTableWizard::execute" );
571 CopyTableAccessGuard
aGuard( *this );
573 m_nOverrideExecutionResult
= -1;
574 sal_Int16 nExecutionResult
= CopyTableWizard_DialogBase::execute();
575 if ( m_nOverrideExecutionResult
)
576 nExecutionResult
= m_nOverrideExecutionResult
;
578 return nExecutionResult
;
581 //-------------------------------------------------------------------------
582 OCopyTableWizard
& CopyTableWizard::impl_getDialog_throw()
584 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "uno", "Ocke.Janssen@sun.com", "CopyTableWizard::impl_getDialog_throw" );
585 OCopyTableWizard
* pWizard
= dynamic_cast< OCopyTableWizard
* >( m_pDialog
);
587 throw DisposedException( ::rtl::OUString(), *this );
591 //-------------------------------------------------------------------------
592 const OCopyTableWizard
& CopyTableWizard::impl_getDialog_throw() const
594 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "uno", "Ocke.Janssen@sun.com", "CopyTableWizard::impl_getDialog_throw" );
595 const OCopyTableWizard
* pWizard
= dynamic_cast< const OCopyTableWizard
* >( m_pDialog
);
597 throw DisposedException( ::rtl::OUString(), *const_cast< CopyTableWizard
* >( this ) );
601 //-------------------------------------------------------------------------
602 void CopyTableWizard::impl_attributesToDialog_nothrow( OCopyTableWizard
& _rDialog
) const
604 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "uno", "Ocke.Janssen@sun.com", "CopyTableWizard::impl_attributesToDialog_nothrow" );
605 // primary key column
606 _rDialog
.setCreatePrimaryKey( m_aPrimaryKeyName
.IsPresent
, m_aPrimaryKeyName
.Value
);
607 _rDialog
.setUseHeaderLine(m_bUseHeaderLineAsColumnNames
);
609 // everything else was passed at construction time already
612 //-------------------------------------------------------------------------
613 void CopyTableWizard::impl_dialogToAttributes_nothrow( const OCopyTableWizard
& _rDialog
)
615 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "uno", "Ocke.Janssen@sun.com", "CopyTableWizard::impl_dialogToAttributes_nothrow" );
616 m_aPrimaryKeyName
.IsPresent
= _rDialog
.shouldCreatePrimaryKey();
617 if ( m_aPrimaryKeyName
.IsPresent
)
618 m_aPrimaryKeyName
.Value
= _rDialog
.getPrimaryKeyName();
620 m_aPrimaryKeyName
.Value
= ::rtl::OUString();
622 m_sDestinationTable
= _rDialog
.getName();
624 m_nOperation
= _rDialog
.getOperation();
625 m_bUseHeaderLineAsColumnNames
= _rDialog
.UseHeaderLine();
628 //-------------------------------------------------------------------------
631 //.....................................................................
632 /** tries to obtain the InteractionHandler associated with a given data source
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.
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
641 InteractionHandler
lcl_getInteractionHandler_throw( const Reference
< XDataSource
>& _rxDataSource
, const InteractionHandler
& _rFallback
)
643 InteractionHandler
xHandler( _rFallback
);
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
);
651 // see whether the document model can provide a handler
652 if ( xDocumentModel
.is() )
654 ::comphelper::NamedValueCollection
aModelArgs( xDocumentModel
->getArgs() );
655 xHandler
= aModelArgs
.getOrDefault( "InteractionHandler", xHandler
);
660 //.....................................................................
661 /** tries to obtain the InteractionHandler associated with a given connection
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.
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
670 InteractionHandler
lcl_getInteractionHandler_throw( const Reference
< XConnection
>& _rxConnection
, const InteractionHandler
& _rFallback
)
672 // try whether there is a data source which the connection belongs to
673 Reference
< XDataSource
> xDataSource
;
674 Reference
< XChild
> xAsChild( _rxConnection
, UNO_QUERY
);
676 xDataSource
= xDataSource
.query( xAsChild
->getParent() );
678 if ( xDataSource
.is() )
679 return lcl_getInteractionHandler_throw( xDataSource
, _rFallback
);
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
690 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "uno", "Ocke.Janssen@sun.com", "CopyTableWizard::impl_ensureDataAccessDescriptor_throw" );
691 Reference
< XPropertySet
> xDescriptor
;
692 _rAllArgs
[ _nArgPos
] >>= xDescriptor
;
694 // the descriptor must be non-NULL, of course
695 bool bIsValid
= xDescriptor
.is();
697 // it must support the proper service
700 Reference
< XServiceInfo
> xSI( xDescriptor
, UNO_QUERY
);
701 bIsValid
= ( xSI
.is()
702 && xSI
->supportsService( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sdb.DataAccessDescriptor" ) ) )
706 // it must be able to provide a connection
709 _out_rxConnection
= impl_extractConnection_throw( xDescriptor
, _out_rxDocInteractionHandler
);
710 bIsValid
= _out_rxConnection
.is();
715 throw IllegalArgumentException(
716 String( ModuleRes( STR_CTW_INVALID_DATA_ACCESS_DESCRIPTOR
) ),
717 *const_cast< CopyTableWizard
* >( this ),
725 //-------------------------------------------------------------------------
728 bool lcl_hasNonEmptyStringValue_throw( const Reference
< XPropertySet
>& _rxDescriptor
,
729 const Reference
< XPropertySetInfo
> _rxPSI
, const ::rtl::OUString
& _rPropertyName
)
731 ::rtl::OUString sValue
;
732 if ( _rxPSI
->hasPropertyByName( _rPropertyName
) )
734 OSL_VERIFY( _rxDescriptor
->getPropertyValue( _rPropertyName
) >>= sValue
);
736 return sValue
.getLength() > 0;
740 //-------------------------------------------------------------------------
741 void CopyTableWizard::impl_checkForUnsupportedSettings_throw( const Reference
< XPropertySet
>& _rxSourceDescriptor
) const
743 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "uno", "Ocke.Janssen@sun.com", "CopyTableWizard::impl_checkForUnsupportedSettings_throw" );
744 OSL_PRECOND( _rxSourceDescriptor
.is(), "CopyTableWizard::impl_checkForUnsupportedSettings_throw: illegal argument!" );
745 Reference
< XPropertySetInfo
> xPSI( _rxSourceDescriptor
->getPropertySetInfo(), UNO_SET_THROW
);
746 ::rtl::OUString sUnsupportedSetting
;
748 // in theory, we could allow to use a mere result set as copy source. However, since this is currently
749 // not implemented at all, we report this in the initialization phase already
750 if ( xPSI
->hasPropertyByName( PROPERTY_RESULT_SET
) )
752 Reference
< XResultSet
> xSource( _rxSourceDescriptor
->getPropertyValue( PROPERTY_RESULT_SET
), UNO_QUERY
);
754 sUnsupportedSetting
= PROPERTY_RESULT_SET
;
757 if ( sUnsupportedSetting
.getLength() == 0 )
759 const ::rtl::OUString aSettings
[] = {
760 PROPERTY_FILTER
, PROPERTY_ORDER
, PROPERTY_HAVING_CLAUSE
, PROPERTY_GROUP_BY
762 for ( size_t i
=0; i
< sizeof( aSettings
) / sizeof( aSettings
[0] ); ++i
)
764 if ( lcl_hasNonEmptyStringValue_throw( _rxSourceDescriptor
, xPSI
, aSettings
[i
] ) )
766 sUnsupportedSetting
= aSettings
[i
];
772 if ( sUnsupportedSetting
.getLength() != 0 )
774 ::rtl::OUString
sMessage( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Unsupported setting in the copy source descriptor: $name$." ) ) );
776 sMessage
= sMessage
.replaceAt( sMessage
.indexOfAsciiL( "$name$", 6 ), 6, sUnsupportedSetting
);
777 throw IllegalArgumentException(
779 *const_cast< CopyTableWizard
* >( this ),
786 //-------------------------------------------------------------------------
787 ::std::auto_ptr
< ICopyTableSourceObject
> CopyTableWizard::impl_extractSourceObject_throw( const Reference
< XPropertySet
>& _rxDescriptor
, sal_Int32
& _out_rCommandType
) const
789 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "uno", "Ocke.Janssen@sun.com", "CopyTableWizard::impl_extractSourceObject_throw" );
790 OSL_PRECOND( _rxDescriptor
.is() && m_xSourceConnection
.is(), "CopyTableWizard::impl_extractSourceObject_throw: illegal arguments!" );
792 impl_checkForUnsupportedSettings_throw( _rxDescriptor
);
794 Reference
< XPropertySetInfo
> xPSI( _rxDescriptor
->getPropertySetInfo(), UNO_SET_THROW
);
795 if ( !xPSI
->hasPropertyByName( PROPERTY_COMMAND
)
796 || !xPSI
->hasPropertyByName( PROPERTY_COMMAND_TYPE
)
798 throw IllegalArgumentException(
799 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Expecting a table or query specification." ) ),
800 *const_cast< CopyTableWizard
* >( this ),
804 ::rtl::OUString sCommand
;
805 _out_rCommandType
= CommandType::COMMAND
;
806 OSL_VERIFY( _rxDescriptor
->getPropertyValue( PROPERTY_COMMAND
) >>= sCommand
);
807 OSL_VERIFY( _rxDescriptor
->getPropertyValue( PROPERTY_COMMAND_TYPE
) >>= _out_rCommandType
);
809 ::std::auto_ptr
< ICopyTableSourceObject
> pSourceObject
;
810 Reference
< XNameAccess
> xContainer
;
811 switch ( _out_rCommandType
)
813 case CommandType::TABLE
:
815 Reference
< XTablesSupplier
> xSuppTables( m_xSourceConnection
.getTyped(), UNO_QUERY
);
816 if ( xSuppTables
.is() )
817 xContainer
.set( xSuppTables
->getTables(), UNO_SET_THROW
);
820 case CommandType::QUERY
:
822 Reference
< XQueriesSupplier
> xSuppQueries( m_xSourceConnection
.getTyped(), UNO_QUERY
);
823 if ( xSuppQueries
.is() )
824 xContainer
.set( xSuppQueries
->getQueries(), UNO_SET_THROW
);
828 throw IllegalArgumentException(
829 String( ModuleRes( STR_CTW_ONLY_TABLES_AND_QUERIES_SUPPORT
) ),
830 *const_cast< CopyTableWizard
* >( this ),
835 if ( xContainer
.is() )
837 pSourceObject
.reset( new ObjectCopySource( m_xSourceConnection
,
838 Reference
< XPropertySet
>( xContainer
->getByName( sCommand
), UNO_QUERY_THROW
) ) );
842 // our source connection is an SDBC level connection only, not a SDBCX level one
843 // Which means it cannot provide the to-be-copied object as component.
845 if ( _out_rCommandType
== CommandType::QUERY
)
846 // we cannot copy a query if the connection cannot provide it ...
847 throw IllegalArgumentException(
848 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "To copy a query, your connection must be able to provide queries." ) ),
850 *const_cast< CopyTableWizard
* >( this ),
853 pSourceObject
.reset( new NamedTableCopySource( m_xSourceConnection
, sCommand
) );
856 return pSourceObject
;
859 //-------------------------------------------------------------------------
860 SharedConnection
CopyTableWizard::impl_extractConnection_throw( const Reference
< XPropertySet
>& _rxDataSourceDescriptor
,
861 InteractionHandler
& _out_rxDocInteractionHandler
) const
863 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "uno", "Ocke.Janssen@sun.com", "CopyTableWizard::impl_extractConnection_throw" );
864 SharedConnection xConnection
;
866 OSL_PRECOND( _rxDataSourceDescriptor
.is(), "CopyTableWizard::impl_extractConnection_throw: no descriptor!" );
867 if ( !_rxDataSourceDescriptor
.is() )
870 InteractionHandler xInteractionHandler
;
874 Reference
< XPropertySetInfo
> xPSI( _rxDataSourceDescriptor
->getPropertySetInfo(), UNO_SET_THROW
);
876 // if there's an ActiveConnection, use it
877 if ( xPSI
->hasPropertyByName( PROPERTY_ACTIVE_CONNECTION
) )
879 Reference
< XConnection
> xPure
;
880 OSL_VERIFY( _rxDataSourceDescriptor
->getPropertyValue( PROPERTY_ACTIVE_CONNECTION
) >>= xPure
);
881 xConnection
.reset( xPure
, SharedConnection::NoTakeOwnership
);
883 if ( xConnection
.is() )
885 xInteractionHandler
= lcl_getInteractionHandler_throw( xConnection
.getTyped(), m_xInteractionHandler
);
886 OSL_POSTCOND( xInteractionHandler
.is(), "CopyTableWizard::impl_extractConnection_throw: lcl_getInteractionHandler_throw returned nonsense!" );
890 // there could be a DataSourceName or a DatabaseLocation, describing the css.sdb.DataSource
891 ::rtl::OUString sDataSource
, sDatabaseLocation
;
892 if ( xPSI
->hasPropertyByName( PROPERTY_DATASOURCENAME
) )
893 OSL_VERIFY( _rxDataSourceDescriptor
->getPropertyValue( PROPERTY_DATASOURCENAME
) >>= sDataSource
);
894 if ( xPSI
->hasPropertyByName( PROPERTY_DATABASE_LOCATION
) )
895 OSL_VERIFY( _rxDataSourceDescriptor
->getPropertyValue( PROPERTY_DATABASE_LOCATION
) >>= sDatabaseLocation
);
897 // need a DatabaseContext for loading the data source
898 Reference
< XNameAccess
> xDatabaseContext( m_aContext
.createComponent( "com.sun.star.sdb.DatabaseContext" ), UNO_QUERY_THROW
);
899 Reference
< XDataSource
> xDataSource
;
900 if ( sDataSource
.getLength() )
901 xDataSource
.set( xDatabaseContext
->getByName( sDataSource
), UNO_QUERY_THROW
);
902 if ( !xDataSource
.is() && sDatabaseLocation
.getLength() )
903 xDataSource
.set( xDatabaseContext
->getByName( sDatabaseLocation
), UNO_QUERY_THROW
);
905 if ( xDataSource
.is() )
907 // first, try connecting with completion
908 xInteractionHandler
= lcl_getInteractionHandler_throw( xDataSource
, m_xInteractionHandler
);
909 OSL_POSTCOND( xInteractionHandler
.is(), "CopyTableWizard::impl_extractConnection_throw: lcl_getInteractionHandler_throw returned nonsense!" );
910 if ( xInteractionHandler
.is() )
912 Reference
< XCompletedConnection
> xInteractiveConnection( xDataSource
, UNO_QUERY
);
913 if ( xInteractiveConnection
.is() )
914 xConnection
.reset( xInteractiveConnection
->connectWithCompletion( xInteractionHandler
), SharedConnection::TakeOwnership
);
917 // interactively connecting was not successful or possible -> connect without interaction
918 if ( !xConnection
.is() )
920 xConnection
.reset( xDataSource
->getConnection( ::rtl::OUString(), ::rtl::OUString() ), SharedConnection::TakeOwnership
);
924 if ( xConnection
.is() )
927 // finally, there could be a ConnectionResource/ConnectionInfo
928 ::rtl::OUString sConnectionResource
;
929 Sequence
< PropertyValue
> aConnectionInfo
;
930 if ( xPSI
->hasPropertyByName( PROPERTY_CONNECTION_RESOURCE
) )
931 OSL_VERIFY( _rxDataSourceDescriptor
->getPropertyValue( PROPERTY_CONNECTION_RESOURCE
) >>= sConnectionResource
);
932 if ( xPSI
->hasPropertyByName( PROPERTY_CONNECTION_INFO
) )
933 OSL_VERIFY( _rxDataSourceDescriptor
->getPropertyValue( PROPERTY_CONNECTION_INFO
) >>= aConnectionInfo
);
935 Reference
< XDriverManager
> xDriverManager
;
936 xDriverManager
.set( m_aContext
.createComponent( "com.sun.star.sdbc.ConnectionPool" ), UNO_QUERY
);
937 if ( !xDriverManager
.is() )
938 // no connection pool installed
939 xDriverManager
.set( m_aContext
.createComponent( "com.sun.star.sdbc.DriverManager" ), UNO_QUERY_THROW
);
941 if ( aConnectionInfo
.getLength() )
942 xConnection
.set( xDriverManager
->getConnectionWithInfo( sConnectionResource
, aConnectionInfo
), UNO_SET_THROW
);
944 xConnection
.set( xDriverManager
->getConnection( sConnectionResource
), UNO_SET_THROW
);
948 if ( xInteractionHandler
!= m_xInteractionHandler
)
949 _out_rxDocInteractionHandler
= xInteractionHandler
;
954 //-------------------------------------------------------------------------
955 ::utl::SharedUNOComponent
< XPreparedStatement
> CopyTableWizard::impl_createSourceStatement_throw() const
957 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "uno", "Ocke.Janssen@sun.com", "CopyTableWizard::impl_createSourceStatement_throw" );
958 OSL_PRECOND( m_xSourceConnection
.is(), "CopyTableWizard::impl_createSourceStatement_throw: illegal call!" );
959 if ( !m_xSourceConnection
.is() )
960 throw RuntimeException( ::rtl::OUString(), *const_cast< CopyTableWizard
* >( this ) );
962 ::utl::SharedUNOComponent
< XPreparedStatement
> xStatement
;
963 switch ( m_nCommandType
)
965 case CommandType::TABLE
:
966 xStatement
.set( m_pSourceObject
->getPreparedSelectStatement(), UNO_SET_THROW
);
969 case CommandType::QUERY
:
971 ::rtl::OUString
sQueryCommand( m_pSourceObject
->getSelectStatement() );
972 xStatement
.set( m_pSourceObject
->getPreparedSelectStatement(), UNO_SET_THROW
);
974 // check whether we have to fill in parameter values
975 // create and fill a composer
977 Reference
< XMultiServiceFactory
> xFactory( m_xSourceConnection
, UNO_QUERY
);
978 ::utl::SharedUNOComponent
< XSingleSelectQueryComposer
> xComposer
;
980 // note: connections below the sdb-level are allowed to not support the XMultiServiceFactory interface
981 xComposer
.set( xFactory
->createInstance( SERVICE_NAME_SINGLESELECTQUERYCOMPOSER
), UNO_QUERY
);
983 if ( xComposer
.is() )
985 xComposer
->setQuery( sQueryCommand
);
987 Reference
< XParameters
> xStatementParams( xStatement
, UNO_QUERY
);
988 OSL_ENSURE( xStatementParams
.is(), "CopyTableWizard::impl_createSourceStatement_throw: no access to the statement's parameters!" );
989 // the statement should be a css.sdbc.PreparedStatement (this is what
990 // we created), and a prepared statement is required to support XParameters
991 if ( xStatementParams
.is() )
993 OSL_ENSURE( m_xInteractionHandler
.is(),
994 "CopyTableWizard::impl_createSourceStatement_throw: no interaction handler for the parameters request!" );
995 // we should always have an interaction handler - as last fallback, we create an own one in ::initialize
997 if ( m_xInteractionHandler
.is() )
998 ::dbtools::askForParameters( xComposer
, xStatementParams
, m_xSourceConnection
, m_xInteractionHandler
);
1005 // this should not have survived initialization phase
1006 throw RuntimeException( ::rtl::OUString(), *const_cast< CopyTableWizard
* >( this ) );
1012 //-------------------------------------------------------------------------
1018 ValueTransfer( const sal_Int32
& _rSourcePos
, const sal_Int32
& _rDestPos
, const ::std::vector
< sal_Int32
>& _rColTypes
,
1019 const Reference
< XRow
>& _rxSource
, const Reference
< XParameters
>& _rxDest
)
1020 :m_rSourcePos( _rSourcePos
)
1021 ,m_rDestPos( _rDestPos
)
1022 ,m_rColTypes( _rColTypes
)
1023 ,m_xSource( _rxSource
)
1028 template< typename VALUE_TYPE
>
1029 void transferValue( VALUE_TYPE ( SAL_CALL
XRow::*_pGetter
)( sal_Int32
),
1030 void (SAL_CALL
XParameters::*_pSetter
)( sal_Int32
, VALUE_TYPE
) )
1032 VALUE_TYPE
value( (m_xSource
.get()->*_pGetter
)( m_rSourcePos
) );
1033 if ( m_xSource
->wasNull() )
1034 m_xDest
->setNull( m_rDestPos
, m_rColTypes
[ m_rSourcePos
] );
1036 (m_xDest
.get()->*_pSetter
)( m_rDestPos
, value
);
1038 template< typename VALUE_TYPE
>
1039 void transferComplexValue( VALUE_TYPE ( SAL_CALL
XRow::*_pGetter
)( sal_Int32
),
1040 void (SAL_CALL
XParameters::*_pSetter
)( sal_Int32
, const VALUE_TYPE
& ) )
1042 const VALUE_TYPE
value( (m_xSource
.get()->*_pGetter
)( m_rSourcePos
) );
1044 if ( m_xSource
->wasNull() )
1045 m_xDest
->setNull( m_rDestPos
, m_rColTypes
[ m_rSourcePos
] );
1047 (m_xDest
.get()->*_pSetter
)( m_rDestPos
, value
);
1051 const sal_Int32
& m_rSourcePos
;
1052 const sal_Int32
& m_rDestPos
;
1053 const ::std::vector
< sal_Int32
> m_rColTypes
;
1054 const Reference
< XRow
> m_xSource
;
1055 const Reference
< XParameters
> m_xDest
;
1059 //-------------------------------------------------------------------------
1060 bool CopyTableWizard::impl_processCopyError_nothrow( const CopyTableRowEvent
& _rEvent
)
1062 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "uno", "Ocke.Janssen@sun.com", "CopyTableWizard::impl_processCopyError_nothrow" );
1063 Reference
< XCopyTableListener
> xListener
;
1066 ::cppu::OInterfaceIteratorHelper
aIter( m_aCopyTableListeners
);
1067 while ( aIter
.hasMoreElements() )
1069 xListener
.set( aIter
.next(), UNO_QUERY_THROW
);
1070 sal_Int16 nListenerChoice
= xListener
->copyRowError( _rEvent
);
1071 switch ( nListenerChoice
)
1073 case CopyTableContinuation::Proceed
: return true; // continue copying
1074 case CopyTableContinuation::CallNextHandler
: continue; // continue the loop, ask next listener
1075 case CopyTableContinuation::Cancel
: return false; // cancel copying
1076 case CopyTableContinuation::AskUser
: break; // stop asking the listeners, ask the user
1079 OSL_ENSURE( false, "CopyTableWizard::impl_processCopyError_nothrow: invalid listener response!" );
1080 // ask next listener
1085 catch( const Exception
& )
1087 DBG_UNHANDLED_EXCEPTION();
1090 // no listener felt responsible for the error, or a listener told to ask the user
1095 aError
.Context
= *this;
1096 aError
.Message
= String( ModuleRes( STR_ERROR_OCCURED_WHILE_COPYING
) );
1098 ::dbtools::SQLExceptionInfo
aInfo( _rEvent
.Error
);
1099 if ( aInfo
.isValid() )
1100 aError
.NextException
= _rEvent
.Error
;
1103 // a non-SQL exception happend
1104 Exception aException
;
1105 OSL_VERIFY( _rEvent
.Error
>>= aException
);
1106 SQLContext aContext
;
1107 aContext
.Context
= aException
.Context
;
1108 aContext
.Message
= aException
.Message
;
1109 aContext
.Details
= _rEvent
.Error
.getValueTypeName();
1110 aError
.NextException
<<= aContext
;
1113 ::rtl::Reference
< ::comphelper::OInteractionRequest
> xRequest( new ::comphelper::OInteractionRequest( makeAny( aError
) ) );
1115 ::rtl::Reference
< ::comphelper::OInteractionApprove
> xYes
= new ::comphelper::OInteractionApprove
;
1116 xRequest
->addContinuation( xYes
.get() );
1117 xRequest
->addContinuation( new ::comphelper::OInteractionDisapprove
);
1119 OSL_ENSURE( m_xInteractionHandler
.is(),
1120 "CopyTableWizard::impl_processCopyError_nothrow: we always should have an interaction handler!" );
1121 if ( m_xInteractionHandler
.is() )
1122 m_xInteractionHandler
->handle( xRequest
.get() );
1124 if ( xYes
->wasSelected() )
1128 catch( const Exception
& )
1130 DBG_UNHANDLED_EXCEPTION();
1137 //-------------------------------------------------------------------------
1138 void CopyTableWizard::impl_copyRows_throw( const Reference
< XResultSet
>& _rxSourceResultSet
,
1139 const Reference
< XPropertySet
>& _rxDestTable
)
1141 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "uno", "Ocke.Janssen@sun.com", "CopyTableWizard::impl_copyRows_throw" );
1142 OSL_PRECOND( m_xDestConnection
.is(), "CopyTableWizard::impl_copyRows_throw: illegal call!" );
1143 if ( !m_xDestConnection
.is() )
1144 throw RuntimeException( ::rtl::OUString(), *this );
1146 Reference
< XDatabaseMetaData
> xDestMetaData( m_xDestConnection
->getMetaData(), UNO_QUERY_THROW
);
1148 const OCopyTableWizard
& rWizard
= impl_getDialog_throw();
1149 ODatabaseExport::TPositions aColumnMapping
= rWizard
.GetColumnPositions();
1150 bool bAutoIncrement
= rWizard
.shouldCreatePrimaryKey();
1152 Reference
< XRow
> xRow ( _rxSourceResultSet
, UNO_QUERY_THROW
);
1153 Reference
< XRowLocate
> xRowLocate ( _rxSourceResultSet
, UNO_QUERY
);
1155 bool bSelectedRecordsOnly
= m_aSourceSelection
.getLength() > 0;
1156 if ( bSelectedRecordsOnly
&& m_bSourceSelectionBookmarks
&& !xRowLocate
.is() )
1158 ::dbtools::throwGenericSQLException(
1159 String( ModuleRes( STR_CTW_COPY_SOURCE_NEEDS_BOOKMARKS
) ),
1164 Reference
< XResultSetMetaDataSupplier
> xSuppResMeta( _rxSourceResultSet
, UNO_QUERY_THROW
);
1165 Reference
< XResultSetMetaData
> xMeta( xSuppResMeta
->getMetaData() );
1167 // we need a vector which all types
1168 sal_Int32 nCount
= xMeta
->getColumnCount();
1169 ::std::vector
< sal_Int32
> aSourceColTypes
;
1170 aSourceColTypes
.reserve( nCount
+ 1 );
1171 aSourceColTypes
.push_back( -1 ); // just to avoid a everytime i-1 call
1173 for ( sal_Int32 k
=1; k
<= nCount
; ++k
)
1174 aSourceColTypes
.push_back( xMeta
->getColumnType( k
) );
1176 // now create, fill and execute the prepared statement
1177 Reference
< XPreparedStatement
> xStatement( ODatabaseExport::createPreparedStatment( xDestMetaData
, _rxDestTable
, aColumnMapping
), UNO_SET_THROW
);
1178 Reference
< XParameters
> xStatementParams( xStatement
, UNO_QUERY_THROW
);
1180 sal_Int32 nRowCount
= 0;
1181 const Any
* pSelectedRow
= m_aSourceSelection
.getConstArray();
1182 const Any
* pSelEnd
= pSelectedRow
+ m_aSourceSelection
.getLength();
1183 bool bContinue
= false;
1185 CopyTableRowEvent aCopyEvent
;
1186 aCopyEvent
.Source
= *this;
1187 aCopyEvent
.SourceData
= _rxSourceResultSet
;
1189 do // loop as long as there are more rows or the selection ends
1192 if ( bSelectedRecordsOnly
)
1194 if ( pSelectedRow
!= pSelEnd
)
1196 if ( m_bSourceSelectionBookmarks
)
1198 xRowLocate
->moveToBookmark( *pSelectedRow
);
1203 OSL_VERIFY( *pSelectedRow
>>= nPos
);
1204 bContinue
= _rxSourceResultSet
->absolute( nPos
);
1210 bContinue
= _rxSourceResultSet
->next();
1218 sal_Bool bInsertAutoIncrement
= sal_True
;
1219 ODatabaseExport::TPositions::const_iterator aPosIter
= aColumnMapping
.begin();
1220 ODatabaseExport::TPositions::const_iterator aPosEnd
= aColumnMapping
.end();
1222 aCopyEvent
.Error
.clear();
1226 m_aCopyTableListeners
.notifyEach( &XCopyTableListener::copyingRow
, aCopyEvent
);
1228 sal_Int32
nDestColumn( 0 );
1229 sal_Int32
nSourceColumn( 1 );
1230 ValueTransfer
aTransfer( nSourceColumn
, nDestColumn
, aSourceColTypes
, xRow
, xStatementParams
);
1232 for ( ; aPosIter
!= aPosEnd
; ++aPosIter
)
1234 nDestColumn
= aPosIter
->first
;
1235 if ( nDestColumn
== COLUMN_POSITION_NOT_FOUND
)
1238 // otherwise we don't get the correct value when only the 2nd source column was selected
1242 if ( bAutoIncrement
&& bInsertAutoIncrement
)
1244 xStatementParams
->setInt( 1, nRowCount
);
1245 bInsertAutoIncrement
= sal_False
;
1249 if ( ( nSourceColumn
< 1 ) || ( nSourceColumn
>= (sal_Int32
)aSourceColTypes
.size() ) )
1250 { // ( we have to check here against 1 because the parameters are 1 based)
1251 ::dbtools::throwSQLException(
1252 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Internal error: invalid column type index." ) ),
1253 ::dbtools::SQL_INVALID_DESCRIPTOR_INDEX
,
1258 switch ( aSourceColTypes
[ nSourceColumn
] )
1260 case DataType::DOUBLE
:
1261 case DataType::REAL
:
1262 aTransfer
.transferValue( &XRow::getDouble
, &XParameters::setDouble
);
1265 case DataType::CHAR
:
1266 case DataType::VARCHAR
:
1267 case DataType::LONGVARCHAR
:
1268 case DataType::DECIMAL
:
1269 case DataType::NUMERIC
:
1270 aTransfer
.transferComplexValue( &XRow::getString
, &XParameters::setString
);
1273 case DataType::BIGINT
:
1274 aTransfer
.transferValue( &XRow::getLong
, &XParameters::setLong
);
1277 case DataType::FLOAT
:
1278 aTransfer
.transferValue( &XRow::getFloat
, &XParameters::setFloat
);
1281 case DataType::LONGVARBINARY
:
1282 case DataType::BINARY
:
1283 case DataType::VARBINARY
:
1284 aTransfer
.transferComplexValue( &XRow::getBytes
, &XParameters::setBytes
);
1287 case DataType::DATE
:
1288 aTransfer
.transferComplexValue( &XRow::getDate
, &XParameters::setDate
);
1291 case DataType::TIME
:
1292 aTransfer
.transferComplexValue( &XRow::getTime
, &XParameters::setTime
);
1295 case DataType::TIMESTAMP
:
1296 aTransfer
.transferComplexValue( &XRow::getTimestamp
, &XParameters::setTimestamp
);
1300 case DataType::BOOLEAN
:
1301 aTransfer
.transferValue( &XRow::getBoolean
, &XParameters::setBoolean
);
1304 case DataType::TINYINT
:
1305 aTransfer
.transferValue( &XRow::getByte
, &XParameters::setByte
);
1308 case DataType::SMALLINT
:
1309 aTransfer
.transferValue( &XRow::getShort
, &XParameters::setShort
);
1312 case DataType::INTEGER
:
1313 aTransfer
.transferValue( &XRow::getInt
, &XParameters::setInt
);
1318 ::rtl::OUString
aMessage( String( ModuleRes( STR_CTW_UNSUPPORTED_COLUMN_TYPE
) ) );
1320 aMessage
.replaceAt( aMessage
.indexOfAsciiL( "$type$", 6 ), 6, ::rtl::OUString::valueOf( aSourceColTypes
[ nSourceColumn
] ) );
1321 aMessage
.replaceAt( aMessage
.indexOfAsciiL( "$pos$", 5 ), 5, ::rtl::OUString::valueOf( nSourceColumn
) );
1323 ::dbtools::throwSQLException(
1325 ::dbtools::SQL_INVALID_SQL_DATA_TYPE
,
1332 xStatement
->executeUpdate();
1335 m_aCopyTableListeners
.notifyEach( &XCopyTableListener::copiedRow
, aCopyEvent
);
1337 catch( const Exception
& )
1339 aCopyEvent
.Error
= ::cppu::getCaughtException();
1342 if ( aCopyEvent
.Error
.hasValue() )
1343 bContinue
= impl_processCopyError_nothrow( aCopyEvent
);
1347 //-------------------------------------------------------------------------
1348 void CopyTableWizard::impl_doCopy_nothrow()
1350 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "uno", "Ocke.Janssen@sun.com", "CopyTableWizard::impl_doCopy_nothrow" );
1355 OCopyTableWizard
& rWizard( impl_getDialog_throw() );
1357 WaitObject
aWO( rWizard
.GetParent() );
1358 Reference
< XPropertySet
> xTable
;
1360 switch ( rWizard
.getOperation() )
1362 case CopyTableOperation::CopyDefinitionOnly
:
1363 case CopyTableOperation::CopyDefinitionAndData
:
1365 xTable
= rWizard
.createTable();
1369 OSL_ENSURE( false, "CopyTableWizard::impl_doCopy_nothrow: createTable should throw here, shouldn't it?" );
1373 if( CopyTableOperation::CopyDefinitionOnly
== rWizard
.getOperation() )
1378 case CopyTableOperation::AppendData
:
1383 xTable
= rWizard
.createTable();
1386 OSL_ENSURE( false, "CopyTableWizard::impl_doCopy_nothrow: createTable should throw here, shouldn't it?" );
1391 bool bServerCopy
= CommandType::TABLE
== m_nCommandType
&& m_xSourceConnection
.getTyped() == m_xDestConnection
.getTyped() && !m_aSourceSelection
.getLength();
1396 m_xDestConnection
->createStatement()->executeUpdate( impl_getSelectStatement_nothrow(xTable
) );
1399 catch( const Exception
& e
)
1402 bServerCopy
= false;
1407 ::utl::SharedUNOComponent
< XPreparedStatement
> xStatement( impl_createSourceStatement_throw(), UNO_SET_THROW
);
1408 Reference
< XResultSet
> xSourceResultSet( xStatement
->executeQuery() );
1409 impl_copyRows_throw( xSourceResultSet
, xTable
);
1414 case CopyTableOperation::CreateAsView
:
1415 rWizard
.createView();
1419 OSL_ENSURE( false, "CopyTableWizard::impl_doCopy_nothrow: What operation, please?" );
1423 catch( const Exception
& )
1425 aError
= ::cppu::getCaughtException();
1427 // silence the error of the user cancelling the parameter's dialog
1428 SQLException aSQLError
;
1429 if ( ( aError
>>= aSQLError
) && ( aSQLError
.ErrorCode
== ::dbtools::ParameterInteractionCancelled
) )
1432 m_nOverrideExecutionResult
= RET_CANCEL
;
1436 if ( aError
.hasValue() && m_xInteractionHandler
.is() )
1440 ::rtl::Reference
< ::comphelper::OInteractionRequest
> xRequest( new ::comphelper::OInteractionRequest( aError
) );
1441 m_xInteractionHandler
->handle( xRequest
.get() );
1443 catch( const Exception
& )
1445 DBG_UNHANDLED_EXCEPTION();
1449 // -----------------------------------------------------------------------------
1450 ::rtl::OUString
CopyTableWizard::impl_getSelectStatement_nothrow(const Reference
< XPropertySet
>& _xTable
)
1452 const Reference
<XColumnsSupplier
> xDestColsSup(_xTable
,UNO_QUERY_THROW
);
1453 const Sequence
< ::rtl::OUString
> aDestColumnNames
= xDestColsSup
->getColumns()->getElementNames();
1454 const Sequence
< ::rtl::OUString
> aColumnNames
= m_pSourceObject
->getColumnNames();
1455 const Reference
< XDatabaseMetaData
> xDestMetaData( m_xDestConnection
->getMetaData(), UNO_QUERY_THROW
);
1456 const ::rtl::OUString sQuote
= xDestMetaData
->getIdentifierQuoteString();
1457 ::rtl::OUStringBuffer sColumns
;
1458 // 1st check if the columns matching
1459 const OCopyTableWizard
& rWizard
= impl_getDialog_throw();
1460 ODatabaseExport::TPositions aColumnMapping
= rWizard
.GetColumnPositions();
1461 ODatabaseExport::TPositions::const_iterator aPosIter
= aColumnMapping
.begin();
1462 for ( sal_Int32 i
= 0; aPosIter
!= aColumnMapping
.end() ; ++aPosIter
,++i
)
1464 if ( COLUMN_POSITION_NOT_FOUND
!= aPosIter
->second
)
1466 if ( sColumns
.getLength() )
1467 sColumns
.appendAscii(",");
1468 sColumns
.append(sQuote
);
1469 sColumns
.append(aDestColumnNames
[aPosIter
->second
- 1]);
1470 sColumns
.append(sQuote
);
1472 } // for ( ; aPosIter != aColumnMapping.end() ; ++aPosIter )
1473 ::rtl::OUStringBuffer sSql
;
1474 sSql
.appendAscii("INSERT INTO ");
1475 const ::rtl::OUString sComposedTableName
= ::dbtools::composeTableName( xDestMetaData
, _xTable
, ::dbtools::eInDataManipulation
, false, false, true );
1476 sSql
.append( sComposedTableName
);
1477 sSql
.appendAscii(" ( ");
1478 sSql
.append( sColumns
);
1479 sSql
.appendAscii(" ) ( ");
1480 sSql
.append( m_pSourceObject
->getSelectStatement());
1481 sSql
.appendAscii(" )");
1483 return sSql
.makeStringAndClear();
1485 //-------------------------------------------------------------------------
1486 void SAL_CALL
CopyTableWizard::initialize( const Sequence
< Any
>& _rArguments
) throw (Exception
, RuntimeException
)
1488 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "uno", "Ocke.Janssen@sun.com", "CopyTableWizard::initialize" );
1489 ::osl::MutexGuard
aGuard( m_aMutex
);
1490 if ( isInitialized() )
1491 throw AlreadyInitializedException( ::rtl::OUString(), *this );
1493 sal_Int32
nArgCount( _rArguments
.getLength() );
1494 if ( ( nArgCount
!= 2 ) && ( nArgCount
!= 3 ) )
1495 throw IllegalArgumentException(
1496 String( ModuleRes( STR_CTW_ILLEGAL_PARAMETER_COUNT
) ),
1503 if ( nArgCount
== 3 )
1504 { // ->createWithInteractionHandler
1505 if ( !( _rArguments
[2] >>= m_xInteractionHandler
) )
1506 throw IllegalArgumentException(
1507 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "The given interaction handler is invalid." ) ),
1513 if ( !m_xInteractionHandler
.is() )
1514 m_xInteractionHandler
.set( m_aContext
.createComponent( "com.sun.star.sdb.InteractionHandler" ), UNO_QUERY_THROW
);
1516 InteractionHandler xSourceDocHandler
;
1517 Reference
< XPropertySet
> xSourceDescriptor( impl_ensureDataAccessDescriptor_throw( _rArguments
, 0, m_xSourceConnection
, xSourceDocHandler
) );
1518 m_pSourceObject
= impl_extractSourceObject_throw( xSourceDescriptor
, m_nCommandType
);
1520 InteractionHandler xDestDocHandler
;
1521 impl_ensureDataAccessDescriptor_throw( _rArguments
, 1, m_xDestConnection
, xDestDocHandler
);
1523 if ( xDestDocHandler
.is() && !m_xInteractionHandler
.is() )
1524 m_xInteractionHandler
= xDestDocHandler
;
1526 catch( const RuntimeException
& ) { throw; }
1527 catch( const IllegalArgumentException
& ) { throw; }
1528 catch( const SQLException
& ) { throw; }
1529 catch( const Exception
& )
1531 throw WrappedTargetException(
1532 String( ModuleRes( STR_CTW_ERROR_DURING_INITIALIZATION
) ),
1534 ::cppu::getCaughtException()
1539 //-------------------------------------------------------------------------
1540 ::cppu::IPropertyArrayHelper
& CopyTableWizard::getInfoHelper()
1542 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "uno", "Ocke.Janssen@sun.com", "CopyTableWizard::getInfoHelper" );
1543 return *getArrayHelper();
1546 //------------------------------------------------------------------------------
1547 ::cppu::IPropertyArrayHelper
* CopyTableWizard::createArrayHelper( ) const
1549 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "uno", "Ocke.Janssen@sun.com", "CopyTableWizard::createArrayHelper" );
1550 Sequence
< Property
> aProps
;
1551 describeProperties( aProps
);
1552 return new ::cppu::OPropertyArrayHelper( aProps
);
1555 //------------------------------------------------------------------------------
1556 Dialog
* CopyTableWizard::createDialog( Window
* _pParent
)
1558 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "uno", "Ocke.Janssen@sun.com", "CopyTableWizard::createDialog" );
1559 OSL_PRECOND( isInitialized(), "CopyTableWizard::createDialog: not initialized!" );
1560 // this should have been prevented in ::execute already
1562 OCopyTableWizard
* pWizard
= new OCopyTableWizard(
1564 m_sDestinationTable
,
1567 m_xSourceConnection
.getTyped(),
1568 m_xDestConnection
.getTyped(),
1569 m_aContext
.getLegacyServiceFactory()
1572 impl_attributesToDialog_nothrow( *pWizard
);
1577 //------------------------------------------------------------------------------
1578 void CopyTableWizard::executedDialog( sal_Int16 _nExecutionResult
)
1580 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "uno", "Ocke.Janssen@sun.com", "CopyTableWizard::executedDialog" );
1581 CopyTableWizard_DialogBase::executedDialog( _nExecutionResult
);
1583 if ( _nExecutionResult
== RET_OK
)
1584 impl_doCopy_nothrow();
1586 // do this after impl_doCopy_nothrow: The attributes may change during copying, for instance
1587 // if the user entered an unqualified table name
1588 impl_dialogToAttributes_nothrow( impl_getDialog_throw() );
1591 //........................................................................
1592 } // namespace dbaui
1593 //........................................................................
1595 extern "C" void SAL_CALL
createRegistryInfo_CopyTableWizard()
1597 static ::dbaui::OMultiInstanceAutoRegistration
< ::dbaui::CopyTableWizard
> aAutoRegistration
;