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