1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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"
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>
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
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
)
96 // ICopyTableSourceObject
97 ICopyTableSourceObject::~ICopyTableSourceObject()
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
115 if ( !m_xObjectPSI
->hasPropertyByName( PROPERTY_COMMAND
) )
116 sName
= ::dbtools::composeTableName( m_xMetaData
, m_xObject
, ::dbtools::EComposeRule::InDataManipulation
, false, false, false );
118 m_xObject
->getPropertyValue( PROPERTY_NAME
) >>= 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();
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
) )
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
);
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
) );
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();
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
) )
221 OSL_VERIFY( m_xObject
->getPropertyValue( PROPERTY_COMMAND
) >>= sSelectStatement
);
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
)
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
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
)
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
278 bool NamedTableCopySource::isView() const
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() )
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
);
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();
347 aNames
[ col
- m_aColumnInfo
.begin() ] = col
->GetName();
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();
375 OFieldDescription
* NamedTableCopySource::createFieldDescription( const OUString
& _rColumnName
) const
377 for ( ::std::vector
< OFieldDescription
>::const_iterator col
= m_aColumnInfo
.begin();
378 col
!= m_aColumnInfo
.end();
381 if ( col
->GetName() == _rColumnName
)
382 return new OFieldDescription( *col
);
387 OUString
NamedTableCopySource::getSelectStatement() const
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();
403 class DummyCopySource
: public ICopyTableSourceObject
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!" );
437 bool DummyCopySource::isView() const
439 SAL_WARN("dbaccess.ui", "DummyCopySource::isView: not to be called!" );
443 void DummyCopySource::copyUISettingsTo( const Reference
< XPropertySet
>& /*_rxObject*/ ) const
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!" );
469 OUString
DummyCopySource::getSelectStatement() const
471 SAL_WARN("dbaccess.ui", "DummyCopySource::getSelectStatement: not to be called!" );
475 ::utl::SharedUNOComponent
< XPreparedStatement
> DummyCopySource::getPreparedSelectStatement() const
477 SAL_WARN("dbaccess.ui", "DummyCopySource::getPreparedSelectStatement: not to be called!" );
478 return ::utl::SharedUNOComponent
< XPreparedStatement
>();
483 bool lcl_canCreateViewFor_nothrow( const Reference
< XConnection
>& _rxConnection
)
485 Reference
< XViewsSupplier
> xSup( _rxConnection
, UNO_QUERY
);
486 Reference
< XDataDescriptorFactory
> xViewFac
;
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() );
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
))
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)
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 );
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() )
557 // no views if the target connection does not support creating them
558 if ( !lcl_canCreateViewFor_nothrow( m_xDestConnection
) )
560 // no views if we're copying to a different database
561 if ( !lcl_sameConnection_throw( _xSourceConnection
, m_xDestConnection
) )
564 if ( m_bInterConnectionCopy
)
566 Reference
< XDatabaseMetaData
> xSrcMeta
= _xSourceConnection
->getMetaData();
570 ::dbtools::qualifiedNameComponents( xSrcMeta
,
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();
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 ) );
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
))
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)
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
) );
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
));
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
);
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()
691 void OCopyTableWizard::dispose()
695 VclPtr
<TabPage
> pPage
= GetPage(0);
696 if ( pPage
== nullptr )
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();
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
;
725 if ( getOperation() != CopyTableOperation::AppendData
)
727 if(GetCurLevel() == 2)
728 ShowPage(GetCurLevel()-2);
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);
754 bool OCopyTableWizard::CheckColumns(sal_Int32
& _rnBreakPos
)
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());
805 m_vColumnPos
.push_back( ODatabaseExport::TPositions::value_type( COLUMN_POSITION_NOT_FOUND
, COLUMN_POSITION_NOT_FOUND
) );
806 m_vColumnTypes
.push_back(0);
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
);
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());
837 IMPL_LINK_NOARG_TYPED(OCopyTableWizard
, ImplOKHdl
, Button
*, void)
839 m_ePressed
= WIZARD_FINISH
;
840 bool bFinish
= DeactivatePage();
844 WaitObject
aWait(this);
845 switch(getOperation())
847 case CopyTableOperation::CopyDefinitionAndData
:
848 case CopyTableOperation::CopyDefinitionOnly
:
850 bool bOnFirstPage
= GetCurLevel() == 0;
853 // we came from the first page so we have to clear
854 // all column information already collected
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));
866 m_mNameMapping
.clear();
867 pPage
->setDisplayRow(nBreakPos
);
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
));
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() )
900 m_aKeyName
= createUniqueName( m_aKeyName
);
901 sal_Int32 nBreakPos2
= 0;
902 CheckColumns(nBreakPos2
);
904 else if ( xAbort
->wasSelected() )
914 case CopyTableOperation::AppendData
:
915 case CopyTableOperation::CreateAsView
:
919 SAL_WARN("dbaccess.ui", "OCopyTableWizard::ImplOKHdl: invalid creation style!");
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!" );
937 pSettingsPage
->setCreatePrimaryKey( _bDoCreate
, _rSuggestedName
);
940 IMPL_LINK_NOARG_TYPED(OCopyTableWizard
, ImplActivateHdl
, WizardDialog
*, void)
942 OWizardPage
* pCurrent
= static_cast<OWizardPage
*>(GetPage(GetCurLevel()));
945 bool bFirstTime
= pCurrent
->IsFirstTime();
951 SetText(pCurrent
->GetTitle());
957 void OCopyTableWizard::CheckButtons()
959 if(GetCurLevel() == 0) // the first page has no back button
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);
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
)
997 void OCopyTableWizard::insertColumn(sal_Int32 _nPos
,OFieldDescription
* _pField
)
999 OSL_ENSURE(_pField
,"FieldDescrioption is null!");
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!");
1020 m_vDestColumns
.erase(_sOldName
);
1021 OSL_ENSURE( m_vDestColumns
.find(_pField
->GetName()) == m_vDestColumns
.end(),"Column with that name already exist!");
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
)
1039 _rColVector
.clear();
1042 OFieldDescription
* pActFieldDescr
= nullptr;
1043 OUString
sCreateParam("x");
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
)
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();
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");
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
;
1120 Reference
<XPropertySet
> xColumn
;
1121 if(pField
->IsPrimaryKey() || !_bKeyColumns
)
1122 xColumn
= xColumnFactory
->createDataDescriptor();
1126 dbaui::setColumnProperties(xColumn
,pField
);
1128 xColumn
->setPropertyValue(PROPERTY_NAME
,makeAny(pField
->GetName()));
1130 xAppend
->appendByDescriptor(xColumn
);
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!");
1138 pField
->copyColumnSettingsTo(xColumn
);
1142 SAL_WARN("dbaccess.ui", "OCopyTableWizard::appendColumns: invalid field name!");
1149 void OCopyTableWizard::appendKey( Reference
<XKeysSupplier
>& _rxSup
, const ODatabaseExport::TColumnVector
* _pVec
)
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() )
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
);
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
;
1192 xTables
= xSup
->getTables();
1193 if ( getOperation() != CopyTableOperation::AppendData
)
1195 Reference
<XDataDescriptorFactory
> xFact(xTables
,UNO_QUERY
);
1196 OSL_ENSURE(xFact
.is(),"No XDataDescriptorFactory available!");
1200 xTable
= xFact
->createDataDescriptor();
1201 OSL_ENSURE(xTable
.is(),"Could not create a new object!");
1205 OUString sCatalog
,sSchema
,sTable
;
1206 Reference
< XDatabaseMetaData
> xMetaData
= m_xDestConnection
->getMetaData();
1207 ::dbtools::qualifiedNameComponents(xMetaData
,
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
);
1238 xAppend
->appendByDescriptor(xTable
);
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
;
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
;
1258 xSuppDestinationColumns
.set( xTable
, UNO_QUERY_THROW
);
1259 // insert new table name into table filter
1260 ::dbaui::appendToFilter( m_xDestConnection
, m_sName
, GetComponentContext(), this );
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(),
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
;
1306 bool OCopyTableWizard::supportsPrimaryKey( const Reference
< XConnection
>& _rxConnection
)
1308 OSL_PRECOND( _rxConnection
.is(), "OCopyTableWizard::supportsPrimaryKey: invalid connection!" );
1309 if ( !_rxConnection
.is() )
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() )
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;
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
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();
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;
1395 if(_nMaxNameLen
&& sAlias
.getLength() >= _nMaxNameLen
)
1396 sAlias
= sAlias
.copy(0,sAlias
.getLength() - (sAlias
.getLength()-_nMaxNameLen
+nDiff
));
1398 OUString
sName(sAlias
);
1400 sName
+= OUString::number(nPos
);
1402 while(_rCmpFunctor(sName
))
1405 sName
+= OUString::number(++nPos
);
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
;
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();
1426 _rNewDataType
= _nDataType
;
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
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
))
1447 case DataType::SMALLINT
:
1448 if(supportsType(DataType::INTEGER
,nDefaultType
))
1451 case DataType::INTEGER
:
1452 if(supportsType(DataType::FLOAT
,nDefaultType
))
1455 case DataType::FLOAT
:
1456 if(supportsType(DataType::REAL
,nDefaultType
))
1459 case DataType::DATE
:
1460 case DataType::TIME
:
1461 if( DataType::DATE
== _pType
->nType
|| DataType::TIME
== _pType
->nType
)
1463 if(supportsType(DataType::TIMESTAMP
,nDefaultType
))
1467 case DataType::TIMESTAMP
:
1468 case DataType::REAL
:
1469 case DataType::BIGINT
:
1470 if ( supportsType(DataType::DOUBLE
,nDefaultType
) )
1473 case DataType::DOUBLE
:
1474 if ( supportsType(DataType::NUMERIC
,nDefaultType
) )
1477 case DataType::NUMERIC
:
1478 supportsType(DataType::DECIMAL
,nDefaultType
);
1480 case DataType::DECIMAL
:
1481 if ( supportsType(DataType::NUMERIC
,nDefaultType
) )
1483 if ( supportsType(DataType::DOUBLE
,nDefaultType
) )
1486 case DataType::VARCHAR
:
1487 if ( supportsType(DataType::LONGVARCHAR
,nDefaultType
) )
1490 case DataType::LONGVARCHAR
:
1491 if ( supportsType(DataType::CLOB
,nDefaultType
) )
1494 case DataType::BINARY
:
1495 if ( supportsType(DataType::VARBINARY
,nDefaultType
) )
1498 case DataType::VARBINARY
:
1499 if ( supportsType(DataType::LONGVARBINARY
,nDefaultType
) )
1502 case DataType::LONGVARBINARY
:
1503 if ( supportsType(DataType::BLOB
,nDefaultType
) )
1505 if ( supportsType(DataType::LONGVARCHAR
,nDefaultType
) )
1507 if ( supportsType(DataType::CLOB
,nDefaultType
) )
1511 nDefaultType
= DataType::VARCHAR
;
1513 pType
= ::dbaui::getTypeInfoFromType(m_aDestTypeInfo
,nDefaultType
,_pType
->aTypeName
,_pType
->aCreateParams
,_pType
->nPrecision
,_pType
->nMaximumScale
,_pType
->bAutoIncrement
,bForce
);
1516 _bNotConvert
= false;
1517 OUString
sCreate("x");
1518 pType
= ::dbaui::getTypeInfoFromType(m_aDestTypeInfo
,DataType::VARCHAR
,_pType
->aTypeName
,sCreate
,50,0,false,bForce
);
1520 pType
= m_pTypeInfo
;
1523 _bNotConvert
= false;
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 );
1536 if ( m_vSourceColumns
.find(sName
) != m_vSourceColumns
.end())
1539 while(m_vSourceColumns
.find(sName
) != m_vSourceColumns
.end())
1542 sName
+= OUString::number(++nPos
);
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: */