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