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>
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
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
)
97 // ICopyTableSourceObject
98 ICopyTableSourceObject::~ICopyTableSourceObject()
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
116 if ( !m_xObjectPSI
->hasPropertyByName( PROPERTY_COMMAND
) )
117 sName
= ::dbtools::composeTableName( m_xMetaData
, m_xObject
, ::dbtools::eInDataManipulation
, false, false, false );
119 m_xObject
->getPropertyValue( PROPERTY_NAME
) >>= 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();
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
) )
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
);
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
) );
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();
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
) )
222 OSL_VERIFY( m_xObject
->getPropertyValue( PROPERTY_COMMAND
) >>= sSelectStatement
);
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( " " );
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
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
)
270 ::dbtools::qualifiedNameComponents( m_xMetaData
, m_sTableName
, m_sTableCatalog
, m_sTableSchema
, m_sTableBareName
, ::dbtools::eComplete
);
271 impl_ensureColumnInfo_throw();
274 OUString
NamedTableCopySource::getQualifiedObjectName() const
279 bool NamedTableCopySource::isView() const
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() )
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
);
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();
348 aNames
[ col
- m_aColumnInfo
.begin() ] = col
->GetName();
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();
376 OFieldDescription
* NamedTableCopySource::createFieldDescription( const OUString
& _rColumnName
) const
378 for ( ::std::vector
< OFieldDescription
>::const_iterator col
= m_aColumnInfo
.begin();
379 col
!= m_aColumnInfo
.end();
382 if ( col
->GetName() == _rColumnName
)
383 return new OFieldDescription( *col
);
388 OUString
NamedTableCopySource::getSelectStatement() const
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();
404 class DummyCopySource
: public ICopyTableSourceObject
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!" );
438 bool DummyCopySource::isView() const
440 SAL_WARN("dbaccess.ui", "DummyCopySource::isView: not to be called!" );
444 void DummyCopySource::copyUISettingsTo( const Reference
< XPropertySet
>& /*_rxObject*/ ) const
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!" );
470 OUString
DummyCopySource::getSelectStatement() const
472 SAL_WARN("dbaccess.ui", "DummyCopySource::getSelectStatement: not to be called!" );
476 ::utl::SharedUNOComponent
< XPreparedStatement
> DummyCopySource::getPreparedSelectStatement() const
478 SAL_WARN("dbaccess.ui", "DummyCopySource::getPreparedSelectStatement: not to be called!" );
479 return ::utl::SharedUNOComponent
< XPreparedStatement
>();
484 bool lcl_canCreateViewFor_nothrow( const Reference
< XConnection
>& _rxConnection
)
486 Reference
< XViewsSupplier
> xSup( _rxConnection
, UNO_QUERY
);
487 Reference
< XDataDescriptorFactory
> xViewFac
;
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() );
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
))
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)
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 );
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() )
558 // no views if the target connection does not support creating them
559 if ( !lcl_canCreateViewFor_nothrow( m_xDestConnection
) )
561 // no views if we're copying to a different database
562 if ( !lcl_sameConnection_throw( _xSourceConnection
, m_xDestConnection
) )
565 if ( m_bInterConnectionCopy
)
567 Reference
< XDatabaseMetaData
> xSrcMeta
= _xSourceConnection
->getMetaData();
571 ::dbtools::qualifiedNameComponents( xSrcMeta
,
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();
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 ) );
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
))
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)
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
) );
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
));
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
);
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()
692 void OCopyTableWizard::dispose()
696 VclPtr
<TabPage
> pPage
= GetPage(0);
697 if ( pPage
== nullptr )
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();
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
;
726 if ( getOperation() != CopyTableOperation::AppendData
)
728 if(GetCurLevel() == 2)
729 ShowPage(GetCurLevel()-2);
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);
757 bool OCopyTableWizard::CheckColumns(sal_Int32
& _rnBreakPos
)
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());
808 m_vColumnPos
.push_back( ODatabaseExport::TPositions::value_type( COLUMN_POSITION_NOT_FOUND
, COLUMN_POSITION_NOT_FOUND
) );
809 m_vColumnTypes
.push_back(0);
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
);
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());
840 IMPL_LINK_NOARG(OCopyTableWizard
, ImplOKHdl
)
842 m_ePressed
= WIZARD_FINISH
;
843 bool bFinish
= DeactivatePage();
847 WaitObject
aWait(this);
848 switch(getOperation())
850 case CopyTableOperation::CopyDefinitionAndData
:
851 case CopyTableOperation::CopyDefinitionOnly
:
853 bool bOnFirstPage
= GetCurLevel() == 0;
856 // we came from the first page so we have to clear
857 // all column information already collected
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));
869 m_mNameMapping
.clear();
870 pPage
->setDisplayRow(nBreakPos
);
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
));
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() )
903 m_aKeyName
= createUniqueName( m_aKeyName
);
904 sal_Int32 nBreakPos2
= 0;
905 CheckColumns(nBreakPos2
);
907 else if ( xAbort
->wasSelected() )
917 case CopyTableOperation::AppendData
:
918 case CopyTableOperation::CreateAsView
:
922 SAL_WARN("dbaccess.ui", "OCopyTableWizard::ImplOKHdl: invalid creation style!");
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!" );
941 pSettingsPage
->setCreatePrimaryKey( _bDoCreate
, _rSuggestedName
);
944 IMPL_LINK_NOARG(OCopyTableWizard
, ImplActivateHdl
)
946 OWizardPage
* pCurrent
= static_cast<OWizardPage
*>(GetPage(GetCurLevel()));
949 bool bFirstTime
= pCurrent
->IsFirstTime();
955 SetText(pCurrent
->GetTitle());
962 void OCopyTableWizard::CheckButtons()
964 if(GetCurLevel() == 0) // the first page has no back button
967 m_pbNext
->Enable(true);
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);
980 m_pbPrev
->Enable(true);
981 // next already has its state
985 void OCopyTableWizard::EnableButton(Wizard_Button_Style eStyle
, bool bEnable
)
988 if(eStyle
== WIZARD_NEXT
)
990 else if(eStyle
== WIZARD_PREV
)
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
)
1010 void OCopyTableWizard::insertColumn(sal_Int32 _nPos
,OFieldDescription
* _pField
)
1012 OSL_ENSURE(_pField
,"FieldDescrioption is null!");
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!");
1033 m_vDestColumns
.erase(_sOldName
);
1034 OSL_ENSURE( m_vDestColumns
.find(_pField
->GetName()) == m_vDestColumns
.end(),"Column with that name already exist!");
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
)
1052 _rColVector
.clear();
1055 OFieldDescription
* pActFieldDescr
= NULL
;
1056 OUString
sCreateParam("x");
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
)
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();
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");
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
;
1133 Reference
<XPropertySet
> xColumn
;
1134 if(pField
->IsPrimaryKey() || !_bKeyColumns
)
1135 xColumn
= xColumnFactory
->createDataDescriptor();
1139 dbaui::setColumnProperties(xColumn
,pField
);
1141 xColumn
->setPropertyValue(PROPERTY_NAME
,makeAny(pField
->GetName()));
1143 xAppend
->appendByDescriptor(xColumn
);
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!");
1151 pField
->copyColumnSettingsTo(xColumn
);
1155 SAL_WARN("dbaccess.ui", "OCopyTableWizard::appendColumns: invalid field name!");
1162 void OCopyTableWizard::appendKey( Reference
<XKeysSupplier
>& _rxSup
, const ODatabaseExport::TColumnVector
* _pVec
)
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() )
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
);
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
;
1205 xTables
= xSup
->getTables();
1206 if ( getOperation() != CopyTableOperation::AppendData
)
1208 Reference
<XDataDescriptorFactory
> xFact(xTables
,UNO_QUERY
);
1209 OSL_ENSURE(xFact
.is(),"No XDataDescriptorFactory available!");
1213 xTable
= xFact
->createDataDescriptor();
1214 OSL_ENSURE(xTable
.is(),"Could not create a new object!");
1218 OUString sCatalog
,sSchema
,sTable
;
1219 Reference
< XDatabaseMetaData
> xMetaData
= m_xDestConnection
->getMetaData();
1220 ::dbtools::qualifiedNameComponents(xMetaData
,
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
);
1251 xAppend
->appendByDescriptor(xTable
);
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
;
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
;
1271 xSuppDestinationColumns
.set( xTable
, UNO_QUERY_THROW
);
1272 // insert new table name into table filter
1273 ::dbaui::appendToFilter( m_xDestConnection
, m_sName
, GetComponentContext(), this );
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(),
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
;
1319 bool OCopyTableWizard::supportsPrimaryKey( const Reference
< XConnection
>& _rxConnection
)
1321 OSL_PRECOND( _rxConnection
.is(), "OCopyTableWizard::supportsPrimaryKey: invalid connection!" );
1322 if ( !_rxConnection
.is() )
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() )
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;
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
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();
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;
1408 if(_nMaxNameLen
&& sAlias
.getLength() >= _nMaxNameLen
)
1409 sAlias
= sAlias
.copy(0,sAlias
.getLength() - (sAlias
.getLength()-_nMaxNameLen
+nDiff
));
1411 OUString
sName(sAlias
);
1413 sName
+= OUString::number(nPos
);
1415 while(_rCmpFunctor(sName
))
1418 sName
+= OUString::number(++nPos
);
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
;
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();
1439 _rNewDataType
= _nDataType
;
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
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
))
1460 case DataType::SMALLINT
:
1461 if(supportsType(DataType::INTEGER
,nDefaultType
))
1464 case DataType::INTEGER
:
1465 if(supportsType(DataType::FLOAT
,nDefaultType
))
1468 case DataType::FLOAT
:
1469 if(supportsType(DataType::REAL
,nDefaultType
))
1472 case DataType::DATE
:
1473 case DataType::TIME
:
1474 if( DataType::DATE
== _pType
->nType
|| DataType::TIME
== _pType
->nType
)
1476 if(supportsType(DataType::TIMESTAMP
,nDefaultType
))
1480 case DataType::TIMESTAMP
:
1481 case DataType::REAL
:
1482 case DataType::BIGINT
:
1483 if ( supportsType(DataType::DOUBLE
,nDefaultType
) )
1486 case DataType::DOUBLE
:
1487 if ( supportsType(DataType::NUMERIC
,nDefaultType
) )
1490 case DataType::NUMERIC
:
1491 supportsType(DataType::DECIMAL
,nDefaultType
);
1493 case DataType::DECIMAL
:
1494 if ( supportsType(DataType::NUMERIC
,nDefaultType
) )
1496 if ( supportsType(DataType::DOUBLE
,nDefaultType
) )
1499 case DataType::VARCHAR
:
1500 if ( supportsType(DataType::LONGVARCHAR
,nDefaultType
) )
1503 case DataType::LONGVARCHAR
:
1504 if ( supportsType(DataType::CLOB
,nDefaultType
) )
1507 case DataType::BINARY
:
1508 if ( supportsType(DataType::VARBINARY
,nDefaultType
) )
1511 case DataType::VARBINARY
:
1512 if ( supportsType(DataType::LONGVARBINARY
,nDefaultType
) )
1515 case DataType::LONGVARBINARY
:
1516 if ( supportsType(DataType::BLOB
,nDefaultType
) )
1518 if ( supportsType(DataType::LONGVARCHAR
,nDefaultType
) )
1520 if ( supportsType(DataType::CLOB
,nDefaultType
) )
1524 nDefaultType
= DataType::VARCHAR
;
1526 pType
= ::dbaui::getTypeInfoFromType(m_aDestTypeInfo
,nDefaultType
,_pType
->aTypeName
,_pType
->aCreateParams
,_pType
->nPrecision
,_pType
->nMaximumScale
,_pType
->bAutoIncrement
,bForce
);
1529 _bNotConvert
= false;
1530 OUString
sCreate("x");
1531 pType
= ::dbaui::getTypeInfoFromType(m_aDestTypeInfo
,DataType::VARCHAR
,_pType
->aTypeName
,sCreate
,50,0,false,bForce
);
1533 pType
= m_pTypeInfo
;
1536 _bNotConvert
= false;
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 );
1549 if ( m_vSourceColumns
.find(sName
) != m_vSourceColumns
.end())
1552 while(m_vSourceColumns
.find(sName
) != m_vSourceColumns
.end())
1555 sName
+= OUString::number(++nPos
);
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: */