/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/


// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_dbui.hxx"

#include "dbu_reghelper.hxx"
#include "dbu_resource.hrc"
#include "dbu_uno.hrc"
#include "dbustrings.hrc"
#include "moduledbu.hxx"
#include "sqlmessage.hxx"
#include "WCopyTable.hxx"

/** === begin UNO includes === **/
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/sdb/application/XCopyTableWizard.hpp>
#include <com/sun/star/sdb/application/CopyTableContinuation.hpp>
#include <com/sun/star/sdb/application/CopyTableOperation.hpp>
#include <com/sun/star/ucb/AlreadyInitializedException.hpp>
#include <com/sun/star/lang/NotInitializedException.hpp>
#include <com/sun/star/sdbc/XDataSource.hpp>
#include <com/sun/star/sdbc/DataType.hpp>
#include <com/sun/star/container/XNameAccess.hpp>
#include <com/sun/star/container/XChild.hpp>
#include <com/sun/star/task/XInteractionHandler.hpp>
#include <com/sun/star/frame/XModel.hpp>
#include <com/sun/star/sdb/XDocumentDataSource.hpp>
#include <com/sun/star/sdb/XCompletedConnection.hpp>
#include <com/sun/star/sdb/CommandType.hpp>
#include <com/sun/star/sdbcx/XTablesSupplier.hpp>
#include <com/sun/star/sdb/XQueriesSupplier.hpp>
#include <com/sun/star/lang/DisposedException.hpp>
#include <com/sun/star/sdb/XSingleSelectQueryComposer.hpp>
#include <com/sun/star/sdbc/XParameters.hpp>
#include <com/sun/star/sdbc/XRow.hpp>
#include <com/sun/star/sdbc/XBlob.hpp>
#include <com/sun/star/sdbc/XClob.hpp>
#include <com/sun/star/sdbcx/XRowLocate.hpp>
#include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp>
#include <com/sun/star/sdb/SQLContext.hpp>
#include <com/sun/star/sdbc/XDriverManager.hpp>
/** === end UNO includes === **/

#include <comphelper/componentcontext.hxx>
#include <comphelper/interaction.hxx>
#include <comphelper/namedvaluecollection.hxx>
#include <comphelper/proparrhlp.hxx>
#include <comphelper/string.hxx>
#include <connectivity/dbexception.hxx>
#include <connectivity/dbtools.hxx>
#include <cppuhelper/exc_hlp.hxx>
#include <cppuhelper/implbase1.hxx>
#include <rtl/ustrbuf.hxx>
#include <rtl/logfile.hxx>
#include <svtools/genericunodialog.hxx>
#include <tools/diagnose_ex.h>
#include <unotools/sharedunocomponent.hxx>
#include <vcl/msgbox.hxx>
#include <vcl/waitobj.hxx>

//........................................................................
namespace dbaui
{
//........................................................................

	/** === begin UNO using === **/
	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::makeAny;
    using ::com::sun::star::uno::Sequence;
    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::XInteractionHandler;
    using ::com::sun::star::frame::XModel;
    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::sdbc::XBlob;
	using ::com::sun::star::sdbc::XClob;
    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::XDriverManager;
    using ::com::sun::star::beans::PropertyValue;
	/** === end UNO using === **/
    namespace CopyTableOperation = ::com::sun::star::sdb::application::CopyTableOperation;
    namespace CopyTableContinuation = ::com::sun::star::sdb::application::CopyTableContinuation;
    namespace CommandType = ::com::sun::star::sdb::CommandType;
    namespace DataType = ::com::sun::star::sdbc::DataType;

    typedef ::utl::SharedUNOComponent< XConnection >    SharedConnection;
    typedef Reference< XInteractionHandler >            InteractionHandler;

    //=========================================================================
    //= CopyTableWizard
    //=========================================================================
    typedef ::svt::OGenericUnoDialog        CopyTableWizard_DialogBase;
    typedef ::cppu::ImplInheritanceHelper1  <   CopyTableWizard_DialogBase
                                            ,   XCopyTableWizard
                                            >   CopyTableWizard_Base;
    class CopyTableWizard
            :public CopyTableWizard_Base
		    ,public ::comphelper::OPropertyArrayUsageHelper< CopyTableWizard >
    {
    public:
	    // XServiceInfo
	    virtual ::rtl::OUString SAL_CALL getImplementationName() throw(RuntimeException);
	    virtual ::comphelper::StringSequence SAL_CALL getSupportedServiceNames() throw(RuntimeException);

	    // XServiceInfo - static methods
	    static Sequence< ::rtl::OUString >  getSupportedServiceNames_Static(void) throw( RuntimeException );
	    static ::rtl::OUString              getImplementationName_Static(void) throw( RuntimeException );
	    static Reference< XInterface >      Create( const Reference< XMultiServiceFactory >& );

        // XCopyTableWizard
        virtual ::sal_Int16 SAL_CALL getOperation() throw (RuntimeException);
        virtual void SAL_CALL setOperation( ::sal_Int16 _operation ) throw (IllegalArgumentException, RuntimeException);
        virtual ::rtl::OUString SAL_CALL getDestinationTableName() throw (RuntimeException);
        virtual void SAL_CALL setDestinationTableName( const ::rtl::OUString& _destinationTableName ) throw (RuntimeException);
        virtual Optional< ::rtl::OUString > SAL_CALL getCreatePrimaryKey() throw (RuntimeException);
        virtual void SAL_CALL setCreatePrimaryKey( const Optional< ::rtl::OUString >& _newPrimaryKey ) throw (IllegalArgumentException, RuntimeException);
        virtual sal_Bool SAL_CALL getUseHeaderLineAsColumnNames() throw (RuntimeException);
        virtual void SAL_CALL setUseHeaderLineAsColumnNames( sal_Bool _bUseHeaderLineAsColumnNames ) throw (RuntimeException);
        virtual void SAL_CALL addCopyTableListener( const Reference< XCopyTableListener >& Listener ) throw (RuntimeException);
        virtual void SAL_CALL removeCopyTableListener( const Reference< XCopyTableListener >& Listener ) throw (RuntimeException);

        // XCopyTableWizard::XExecutableDialog
        virtual void SAL_CALL setTitle( const ::rtl::OUString& aTitle ) throw (RuntimeException);
        virtual ::sal_Int16 SAL_CALL execute(  ) throw (RuntimeException);

        // XInitialization
        virtual void SAL_CALL initialize( const Sequence< Any >& aArguments ) throw (Exception, RuntimeException);

	    // XPropertySet
	    virtual Reference< XPropertySetInfo > SAL_CALL getPropertySetInfo() throw(RuntimeException);
	    virtual ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper();

	    // OPropertyArrayUsageHelper
	    virtual ::cppu::IPropertyArrayHelper* createArrayHelper( ) const;

    public:
        ::osl::Mutex&   getMutex() { return m_aMutex; }
        bool            isInitialized() const { return m_xSourceConnection.is() && m_pSourceObject.get() && m_xDestConnection.is(); }

    protected:
	    CopyTableWizard( const Reference< XMultiServiceFactory >& _rxORB );
        ~CopyTableWizard();

        // OGenericUnoDialog overridables
	    virtual Dialog*	createDialog( Window* _pParent );
        virtual void executedDialog( sal_Int16 _nExecutionResult );

    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 );

        /** returns our typed dialog

            @throws ::com::sun::star::uno::RuntimeException
                if we don't have a dialog at the moment the method is called
        */
        OCopyTableWizard&
                impl_getDialog_throw();

        /** returns our typed dialog

            @throws ::com::sun::star::uno::RuntimeException
                if we don't have a dialog at the moment the method is called
        */
        const OCopyTableWizard&
                impl_getDialog_throw() const;

        /** ensures the given argument sequence contains a valid data access descriptor at the given position
            @param _rAllArgs
                the arguments as passed to ->initialize
            @param _nArgPos
                the position within ->_rAllArgs which contains the data access descriptor
            @param _out_rxConnection
                will, upon successful return, contain the connection for the data source
            @param _out_rxDocInteractionHandler
                will, upon successful return, contain the interaction handler which could
                be deduced from database document described by the descriptor, if any.
                (It is possible that the descriptor does not allow to deduce a database document,
                in which case <code>_out_rxDocInteractionHandler</code> will be <NULL/>.)
            @return the data access descriptor
        */
        Reference< XPropertySet >
                impl_ensureDataAccessDescriptor_throw(
                    const Sequence< Any >& _rAllArgs,
                    const sal_Int16 _nArgPos,
                    SharedConnection& _out_rxConnection,
                    InteractionHandler& _out_rxDocInteractionHandler
                ) const;

        /** extracts the source object (table or query) described by the given descriptor,
            relative to m_xSourceConnection
        */
        ::std::auto_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.

            Effectively, this method extracts m_xSourceResultSet, m_aSourceSelection, and m_bSourceSelectionBookmarks.

            If an inconsistent/insufficent sub set of those properties is present in the descriptor, and exception
            is thrown.
        */
        void    impl_extractSourceResultSet_throw(
                    const Reference< XPropertySet >& i_rDescriptor
                );

        /** checks whether the given copy source descriptor contains settings which are not
            supported (yet)

            Throws an IllegalArgumentException if the descriptor contains a valid setting, which is
            not yet supported.
        */
        void    impl_checkForUnsupportedSettings_throw(
            const Reference< XPropertySet >& _rxSourceDescriptor ) const;

        /** obtaines the connection described by the given data access descriptor

            If needed and possible, the method will ask the user, using the interaction
            handler associated with the database described by the descriptor.

            All errors are handled with the InteractionHandler associated with the data source,
            if there is one. Else, they will be silenced (but asserted in non-product builds).
        
            @param _rxDataSourceDescriptor
                the data access descriptor describing the data source whose connection
                should be obtained. Must not be <NULL/>.
            @param _out_rxDocInteractionHandler
                the interaction handler which could be deduced from the descriptor

            @throws RuntimeException
                if anything goes seriously wrong.
        */
        SharedConnection
                impl_extractConnection_throw(
                    const Reference< XPropertySet >& _rxDataSourceDescriptor,
                    InteractionHandler& _out_rxDocInteractionHandler
                ) const;

        /** actually copies the table

            This method is called after the dialog has been successfully executed.
        */
        void    impl_doCopy_nothrow();

        /** creates the INSERT INTO statement
            @param  _xTable The destination table.
        */
        ::rtl::OUString impl_getServerSideCopyStatement_throw( const Reference< XPropertySet >& _xTable );

        /** creates the statement which, when executed, will produce the source data to copy

            If the source object refers to a query which contains parameters, those parameters
            are filled in, using an interaction handler.
        */
        ::utl::SharedUNOComponent< XPreparedStatement >
                impl_createSourceStatement_throw() const;

        /** 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 occured during copying

            First, all listeners are ask. If a listener tells to cancel or continue copying, this is reported to the
            method's caller. If a listener tells to ask the user, this is done, and the user's decision is
            reported to the method's caller.

            @return
                <TRUE/> if and only if copying should be continued.
        */
        bool    impl_processCopyError_nothrow(
                    const CopyTableRowEvent& _rEvent );

private:
        ::comphelper::ComponentContext  m_aContext;

        // attributes
        sal_Int16                       m_nOperation;
        ::rtl::OUString                 m_sDestinationTable;
        Optional< ::rtl::OUString >     m_aPrimaryKeyName;
        sal_Bool                        m_bUseHeaderLineAsColumnNames;

        // source
        SharedConnection                m_xSourceConnection;
        sal_Int32                       m_nCommandType;
        ::std::auto_ptr< ICopyTableSourceObject >
                                        m_pSourceObject;
        Reference< XResultSet >         m_xSourceResultSet;
        Sequence< Any >                 m_aSourceSelection;
        sal_Bool                        m_bSourceSelectionBookmarks;

        // destination
        SharedConnection                m_xDestConnection;

        // other
        InteractionHandler              m_xInteractionHandler;
        ::cppu::OInterfaceContainerHelper
                                        m_aCopyTableListeners;
        sal_Int16                       m_nOverrideExecutionResult;
    };

//=========================================================================
//= MethodGuard
//=========================================================================
class CopyTableAccessGuard
{
public:
    CopyTableAccessGuard( CopyTableWizard& _rWizard )
        :m_rWizard( _rWizard )
    {
        m_rWizard.getMutex().acquire();
        if ( !m_rWizard.isInitialized() )
            throw NotInitializedException();
    }

    ~CopyTableAccessGuard()
    {
        m_rWizard.getMutex().release();
    }

private:
    CopyTableWizard&    m_rWizard;
};

//=========================================================================
//-------------------------------------------------------------------------
CopyTableWizard::CopyTableWizard( const Reference< XMultiServiceFactory >& _rxORB )
    :CopyTableWizard_Base( _rxORB )
    ,m_aContext( _rxORB )
    ,m_nOperation( CopyTableOperation::CopyDefinitionAndData )
    ,m_sDestinationTable()
    ,m_aPrimaryKeyName( sal_False, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ID" ) ))
    ,m_bUseHeaderLineAsColumnNames( sal_True )
    ,m_xSourceConnection()
    ,m_nCommandType( CommandType::COMMAND )
    ,m_pSourceObject()
    ,m_xSourceResultSet()
    ,m_aSourceSelection()
    ,m_bSourceSelectionBookmarks( sal_True )
    ,m_xDestConnection()
    ,m_aCopyTableListeners( m_aMutex )
    ,m_nOverrideExecutionResult( -1 )
{
}

//-------------------------------------------------------------------------
CopyTableWizard::~CopyTableWizard()
{
    acquire();

    // protect some members whose dtor might potentially throw
    try { m_xSourceConnection.clear();  }
    catch( const Exception& ) { DBG_UNHANDLED_EXCEPTION(); }
    try { m_xDestConnection.clear();  }
    catch( const Exception& ) { DBG_UNHANDLED_EXCEPTION(); }

    // 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?
}

//-------------------------------------------------------------------------
Reference< XInterface > CopyTableWizard::Create( const Reference< XMultiServiceFactory >& _rxFactory )
{
    return *( new CopyTableWizard( _rxFactory ) );
}

//-------------------------------------------------------------------------
::rtl::OUString SAL_CALL CopyTableWizard::getImplementationName() throw(RuntimeException)
{
    return getImplementationName_Static();
}

//-------------------------------------------------------------------------
::rtl::OUString CopyTableWizard::getImplementationName_Static() throw(RuntimeException)
{
    return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "org.openoffice.comp.dbu.CopyTableWizard" ) );
}

//-------------------------------------------------------------------------
::comphelper::StringSequence SAL_CALL CopyTableWizard::getSupportedServiceNames() throw(RuntimeException)
{
    return getSupportedServiceNames_Static();
}

//-------------------------------------------------------------------------
::comphelper::StringSequence CopyTableWizard::getSupportedServiceNames_Static() throw(RuntimeException)
{
    ::comphelper::StringSequence aSupported(1);
    aSupported.getArray()[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sdb.application.CopyTableWizard" ) );
    return aSupported;
}

//-------------------------------------------------------------------------
Reference< XPropertySetInfo > SAL_CALL CopyTableWizard::getPropertySetInfo() throw(RuntimeException)
{
    Reference< XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) );
    return xInfo;
}

//--------------------------------------------------------------------
::sal_Int16 SAL_CALL CopyTableWizard::getOperation() throw (RuntimeException)
{
    CopyTableAccessGuard aGuard( *this );
    return m_nOperation;
}

//--------------------------------------------------------------------
void SAL_CALL CopyTableWizard::setOperation( ::sal_Int16 _operation ) throw (IllegalArgumentException, RuntimeException)
{
    CopyTableAccessGuard aGuard( *this );

    if  (   ( _operation != CopyTableOperation::CopyDefinitionAndData )
        &&  ( _operation != CopyTableOperation::CopyDefinitionOnly )
        &&  ( _operation != CopyTableOperation::CreateAsView )
        &&  ( _operation != CopyTableOperation::AppendData )
        )
        throw IllegalArgumentException( ::rtl::OUString(), *this, 1 );

    if  (   ( _operation == CopyTableOperation::CreateAsView )
        &&  !OCopyTableWizard::supportsViews( m_xDestConnection )
        )
        throw IllegalArgumentException(
            String( ModuleRes( STR_CTW_NO_VIEWS_SUPPORT ) ),
            *this,
            1
        );

    m_nOperation = _operation;
}

//--------------------------------------------------------------------
::rtl::OUString SAL_CALL CopyTableWizard::getDestinationTableName() throw (RuntimeException)
{
    CopyTableAccessGuard aGuard( *this );
    return m_sDestinationTable;
}

//--------------------------------------------------------------------
void SAL_CALL CopyTableWizard::setDestinationTableName( const ::rtl::OUString& _destinationTableName ) throw (RuntimeException)
{
    CopyTableAccessGuard aGuard( *this );
    m_sDestinationTable = _destinationTableName;
}

//--------------------------------------------------------------------
Optional< ::rtl::OUString > SAL_CALL CopyTableWizard::getCreatePrimaryKey() throw (RuntimeException)
{
    CopyTableAccessGuard aGuard( *this );
    return m_aPrimaryKeyName;
}

//--------------------------------------------------------------------
void SAL_CALL CopyTableWizard::setCreatePrimaryKey( const Optional< ::rtl::OUString >& _newPrimaryKey ) throw (IllegalArgumentException, RuntimeException)
{
    CopyTableAccessGuard aGuard( *this );

    if ( _newPrimaryKey.IsPresent && !OCopyTableWizard::supportsPrimaryKey( m_xDestConnection ) )
        throw IllegalArgumentException(
                String( ModuleRes( STR_CTW_NO_PRIMARY_KEY_SUPPORT ) ),
            *this,
            1
        );

    m_aPrimaryKeyName = _newPrimaryKey;
}
// -----------------------------------------------------------------------------
sal_Bool SAL_CALL CopyTableWizard::getUseHeaderLineAsColumnNames() throw (RuntimeException)
{
    CopyTableAccessGuard aGuard( *this );
    return m_bUseHeaderLineAsColumnNames;
}
// -----------------------------------------------------------------------------
void SAL_CALL CopyTableWizard::setUseHeaderLineAsColumnNames( sal_Bool _bUseHeaderLineAsColumnNames ) throw (RuntimeException)
{
    CopyTableAccessGuard aGuard( *this );
    m_bUseHeaderLineAsColumnNames = _bUseHeaderLineAsColumnNames;
}
//--------------------------------------------------------------------
void SAL_CALL CopyTableWizard::addCopyTableListener( const Reference< XCopyTableListener >& _rxListener ) throw (RuntimeException)
{
    CopyTableAccessGuard aGuard( *this );
    if ( _rxListener.is() )
        m_aCopyTableListeners.addInterface( _rxListener );
}

//--------------------------------------------------------------------
void SAL_CALL CopyTableWizard::removeCopyTableListener( const Reference< XCopyTableListener >& _rxListener ) throw (RuntimeException)
{
    CopyTableAccessGuard aGuard( *this );
    if ( _rxListener.is() )
        m_aCopyTableListeners.removeInterface( _rxListener );
}

//--------------------------------------------------------------------
void SAL_CALL CopyTableWizard::setTitle( const ::rtl::OUString& _rTitle ) throw (RuntimeException)
{
    CopyTableAccessGuard aGuard( *this );
    CopyTableWizard_DialogBase::setTitle( _rTitle );
}

//--------------------------------------------------------------------
::sal_Int16 SAL_CALL CopyTableWizard::execute(  ) throw (RuntimeException)
{
    CopyTableAccessGuard aGuard( *this );

    m_nOverrideExecutionResult = -1;
    sal_Int16 nExecutionResult = CopyTableWizard_DialogBase::execute();
    if ( m_nOverrideExecutionResult )
        nExecutionResult = m_nOverrideExecutionResult;

    return nExecutionResult;
}

//-------------------------------------------------------------------------
OCopyTableWizard& CopyTableWizard::impl_getDialog_throw()
{
    OCopyTableWizard* pWizard = dynamic_cast< OCopyTableWizard* >( m_pDialog );
    if ( !pWizard )
        throw DisposedException( ::rtl::OUString(), *this );
    return *pWizard;
}

//-------------------------------------------------------------------------
const OCopyTableWizard& CopyTableWizard::impl_getDialog_throw() const
{
    const OCopyTableWizard* pWizard = dynamic_cast< const OCopyTableWizard* >( m_pDialog );
    if ( !pWizard )
        throw DisposedException( ::rtl::OUString(), *const_cast< CopyTableWizard* >( this ) );
    return *pWizard;
}

//-------------------------------------------------------------------------
void CopyTableWizard::impl_attributesToDialog_nothrow( OCopyTableWizard& _rDialog ) const
{
    // primary key column
    _rDialog.setCreatePrimaryKey( m_aPrimaryKeyName.IsPresent, m_aPrimaryKeyName.Value );
    _rDialog.setUseHeaderLine(m_bUseHeaderLineAsColumnNames);

    // everything else was passed at construction time already
}

//-------------------------------------------------------------------------
void CopyTableWizard::impl_dialogToAttributes_nothrow( const OCopyTableWizard& _rDialog )
{
    m_aPrimaryKeyName.IsPresent = _rDialog.shouldCreatePrimaryKey();
    if ( m_aPrimaryKeyName.IsPresent )
        m_aPrimaryKeyName.Value = _rDialog.getPrimaryKeyName();
    else
        m_aPrimaryKeyName.Value = ::rtl::OUString();

    m_sDestinationTable = _rDialog.getName();

    m_nOperation = _rDialog.getOperation();
    m_bUseHeaderLineAsColumnNames = _rDialog.UseHeaderLine();
}

//-------------------------------------------------------------------------
namespace
{
    //.....................................................................
    /** tries to obtain the InteractionHandler associated with a given data source

        If the data source is a sdb-level data source, it will have a DatabaseDocument associated
        with it. This doocument may have an InteractionHandler used while loading it.

        @throws RuntimeException
            if it occures during invoking any of the data source's methods, or if any of the involved
            components violates its contract by not providing the required interfaces
    */
    InteractionHandler lcl_getInteractionHandler_throw( const Reference< XDataSource >& _rxDataSource, const InteractionHandler& _rFallback )
    {
        InteractionHandler xHandler( _rFallback );

        // 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() )
        {
            ::comphelper::NamedValueCollection aModelArgs( xDocumentModel->getArgs() );
            xHandler = aModelArgs.getOrDefault( "InteractionHandler", xHandler );
        }

        return xHandler;
    }
    //.....................................................................
    /** tries to obtain the InteractionHandler associated with a given connection

        If the connection belongs to a sdb-level data source, then this data source
        is examined for an interaction handler. Else, <NULL/> is returned.

        @throws RuntimeException
            if it occures during invoking any of the data source's methods, or if any of the involved
            components violates its contract by not providing the required interfaces
    */
    InteractionHandler lcl_getInteractionHandler_throw( const Reference< XConnection >& _rxConnection, const InteractionHandler& _rFallback )
    {
        // try whether there is a data source which the connection belongs to
        Reference< XDataSource > xDataSource;
        Reference< XChild > xAsChild( _rxConnection, UNO_QUERY );
        if ( xAsChild.is() )
            xDataSource = xDataSource.query( xAsChild->getParent() );

        if ( xDataSource.is() )
            return lcl_getInteractionHandler_throw( xDataSource, _rFallback );

        return _rFallback;
    }
}

//-------------------------------------------------------------------------
Reference< XPropertySet > CopyTableWizard::impl_ensureDataAccessDescriptor_throw(
    const Sequence< Any >& _rAllArgs, const sal_Int16 _nArgPos, SharedConnection& _out_rxConnection,
    InteractionHandler& _out_rxDocInteractionHandler ) const
{
    Reference< XPropertySet > xDescriptor;
    _rAllArgs[ _nArgPos ] >>= xDescriptor;

    // 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( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sdb.DataAccessDescriptor" ) ) )
                    );
    }

    // 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(
            String( ModuleRes( STR_CTW_INVALID_DATA_ACCESS_DESCRIPTOR ) ),
            *const_cast< CopyTableWizard* >( this ),
            _nArgPos + 1
        );
    }

    return xDescriptor;
}

//-------------------------------------------------------------------------
namespace
{
    bool lcl_hasNonEmptyStringValue_throw( const Reference< XPropertySet >& _rxDescriptor,
        const Reference< XPropertySetInfo > _rxPSI, const ::rtl::OUString& _rPropertyName )
    {
        ::rtl::OUString sValue;
        if ( _rxPSI->hasPropertyByName( _rPropertyName ) )
        {
            OSL_VERIFY( _rxDescriptor->getPropertyValue( _rPropertyName ) >>= sValue );
        }
        return sValue.getLength() > 0;
    }
}

//-------------------------------------------------------------------------
void CopyTableWizard::impl_checkForUnsupportedSettings_throw( const Reference< XPropertySet >& _rxSourceDescriptor ) const
{
    OSL_PRECOND( _rxSourceDescriptor.is(), "CopyTableWizard::impl_checkForUnsupportedSettings_throw: illegal argument!" );
    Reference< XPropertySetInfo > xPSI( _rxSourceDescriptor->getPropertySetInfo(), UNO_SET_THROW );
    ::rtl::OUString sUnsupportedSetting;

    const ::rtl::OUString aSettings[] = {
        PROPERTY_FILTER, PROPERTY_ORDER, PROPERTY_HAVING_CLAUSE, PROPERTY_GROUP_BY
    };
    for ( size_t i=0; i < sizeof( aSettings ) / sizeof( aSettings[0] ); ++i )
    {
        if ( lcl_hasNonEmptyStringValue_throw( _rxSourceDescriptor, xPSI, aSettings[i] ) )
        {
            sUnsupportedSetting = aSettings[i];
            break;
        }
    }

    if ( sUnsupportedSetting.getLength() != 0 )
    {
        ::rtl::OUString sMessage( String(ModuleRes( STR_CTW_ERROR_UNSUPPORTED_SETTING )) );
        ::comphelper::string::searchAndReplaceAsciiI( sMessage, "$name$", sUnsupportedSetting );
        throw IllegalArgumentException(
            sMessage,
            *const_cast< CopyTableWizard* >( this ),
            1
        );
    }

}

//-------------------------------------------------------------------------
::std::auto_ptr< ICopyTableSourceObject > CopyTableWizard::impl_extractSourceObject_throw( const Reference< XPropertySet >& _rxDescriptor, sal_Int32& _out_rCommandType ) const
{
    OSL_PRECOND( _rxDescriptor.is() && m_xSourceConnection.is(), "CopyTableWizard::impl_extractSourceObject_throw: illegal arguments!" );

    Reference< XPropertySetInfo > xPSI( _rxDescriptor->getPropertySetInfo(), UNO_SET_THROW );
    if  (   !xPSI->hasPropertyByName( PROPERTY_COMMAND )
        ||  !xPSI->hasPropertyByName( PROPERTY_COMMAND_TYPE )
        )
        throw IllegalArgumentException(
            ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Expecting a table or query specification." ) ),
                // TODO: resource
            *const_cast< CopyTableWizard* >( this ),
            1
        );

    ::rtl::OUString sCommand;
    _out_rCommandType = CommandType::COMMAND;
    OSL_VERIFY( _rxDescriptor->getPropertyValue( PROPERTY_COMMAND ) >>= sCommand );
    OSL_VERIFY( _rxDescriptor->getPropertyValue( PROPERTY_COMMAND_TYPE ) >>= _out_rCommandType );

    ::std::auto_ptr< ICopyTableSourceObject > pSourceObject;
    Reference< XNameAccess > xContainer;
    switch ( _out_rCommandType )
    {
    case CommandType::TABLE:
    {
        Reference< XTablesSupplier > xSuppTables( m_xSourceConnection.getTyped(), UNO_QUERY );
        if ( xSuppTables.is() )
            xContainer.set( xSuppTables->getTables(), UNO_SET_THROW );
    }
    break;
    case CommandType::QUERY:
    {
        Reference< XQueriesSupplier > xSuppQueries( m_xSourceConnection.getTyped(), UNO_QUERY );
        if ( xSuppQueries.is() )
            xContainer.set( xSuppQueries->getQueries(), UNO_SET_THROW );
    }
    break;
    default:
        throw IllegalArgumentException(
            String( ModuleRes( STR_CTW_ONLY_TABLES_AND_QUERIES_SUPPORT ) ),
            *const_cast< CopyTableWizard* >( this ),
            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(
                String(ModuleRes( STR_CTW_ERROR_NO_QUERY )),
                *const_cast< CopyTableWizard* >( this ),
                1
            );
        pSourceObject.reset( new NamedTableCopySource( m_xSourceConnection, sCommand ) );
    }

    return pSourceObject;
}

//-------------------------------------------------------------------------
void CopyTableWizard::impl_extractSourceResultSet_throw( const Reference< XPropertySet >& i_rDescriptor )
{
    Reference< XPropertySetInfo > xPSI( i_rDescriptor->getPropertySetInfo(), UNO_SET_THROW );

    // extract relevant settings
    if ( xPSI->hasPropertyByName( PROPERTY_RESULT_SET ) )
        m_xSourceResultSet.set( i_rDescriptor->getPropertyValue( PROPERTY_RESULT_SET ), UNO_QUERY );

    if ( xPSI->hasPropertyByName( PROPERTY_SELECTION ) )
        OSL_VERIFY( i_rDescriptor->getPropertyValue( PROPERTY_SELECTION ) >>= m_aSourceSelection );

    if ( xPSI->hasPropertyByName( PROPERTY_BOOKMARK_SELECTION ) )
        OSL_VERIFY( i_rDescriptor->getPropertyValue( PROPERTY_BOOKMARK_SELECTION ) >>= m_bSourceSelectionBookmarks );

    // sanity checks
    const bool bHasResultSet = m_xSourceResultSet.is();
    const bool bHasSelection = ( m_aSourceSelection.getLength() != 0 );
    if ( bHasSelection && !bHasResultSet )
        throw IllegalArgumentException(
            ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "A result set is needed when specifying a selection to copy." ) ),
                // TODO: resource
            *this,
            1
        );

    if ( bHasSelection && m_bSourceSelectionBookmarks )
    {
        Reference< XRowLocate > xRowLocate( m_xSourceResultSet, UNO_QUERY );
        if ( !xRowLocate.is() )
        {
            ::dbtools::throwGenericSQLException(
                String( ModuleRes( STR_CTW_COPY_SOURCE_NEEDS_BOOKMARKS ) ),
                *this
            );
        }
    }
}

//-------------------------------------------------------------------------
SharedConnection CopyTableWizard::impl_extractConnection_throw( const Reference< XPropertySet >& _rxDataSourceDescriptor,
    InteractionHandler& _out_rxDocInteractionHandler ) const
{
    SharedConnection xConnection;

    OSL_PRECOND( _rxDataSourceDescriptor.is(), "CopyTableWizard::impl_extractConnection_throw: no descriptor!" );
    if ( !_rxDataSourceDescriptor.is() )
        return xConnection;

    InteractionHandler xInteractionHandler;

    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 );
        OSL_POSTCOND( xInteractionHandler.is(), "CopyTableWizard::impl_extractConnection_throw: lcl_getInteractionHandler_throw returned nonsense!" );
        break;
    }

    // there could be a DataSourceName or a DatabaseLocation, describing the css.sdb.DataSource
    ::rtl::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< XNameAccess > xDatabaseContext( m_aContext.createComponent( "com.sun.star.sdb.DatabaseContext" ), UNO_QUERY_THROW );
    Reference< XDataSource > xDataSource;
    if ( sDataSource.getLength() )
        xDataSource.set( xDatabaseContext->getByName( sDataSource ), UNO_QUERY_THROW );
    if ( !xDataSource.is() && sDatabaseLocation.getLength() )
        xDataSource.set( xDatabaseContext->getByName( sDatabaseLocation ), UNO_QUERY_THROW );

    if ( xDataSource.is() )
    {
        // first, try connecting with completion
        xInteractionHandler = lcl_getInteractionHandler_throw( xDataSource, m_xInteractionHandler );
        OSL_POSTCOND( xInteractionHandler.is(), "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( ::rtl::OUString(), ::rtl::OUString() ), SharedConnection::TakeOwnership );
        }
    }

    if ( xConnection.is() )
        break;

    // finally, there could be a ConnectionResource/ConnectionInfo
    ::rtl::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;
    xDriverManager.set( m_aContext.createComponent( "com.sun.star.sdbc.ConnectionPool" ), UNO_QUERY );
    if ( !xDriverManager.is() )
        // no connection pool installed
        xDriverManager.set( m_aContext.createComponent( "com.sun.star.sdbc.DriverManager" ), UNO_QUERY_THROW );

    if ( aConnectionInfo.getLength() )
        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;

    return xConnection;
}

//-------------------------------------------------------------------------
::utl::SharedUNOComponent< XPreparedStatement > CopyTableWizard::impl_createSourceStatement_throw() const
{
    OSL_PRECOND( m_xSourceConnection.is(), "CopyTableWizard::impl_createSourceStatement_throw: illegal call!" );
    if ( !m_xSourceConnection.is() )
        throw RuntimeException( ::rtl::OUString(), *const_cast< CopyTableWizard* >( this ) );

    ::utl::SharedUNOComponent< XPreparedStatement > xStatement;
    switch ( m_nCommandType )
    {
    case CommandType::TABLE:
        xStatement.set( m_pSourceObject->getPreparedSelectStatement(), UNO_SET_THROW );
        break;

    case CommandType::QUERY:
    {
        ::rtl::OUString sQueryCommand( m_pSourceObject->getSelectStatement() );
        xStatement.set( m_pSourceObject->getPreparedSelectStatement(), UNO_SET_THROW );

        // 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

                if ( m_xInteractionHandler.is() )
                    ::dbtools::askForParameters( xComposer, xStatementParams, m_xSourceConnection, m_xInteractionHandler );
            }
        }
    }
    break;

    default:
        // this should not have survived initialization phase
        throw RuntimeException( ::rtl::OUString(), *const_cast< CopyTableWizard* >( this ) );
    }

    return xStatement;
}

//-------------------------------------------------------------------------
namespace
{
    class ValueTransfer
    {
    public:
        ValueTransfer( const sal_Int32& _rSourcePos, const sal_Int32& _rDestPos, const ::std::vector< sal_Int32 >& _rColTypes,
            const Reference< XRow >& _rxSource, const Reference< XParameters >& _rxDest )
            :m_rSourcePos( _rSourcePos )
            ,m_rDestPos( _rDestPos )
            ,m_rColTypes( _rColTypes )
            ,m_xSource( _rxSource )
            ,m_xDest( _rxDest )
        {
        }

    template< typename VALUE_TYPE >
    void transferValue( 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 ) );
        if ( m_xSource->wasNull() )
            m_xDest->setNull( m_rDestPos, m_rColTypes[ m_rSourcePos ] );
        else
            (m_xDest.get()->*_pSetter)( m_rDestPos, value );
    }
 template< typename VALUE_TYPE >
    void transferComplexValue( 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 ) );
               {
        if ( m_xSource->wasNull() )
            m_xDest->setNull( m_rDestPos, m_rColTypes[ m_rSourcePos ] );
        else
            (m_xDest.get()->*_pSetter)( m_rDestPos, value );
               }
    }
    private:
        const sal_Int32&                    m_rSourcePos;
        const sal_Int32&                    m_rDestPos;
        const ::std::vector< sal_Int32 >    m_rColTypes;
        const Reference< XRow >             m_xSource;
        const Reference< XParameters >      m_xDest;
    };
}

//-------------------------------------------------------------------------
bool CopyTableWizard::impl_processCopyError_nothrow( const CopyTableRowEvent& _rEvent )
{
    Reference< XCopyTableListener > xListener;
    try
    {
        ::cppu::OInterfaceIteratorHelper aIter( m_aCopyTableListeners );
        while ( aIter.hasMoreElements() )
        {
            xListener.set( aIter.next(), UNO_QUERY_THROW );
            sal_Int16 nListenerChoice = xListener->copyRowError( _rEvent );
            switch ( nListenerChoice )
            {
            case CopyTableContinuation::Proceed:            return true;    // continue copying
            case CopyTableContinuation::CallNextHandler:    continue;       // continue the loop, ask next listener
            case CopyTableContinuation::Cancel:             return false;   // cancel copying
            case CopyTableContinuation::AskUser:            break;          // stop asking the listeners, ask the user

            default:
                OSL_ENSURE( false, "CopyTableWizard::impl_processCopyError_nothrow: invalid listener response!" );
                // ask next listener
                continue;
            }
        }
    }
    catch( const Exception& )
    {
    	DBG_UNHANDLED_EXCEPTION();
    }

    // no listener felt responsible for the error, or a listener told to ask the user

    try
    {
        SQLContext aError;
        aError.Context = *this;
        aError.Message = String( ModuleRes( STR_ERROR_OCCURED_WHILE_COPYING ) );

        ::dbtools::SQLExceptionInfo aInfo( _rEvent.Error );
        if ( aInfo.isValid() )
            aError.NextException = _rEvent.Error;
        else
        {
            // a non-SQL exception happend
            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;
        }

        ::rtl::Reference< ::comphelper::OInteractionRequest > xRequest( new ::comphelper::OInteractionRequest( makeAny( aError ) ) );

        ::rtl::Reference< ::comphelper::OInteractionApprove > xYes = new ::comphelper::OInteractionApprove;
        xRequest->addContinuation( xYes.get() );
        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() );

        if ( xYes->wasSelected() )
            // continue copying
            return true;
    }
    catch( const Exception& )
    {
    	DBG_UNHANDLED_EXCEPTION();
    }

    // cancel copying
    return false;
}

