Bump version to 5.0-14
[LibreOffice.git] / dbaccess / source / ui / misc / WCopyTable.cxx
blob844fa7ff8f0b3e8674e8d67d3965d0fbc0232e20
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>
64 #include <o3tl/compat_functional.hxx>
66 using namespace ::dbaui;
67 using namespace ::com::sun::star::uno;
68 using namespace ::com::sun::star::beans;
69 using namespace ::com::sun::star::container;
70 using namespace ::com::sun::star::util;
71 using namespace ::com::sun::star::sdb;
72 using namespace ::com::sun::star::sdbc;
73 using namespace ::com::sun::star::sdbcx;
74 using namespace ::com::sun::star::lang;
75 using namespace ::com::sun::star::task;
76 using namespace dbtools;
78 namespace CopyTableOperation = ::com::sun::star::sdb::application::CopyTableOperation;
80 #define MAX_PAGES 4 // max. number of pages, which are shown
82 namespace
84 void clearColumns(ODatabaseExport::TColumns& _rColumns, ODatabaseExport::TColumnVector& _rColumnsVec)
86 ODatabaseExport::TColumns::iterator aIter = _rColumns.begin();
87 ODatabaseExport::TColumns::iterator aEnd = _rColumns.end();
89 for(;aIter != aEnd;++aIter)
90 delete aIter->second;
92 _rColumnsVec.clear();
93 _rColumns.clear();
97 // ICopyTableSourceObject
98 ICopyTableSourceObject::~ICopyTableSourceObject()
102 // ObjectCopySource
103 ObjectCopySource::ObjectCopySource( const Reference< XConnection >& _rxConnection, const Reference< XPropertySet >& _rxObject )
104 :m_xConnection( _rxConnection, UNO_SET_THROW )
105 ,m_xMetaData( _rxConnection->getMetaData(), UNO_SET_THROW )
106 ,m_xObject( _rxObject, UNO_SET_THROW )
107 ,m_xObjectPSI( _rxObject->getPropertySetInfo(), UNO_SET_THROW )
108 ,m_xObjectColumns( Reference< XColumnsSupplier >( _rxObject, UNO_QUERY_THROW )->getColumns(), UNO_SET_THROW )
112 OUString ObjectCopySource::getQualifiedObjectName() const
114 OUString sName;
116 if ( !m_xObjectPSI->hasPropertyByName( PROPERTY_COMMAND ) )
117 sName = ::dbtools::composeTableName( m_xMetaData, m_xObject, ::dbtools::eInDataManipulation, false, false, false );
118 else
119 m_xObject->getPropertyValue( PROPERTY_NAME ) >>= sName;
120 return sName;
123 bool ObjectCopySource::isView() const
125 bool bIsView = false;
128 if ( m_xObjectPSI->hasPropertyByName( PROPERTY_TYPE ) )
130 OUString sObjectType;
131 OSL_VERIFY( m_xObject->getPropertyValue( PROPERTY_TYPE ) >>= sObjectType );
132 bIsView = sObjectType == "VIEW";
135 catch( const Exception& )
137 DBG_UNHANDLED_EXCEPTION();
139 return bIsView;
142 void ObjectCopySource::copyUISettingsTo( const Reference< XPropertySet >& _rxObject ) const
144 const OUString aCopyProperties[] = {
145 OUString(PROPERTY_FONT), OUString(PROPERTY_ROW_HEIGHT), OUString(PROPERTY_TEXTCOLOR),OUString(PROPERTY_TEXTLINECOLOR),OUString(PROPERTY_TEXTEMPHASIS),OUString(PROPERTY_TEXTRELIEF)
147 for ( size_t i=0; i < sizeof( aCopyProperties ) / sizeof( aCopyProperties[0] ); ++i )
149 if ( m_xObjectPSI->hasPropertyByName( aCopyProperties[i] ) )
150 _rxObject->setPropertyValue( aCopyProperties[i], m_xObject->getPropertyValue( aCopyProperties[i] ) );
154 void ObjectCopySource::copyFilterAndSortingTo( const Reference< XConnection >& _xConnection,const Reference< XPropertySet >& _rxObject ) const
156 ::std::pair< OUString, OUString > aProperties[] = {
157 ::std::pair< OUString, OUString >(PROPERTY_FILTER,OUString(" AND "))
158 ,::std::pair< OUString, OUString >(PROPERTY_ORDER,OUString(" ORDER BY "))
163 const OUString sSourceName = ::dbtools::composeTableNameForSelect(m_xConnection,m_xObject) + ".";
164 const OUString sTargetName = ::dbtools::composeTableNameForSelect(_xConnection,_rxObject);
165 const OUString sTargetNameTemp = sTargetName + ".";
167 OUString sStatement = "SELECT * FROM " + sTargetName + " WHERE 0=1";
169 for ( size_t i=0; i < SAL_N_ELEMENTS(aProperties); ++i )
171 if ( m_xObjectPSI->hasPropertyByName( aProperties[i].first ) )
173 OUString sFilter;
174 m_xObject->getPropertyValue( aProperties[i].first ) >>= sFilter;
175 if ( !sFilter.isEmpty() )
177 sStatement += aProperties[i].second;
178 OUString sReplace = sFilter;
179 sReplace = sReplace.replaceFirst(sSourceName,sTargetNameTemp);
180 sFilter = sReplace;
181 _rxObject->setPropertyValue( aProperties[i].first, makeAny(sFilter) );
182 sStatement += sFilter;
187 _xConnection->createStatement()->executeQuery(sStatement);
189 if ( m_xObjectPSI->hasPropertyByName( PROPERTY_APPLYFILTER ) )
190 _rxObject->setPropertyValue( PROPERTY_APPLYFILTER, m_xObject->getPropertyValue( PROPERTY_APPLYFILTER ) );
192 catch(Exception&)
197 Sequence< OUString > ObjectCopySource::getColumnNames() const
199 return m_xObjectColumns->getElementNames();
202 Sequence< OUString > ObjectCopySource::getPrimaryKeyColumnNames() const
204 const Reference<XNameAccess> xPrimaryKeyColumns = getPrimaryKeyColumns_throw(m_xObject);
205 Sequence< OUString > aKeyColNames;
206 if ( xPrimaryKeyColumns.is() )
207 aKeyColNames = xPrimaryKeyColumns->getElementNames();
208 return aKeyColNames;
211 OFieldDescription* ObjectCopySource::createFieldDescription( const OUString& _rColumnName ) const
213 Reference< XPropertySet > xColumn( m_xObjectColumns->getByName( _rColumnName ), UNO_QUERY_THROW );
214 return new OFieldDescription( xColumn );
217 OUString ObjectCopySource::getSelectStatement() const
219 OUString sSelectStatement;
220 if ( m_xObjectPSI->hasPropertyByName( PROPERTY_COMMAND ) )
221 { // query
222 OSL_VERIFY( m_xObject->getPropertyValue( PROPERTY_COMMAND ) >>= sSelectStatement );
224 else
225 { // table
226 OUStringBuffer aSQL;
227 aSQL.appendAscii( "SELECT " );
229 // we need to create the sql stmt with column names
230 // otherwise it is possible that names don't match
231 const OUString sQuote = m_xMetaData->getIdentifierQuoteString();
233 Sequence< OUString > aColumnNames = getColumnNames();
234 const OUString* pColumnName = aColumnNames.getConstArray();
235 const OUString* pEnd = pColumnName + aColumnNames.getLength();
236 for ( ; pColumnName != pEnd; )
238 aSQL.append( ::dbtools::quoteName( sQuote, *pColumnName++ ) );
240 if ( pColumnName == pEnd )
241 aSQL.appendAscii( " " );
242 else
243 aSQL.appendAscii( ", " );
246 aSQL.append( "FROM " + ::dbtools::composeTableNameForSelect( m_xConnection, m_xObject ) );
248 sSelectStatement = aSQL.makeStringAndClear();
251 return sSelectStatement;
254 ::utl::SharedUNOComponent< XPreparedStatement > ObjectCopySource::getPreparedSelectStatement() const
256 ::utl::SharedUNOComponent< XPreparedStatement > xStatement(
257 m_xConnection->prepareStatement( getSelectStatement() ),
258 ::utl::SharedUNOComponent< XPreparedStatement >::TakeOwnership
260 return xStatement;
263 // NamedTableCopySource
264 NamedTableCopySource::NamedTableCopySource( const Reference< XConnection >& _rxConnection, const OUString& _rTableName )
265 :m_xConnection( _rxConnection, UNO_SET_THROW )
266 ,m_xMetaData( _rxConnection->getMetaData(), UNO_SET_THROW )
267 ,m_sTableName( _rTableName )
268 ,m_aColumnInfo()
270 ::dbtools::qualifiedNameComponents( m_xMetaData, m_sTableName, m_sTableCatalog, m_sTableSchema, m_sTableBareName, ::dbtools::eComplete );
271 impl_ensureColumnInfo_throw();
274 OUString NamedTableCopySource::getQualifiedObjectName() const
276 return m_sTableName;
279 bool NamedTableCopySource::isView() const
281 OUString sTableType;
284 Reference< XResultSet > xTableDesc( m_xMetaData->getTables( makeAny( m_sTableCatalog ), m_sTableSchema, m_sTableBareName,
285 Sequence< OUString >() ) );
286 Reference< XRow > xTableDescRow( xTableDesc, UNO_QUERY_THROW );
287 OSL_VERIFY( xTableDesc->next() );
288 sTableType = xTableDescRow->getString( 4 );
289 OSL_ENSURE( !xTableDescRow->wasNull(), "NamedTableCopySource::isView: invalid table type!" );
291 catch( const Exception& )
293 DBG_UNHANDLED_EXCEPTION();
295 return sTableType == "VIEW";
298 void NamedTableCopySource::copyUISettingsTo( const Reference< XPropertySet >& /*_rxObject*/ ) const
300 // not supported: we do not have UI settings to copy
303 void NamedTableCopySource::copyFilterAndSortingTo( const Reference< XConnection >& ,const Reference< XPropertySet >& /*_rxObject*/ ) const
307 void NamedTableCopySource::impl_ensureColumnInfo_throw()
309 if ( !m_aColumnInfo.empty() )
310 return;
312 Reference< XResultSetMetaDataSupplier > xStatementMetaSupp( impl_ensureStatement_throw().getTyped(), UNO_QUERY_THROW );
313 Reference< XResultSetMetaData > xStatementMeta( xStatementMetaSupp->getMetaData(), UNO_SET_THROW );
315 sal_Int32 nColCount( xStatementMeta->getColumnCount() );
316 for ( sal_Int32 i = 1; i <= nColCount; ++i )
318 OFieldDescription aDesc;
320 aDesc.SetName( xStatementMeta->getColumnName( i ) );
321 aDesc.SetHelpText( xStatementMeta->getColumnLabel( i ) );
322 aDesc.SetTypeValue( xStatementMeta->getColumnType( i ) );
323 aDesc.SetTypeName( xStatementMeta->getColumnTypeName( i ) );
324 aDesc.SetPrecision( xStatementMeta->getPrecision( i ) );
325 aDesc.SetScale( xStatementMeta->getScale( i ) );
326 aDesc.SetIsNullable( xStatementMeta->isNullable( i ) );
327 aDesc.SetCurrency( xStatementMeta->isCurrency( i ) );
328 aDesc.SetAutoIncrement( xStatementMeta->isAutoIncrement( i ) );
330 m_aColumnInfo.push_back( aDesc );
334 ::utl::SharedUNOComponent< XPreparedStatement > NamedTableCopySource::impl_ensureStatement_throw()
336 if ( !m_xStatement.is() )
337 m_xStatement.set( m_xConnection->prepareStatement( getSelectStatement() ), UNO_SET_THROW );
338 return m_xStatement;
341 Sequence< OUString > NamedTableCopySource::getColumnNames() const
343 Sequence< OUString > aNames( m_aColumnInfo.size() );
344 for ( ::std::vector< OFieldDescription >::const_iterator col = m_aColumnInfo.begin();
345 col != m_aColumnInfo.end();
346 ++col
348 aNames[ col - m_aColumnInfo.begin() ] = col->GetName();
350 return aNames;
353 Sequence< OUString > NamedTableCopySource::getPrimaryKeyColumnNames() const
355 Sequence< OUString > aPKColNames;
359 Reference< XResultSet > xPKDesc( m_xMetaData->getPrimaryKeys( makeAny( m_sTableCatalog ), m_sTableSchema, m_sTableBareName ) );
360 Reference< XRow > xPKDescRow( xPKDesc, UNO_QUERY_THROW );
361 while ( xPKDesc->next() )
363 sal_Int32 len( aPKColNames.getLength() );
364 aPKColNames.realloc( len + 1 );
365 aPKColNames[ len ] = xPKDescRow->getString( 4 ); // COLUMN_NAME
368 catch( const Exception& )
370 DBG_UNHANDLED_EXCEPTION();
373 return aPKColNames;
376 OFieldDescription* NamedTableCopySource::createFieldDescription( const OUString& _rColumnName ) const
378 for ( ::std::vector< OFieldDescription >::const_iterator col = m_aColumnInfo.begin();
379 col != m_aColumnInfo.end();
380 ++col
382 if ( col->GetName() == _rColumnName )
383 return new OFieldDescription( *col );
385 return NULL;
388 OUString NamedTableCopySource::getSelectStatement() const
390 OUStringBuffer aSQL;
391 aSQL.appendAscii( "SELECT * FROM " );
393 aSQL.append( ::dbtools::composeTableNameForSelect( m_xConnection, m_sTableCatalog, m_sTableSchema, m_sTableBareName ) );
395 return aSQL.makeStringAndClear();
398 ::utl::SharedUNOComponent< XPreparedStatement > NamedTableCopySource::getPreparedSelectStatement() const
400 return const_cast< NamedTableCopySource* >( this )->impl_ensureStatement_throw();
403 // DummyCopySource
404 class DummyCopySource : public ICopyTableSourceObject
406 public:
407 DummyCopySource() { }
409 static const DummyCopySource& Instance();
411 // ICopyTableSourceObject overridables
412 virtual OUString getQualifiedObjectName() const SAL_OVERRIDE;
413 virtual bool isView() const SAL_OVERRIDE;
414 virtual void copyUISettingsTo( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& _rxObject ) const SAL_OVERRIDE;
415 virtual void copyFilterAndSortingTo(const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >& _xConnection, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& _rxObject ) const SAL_OVERRIDE;
416 virtual ::com::sun::star::uno::Sequence< OUString >
417 getColumnNames() const SAL_OVERRIDE;
418 virtual ::com::sun::star::uno::Sequence< OUString >
419 getPrimaryKeyColumnNames() const SAL_OVERRIDE;
420 virtual OFieldDescription* createFieldDescription( const OUString& _rColumnName ) const SAL_OVERRIDE;
421 virtual OUString getSelectStatement() const SAL_OVERRIDE;
422 virtual ::utl::SharedUNOComponent< XPreparedStatement >
423 getPreparedSelectStatement() const SAL_OVERRIDE;
426 const DummyCopySource& DummyCopySource::Instance()
428 static DummyCopySource s_aTheInstance;
429 return s_aTheInstance;
432 OUString DummyCopySource::getQualifiedObjectName() const
434 SAL_WARN("dbaccess.ui", "DummyCopySource::getQualifiedObjectName: not to be called!" );
435 return OUString();
438 bool DummyCopySource::isView() const
440 SAL_WARN("dbaccess.ui", "DummyCopySource::isView: not to be called!" );
441 return false;
444 void DummyCopySource::copyUISettingsTo( const Reference< XPropertySet >& /*_rxObject*/ ) const
446 // no support
449 void DummyCopySource::copyFilterAndSortingTo( const Reference< XConnection >& ,const Reference< XPropertySet >& /*_rxObject*/ ) const
453 Sequence< OUString > DummyCopySource::getColumnNames() const
455 return Sequence< OUString >();
458 Sequence< OUString > DummyCopySource::getPrimaryKeyColumnNames() const
460 SAL_WARN("dbaccess.ui", "DummyCopySource::getPrimaryKeyColumnNames: not to be called!" );
461 return Sequence< OUString >();
464 OFieldDescription* DummyCopySource::createFieldDescription( const OUString& /*_rColumnName*/ ) const
466 SAL_WARN("dbaccess.ui", "DummyCopySource::createFieldDescription: not to be called!" );
467 return NULL;
470 OUString DummyCopySource::getSelectStatement() const
472 SAL_WARN("dbaccess.ui", "DummyCopySource::getSelectStatement: not to be called!" );
473 return OUString();
476 ::utl::SharedUNOComponent< XPreparedStatement > DummyCopySource::getPreparedSelectStatement() const
478 SAL_WARN("dbaccess.ui", "DummyCopySource::getPreparedSelectStatement: not to be called!" );
479 return ::utl::SharedUNOComponent< XPreparedStatement >();
482 namespace
484 bool lcl_canCreateViewFor_nothrow( const Reference< XConnection >& _rxConnection )
486 Reference< XViewsSupplier > xSup( _rxConnection, UNO_QUERY );
487 Reference< XDataDescriptorFactory > xViewFac;
488 if ( xSup.is() )
489 xViewFac.set( xSup->getViews(), UNO_QUERY );
490 return xViewFac.is();
493 bool lcl_sameConnection_throw( const Reference< XConnection >& _rxLHS, const Reference< XConnection >& _rxRHS )
495 Reference< XDatabaseMetaData > xMetaLHS( _rxLHS->getMetaData(), UNO_QUERY_THROW );
496 Reference< XDatabaseMetaData > xMetaRHS( _rxRHS->getMetaData(), UNO_QUERY_THROW );
497 return xMetaLHS->getURL().equals( xMetaRHS->getURL() );
501 // OCopyTableWizard
502 OCopyTableWizard::OCopyTableWizard( vcl::Window * pParent, const OUString& _rDefaultName, sal_Int16 _nOperation,
503 const ICopyTableSourceObject& _rSourceObject, const Reference< XConnection >& _xSourceConnection,
504 const Reference< XConnection >& _xConnection, const Reference< XComponentContext >& _rxContext,
505 const Reference< XInteractionHandler>& _xInteractionHandler)
506 : WizardDialog( pParent, "RTFCopyTable", "dbaccess/ui/rtfcopytabledialog.ui")
507 ,m_mNameMapping(_xConnection->getMetaData().is() && _xConnection->getMetaData()->supportsMixedCaseQuotedIdentifiers())
508 ,m_xDestConnection( _xConnection )
509 ,m_rSourceObject( _rSourceObject )
510 ,m_xFormatter( getNumberFormatter( _xConnection, _rxContext ) )
511 ,m_xContext(_rxContext)
512 ,m_xInteractionHandler(_xInteractionHandler)
513 ,m_sTypeNames(ModuleRes(STR_TABLEDESIGN_DBFIELDTYPES))
514 ,m_nPageCount(0)
515 ,m_bDeleteSourceColumns(true)
516 ,m_bInterConnectionCopy( _xSourceConnection != _xConnection )
517 ,m_sName( _rDefaultName )
518 ,m_nOperation( _nOperation )
519 ,m_ePressed( WIZARD_NONE )
520 ,m_bCreatePrimaryKeyColumn(false)
522 construct();
524 // extract table name
525 OUString sInitialTableName( _rDefaultName );
528 m_sSourceName = m_rSourceObject.getQualifiedObjectName();
529 OSL_ENSURE( !m_sSourceName.isEmpty(), "OCopyTableWizard::OCopyTableWizard: unable to retrieve the source object's name!" );
531 if ( sInitialTableName.isEmpty() )
532 sInitialTableName = m_sSourceName;
534 if ( m_sName.isEmpty() )
536 if ( _xSourceConnection == m_xDestConnection )
538 Reference< XTablesSupplier > xSup( m_xDestConnection, UNO_QUERY_THROW );
539 m_sName = ::dbtools::createUniqueName( xSup->getTables(), sInitialTableName, false );
541 else
542 m_sName = sInitialTableName;
545 catch ( const Exception& )
547 m_sName = sInitialTableName;
550 ::dbaui::fillTypeInfo( _xSourceConnection, m_sTypeNames, m_aTypeInfo, m_aTypeInfoIndex );
551 ::dbaui::fillTypeInfo( m_xDestConnection, m_sTypeNames, m_aDestTypeInfo, m_aDestTypeInfoIndex );
552 impl_loadSourceData();
554 bool bAllowViews = true;
555 // if the source is a, don't allow creating views
556 if ( m_rSourceObject.isView() )
557 bAllowViews = false;
558 // no views if the target connection does not support creating them
559 if ( !lcl_canCreateViewFor_nothrow( m_xDestConnection ) )
560 bAllowViews = false;
561 // no views if we're copying to a different database
562 if ( !lcl_sameConnection_throw( _xSourceConnection, m_xDestConnection ) )
563 bAllowViews = false;
565 if ( m_bInterConnectionCopy )
567 Reference< XDatabaseMetaData > xSrcMeta = _xSourceConnection->getMetaData();
568 OUString sCatalog;
569 OUString sSchema;
570 OUString sTable;
571 ::dbtools::qualifiedNameComponents( xSrcMeta,
572 m_sName,
573 sCatalog,
574 sSchema,
575 sTable,
576 ::dbtools::eInDataManipulation);
578 m_sName = ::dbtools::composeTableName(m_xDestConnection->getMetaData(),sCatalog,sSchema,sTable,false,::dbtools::eInTableDefinitions);
581 VclPtrInstance<OCopyTable> pPage1( this );
582 pPage1->disallowUseHeaderLine();
583 if ( !bAllowViews )
584 pPage1->disallowViews();
585 pPage1->setCreateStyleAction();
586 AddWizardPage(pPage1);
588 AddWizardPage( VclPtr<OWizNameMatching>::Create( this ) );
589 AddWizardPage( VclPtr<OWizColumnSelect>::Create( this ) );
590 AddWizardPage( VclPtr<OWizNormalExtend>::Create( this ) );
591 ActivatePage();
594 OCopyTableWizard::OCopyTableWizard( vcl::Window* pParent, const OUString& _rDefaultName, sal_Int16 _nOperation,
595 const ODatabaseExport::TColumns& _rSourceColumns, const ODatabaseExport::TColumnVector& _rSourceColVec,
596 const Reference< XConnection >& _xConnection, const Reference< XNumberFormatter >& _xFormatter,
597 TypeSelectionPageFactory _pTypeSelectionPageFactory, SvStream& _rTypeSelectionPageArg, const Reference< XComponentContext >& _rxContext )
598 :WizardDialog( pParent, "RTFCopyTable", "dbaccess/ui/rtfcopytabledialog.ui")
599 ,m_vSourceColumns(_rSourceColumns)
600 ,m_mNameMapping(_xConnection->getMetaData().is() && _xConnection->getMetaData()->supportsMixedCaseQuotedIdentifiers())
601 ,m_xDestConnection( _xConnection )
602 ,m_rSourceObject( DummyCopySource::Instance() )
603 ,m_xFormatter(_xFormatter)
604 ,m_xContext(_rxContext)
605 ,m_sTypeNames(ModuleRes(STR_TABLEDESIGN_DBFIELDTYPES))
606 ,m_nPageCount(0)
607 ,m_bDeleteSourceColumns(false)
608 ,m_bInterConnectionCopy( false )
609 ,m_sName(_rDefaultName)
610 ,m_nOperation( _nOperation )
611 ,m_ePressed( WIZARD_NONE )
612 ,m_bCreatePrimaryKeyColumn(false)
614 construct();
615 ODatabaseExport::TColumnVector::const_iterator aIter = _rSourceColVec.begin();
616 ODatabaseExport::TColumnVector::const_iterator aEnd = _rSourceColVec.end();
617 for (; aIter != aEnd ; ++aIter)
619 m_vSourceVec.push_back(m_vSourceColumns.find((*aIter)->first));
622 ::dbaui::fillTypeInfo( _xConnection, m_sTypeNames, m_aTypeInfo, m_aTypeInfoIndex );
623 ::dbaui::fillTypeInfo( _xConnection, m_sTypeNames, m_aDestTypeInfo, m_aDestTypeInfoIndex );
625 m_xInteractionHandler.set( InteractionHandler::createWithParent(m_xContext, 0), UNO_QUERY );
627 VclPtrInstance<OCopyTable> pPage1( this );
628 pPage1->disallowViews();
629 pPage1->setCreateStyleAction();
630 AddWizardPage( pPage1 );
632 AddWizardPage( VclPtr<OWizNameMatching>::Create( this ) );
633 AddWizardPage( VclPtr<OWizColumnSelect>::Create( this ) );
634 AddWizardPage( (*_pTypeSelectionPageFactory)( this, _rTypeSelectionPageArg ) );
636 ActivatePage();
639 void OCopyTableWizard::construct()
641 SetSizePixel(Size(580, 350));
643 AddButton( m_pbHelp = VclPtr<HelpButton>::Create(this, WB_TABSTOP) );
644 AddButton( m_pbCancel = VclPtr<CancelButton>::Create(this, WB_TABSTOP) );
645 AddButton( m_pbPrev = VclPtr<PushButton>::Create(this, WB_TABSTOP));
646 AddButton( m_pbNext = VclPtr<PushButton>::Create(this, WB_TABSTOP));
647 AddButton( m_pbFinish = VclPtr<PushButton>::Create(this, WB_TABSTOP));
649 m_pbHelp->SetSizePixel( LogicToPixel( Size( 50, 14 ), MAP_APPFONT ) );
650 m_pbCancel->SetSizePixel( LogicToPixel( Size( 50, 14 ), MAP_APPFONT ) );
651 m_pbPrev->SetSizePixel( LogicToPixel( Size( 50, 14 ), MAP_APPFONT ) );
652 m_pbNext->SetSizePixel( LogicToPixel( Size( 50, 14 ), MAP_APPFONT ) );
653 m_pbFinish->SetSizePixel( LogicToPixel( Size( 50, 14 ), MAP_APPFONT ) );
655 m_pbPrev->SetText(ModuleRes(STR_WIZ_PB_PREV));
656 m_pbNext->SetText(ModuleRes(STR_WIZ_PB_NEXT));
657 m_pbFinish->SetText(ModuleRes(STR_WIZ_PB_OK));
659 m_pbHelp->Show();
660 m_pbCancel->Show();
661 m_pbPrev->Show();
662 m_pbNext->Show();
663 m_pbFinish->Show();
665 m_pbPrev->SetClickHdl( LINK( this, OCopyTableWizard, ImplPrevHdl ) );
666 m_pbNext->SetClickHdl( LINK( this, OCopyTableWizard, ImplNextHdl ) );
667 m_pbFinish->SetClickHdl( LINK( this, OCopyTableWizard, ImplOKHdl ) );
669 SetActivatePageHdl( LINK( this, OCopyTableWizard, ImplActivateHdl ) );
671 SetPrevButton( m_pbPrev );
672 SetNextButton( m_pbNext );
674 m_pbNext->GrabFocus();
676 if (m_vDestColumns.size())
677 // source is a html or rtf table
678 m_pbNext->SetStyle(m_pbFinish->GetStyle() | WB_DEFBUTTON);
679 else
680 m_pbFinish->SetStyle(m_pbFinish->GetStyle() | WB_DEFBUTTON);
682 m_pTypeInfo = TOTypeInfoSP(new OTypeInfo());
683 m_pTypeInfo->aUIName = m_sTypeNames.getToken(TYPE_OTHER, ';');
684 m_bAddPKFirstTime = true;
687 OCopyTableWizard::~OCopyTableWizard()
689 disposeOnce();
692 void OCopyTableWizard::dispose()
694 for ( ;; )
696 VclPtr<TabPage> pPage = GetPage(0);
697 if ( pPage == nullptr )
698 break;
699 RemovePage( pPage );
700 pPage.disposeAndClear();
703 if ( m_bDeleteSourceColumns )
704 clearColumns(m_vSourceColumns,m_vSourceVec);
706 clearColumns(m_vDestColumns,m_aDestVec);
708 // clear the type information
709 m_aTypeInfoIndex.clear();
710 m_aTypeInfo.clear();
711 m_aDestTypeInfoIndex.clear();
713 m_pbHelp.disposeAndClear();
714 m_pbCancel.disposeAndClear();
715 m_pbPrev.disposeAndClear();
716 m_pbNext.disposeAndClear();
717 m_pbFinish.disposeAndClear();
718 WizardDialog::dispose();
721 IMPL_LINK_NOARG(OCopyTableWizard, ImplPrevHdl)
723 m_ePressed = WIZARD_PREV;
724 if ( GetCurLevel() )
726 if ( getOperation() != CopyTableOperation::AppendData )
728 if(GetCurLevel() == 2)
729 ShowPage(GetCurLevel()-2);
730 else
731 ShowPrevPage();
733 else
734 ShowPrevPage();
736 return 0;
739 IMPL_LINK_NOARG(OCopyTableWizard, ImplNextHdl)
741 m_ePressed = WIZARD_NEXT;
742 if ( GetCurLevel() < MAX_PAGES )
744 if ( getOperation() != CopyTableOperation::AppendData )
746 if(GetCurLevel() == 0)
747 ShowPage(GetCurLevel()+2);
748 else
749 ShowNextPage();
751 else
752 ShowNextPage();
754 return 0;
757 bool OCopyTableWizard::CheckColumns(sal_Int32& _rnBreakPos)
759 bool bRet = true;
760 m_vColumnPos.clear();
761 m_vColumnTypes.clear();
763 OSL_ENSURE( m_xDestConnection.is(), "OCopyTableWizard::CheckColumns: No connection!" );
764 // If database is able to process PrimaryKeys, set PrimaryKey
765 if ( m_xDestConnection.is() )
767 bool bPKeyAllowed = supportsPrimaryKey();
769 bool bContainsColumns = !m_vDestColumns.empty();
771 if ( bPKeyAllowed && shouldCreatePrimaryKey() )
773 // add extra column for the primary key
774 TOTypeInfoSP pTypeInfo = queryPrimaryKeyType(m_aDestTypeInfo);
775 if ( pTypeInfo.get() )
777 if ( m_bAddPKFirstTime )
779 OFieldDescription* pField = new OFieldDescription();
780 pField->SetName(m_aKeyName);
781 pField->FillFromTypeInfo(pTypeInfo,true,true);
782 pField->SetPrimaryKey(true);
783 m_bAddPKFirstTime = false;
784 insertColumn(0,pField);
786 m_vColumnPos.push_back(ODatabaseExport::TPositions::value_type(1,1));
787 m_vColumnTypes.push_back(pTypeInfo->nType);
791 if ( bContainsColumns )
792 { // we have dest columns so look for the matching column
793 ODatabaseExport::TColumnVector::const_iterator aSrcIter = m_vSourceVec.begin();
794 ODatabaseExport::TColumnVector::const_iterator aSrcEnd = m_vSourceVec.end();
795 for(;aSrcIter != aSrcEnd;++aSrcIter)
797 ODatabaseExport::TColumns::iterator aDestIter = m_vDestColumns.find(m_mNameMapping[(*aSrcIter)->first]);
799 if ( aDestIter != m_vDestColumns.end() )
801 ODatabaseExport::TColumnVector::const_iterator aFind = ::std::find(m_aDestVec.begin(),m_aDestVec.end(),aDestIter);
802 sal_Int32 nPos = (aFind - m_aDestVec.begin())+1;
803 m_vColumnPos.push_back(ODatabaseExport::TPositions::value_type(nPos,nPos));
804 m_vColumnTypes.push_back((*aFind)->second->GetType());
806 else
808 m_vColumnPos.push_back( ODatabaseExport::TPositions::value_type( COLUMN_POSITION_NOT_FOUND, COLUMN_POSITION_NOT_FOUND ) );
809 m_vColumnTypes.push_back(0);
813 else
815 Reference< XDatabaseMetaData > xMetaData( m_xDestConnection->getMetaData() );
816 OUString sExtraChars = xMetaData->getExtraNameCharacters();
817 sal_Int32 nMaxNameLen = getMaxColumnNameLength();
819 ODatabaseExport::TColumnVector::const_iterator aSrcIter = m_vSourceVec.begin();
820 ODatabaseExport::TColumnVector::const_iterator aSrcEnd = m_vSourceVec.end();
821 for(_rnBreakPos=0;aSrcIter != aSrcEnd && bRet ;++aSrcIter,++_rnBreakPos)
823 OFieldDescription* pField = new OFieldDescription(*(*aSrcIter)->second);
824 pField->SetName(convertColumnName(TExportColumnFindFunctor(&m_vDestColumns),(*aSrcIter)->first,sExtraChars,nMaxNameLen));
825 TOTypeInfoSP pType = convertType((*aSrcIter)->second->getSpecialTypeInfo(),bRet);
826 pField->SetType(pType);
827 if ( !bPKeyAllowed )
828 pField->SetPrimaryKey(false);
830 // now create a column
831 insertColumn(m_vDestColumns.size(),pField);
832 m_vColumnPos.push_back(ODatabaseExport::TPositions::value_type(m_vDestColumns.size(),m_vDestColumns.size()));
833 m_vColumnTypes.push_back((*aSrcIter)->second->GetType());
837 return bRet;
840 IMPL_LINK_NOARG(OCopyTableWizard, ImplOKHdl)
842 m_ePressed = WIZARD_FINISH;
843 bool bFinish = DeactivatePage();
845 if(bFinish)
847 WaitObject aWait(this);
848 switch(getOperation())
850 case CopyTableOperation::CopyDefinitionAndData:
851 case CopyTableOperation::CopyDefinitionOnly:
853 bool bOnFirstPage = GetCurLevel() == 0;
854 if ( bOnFirstPage )
856 // we came from the first page so we have to clear
857 // all column information already collected
858 clearDestColumns();
859 m_mNameMapping.clear();
861 sal_Int32 nBreakPos = 0;
862 bool bCheckOk = CheckColumns(nBreakPos);
863 if ( bOnFirstPage && !bCheckOk )
865 showColumnTypeNotSupported(m_vSourceVec[nBreakPos-1]->first);
866 OWizTypeSelect* pPage = static_cast<OWizTypeSelect*>(GetPage(3));
867 if ( pPage )
869 m_mNameMapping.clear();
870 pPage->setDisplayRow(nBreakPos);
871 ShowPage(3);
872 return 0;
875 if ( m_xDestConnection.is() )
877 if ( supportsPrimaryKey() )
879 ODatabaseExport::TColumns::iterator aFind = ::std::find_if(m_vDestColumns.begin(),m_vDestColumns.end()
880 ,::o3tl::compose1(::std::mem_fun(&OFieldDescription::IsPrimaryKey),::o3tl::select2nd<ODatabaseExport::TColumns::value_type>()));
881 if ( aFind == m_vDestColumns.end() && m_xInteractionHandler.is() )
884 OUString sMsg(ModuleRes(STR_TABLEDESIGN_NO_PRIM_KEY));
885 SQLContext aError;
886 aError.Message = sMsg;
887 ::rtl::Reference< ::comphelper::OInteractionRequest > xRequest( new ::comphelper::OInteractionRequest( makeAny( aError ) ) );
888 ::rtl::Reference< ::comphelper::OInteractionApprove > xYes = new ::comphelper::OInteractionApprove;
889 xRequest->addContinuation( xYes.get() );
890 xRequest->addContinuation( new ::comphelper::OInteractionDisapprove );
891 ::rtl::Reference< ::comphelper::OInteractionAbort > xAbort = new ::comphelper::OInteractionAbort;
892 xRequest->addContinuation( xAbort.get() );
894 m_xInteractionHandler->handle( xRequest.get() );
896 if ( xYes->wasSelected() )
898 OCopyTable* pPage = static_cast<OCopyTable*>(GetPage(0));
899 m_bCreatePrimaryKeyColumn = true;
900 m_aKeyName = pPage->GetKeyName();
901 if ( m_aKeyName.isEmpty() )
902 m_aKeyName = "ID";
903 m_aKeyName = createUniqueName( m_aKeyName );
904 sal_Int32 nBreakPos2 = 0;
905 CheckColumns(nBreakPos2);
907 else if ( xAbort->wasSelected() )
909 ShowPage(3);
910 return 0;
915 break;
917 case CopyTableOperation::AppendData:
918 case CopyTableOperation::CreateAsView:
919 break;
920 default:
922 SAL_WARN("dbaccess.ui", "OCopyTableWizard::ImplOKHdl: invalid creation style!");
926 EndDialog(RET_OK);
928 return bFinish ? 1 : 0;
932 void OCopyTableWizard::setCreatePrimaryKey( bool _bDoCreate, const OUString& _rSuggestedName )
934 m_bCreatePrimaryKeyColumn = _bDoCreate;
935 if ( !_rSuggestedName.isEmpty() )
936 m_aKeyName = _rSuggestedName;
938 OCopyTable* pSettingsPage = dynamic_cast< OCopyTable* >( GetPage( 0 ) );
939 OSL_ENSURE( pSettingsPage, "OCopyTableWizard::setCreatePrimaryKey: page should have been added in the ctor!" );
940 if ( pSettingsPage )
941 pSettingsPage->setCreatePrimaryKey( _bDoCreate, _rSuggestedName );
944 IMPL_LINK_NOARG(OCopyTableWizard, ImplActivateHdl)
946 OWizardPage* pCurrent = static_cast<OWizardPage*>(GetPage(GetCurLevel()));
947 if(pCurrent)
949 bool bFirstTime = pCurrent->IsFirstTime();
950 if(bFirstTime)
951 pCurrent->Reset();
953 CheckButtons();
955 SetText(pCurrent->GetTitle());
957 Invalidate();
959 return 0;
962 void OCopyTableWizard::CheckButtons()
964 if(GetCurLevel() == 0) // the first page has no back button
966 if(m_nPageCount > 1)
967 m_pbNext->Enable(true);
968 else
969 m_pbNext->Enable(false);
971 m_pbPrev->Enable(false);
973 else if(GetCurLevel() == m_nPageCount-1) // the last page has no next button
975 m_pbNext->Enable(false);
976 m_pbPrev->Enable(true);
978 else
980 m_pbPrev->Enable(true);
981 // next already has its state
985 void OCopyTableWizard::EnableButton(Wizard_Button_Style eStyle, bool bEnable)
987 Button* pButton;
988 if(eStyle == WIZARD_NEXT)
989 pButton = m_pbNext;
990 else if(eStyle == WIZARD_PREV)
991 pButton = m_pbPrev;
992 else
993 pButton = m_pbFinish;
994 pButton->Enable(bEnable);
998 bool OCopyTableWizard::DeactivatePage()
1000 OWizardPage* pPage = static_cast<OWizardPage*>(GetPage(GetCurLevel()));
1001 return pPage && pPage->LeavePage();
1004 void OCopyTableWizard::AddWizardPage(OWizardPage* pPage)
1006 AddPage(pPage);
1007 ++m_nPageCount;
1010 void OCopyTableWizard::insertColumn(sal_Int32 _nPos,OFieldDescription* _pField)
1012 OSL_ENSURE(_pField,"FieldDescrioption is null!");
1013 if ( _pField )
1015 ODatabaseExport::TColumns::iterator aFind = m_vDestColumns.find(_pField->GetName());
1016 if ( aFind != m_vDestColumns.end() )
1018 delete aFind->second;
1019 m_vDestColumns.erase(aFind);
1022 m_aDestVec.insert(m_aDestVec.begin() + _nPos,
1023 m_vDestColumns.insert(ODatabaseExport::TColumns::value_type(_pField->GetName(),_pField)).first);
1024 m_mNameMapping[_pField->GetName()] = _pField->GetName();
1028 void OCopyTableWizard::replaceColumn(sal_Int32 _nPos,OFieldDescription* _pField,const OUString& _sOldName)
1030 OSL_ENSURE(_pField,"FieldDescrioption is null!");
1031 if ( _pField )
1033 m_vDestColumns.erase(_sOldName);
1034 OSL_ENSURE( m_vDestColumns.find(_pField->GetName()) == m_vDestColumns.end(),"Column with that name already exist!");
1036 m_aDestVec[_nPos] =
1037 m_vDestColumns.insert(ODatabaseExport::TColumns::value_type(_pField->GetName(),_pField)).first;
1041 void OCopyTableWizard::impl_loadSourceData()
1043 loadData( m_rSourceObject, m_vSourceColumns, m_vSourceVec );
1046 void OCopyTableWizard::loadData( const ICopyTableSourceObject& _rSourceObject, ODatabaseExport::TColumns& _rColumns, ODatabaseExport::TColumnVector& _rColVector )
1048 ODatabaseExport::TColumns::iterator colEnd = _rColumns.end();
1049 for ( ODatabaseExport::TColumns::iterator col = _rColumns.begin(); col != colEnd; ++col )
1050 delete col->second;
1052 _rColVector.clear();
1053 _rColumns.clear();
1055 OFieldDescription* pActFieldDescr = NULL;
1056 OUString sCreateParam("x");
1057 // ReadOnly-Flag
1058 // On drop no line must be editable.
1059 // On add only empty lines must be editable.
1060 // On Add and Drop all lines can be edited.
1061 Sequence< OUString > aColumns( _rSourceObject.getColumnNames() );
1062 const OUString* pColumn = aColumns.getConstArray();
1063 const OUString* pColumnEnd = pColumn + aColumns.getLength();
1065 for ( ; pColumn != pColumnEnd; ++pColumn )
1067 // get the properties of the column
1068 pActFieldDescr = _rSourceObject.createFieldDescription( *pColumn );
1069 OSL_ENSURE( pActFieldDescr, "OCopyTableWizard::loadData: illegal field description!" );
1070 if ( !pActFieldDescr )
1071 continue;
1073 sal_Int32 nType = pActFieldDescr->GetType();
1074 sal_Int32 nScale = pActFieldDescr->GetScale();
1075 sal_Int32 nPrecision = pActFieldDescr->GetPrecision();
1076 bool bAutoIncrement = pActFieldDescr->IsAutoIncrement();
1077 OUString sTypeName = pActFieldDescr->GetTypeName();
1079 // search for type
1080 bool bForce;
1081 TOTypeInfoSP pTypeInfo = ::dbaui::getTypeInfoFromType(m_aTypeInfo,nType,sTypeName,sCreateParam,nPrecision,nScale,bAutoIncrement,bForce);
1082 if ( !pTypeInfo.get() )
1083 pTypeInfo = m_pTypeInfo;
1085 pActFieldDescr->FillFromTypeInfo(pTypeInfo,true,false);
1086 _rColVector.push_back(_rColumns.insert(ODatabaseExport::TColumns::value_type(pActFieldDescr->GetName(),pActFieldDescr)).first);
1089 // determine which columns belong to the primary key
1090 Sequence< OUString > aPrimaryKeyColumns( _rSourceObject.getPrimaryKeyColumnNames() );
1091 const OUString* pKeyColName = aPrimaryKeyColumns.getConstArray();
1092 const OUString* pKeyColEnd = pKeyColName + aPrimaryKeyColumns.getLength();
1094 for( ; pKeyColName != pKeyColEnd; ++pKeyColName )
1096 ODatabaseExport::TColumns::iterator keyPos = _rColumns.find( *pKeyColName );
1097 if ( keyPos != _rColumns.end() )
1099 keyPos->second->SetPrimaryKey( true );
1100 keyPos->second->SetIsNullable( ColumnValue::NO_NULLS );
1105 void OCopyTableWizard::clearDestColumns()
1107 clearColumns(m_vDestColumns,m_aDestVec);
1108 m_bAddPKFirstTime = true;
1109 m_mNameMapping.clear();
1112 void OCopyTableWizard::appendColumns( Reference<XColumnsSupplier>& _rxColSup, const ODatabaseExport::TColumnVector* _pVec, bool _bKeyColumns)
1114 // now append the columns
1115 OSL_ENSURE(_rxColSup.is(),"No columns supplier");
1116 if(!_rxColSup.is())
1117 return;
1118 Reference<XNameAccess> xColumns = _rxColSup->getColumns();
1119 OSL_ENSURE(xColumns.is(),"No columns");
1120 Reference<XDataDescriptorFactory> xColumnFactory(xColumns,UNO_QUERY);
1122 Reference<XAppend> xAppend(xColumns,UNO_QUERY);
1123 OSL_ENSURE(xAppend.is(),"No XAppend Interface!");
1125 ODatabaseExport::TColumnVector::const_iterator aIter = _pVec->begin();
1126 ODatabaseExport::TColumnVector::const_iterator aEnd = _pVec->end();
1127 for(;aIter != aEnd;++aIter)
1129 OFieldDescription* pField = (*aIter)->second;
1130 if(!pField)
1131 continue;
1133 Reference<XPropertySet> xColumn;
1134 if(pField->IsPrimaryKey() || !_bKeyColumns)
1135 xColumn = xColumnFactory->createDataDescriptor();
1136 if(xColumn.is())
1138 if(!_bKeyColumns)
1139 dbaui::setColumnProperties(xColumn,pField);
1140 else
1141 xColumn->setPropertyValue(PROPERTY_NAME,makeAny(pField->GetName()));
1143 xAppend->appendByDescriptor(xColumn);
1144 xColumn = NULL;
1145 // now only the settings are missing
1146 if(xColumns->hasByName(pField->GetName()))
1148 xColumn.set(xColumns->getByName(pField->GetName()),UNO_QUERY);
1149 OSL_ENSURE(xColumn.is(),"OCopyTableWizard::appendColumns: Column is NULL!");
1150 if ( xColumn.is() )
1151 pField->copyColumnSettingsTo(xColumn);
1153 else
1155 SAL_WARN("dbaccess.ui", "OCopyTableWizard::appendColumns: invalid field name!");
1162 void OCopyTableWizard::appendKey( Reference<XKeysSupplier>& _rxSup, const ODatabaseExport::TColumnVector* _pVec)
1164 if(!_rxSup.is())
1165 return; // the database doesn't support keys
1166 OSL_ENSURE(_rxSup.is(),"No XKeysSupplier!");
1167 Reference<XDataDescriptorFactory> xKeyFactory(_rxSup->getKeys(),UNO_QUERY);
1168 OSL_ENSURE(xKeyFactory.is(),"No XDataDescriptorFactory Interface!");
1169 if ( !xKeyFactory.is() )
1170 return;
1171 Reference<XAppend> xAppend(xKeyFactory,UNO_QUERY);
1172 OSL_ENSURE(xAppend.is(),"No XAppend Interface!");
1174 Reference<XPropertySet> xKey = xKeyFactory->createDataDescriptor();
1175 OSL_ENSURE(xKey.is(),"Key is null!");
1176 xKey->setPropertyValue(PROPERTY_TYPE,makeAny(KeyType::PRIMARY));
1178 Reference<XColumnsSupplier> xColSup(xKey,UNO_QUERY);
1179 if(xColSup.is())
1181 appendColumns(xColSup,_pVec,true);
1182 Reference<XNameAccess> xColumns = xColSup->getColumns();
1183 if(xColumns.is() && xColumns->getElementNames().getLength())
1184 xAppend->appendByDescriptor(xKey);
1189 Reference< XPropertySet > OCopyTableWizard::createView() const
1191 OUString sCommand( m_rSourceObject.getSelectStatement() );
1192 OSL_ENSURE( !sCommand.isEmpty(), "OCopyTableWizard::createView: no statement in the source object!" );
1193 // there are legitimate cases in which getSelectStatement does not provide a statement,
1194 // but in all those cases, this method here should never be called.
1195 return ::dbaui::createView( m_sName, m_xDestConnection, sCommand );
1198 Reference< XPropertySet > OCopyTableWizard::createTable()
1200 Reference< XPropertySet > xTable;
1202 Reference<XTablesSupplier> xSup( m_xDestConnection, UNO_QUERY );
1203 Reference< XNameAccess > xTables;
1204 if(xSup.is())
1205 xTables = xSup->getTables();
1206 if ( getOperation() != CopyTableOperation::AppendData )
1208 Reference<XDataDescriptorFactory> xFact(xTables,UNO_QUERY);
1209 OSL_ENSURE(xFact.is(),"No XDataDescriptorFactory available!");
1210 if(!xFact.is())
1211 return NULL;
1213 xTable = xFact->createDataDescriptor();
1214 OSL_ENSURE(xTable.is(),"Could not create a new object!");
1215 if(!xTable.is())
1216 return NULL;
1218 OUString sCatalog,sSchema,sTable;
1219 Reference< XDatabaseMetaData> xMetaData = m_xDestConnection->getMetaData();
1220 ::dbtools::qualifiedNameComponents(xMetaData,
1221 m_sName,
1222 sCatalog,
1223 sSchema,
1224 sTable,
1225 ::dbtools::eInDataManipulation);
1227 if ( sCatalog.isEmpty() && xMetaData->supportsCatalogsInTableDefinitions() )
1229 sCatalog = m_xDestConnection->getCatalog();
1232 if ( sSchema.isEmpty() && xMetaData->supportsSchemasInTableDefinitions() )
1234 sSchema = xMetaData->getUserName();
1237 xTable->setPropertyValue(PROPERTY_CATALOGNAME,makeAny(sCatalog));
1238 xTable->setPropertyValue(PROPERTY_SCHEMANAME,makeAny(sSchema));
1239 xTable->setPropertyValue(PROPERTY_NAME,makeAny(sTable));
1241 Reference< XColumnsSupplier > xSuppDestinationColumns( xTable, UNO_QUERY );
1242 // now append the columns
1243 const ODatabaseExport::TColumnVector& rVec = getDestVector();
1244 appendColumns( xSuppDestinationColumns, &rVec );
1245 // now append the primary key
1246 Reference<XKeysSupplier> xKeySup(xTable,UNO_QUERY);
1247 appendKey(xKeySup, &rVec);
1249 Reference<XAppend> xAppend(xTables,UNO_QUERY);
1250 if(xAppend.is())
1251 xAppend->appendByDescriptor(xTable);
1253 // xTable = NULL;
1254 // we need to reget the table because after appending it, it is no longer valid
1255 if(xTables->hasByName(m_sName))
1256 xTables->getByName(m_sName) >>= xTable;
1257 else
1259 OUString sComposedName(
1260 ::dbtools::composeTableName( m_xDestConnection->getMetaData(), xTable, ::dbtools::eInDataManipulation, false, false, false ) );
1261 if(xTables->hasByName(sComposedName))
1263 xTables->getByName(sComposedName) >>= xTable;
1264 m_sName = sComposedName;
1266 else
1267 xTable = NULL;
1269 if(xTable.is())
1271 xSuppDestinationColumns.set( xTable, UNO_QUERY_THROW );
1272 // insert new table name into table filter
1273 ::dbaui::appendToFilter( m_xDestConnection, m_sName, GetComponentContext(), this );
1275 // copy ui settings
1276 m_rSourceObject.copyUISettingsTo( xTable );
1277 //copy filter and sorting
1278 m_rSourceObject.copyFilterAndSortingTo(m_xDestConnection,xTable);
1279 // set column mappings
1280 Reference<XNameAccess> xNameAccess = xSuppDestinationColumns->getColumns();
1281 Sequence< OUString> aSeq = xNameAccess->getElementNames();
1282 const OUString* pIter = aSeq.getConstArray();
1283 const OUString* pEnd = pIter + aSeq.getLength();
1285 for(sal_Int32 nNewPos=1;pIter != pEnd;++pIter,++nNewPos)
1287 ODatabaseExport::TColumns::const_iterator aDestIter = m_vDestColumns.find(*pIter);
1289 if ( aDestIter != m_vDestColumns.end() )
1291 ODatabaseExport::TColumnVector::const_iterator aFind = ::std::find(m_aDestVec.begin(),m_aDestVec.end(),aDestIter);
1292 sal_Int32 nPos = (aFind - m_aDestVec.begin())+1;
1294 ODatabaseExport::TPositions::iterator aPosFind = ::std::find_if(
1295 m_vColumnPos.begin(),
1296 m_vColumnPos.end(),
1297 ::o3tl::compose1( ::std::bind2nd( ::std::equal_to< sal_Int32 >(), nPos ),
1298 ::o3tl::select1st< ODatabaseExport::TPositions::value_type >()
1302 if ( m_vColumnPos.end() != aPosFind )
1304 aPosFind->second = nNewPos;
1305 OSL_ENSURE( m_vColumnTypes.size() > size_t( aPosFind - m_vColumnPos.begin() ),
1306 "Invalid index for vector!" );
1307 m_vColumnTypes[ aPosFind - m_vColumnPos.begin() ] = (*aFind)->second->GetType();
1313 else if(xTables.is() && xTables->hasByName(m_sName))
1314 xTables->getByName(m_sName) >>= xTable;
1316 return xTable;
1319 bool OCopyTableWizard::supportsPrimaryKey( const Reference< XConnection >& _rxConnection )
1321 OSL_PRECOND( _rxConnection.is(), "OCopyTableWizard::supportsPrimaryKey: invalid connection!" );
1322 if ( !_rxConnection.is() )
1323 return false;
1325 ::dbtools::DatabaseMetaData aMetaData( _rxConnection );
1326 return aMetaData.supportsPrimaryKeys();
1329 bool OCopyTableWizard::supportsViews( const Reference< XConnection >& _rxConnection )
1331 OSL_PRECOND( _rxConnection.is(), "OCopyTableWizard::supportsViews: invalid connection!" );
1332 if ( !_rxConnection.is() )
1333 return false;
1335 bool bSupportsViews( false );
1338 Reference< XDatabaseMetaData > xMetaData( _rxConnection->getMetaData(), UNO_SET_THROW );
1339 Reference< XViewsSupplier > xViewSups( _rxConnection, UNO_QUERY );
1340 bSupportsViews = xViewSups.is();
1341 if ( !bSupportsViews )
1345 Reference< XResultSet > xRs( xMetaData->getTableTypes(), UNO_SET_THROW );
1346 Reference< XRow > xRow( xRs, UNO_QUERY_THROW );
1347 while ( xRs->next() )
1349 OUString sValue = xRow->getString( 1 );
1350 if ( !xRow->wasNull() && sValue.equalsIgnoreAsciiCase("View") )
1352 bSupportsViews = true;
1353 break;
1357 catch( const SQLException& )
1359 DBG_UNHANDLED_EXCEPTION();
1363 catch( const Exception& )
1365 DBG_UNHANDLED_EXCEPTION();
1367 return bSupportsViews;
1370 sal_Int32 OCopyTableWizard::getMaxColumnNameLength() const
1372 sal_Int32 nLen = 0;
1373 if ( m_xDestConnection.is() )
1377 Reference< XDatabaseMetaData > xMetaData( m_xDestConnection->getMetaData(), UNO_SET_THROW );
1378 nLen = xMetaData->getMaxColumnNameLength();
1380 catch(const Exception&)
1382 DBG_UNHANDLED_EXCEPTION();
1385 return nLen;
1388 void OCopyTableWizard::setOperation( const sal_Int16 _nOperation )
1390 m_nOperation = _nOperation;
1394 OUString OCopyTableWizard::convertColumnName(const TColumnFindFunctor& _rCmpFunctor,
1395 const OUString& _sColumnName,
1396 const OUString& _sExtraChars,
1397 sal_Int32 _nMaxNameLen)
1399 OUString sAlias = _sColumnName;
1400 if ( isSQL92CheckEnabled( m_xDestConnection ) )
1401 sAlias = ::dbtools::convertName2SQLName(_sColumnName,_sExtraChars);
1402 if((_nMaxNameLen && sAlias.getLength() > _nMaxNameLen) || _rCmpFunctor(sAlias))
1404 sal_Int32 nDiff = 1;
1407 ++nDiff;
1408 if(_nMaxNameLen && sAlias.getLength() >= _nMaxNameLen)
1409 sAlias = sAlias.copy(0,sAlias.getLength() - (sAlias.getLength()-_nMaxNameLen+nDiff));
1411 OUString sName(sAlias);
1412 sal_Int32 nPos = 1;
1413 sName += OUString::number(nPos);
1415 while(_rCmpFunctor(sName))
1417 sName = sAlias;
1418 sName += OUString::number(++nPos);
1420 sAlias = sName;
1421 // we have to check again, it could happen that the name is already to long
1423 while(_nMaxNameLen && sAlias.getLength() > _nMaxNameLen);
1425 OSL_ENSURE(m_mNameMapping.find(_sColumnName) == m_mNameMapping.end(),"name doubled!");
1426 m_mNameMapping[_sColumnName] = sAlias;
1427 return sAlias;
1430 void OCopyTableWizard::removeColumnNameFromNameMap(const OUString& _sName)
1432 m_mNameMapping.erase(_sName);
1435 bool OCopyTableWizard::supportsType(sal_Int32 _nDataType, sal_Int32& _rNewDataType)
1437 bool bRet = m_aDestTypeInfo.find(_nDataType) != m_aDestTypeInfo.end();
1438 if ( bRet )
1439 _rNewDataType = _nDataType;
1440 return bRet;
1443 TOTypeInfoSP OCopyTableWizard::convertType(const TOTypeInfoSP& _pType, bool& _bNotConvert)
1445 if ( !m_bInterConnectionCopy )
1446 // no need to convert if the source and destination connection are the same
1447 return _pType;
1449 bool bForce;
1450 TOTypeInfoSP pType = ::dbaui::getTypeInfoFromType(m_aDestTypeInfo,_pType->nType,_pType->aTypeName,_pType->aCreateParams,_pType->nPrecision,_pType->nMaximumScale,_pType->bAutoIncrement,bForce);
1451 if ( !pType.get() || bForce )
1452 { // no type found so we have to find the correct one ourself
1453 sal_Int32 nDefaultType = DataType::VARCHAR;
1454 switch(_pType->nType)
1456 case DataType::TINYINT:
1457 if(supportsType(DataType::SMALLINT,nDefaultType))
1458 break;
1459 // run through
1460 case DataType::SMALLINT:
1461 if(supportsType(DataType::INTEGER,nDefaultType))
1462 break;
1463 // run through
1464 case DataType::INTEGER:
1465 if(supportsType(DataType::FLOAT,nDefaultType))
1466 break;
1467 // run through
1468 case DataType::FLOAT:
1469 if(supportsType(DataType::REAL,nDefaultType))
1470 break;
1471 // run through
1472 case DataType::DATE:
1473 case DataType::TIME:
1474 if( DataType::DATE == _pType->nType || DataType::TIME == _pType->nType )
1476 if(supportsType(DataType::TIMESTAMP,nDefaultType))
1477 break;
1479 // run through
1480 case DataType::TIMESTAMP:
1481 case DataType::REAL:
1482 case DataType::BIGINT:
1483 if ( supportsType(DataType::DOUBLE,nDefaultType) )
1484 break;
1485 // run through
1486 case DataType::DOUBLE:
1487 if ( supportsType(DataType::NUMERIC,nDefaultType) )
1488 break;
1489 // run through
1490 case DataType::NUMERIC:
1491 supportsType(DataType::DECIMAL,nDefaultType);
1492 break;
1493 case DataType::DECIMAL:
1494 if ( supportsType(DataType::NUMERIC,nDefaultType) )
1495 break;
1496 if ( supportsType(DataType::DOUBLE,nDefaultType) )
1497 break;
1498 break;
1499 case DataType::VARCHAR:
1500 if ( supportsType(DataType::LONGVARCHAR,nDefaultType) )
1501 break;
1502 break;
1503 case DataType::LONGVARCHAR:
1504 if ( supportsType(DataType::CLOB,nDefaultType) )
1505 break;
1506 break;
1507 case DataType::BINARY:
1508 if ( supportsType(DataType::VARBINARY,nDefaultType) )
1509 break;
1510 break;
1511 case DataType::VARBINARY:
1512 if ( supportsType(DataType::LONGVARBINARY,nDefaultType) )
1513 break;
1514 break;
1515 case DataType::LONGVARBINARY:
1516 if ( supportsType(DataType::BLOB,nDefaultType) )
1517 break;
1518 if ( supportsType(DataType::LONGVARCHAR,nDefaultType) )
1519 break;
1520 if ( supportsType(DataType::CLOB,nDefaultType) )
1521 break;
1522 break;
1523 default:
1524 nDefaultType = DataType::VARCHAR;
1526 pType = ::dbaui::getTypeInfoFromType(m_aDestTypeInfo,nDefaultType,_pType->aTypeName,_pType->aCreateParams,_pType->nPrecision,_pType->nMaximumScale,_pType->bAutoIncrement,bForce);
1527 if ( !pType.get() )
1529 _bNotConvert = false;
1530 OUString sCreate("x");
1531 pType = ::dbaui::getTypeInfoFromType(m_aDestTypeInfo,DataType::VARCHAR,_pType->aTypeName,sCreate,50,0,false,bForce);
1532 if ( !pType.get() )
1533 pType = m_pTypeInfo;
1535 else if ( bForce )
1536 _bNotConvert = false;
1538 return pType;
1541 OUString OCopyTableWizard::createUniqueName(const OUString& _sName)
1543 OUString sName = _sName;
1544 Sequence< OUString > aColumnNames( m_rSourceObject.getColumnNames() );
1545 if ( aColumnNames.getLength() )
1546 sName = ::dbtools::createUniqueName( aColumnNames, sName, false );
1547 else
1549 if ( m_vSourceColumns.find(sName) != m_vSourceColumns.end())
1551 sal_Int32 nPos = 0;
1552 while(m_vSourceColumns.find(sName) != m_vSourceColumns.end())
1554 sName = _sName;
1555 sName += OUString::number(++nPos);
1559 return sName;
1562 void OCopyTableWizard::showColumnTypeNotSupported(const OUString& _rColumnName)
1564 OUString sMessage( ModuleRes( STR_UNKNOWN_TYPE_FOUND ) );
1565 sMessage = sMessage.replaceFirst("#1",_rColumnName);
1566 showError(sMessage);
1569 void OCopyTableWizard::showError(const OUString& _sErrorMessage)
1571 SQLExceptionInfo aInfo(_sErrorMessage);
1572 showError(aInfo.get());
1575 void OCopyTableWizard::showError(const Any& _aError)
1577 if ( _aError.hasValue() && m_xInteractionHandler.is() )
1581 ::rtl::Reference< ::comphelper::OInteractionRequest > xRequest( new ::comphelper::OInteractionRequest( _aError ) );
1582 m_xInteractionHandler->handle( xRequest.get() );
1584 catch( const Exception& )
1586 DBG_UNHANDLED_EXCEPTION();
1591 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */