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 "moduledbu.hxx"
23 #include <com/sun/star/sdbcx/XTablesSupplier.hpp>
24 #include <com/sun/star/sdbcx/XDataDescriptorFactory.hpp>
25 #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
26 #include <com/sun/star/sdbcx/XAppend.hpp>
27 #include <com/sun/star/sdbcx/KeyType.hpp>
28 #include <com/sun/star/sdbc/DataType.hpp>
29 #include <com/sun/star/sdbc/ColumnValue.hpp>
30 #include <com/sun/star/sdb/CommandType.hpp>
31 #include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp>
32 #include <com/sun/star/sdbc/XRow.hpp>
33 #include <com/sun/star/uno/XComponentContext.hpp>
34 #include <com/sun/star/util/NumberFormat.hpp>
35 #include <com/sun/star/util/XNumberFormatTypes.hpp>
36 #include "dbustrings.hrc"
37 #include "dbu_misc.hrc"
38 #include <connectivity/dbconversion.hxx>
39 #include <osl/thread.h>
40 #include <sfx2/sfxhtml.hxx>
41 #include <svl/numuno.hxx>
42 #include <connectivity/dbtools.hxx>
43 #include <comphelper/extract.hxx>
44 #include "TypeInfo.hxx"
45 #include "FieldDescriptions.hxx"
46 #include "UITools.hxx"
47 #include <unotools/configmgr.hxx>
48 #include <o3tl/compat_functional.hxx>
49 #include <tools/debug.hxx>
50 #include <tools/diagnose_ex.h>
51 #include <tools/contnr.hxx>
52 #include <i18nlangtag/mslangid.hxx>
53 #include <com/sun/star/awt/FontDescriptor.hpp>
54 #include "WCopyTable.hxx"
55 #include "WExtendPages.hxx"
57 #include <unotools/syslocale.hxx>
58 #include <svl/zforlist.hxx>
59 #include <connectivity/dbexception.hxx>
60 #include <connectivity/FValue.hxx>
61 #include <com/sun/star/sdbc/SQLWarning.hpp>
62 #include <com/sun/star/sdb/SQLContext.hpp>
63 #include <com/sun/star/sdb/application/CopyTableOperation.hpp>
64 #include "sqlmessage.hxx"
65 #include "UpdateHelperImpl.hxx"
66 #include <vcl/msgbox.hxx>
67 #include <cppuhelper/exc_hlp.hxx>
69 using namespace dbaui
;
71 using namespace ::com::sun::star::uno
;
72 using namespace ::com::sun::star::beans
;
73 using namespace ::com::sun::star::container
;
74 using namespace ::com::sun::star::util
;
75 using namespace ::com::sun::star::sdbc
;
76 using namespace ::com::sun::star::sdbcx
;
77 using namespace ::com::sun::star::sdb
;
78 using namespace ::com::sun::star::lang
;
79 using namespace ::com::sun::star::awt
;
81 namespace CopyTableOperation
= ::com::sun::star::sdb::application::CopyTableOperation
;
84 ODatabaseExport::ODatabaseExport(sal_Int32 nRows
,
85 const TPositions
&_rColumnPositions
,
86 const Reference
< XNumberFormatter
>& _rxNumberF
,
87 const Reference
< ::com::sun::star::uno::XComponentContext
>& _rxContext
,
88 const TColumnVector
* pList
,
89 const OTypeInfoMap
* _pInfoMap
,
90 bool _bAutoIncrementEnabled
,
91 SvStream
& _rInputStream
)
92 :m_vColumns(_rColumnPositions
)
94 ,m_xFormatter(_rxNumberF
)
95 ,m_xContext(_rxContext
)
97 ,m_rInputStream( _rInputStream
)
100 ,m_pInfoMap(_pInfoMap
)
104 ,m_nDefToken( osl_getThreadTextEncoding() )
108 ,m_bDontAskAgain(false)
109 ,m_bIsAutoIncrement(_bAutoIncrementEnabled
)
110 ,m_bFoundTable(false)
112 ,m_bAppendFirstLine(false)
115 sal_Int32 nCount
= 0;
116 for(sal_Int32 j
=0;j
< (sal_Int32
)m_vColumns
.size();++j
)
117 if ( m_vColumns
[j
].first
!= COLUMN_POSITION_NOT_FOUND
)
120 m_vColumnSize
.resize(nCount
);
121 m_vNumberFormat
.resize(nCount
);
122 for(sal_Int32 i
=0;i
<nCount
;++i
)
124 m_vColumnSize
[i
] = 0;
125 m_vNumberFormat
[i
] = 0;
130 SvtSysLocale aSysLocale
;
131 m_aLocale
= aSysLocale
.GetLanguageTag().getLocale();
137 SetColumnTypes(pList
,_pInfoMap
);
140 ODatabaseExport::ODatabaseExport(const SharedConnection
& _rxConnection
,
141 const Reference
< XNumberFormatter
>& _rxNumberF
,
142 const Reference
< ::com::sun::star::uno::XComponentContext
>& _rxContext
,
143 const TColumnVector
* pList
,
144 const OTypeInfoMap
* _pInfoMap
,
145 SvStream
& _rInputStream
)
146 :m_aDestColumns(_rxConnection
->getMetaData().is() && _rxConnection
->getMetaData()->supportsMixedCaseQuotedIdentifiers() == sal_True
)
147 ,m_xConnection(_rxConnection
)
148 ,m_xFormatter(_rxNumberF
)
149 ,m_xContext(_rxContext
)
151 ,m_rInputStream( _rInputStream
)
158 ,m_nDefToken( osl_getThreadTextEncoding() )
162 ,m_bDontAskAgain(false)
163 ,m_bIsAutoIncrement(false)
164 ,m_bFoundTable(false)
166 ,m_bAppendFirstLine(false)
170 SvtSysLocale aSysLocale
;
171 m_aLocale
= aSysLocale
.GetLanguageTag().getLocale();
177 Reference
<XTablesSupplier
> xTablesSup(m_xConnection
,UNO_QUERY
);
179 m_xTables
= xTablesSup
->getTables();
181 Reference
<XDatabaseMetaData
> xMeta
= m_xConnection
->getMetaData();
182 Reference
<XResultSet
> xSet
= xMeta
.is() ? xMeta
->getTypeInfo() : Reference
<XResultSet
>();
185 ::connectivity::ORowSetValue aValue
;
186 ::std::vector
<sal_Int32
> aTypes
;
187 ::std::vector
<sal_Bool
> aNullable
;
188 Reference
<XResultSetMetaData
> xResultSetMetaData
= Reference
<XResultSetMetaDataSupplier
>(xSet
,UNO_QUERY_THROW
)->getMetaData();
189 Reference
<XRow
> xRow(xSet
,UNO_QUERY_THROW
);
192 if ( aTypes
.empty() )
194 sal_Int32 nCount
= xResultSetMetaData
->getColumnCount();
197 aTypes
.reserve(nCount
+1);
198 aNullable
.reserve(nCount
+1);
199 aTypes
.push_back(-1);
200 aNullable
.push_back(sal_False
);
201 for (sal_Int32 j
= 1; j
<= nCount
; ++j
)
203 aNullable
.push_back(xResultSetMetaData
->isNullable(j
) != ColumnValue::NO_NULLS
);
204 aTypes
.push_back(xResultSetMetaData
->getColumnType(j
));
209 OSL_ENSURE((nPos
) < static_cast<sal_Int32
>(aTypes
.size()),"aTypes: Illegal index for vector");
210 aValue
.fill(nPos
,aTypes
[nPos
],aNullable
[nPos
],xRow
);
211 OUString sTypeName
= aValue
;
213 OSL_ENSURE((nPos
) < static_cast<sal_Int32
>(aTypes
.size()),"aTypes: Illegal index for vector");
214 aValue
.fill(nPos
,aTypes
[nPos
],aNullable
[nPos
],xRow
);
215 sal_Int32 nType
= aValue
;
218 if( nType
== DataType::VARCHAR
)
220 m_pTypeInfo
= TOTypeInfoSP(new OTypeInfo());
222 m_pTypeInfo
->aTypeName
= sTypeName
;
223 m_pTypeInfo
->nType
= nType
;
225 OSL_ENSURE((nPos
) < static_cast<sal_Int32
>(aTypes
.size()),"aTypes: Illegal index for vector");
226 aValue
.fill(nPos
,aTypes
[nPos
],aNullable
[nPos
],xRow
);
227 m_pTypeInfo
->nPrecision
= aValue
;
229 aValue
.fill(nPos
,aTypes
[nPos
],aNullable
[nPos
],xRow
);
230 m_pTypeInfo
->aLiteralPrefix
= aValue
;
232 aValue
.fill(nPos
,aTypes
[nPos
],aNullable
[nPos
],xRow
);
233 m_pTypeInfo
->aLiteralSuffix
= aValue
;
235 aValue
.fill(nPos
,aTypes
[nPos
],aNullable
[nPos
],xRow
);
236 m_pTypeInfo
->aCreateParams
= aValue
;
238 aValue
.fill(nPos
,aTypes
[nPos
],aNullable
[nPos
],xRow
);
239 m_pTypeInfo
->bNullable
= (sal_Int32
)aValue
== ColumnValue::NULLABLE
;
241 aValue
.fill(nPos
,aTypes
[nPos
],aNullable
[nPos
],xRow
);
242 m_pTypeInfo
->bCaseSensitive
= aValue
;
244 aValue
.fill(nPos
,aTypes
[nPos
],aNullable
[nPos
],xRow
);
245 m_pTypeInfo
->nSearchType
= aValue
;
247 aValue
.fill(nPos
,aTypes
[nPos
],aNullable
[nPos
],xRow
);
248 m_pTypeInfo
->bUnsigned
= aValue
;
250 aValue
.fill(nPos
,aTypes
[nPos
],aNullable
[nPos
],xRow
);
251 m_pTypeInfo
->bCurrency
= aValue
;
253 aValue
.fill(nPos
,aTypes
[nPos
],aNullable
[nPos
],xRow
);
254 m_pTypeInfo
->bAutoIncrement
= aValue
;
256 aValue
.fill(nPos
,aTypes
[nPos
],aNullable
[nPos
],xRow
);
257 m_pTypeInfo
->aLocalTypeName
= aValue
;
259 aValue
.fill(nPos
,aTypes
[nPos
],aNullable
[nPos
],xRow
);
260 m_pTypeInfo
->nMinimumScale
= aValue
;
262 aValue
.fill(nPos
,aTypes
[nPos
],aNullable
[nPos
],xRow
);
263 m_pTypeInfo
->nMaximumScale
= aValue
;
265 aValue
.fill(nPos
,aTypes
[nPos
],xRow
);
266 m_pTypeInfo
->nNumPrecRadix
= aValue
;
268 // check if values are less than zero like it happens in a oracle jdbc driver
269 if( m_pTypeInfo
->nPrecision
< 0)
270 m_pTypeInfo
->nPrecision
= 0;
271 if( m_pTypeInfo
->nMinimumScale
< 0)
272 m_pTypeInfo
->nMinimumScale
= 0;
273 if( m_pTypeInfo
->nMaximumScale
< 0)
274 m_pTypeInfo
->nMaximumScale
= 0;
275 if( m_pTypeInfo
->nNumPrecRadix
<= 1)
276 m_pTypeInfo
->nNumPrecRadix
= 10;
282 m_pTypeInfo
= TOTypeInfoSP(new OTypeInfo());
283 SetColumnTypes(pList
,_pInfoMap
);
286 ODatabaseExport::~ODatabaseExport()
289 ODatabaseExport::TColumns::iterator aIter
= m_aDestColumns
.begin();
290 ODatabaseExport::TColumns::iterator aEnd
= m_aDestColumns
.end();
292 for(;aIter
!= aEnd
;++aIter
)
293 delete aIter
->second
;
294 m_vDestVector
.clear();
295 m_aDestColumns
.clear();
298 void ODatabaseExport::insertValueIntoColumn()
300 if(m_nColumnPos
< sal_Int32(m_vDestVector
.size()))
302 OFieldDescription
* pField
= m_vDestVector
[m_nColumnPos
]->second
;
305 sal_Int32 nNewPos
= m_bIsAutoIncrement
? m_nColumnPos
+1 : m_nColumnPos
;
306 OSL_ENSURE((nNewPos
) < static_cast<sal_Int32
>(m_vColumns
.size()),"m_vColumns: Illegal index for vector");
308 if ( (nNewPos
) < static_cast<sal_Int32
>(m_vColumns
.size() ) )
310 sal_Int32 nPos
= m_vColumns
[nNewPos
].first
;
311 if ( nPos
!= COLUMN_POSITION_NOT_FOUND
)
313 if ( m_sTextToken
.isEmpty() && pField
->IsNullable() )
314 m_pUpdateHelper
->updateNull(nPos
,pField
->GetType());
317 OSL_ENSURE((nNewPos
) < static_cast<sal_Int32
>(m_vColumnTypes
.size()),"Illegal index for vector");
318 if (m_vColumnTypes
[nNewPos
] != DataType::VARCHAR
&& m_vColumnTypes
[nNewPos
] != DataType::CHAR
&& m_vColumnTypes
[nNewPos
] != DataType::LONGVARCHAR
)
320 SAL_INFO("dbaccess", "ODatabaseExport::insertValueIntoColumn != DataType::VARCHAR" );
322 sal_Int32 nNumberFormat
= 0;
323 double fOutNumber
= 0.0;
324 bool bNumberFormatError
= false;
325 if ( m_pFormatter
&& !m_sNumToken
.isEmpty() )
327 LanguageType eNumLang
= LANGUAGE_NONE
;
328 sal_uInt32
nNumberFormat2( nNumberFormat
);
329 fOutNumber
= SfxHTMLParser::GetTableDataOptionsValNum(nNumberFormat2
,eNumLang
,m_sTextToken
,m_sNumToken
,*m_pFormatter
);
330 if ( eNumLang
!= LANGUAGE_NONE
)
332 nNumberFormat2
= m_pFormatter
->GetFormatForLanguageIfBuiltIn( nNumberFormat2
, eNumLang
);
333 m_pFormatter
->IsNumberFormat( m_sTextToken
, nNumberFormat2
, fOutNumber
);
335 nNumberFormat
= static_cast<sal_Int32
>(nNumberFormat2
);
339 Reference
< XNumberFormatsSupplier
> xSupplier
= m_xFormatter
->getNumberFormatsSupplier();
340 Reference
<XNumberFormatTypes
> xNumType(xSupplier
->getNumberFormats(),UNO_QUERY
);
341 sal_Int16 nFormats
[] = {
342 NumberFormat::DATETIME
345 ,NumberFormat::CURRENCY
346 ,NumberFormat::NUMBER
347 ,NumberFormat::LOGICAL
349 for (size_t i
= 0; i
< sizeof(nFormats
)/sizeof(nFormats
[0]); ++i
)
353 nNumberFormat
= m_xFormatter
->detectNumberFormat(xNumType
->getStandardFormat(nFormats
[i
],m_aLocale
),m_sTextToken
);
362 fOutNumber
= m_xFormatter
->convertStringToNumber(nNumberFormat
,m_sTextToken
);
366 bNumberFormatError
= true;
367 m_pUpdateHelper
->updateString(nPos
,m_sTextToken
);
370 if ( !bNumberFormatError
)
374 Reference
< XNumberFormatsSupplier
> xSupplier
= m_xFormatter
->getNumberFormatsSupplier();
375 Reference
< XNumberFormats
> xFormats
= xSupplier
->getNumberFormats();
376 Reference
<XPropertySet
> xProp
= xFormats
->getByKey(nNumberFormat
);
378 xProp
->getPropertyValue(PROPERTY_TYPE
) >>= nType
;
381 case NumberFormat::DATE
:
382 m_pUpdateHelper
->updateDate(nPos
,::dbtools::DBTypeConversion::toDate(fOutNumber
,m_aNullDate
));
384 case NumberFormat::DATETIME
:
385 m_pUpdateHelper
->updateTimestamp(nPos
,::dbtools::DBTypeConversion::toDateTime(fOutNumber
,m_aNullDate
));
387 case NumberFormat::TIME
:
388 m_pUpdateHelper
->updateTime(nPos
,::dbtools::DBTypeConversion::toTime(fOutNumber
));
391 m_pUpdateHelper
->updateDouble(nPos
,fOutNumber
);
396 m_pUpdateHelper
->updateString(nPos
,m_sTextToken
);
402 m_pUpdateHelper
->updateString(nPos
,m_sTextToken
);
411 sal_Int16
ODatabaseExport::CheckString(const OUString
& aCheckToken
, sal_Int16 _nOldNumberFormat
)
413 sal_Int16 nNumberFormat
= 0;
417 Reference
< XNumberFormatsSupplier
> xSupplier
= m_xFormatter
->getNumberFormatsSupplier();
418 Reference
< XNumberFormats
> xFormats
= xSupplier
->getNumberFormats();
421 if ( m_pFormatter
&& !m_sNumToken
.isEmpty() )
423 double fOutNumber
= 0.0;
424 LanguageType eNumLang
;
425 sal_uInt32
nFormatKey(0);
426 fOutNumber
= SfxHTMLParser::GetTableDataOptionsValNum(nFormatKey
,eNumLang
,m_sTextToken
,m_sNumToken
,*m_pFormatter
);
427 if ( eNumLang
!= LANGUAGE_NONE
)
429 nFormatKey
= m_pFormatter
->GetFormatForLanguageIfBuiltIn( nFormatKey
, eNumLang
);
430 if ( !m_pFormatter
->IsNumberFormat( m_sTextToken
, nFormatKey
, fOutNumber
) )
431 return NumberFormat::TEXT
;
433 Reference
<XPropertySet
> xProp
= xFormats
->getByKey(nFormatKey
);
434 xProp
->getPropertyValue(PROPERTY_TYPE
) >>= nNumberFormat
;
438 Reference
<XNumberFormatTypes
> xNumType(xFormats
,UNO_QUERY
);
439 sal_Int32 nFormatKey
= m_xFormatter
->detectNumberFormat(xNumType
->getStandardFormat(NumberFormat::ALL
,m_aLocale
),aCheckToken
);
440 m_xFormatter
->convertStringToNumber(nFormatKey
,aCheckToken
);
442 Reference
<XPropertySet
> xProp
= xFormats
->getByKey(nFormatKey
);
444 xProp
->getPropertyValue(PROPERTY_TYPE
) >>= nType
;
448 case NumberFormat::ALL
:
449 nNumberFormat
= NumberFormat::ALL
;
451 case NumberFormat::DEFINED
:
452 nNumberFormat
= NumberFormat::TEXT
;
454 case NumberFormat::DATE
:
455 switch(_nOldNumberFormat
)
457 case NumberFormat::DATETIME
:
458 case NumberFormat::TEXT
:
459 case NumberFormat::DATE
:
460 nNumberFormat
= _nOldNumberFormat
;
462 case NumberFormat::ALL
:
463 nNumberFormat
= NumberFormat::DATE
;
466 nNumberFormat
= NumberFormat::TEXT
;
470 case NumberFormat::TIME
:
471 switch(_nOldNumberFormat
)
473 case NumberFormat::DATETIME
:
474 case NumberFormat::TEXT
:
475 case NumberFormat::TIME
:
476 nNumberFormat
= _nOldNumberFormat
;
478 case NumberFormat::ALL
:
479 nNumberFormat
= NumberFormat::TIME
;
482 nNumberFormat
= NumberFormat::TEXT
;
486 case NumberFormat::CURRENCY
:
487 switch(_nOldNumberFormat
)
489 case NumberFormat::NUMBER
:
490 nNumberFormat
= NumberFormat::CURRENCY
;
492 case NumberFormat::CURRENCY
:
493 nNumberFormat
= _nOldNumberFormat
;
495 case NumberFormat::ALL
:
496 nNumberFormat
= NumberFormat::CURRENCY
;
499 nNumberFormat
= NumberFormat::TEXT
;
503 case NumberFormat::NUMBER
:
504 case NumberFormat::SCIENTIFIC
:
505 case NumberFormat::FRACTION
:
506 case NumberFormat::PERCENT
:
507 switch(_nOldNumberFormat
)
509 case NumberFormat::NUMBER
:
510 nNumberFormat
= _nOldNumberFormat
;
512 case NumberFormat::CURRENCY
:
513 nNumberFormat
= NumberFormat::CURRENCY
;
515 case NumberFormat::ALL
:
516 nNumberFormat
= nType
;
519 nNumberFormat
= NumberFormat::TEXT
;
523 case NumberFormat::TEXT
:
524 case NumberFormat::UNDEFINED
:
525 case NumberFormat::LOGICAL
:
526 nNumberFormat
= NumberFormat::TEXT
; // Text "uberschreibt alles
528 case NumberFormat::DATETIME
:
529 switch(_nOldNumberFormat
)
531 case NumberFormat::DATETIME
:
532 case NumberFormat::TEXT
:
533 case NumberFormat::TIME
:
534 nNumberFormat
= _nOldNumberFormat
;
536 case NumberFormat::ALL
:
537 nNumberFormat
= NumberFormat::DATETIME
;
540 nNumberFormat
= NumberFormat::TEXT
;
545 SAL_WARN("dbaccess.ui", "ODatabaseExport: Unbekanntes Format");
551 nNumberFormat
= NumberFormat::TEXT
; // Text "uberschreibt alles
554 return nNumberFormat
;
557 void ODatabaseExport::SetColumnTypes(const TColumnVector
* _pList
,const OTypeInfoMap
* _pInfoMap
)
559 if(_pList
&& _pInfoMap
)
561 OSL_ENSURE(m_vNumberFormat
.size() == m_vColumnSize
.size() && m_vColumnSize
.size() == _pList
->size(),"Illegal columns in list");
562 Reference
< XNumberFormatsSupplier
> xSupplier
= m_xFormatter
->getNumberFormatsSupplier();
563 Reference
< XNumberFormats
> xFormats
= xSupplier
->getNumberFormats();
564 TColumnVector::const_iterator aIter
= _pList
->begin();
565 TColumnVector::const_iterator aEnd
= _pList
->end();
566 for(sal_Int32 i
= 0;aIter
!= aEnd
&& (i
) < static_cast<sal_Int32
>(m_vNumberFormat
.size()) && (i
) < static_cast<sal_Int32
>(m_vColumnSize
.size()) ;++aIter
,++i
)
569 sal_Int32
nLength(0),nScale(0);
570 sal_Int16 nType
= m_vNumberFormat
[i
] & ~NumberFormat::DEFINED
;
574 case NumberFormat::ALL
:
575 nDataType
= DataType::DOUBLE
;
577 case NumberFormat::DEFINED
:
578 nDataType
= DataType::VARCHAR
;
579 nLength
= ((m_vColumnSize
[i
] % 10 ) ? m_vColumnSize
[i
]/ 10 + 1: m_vColumnSize
[i
]/ 10) * 10;
581 case NumberFormat::DATE
:
582 nDataType
= DataType::DATE
;
584 case NumberFormat::TIME
:
585 nDataType
= DataType::TIME
;
587 case NumberFormat::DATETIME
:
588 nDataType
= DataType::TIMESTAMP
;
590 case NumberFormat::CURRENCY
:
591 nDataType
= DataType::NUMERIC
;
595 case NumberFormat::NUMBER
:
596 case NumberFormat::SCIENTIFIC
:
597 case NumberFormat::FRACTION
:
598 case NumberFormat::PERCENT
:
599 nDataType
= DataType::DOUBLE
;
601 case NumberFormat::TEXT
:
602 case NumberFormat::UNDEFINED
:
603 case NumberFormat::LOGICAL
:
605 nDataType
= DataType::VARCHAR
;
606 nLength
= ((m_vColumnSize
[i
] % 10 ) ? m_vColumnSize
[i
]/ 10 + 1: m_vColumnSize
[i
]/ 10) * 10;
609 OTypeInfoMap::const_iterator aFind
= _pInfoMap
->find(nDataType
);
610 if(aFind
!= _pInfoMap
->end())
612 (*aIter
)->second
->SetType(aFind
->second
);
613 (*aIter
)->second
->SetPrecision(::std::min
<sal_Int32
>(aFind
->second
->nPrecision
,nLength
));
614 (*aIter
)->second
->SetScale(::std::min
<sal_Int32
>(aFind
->second
->nMaximumScale
,nScale
));
616 sal_Int32 nFormatKey
= ::dbtools::getDefaultNumberFormat( nDataType
,
617 (*aIter
)->second
->GetScale(),
618 (*aIter
)->second
->IsCurrency(),
619 Reference
< XNumberFormatTypes
>(xFormats
,UNO_QUERY
),
622 (*aIter
)->second
->SetFormatKey(nFormatKey
);
628 void ODatabaseExport::CreateDefaultColumn(const OUString
& _rColumnName
)
630 Reference
< XDatabaseMetaData
> xDestMetaData(m_xConnection
->getMetaData());
631 sal_Int32
nMaxNameLen(xDestMetaData
->getMaxColumnNameLength());
632 OUString aAlias
= _rColumnName
;
633 if ( isSQL92CheckEnabled(m_xConnection
) )
634 aAlias
= ::dbtools::convertName2SQLName(_rColumnName
,xDestMetaData
->getExtraNameCharacters());
636 if(nMaxNameLen
&& aAlias
.getLength() > nMaxNameLen
)
637 aAlias
= aAlias
.copy(0, ::std::min
<sal_Int32
>( nMaxNameLen
-1, aAlias
.getLength() ) );
639 OUString
sName(aAlias
);
640 if(m_aDestColumns
.find(sName
) != m_aDestColumns
.end())
643 sal_Int32 nCount
= 2;
644 while(m_aDestColumns
.find(sName
) != m_aDestColumns
.end())
647 sName
+= OUString::number(++nPos
);
648 if(nMaxNameLen
&& sName
.getLength() > nMaxNameLen
)
650 aAlias
= aAlias
.copy(0,::std::min
<sal_Int32
>( nMaxNameLen
-nCount
, aAlias
.getLength() ));
652 sName
+= OUString::number(nPos
);
658 // now create a column
659 OFieldDescription
* pField
= new OFieldDescription();
660 pField
->SetType(m_pTypeInfo
);
661 pField
->SetName(aAlias
);
662 pField
->SetPrecision(::std::min
<sal_Int32
>((sal_Int32
)255,m_pTypeInfo
->nPrecision
));
664 pField
->SetIsNullable(ColumnValue::NULLABLE
);
665 pField
->SetAutoIncrement(false);
666 pField
->SetPrimaryKey(false);
667 pField
->SetCurrency(false);
669 TColumns::iterator aFind
= m_aDestColumns
.find( aAlias
);
670 if ( aFind
!= m_aDestColumns
.end() )
672 delete aFind
->second
;
673 m_aDestColumns
.erase(aFind
);
676 m_vDestVector
.push_back(m_aDestColumns
.insert(TColumns::value_type(aAlias
,pField
)).first
);
679 bool ODatabaseExport::createRowSet()
681 m_pUpdateHelper
.reset(new OParameterUpdateHelper(createPreparedStatment(m_xConnection
->getMetaData(),m_xTable
,m_vColumns
)));
683 return m_pUpdateHelper
.get() != NULL
;
686 bool ODatabaseExport::executeWizard(const OUString
& _rTableName
, const Any
& _aTextColor
, const FontDescriptor
& _rFont
)
688 bool bHaveDefaultTable
= !m_sDefaultTableName
.isEmpty();
689 OUString
sTableName( bHaveDefaultTable
? m_sDefaultTableName
: _rTableName
);
690 ScopedVclPtrInstance
<OCopyTableWizard
> aWizard(
693 bHaveDefaultTable
? CopyTableOperation::AppendData
: CopyTableOperation::CopyDefinitionAndData
,
698 getTypeSelectionPageFactory(),
706 if (aWizard
->Execute())
708 switch(aWizard
->getOperation())
710 case CopyTableOperation::CopyDefinitionAndData
:
711 case CopyTableOperation::AppendData
:
713 m_xTable
= aWizard
->createTable();
714 bError
= !m_xTable
.is();
717 m_xTable
->setPropertyValue(PROPERTY_FONT
,makeAny(_rFont
));
718 if(_aTextColor
.hasValue())
719 m_xTable
->setPropertyValue(PROPERTY_TEXTCOLOR
,_aTextColor
);
721 m_bIsAutoIncrement
= aWizard
->shouldCreatePrimaryKey();
722 m_vColumns
= aWizard
->GetColumnPositions();
723 m_vColumnTypes
= aWizard
->GetColumnTypes();
724 m_bAppendFirstLine
= !aWizard
->UseHeaderLine();
728 bError
= true; // there is no error but I have nothing more to do
735 bError
= !createRowSet();
737 catch( const SQLException
&)
739 ::dbaui::showError( ::dbtools::SQLExceptionInfo( ::cppu::getCaughtException() ), aWizard
.get(), m_xContext
);
742 catch( const Exception
& )
744 DBG_UNHANDLED_EXCEPTION();
750 void ODatabaseExport::showErrorDialog(const ::com::sun::star::sdbc::SQLException
& e
)
754 OUString
aMsg(e
.Message
);
756 aMsg
+= ModuleRes( STR_QRY_CONTINUE
);
757 ScopedVclPtrInstance
< OSQLWarningBox
> aBox( nullptr, aMsg
, WB_YES_NO
| WB_DEF_NO
);
759 if (aBox
->Execute() == RET_YES
)
760 m_bDontAskAgain
= true;
766 void ODatabaseExport::adjustFormat()
768 if ( !m_sTextToken
.isEmpty() )
770 sal_Int32 nNewPos
= m_bIsAutoIncrement
? m_nColumnPos
+1 : m_nColumnPos
;
771 OSL_ENSURE((nNewPos
) < static_cast<sal_Int32
>(m_vColumns
.size()),"Illegal index for vector");
772 if ( (nNewPos
) < static_cast<sal_Int32
>(m_vColumns
.size()) )
774 sal_Int32 nColPos
= m_vColumns
[nNewPos
].first
;
775 if( nColPos
!= sal::static_int_cast
< long >(CONTAINER_ENTRY_NOTFOUND
))
778 OSL_ENSURE((nColPos
) < static_cast<sal_Int32
>(m_vNumberFormat
.size()),"m_vFormatKey: Illegal index for vector");
779 OSL_ENSURE((nColPos
) < static_cast<sal_Int32
>(m_vColumnSize
.size()),"m_vColumnSize: Illegal index for vector");
780 m_vNumberFormat
[nColPos
] = CheckString(m_sTextToken
,m_vNumberFormat
[nColPos
]);
781 m_vColumnSize
[nColPos
] = ::std::max
<sal_Int32
>((sal_Int32
)m_vColumnSize
[nColPos
], m_sTextToken
.getLength());
788 void ODatabaseExport::eraseTokens()
790 m_sTextToken
.clear();
795 void ODatabaseExport::ensureFormatter()
799 Reference
< XNumberFormatsSupplier
> xSupplier
= m_xFormatter
->getNumberFormatsSupplier();
800 Reference
< XUnoTunnel
> xTunnel(xSupplier
,UNO_QUERY
);
801 SvNumberFormatsSupplierObj
* pSupplierImpl
= reinterpret_cast<SvNumberFormatsSupplierObj
*>(xTunnel
->getSomething(SvNumberFormatsSupplierObj::getUnoTunnelId()));
802 m_pFormatter
= pSupplierImpl
? pSupplierImpl
->GetNumberFormatter() : NULL
;
803 Reference
<XPropertySet
> xNumberFormatSettings
= xSupplier
->getNumberFormatSettings();
804 xNumberFormatSettings
->getPropertyValue("NullDate") >>= m_aNullDate
;
808 Reference
< XPreparedStatement
> ODatabaseExport::createPreparedStatment( const Reference
<XDatabaseMetaData
>& _xMetaData
809 ,const Reference
<XPropertySet
>& _xDestTable
810 ,const TPositions
& _rvColumns
)
812 OUString
aSql("INSERT INTO ");
813 OUString sComposedTableName
= ::dbtools::composeTableName( _xMetaData
, _xDestTable
, ::dbtools::eInDataManipulation
, false, false, true );
815 aSql
+= sComposedTableName
;
817 // set values and column names
818 OUString
aValues(" VALUES ( ");
821 if ( _xMetaData
.is() )
822 aQuote
= _xMetaData
->getIdentifierQuoteString();
824 Reference
<XColumnsSupplier
> xDestColsSup(_xDestTable
,UNO_QUERY_THROW
);
826 // create sql string and set column types
827 Sequence
< OUString
> aDestColumnNames
= xDestColsSup
->getColumns()->getElementNames();
828 if ( aDestColumnNames
.getLength() == 0 )
830 return Reference
< XPreparedStatement
> ();
832 const OUString
* pIter
= aDestColumnNames
.getConstArray();
833 ::std::vector
< OUString
> aInsertList
;
834 aInsertList
.resize(aDestColumnNames
.getLength()+1);
836 for(sal_uInt32 j
=0; j
< aInsertList
.size() ;++i
,++j
)
838 ODatabaseExport::TPositions::const_iterator aFind
= ::std::find_if(_rvColumns
.begin(),_rvColumns
.end(),
839 ::o3tl::compose1(::std::bind2nd(::std::equal_to
<sal_Int32
>(),i
+1),::o3tl::select2nd
<ODatabaseExport::TPositions::value_type
>()));
840 if ( _rvColumns
.end() != aFind
&& aFind
->second
!= sal::static_int_cast
< long >(CONTAINER_ENTRY_NOTFOUND
) && aFind
->first
!= sal::static_int_cast
< long >(CONTAINER_ENTRY_NOTFOUND
) )
842 OSL_ENSURE((aFind
->first
) < static_cast<sal_Int32
>(aInsertList
.size()),"aInsertList: Illegal index for vector");
843 aInsertList
[aFind
->first
] = ::dbtools::quoteName( aQuote
,*(pIter
+i
));
848 // create the sql string
849 ::std::vector
< OUString
>::iterator aInsertEnd
= aInsertList
.end();
850 for (::std::vector
< OUString
>::iterator aInsertIter
= aInsertList
.begin(); aInsertIter
!= aInsertEnd
; ++aInsertIter
)
852 if ( !aInsertIter
->isEmpty() )
854 aSql
+= *aInsertIter
;
860 aSql
= aSql
.replaceAt(aSql
.getLength()-1, 1, ")");
861 aValues
= aValues
.replaceAt(aValues
.getLength()-1, 1, ")");
864 // now create,fill and execute the prepared statement
865 return Reference
< XPreparedStatement
>(_xMetaData
->getConnection()->prepareStatement(aSql
));
868 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */