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