diff options
Diffstat (limited to 'dbaccess/source/ui/uno/copytablewizard.cxx')
-rw-r--r-- | dbaccess/source/ui/uno/copytablewizard.cxx | 171 |
1 files changed, 91 insertions, 80 deletions
diff --git a/dbaccess/source/ui/uno/copytablewizard.cxx b/dbaccess/source/ui/uno/copytablewizard.cxx index 51420d74995c..880600342dea 100644 --- a/dbaccess/source/ui/uno/copytablewizard.cxx +++ b/dbaccess/source/ui/uno/copytablewizard.cxx @@ -60,11 +60,12 @@ #include <cppuhelper/exc_hlp.hxx> #include <cppuhelper/implbase.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; @@ -572,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; @@ -660,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) { @@ -942,40 +941,39 @@ namespace class ValueTransfer { public: - ValueTransfer( const sal_Int32& _rSourcePos, const sal_Int32& _rDestPos, 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( std::move(_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; }; @@ -1013,26 +1011,22 @@ 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 ); @@ -1067,6 +1061,7 @@ void CopyTableWizard::impl_copyRows_throw( const Reference< XResultSet >& _rxSou 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 ); @@ -1091,7 +1086,7 @@ 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(); @@ -1138,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, std::vector(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; @@ -1155,7 +1150,15 @@ 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::StandardSQLState::INVALID_DESCRIPTOR_INDEX, *this); @@ -1165,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: @@ -1173,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: @@ -1256,6 +1259,7 @@ void CopyTableWizard::impl_copyRows_throw( const Reference< XResultSet >& _rxSou } catch( const Exception& ) { + TOOLS_WARN_EXCEPTION("dbaccess", ""); aCopyEvent.Error = ::cppu::getCaughtException(); } @@ -1350,42 +1354,48 @@ void CopyTableWizard::impl_doCopy_nothrow() // tdf#119962 const Reference< XDatabaseMetaData > xDestMetaData( m_xDestConnection->getMetaData(), UNO_SET_THROW ); - const OUString sComposedTableName = ::dbtools::composeTableName( xDestMetaData, xTable, ::dbtools::EComposeRule::InDataManipulation, true ); + 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("SchemaName") >>= aSchema; - xTable->getPropertyValue("Name") >>= aTable; - Any aCatalog = xTable->getPropertyValue("CatalogName"); + OUString aSchema,aTable; + xTable->getPropertyValue("SchemaName") >>= aSchema; + xTable->getPropertyValue("Name") >>= aTable; + Any aCatalog = xTable->getPropertyValue("CatalogName"); - const Reference< XResultSet > xResultPKCL(xDestMetaData->getPrimaryKeys(aCatalog,aSchema,aTable)); - Reference< XRow > xRowPKCL(xResultPKCL, UNO_QUERY_THROW); - OUString sPKCL; - if ( xRowPKCL.is() ) - { - if (xResultPKCL->next()) + const Reference< XResultSet > xResultPKCL(xDestMetaData->getPrimaryKeys(aCatalog,aSchema,aTable)); + Reference< XRow > xRowPKCL(xResultPKCL, UNO_QUERY_THROW); + OUString sPKCL; + if ( xRowPKCL.is() ) { - sPKCL = xRowPKCL->getString(4); + if (xResultPKCL->next()) + { + sPKCL = xRowPKCL->getString(4); + } } - } - if (!sPKCL.isEmpty()) - { - OUString strSql = "SELECT MAX(\"" + sPKCL + "\") FROM " + sComposedTableName; + 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); + 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); - } + 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); + if (maxVal > 0L) + { + strSql = "ALTER TABLE " + sComposedTableName + " ALTER \"" + sPKCL + "\" RESTART WITH " + OUString::number(maxVal + 1); - m_xDestConnection->createStatement()->execute(strSql); + m_xDestConnection->createStatement()->execute(strSql); + } } } } @@ -1403,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; @@ -1445,7 +1456,7 @@ OUString CopyTableWizard::impl_getServerSideCopyStatement_throw(const Reference< } } 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; } |