using ::com::sun::star::uno::Reference; using ::com::sun::star::uno::XInterface; using ::com::sun::star::uno::UNO_QUERY; using ::com::sun::star::uno::UNO_QUERY_THROW; using ::com::sun::star::uno::UNO_SET_THROW; using ::com::sun::star::uno::Exception; using ::com::sun::star::uno::RuntimeException; using ::com::sun::star::uno::Any; using ::com::sun::star::uno::Sequence; using ::com::sun::star::uno::XComponentContext; using ::com::sun::star::beans::XPropertySetInfo; using ::com::sun::star::lang::XMultiServiceFactory; using ::com::sun::star::beans::Property; using ::com::sun::star::sdb::application::XCopyTableWizard; using ::com::sun::star::sdb::application::XCopyTableListener; using ::com::sun::star::sdb::application::CopyTableRowEvent; using ::com::sun::star::beans::Optional; using ::com::sun::star::lang::IllegalArgumentException; using ::com::sun::star::ucb::AlreadyInitializedException; using ::com::sun::star::beans::XPropertySet; using ::com::sun::star::lang::NotInitializedException; using ::com::sun::star::lang::XServiceInfo; using ::com::sun::star::sdbc::XConnection; using ::com::sun::star::sdbc::XDataSource; using ::com::sun::star::container::XNameAccess; using ::com::sun::star::container::XChild; using ::com::sun::star::task::InteractionHandler; using ::com::sun::star::task::XInteractionHandler; using ::com::sun::star::frame::XModel; using ::com::sun::star::sdb::DatabaseContext; using ::com::sun::star::sdb::XDatabaseContext; using ::com::sun::star::sdb::XDocumentDataSource; using ::com::sun::star::sdb::XCompletedConnection; using ::com::sun::star::lang::WrappedTargetException; using ::com::sun::star::sdbcx::XTablesSupplier; using ::com::sun::star::sdb::XQueriesSupplier; using ::com::sun::star::lang::DisposedException; using ::com::sun::star::sdbc::XPreparedStatement; using ::com::sun::star::sdb::XSingleSelectQueryComposer; using ::com::sun::star::sdbc::XDatabaseMetaData; using ::com::sun::star::sdbcx::XColumnsSupplier; using ::com::sun::star::sdbc::XParameters; using ::com::sun::star::sdbc::XResultSet; using ::com::sun::star::sdbc::XRow; using ::com::sun::star::sdbcx::XRowLocate; using ::com::sun::star::sdbc::XResultSetMetaDataSupplier; using ::com::sun::star::sdbc::XResultSetMetaData; using ::com::sun::star::sdbc::SQLException; using ::com::sun::star::sdb::SQLContext; using ::com::sun::star::sdbc::ConnectionPool; using ::com::sun::star::sdbc::XDriverManager; using ::com::sun::star::sdbc::DriverManager; using ::com::sun::star::beans::PropertyValue;
private: /// ensures our current attribute values are reflected in the dialog void impl_attributesToDialog_nothrow( OCopyTableWizard& _rDialog ) const;
/// ensures the current dialog settings are reflected in our attributes void impl_dialogToAttributes_nothrow( const OCopyTableWizard& _rDialog );
/** ensures the given argument sequence contains a valid data access descriptor at the given position @param_rAllArgs theargumentsaspassedto->initialize @param_nArgPos thepositionwithin->_rAllArgswhichcontainsthedataaccessdescriptor @param_out_rxConnection will,uponsuccessfulreturn,containtheconnectionforthedatasource @param_out_rxDocInteractionHandler will,uponsuccessfulreturn,containtheinteractionhandlerwhichcould bededucedfromdatabasedocumentdescribedbythedescriptor,ifany. (Itispossiblethatthedescriptordoesnotallowtodeduceadatabasedocument, inwhichcase<code>_out_rxDocInteractionHandler</code>willbe<NULL/>.) @returnthedataaccessdescriptor
*/
Reference< XPropertySet >
impl_ensureDataAccessDescriptor_throw( const Sequence< Any >& _rAllArgs, const sal_Int16 _nArgPos,
SharedConnection& _out_rxConnection,
Reference< XInteractionHandler >& _out_rxDocInteractionHandler
) const;
/** extracts the source object (table or query) described by the given descriptor, relativetom_xSourceConnection
*/
std::unique_ptr< ICopyTableSourceObject >
impl_extractSourceObject_throw( const Reference< XPropertySet >& _rxDescriptor,
sal_Int32& _out_rCommandType
) const;
/** extracts the result set to copy records from, and the selection-related aspects, if any.
/** copies the data rows from the given source result set to the given destination table
*/ void impl_copyRows_throw( const Reference< XResultSet >& _rxSourceResultSet, const Reference< XPropertySet >& _rxDestTable
);
/** processes an error which occurred during copying
// TODO: shouldn't we have explicit disposal support? If a listener is registered // at our instance, and perhaps holds this our instance by a hard ref, then we'll never // be destroyed. // However, adding XComponent support to the GenericUNODialog probably requires // some thinking - would it break existing clients which do not call a dispose, then?
}
// try to obtain the document model
Reference< XModel > xDocumentModel;
Reference< XDocumentDataSource > xDocDataSource( _rxDataSource, UNO_QUERY ); if ( xDocDataSource.is() )
xDocumentModel.set( xDocDataSource->getDatabaseDocument(), UNO_QUERY_THROW );
// see whether the document model can provide a handler if ( xDocumentModel.is() )
{
xHandler = ::comphelper::NamedValueCollection::getOrDefault( xDocumentModel->getArgs(), u"InteractionHandler", xHandler );
}
return xHandler;
} /** tries to obtain the InteractionHandler associated with a given connection
// the descriptor must be non-NULL, of course bool bIsValid = xDescriptor.is();
// it must support the proper service if ( bIsValid )
{
Reference< XServiceInfo > xSI( xDescriptor, UNO_QUERY );
bIsValid = ( xSI.is()
&& xSI->supportsService( u"com.sun.star.sdb.DataAccessDescriptor"_ustr ) );
}
// it must be able to provide a connection if ( bIsValid )
{
_out_rxConnection = impl_extractConnection_throw( xDescriptor, _out_rxDocInteractionHandler );
bIsValid = _out_rxConnection.is();
}
if ( !bIsValid )
{ throw IllegalArgumentException(
DBA_RES( STR_CTW_INVALID_DATA_ACCESS_DESCRIPTOR ),
*const_cast< CopyTableWizard* >( this ),
_nArgPos + 1
);
}
if ( xContainer.is() )
{
pSourceObject.reset( new ObjectCopySource( m_xSourceConnection,
Reference< XPropertySet >( xContainer->getByName( sCommand ), UNO_QUERY_THROW ) ) );
} else
{ // our source connection is an SDBC level connection only, not a SDBCX level one // Which means it cannot provide the to-be-copied object as component.
if ( _out_rCommandType == CommandType::QUERY ) // we cannot copy a query if the connection cannot provide it ... throw IllegalArgumentException(
DBA_RES( STR_CTW_ERROR_NO_QUERY ),
*const_cast< CopyTableWizard* >( this ), 1
);
pSourceObject.reset( new NamedTableCopySource( m_xSourceConnection, sCommand ) );
}
// sanity checks constbool bHasResultSet = m_xSourceResultSet.is(); constbool bHasSelection = m_aSourceSelection.hasElements(); if ( bHasSelection && !bHasResultSet ) throw IllegalArgumentException(u"A result set is needed when specifying a selection to copy."_ustr, // TODO: resource
*this, 1);
do
{
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() )
{
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;
// 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 );
// check whether we have to fill in parameter values // create and fill a composer
Reference< XMultiServiceFactory > xFactory( m_xSourceConnection, UNO_QUERY );
::utl::SharedUNOComponent< XSingleSelectQueryComposer > xComposer; if ( xFactory.is() ) // note: connections below the sdb-level are allowed to not support the XMultiServiceFactory interface
xComposer.set( xFactory->createInstance( SERVICE_NAME_SINGLESELECTQUERYCOMPOSER ), UNO_QUERY );
if ( xComposer.is() )
{
xComposer->setQuery( sQueryCommand );
Reference< XParameters > xStatementParams( xStatement, UNO_QUERY );
OSL_ENSURE( xStatementParams.is(), "CopyTableWizard::impl_createSourceStatement_throw: no access to the statement's parameters!" ); // the statement should be a css.sdbc.PreparedStatement (this is what // we created), and a prepared statement is required to support XParameters if ( xStatementParams.is() )
{
OSL_ENSURE( m_xInteractionHandler.is(), "CopyTableWizard::impl_createSourceStatement_throw: no interaction handler for the parameters request!" ); // we should always have an interaction handler - as last fallback, we create an own one in ::initialize
default: // this should not have survived initialization phase throw RuntimeException(u"No case matched, this should not have survived the initialization phase"_ustr, *const_cast< CopyTableWizard* >( this ));
}
::rtl::Reference< ::comphelper::OInteractionApprove > xYes = new ::comphelper::OInteractionApprove;
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 );
// we need a vector which all types
sal_Int32 nCount = xMeta->getColumnCount();
std::vector< sal_Int32 > aSourceColTypes;
aSourceColTypes.reserve( nCount + 1 );
aSourceColTypes.push_back( -1 ); // just to avoid an every time i-1 call
std::vector< sal_Int32 > aSourcePrec;
aSourcePrec.reserve( nCount + 1 );
aSourcePrec.push_back( -1 ); // just to avoid an every time i-1 call
for ( sal_Int32 k=1; k <= nCount; ++k )
{
aSourceColTypes.push_back( xMeta->getColumnType( k ) );
aSourcePrec.push_back( xMeta->getPrecision( k ) );
}
// now create, fill and execute the prepared statement
Reference< XPreparedStatement > xStatement( ODatabaseExport::createPreparedStatement( xDestMetaData, _rxDestTable, aColumnPositions ), UNO_SET_THROW );
Reference< XParameters > xStatementParams( xStatement, UNO_QUERY_THROW );
for ( autoconst& rColumnPos : aColumnPositions )
{
sal_Int32 nDestColumn = rColumnPos.first; if ( nDestColumn == COLUMN_POSITION_NOT_FOUND )
{
++nSourceColumn; // otherwise we don't get the correct value when only the 2nd source column was selected 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(u"Internal error: invalid column type index."_ustr,
::dbtools::StandardSQLState::INVALID_DESCRIPTOR_INDEX, *this);
}
switch ( aSourceColTypes[ nSourceColumn ] )
{ case DataType::DOUBLE: case DataType::REAL:
aTransfer.transferValue( nSourceColumn, nDestColumn, &XRow::getDouble, &XParameters::setDouble ); break;
case DataType::CHAR: case DataType::VARCHAR: case DataType::LONGVARCHAR: case DataType::DECIMAL: case DataType::NUMERIC:
aTransfer.transferComplexValue( nSourceColumn, nDestColumn, &XRow::getString, &XParameters::setString ); break;
case DataType::BIGINT:
aTransfer.transferValue( nSourceColumn, nDestColumn, &XRow::getLong, &XParameters::setLong ); break;
case DataType::FLOAT:
aTransfer.transferValue( nSourceColumn, nDestColumn, &XRow::getFloat, &XParameters::setFloat ); break;
case DataType::LONGVARBINARY: case DataType::BINARY: case DataType::VARBINARY:
aTransfer.transferComplexValue( nSourceColumn, nDestColumn, &XRow::getBytes, &XParameters::setBytes ); break;
case DataType::DATE:
aTransfer.transferComplexValue( nSourceColumn, nDestColumn, &XRow::getDate, &XParameters::setDate ); break;
case DataType::TIME:
aTransfer.transferComplexValue( nSourceColumn, nDestColumn, &XRow::getTime, &XParameters::setTime ); break;
case DataType::TIMESTAMP:
aTransfer.transferComplexValue( nSourceColumn, nDestColumn, &XRow::getTimestamp, &XParameters::setTimestamp ); break;
case DataType::BIT: if ( aSourcePrec[nSourceColumn] > 1 )
{
aTransfer.transferComplexValue( nSourceColumn, nDestColumn, &XRow::getBytes, &XParameters::setBytes ); break;
}
[[fallthrough]]; case DataType::BOOLEAN:
aTransfer.transferValue( nSourceColumn, nDestColumn, &XRow::getBoolean, &XParameters::setBoolean ); break;
case DataType::TINYINT:
aTransfer.transferValue( nSourceColumn, nDestColumn, &XRow::getByte, &XParameters::setByte ); break;
case DataType::SMALLINT:
aTransfer.transferValue( nSourceColumn, nDestColumn, &XRow::getShort, &XParameters::setShort ); break;
case DataType::INTEGER:
aTransfer.transferValue( nSourceColumn, nDestColumn, &XRow::getInt, &XParameters::setInt ); break;
case DataType::BLOB:
aTransfer.transferComplexValue( nSourceColumn, nDestColumn, &XRow::getBlob, &XParameters::setBlob ); break;
case DataType::CLOB:
aTransfer.transferComplexValue( nSourceColumn, nDestColumn, &XRow::getClob, &XParameters::setClob ); break;
std::unique_ptr<weld::DialogController> CopyTableWizard::createDialog(const css::uno::Reference<css::awt::XWindow>& rParent)
{
OSL_PRECOND( isInitialized(), "CopyTableWizard::createDialog: not initialized!" ); // this should have been prevented in ::execute already
if ( _nExecutionResult == RET_OK )
impl_doCopy_nothrow();
// do this after impl_doCopy_nothrow: The attributes may change during copying, for instance // if the user entered an unqualified table name
impl_dialogToAttributes_nothrow( impl_getDialog_throw() );
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Angebot
Hier finden Sie eine Liste der Produkte des Unternehmens