diff options
Diffstat (limited to 'dbaccess/source/ui/uno/copytablewizard.cxx')
-rw-r--r-- | dbaccess/source/ui/uno/copytablewizard.cxx | 341 |
1 files changed, 193 insertions, 148 deletions
diff --git a/dbaccess/source/ui/uno/copytablewizard.cxx b/dbaccess/source/ui/uno/copytablewizard.cxx index fedcb407f7d7..13a4f050731b 100644 --- a/dbaccess/source/ui/uno/copytablewizard.cxx +++ b/dbaccess/source/ui/uno/copytablewizard.cxx @@ -59,12 +59,13 @@ #include <connectivity/dbtools.hxx> #include <cppuhelper/exc_hlp.hxx> #include <cppuhelper/implbase.hxx> -#include <comphelper/interfacecontainer2.hxx> +#include <comphelper/interfacecontainer3.hxx> +#include <o3tl/safeint.hxx> #include <rtl/ustrbuf.hxx> #include <sal/log.hxx> #include <svtools/genericunodialog.hxx> #include <toolkit/helper/vclunohelper.hxx> -#include <tools/diagnose_ex.h> +#include <comphelper/diagnose_ex.hxx> #include <unotools/sharedunocomponent.hxx> #include <vcl/svapp.hxx> @@ -79,7 +80,6 @@ namespace dbaui using ::com::sun::star::uno::Exception; using ::com::sun::star::uno::RuntimeException; using ::com::sun::star::uno::Any; - using ::com::sun::star::uno::makeAny; using ::com::sun::star::uno::Sequence; using ::com::sun::star::uno::XComponentContext; using ::com::sun::star::beans::XPropertySetInfo; @@ -338,7 +338,7 @@ private: // other Reference< XInteractionHandler > m_xInteractionHandler; - ::comphelper::OInterfaceContainerHelper2 + ::comphelper::OInterfaceContainerHelper3<XCopyTableListener> m_aCopyTableListeners; sal_Int16 m_nOverrideExecutionResult; }; @@ -370,16 +370,10 @@ CopyTableWizard::CopyTableWizard( const Reference< XComponentContext >& _rxORB ) :CopyTableWizard_Base( _rxORB ) ,m_xContext( _rxORB ) ,m_nOperation( CopyTableOperation::CopyDefinitionAndData ) - ,m_sDestinationTable() - ,m_aPrimaryKeyName( false, "ID" ) + ,m_aPrimaryKeyName( false, u"ID"_ustr ) ,m_bUseHeaderLineAsColumnNames( true ) - ,m_xSourceConnection() ,m_nCommandType( CommandType::COMMAND ) - ,m_pSourceObject() - ,m_xSourceResultSet() - ,m_aSourceSelection() ,m_bSourceSelectionBookmarks( true ) - ,m_xDestConnection() ,m_aCopyTableListeners( m_aMutex ) ,m_nOverrideExecutionResult( -1 ) { @@ -404,12 +398,12 @@ CopyTableWizard::~CopyTableWizard() OUString SAL_CALL CopyTableWizard::getImplementationName() { - return "org.openoffice.comp.dbu.CopyTableWizard"; + return u"org.openoffice.comp.dbu.CopyTableWizard"_ustr; } css::uno::Sequence<OUString> SAL_CALL CopyTableWizard::getSupportedServiceNames() { - return { "com.sun.star.sdb.application.CopyTableWizard" }; + return { u"com.sun.star.sdb.application.CopyTableWizard"_ustr }; } Reference< XPropertySetInfo > SAL_CALL CopyTableWizard::getPropertySetInfo() @@ -578,8 +572,7 @@ namespace // see whether the document model can provide a handler if ( xDocumentModel.is() ) { - ::comphelper::NamedValueCollection aModelArgs( xDocumentModel->getArgs() ); - xHandler = aModelArgs.getOrDefault( "InteractionHandler", xHandler ); + xHandler = ::comphelper::NamedValueCollection::getOrDefault( xDocumentModel->getArgs(), u"InteractionHandler", xHandler ); } return xHandler; @@ -623,7 +616,7 @@ Reference< XPropertySet > CopyTableWizard::impl_ensureDataAccessDescriptor_throw { Reference< XServiceInfo > xSI( xDescriptor, UNO_QUERY ); bIsValid = ( xSI.is() - && xSI->supportsService( "com.sun.star.sdb.DataAccessDescriptor" ) ); + && xSI->supportsService( u"com.sun.star.sdb.DataAccessDescriptor"_ustr ) ); } // it must be able to provide a connection @@ -666,7 +659,7 @@ void CopyTableWizard::impl_checkForUnsupportedSettings_throw( const Reference< X OUString sUnsupportedSetting; const OUString aSettings[] = { - OUString(PROPERTY_FILTER), OUString(PROPERTY_ORDER), OUString(PROPERTY_HAVING_CLAUSE), OUString(PROPERTY_GROUP_BY) + PROPERTY_FILTER, PROPERTY_ORDER, PROPERTY_HAVING_CLAUSE, PROPERTY_GROUP_BY }; for (const auto & aSetting : aSettings) { @@ -699,7 +692,7 @@ std::unique_ptr< ICopyTableSourceObject > CopyTableWizard::impl_extractSourceObj if ( !xPSI->hasPropertyByName( PROPERTY_COMMAND ) || !xPSI->hasPropertyByName( PROPERTY_COMMAND_TYPE ) ) - throw IllegalArgumentException("Expecting a table or query specification.", + throw IllegalArgumentException(u"Expecting a table or query specification."_ustr, // TODO: resource *const_cast< CopyTableWizard* >( this ), 1); @@ -775,7 +768,7 @@ void CopyTableWizard::impl_extractSourceResultSet_throw( const Reference< XPrope const bool bHasResultSet = m_xSourceResultSet.is(); const bool bHasSelection = m_aSourceSelection.hasElements(); if ( bHasSelection && !bHasResultSet ) - throw IllegalArgumentException("A result set is needed when specifying a selection to copy.", + throw IllegalArgumentException(u"A result set is needed when specifying a selection to copy."_ustr, // TODO: resource *this, 1); @@ -805,84 +798,84 @@ SharedConnection CopyTableWizard::impl_extractConnection_throw( const Reference< do { - Reference< XPropertySetInfo > xPSI( _rxDataSourceDescriptor->getPropertySetInfo(), UNO_SET_THROW ); + Reference< XPropertySetInfo > xPSI( _rxDataSourceDescriptor->getPropertySetInfo(), UNO_SET_THROW ); - // if there's an ActiveConnection, use it - if ( xPSI->hasPropertyByName( PROPERTY_ACTIVE_CONNECTION ) ) - { - Reference< XConnection > xPure; - OSL_VERIFY( _rxDataSourceDescriptor->getPropertyValue( PROPERTY_ACTIVE_CONNECTION ) >>= xPure ); - xConnection.reset( xPure, SharedConnection::NoTakeOwnership ); - } - if ( xConnection.is() ) - { - xInteractionHandler = lcl_getInteractionHandler_throw( xConnection.getTyped(), m_xInteractionHandler ); - SAL_WARN_IF( !xInteractionHandler.is(), "dbaccess.ui", "CopyTableWizard::impl_extractConnection_throw: lcl_getInteractionHandler_throw returned nonsense!" ); - break; - } - - // there could be a DataSourceName or a DatabaseLocation, describing the css.sdb.DataSource - OUString sDataSource, sDatabaseLocation; - if ( xPSI->hasPropertyByName( PROPERTY_DATASOURCENAME ) ) - OSL_VERIFY( _rxDataSourceDescriptor->getPropertyValue( PROPERTY_DATASOURCENAME ) >>= sDataSource ); - if ( xPSI->hasPropertyByName( PROPERTY_DATABASE_LOCATION ) ) - OSL_VERIFY( _rxDataSourceDescriptor->getPropertyValue( PROPERTY_DATABASE_LOCATION ) >>= sDatabaseLocation ); - - // need a DatabaseContext for loading the data source - Reference< XDatabaseContext > xDatabaseContext = DatabaseContext::create( m_xContext ); - Reference< XDataSource > xDataSource; - if ( !sDataSource.isEmpty() ) - xDataSource.set( xDatabaseContext->getByName( sDataSource ), UNO_QUERY_THROW ); - if ( !xDataSource.is() && !sDatabaseLocation.isEmpty() ) - xDataSource.set( xDatabaseContext->getByName( sDatabaseLocation ), UNO_QUERY_THROW ); - - if ( xDataSource.is() ) - { - // first, try connecting with completion - xInteractionHandler = lcl_getInteractionHandler_throw( xDataSource, m_xInteractionHandler ); - SAL_WARN_IF( !xInteractionHandler.is(), "dbaccess.ui", "CopyTableWizard::impl_extractConnection_throw: lcl_getInteractionHandler_throw returned nonsense!" ); - if ( xInteractionHandler.is() ) + // if there's an ActiveConnection, use it + if ( xPSI->hasPropertyByName( PROPERTY_ACTIVE_CONNECTION ) ) { - Reference< XCompletedConnection > xInteractiveConnection( xDataSource, UNO_QUERY ); - if ( xInteractiveConnection.is() ) - xConnection.reset( xInteractiveConnection->connectWithCompletion( xInteractionHandler ), SharedConnection::TakeOwnership ); + Reference< XConnection > xPure; + OSL_VERIFY( _rxDataSourceDescriptor->getPropertyValue( PROPERTY_ACTIVE_CONNECTION ) >>= xPure ); + xConnection.reset( xPure, SharedConnection::NoTakeOwnership ); } + if ( xConnection.is() ) + { + xInteractionHandler = lcl_getInteractionHandler_throw( xConnection.getTyped(), m_xInteractionHandler ); + SAL_WARN_IF( !xInteractionHandler.is(), "dbaccess.ui", "CopyTableWizard::impl_extractConnection_throw: lcl_getInteractionHandler_throw returned nonsense!" ); + break; + } + + // there could be a DataSourceName or a DatabaseLocation, describing the css.sdb.DataSource + OUString sDataSource, sDatabaseLocation; + if ( xPSI->hasPropertyByName( PROPERTY_DATASOURCENAME ) ) + OSL_VERIFY( _rxDataSourceDescriptor->getPropertyValue( PROPERTY_DATASOURCENAME ) >>= sDataSource ); + if ( xPSI->hasPropertyByName( PROPERTY_DATABASE_LOCATION ) ) + OSL_VERIFY( _rxDataSourceDescriptor->getPropertyValue( PROPERTY_DATABASE_LOCATION ) >>= sDatabaseLocation ); + + // need a DatabaseContext for loading the data source + Reference< XDatabaseContext > xDatabaseContext = DatabaseContext::create( m_xContext ); + Reference< XDataSource > xDataSource; + if ( !sDataSource.isEmpty() ) + xDataSource.set( xDatabaseContext->getByName( sDataSource ), UNO_QUERY_THROW ); + if ( !xDataSource.is() && !sDatabaseLocation.isEmpty() ) + xDataSource.set( xDatabaseContext->getByName( sDatabaseLocation ), UNO_QUERY_THROW ); - // interactively connecting was not successful or possible -> connect without interaction - if ( !xConnection.is() ) + if ( xDataSource.is() ) { - xConnection.reset( xDataSource->getConnection( OUString(), OUString() ), SharedConnection::TakeOwnership ); + // first, try connecting with completion + xInteractionHandler = lcl_getInteractionHandler_throw( xDataSource, m_xInteractionHandler ); + SAL_WARN_IF( !xInteractionHandler.is(), "dbaccess.ui", "CopyTableWizard::impl_extractConnection_throw: lcl_getInteractionHandler_throw returned nonsense!" ); + if ( xInteractionHandler.is() ) + { + Reference< XCompletedConnection > xInteractiveConnection( xDataSource, UNO_QUERY ); + if ( xInteractiveConnection.is() ) + xConnection.reset( xInteractiveConnection->connectWithCompletion( xInteractionHandler ), SharedConnection::TakeOwnership ); + } + + // interactively connecting was not successful or possible -> connect without interaction + if ( !xConnection.is() ) + { + xConnection.reset( xDataSource->getConnection( OUString(), OUString() ), SharedConnection::TakeOwnership ); + } } - } - if ( xConnection.is() ) - break; + if ( xConnection.is() ) + break; - // finally, there could be a ConnectionResource/ConnectionInfo - OUString sConnectionResource; - Sequence< PropertyValue > aConnectionInfo; - if ( xPSI->hasPropertyByName( PROPERTY_CONNECTION_RESOURCE ) ) - OSL_VERIFY( _rxDataSourceDescriptor->getPropertyValue( PROPERTY_CONNECTION_RESOURCE ) >>= sConnectionResource ); - if ( xPSI->hasPropertyByName( PROPERTY_CONNECTION_INFO ) ) - OSL_VERIFY( _rxDataSourceDescriptor->getPropertyValue( PROPERTY_CONNECTION_INFO ) >>= aConnectionInfo ); - - Reference< XDriverManager > xDriverManager; - try { - xDriverManager.set( ConnectionPool::create( m_xContext ), UNO_QUERY_THROW ); - } catch( const Exception& ) { } - if ( !xDriverManager.is() ) - // no connection pool installed - xDriverManager.set( DriverManager::create( m_xContext ), UNO_QUERY_THROW ); - - if ( aConnectionInfo.hasElements() ) - xConnection.set( xDriverManager->getConnectionWithInfo( sConnectionResource, aConnectionInfo ), UNO_SET_THROW ); - else - xConnection.set( xDriverManager->getConnection( sConnectionResource ), UNO_SET_THROW ); + // finally, there could be a ConnectionResource/ConnectionInfo + OUString sConnectionResource; + Sequence< PropertyValue > aConnectionInfo; + if ( xPSI->hasPropertyByName( PROPERTY_CONNECTION_RESOURCE ) ) + OSL_VERIFY( _rxDataSourceDescriptor->getPropertyValue( PROPERTY_CONNECTION_RESOURCE ) >>= sConnectionResource ); + if ( xPSI->hasPropertyByName( PROPERTY_CONNECTION_INFO ) ) + OSL_VERIFY( _rxDataSourceDescriptor->getPropertyValue( PROPERTY_CONNECTION_INFO ) >>= aConnectionInfo ); + + Reference< XDriverManager > xDriverManager; + try { + xDriverManager.set( ConnectionPool::create( m_xContext ), UNO_QUERY_THROW ); + } catch( const Exception& ) { } + if ( !xDriverManager.is() ) + // no connection pool installed + xDriverManager.set( DriverManager::create( m_xContext ), UNO_QUERY_THROW ); + + if ( aConnectionInfo.hasElements() ) + xConnection.set( xDriverManager->getConnectionWithInfo( sConnectionResource, aConnectionInfo ), UNO_SET_THROW ); + else + xConnection.set( xDriverManager->getConnection( sConnectionResource ), UNO_SET_THROW ); } while ( false ); if ( xInteractionHandler != m_xInteractionHandler ) - _out_rxDocInteractionHandler = xInteractionHandler; + _out_rxDocInteractionHandler = std::move(xInteractionHandler); return xConnection; } @@ -891,7 +884,7 @@ SharedConnection CopyTableWizard::impl_extractConnection_throw( const Reference< { OSL_PRECOND( m_xSourceConnection.is(), "CopyTableWizard::impl_createSourceStatement_throw: illegal call!" ); if ( !m_xSourceConnection.is() ) - throw RuntimeException( "CopyTableWizard::impl_createSourceStatement_throw: illegal call!", *const_cast< CopyTableWizard* >( this )); + throw RuntimeException( u"CopyTableWizard::impl_createSourceStatement_throw: illegal call!"_ustr, *const_cast< CopyTableWizard* >( this )); ::utl::SharedUNOComponent< XPreparedStatement > xStatement; switch ( m_nCommandType ) @@ -937,7 +930,7 @@ SharedConnection CopyTableWizard::impl_extractConnection_throw( const Reference< default: // this should not have survived initialization phase - throw RuntimeException("No case matched, this should not have survived the initialization phase", *const_cast< CopyTableWizard* >( this )); + throw RuntimeException(u"No case matched, this should not have survived the initialization phase"_ustr, *const_cast< CopyTableWizard* >( this )); } return xStatement; @@ -948,40 +941,39 @@ namespace class ValueTransfer { public: - ValueTransfer( const sal_Int32& _rSourcePos, const sal_Int32& _rDestPos, const std::vector< sal_Int32 >& _rColTypes, + ValueTransfer( std::vector< sal_Int32 > _rColTypes, const Reference< XRow >& _rxSource, const Reference< XParameters >& _rxDest ) - :m_rSourcePos( _rSourcePos ) - ,m_rDestPos( _rDestPos ) - ,m_rColTypes( _rColTypes ) + :m_ColTypes( std::move(_rColTypes) ) ,m_xSource( _rxSource ) ,m_xDest( _rxDest ) { } template< typename VALUE_TYPE > - void transferValue( VALUE_TYPE ( SAL_CALL XRow::*_pGetter )( sal_Int32 ), + void transferValue( sal_Int32 _nSourcePos, sal_Int32 _nDestPos, + VALUE_TYPE ( SAL_CALL XRow::*_pGetter )( sal_Int32 ), void (SAL_CALL XParameters::*_pSetter)( sal_Int32, VALUE_TYPE ) ) { - VALUE_TYPE value( (m_xSource.get()->*_pGetter)( m_rSourcePos ) ); + VALUE_TYPE value( (m_xSource.get()->*_pGetter)( _nSourcePos ) ); if ( m_xSource->wasNull() ) - m_xDest->setNull( m_rDestPos, m_rColTypes[ m_rSourcePos ] ); + m_xDest->setNull( _nDestPos, m_ColTypes[ _nSourcePos ] ); else - (m_xDest.get()->*_pSetter)( m_rDestPos, value ); + (m_xDest.get()->*_pSetter)( _nDestPos, value ); } - template< typename VALUE_TYPE > - void transferComplexValue( VALUE_TYPE ( SAL_CALL XRow::*_pGetter )( sal_Int32 ), + + template< typename VALUE_TYPE > + void transferComplexValue( sal_Int32 _nSourcePos, sal_Int32 _nDestPos, + VALUE_TYPE ( SAL_CALL XRow::*_pGetter )( sal_Int32 ), void (SAL_CALL XParameters::*_pSetter)( sal_Int32, const VALUE_TYPE& ) ) { - const VALUE_TYPE value( (m_xSource.get()->*_pGetter)( m_rSourcePos ) ); + const VALUE_TYPE value( (m_xSource.get()->*_pGetter)( _nSourcePos ) ); if ( m_xSource->wasNull() ) - m_xDest->setNull( m_rDestPos, m_rColTypes[ m_rSourcePos ] ); + m_xDest->setNull( _nDestPos, m_ColTypes[ _nSourcePos ] ); else - (m_xDest.get()->*_pSetter)( m_rDestPos, value ); + (m_xDest.get()->*_pSetter)( _nDestPos, value ); } private: - const sal_Int32& m_rSourcePos; - const sal_Int32& m_rDestPos; - const std::vector< sal_Int32 > m_rColTypes; + const std::vector< sal_Int32 > m_ColTypes; const Reference< XRow > m_xSource; const Reference< XParameters > m_xDest; }; @@ -989,13 +981,12 @@ namespace bool CopyTableWizard::impl_processCopyError_nothrow( const CopyTableRowEvent& _rEvent ) { - Reference< XCopyTableListener > xListener; try { - ::comphelper::OInterfaceIteratorHelper2 aIter( m_aCopyTableListeners ); + ::comphelper::OInterfaceIteratorHelper3 aIter( m_aCopyTableListeners ); while ( aIter.hasMoreElements() ) { - xListener.set( aIter.next(), UNO_QUERY_THROW ); + Reference< XCopyTableListener > xListener( aIter.next() ); sal_Int16 nListenerChoice = xListener->copyRowError( _rEvent ); switch ( nListenerChoice ) { @@ -1020,35 +1011,31 @@ bool CopyTableWizard::impl_processCopyError_nothrow( const CopyTableRowEvent& _r try { - SQLContext aError; - aError.Context = *this; - aError.Message = DBA_RES(STR_ERROR_OCCURRED_WHILE_COPYING); - + css::uno::Any next; ::dbtools::SQLExceptionInfo aInfo( _rEvent.Error ); if ( aInfo.isValid() ) - aError.NextException = _rEvent.Error; + next = _rEvent.Error; else { // a non-SQL exception happened Exception aException; OSL_VERIFY( _rEvent.Error >>= aException ); - SQLContext aContext; - aContext.Context = aException.Context; - aContext.Message = aException.Message; - aContext.Details = _rEvent.Error.getValueTypeName(); - aError.NextException <<= aContext; + SQLContext aContext(aException.Message, aException.Context, {}, 0, {}, + _rEvent.Error.getValueTypeName()); + next <<= aContext; } + SQLContext aError(DBA_RES(STR_ERROR_OCCURRED_WHILE_COPYING), *this, {}, 0, next, {}); - ::rtl::Reference< ::comphelper::OInteractionRequest > xRequest( new ::comphelper::OInteractionRequest( makeAny( aError ) ) ); + ::rtl::Reference< ::comphelper::OInteractionRequest > xRequest( new ::comphelper::OInteractionRequest( Any( aError ) ) ); ::rtl::Reference< ::comphelper::OInteractionApprove > xYes = new ::comphelper::OInteractionApprove; - xRequest->addContinuation( xYes.get() ); + xRequest->addContinuation( xYes ); xRequest->addContinuation( new ::comphelper::OInteractionDisapprove ); OSL_ENSURE( m_xInteractionHandler.is(), "CopyTableWizard::impl_processCopyError_nothrow: we always should have an interaction handler!" ); if ( m_xInteractionHandler.is() ) - m_xInteractionHandler->handle( xRequest.get() ); + m_xInteractionHandler->handle( xRequest ); if ( xYes->wasSelected() ) // continue copying @@ -1068,12 +1055,13 @@ void CopyTableWizard::impl_copyRows_throw( const Reference< XResultSet >& _rxSou { OSL_PRECOND( m_xDestConnection.is(), "CopyTableWizard::impl_copyRows_throw: illegal call!" ); if ( !m_xDestConnection.is() ) - throw RuntimeException( "m_xDestConnection is set to null, CopyTableWizard::impl_copyRows_throw: illegal call!", *this ); + throw RuntimeException( u"m_xDestConnection is set to null, CopyTableWizard::impl_copyRows_throw: illegal call!"_ustr, *this ); Reference< XDatabaseMetaData > xDestMetaData( m_xDestConnection->getMetaData(), UNO_SET_THROW ); const OCopyTableWizard& rWizard = impl_getDialog_throw(); ODatabaseExport::TPositions aColumnPositions = rWizard.GetColumnPositions(); + const bool bShouldCreatePrimaryKey = rWizard.shouldCreatePrimaryKey(); Reference< XRow > xRow ( _rxSourceResultSet, UNO_QUERY_THROW ); Reference< XRowLocate > xRowLocate ( _rxSourceResultSet, UNO_QUERY_THROW ); @@ -1098,12 +1086,12 @@ void CopyTableWizard::impl_copyRows_throw( const Reference< XResultSet >& _rxSou } // now create, fill and execute the prepared statement - Reference< XPreparedStatement > xStatement( ODatabaseExport::createPreparedStatment( xDestMetaData, _rxDestTable, aColumnPositions ), UNO_SET_THROW ); + Reference< XPreparedStatement > xStatement( ODatabaseExport::createPreparedStatement( xDestMetaData, _rxDestTable, aColumnPositions ), UNO_SET_THROW ); Reference< XParameters > xStatementParams( xStatement, UNO_QUERY_THROW ); const bool bSelectedRecordsOnly = m_aSourceSelection.hasElements(); - const Any* pSelectedRow = m_aSourceSelection.getConstArray(); - const Any* pSelEnd = pSelectedRow + m_aSourceSelection.getLength(); + const Any* pSelectedRow = m_aSourceSelection.begin(); + const Any* pSelEnd = m_aSourceSelection.end(); sal_Int32 nRowCount = 0; bool bContinue = false; @@ -1145,16 +1133,16 @@ void CopyTableWizard::impl_copyRows_throw( const Reference< XResultSet >& _rxSou aCopyEvent.Error.clear(); try { + bool bInsertedPrimaryKey = false; // notify listeners m_aCopyTableListeners.notifyEach( &XCopyTableListener::copyingRow, aCopyEvent ); - sal_Int32 nDestColumn( 0 ); sal_Int32 nSourceColumn( 1 ); - ValueTransfer aTransfer( nSourceColumn, nDestColumn, aSourceColTypes, xRow, xStatementParams ); + ValueTransfer aTransfer( aSourceColTypes, xRow, xStatementParams ); for ( auto const& rColumnPos : aColumnPositions ) { - nDestColumn = rColumnPos.first; + sal_Int32 nDestColumn = rColumnPos.first; if ( nDestColumn == COLUMN_POSITION_NOT_FOUND ) { ++nSourceColumn; @@ -1162,9 +1150,17 @@ void CopyTableWizard::impl_copyRows_throw( const Reference< XResultSet >& _rxSou continue; } - if ( ( nSourceColumn < 1 ) || ( nSourceColumn >= static_cast<sal_Int32>(aSourceColTypes.size()) ) ) + if ( bShouldCreatePrimaryKey && !bInsertedPrimaryKey ) + { + xStatementParams->setInt( 1, nRowCount ); + ++nSourceColumn; + bInsertedPrimaryKey = true; + continue; + } + + if ( ( nSourceColumn < 1 ) || ( o3tl::make_unsigned(nSourceColumn) >= aSourceColTypes.size() ) ) { // ( we have to check here against 1 because the parameters are 1 based) - ::dbtools::throwSQLException("Internal error: invalid column type index.", + ::dbtools::throwSQLException(u"Internal error: invalid column type index."_ustr, ::dbtools::StandardSQLState::INVALID_DESCRIPTOR_INDEX, *this); } @@ -1172,7 +1168,7 @@ void CopyTableWizard::impl_copyRows_throw( const Reference< XResultSet >& _rxSou { case DataType::DOUBLE: case DataType::REAL: - aTransfer.transferValue( &XRow::getDouble, &XParameters::setDouble ); + aTransfer.transferValue( nSourceColumn, nDestColumn, &XRow::getDouble, &XParameters::setDouble ); break; case DataType::CHAR: @@ -1180,64 +1176,64 @@ void CopyTableWizard::impl_copyRows_throw( const Reference< XResultSet >& _rxSou case DataType::LONGVARCHAR: case DataType::DECIMAL: case DataType::NUMERIC: - aTransfer.transferComplexValue( &XRow::getString, &XParameters::setString ); + aTransfer.transferComplexValue( nSourceColumn, nDestColumn, &XRow::getString, &XParameters::setString ); break; case DataType::BIGINT: - aTransfer.transferValue( &XRow::getLong, &XParameters::setLong ); + aTransfer.transferValue( nSourceColumn, nDestColumn, &XRow::getLong, &XParameters::setLong ); break; case DataType::FLOAT: - aTransfer.transferValue( &XRow::getFloat, &XParameters::setFloat ); + aTransfer.transferValue( nSourceColumn, nDestColumn, &XRow::getFloat, &XParameters::setFloat ); break; case DataType::LONGVARBINARY: case DataType::BINARY: case DataType::VARBINARY: - aTransfer.transferComplexValue( &XRow::getBytes, &XParameters::setBytes ); + aTransfer.transferComplexValue( nSourceColumn, nDestColumn, &XRow::getBytes, &XParameters::setBytes ); break; case DataType::DATE: - aTransfer.transferComplexValue( &XRow::getDate, &XParameters::setDate ); + aTransfer.transferComplexValue( nSourceColumn, nDestColumn, &XRow::getDate, &XParameters::setDate ); break; case DataType::TIME: - aTransfer.transferComplexValue( &XRow::getTime, &XParameters::setTime ); + aTransfer.transferComplexValue( nSourceColumn, nDestColumn, &XRow::getTime, &XParameters::setTime ); break; case DataType::TIMESTAMP: - aTransfer.transferComplexValue( &XRow::getTimestamp, &XParameters::setTimestamp ); + aTransfer.transferComplexValue( nSourceColumn, nDestColumn, &XRow::getTimestamp, &XParameters::setTimestamp ); break; case DataType::BIT: if ( aSourcePrec[nSourceColumn] > 1 ) { - aTransfer.transferComplexValue( &XRow::getBytes, &XParameters::setBytes ); + aTransfer.transferComplexValue( nSourceColumn, nDestColumn, &XRow::getBytes, &XParameters::setBytes ); break; } [[fallthrough]]; case DataType::BOOLEAN: - aTransfer.transferValue( &XRow::getBoolean, &XParameters::setBoolean ); + aTransfer.transferValue( nSourceColumn, nDestColumn, &XRow::getBoolean, &XParameters::setBoolean ); break; case DataType::TINYINT: - aTransfer.transferValue( &XRow::getByte, &XParameters::setByte ); + aTransfer.transferValue( nSourceColumn, nDestColumn, &XRow::getByte, &XParameters::setByte ); break; case DataType::SMALLINT: - aTransfer.transferValue( &XRow::getShort, &XParameters::setShort ); + aTransfer.transferValue( nSourceColumn, nDestColumn, &XRow::getShort, &XParameters::setShort ); break; case DataType::INTEGER: - aTransfer.transferValue( &XRow::getInt, &XParameters::setInt ); + aTransfer.transferValue( nSourceColumn, nDestColumn, &XRow::getInt, &XParameters::setInt ); break; case DataType::BLOB: - aTransfer.transferComplexValue( &XRow::getBlob, &XParameters::setBlob ); + aTransfer.transferComplexValue( nSourceColumn, nDestColumn, &XRow::getBlob, &XParameters::setBlob ); break; case DataType::CLOB: - aTransfer.transferComplexValue( &XRow::getClob, &XParameters::setClob ); + aTransfer.transferComplexValue( nSourceColumn, nDestColumn, &XRow::getClob, &XParameters::setClob ); break; default: @@ -1263,6 +1259,7 @@ void CopyTableWizard::impl_copyRows_throw( const Reference< XResultSet >& _rxSou } catch( const Exception& ) { + TOOLS_WARN_EXCEPTION("dbaccess", ""); aCopyEvent.Error = ::cppu::getCaughtException(); } @@ -1354,6 +1351,53 @@ void CopyTableWizard::impl_doCopy_nothrow() if ( xSourceResultSet.is() ) impl_copyRows_throw( xSourceResultSet, xTable ); + + // tdf#119962 + const Reference< XDatabaseMetaData > xDestMetaData( m_xDestConnection->getMetaData(), UNO_SET_THROW ); + OUString sDatabaseDest = xDestMetaData->getDatabaseProductName().toAsciiLowerCase(); + // If we created a new primary key, then it won't necessarily be an IDENTITY column + const bool bShouldCreatePrimaryKey = rWizard.shouldCreatePrimaryKey(); + if ( !bShouldCreatePrimaryKey && (sDatabaseDest.indexOf("firebird") != -1) ) + { + const OUString sComposedTableName = ::dbtools::composeTableName( xDestMetaData, xTable, ::dbtools::EComposeRule::InDataManipulation, true ); + + OUString aSchema,aTable; + xTable->getPropertyValue(u"SchemaName"_ustr) >>= aSchema; + xTable->getPropertyValue(u"Name"_ustr) >>= aTable; + Any aCatalog = xTable->getPropertyValue(u"CatalogName"_ustr); + + const Reference< XResultSet > xResultPKCL(xDestMetaData->getPrimaryKeys(aCatalog,aSchema,aTable)); + Reference< XRow > xRowPKCL(xResultPKCL, UNO_QUERY_THROW); + OUString sPKCL; + if ( xRowPKCL.is() ) + { + if (xResultPKCL->next()) + { + sPKCL = xRowPKCL->getString(4); + } + } + + if (!sPKCL.isEmpty()) + { + OUString strSql = "SELECT MAX(\"" + sPKCL + "\") FROM " + sComposedTableName; + + Reference< XResultSet > xResultMAXNUM(m_xDestConnection->createStatement()->executeQuery(strSql)); + Reference< XRow > xRow(xResultMAXNUM, UNO_QUERY_THROW); + + sal_Int64 maxVal = -1L; + if (xResultMAXNUM->next()) + { + maxVal = xRow->getLong(1); + } + + if (maxVal > 0L) + { + strSql = "ALTER TABLE " + sComposedTableName + " ALTER \"" + sPKCL + "\" RESTART WITH " + OUString::number(maxVal + 1); + + m_xDestConnection->createStatement()->execute(strSql); + } + } + } } break; @@ -1369,6 +1413,7 @@ void CopyTableWizard::impl_doCopy_nothrow() catch( const Exception& ) { aError = ::cppu::getCaughtException(); + SAL_WARN("dbaccess", exceptionToString(aError)); // silence the error of the user cancelling the parameter's dialog SQLException aSQLError; @@ -1384,7 +1429,7 @@ void CopyTableWizard::impl_doCopy_nothrow() try { ::rtl::Reference< ::comphelper::OInteractionRequest > xRequest( new ::comphelper::OInteractionRequest( aError ) ); - m_xInteractionHandler->handle( xRequest.get() ); + m_xInteractionHandler->handle( xRequest ); } catch( const Exception& ) { @@ -1407,11 +1452,11 @@ OUString CopyTableWizard::impl_getServerSideCopyStatement_throw(const Reference< { if ( !sColumns.isEmpty() ) sColumns.append(","); - sColumns.append(sQuote).append(aDestColumnNames[rColumnPositionPair.second - 1]).append(sQuote); + sColumns.append(sQuote + aDestColumnNames[rColumnPositionPair.second - 1] + sQuote); } } const OUString sComposedTableName = ::dbtools::composeTableName( xDestMetaData, _xTable, ::dbtools::EComposeRule::InDataManipulation, true ); - OUString sSql("INSERT INTO " + sComposedTableName + " ( " + sColumns.makeStringAndClear() + " ) " + m_pSourceObject->getSelectStatement()); + OUString sSql("INSERT INTO " + sComposedTableName + " ( " + sColumns + " ) " + m_pSourceObject->getSelectStatement()); return sSql; } @@ -1454,12 +1499,12 @@ void SAL_CALL CopyTableWizard::initialize( const Sequence< Any >& _rArguments ) impl_ensureDataAccessDescriptor_throw( _rArguments, 1, m_xDestConnection, xDestDocHandler ); if ( xDestDocHandler.is() && !m_xInteractionHandler.is() ) - m_xInteractionHandler = xDestDocHandler; + m_xInteractionHandler = std::move(xDestDocHandler); Reference< XPropertySet > xInteractionHandler(m_xInteractionHandler, UNO_QUERY); if (xInteractionHandler.is()) { - Any aParentWindow(xInteractionHandler->getPropertyValue("ParentWindow")); + Any aParentWindow(xInteractionHandler->getPropertyValue(u"ParentWindow"_ustr)); aParentWindow >>= m_xParent; } } |