//-------------------------------------------------------------------------
void CopyTableWizard::impl_copyRows_throw( const Reference< XResultSet >& _rxSourceResultSet,
    const Reference< XPropertySet >& _rxDestTable )
{
    OSL_PRECOND( m_xDestConnection.is(), "CopyTableWizard::impl_copyRows_throw: illegal call!" );
    if ( !m_xDestConnection.is() )
        throw RuntimeException( ::rtl::OUString(), *this );

    Reference< XDatabaseMetaData > xDestMetaData( m_xDestConnection->getMetaData(), UNO_QUERY_THROW );

    const OCopyTableWizard& rWizard             = impl_getDialog_throw();
    ODatabaseExport::TPositions aColumnMapping  = rWizard.GetColumnPositions();
    bool bAutoIncrement                         = rWizard.shouldCreatePrimaryKey();

    Reference< XRow > xRow              ( _rxSourceResultSet, UNO_QUERY_THROW );
    Reference< XRowLocate > xRowLocate  ( _rxSourceResultSet, UNO_QUERY_THROW );

    Reference< XResultSetMetaDataSupplier > xSuppResMeta( _rxSourceResultSet, UNO_QUERY_THROW );
    Reference< XResultSetMetaData> xMeta( xSuppResMeta->getMetaData() );

    // 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 a everytime i-1 call

    ::std::vector< sal_Int32 > aSourcePrec;
    aSourcePrec.reserve( nCount + 1 );
    aSourcePrec.push_back( -1 ); // just to avoid a everytime 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::createPreparedStatment( xDestMetaData, _rxDestTable, aColumnMapping ), UNO_SET_THROW );
    Reference< XParameters > xStatementParams( xStatement, UNO_QUERY_THROW );

    const bool bSelectedRecordsOnly = m_aSourceSelection.getLength() != 0;
    const Any* pSelectedRow         = m_aSourceSelection.getConstArray();
    const Any* pSelEnd              = pSelectedRow + m_aSourceSelection.getLength();

    sal_Int32 nRowCount = 0;
    bool bContinue = false;

    CopyTableRowEvent aCopyEvent;
    aCopyEvent.Source = *this;
    aCopyEvent.SourceData = _rxSourceResultSet;

    do // loop as long as there are more rows or the selection ends
    {
        bContinue = false;
        if ( bSelectedRecordsOnly )
        {
            if ( pSelectedRow != pSelEnd )
            {
                if ( m_bSourceSelectionBookmarks )
                {
                    bContinue = xRowLocate->moveToBookmark( *pSelectedRow );
                }
                else
                {
                    sal_Int32 nPos = 0;
                    OSL_VERIFY( *pSelectedRow >>= nPos );
                    bContinue = _rxSourceResultSet->absolute( nPos );
                }
                ++pSelectedRow;
            }
        }
        else
            bContinue = _rxSourceResultSet->next();

        if ( !bContinue )
		{
            break;
		}

        ++nRowCount;
        sal_Bool bInsertAutoIncrement = sal_True;
        ODatabaseExport::TPositions::const_iterator aPosIter = aColumnMapping.begin();
        ODatabaseExport::TPositions::const_iterator aPosEnd = aColumnMapping.end();

        aCopyEvent.Error.clear();
        try
        {
            // notify listeners
            m_aCopyTableListeners.notifyEach( &XCopyTableListener::copyingRow, aCopyEvent );

            sal_Int32 nDestColumn( 0 );
            sal_Int32 nSourceColumn( 1 );
			ValueTransfer aTransfer( nSourceColumn, nDestColumn, aSourceColTypes, xRow, xStatementParams );

            for ( ; aPosIter != aPosEnd; ++aPosIter )
            {
                nDestColumn = aPosIter->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 ( bAutoIncrement && bInsertAutoIncrement )
                {
                    xStatementParams->setInt( 1, nRowCount );
                    bInsertAutoIncrement = sal_False;
                    continue;
                }

                if ( ( nSourceColumn < 1 ) || ( nSourceColumn >= (sal_Int32)aSourceColTypes.size() ) )
                {   // ( we have to check here against 1 because the parameters are 1 based)
                    ::dbtools::throwSQLException(
                        ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Internal error: invalid column type index." ) ),
                        ::dbtools::SQL_INVALID_DESCRIPTOR_INDEX,
                        *this
                    );
                }

                switch ( aSourceColTypes[ nSourceColumn ] )
                {
                    case DataType::DOUBLE:
                    case DataType::REAL:
                        aTransfer.transferValue( &XRow::getDouble, &XParameters::setDouble );
                        break;

                    case DataType::CHAR:
                    case DataType::VARCHAR:
                    case DataType::LONGVARCHAR:
                    case DataType::DECIMAL:
                    case DataType::NUMERIC:
                        aTransfer.transferComplexValue( &XRow::getString, &XParameters::setString );
                        break;                      

                    case DataType::BIGINT:
                        aTransfer.transferValue( &XRow::getLong, &XParameters::setLong );
                        break;

                    case DataType::FLOAT:
                        aTransfer.transferValue( &XRow::getFloat, &XParameters::setFloat );
                        break;

                    case DataType::LONGVARBINARY:
                    case DataType::BINARY:
                    case DataType::VARBINARY:
                        aTransfer.transferComplexValue( &XRow::getBytes, &XParameters::setBytes );
                        break;

                    case DataType::DATE:
                        aTransfer.transferComplexValue( &XRow::getDate, &XParameters::setDate );
                        break;

                    case DataType::TIME:
                        aTransfer.transferComplexValue( &XRow::getTime, &XParameters::setTime );
                        break;

                    case DataType::TIMESTAMP:
                        aTransfer.transferComplexValue( &XRow::getTimestamp, &XParameters::setTimestamp );
                        break;

                    case DataType::BIT:
                        if ( aSourcePrec[nSourceColumn] > 1 )
                        {
                            aTransfer.transferComplexValue( &XRow::getBytes, &XParameters::setBytes );
                            break;
                        }
                        // run through
                    case DataType::BOOLEAN:                        
                        aTransfer.transferValue( &XRow::getBoolean, &XParameters::setBoolean );
                        break;

                    case DataType::TINYINT:
                        aTransfer.transferValue( &XRow::getByte, &XParameters::setByte );
                        break;

                    case DataType::SMALLINT:
                        aTransfer.transferValue( &XRow::getShort, &XParameters::setShort );
                        break;

                    case DataType::INTEGER:
                        aTransfer.transferValue( &XRow::getInt, &XParameters::setInt );
                        break;

					case DataType::BLOB:
                        aTransfer.transferComplexValue( &XRow::getBlob, &XParameters::setBlob );
                        break;

					case DataType::CLOB:
                        aTransfer.transferComplexValue( &XRow::getClob, &XParameters::setClob );
                        break;

                    default:
                    {
                        ::rtl::OUString aMessage( String( ModuleRes( STR_CTW_UNSUPPORTED_COLUMN_TYPE ) ) );

                        aMessage.replaceAt( aMessage.indexOfAsciiL( "$type$", 6 ), 6, ::rtl::OUString::valueOf( aSourceColTypes[ nSourceColumn ] ) );
                        aMessage.replaceAt( aMessage.indexOfAsciiL( "$pos$", 5 ), 5, ::rtl::OUString::valueOf( nSourceColumn ) );

                        ::dbtools::throwSQLException(
                            aMessage,
                            ::dbtools::SQL_INVALID_SQL_DATA_TYPE,
                            *this
                        );
                    }
                }
                ++nSourceColumn;
            }
            xStatement->executeUpdate();

            // notify listeners
            m_aCopyTableListeners.notifyEach( &XCopyTableListener::copiedRow, aCopyEvent );
        }
        catch( const Exception& )
        {
            aCopyEvent.Error = ::cppu::getCaughtException();
        }

        if ( aCopyEvent.Error.hasValue() )
            bContinue = impl_processCopyError_nothrow( aCopyEvent );
    }
    while( bContinue );
}
//-------------------------------------------------------------------------
void CopyTableWizard::impl_doCopy_nothrow()
{
    Any aError;

    try
    {
        OCopyTableWizard& rWizard( impl_getDialog_throw() );

        WaitObject aWO( rWizard.GetParent() );
        Reference< XPropertySet > xTable;

        switch ( rWizard.getOperation() )
        {
            case CopyTableOperation::CopyDefinitionOnly:
            case CopyTableOperation::CopyDefinitionAndData:
            {
                xTable = rWizard.createTable();

                if( !xTable.is() )
                {
                    OSL_ENSURE( false, "CopyTableWizard::impl_doCopy_nothrow: createTable should throw here, shouldn't it?" );
                    break;
                }

                if( CopyTableOperation::CopyDefinitionOnly == rWizard.getOperation() )
                    break;
            }
            // run through

            case CopyTableOperation::AppendData:
            {

                if ( !xTable.is() )
                {
                    xTable = rWizard.createTable();
                    if ( !xTable.is() )
                    {
                        OSL_ENSURE( false, "CopyTableWizard::impl_doCopy_nothrow: createTable should throw here, shouldn't it?" );
                        break;
                    }
                }

                ::utl::SharedUNOComponent< XPreparedStatement > xSourceStatement;
                ::utl::SharedUNOComponent< XResultSet > xSourceResultSet;

                if ( m_xSourceResultSet.is() )
                {
                    xSourceResultSet.reset( m_xSourceResultSet, ::utl::SharedUNOComponent< XResultSet >::NoTakeOwnership );
                }
                else
                {
                    const bool bIsSameConnection = ( m_xSourceConnection.getTyped() == m_xDestConnection.getTyped() );
                    const bool bIsTable = ( CommandType::TABLE == m_nCommandType );
                    bool bDone = false;
                    if ( bIsSameConnection && bIsTable )
                    {
                        // try whether the server supports copying via SQL
                        try
                        {
                            m_xDestConnection->createStatement()->executeUpdate( impl_getServerSideCopyStatement_throw(xTable) );
                            bDone = true;
                        }
                        catch( const Exception& )
                        {
                            // this is allowed.
                        }
                    }

                    if ( !bDone )
                    {
                        xSourceStatement.set( impl_createSourceStatement_throw(), UNO_SET_THROW );
                        xSourceResultSet.set( xSourceStatement->executeQuery(), UNO_SET_THROW );
                    }
                }

                if ( xSourceResultSet.is() )
                    impl_copyRows_throw( xSourceResultSet, xTable );
            }
            break;

            case CopyTableOperation::CreateAsView:
                rWizard.createView();
                break;

            default:
                OSL_ENSURE( false, "CopyTableWizard::impl_doCopy_nothrow: What operation, please?" );
                break;
        }
    }
    catch( const Exception& )
    {
        aError = ::cppu::getCaughtException();

        // silence the error of the user cancelling the parameter's dialog
        SQLException aSQLError;
        if ( ( aError >>= aSQLError ) && ( aSQLError.ErrorCode == ::dbtools::ParameterInteractionCancelled ) )
        {
            aError.clear();
            m_nOverrideExecutionResult = RET_CANCEL;
        }
    }

    if ( aError.hasValue() && m_xInteractionHandler.is() )
    {
        try
        {
            ::rtl::Reference< ::comphelper::OInteractionRequest > xRequest( new ::comphelper::OInteractionRequest( aError ) );
            m_xInteractionHandler->handle( xRequest.get() );
        }
        catch( const Exception& )
        {
        	DBG_UNHANDLED_EXCEPTION();
        }
    }
}
// -----------------------------------------------------------------------------
::rtl::OUString CopyTableWizard::impl_getServerSideCopyStatement_throw(const Reference< XPropertySet >& _xTable)
{
    const Reference<XColumnsSupplier> xDestColsSup(_xTable,UNO_QUERY_THROW);
	const Sequence< ::rtl::OUString> aDestColumnNames = xDestColsSup->getColumns()->getElementNames();
    const Sequence< ::rtl::OUString > aColumnNames = m_pSourceObject->getColumnNames();
    const Reference< XDatabaseMetaData > xDestMetaData( m_xDestConnection->getMetaData(), UNO_QUERY_THROW );
    const ::rtl::OUString sQuote = xDestMetaData->getIdentifierQuoteString();
    ::rtl::OUStringBuffer sColumns;
    // 1st check if the columns matching
    const OCopyTableWizard& rWizard             = impl_getDialog_throw();
    ODatabaseExport::TPositions aColumnMapping  = rWizard.GetColumnPositions();
    ODatabaseExport::TPositions::const_iterator aPosIter = aColumnMapping.begin();
    for ( sal_Int32 i = 0; aPosIter != aColumnMapping.end() ; ++aPosIter,++i )
    {
        if ( COLUMN_POSITION_NOT_FOUND != aPosIter->second )
        {
            if ( sColumns.getLength() )
                sColumns.appendAscii(",");
            sColumns.append(sQuote);
            sColumns.append(aDestColumnNames[aPosIter->second - 1]);
            sColumns.append(sQuote);
        }
    } // for ( ; aPosIter != aColumnMapping.end() ; ++aPosIter )
    ::rtl::OUStringBuffer sSql;
    sSql.appendAscii("INSERT INTO ");
    const ::rtl::OUString sComposedTableName = ::dbtools::composeTableName( xDestMetaData, _xTable, ::dbtools::eInDataManipulation, false, false, true );
    sSql.append( sComposedTableName );
    sSql.appendAscii(" ( ");
    sSql.append( sColumns );
    sSql.appendAscii(" ) ( ");
    sSql.append( m_pSourceObject->getSelectStatement());
    sSql.appendAscii(" )");
    
    return sSql.makeStringAndClear();
}
//-------------------------------------------------------------------------
void SAL_CALL CopyTableWizard::initialize( const Sequence< Any >& _rArguments ) throw (Exception, RuntimeException)
{
    ::osl::MutexGuard aGuard( m_aMutex );
    if ( isInitialized() )
        throw AlreadyInitializedException( ::rtl::OUString(), *this );

    sal_Int32 nArgCount( _rArguments.getLength() );
    if ( ( nArgCount != 2 ) && ( nArgCount != 3 ) )
        throw IllegalArgumentException(
            String( ModuleRes( STR_CTW_ILLEGAL_PARAMETER_COUNT ) ),
            *this,
            1
        );

    try
    {
        if ( nArgCount == 3 )
        {   // ->createWithInteractionHandler
            if ( !( _rArguments[2] >>= m_xInteractionHandler ) )
                throw IllegalArgumentException(
                    String(ModuleRes( STR_CTW_ERROR_INVALID_INTERACTIONHANDLER )),
                    *this,
                    3
                );
        }
        if ( !m_xInteractionHandler.is() )
            m_xInteractionHandler.set( m_aContext.createComponent( "com.sun.star.task.InteractionHandler" ), UNO_QUERY_THROW );

        InteractionHandler xSourceDocHandler;
        Reference< XPropertySet > xSourceDescriptor( impl_ensureDataAccessDescriptor_throw( _rArguments, 0, m_xSourceConnection, xSourceDocHandler ) );
        impl_checkForUnsupportedSettings_throw( xSourceDescriptor );
        m_pSourceObject = impl_extractSourceObject_throw( xSourceDescriptor, m_nCommandType );
        impl_extractSourceResultSet_throw( xSourceDescriptor );

        InteractionHandler xDestDocHandler;
        impl_ensureDataAccessDescriptor_throw( _rArguments, 1, m_xDestConnection, xDestDocHandler );

        if ( xDestDocHandler.is() && !m_xInteractionHandler.is() )
            m_xInteractionHandler = xDestDocHandler;
    }
    catch( const RuntimeException& ) { throw; }
    catch( const IllegalArgumentException& ) { throw; }
    catch( const SQLException& ) { throw; }
    catch( const Exception& )
    {
        throw WrappedTargetException(
            String( ModuleRes( STR_CTW_ERROR_DURING_INITIALIZATION ) ),
            *this,
            ::cppu::getCaughtException()
        );
    }
}

//-------------------------------------------------------------------------
::cppu::IPropertyArrayHelper& CopyTableWizard::getInfoHelper()
{
    return *getArrayHelper();
}

//------------------------------------------------------------------------------
::cppu::IPropertyArrayHelper* CopyTableWizard::createArrayHelper( ) const
{
    Sequence< Property > aProps;
    describeProperties( aProps );
    return new ::cppu::OPropertyArrayHelper( aProps );
}

//------------------------------------------------------------------------------
Dialog*	CopyTableWizard::createDialog( Window* _pParent )
{
    OSL_PRECOND( isInitialized(), "CopyTableWizard::createDialog: not initialized!" );
        // this should have been prevented in ::execute already

    OCopyTableWizard* pWizard = new OCopyTableWizard(
        _pParent,
        m_sDestinationTable,
        m_nOperation,
        *m_pSourceObject,
        m_xSourceConnection.getTyped(),
        m_xDestConnection.getTyped(),
        m_aContext.getLegacyServiceFactory(),
        m_xInteractionHandler
    );

    impl_attributesToDialog_nothrow( *pWizard );

    return pWizard;
}

//------------------------------------------------------------------------------
void CopyTableWizard::executedDialog( sal_Int16 _nExecutionResult )
{
    CopyTableWizard_DialogBase::executedDialog( _nExecutionResult );

    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() );
}

//........................................................................
} // namespace dbaui
//........................................................................

extern "C" void SAL_CALL createRegistryInfo_CopyTableWizard()
{
    static ::dbaui::OMultiInstanceAutoRegistration< ::dbaui::CopyTableWizard > aAutoRegistration;
}
