Version 5.2.6.1, tag libreoffice-5.2.6.1
[LibreOffice.git] / dbaccess / source / ui / misc / WCopyTable.cxx
blob240d6389940607749648fd65c072ca5b50a013df
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "dbu_misc.hrc"
21 #include "dbustrings.hrc"
22 #include "moduledbu.hxx"
23 #include "sqlmessage.hxx"
24 #include "UITools.hxx"
25 #include "WColumnSelect.hxx"
26 #include "WCopyTable.hxx"
27 #include "WCPage.hxx"
28 #include "WExtendPages.hxx"
29 #include "WNameMatch.hxx"
30 #include "WTypeSelect.hxx"
32 #include <com/sun/star/sdb/application/CopyTableOperation.hpp>
33 #include <com/sun/star/sdb/SQLContext.hpp>
34 #include <com/sun/star/sdbc/ColumnValue.hpp>
35 #include <com/sun/star/sdbc/DataType.hpp>
36 #include <com/sun/star/sdbc/XResultSet.hpp>
37 #include <com/sun/star/sdbc/XRow.hpp>
38 #include <com/sun/star/sdbcx/KeyType.hpp>
39 #include <com/sun/star/sdbcx/XAppend.hpp>
40 #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
41 #include <com/sun/star/sdbcx/XDataDescriptorFactory.hpp>
42 #include <com/sun/star/sdbcx/XKeysSupplier.hpp>
43 #include <com/sun/star/sdbcx/XTablesSupplier.hpp>
44 #include <com/sun/star/sdbcx/XViewsSupplier.hpp>
45 #include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp>
46 #include <com/sun/star/task/InteractionHandler.hpp>
48 #include <comphelper/extract.hxx>
49 #include <comphelper/processfactory.hxx>
50 #include <comphelper/types.hxx>
51 #include <comphelper/interaction.hxx>
52 #include <connectivity/dbtools.hxx>
53 #include <connectivity/dbmetadata.hxx>
54 #include <connectivity/dbexception.hxx>
56 #include <rtl/ustrbuf.hxx>
57 #include <tools/debug.hxx>
58 #include <tools/diagnose_ex.h>
59 #include <vcl/lstbox.hxx>
60 #include <vcl/msgbox.hxx>
61 #include <vcl/waitobj.hxx>
63 #include <functional>
65 using namespace ::dbaui;
66 using namespace ::com::sun::star::uno;
67 using namespace ::com::sun::star::beans;
68 using namespace ::com::sun::star::container;
69 using namespace ::com::sun::star::util;
70 using namespace ::com::sun::star::sdb;
71 using namespace ::com::sun::star::sdbc;
72 using namespace ::com::sun::star::sdbcx;
73 using namespace ::com::sun::star::lang;
74 using namespace ::com::sun::star::task;
75 using namespace dbtools;
77 namespace CopyTableOperation = ::com::sun::star::sdb::application::CopyTableOperation;
79 #define MAX_PAGES 4 // max. number of pages, which are shown
81 namespace
83 void clearColumns(ODatabaseExport::TColumns& _rColumns, ODatabaseExport::TColumnVector& _rColumnsVec)
85 ODatabaseExport::TColumns::const_iterator aIter = _rColumns.begin();
86 ODatabaseExport::TColumns::const_iterator aEnd = _rColumns.end();
88 for(;aIter != aEnd;++aIter)
89 delete aIter->second;
91 _rColumnsVec.clear();
92 _rColumns.clear();
96 // ICopyTableSourceObject
97 ICopyTableSourceObject::~ICopyTableSourceObject()
101 // ObjectCopySource
102 ObjectCopySource::ObjectCopySource( const Reference< XConnection >& _rxConnection, const Reference< XPropertySet >& _rxObject )
103 :m_xConnection( _rxConnection, UNO_SET_THROW )
104 ,m_xMetaData( _rxConnection->getMetaData(), UNO_SET_THROW )
105 ,m_xObject( _rxObject, UNO_SET_THROW )
106 ,m_xObjectPSI( _rxObject->getPropertySetInfo(), UNO_SET_THROW )
107 ,m_xObjectColumns( Reference< XColumnsSupplier >( _rxObject, UNO_QUERY_THROW )->getColumns(), UNO_SET_THROW )
111 OUString ObjectCopySource::getQualifiedObjectName() const
113 OUString sName;
115 if ( !m_xObjectPSI->hasPropertyByName( PROPERTY_COMMAND ) )
116 sName = ::dbtools::composeTableName( m_xMetaData, m_xObject, ::dbtools::EComposeRule::InDataManipulation, false, false, false );
117 else
118 m_xObject->getPropertyValue( PROPERTY_NAME ) >>= sName;
119 return sName;
122 bool ObjectCopySource::isView() const
124 bool bIsView = false;
127 if ( m_xObjectPSI->hasPropertyByName( PROPERTY_TYPE ) )
129 OUString sObjectType;
130 OSL_VERIFY( m_xObject->getPropertyValue( PROPERTY_TYPE ) >>= sObjectType );
131 bIsView = sObjectType == "VIEW";
134 catch( const Exception& )
136 DBG_UNHANDLED_EXCEPTION();
138 return bIsView;
141 void ObjectCopySource::copyUISettingsTo( const Reference< XPropertySet >& _rxObject ) const
143 const OUString aCopyProperties[] = {
144 OUString(PROPERTY_FONT), OUString(PROPERTY_ROW_HEIGHT), OUString(PROPERTY_TEXTCOLOR),OUString(PROPERTY_TEXTLINECOLOR),OUString(PROPERTY_TEXTEMPHASIS),OUString(PROPERTY_TEXTRELIEF)
146 for (const auto & aCopyPropertie : aCopyProperties)
148 if ( m_xObjectPSI->hasPropertyByName( aCopyPropertie ) )
149 _rxObject->setPropertyValue( aCopyPropertie, m_xObject->getPropertyValue( aCopyPropertie ) );
153 void ObjectCopySource::copyFilterAndSortingTo( const Reference< XConnection >& _xConnection,const Reference< XPropertySet >& _rxObject ) const
155 ::std::pair< OUString, OUString > aProperties[] = {
156 ::std::pair< OUString, OUString >(PROPERTY_FILTER,OUString(" AND "))
157 ,::std::pair< OUString, OUString >(PROPERTY_ORDER,OUString(" ORDER BY "))
162 const OUString sSourceName = ::dbtools::composeTableNameForSelect(m_xConnection,m_xObject) + ".";
163 const OUString sTargetName = ::dbtools::composeTableNameForSelect(_xConnection,_rxObject);
164 const OUString sTargetNameTemp = sTargetName + ".";
166 OUString sStatement = "SELECT * FROM " + sTargetName + " WHERE 0=1";
168 for (const std::pair<OUString,OUString> & aPropertie : aProperties)
170 if ( m_xObjectPSI->hasPropertyByName( aPropertie.first ) )
172 OUString sFilter;
173 m_xObject->getPropertyValue( aPropertie.first ) >>= sFilter;
174 if ( !sFilter.isEmpty() )
176 sStatement += aPropertie.second;
177 OUString sReplace = sFilter;
178 sReplace = sReplace.replaceFirst(sSourceName,sTargetNameTemp);
179 sFilter = sReplace;
180 _rxObject->setPropertyValue( aPropertie.first, makeAny(sFilter) );
181 sStatement += sFilter;
186 _xConnection->createStatement()->executeQuery(sStatement);
188 if ( m_xObjectPSI->hasPropertyByName( PROPERTY_APPLYFILTER ) )
189 _rxObject->setPropertyValue( PROPERTY_APPLYFILTER, m_xObject->getPropertyValue( PROPERTY_APPLYFILTER ) );
191 catch(Exception&)
196 Sequence< OUString > ObjectCopySource::getColumnNames() const
198 return m_xObjectColumns->getElementNames();
201 Sequence< OUString > ObjectCopySource::getPrimaryKeyColumnNames() const
203 const Reference<XNameAccess> xPrimaryKeyColumns = getPrimaryKeyColumns_throw(m_xObject);
204 Sequence< OUString > aKeyColNames;
205 if ( xPrimaryKeyColumns.is() )
206 aKeyColNames = xPrimaryKeyColumns->getElementNames();
207 return aKeyColNames;
210 OFieldDescription* ObjectCopySource::createFieldDescription( const OUString& _rColumnName ) const
212 Reference< XPropertySet > xColumn( m_xObjectColumns->getByName( _rColumnName ), UNO_QUERY_THROW );
213 return new OFieldDescription( xColumn );
216 OUString ObjectCopySource::getSelectStatement() const
218 OUString sSelectStatement;
219 if ( m_xObjectPSI->hasPropertyByName( PROPERTY_COMMAND ) )
220 { // query
221 OSL_VERIFY( m_xObject->getPropertyValue( PROPERTY_COMMAND ) >>= sSelectStatement );
223 else
224 { // table
225 OUStringBuffer aSQL;
226 aSQL.append( "SELECT " );
228 // we need to create the sql stmt with column names
229 // otherwise it is possible that names don't match
230 const OUString sQuote = m_xMetaData->getIdentifierQuoteString();
232 Sequence< OUString > aColumnNames = getColumnNames();
233 const OUString* pColumnName = aColumnNames.getConstArray();
234 const OUString* pEnd = pColumnName + aColumnNames.getLength();
235 for ( ; pColumnName != pEnd; )
237 aSQL.append( ::dbtools::quoteName( sQuote, *pColumnName++ ) );
239 if ( pColumnName == pEnd )
240 aSQL.append( " " );
241 else
242 aSQL.append( ", " );
245 aSQL.append( "FROM " + ::dbtools::composeTableNameForSelect( m_xConnection, m_xObject ) );
247 sSelectStatement = aSQL.makeStringAndClear();
250 return sSelectStatement;
253 ::utl::SharedUNOComponent< XPreparedStatement > ObjectCopySource::getPreparedSelectStatement() const
255 ::utl::SharedUNOComponent< XPreparedStatement > xStatement(
256 m_xConnection->prepareStatement( getSelectStatement() ),
257 ::utl::SharedUNOComponent< XPreparedStatement >::TakeOwnership
259 return xStatement;
262 // NamedTableCopySource
263 NamedTableCopySource::NamedTableCopySource( const Reference< XConnection >& _rxConnection, const OUString& _rTableName )
264 :m_xConnection( _rxConnection, UNO_SET_THROW )
265 ,m_xMetaData( _rxConnection->getMetaData(), UNO_SET_THROW )
266 ,m_sTableName( _rTableName )
267 ,m_aColumnInfo()
269 ::dbtools::qualifiedNameComponents( m_xMetaData, m_sTableName, m_sTableCatalog, m_sTableSchema, m_sTableBareName, ::dbtools::EComposeRule::Complete );
270 impl_ensureColumnInfo_throw();
273 OUString NamedTableCopySource::getQualifiedObjectName() const
275 return m_sTableName;
278 bool NamedTableCopySource::isView() const
280 OUString sTableType;
283 Reference< XResultSet > xTableDesc( m_xMetaData->getTables( makeAny( m_sTableCatalog ), m_sTableSchema, m_sTableBareName,
284 Sequence< OUString >() ) );
285 Reference< XRow > xTableDescRow( xTableDesc, UNO_QUERY_THROW );
286 OSL_VERIFY( xTableDesc->next() );
287 sTableType = xTableDescRow->getString( 4 );
288 OSL_ENSURE( !xTableDescRow->wasNull(), "NamedTableCopySource::isView: invalid table type!" );
290 catch( const Exception& )
292 DBG_UNHANDLED_EXCEPTION();
294 return sTableType == "VIEW";
297 void NamedTableCopySource::copyUISettingsTo( const Reference< XPropertySet >& /*_rxObject*/ ) const
299 // not supported: we do not have UI settings to copy
302 void NamedTableCopySource::copyFilterAndSortingTo( const Reference< XConnection >& ,const Reference< XPropertySet >& /*_rxObject*/ ) const
306 void NamedTableCopySource::impl_ensureColumnInfo_throw()
308 if ( !m_aColumnInfo.empty() )
309 return;
311 Reference< XResultSetMetaDataSupplier > xStatementMetaSupp( impl_ensureStatement_throw().getTyped(), UNO_QUERY_THROW );
312 Reference< XResultSetMetaData > xStatementMeta( xStatementMetaSupp->getMetaData(), UNO_SET_THROW );
314 sal_Int32 nColCount( xStatementMeta->getColumnCount() );
315 for ( sal_Int32 i = 1; i <= nColCount; ++i )
317 OFieldDescription aDesc;
319 aDesc.SetName( xStatementMeta->getColumnName( i ) );
320 aDesc.SetHelpText( xStatementMeta->getColumnLabel( i ) );
321 aDesc.SetTypeValue( xStatementMeta->getColumnType( i ) );
322 aDesc.SetTypeName( xStatementMeta->getColumnTypeName( i ) );
323 aDesc.SetPrecision( xStatementMeta->getPrecision( i ) );
324 aDesc.SetScale( xStatementMeta->getScale( i ) );
325 aDesc.SetIsNullable( xStatementMeta->isNullable( i ) );
326 aDesc.SetCurrency( xStatementMeta->isCurrency( i ) );
327 aDesc.SetAutoIncrement( xStatementMeta->isAutoIncrement( i ) );
329 m_aColumnInfo.push_back( aDesc );
333 ::utl::SharedUNOComponent< XPreparedStatement > NamedTableCopySource::impl_ensureStatement_throw()
335 if ( !m_xStatement.is() )
336 m_xStatement.set( m_xConnection->prepareStatement( getSelectStatement() ), UNO_SET_THROW );
337 return m_xStatement;
340 Sequence< OUString > NamedTableCopySource::getColumnNames() const
342 Sequence< OUString > aNames( m_aColumnInfo.size() );
343 for ( ::std::vector< OFieldDescription >::const_iterator col = m_aColumnInfo.begin();
344 col != m_aColumnInfo.end();
345 ++col
347 aNames[ col - m_aColumnInfo.begin() ] = col->GetName();
349 return aNames;
352 Sequence< OUString > NamedTableCopySource::getPrimaryKeyColumnNames() const
354 Sequence< OUString > aPKColNames;
358 Reference< XResultSet > xPKDesc( m_xMetaData->getPrimaryKeys( makeAny( m_sTableCatalog ), m_sTableSchema, m_sTableBareName ) );
359 Reference< XRow > xPKDescRow( xPKDesc, UNO_QUERY_THROW );
360 while ( xPKDesc->next() )
362 sal_Int32 len( aPKColNames.getLength() );
363 aPKColNames.realloc( len + 1 );
364 aPKColNames[ len ] = xPKDescRow->getString( 4 ); // COLUMN_NAME
367 catch( const Exception& )
369 DBG_UNHANDLED_EXCEPTION();
372 return aPKColNames;
375 OFieldDescription* NamedTableCopySource::createFieldDescription( const OUString& _rColumnName ) const
377 for ( ::std::vector< OFieldDescription >::const_iterator col = m_aColumnInfo.begin();
378 col != m_aColumnInfo.end();
379 ++col
381 if ( col->GetName() == _rColumnName )
382 return new OFieldDescription( *col );
384 return nullptr;
387 OUString NamedTableCopySource::getSelectStatement() const
389 OUStringBuffer aSQL;
390 aSQL.append( "SELECT * FROM " );
392 aSQL.append( ::dbtools::composeTableNameForSelect( m_xConnection, m_sTableCatalog, m_sTableSchema, m_sTableBareName ) );
394 return aSQL.makeStringAndClear();
397 ::utl::SharedUNOComponent< XPreparedStatement > NamedTableCopySource::getPreparedSelectStatement() const
399 return const_cast< NamedTableCopySource* >( this )->impl_ensureStatement_throw();
402 // DummyCopySource
403 class DummyCopySource : public ICopyTableSourceObject
405 public:
406 DummyCopySource() { }
408 static const DummyCopySource& Instance();
410 // ICopyTableSourceObject overridables
411 virtual OUString getQualifiedObjectName() const override;
412 virtual bool isView() const override;
413 virtual void copyUISettingsTo( const css::uno::Reference< css::beans::XPropertySet >& _rxObject ) const override;
414 virtual void copyFilterAndSortingTo(const css::uno::Reference< css::sdbc::XConnection >& _xConnection, const css::uno::Reference< css::beans::XPropertySet >& _rxObject ) const override;
415 virtual css::uno::Sequence< OUString >
416 getColumnNames() const override;
417 virtual css::uno::Sequence< OUString >
418 getPrimaryKeyColumnNames() const override;
419 virtual OFieldDescription* createFieldDescription( const OUString& _rColumnName ) const override;
420 virtual OUString getSelectStatement() const override;
421 virtual ::utl::SharedUNOComponent< XPreparedStatement >
422 getPreparedSelectStatement() const override;
425 const DummyCopySource& DummyCopySource::Instance()
427 static DummyCopySource s_aTheInstance;
428 return s_aTheInstance;
431 OUString DummyCopySource::getQualifiedObjectName() const
433 SAL_WARN("dbaccess.ui", "DummyCopySource::getQualifiedObjectName: not to be called!" );
434 return OUString();
437 bool DummyCopySource::isView() const
439 SAL_WARN("dbaccess.ui", "DummyCopySource::isView: not to be called!" );
440 return false;
443 void DummyCopySource::copyUISettingsTo( const Reference< XPropertySet >& /*_rxObject*/ ) const
445 // no support
448 void DummyCopySource::copyFilterAndSortingTo( const Reference< XConnection >& ,const Reference< XPropertySet >& /*_rxObject*/ ) const
452 Sequence< OUString > DummyCopySource::getColumnNames() const
454 return Sequence< OUString >();
457 Sequence< OUString > DummyCopySource::getPrimaryKeyColumnNames() const
459 SAL_WARN("dbaccess.ui", "DummyCopySource::getPrimaryKeyColumnNames: not to be called!" );
460 return Sequence< OUString >();
463 OFieldDescription* DummyCopySource::createFieldDescription( const OUString& /*_rColumnName*/ ) const
465 SAL_WARN("dbaccess.ui", "DummyCopySource::createFieldDescription: not to be called!" );
466 return nullptr;
469 OUString DummyCopySource::getSelectStatement() const
471 SAL_WARN("dbaccess.ui", "DummyCopySource::getSelectStatement: not to be called!" );
472 return OUString();
475 ::utl::SharedUNOComponent< XPreparedStatement > DummyCopySource::getPreparedSelectStatement() const
477 SAL_WARN("dbaccess.ui", "DummyCopySource::getPreparedSelectStatement: not to be called!" );
478 return ::utl::SharedUNOComponent< XPreparedStatement >();
481 namespace
483 bool lcl_canCreateViewFor_nothrow( const Reference< XConnection >& _rxConnection )
485 Reference< XViewsSupplier > xSup( _rxConnection, UNO_QUERY );
486 Reference< XDataDescriptorFactory > xViewFac;
487 if ( xSup.is() )
488 xViewFac.set( xSup->getViews(), UNO_QUERY );
489 return xViewFac.is();
492 bool lcl_sameConnection_throw( const Reference< XConnection >& _rxLHS, const Reference< XConnection >& _rxRHS )
494 Reference< XDatabaseMetaData > xMetaLHS( _rxLHS->getMetaData(), UNO_QUERY_THROW );
495 Reference< XDatabaseMetaData > xMetaRHS( _rxRHS->getMetaData(), UNO_QUERY_THROW );
496 return xMetaLHS->getURL().equals( xMetaRHS->getURL() );
500 // OCopyTableWizard
501 OCopyTableWizard::OCopyTableWizard( vcl::Window * pParent, const OUString& _rDefaultName, sal_Int16 _nOperation,
502 const ICopyTableSourceObject& _rSourceObject, const Reference< XConnection >& _xSourceConnection,
503 const Reference< XConnection >& _xConnection, const Reference< XComponentContext >& _rxContext,
504 const Reference< XInteractionHandler>& _xInteractionHandler)
505 : WizardDialog( pParent, "RTFCopyTable", "dbaccess/ui/rtfcopytabledialog.ui")
506 ,m_mNameMapping(_xConnection->getMetaData().is() && _xConnection->getMetaData()->supportsMixedCaseQuotedIdentifiers())
507 ,m_xDestConnection( _xConnection )
508 ,m_rSourceObject( _rSourceObject )
509 ,m_xFormatter( getNumberFormatter( _xConnection, _rxContext ) )
510 ,m_xContext(_rxContext)
511 ,m_xInteractionHandler(_xInteractionHandler)
512 ,m_sTypeNames(ModuleRes(STR_TABLEDESIGN_DBFIELDTYPES))
513 ,m_nPageCount(0)
514 ,m_bDeleteSourceColumns(true)
515 ,m_bInterConnectionCopy( _xSourceConnection != _xConnection )
516 ,m_sName( _rDefaultName )
517 ,m_nOperation( _nOperation )
518 ,m_ePressed( WIZARD_NONE )
519 ,m_bCreatePrimaryKeyColumn(false)
521 construct();
523 // extract table name
524 OUString sInitialTableName( _rDefaultName );
527 m_sSourceName = m_rSourceObject.getQualifiedObjectName();
528 OSL_ENSURE( !m_sSourceName.isEmpty(), "OCopyTableWizard::OCopyTableWizard: unable to retrieve the source object's name!" );
530 if ( sInitialTableName.isEmpty() )
531 sInitialTableName = m_sSourceName;
533 if ( m_sName.isEmpty() )
535 if ( _xSourceConnection == m_xDestConnection )
537 Reference< XTablesSupplier > xSup( m_xDestConnection, UNO_QUERY_THROW );
538 m_sName = ::dbtools::createUniqueName( xSup->getTables(), sInitialTableName, false );
540 else
541 m_sName = sInitialTableName;
544 catch ( const Exception& )
546 m_sName = sInitialTableName;
549 ::dbaui::fillTypeInfo( _xSourceConnection, m_sTypeNames, m_aTypeInfo, m_aTypeInfoIndex );
550 ::dbaui::fillTypeInfo( m_xDestConnection, m_sTypeNames, m_aDestTypeInfo, m_aDestTypeInfoIndex );
551 impl_loadSourceData();
553 bool bAllowViews = true;
554 // if the source is a, don't allow creating views
555 if ( m_rSourceObject.isView() )
556 bAllowViews = false;
557 // no views if the target connection does not support creating them
558 if ( !lcl_canCreateViewFor_nothrow( m_xDestConnection ) )
559 bAllowViews = false;
560 // no views if we're copying to a different database
561 if ( !lcl_sameConnection_throw( _xSourceConnection, m_xDestConnection ) )
562 bAllowViews = false;
564 if ( m_bInterConnectionCopy )
566 Reference< XDatabaseMetaData > xSrcMeta = _xSourceConnection->getMetaData();
567 OUString sCatalog;
568 OUString sSchema;
569 OUString sTable;
570 ::dbtools::qualifiedNameComponents( xSrcMeta,
571 m_sName,
572 sCatalog,
573 sSchema,
574 sTable,
575 ::dbtools::EComposeRule::InDataManipulation);
577 m_sName = ::dbtools::composeTableName(m_xDestConnection->getMetaData(),sCatalog,sSchema,sTable,false,::dbtools::EComposeRule::InTableDefinitions);
580 VclPtrInstance<OCopyTable> pPage1( this );
581 pPage1->disallowUseHeaderLine();
582 if ( !bAllowViews )
583 pPage1->disallowViews();
584 pPage1->setCreateStyleAction();
585 AddWizardPage(pPage1);
587 AddWizardPage( VclPtr<OWizNameMatching>::Create( this ) );
588 AddWizardPage( VclPtr<OWizColumnSelect>::Create( this ) );
589 AddWizardPage( VclPtr<OWizNormalExtend>::Create( this ) );
590 ActivatePage();
593 OCopyTableWizard::OCopyTableWizard( vcl::Window* pParent, const OUString& _rDefaultName, sal_Int16 _nOperation,
594 const ODatabaseExport::TColumns& _rSourceColumns, const ODatabaseExport::TColumnVector& _rSourceColVec,
595 const Reference< XConnection >& _xConnection, const Reference< XNumberFormatter >& _xFormatter,
596 TypeSelectionPageFactory _pTypeSelectionPageFactory, SvStream& _rTypeSelectionPageArg, const Reference< XComponentContext >& _rxContext )
597 :WizardDialog( pParent, "RTFCopyTable", "dbaccess/ui/rtfcopytabledialog.ui")
598 ,m_vSourceColumns(_rSourceColumns)
599 ,m_mNameMapping(_xConnection->getMetaData().is() && _xConnection->getMetaData()->supportsMixedCaseQuotedIdentifiers())
600 ,m_xDestConnection( _xConnection )
601 ,m_rSourceObject( DummyCopySource::Instance() )
602 ,m_xFormatter(_xFormatter)
603 ,m_xContext(_rxContext)
604 ,m_sTypeNames(ModuleRes(STR_TABLEDESIGN_DBFIELDTYPES))
605 ,m_nPageCount(0)
606 ,m_bDeleteSourceColumns(false)
607 ,m_bInterConnectionCopy( false )
608 ,m_sName(_rDefaultName)
609 ,m_nOperation( _nOperation )
610 ,m_ePressed( WIZARD_NONE )
611 ,m_bCreatePrimaryKeyColumn(false)
613 construct();
614 ODatabaseExport::TColumnVector::const_iterator aIter = _rSourceColVec.begin();
615 ODatabaseExport::TColumnVector::const_iterator aEnd = _rSourceColVec.end();
616 for (; aIter != aEnd ; ++aIter)
618 m_vSourceVec.push_back(m_vSourceColumns.find((*aIter)->first));
621 ::dbaui::fillTypeInfo( _xConnection, m_sTypeNames, m_aTypeInfo, m_aTypeInfoIndex );
622 ::dbaui::fillTypeInfo( _xConnection, m_sTypeNames, m_aDestTypeInfo, m_aDestTypeInfoIndex );
624 m_xInteractionHandler.set( InteractionHandler::createWithParent(m_xContext, nullptr), UNO_QUERY );
626 VclPtrInstance<OCopyTable> pPage1( this );
627 pPage1->disallowViews();
628 pPage1->setCreateStyleAction();
629 AddWizardPage( pPage1 );
631 AddWizardPage( VclPtr<OWizNameMatching>::Create( this ) );
632 AddWizardPage( VclPtr<OWizColumnSelect>::Create( this ) );
633 AddWizardPage( (*_pTypeSelectionPageFactory)( this, _rTypeSelectionPageArg ) );
635 ActivatePage();
638 void OCopyTableWizard::construct()
640 SetSizePixel(Size(580, 350));
642 AddButton( m_pbHelp = VclPtr<HelpButton>::Create(this, WB_TABSTOP) );
643 AddButton( m_pbCancel = VclPtr<CancelButton>::Create(this, WB_TABSTOP) );
644 AddButton( m_pbPrev = VclPtr<PushButton>::Create(this, WB_TABSTOP));
645 AddButton( m_pbNext = VclPtr<PushButton>::Create(this, WB_TABSTOP));
646 AddButton( m_pbFinish = VclPtr<PushButton>::Create(this, WB_TABSTOP));
648 m_pbHelp->SetSizePixel( LogicToPixel( Size( 50, 14 ), MAP_APPFONT ) );
649 m_pbCancel->SetSizePixel( LogicToPixel( Size( 50, 14 ), MAP_APPFONT ) );
650 m_pbPrev->SetSizePixel( LogicToPixel( Size( 50, 14 ), MAP_APPFONT ) );
651 m_pbNext->SetSizePixel( LogicToPixel( Size( 50, 14 ), MAP_APPFONT ) );
652 m_pbFinish->SetSizePixel( LogicToPixel( Size( 50, 14 ), MAP_APPFONT ) );
654 m_pbPrev->SetText(ModuleRes(STR_WIZ_PB_PREV));
655 m_pbNext->SetText(ModuleRes(STR_WIZ_PB_NEXT));
656 m_pbFinish->SetText(ModuleRes(STR_WIZ_PB_OK));
658 m_pbHelp->Show();
659 m_pbCancel->Show();
660 m_pbPrev->Show();
661 m_pbNext->Show();
662 m_pbFinish->Show();
664 m_pbPrev->SetClickHdl( LINK( this, OCopyTableWizard, ImplPrevHdl ) );
665 m_pbNext->SetClickHdl( LINK( this, OCopyTableWizard, ImplNextHdl ) );
666 m_pbFinish->SetClickHdl( LINK( this, OCopyTableWizard, ImplOKHdl ) );
668 SetActivatePageHdl( LINK( this, OCopyTableWizard, ImplActivateHdl ) );
670 SetPrevButton( m_pbPrev );
671 SetNextButton( m_pbNext );
673 m_pbNext->GrabFocus();
675 if (m_vDestColumns.size())
676 // source is a html or rtf table
677 m_pbNext->SetStyle(m_pbFinish->GetStyle() | WB_DEFBUTTON);
678 else
679 m_pbFinish->SetStyle(m_pbFinish->GetStyle() | WB_DEFBUTTON);
681 m_pTypeInfo = std::make_shared<OTypeInfo>();
682 m_pTypeInfo->aUIName = m_sTypeNames.getToken(TYPE_OTHER, ';');
683 m_bAddPKFirstTime = true;
686 OCopyTableWizard::~OCopyTableWizard()
688 disposeOnce();
691 void OCopyTableWizard::dispose()
693 for ( ;; )
695 VclPtr<TabPage> pPage = GetPage(0);
696 if ( pPage == nullptr )
697 break;
698 RemovePage( pPage );
699 pPage.disposeAndClear();
702 if ( m_bDeleteSourceColumns )
703 clearColumns(m_vSourceColumns,m_vSourceVec);
705 clearColumns(m_vDestColumns,m_aDestVec);
707 // clear the type information
708 m_aTypeInfoIndex.clear();
709 m_aTypeInfo.clear();
710 m_aDestTypeInfoIndex.clear();
712 m_pbHelp.disposeAndClear();
713 m_pbCancel.disposeAndClear();
714 m_pbPrev.disposeAndClear();
715 m_pbNext.disposeAndClear();
716 m_pbFinish.disposeAndClear();
717 WizardDialog::dispose();
720 IMPL_LINK_NOARG_TYPED(OCopyTableWizard, ImplPrevHdl, Button*, void)
722 m_ePressed = WIZARD_PREV;
723 if ( GetCurLevel() )
725 if ( getOperation() != CopyTableOperation::AppendData )
727 if(GetCurLevel() == 2)
728 ShowPage(GetCurLevel()-2);
729 else
730 ShowPrevPage();
732 else
733 ShowPrevPage();
737 IMPL_LINK_NOARG_TYPED(OCopyTableWizard, ImplNextHdl, Button*, void)
739 m_ePressed = WIZARD_NEXT;
740 if ( GetCurLevel() < MAX_PAGES )
742 if ( getOperation() != CopyTableOperation::AppendData )
744 if(GetCurLevel() == 0)
745 ShowPage(GetCurLevel()+2);
746 else
747 ShowNextPage();
749 else
750 ShowNextPage();
754 bool OCopyTableWizard::CheckColumns(sal_Int32& _rnBreakPos)
756 bool bRet = true;
757 m_vColumnPos.clear();
758 m_vColumnTypes.clear();
760 OSL_ENSURE( m_xDestConnection.is(), "OCopyTableWizard::CheckColumns: No connection!" );
761 // If database is able to process PrimaryKeys, set PrimaryKey
762 if ( m_xDestConnection.is() )
764 bool bPKeyAllowed = supportsPrimaryKey();
766 bool bContainsColumns = !m_vDestColumns.empty();
768 if ( bPKeyAllowed && shouldCreatePrimaryKey() )
770 // add extra column for the primary key
771 TOTypeInfoSP pTypeInfo = queryPrimaryKeyType(m_aDestTypeInfo);
772 if ( pTypeInfo.get() )
774 if ( m_bAddPKFirstTime )
776 OFieldDescription* pField = new OFieldDescription();
777 pField->SetName(m_aKeyName);
778 pField->FillFromTypeInfo(pTypeInfo,true,true);
779 pField->SetPrimaryKey(true);
780 m_bAddPKFirstTime = false;
781 insertColumn(0,pField);
783 m_vColumnPos.push_back(ODatabaseExport::TPositions::value_type(1,1));
784 m_vColumnTypes.push_back(pTypeInfo->nType);
788 if ( bContainsColumns )
789 { // we have dest columns so look for the matching column
790 ODatabaseExport::TColumnVector::const_iterator aSrcIter = m_vSourceVec.begin();
791 ODatabaseExport::TColumnVector::const_iterator aSrcEnd = m_vSourceVec.end();
792 for(;aSrcIter != aSrcEnd;++aSrcIter)
794 ODatabaseExport::TColumns::const_iterator aDestIter = m_vDestColumns.find(m_mNameMapping[(*aSrcIter)->first]);
796 if ( aDestIter != m_vDestColumns.end() )
798 ODatabaseExport::TColumnVector::const_iterator aFind = ::std::find(m_aDestVec.begin(),m_aDestVec.end(),aDestIter);
799 sal_Int32 nPos = (aFind - m_aDestVec.begin())+1;
800 m_vColumnPos.push_back(ODatabaseExport::TPositions::value_type(nPos,nPos));
801 m_vColumnTypes.push_back((*aFind)->second->GetType());
803 else
805 m_vColumnPos.push_back( ODatabaseExport::TPositions::value_type( COLUMN_POSITION_NOT_FOUND, COLUMN_POSITION_NOT_FOUND ) );
806 m_vColumnTypes.push_back(0);
810 else
812 Reference< XDatabaseMetaData > xMetaData( m_xDestConnection->getMetaData() );
813 OUString sExtraChars = xMetaData->getExtraNameCharacters();
814 sal_Int32 nMaxNameLen = getMaxColumnNameLength();
816 ODatabaseExport::TColumnVector::const_iterator aSrcIter = m_vSourceVec.begin();
817 ODatabaseExport::TColumnVector::const_iterator aSrcEnd = m_vSourceVec.end();
818 for(_rnBreakPos=0;aSrcIter != aSrcEnd && bRet ;++aSrcIter,++_rnBreakPos)
820 OFieldDescription* pField = new OFieldDescription(*(*aSrcIter)->second);
821 pField->SetName(convertColumnName(TExportColumnFindFunctor(&m_vDestColumns),(*aSrcIter)->first,sExtraChars,nMaxNameLen));
822 TOTypeInfoSP pType = convertType((*aSrcIter)->second->getSpecialTypeInfo(),bRet);
823 pField->SetType(pType);
824 if ( !bPKeyAllowed )
825 pField->SetPrimaryKey(false);
827 // now create a column
828 insertColumn(m_vDestColumns.size(),pField);
829 m_vColumnPos.push_back(ODatabaseExport::TPositions::value_type(m_vDestColumns.size(),m_vDestColumns.size()));
830 m_vColumnTypes.push_back((*aSrcIter)->second->GetType());
834 return bRet;
837 IMPL_LINK_NOARG_TYPED(OCopyTableWizard, ImplOKHdl, Button*, void)
839 m_ePressed = WIZARD_FINISH;
840 bool bFinish = DeactivatePage();
842 if(bFinish)
844 WaitObject aWait(this);
845 switch(getOperation())
847 case CopyTableOperation::CopyDefinitionAndData:
848 case CopyTableOperation::CopyDefinitionOnly:
850 bool bOnFirstPage = GetCurLevel() == 0;
851 if ( bOnFirstPage )
853 // we came from the first page so we have to clear
854 // all column information already collected
855 clearDestColumns();
856 m_mNameMapping.clear();
858 sal_Int32 nBreakPos = 0;
859 bool bCheckOk = CheckColumns(nBreakPos);
860 if ( bOnFirstPage && !bCheckOk )
862 showColumnTypeNotSupported(m_vSourceVec[nBreakPos-1]->first);
863 OWizTypeSelect* pPage = static_cast<OWizTypeSelect*>(GetPage(3));
864 if ( pPage )
866 m_mNameMapping.clear();
867 pPage->setDisplayRow(nBreakPos);
868 ShowPage(3);
869 return;
872 if ( m_xDestConnection.is() )
874 if ( supportsPrimaryKey() )
876 ODatabaseExport::TColumns::const_iterator aFind = ::std::find_if(m_vDestColumns.begin(),m_vDestColumns.end(),
877 [] (const ODatabaseExport::TColumns::value_type& tCol) { return tCol.second->IsPrimaryKey(); });
878 if ( aFind == m_vDestColumns.end() && m_xInteractionHandler.is() )
881 OUString sMsg(ModuleRes(STR_TABLEDESIGN_NO_PRIM_KEY));
882 SQLContext aError;
883 aError.Message = sMsg;
884 ::rtl::Reference< ::comphelper::OInteractionRequest > xRequest( new ::comphelper::OInteractionRequest( makeAny( aError ) ) );
885 ::rtl::Reference< ::comphelper::OInteractionApprove > xYes = new ::comphelper::OInteractionApprove;
886 xRequest->addContinuation( xYes.get() );
887 xRequest->addContinuation( new ::comphelper::OInteractionDisapprove );
888 ::rtl::Reference< ::comphelper::OInteractionAbort > xAbort = new ::comphelper::OInteractionAbort;
889 xRequest->addContinuation( xAbort.get() );
891 m_xInteractionHandler->handle( xRequest.get() );
893 if ( xYes->wasSelected() )
895 OCopyTable* pPage = static_cast<OCopyTable*>(GetPage(0));
896 m_bCreatePrimaryKeyColumn = true;
897 m_aKeyName = pPage->GetKeyName();
898 if ( m_aKeyName.isEmpty() )
899 m_aKeyName = "ID";
900 m_aKeyName = createUniqueName( m_aKeyName );
901 sal_Int32 nBreakPos2 = 0;
902 CheckColumns(nBreakPos2);
904 else if ( xAbort->wasSelected() )
906 ShowPage(3);
907 return;
912 break;
914 case CopyTableOperation::AppendData:
915 case CopyTableOperation::CreateAsView:
916 break;
917 default:
919 SAL_WARN("dbaccess.ui", "OCopyTableWizard::ImplOKHdl: invalid creation style!");
923 EndDialog(RET_OK);
928 void OCopyTableWizard::setCreatePrimaryKey( bool _bDoCreate, const OUString& _rSuggestedName )
930 m_bCreatePrimaryKeyColumn = _bDoCreate;
931 if ( !_rSuggestedName.isEmpty() )
932 m_aKeyName = _rSuggestedName;
934 OCopyTable* pSettingsPage = dynamic_cast< OCopyTable* >( GetPage( 0 ) );
935 OSL_ENSURE( pSettingsPage, "OCopyTableWizard::setCreatePrimaryKey: page should have been added in the ctor!" );
936 if ( pSettingsPage )
937 pSettingsPage->setCreatePrimaryKey( _bDoCreate, _rSuggestedName );
940 IMPL_LINK_NOARG_TYPED(OCopyTableWizard, ImplActivateHdl, WizardDialog*, void)
942 OWizardPage* pCurrent = static_cast<OWizardPage*>(GetPage(GetCurLevel()));
943 if(pCurrent)
945 bool bFirstTime = pCurrent->IsFirstTime();
946 if(bFirstTime)
947 pCurrent->Reset();
949 CheckButtons();
951 SetText(pCurrent->GetTitle());
953 Invalidate();
957 void OCopyTableWizard::CheckButtons()
959 if(GetCurLevel() == 0) // the first page has no back button
961 if(m_nPageCount > 1)
962 m_pbNext->Enable();
963 else
964 m_pbNext->Enable(false);
966 m_pbPrev->Enable(false);
968 else if(GetCurLevel() == m_nPageCount-1) // the last page has no next button
970 m_pbNext->Enable(false);
971 m_pbPrev->Enable();
973 else
975 m_pbPrev->Enable();
976 // next already has its state
980 void OCopyTableWizard::EnableNextButton(bool bEnable)
982 m_pbNext->Enable(bEnable);
985 bool OCopyTableWizard::DeactivatePage()
987 OWizardPage* pPage = static_cast<OWizardPage*>(GetPage(GetCurLevel()));
988 return pPage && pPage->LeavePage();
991 void OCopyTableWizard::AddWizardPage(OWizardPage* pPage)
993 AddPage(pPage);
994 ++m_nPageCount;
997 void OCopyTableWizard::insertColumn(sal_Int32 _nPos,OFieldDescription* _pField)
999 OSL_ENSURE(_pField,"FieldDescrioption is null!");
1000 if ( _pField )
1002 ODatabaseExport::TColumns::const_iterator aFind = m_vDestColumns.find(_pField->GetName());
1003 if ( aFind != m_vDestColumns.end() )
1005 delete aFind->second;
1006 m_vDestColumns.erase(aFind);
1009 m_aDestVec.insert(m_aDestVec.begin() + _nPos,
1010 m_vDestColumns.insert(ODatabaseExport::TColumns::value_type(_pField->GetName(),_pField)).first);
1011 m_mNameMapping[_pField->GetName()] = _pField->GetName();
1015 void OCopyTableWizard::replaceColumn(sal_Int32 _nPos,OFieldDescription* _pField,const OUString& _sOldName)
1017 OSL_ENSURE(_pField,"FieldDescrioption is null!");
1018 if ( _pField )
1020 m_vDestColumns.erase(_sOldName);
1021 OSL_ENSURE( m_vDestColumns.find(_pField->GetName()) == m_vDestColumns.end(),"Column with that name already exist!");
1023 m_aDestVec[_nPos] =
1024 m_vDestColumns.insert(ODatabaseExport::TColumns::value_type(_pField->GetName(),_pField)).first;
1028 void OCopyTableWizard::impl_loadSourceData()
1030 loadData( m_rSourceObject, m_vSourceColumns, m_vSourceVec );
1033 void OCopyTableWizard::loadData( const ICopyTableSourceObject& _rSourceObject, ODatabaseExport::TColumns& _rColumns, ODatabaseExport::TColumnVector& _rColVector )
1035 ODatabaseExport::TColumns::const_iterator colEnd = _rColumns.end();
1036 for ( ODatabaseExport::TColumns::const_iterator col = _rColumns.begin(); col != colEnd; ++col )
1037 delete col->second;
1039 _rColVector.clear();
1040 _rColumns.clear();
1042 OFieldDescription* pActFieldDescr = nullptr;
1043 OUString sCreateParam("x");
1044 // ReadOnly-Flag
1045 // On drop no line must be editable.
1046 // On add only empty lines must be editable.
1047 // On Add and Drop all lines can be edited.
1048 Sequence< OUString > aColumns( _rSourceObject.getColumnNames() );
1049 const OUString* pColumn = aColumns.getConstArray();
1050 const OUString* pColumnEnd = pColumn + aColumns.getLength();
1052 for ( ; pColumn != pColumnEnd; ++pColumn )
1054 // get the properties of the column
1055 pActFieldDescr = _rSourceObject.createFieldDescription( *pColumn );
1056 OSL_ENSURE( pActFieldDescr, "OCopyTableWizard::loadData: illegal field description!" );
1057 if ( !pActFieldDescr )
1058 continue;
1060 sal_Int32 nType = pActFieldDescr->GetType();
1061 sal_Int32 nScale = pActFieldDescr->GetScale();
1062 sal_Int32 nPrecision = pActFieldDescr->GetPrecision();
1063 bool bAutoIncrement = pActFieldDescr->IsAutoIncrement();
1064 OUString sTypeName = pActFieldDescr->GetTypeName();
1066 // search for type
1067 bool bForce;
1068 TOTypeInfoSP pTypeInfo = ::dbaui::getTypeInfoFromType(m_aTypeInfo,nType,sTypeName,sCreateParam,nPrecision,nScale,bAutoIncrement,bForce);
1069 if ( !pTypeInfo.get() )
1070 pTypeInfo = m_pTypeInfo;
1072 pActFieldDescr->FillFromTypeInfo(pTypeInfo,true,false);
1073 _rColVector.push_back(_rColumns.insert(ODatabaseExport::TColumns::value_type(pActFieldDescr->GetName(),pActFieldDescr)).first);
1076 // determine which columns belong to the primary key
1077 Sequence< OUString > aPrimaryKeyColumns( _rSourceObject.getPrimaryKeyColumnNames() );
1078 const OUString* pKeyColName = aPrimaryKeyColumns.getConstArray();
1079 const OUString* pKeyColEnd = pKeyColName + aPrimaryKeyColumns.getLength();
1081 for( ; pKeyColName != pKeyColEnd; ++pKeyColName )
1083 ODatabaseExport::TColumns::const_iterator keyPos = _rColumns.find( *pKeyColName );
1084 if ( keyPos != _rColumns.end() )
1086 keyPos->second->SetPrimaryKey( true );
1087 keyPos->second->SetIsNullable( ColumnValue::NO_NULLS );
1092 void OCopyTableWizard::clearDestColumns()
1094 clearColumns(m_vDestColumns,m_aDestVec);
1095 m_bAddPKFirstTime = true;
1096 m_mNameMapping.clear();
1099 void OCopyTableWizard::appendColumns( Reference<XColumnsSupplier>& _rxColSup, const ODatabaseExport::TColumnVector* _pVec, bool _bKeyColumns)
1101 // now append the columns
1102 OSL_ENSURE(_rxColSup.is(),"No columns supplier");
1103 if(!_rxColSup.is())
1104 return;
1105 Reference<XNameAccess> xColumns = _rxColSup->getColumns();
1106 OSL_ENSURE(xColumns.is(),"No columns");
1107 Reference<XDataDescriptorFactory> xColumnFactory(xColumns,UNO_QUERY);
1109 Reference<XAppend> xAppend(xColumns,UNO_QUERY);
1110 OSL_ENSURE(xAppend.is(),"No XAppend Interface!");
1112 ODatabaseExport::TColumnVector::const_iterator aIter = _pVec->begin();
1113 ODatabaseExport::TColumnVector::const_iterator aEnd = _pVec->end();
1114 for(;aIter != aEnd;++aIter)
1116 OFieldDescription* pField = (*aIter)->second;
1117 if(!pField)
1118 continue;
1120 Reference<XPropertySet> xColumn;
1121 if(pField->IsPrimaryKey() || !_bKeyColumns)
1122 xColumn = xColumnFactory->createDataDescriptor();
1123 if(xColumn.is())
1125 if(!_bKeyColumns)
1126 dbaui::setColumnProperties(xColumn,pField);
1127 else
1128 xColumn->setPropertyValue(PROPERTY_NAME,makeAny(pField->GetName()));
1130 xAppend->appendByDescriptor(xColumn);
1131 xColumn = nullptr;
1132 // now only the settings are missing
1133 if(xColumns->hasByName(pField->GetName()))
1135 xColumn.set(xColumns->getByName(pField->GetName()),UNO_QUERY);
1136 OSL_ENSURE(xColumn.is(),"OCopyTableWizard::appendColumns: Column is NULL!");
1137 if ( xColumn.is() )
1138 pField->copyColumnSettingsTo(xColumn);
1140 else
1142 SAL_WARN("dbaccess.ui", "OCopyTableWizard::appendColumns: invalid field name!");
1149 void OCopyTableWizard::appendKey( Reference<XKeysSupplier>& _rxSup, const ODatabaseExport::TColumnVector* _pVec)
1151 if(!_rxSup.is())
1152 return; // the database doesn't support keys
1153 OSL_ENSURE(_rxSup.is(),"No XKeysSupplier!");
1154 Reference<XDataDescriptorFactory> xKeyFactory(_rxSup->getKeys(),UNO_QUERY);
1155 OSL_ENSURE(xKeyFactory.is(),"No XDataDescriptorFactory Interface!");
1156 if ( !xKeyFactory.is() )
1157 return;
1158 Reference<XAppend> xAppend(xKeyFactory,UNO_QUERY);
1159 OSL_ENSURE(xAppend.is(),"No XAppend Interface!");
1161 Reference<XPropertySet> xKey = xKeyFactory->createDataDescriptor();
1162 OSL_ENSURE(xKey.is(),"Key is null!");
1163 xKey->setPropertyValue(PROPERTY_TYPE,makeAny(KeyType::PRIMARY));
1165 Reference<XColumnsSupplier> xColSup(xKey,UNO_QUERY);
1166 if(xColSup.is())
1168 appendColumns(xColSup,_pVec,true);
1169 Reference<XNameAccess> xColumns = xColSup->getColumns();
1170 if(xColumns.is() && xColumns->getElementNames().getLength())
1171 xAppend->appendByDescriptor(xKey);
1176 Reference< XPropertySet > OCopyTableWizard::createView() const
1178 OUString sCommand( m_rSourceObject.getSelectStatement() );
1179 OSL_ENSURE( !sCommand.isEmpty(), "OCopyTableWizard::createView: no statement in the source object!" );
1180 // there are legitimate cases in which getSelectStatement does not provide a statement,
1181 // but in all those cases, this method here should never be called.
1182 return ::dbaui::createView( m_sName, m_xDestConnection, sCommand );
1185 Reference< XPropertySet > OCopyTableWizard::createTable()
1187 Reference< XPropertySet > xTable;
1189 Reference<XTablesSupplier> xSup( m_xDestConnection, UNO_QUERY );
1190 Reference< XNameAccess > xTables;
1191 if(xSup.is())
1192 xTables = xSup->getTables();
1193 if ( getOperation() != CopyTableOperation::AppendData )
1195 Reference<XDataDescriptorFactory> xFact(xTables,UNO_QUERY);
1196 OSL_ENSURE(xFact.is(),"No XDataDescriptorFactory available!");
1197 if(!xFact.is())
1198 return nullptr;
1200 xTable = xFact->createDataDescriptor();
1201 OSL_ENSURE(xTable.is(),"Could not create a new object!");
1202 if(!xTable.is())
1203 return nullptr;
1205 OUString sCatalog,sSchema,sTable;
1206 Reference< XDatabaseMetaData> xMetaData = m_xDestConnection->getMetaData();
1207 ::dbtools::qualifiedNameComponents(xMetaData,
1208 m_sName,
1209 sCatalog,
1210 sSchema,
1211 sTable,
1212 ::dbtools::EComposeRule::InDataManipulation);
1214 if ( sCatalog.isEmpty() && xMetaData->supportsCatalogsInTableDefinitions() )
1216 sCatalog = m_xDestConnection->getCatalog();
1219 if ( sSchema.isEmpty() && xMetaData->supportsSchemasInTableDefinitions() )
1221 sSchema = xMetaData->getUserName();
1224 xTable->setPropertyValue(PROPERTY_CATALOGNAME,makeAny(sCatalog));
1225 xTable->setPropertyValue(PROPERTY_SCHEMANAME,makeAny(sSchema));
1226 xTable->setPropertyValue(PROPERTY_NAME,makeAny(sTable));
1228 Reference< XColumnsSupplier > xSuppDestinationColumns( xTable, UNO_QUERY );
1229 // now append the columns
1230 const ODatabaseExport::TColumnVector& rVec = getDestVector();
1231 appendColumns( xSuppDestinationColumns, &rVec );
1232 // now append the primary key
1233 Reference<XKeysSupplier> xKeySup(xTable,UNO_QUERY);
1234 appendKey(xKeySup, &rVec);
1236 Reference<XAppend> xAppend(xTables,UNO_QUERY);
1237 if(xAppend.is())
1238 xAppend->appendByDescriptor(xTable);
1240 // xTable = NULL;
1241 // we need to reget the table because after appending it, it is no longer valid
1242 if(xTables->hasByName(m_sName))
1243 xTables->getByName(m_sName) >>= xTable;
1244 else
1246 OUString sComposedName(
1247 ::dbtools::composeTableName( m_xDestConnection->getMetaData(), xTable, ::dbtools::EComposeRule::InDataManipulation, false, false, false ) );
1248 if(xTables->hasByName(sComposedName))
1250 xTables->getByName(sComposedName) >>= xTable;
1251 m_sName = sComposedName;
1253 else
1254 xTable = nullptr;
1256 if(xTable.is())
1258 xSuppDestinationColumns.set( xTable, UNO_QUERY_THROW );
1259 // insert new table name into table filter
1260 ::dbaui::appendToFilter( m_xDestConnection, m_sName, GetComponentContext(), this );
1262 // copy ui settings
1263 m_rSourceObject.copyUISettingsTo( xTable );
1264 //copy filter and sorting
1265 m_rSourceObject.copyFilterAndSortingTo(m_xDestConnection,xTable);
1266 // set column mappings
1267 Reference<XNameAccess> xNameAccess = xSuppDestinationColumns->getColumns();
1268 Sequence< OUString> aSeq = xNameAccess->getElementNames();
1269 const OUString* pIter = aSeq.getConstArray();
1270 const OUString* pEnd = pIter + aSeq.getLength();
1272 for(sal_Int32 nNewPos=1;pIter != pEnd;++pIter,++nNewPos)
1274 ODatabaseExport::TColumns::const_iterator aDestIter = m_vDestColumns.find(*pIter);
1276 if ( aDestIter != m_vDestColumns.end() )
1278 ODatabaseExport::TColumnVector::const_iterator aFind = ::std::find(m_aDestVec.begin(),m_aDestVec.end(),aDestIter);
1279 sal_Int32 nPos = (aFind - m_aDestVec.begin())+1;
1281 ODatabaseExport::TPositions::iterator aPosFind = ::std::find_if(
1282 m_vColumnPos.begin(),
1283 m_vColumnPos.end(),
1284 [nPos] (const ODatabaseExport::TPositions::value_type& tPos) {
1285 return tPos.first == nPos;
1289 if ( m_vColumnPos.end() != aPosFind )
1291 aPosFind->second = nNewPos;
1292 OSL_ENSURE( m_vColumnTypes.size() > size_t( aPosFind - m_vColumnPos.begin() ),
1293 "Invalid index for vector!" );
1294 m_vColumnTypes[ aPosFind - m_vColumnPos.begin() ] = (*aFind)->second->GetType();
1300 else if(xTables.is() && xTables->hasByName(m_sName))
1301 xTables->getByName(m_sName) >>= xTable;
1303 return xTable;
1306 bool OCopyTableWizard::supportsPrimaryKey( const Reference< XConnection >& _rxConnection )
1308 OSL_PRECOND( _rxConnection.is(), "OCopyTableWizard::supportsPrimaryKey: invalid connection!" );
1309 if ( !_rxConnection.is() )
1310 return false;
1312 ::dbtools::DatabaseMetaData aMetaData( _rxConnection );
1313 return aMetaData.supportsPrimaryKeys();
1316 bool OCopyTableWizard::supportsViews( const Reference< XConnection >& _rxConnection )
1318 OSL_PRECOND( _rxConnection.is(), "OCopyTableWizard::supportsViews: invalid connection!" );
1319 if ( !_rxConnection.is() )
1320 return false;
1322 bool bSupportsViews( false );
1325 Reference< XDatabaseMetaData > xMetaData( _rxConnection->getMetaData(), UNO_SET_THROW );
1326 Reference< XViewsSupplier > xViewSups( _rxConnection, UNO_QUERY );
1327 bSupportsViews = xViewSups.is();
1328 if ( !bSupportsViews )
1332 Reference< XResultSet > xRs( xMetaData->getTableTypes(), UNO_SET_THROW );
1333 Reference< XRow > xRow( xRs, UNO_QUERY_THROW );
1334 while ( xRs->next() )
1336 OUString sValue = xRow->getString( 1 );
1337 if ( !xRow->wasNull() && sValue.equalsIgnoreAsciiCase("View") )
1339 bSupportsViews = true;
1340 break;
1344 catch( const SQLException& )
1346 DBG_UNHANDLED_EXCEPTION();
1350 catch( const Exception& )
1352 DBG_UNHANDLED_EXCEPTION();
1354 return bSupportsViews;
1357 sal_Int32 OCopyTableWizard::getMaxColumnNameLength() const
1359 sal_Int32 nLen = 0;
1360 if ( m_xDestConnection.is() )
1364 Reference< XDatabaseMetaData > xMetaData( m_xDestConnection->getMetaData(), UNO_SET_THROW );
1365 nLen = xMetaData->getMaxColumnNameLength();
1367 catch(const Exception&)
1369 DBG_UNHANDLED_EXCEPTION();
1372 return nLen;
1375 void OCopyTableWizard::setOperation( const sal_Int16 _nOperation )
1377 m_nOperation = _nOperation;
1381 OUString OCopyTableWizard::convertColumnName(const TColumnFindFunctor& _rCmpFunctor,
1382 const OUString& _sColumnName,
1383 const OUString& _sExtraChars,
1384 sal_Int32 _nMaxNameLen)
1386 OUString sAlias = _sColumnName;
1387 if ( isSQL92CheckEnabled( m_xDestConnection ) )
1388 sAlias = ::dbtools::convertName2SQLName(_sColumnName,_sExtraChars);
1389 if((_nMaxNameLen && sAlias.getLength() > _nMaxNameLen) || _rCmpFunctor(sAlias))
1391 sal_Int32 nDiff = 1;
1394 ++nDiff;
1395 if(_nMaxNameLen && sAlias.getLength() >= _nMaxNameLen)
1396 sAlias = sAlias.copy(0,sAlias.getLength() - (sAlias.getLength()-_nMaxNameLen+nDiff));
1398 OUString sName(sAlias);
1399 sal_Int32 nPos = 1;
1400 sName += OUString::number(nPos);
1402 while(_rCmpFunctor(sName))
1404 sName = sAlias;
1405 sName += OUString::number(++nPos);
1407 sAlias = sName;
1408 // we have to check again, it could happen that the name is already to long
1410 while(_nMaxNameLen && sAlias.getLength() > _nMaxNameLen);
1412 OSL_ENSURE(m_mNameMapping.find(_sColumnName) == m_mNameMapping.end(),"name doubled!");
1413 m_mNameMapping[_sColumnName] = sAlias;
1414 return sAlias;
1417 void OCopyTableWizard::removeColumnNameFromNameMap(const OUString& _sName)
1419 m_mNameMapping.erase(_sName);
1422 bool OCopyTableWizard::supportsType(sal_Int32 _nDataType, sal_Int32& _rNewDataType)
1424 bool bRet = m_aDestTypeInfo.find(_nDataType) != m_aDestTypeInfo.end();
1425 if ( bRet )
1426 _rNewDataType = _nDataType;
1427 return bRet;
1430 TOTypeInfoSP OCopyTableWizard::convertType(const TOTypeInfoSP& _pType, bool& _bNotConvert)
1432 if ( !m_bInterConnectionCopy )
1433 // no need to convert if the source and destination connection are the same
1434 return _pType;
1436 bool bForce;
1437 TOTypeInfoSP pType = ::dbaui::getTypeInfoFromType(m_aDestTypeInfo,_pType->nType,_pType->aTypeName,_pType->aCreateParams,_pType->nPrecision,_pType->nMaximumScale,_pType->bAutoIncrement,bForce);
1438 if ( !pType.get() || bForce )
1439 { // no type found so we have to find the correct one ourself
1440 sal_Int32 nDefaultType = DataType::VARCHAR;
1441 switch(_pType->nType)
1443 case DataType::TINYINT:
1444 if(supportsType(DataType::SMALLINT,nDefaultType))
1445 break;
1446 SAL_FALLTHROUGH;
1447 case DataType::SMALLINT:
1448 if(supportsType(DataType::INTEGER,nDefaultType))
1449 break;
1450 SAL_FALLTHROUGH;
1451 case DataType::INTEGER:
1452 if(supportsType(DataType::FLOAT,nDefaultType))
1453 break;
1454 SAL_FALLTHROUGH;
1455 case DataType::FLOAT:
1456 if(supportsType(DataType::REAL,nDefaultType))
1457 break;
1458 SAL_FALLTHROUGH;
1459 case DataType::DATE:
1460 case DataType::TIME:
1461 if( DataType::DATE == _pType->nType || DataType::TIME == _pType->nType )
1463 if(supportsType(DataType::TIMESTAMP,nDefaultType))
1464 break;
1466 SAL_FALLTHROUGH;
1467 case DataType::TIMESTAMP:
1468 case DataType::REAL:
1469 case DataType::BIGINT:
1470 if ( supportsType(DataType::DOUBLE,nDefaultType) )
1471 break;
1472 SAL_FALLTHROUGH;
1473 case DataType::DOUBLE:
1474 if ( supportsType(DataType::NUMERIC,nDefaultType) )
1475 break;
1476 SAL_FALLTHROUGH;
1477 case DataType::NUMERIC:
1478 supportsType(DataType::DECIMAL,nDefaultType);
1479 break;
1480 case DataType::DECIMAL:
1481 if ( supportsType(DataType::NUMERIC,nDefaultType) )
1482 break;
1483 if ( supportsType(DataType::DOUBLE,nDefaultType) )
1484 break;
1485 break;
1486 case DataType::VARCHAR:
1487 if ( supportsType(DataType::LONGVARCHAR,nDefaultType) )
1488 break;
1489 break;
1490 case DataType::LONGVARCHAR:
1491 if ( supportsType(DataType::CLOB,nDefaultType) )
1492 break;
1493 break;
1494 case DataType::BINARY:
1495 if ( supportsType(DataType::VARBINARY,nDefaultType) )
1496 break;
1497 break;
1498 case DataType::VARBINARY:
1499 if ( supportsType(DataType::LONGVARBINARY,nDefaultType) )
1500 break;
1501 break;
1502 case DataType::LONGVARBINARY:
1503 if ( supportsType(DataType::BLOB,nDefaultType) )
1504 break;
1505 if ( supportsType(DataType::LONGVARCHAR,nDefaultType) )
1506 break;
1507 if ( supportsType(DataType::CLOB,nDefaultType) )
1508 break;
1509 break;
1510 default:
1511 nDefaultType = DataType::VARCHAR;
1513 pType = ::dbaui::getTypeInfoFromType(m_aDestTypeInfo,nDefaultType,_pType->aTypeName,_pType->aCreateParams,_pType->nPrecision,_pType->nMaximumScale,_pType->bAutoIncrement,bForce);
1514 if ( !pType.get() )
1516 _bNotConvert = false;
1517 OUString sCreate("x");
1518 pType = ::dbaui::getTypeInfoFromType(m_aDestTypeInfo,DataType::VARCHAR,_pType->aTypeName,sCreate,50,0,false,bForce);
1519 if ( !pType.get() )
1520 pType = m_pTypeInfo;
1522 else if ( bForce )
1523 _bNotConvert = false;
1525 return pType;
1528 OUString OCopyTableWizard::createUniqueName(const OUString& _sName)
1530 OUString sName = _sName;
1531 Sequence< OUString > aColumnNames( m_rSourceObject.getColumnNames() );
1532 if ( aColumnNames.getLength() )
1533 sName = ::dbtools::createUniqueName( aColumnNames, sName, false );
1534 else
1536 if ( m_vSourceColumns.find(sName) != m_vSourceColumns.end())
1538 sal_Int32 nPos = 0;
1539 while(m_vSourceColumns.find(sName) != m_vSourceColumns.end())
1541 sName = _sName;
1542 sName += OUString::number(++nPos);
1546 return sName;
1549 void OCopyTableWizard::showColumnTypeNotSupported(const OUString& _rColumnName)
1551 OUString sMessage( ModuleRes( STR_UNKNOWN_TYPE_FOUND ) );
1552 sMessage = sMessage.replaceFirst("#1",_rColumnName);
1553 showError(sMessage);
1556 void OCopyTableWizard::showError(const OUString& _sErrorMessage)
1558 SQLExceptionInfo aInfo(_sErrorMessage);
1559 showError(aInfo.get());
1562 void OCopyTableWizard::showError(const Any& _aError)
1564 if ( _aError.hasValue() && m_xInteractionHandler.is() )
1568 ::rtl::Reference< ::comphelper::OInteractionRequest > xRequest( new ::comphelper::OInteractionRequest( _aError ) );
1569 m_xInteractionHandler->handle( xRequest.get() );
1571 catch( const Exception& )
1573 DBG_UNHANDLED_EXCEPTION();
1578 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */