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 <DExport.hxx>
21 #include <core_resource.hxx>
23 #include <com/sun/star/sdbcx/XTablesSupplier.hpp>
24 #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
25 #include <com/sun/star/sdbc/DataType.hpp>
26 #include <com/sun/star/sdbc/ColumnValue.hpp>
27 #include <com/sun/star/sdb/CommandType.hpp>
28 #include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp>
29 #include <com/sun/star/sdbc/XRow.hpp>
30 #include <com/sun/star/uno/XComponentContext.hpp>
31 #include <com/sun/star/util/NumberFormat.hpp>
32 #include <com/sun/star/util/XNumberFormatTypes.hpp>
33 #include <strings.hrc>
34 #include <strings.hxx>
35 #include <connectivity/dbconversion.hxx>
36 #include <sal/log.hxx>
37 #include <sfx2/sfxhtml.hxx>
38 #include <svl/numuno.hxx>
39 #include <connectivity/dbtools.hxx>
40 #include <TypeInfo.hxx>
41 #include <FieldDescriptions.hxx>
42 #include <UITools.hxx>
43 #include <comphelper/diagnose_ex.hxx>
44 #include <com/sun/star/awt/FontDescriptor.hpp>
45 #include <WCopyTable.hxx>
46 #include <unotools/syslocale.hxx>
47 #include <svl/numformat.hxx>
48 #include <connectivity/dbexception.hxx>
49 #include <connectivity/FValue.hxx>
50 #include <com/sun/star/sdb/application/CopyTableOperation.hpp>
51 #include <sqlmessage.hxx>
52 #include "UpdateHelperImpl.hxx"
53 #include <cppuhelper/exc_hlp.hxx>
55 using namespace dbaui
;
57 using namespace ::com::sun::star::uno
;
58 using namespace ::com::sun::star::beans
;
59 using namespace ::com::sun::star::container
;
60 using namespace ::com::sun::star::util
;
61 using namespace ::com::sun::star::sdbc
;
62 using namespace ::com::sun::star::sdbcx
;
63 using namespace ::com::sun::star::sdb
;
64 using namespace ::com::sun::star::lang
;
65 using namespace ::com::sun::star::awt
;
67 namespace CopyTableOperation
= ::com::sun::star::sdb::application::CopyTableOperation
;
70 ODatabaseExport::ODatabaseExport(sal_Int32 nRows
,
71 TPositions
&&_rColumnPositions
,
72 const Reference
< XNumberFormatter
>& _rxNumberF
,
73 const Reference
< css::uno::XComponentContext
>& _rxContext
,
74 const TColumnVector
* pList
,
75 const OTypeInfoMap
* _pInfoMap
,
76 bool _bAutoIncrementEnabled
,
77 SvStream
& _rInputStream
)
78 :m_vColumnPositions(std::move(_rColumnPositions
))
80 ,m_xFormatter(_rxNumberF
)
81 ,m_xContext(_rxContext
)
82 ,m_pFormatter(nullptr)
83 ,m_rInputStream( _rInputStream
)
85 ,m_pInfoMap(_pInfoMap
)
92 ,m_bDontAskAgain(false)
93 ,m_bIsAutoIncrement(_bAutoIncrementEnabled
)
96 ,m_bAppendFirstLine(false)
100 for(const std::pair
<sal_Int32
,sal_Int32
> & rPair
: m_vColumnPositions
)
101 if ( rPair
.first
!= COLUMN_POSITION_NOT_FOUND
)
104 m_vColumnSize
.resize(nCount
);
105 m_vNumberFormat
.resize(nCount
);
106 for(sal_Int32 i
=0;i
<nCount
;++i
)
108 m_vColumnSize
[i
] = 0;
109 m_vNumberFormat
[i
] = 0;
114 SvtSysLocale aSysLocale
;
115 m_aLocale
= aSysLocale
.GetLanguageTag().getLocale();
121 SetColumnTypes(pList
,_pInfoMap
);
124 ODatabaseExport::ODatabaseExport(const SharedConnection
& _rxConnection
,
125 const Reference
< XNumberFormatter
>& _rxNumberF
,
126 const Reference
< css::uno::XComponentContext
>& _rxContext
,
127 SvStream
& _rInputStream
)
128 :m_aDestColumns(_rxConnection
->getMetaData().is() && _rxConnection
->getMetaData()->supportsMixedCaseQuotedIdentifiers())
129 ,m_xConnection(_rxConnection
)
130 ,m_xFormatter(_rxNumberF
)
131 ,m_xContext(_rxContext
)
132 ,m_pFormatter(nullptr)
133 ,m_rInputStream( _rInputStream
)
134 ,m_pColumnList(nullptr)
142 ,m_bDontAskAgain(false)
143 ,m_bIsAutoIncrement(false)
144 ,m_bFoundTable(false)
146 ,m_bAppendFirstLine(false)
150 SvtSysLocale aSysLocale
;
151 m_aLocale
= aSysLocale
.GetLanguageTag().getLocale();
157 Reference
<XTablesSupplier
> xTablesSup(m_xConnection
,UNO_QUERY
);
159 m_xTables
= xTablesSup
->getTables();
161 Reference
<XDatabaseMetaData
> xMeta
= m_xConnection
->getMetaData();
162 Reference
<XResultSet
> xSet
= xMeta
.is() ? xMeta
->getTypeInfo() : Reference
<XResultSet
>();
165 ::connectivity::ORowSetValue aValue
;
166 std::vector
<sal_Int32
> aTypes
;
167 std::vector
<bool> aNullable
;
168 Reference
<XResultSetMetaData
> xResultSetMetaData
= Reference
<XResultSetMetaDataSupplier
>(xSet
,UNO_QUERY_THROW
)->getMetaData();
169 Reference
<XRow
> xRow(xSet
,UNO_QUERY_THROW
);
172 if ( aTypes
.empty() )
174 sal_Int32 nCount
= xResultSetMetaData
->getColumnCount();
177 aTypes
.reserve(nCount
+1);
178 aNullable
.reserve(nCount
+1);
179 aTypes
.push_back(-1);
180 aNullable
.push_back(false);
181 for (sal_Int32 j
= 1; j
<= nCount
; ++j
)
183 aNullable
.push_back(xResultSetMetaData
->isNullable(j
) != ColumnValue::NO_NULLS
);
184 aTypes
.push_back(xResultSetMetaData
->getColumnType(j
));
189 OSL_ENSURE((nPos
) < static_cast<sal_Int32
>(aTypes
.size()),"aTypes: Illegal index for vector");
190 aValue
.fill(nPos
,aTypes
[nPos
],aNullable
[nPos
],xRow
);
191 OUString sTypeName
= aValue
.getString();
193 OSL_ENSURE((nPos
) < static_cast<sal_Int32
>(aTypes
.size()),"aTypes: Illegal index for vector");
194 aValue
.fill(nPos
,aTypes
[nPos
],aNullable
[nPos
],xRow
);
195 sal_Int32 nType
= aValue
.getInt32();
198 if( nType
== DataType::VARCHAR
)
200 m_pTypeInfo
= std::make_shared
<OTypeInfo
>();
202 m_pTypeInfo
->aTypeName
= sTypeName
;
203 m_pTypeInfo
->nType
= nType
;
205 OSL_ENSURE((nPos
) < static_cast<sal_Int32
>(aTypes
.size()),"aTypes: Illegal index for vector");
206 aValue
.fill(nPos
,aTypes
[nPos
],aNullable
[nPos
],xRow
);
207 m_pTypeInfo
->nPrecision
= aValue
.getInt32();
209 aValue
.fill(nPos
,aTypes
[nPos
],aNullable
[nPos
],xRow
); //LiteralPrefix
211 aValue
.fill(nPos
,aTypes
[nPos
],aNullable
[nPos
],xRow
); //LiteralSuffix
213 aValue
.fill(nPos
,aTypes
[nPos
],aNullable
[nPos
],xRow
);
214 m_pTypeInfo
->aCreateParams
= aValue
.getString();
216 aValue
.fill(nPos
,aTypes
[nPos
],aNullable
[nPos
],xRow
);
217 m_pTypeInfo
->bNullable
= aValue
.getInt32() == ColumnValue::NULLABLE
;
219 aValue
.fill(nPos
,aTypes
[nPos
],aNullable
[nPos
],xRow
);
222 aValue
.fill(nPos
,aTypes
[nPos
],aNullable
[nPos
],xRow
);
223 m_pTypeInfo
->nSearchType
= aValue
.getInt16();
225 aValue
.fill(nPos
,aTypes
[nPos
],aNullable
[nPos
],xRow
);
228 aValue
.fill(nPos
,aTypes
[nPos
],aNullable
[nPos
],xRow
);
229 m_pTypeInfo
->bCurrency
= aValue
.getBool();
231 aValue
.fill(nPos
,aTypes
[nPos
],aNullable
[nPos
],xRow
);
232 m_pTypeInfo
->bAutoIncrement
= aValue
.getBool();
234 aValue
.fill(nPos
,aTypes
[nPos
],aNullable
[nPos
],xRow
);
235 m_pTypeInfo
->aLocalTypeName
= aValue
.getString();
237 aValue
.fill(nPos
,aTypes
[nPos
],aNullable
[nPos
],xRow
);
238 m_pTypeInfo
->nMinimumScale
= aValue
.getInt16();
240 aValue
.fill(nPos
,aTypes
[nPos
],aNullable
[nPos
],xRow
);
241 m_pTypeInfo
->nMaximumScale
= aValue
.getInt16();
243 aValue
.fill(nPos
,aTypes
[nPos
],xRow
);
244 m_pTypeInfo
->nNumPrecRadix
= aValue
.getInt32();
246 // check if values are less than zero like it happens in a oracle jdbc driver
247 if( m_pTypeInfo
->nPrecision
< 0)
248 m_pTypeInfo
->nPrecision
= 0;
249 if( m_pTypeInfo
->nMinimumScale
< 0)
250 m_pTypeInfo
->nMinimumScale
= 0;
251 if( m_pTypeInfo
->nMaximumScale
< 0)
252 m_pTypeInfo
->nMaximumScale
= 0;
253 if( m_pTypeInfo
->nNumPrecRadix
<= 1)
254 m_pTypeInfo
->nNumPrecRadix
= 10;
260 m_pTypeInfo
= std::make_shared
<OTypeInfo
>();
263 ODatabaseExport::~ODatabaseExport()
265 m_pFormatter
= nullptr;
266 for (auto const& destColumn
: m_aDestColumns
)
267 delete destColumn
.second
;
268 m_vDestVector
.clear();
269 m_aDestColumns
.clear();
272 void ODatabaseExport::insertValueIntoColumn()
274 if(m_nColumnPos
>= sal_Int32(m_vDestVector
.size()))
277 OFieldDescription
* pField
= m_vDestVector
[m_nColumnPos
]->second
;
281 sal_Int32 nNewPos
= m_bIsAutoIncrement
? m_nColumnPos
+1 : m_nColumnPos
;
282 OSL_ENSURE(nNewPos
< static_cast<sal_Int32
>(m_vColumnPositions
.size()),"m_vColumnPositions: Illegal index for vector");
284 if ( nNewPos
< static_cast<sal_Int32
>(m_vColumnPositions
.size() ) )
286 sal_Int32 nPos
= m_vColumnPositions
[nNewPos
].first
;
287 if ( nPos
!= COLUMN_POSITION_NOT_FOUND
)
289 if ( m_sTextToken
.isEmpty() && pField
->IsNullable() )
290 m_pUpdateHelper
->updateNull(nPos
,pField
->GetType());
293 OSL_ENSURE((nNewPos
) < static_cast<sal_Int32
>(m_vColumnTypes
.size()),"Illegal index for vector");
294 if (m_vColumnTypes
[nNewPos
] != DataType::VARCHAR
&& m_vColumnTypes
[nNewPos
] != DataType::CHAR
&& m_vColumnTypes
[nNewPos
] != DataType::LONGVARCHAR
)
296 SAL_INFO("dbaccess.ui", "ODatabaseExport::insertValueIntoColumn != DataType::VARCHAR" );
298 sal_Int32 nNumberFormat
= 0;
299 double fOutNumber
= 0.0;
300 bool bNumberFormatError
= false;
301 if ( m_pFormatter
&& !m_sNumToken
.isEmpty() )
303 LanguageType eNumLang
= LANGUAGE_NONE
;
304 sal_uInt32
nNumberFormat2( nNumberFormat
);
305 fOutNumber
= SfxHTMLParser::GetTableDataOptionsValNum(nNumberFormat2
,eNumLang
,m_sTextToken
,m_sNumToken
,*m_pFormatter
);
306 if ( eNumLang
!= LANGUAGE_NONE
)
308 nNumberFormat2
= m_pFormatter
->GetFormatForLanguageIfBuiltIn( nNumberFormat2
, eNumLang
);
309 (void)m_pFormatter
->IsNumberFormat( m_sTextToken
, nNumberFormat2
, fOutNumber
);
311 nNumberFormat
= static_cast<sal_Int32
>(nNumberFormat2
);
315 Reference
< XNumberFormatsSupplier
> xSupplier
= m_xFormatter
->getNumberFormatsSupplier();
316 Reference
<XNumberFormatTypes
> xNumType(xSupplier
->getNumberFormats(),UNO_QUERY
);
317 const sal_Int16 nFormats
[] = {
318 NumberFormat::DATETIME
321 ,NumberFormat::CURRENCY
322 ,NumberFormat::NUMBER
323 ,NumberFormat::LOGICAL
325 for (short nFormat
: nFormats
)
329 nNumberFormat
= m_xFormatter
->detectNumberFormat(xNumType
->getStandardFormat(nFormat
,m_aLocale
),m_sTextToken
);
338 fOutNumber
= m_xFormatter
->convertStringToNumber(nNumberFormat
,m_sTextToken
);
342 bNumberFormatError
= true;
343 m_pUpdateHelper
->updateString(nPos
,m_sTextToken
);
346 if ( !bNumberFormatError
)
350 Reference
< XNumberFormatsSupplier
> xSupplier
= m_xFormatter
->getNumberFormatsSupplier();
351 Reference
< XNumberFormats
> xFormats
= xSupplier
->getNumberFormats();
352 Reference
<XPropertySet
> xProp
= xFormats
->getByKey(nNumberFormat
);
354 xProp
->getPropertyValue(PROPERTY_TYPE
) >>= nType
;
357 case NumberFormat::DATE
:
358 m_pUpdateHelper
->updateDate(nPos
,::dbtools::DBTypeConversion::toDate(fOutNumber
,m_aNullDate
));
360 case NumberFormat::DATETIME
:
361 m_pUpdateHelper
->updateTimestamp(nPos
,::dbtools::DBTypeConversion::toDateTime(fOutNumber
,m_aNullDate
));
363 case NumberFormat::TIME
:
364 m_pUpdateHelper
->updateTime(nPos
,::dbtools::DBTypeConversion::toTime(fOutNumber
));
367 m_pUpdateHelper
->updateDouble(nPos
,fOutNumber
);
372 m_pUpdateHelper
->updateString(nPos
,m_sTextToken
);
378 m_pUpdateHelper
->updateString(nPos
,m_sTextToken
);
385 sal_Int16
ODatabaseExport::CheckString(const OUString
& aCheckToken
, sal_Int16 _nOldNumberFormat
)
387 sal_Int16 nNumberFormat
= 0;
391 Reference
< XNumberFormatsSupplier
> xSupplier
= m_xFormatter
->getNumberFormatsSupplier();
392 Reference
< XNumberFormats
> xFormats
= xSupplier
->getNumberFormats();
395 if ( m_pFormatter
&& !m_sNumToken
.isEmpty() )
397 LanguageType eNumLang
;
398 sal_uInt32
nFormatKey(0);
399 double fOutNumber
= SfxHTMLParser::GetTableDataOptionsValNum(nFormatKey
,eNumLang
,m_sTextToken
,m_sNumToken
,*m_pFormatter
);
400 if ( eNumLang
!= LANGUAGE_NONE
)
402 nFormatKey
= m_pFormatter
->GetFormatForLanguageIfBuiltIn( nFormatKey
, eNumLang
);
403 if ( !m_pFormatter
->IsNumberFormat( m_sTextToken
, nFormatKey
, fOutNumber
) )
404 return NumberFormat::TEXT
;
406 Reference
<XPropertySet
> xProp
= xFormats
->getByKey(nFormatKey
);
407 xProp
->getPropertyValue(PROPERTY_TYPE
) >>= nNumberFormat
;
411 Reference
<XNumberFormatTypes
> xNumType(xFormats
,UNO_QUERY
);
412 sal_Int32 nFormatKey
= m_xFormatter
->detectNumberFormat(xNumType
->getStandardFormat(NumberFormat::ALL
,m_aLocale
),aCheckToken
);
413 m_xFormatter
->convertStringToNumber(nFormatKey
,aCheckToken
);
415 Reference
<XPropertySet
> xProp
= xFormats
->getByKey(nFormatKey
);
417 xProp
->getPropertyValue(PROPERTY_TYPE
) >>= nType
;
421 case NumberFormat::ALL
:
422 nNumberFormat
= NumberFormat::ALL
;
424 case NumberFormat::DEFINED
:
425 nNumberFormat
= NumberFormat::TEXT
;
427 case NumberFormat::DATE
:
428 switch(_nOldNumberFormat
)
430 case NumberFormat::DATETIME
:
431 case NumberFormat::TEXT
:
432 case NumberFormat::DATE
:
433 nNumberFormat
= _nOldNumberFormat
;
435 case NumberFormat::ALL
:
436 nNumberFormat
= NumberFormat::DATE
;
439 nNumberFormat
= NumberFormat::TEXT
;
443 case NumberFormat::TIME
:
444 switch(_nOldNumberFormat
)
446 case NumberFormat::DATETIME
:
447 case NumberFormat::TEXT
:
448 case NumberFormat::TIME
:
449 nNumberFormat
= _nOldNumberFormat
;
451 case NumberFormat::ALL
:
452 nNumberFormat
= NumberFormat::TIME
;
455 nNumberFormat
= NumberFormat::TEXT
;
459 case NumberFormat::CURRENCY
:
460 switch(_nOldNumberFormat
)
462 case NumberFormat::NUMBER
:
463 nNumberFormat
= NumberFormat::CURRENCY
;
465 case NumberFormat::CURRENCY
:
466 nNumberFormat
= _nOldNumberFormat
;
468 case NumberFormat::ALL
:
469 nNumberFormat
= NumberFormat::CURRENCY
;
472 nNumberFormat
= NumberFormat::TEXT
;
476 case NumberFormat::NUMBER
:
477 case NumberFormat::SCIENTIFIC
:
478 case NumberFormat::FRACTION
:
479 case NumberFormat::PERCENT
:
480 switch(_nOldNumberFormat
)
482 case NumberFormat::NUMBER
:
483 nNumberFormat
= _nOldNumberFormat
;
485 case NumberFormat::CURRENCY
:
486 nNumberFormat
= NumberFormat::CURRENCY
;
488 case NumberFormat::ALL
:
489 nNumberFormat
= nType
;
492 nNumberFormat
= NumberFormat::TEXT
;
496 case NumberFormat::TEXT
:
497 case NumberFormat::UNDEFINED
:
498 case NumberFormat::LOGICAL
:
499 nNumberFormat
= NumberFormat::TEXT
; // Text overwrites everything
501 case NumberFormat::DATETIME
:
502 switch(_nOldNumberFormat
)
504 case NumberFormat::DATETIME
:
505 case NumberFormat::TEXT
:
506 case NumberFormat::TIME
:
507 nNumberFormat
= _nOldNumberFormat
;
509 case NumberFormat::ALL
:
510 nNumberFormat
= NumberFormat::DATETIME
;
513 nNumberFormat
= NumberFormat::TEXT
;
518 SAL_WARN("dbaccess.ui", "ODatabaseExport: Unknown NumberFormat");
524 nNumberFormat
= NumberFormat::TEXT
; // Text overwrites everything
527 return nNumberFormat
;
530 void ODatabaseExport::SetColumnTypes(const TColumnVector
* _pList
,const OTypeInfoMap
* _pInfoMap
)
532 if(!(_pList
&& _pInfoMap
))
535 OSL_ENSURE(m_vNumberFormat
.size() == m_vColumnSize
.size() && m_vColumnSize
.size() == _pList
->size(),"Illegal columns in list");
536 Reference
< XNumberFormatsSupplier
> xSupplier
= m_xFormatter
->getNumberFormatsSupplier();
537 Reference
< XNumberFormats
> xFormats
= xSupplier
->getNumberFormats();
538 sal_Int32 minBothSize
= std::min
<sal_Int32
>(m_vNumberFormat
.size(), m_vColumnSize
.size());
540 for (auto const& elem
: *_pList
)
542 if (i
>= minBothSize
)
546 sal_Int32
nLength(0),nScale(0);
547 sal_Int16 nType
= m_vNumberFormat
[i
] & ~NumberFormat::DEFINED
;
551 case NumberFormat::ALL
:
552 nDataType
= DataType::DOUBLE
;
554 case NumberFormat::DEFINED
:
555 nDataType
= DataType::VARCHAR
;
556 nLength
= ((m_vColumnSize
[i
] % 10 ) ? m_vColumnSize
[i
]/ 10 + 1: m_vColumnSize
[i
]/ 10) * 10;
558 case NumberFormat::DATE
:
559 nDataType
= DataType::DATE
;
561 case NumberFormat::TIME
:
562 nDataType
= DataType::TIME
;
564 case NumberFormat::DATETIME
:
565 nDataType
= DataType::TIMESTAMP
;
567 case NumberFormat::CURRENCY
:
568 nDataType
= DataType::NUMERIC
;
572 case NumberFormat::NUMBER
:
573 case NumberFormat::SCIENTIFIC
:
574 case NumberFormat::FRACTION
:
575 case NumberFormat::PERCENT
:
576 nDataType
= DataType::DOUBLE
;
578 case NumberFormat::TEXT
:
579 case NumberFormat::UNDEFINED
:
580 case NumberFormat::LOGICAL
:
582 nDataType
= DataType::VARCHAR
;
583 nLength
= ((m_vColumnSize
[i
] % 10 ) ? m_vColumnSize
[i
]/ 10 + 1: m_vColumnSize
[i
]/ 10) * 10;
586 OTypeInfoMap::const_iterator aFind
= _pInfoMap
->find(nDataType
);
587 if(aFind
!= _pInfoMap
->end())
589 elem
->second
->SetType(aFind
->second
);
590 elem
->second
->SetPrecision(std::min
<sal_Int32
>(aFind
->second
->nPrecision
,nLength
));
591 elem
->second
->SetScale(std::min
<sal_Int32
>(aFind
->second
->nMaximumScale
,nScale
));
593 sal_Int32 nFormatKey
= ::dbtools::getDefaultNumberFormat( nDataType
,
594 elem
->second
->GetScale(),
595 elem
->second
->IsCurrency(),
596 Reference
< XNumberFormatTypes
>(xFormats
,UNO_QUERY
),
599 elem
->second
->SetFormatKey(nFormatKey
);
605 void ODatabaseExport::CreateDefaultColumn(const OUString
& _rColumnName
)
607 Reference
< XDatabaseMetaData
> xDestMetaData(m_xConnection
->getMetaData());
608 sal_Int32
nMaxNameLen(xDestMetaData
->getMaxColumnNameLength());
609 OUString aAlias
= _rColumnName
;
610 if ( isSQL92CheckEnabled(m_xConnection
) )
611 aAlias
= ::dbtools::convertName2SQLName(_rColumnName
,xDestMetaData
->getExtraNameCharacters());
613 if(nMaxNameLen
&& aAlias
.getLength() > nMaxNameLen
)
614 aAlias
= aAlias
.copy(0, std::min
<sal_Int32
>( nMaxNameLen
-1, aAlias
.getLength() ) );
616 OUString
sName(aAlias
);
617 if(m_aDestColumns
.find(sName
) != m_aDestColumns
.end())
620 sal_Int32 nCount
= 2;
621 while(m_aDestColumns
.find(sName
) != m_aDestColumns
.end())
624 + OUString::number(++nPos
);
625 if(nMaxNameLen
&& sName
.getLength() > nMaxNameLen
)
627 aAlias
= aAlias
.copy(0,std::min
<sal_Int32
>( nMaxNameLen
-nCount
, aAlias
.getLength() ));
629 + OUString::number(nPos
);
635 // now create a column
636 OFieldDescription
* pField
= new OFieldDescription();
637 pField
->SetType(m_pTypeInfo
);
638 pField
->SetName(aAlias
);
639 pField
->SetPrecision(std::min
<sal_Int32
>(sal_Int32(255),m_pTypeInfo
->nPrecision
));
641 pField
->SetIsNullable(ColumnValue::NULLABLE
);
642 pField
->SetAutoIncrement(false);
643 pField
->SetPrimaryKey(false);
644 pField
->SetCurrency(false);
646 TColumns::const_iterator aFind
= m_aDestColumns
.find( aAlias
);
647 if ( aFind
!= m_aDestColumns
.end() )
649 delete aFind
->second
;
650 m_aDestColumns
.erase(aFind
);
653 m_vDestVector
.emplace_back(m_aDestColumns
.emplace(aAlias
,pField
).first
);
656 void ODatabaseExport::createRowSet()
658 m_pUpdateHelper
= std::make_shared
<OParameterUpdateHelper
>(createPreparedStatement(m_xConnection
->getMetaData(),m_xTable
,m_vColumnPositions
));
661 bool ODatabaseExport::executeWizard(const OUString
& _rTableName
, const Any
& _aTextColor
, const FontDescriptor
& _rFont
)
663 bool bHaveDefaultTable
= !m_sDefaultTableName
.isEmpty();
664 OUString
sTableName( bHaveDefaultTable
? m_sDefaultTableName
: _rTableName
);
665 OCopyTableWizard
aWizard(
668 bHaveDefaultTable
? CopyTableOperation::AppendData
: CopyTableOperation::CopyDefinitionAndData
,
669 ODatabaseExport::TColumns(m_aDestColumns
),
673 getTypeSelectionPageFactory(),
683 switch(aWizard
.getOperation())
685 case CopyTableOperation::CopyDefinitionAndData
:
686 case CopyTableOperation::AppendData
:
688 m_xTable
= aWizard
.returnTable();
689 bError
= !m_xTable
.is();
692 m_xTable
->setPropertyValue(PROPERTY_FONT
,Any(_rFont
));
693 if(_aTextColor
.hasValue())
694 m_xTable
->setPropertyValue(PROPERTY_TEXTCOLOR
,_aTextColor
);
696 m_bIsAutoIncrement
= aWizard
.shouldCreatePrimaryKey();
697 m_vColumnPositions
= aWizard
.GetColumnPositions();
698 m_vColumnTypes
= aWizard
.GetColumnTypes();
699 m_bAppendFirstLine
= !aWizard
.UseHeaderLine();
703 bError
= true; // there is no error but I have nothing more to do
712 catch( const SQLException
&)
714 ::dbtools::showError( ::dbtools::SQLExceptionInfo( ::cppu::getCaughtException() ), aWizard
.getDialog()->GetXWindow(), m_xContext
);
717 catch( const Exception
& )
719 DBG_UNHANDLED_EXCEPTION("dbaccess");
725 void ODatabaseExport::showErrorDialog(const css::sdbc::SQLException
& e
)
729 OUString aMsg
= e
.Message
731 + DBA_RES( STR_QRY_CONTINUE
);
732 OSQLWarningBox
aBox(nullptr, aMsg
, MessBoxStyle::YesNo
| MessBoxStyle::DefaultNo
);
734 if (aBox
.run() == RET_YES
)
735 m_bDontAskAgain
= true;
741 void ODatabaseExport::adjustFormat()
743 if ( m_sTextToken
.isEmpty() )
746 sal_Int32 nNewPos
= m_bIsAutoIncrement
? m_nColumnPos
+1 : m_nColumnPos
;
747 OSL_ENSURE(nNewPos
< static_cast<sal_Int32
>(m_vColumnPositions
.size()),"Illegal index for vector");
748 if ( nNewPos
< static_cast<sal_Int32
>(m_vColumnPositions
.size()) )
750 sal_Int32 nColPos
= m_vColumnPositions
[nNewPos
].first
;
751 if( nColPos
!= COLUMN_POSITION_NOT_FOUND
)
754 OSL_ENSURE((nColPos
) < static_cast<sal_Int32
>(m_vNumberFormat
.size()),"m_vFormatKey: Illegal index for vector");
755 OSL_ENSURE((nColPos
) < static_cast<sal_Int32
>(m_vColumnSize
.size()),"m_vColumnSize: Illegal index for vector");
756 m_vNumberFormat
[nColPos
] = CheckString(m_sTextToken
,m_vNumberFormat
[nColPos
]);
757 m_vColumnSize
[nColPos
] = std::max
<sal_Int32
>(static_cast<sal_Int32
>(m_vColumnSize
[nColPos
]), m_sTextToken
.getLength());
763 void ODatabaseExport::eraseTokens()
765 m_sTextToken
.clear();
769 void ODatabaseExport::ensureFormatter()
773 Reference
< XNumberFormatsSupplier
> xSupplier
= m_xFormatter
->getNumberFormatsSupplier();
774 auto pSupplierImpl
= comphelper::getFromUnoTunnel
<SvNumberFormatsSupplierObj
>(xSupplier
);
775 m_pFormatter
= pSupplierImpl
? pSupplierImpl
->GetNumberFormatter() : nullptr;
776 Reference
<XPropertySet
> xNumberFormatSettings
= xSupplier
->getNumberFormatSettings();
777 xNumberFormatSettings
->getPropertyValue("NullDate") >>= m_aNullDate
;
781 Reference
< XPreparedStatement
> ODatabaseExport::createPreparedStatement( const Reference
<XDatabaseMetaData
>& _xMetaData
782 ,const Reference
<XPropertySet
>& _xDestTable
783 ,const TPositions
& _rvColumns
)
785 OUString sComposedTableName
= ::dbtools::composeTableName( _xMetaData
, _xDestTable
, ::dbtools::EComposeRule::InDataManipulation
, true );
787 OUStringBuffer aSql
= "INSERT INTO "
791 // set values and column names
792 OUStringBuffer
aValues(" VALUES ( ");
795 if ( _xMetaData
.is() )
796 aQuote
= _xMetaData
->getIdentifierQuoteString();
798 Reference
<XColumnsSupplier
> xDestColsSup(_xDestTable
,UNO_QUERY_THROW
);
800 // create sql string and set column types
801 Sequence
< OUString
> aDestColumnNames
= xDestColsSup
->getColumns()->getElementNames();
802 if ( !aDestColumnNames
.hasElements() )
804 return Reference
< XPreparedStatement
> ();
806 const OUString
* pIter
= aDestColumnNames
.getConstArray();
807 std::vector
< OUString
> aInsertList
;
808 aInsertList
.resize(aDestColumnNames
.getLength()+1);
809 for(size_t j
=0; j
< aInsertList
.size(); ++j
)
811 ODatabaseExport::TPositions::const_iterator aFind
= std::find_if(_rvColumns
.begin(),_rvColumns
.end(),
812 [j
] (const ODatabaseExport::TPositions::value_type
& tPos
)
813 { return tPos
.second
== static_cast<sal_Int32
>(j
+1); });
814 if ( _rvColumns
.end() != aFind
&& aFind
->second
!= COLUMN_POSITION_NOT_FOUND
&& aFind
->first
!= COLUMN_POSITION_NOT_FOUND
)
816 OSL_ENSURE((aFind
->first
) < static_cast<sal_Int32
>(aInsertList
.size()),"aInsertList: Illegal index for vector");
817 aInsertList
[aFind
->first
] = ::dbtools::quoteName( aQuote
,*(pIter
+j
));
821 // create the sql string
822 for (auto const& elem
: aInsertList
)
824 if ( !elem
.isEmpty() )
828 aValues
.append("?,");
832 aSql
[aSql
.getLength()-1] = ')';
833 aValues
[aValues
.getLength()-1] = ')';
835 aSql
.append(aValues
);
836 // now create,fill and execute the prepared statement
837 return _xMetaData
->getConnection()->prepareStatement(aSql
.makeStringAndClear());
840 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */