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 <tools/debug.hxx>
49 #include <tools/diagnose_ex.h>
50 #include <tools/contnr.hxx>
51 #include <i18nlangtag/mslangid.hxx>
52 #include <com/sun/star/awt/FontDescriptor.hpp>
53 #include "WCopyTable.hxx"
54 #include "WExtendPages.hxx"
56 #include <unotools/syslocale.hxx>
57 #include <svl/zforlist.hxx>
58 #include <connectivity/dbexception.hxx>
59 #include <connectivity/FValue.hxx>
60 #include <com/sun/star/sdbc/SQLWarning.hpp>
61 #include <com/sun/star/sdb/SQLContext.hpp>
62 #include <com/sun/star/sdb/application/CopyTableOperation.hpp>
63 #include "sqlmessage.hxx"
64 #include "UpdateHelperImpl.hxx"
65 #include <vcl/msgbox.hxx>
66 #include <cppuhelper/exc_hlp.hxx>
68 using namespace dbaui
;
70 using namespace ::com::sun::star::uno
;
71 using namespace ::com::sun::star::beans
;
72 using namespace ::com::sun::star::container
;
73 using namespace ::com::sun::star::util
;
74 using namespace ::com::sun::star::sdbc
;
75 using namespace ::com::sun::star::sdbcx
;
76 using namespace ::com::sun::star::sdb
;
77 using namespace ::com::sun::star::lang
;
78 using namespace ::com::sun::star::awt
;
80 namespace CopyTableOperation
= ::com::sun::star::sdb::application::CopyTableOperation
;
83 ODatabaseExport::ODatabaseExport(sal_Int32 nRows
,
84 const TPositions
&_rColumnPositions
,
85 const Reference
< XNumberFormatter
>& _rxNumberF
,
86 const Reference
< css::uno::XComponentContext
>& _rxContext
,
87 const TColumnVector
* pList
,
88 const OTypeInfoMap
* _pInfoMap
,
89 bool _bAutoIncrementEnabled
,
90 SvStream
& _rInputStream
)
91 :m_vColumns(_rColumnPositions
)
93 ,m_xFormatter(_rxNumberF
)
94 ,m_xContext(_rxContext
)
95 ,m_pFormatter(nullptr)
96 ,m_rInputStream( _rInputStream
)
99 ,m_pInfoMap(_pInfoMap
)
103 ,m_nDefToken( osl_getThreadTextEncoding() )
107 ,m_bDontAskAgain(false)
108 ,m_bIsAutoIncrement(_bAutoIncrementEnabled
)
109 ,m_bFoundTable(false)
111 ,m_bAppendFirstLine(false)
114 sal_Int32 nCount
= 0;
115 for(const std::pair
<sal_Int32
,sal_Int32
> & rPair
: m_vColumns
)
116 if ( rPair
.first
!= COLUMN_POSITION_NOT_FOUND
)
119 m_vColumnSize
.resize(nCount
);
120 m_vNumberFormat
.resize(nCount
);
121 for(sal_Int32 i
=0;i
<nCount
;++i
)
123 m_vColumnSize
[i
] = 0;
124 m_vNumberFormat
[i
] = 0;
129 SvtSysLocale aSysLocale
;
130 m_aLocale
= aSysLocale
.GetLanguageTag().getLocale();
136 SetColumnTypes(pList
,_pInfoMap
);
139 ODatabaseExport::ODatabaseExport(const SharedConnection
& _rxConnection
,
140 const Reference
< XNumberFormatter
>& _rxNumberF
,
141 const Reference
< css::uno::XComponentContext
>& _rxContext
,
142 const TColumnVector
* pList
,
143 const OTypeInfoMap
* _pInfoMap
,
144 SvStream
& _rInputStream
)
145 :m_aDestColumns(_rxConnection
->getMetaData().is() && _rxConnection
->getMetaData()->supportsMixedCaseQuotedIdentifiers())
146 ,m_xConnection(_rxConnection
)
147 ,m_xFormatter(_rxNumberF
)
148 ,m_xContext(_rxContext
)
149 ,m_pFormatter(nullptr)
150 ,m_rInputStream( _rInputStream
)
152 ,m_pColumnList(nullptr)
157 ,m_nDefToken( osl_getThreadTextEncoding() )
161 ,m_bDontAskAgain(false)
162 ,m_bIsAutoIncrement(false)
163 ,m_bFoundTable(false)
165 ,m_bAppendFirstLine(false)
169 SvtSysLocale aSysLocale
;
170 m_aLocale
= aSysLocale
.GetLanguageTag().getLocale();
176 Reference
<XTablesSupplier
> xTablesSup(m_xConnection
,UNO_QUERY
);
178 m_xTables
= xTablesSup
->getTables();
180 Reference
<XDatabaseMetaData
> xMeta
= m_xConnection
->getMetaData();
181 Reference
<XResultSet
> xSet
= xMeta
.is() ? xMeta
->getTypeInfo() : Reference
<XResultSet
>();
184 ::connectivity::ORowSetValue aValue
;
185 ::std::vector
<sal_Int32
> aTypes
;
186 ::std::vector
<sal_Bool
> aNullable
;
187 Reference
<XResultSetMetaData
> xResultSetMetaData
= Reference
<XResultSetMetaDataSupplier
>(xSet
,UNO_QUERY_THROW
)->getMetaData();
188 Reference
<XRow
> xRow(xSet
,UNO_QUERY_THROW
);
191 if ( aTypes
.empty() )
193 sal_Int32 nCount
= xResultSetMetaData
->getColumnCount();
196 aTypes
.reserve(nCount
+1);
197 aNullable
.reserve(nCount
+1);
198 aTypes
.push_back(-1);
199 aNullable
.push_back(false);
200 for (sal_Int32 j
= 1; j
<= nCount
; ++j
)
202 aNullable
.push_back(xResultSetMetaData
->isNullable(j
) != ColumnValue::NO_NULLS
);
203 aTypes
.push_back(xResultSetMetaData
->getColumnType(j
));
208 OSL_ENSURE((nPos
) < static_cast<sal_Int32
>(aTypes
.size()),"aTypes: Illegal index for vector");
209 aValue
.fill(nPos
,aTypes
[nPos
],aNullable
[nPos
],xRow
);
210 OUString sTypeName
= aValue
;
212 OSL_ENSURE((nPos
) < static_cast<sal_Int32
>(aTypes
.size()),"aTypes: Illegal index for vector");
213 aValue
.fill(nPos
,aTypes
[nPos
],aNullable
[nPos
],xRow
);
214 sal_Int32 nType
= aValue
;
217 if( nType
== DataType::VARCHAR
)
219 m_pTypeInfo
= std::make_shared
<OTypeInfo
>();
221 m_pTypeInfo
->aTypeName
= sTypeName
;
222 m_pTypeInfo
->nType
= nType
;
224 OSL_ENSURE((nPos
) < static_cast<sal_Int32
>(aTypes
.size()),"aTypes: Illegal index for vector");
225 aValue
.fill(nPos
,aTypes
[nPos
],aNullable
[nPos
],xRow
);
226 m_pTypeInfo
->nPrecision
= aValue
;
228 aValue
.fill(nPos
,aTypes
[nPos
],aNullable
[nPos
],xRow
);
229 m_pTypeInfo
->aLiteralPrefix
= aValue
;
231 aValue
.fill(nPos
,aTypes
[nPos
],aNullable
[nPos
],xRow
);
232 m_pTypeInfo
->aLiteralSuffix
= aValue
;
234 aValue
.fill(nPos
,aTypes
[nPos
],aNullable
[nPos
],xRow
);
235 m_pTypeInfo
->aCreateParams
= aValue
;
237 aValue
.fill(nPos
,aTypes
[nPos
],aNullable
[nPos
],xRow
);
238 m_pTypeInfo
->bNullable
= (sal_Int32
)aValue
== ColumnValue::NULLABLE
;
240 aValue
.fill(nPos
,aTypes
[nPos
],aNullable
[nPos
],xRow
);
241 m_pTypeInfo
->bCaseSensitive
= aValue
;
243 aValue
.fill(nPos
,aTypes
[nPos
],aNullable
[nPos
],xRow
);
244 m_pTypeInfo
->nSearchType
= aValue
;
246 aValue
.fill(nPos
,aTypes
[nPos
],aNullable
[nPos
],xRow
);
247 m_pTypeInfo
->bUnsigned
= aValue
;
249 aValue
.fill(nPos
,aTypes
[nPos
],aNullable
[nPos
],xRow
);
250 m_pTypeInfo
->bCurrency
= aValue
;
252 aValue
.fill(nPos
,aTypes
[nPos
],aNullable
[nPos
],xRow
);
253 m_pTypeInfo
->bAutoIncrement
= aValue
;
255 aValue
.fill(nPos
,aTypes
[nPos
],aNullable
[nPos
],xRow
);
256 m_pTypeInfo
->aLocalTypeName
= aValue
;
258 aValue
.fill(nPos
,aTypes
[nPos
],aNullable
[nPos
],xRow
);
259 m_pTypeInfo
->nMinimumScale
= aValue
;
261 aValue
.fill(nPos
,aTypes
[nPos
],aNullable
[nPos
],xRow
);
262 m_pTypeInfo
->nMaximumScale
= aValue
;
264 aValue
.fill(nPos
,aTypes
[nPos
],xRow
);
265 m_pTypeInfo
->nNumPrecRadix
= aValue
;
267 // check if values are less than zero like it happens in a oracle jdbc driver
268 if( m_pTypeInfo
->nPrecision
< 0)
269 m_pTypeInfo
->nPrecision
= 0;
270 if( m_pTypeInfo
->nMinimumScale
< 0)
271 m_pTypeInfo
->nMinimumScale
= 0;
272 if( m_pTypeInfo
->nMaximumScale
< 0)
273 m_pTypeInfo
->nMaximumScale
= 0;
274 if( m_pTypeInfo
->nNumPrecRadix
<= 1)
275 m_pTypeInfo
->nNumPrecRadix
= 10;
281 m_pTypeInfo
= std::make_shared
<OTypeInfo
>();
282 SetColumnTypes(pList
,_pInfoMap
);
285 ODatabaseExport::~ODatabaseExport()
287 m_pFormatter
= nullptr;
288 ODatabaseExport::TColumns::const_iterator aIter
= m_aDestColumns
.begin();
289 ODatabaseExport::TColumns::const_iterator aEnd
= m_aDestColumns
.end();
291 for(;aIter
!= aEnd
;++aIter
)
292 delete aIter
->second
;
293 m_vDestVector
.clear();
294 m_aDestColumns
.clear();
297 void ODatabaseExport::insertValueIntoColumn()
299 if(m_nColumnPos
< sal_Int32(m_vDestVector
.size()))
301 OFieldDescription
* pField
= m_vDestVector
[m_nColumnPos
]->second
;
304 sal_Int32 nNewPos
= m_bIsAutoIncrement
? m_nColumnPos
+1 : m_nColumnPos
;
305 OSL_ENSURE((nNewPos
) < static_cast<sal_Int32
>(m_vColumns
.size()),"m_vColumns: Illegal index for vector");
307 if ( (nNewPos
) < static_cast<sal_Int32
>(m_vColumns
.size() ) )
309 sal_Int32 nPos
= m_vColumns
[nNewPos
].first
;
310 if ( nPos
!= COLUMN_POSITION_NOT_FOUND
)
312 if ( m_sTextToken
.isEmpty() && pField
->IsNullable() )
313 m_pUpdateHelper
->updateNull(nPos
,pField
->GetType());
316 OSL_ENSURE((nNewPos
) < static_cast<sal_Int32
>(m_vColumnTypes
.size()),"Illegal index for vector");
317 if (m_vColumnTypes
[nNewPos
] != DataType::VARCHAR
&& m_vColumnTypes
[nNewPos
] != DataType::CHAR
&& m_vColumnTypes
[nNewPos
] != DataType::LONGVARCHAR
)
319 SAL_INFO("dbaccess", "ODatabaseExport::insertValueIntoColumn != DataType::VARCHAR" );
321 sal_Int32 nNumberFormat
= 0;
322 double fOutNumber
= 0.0;
323 bool bNumberFormatError
= false;
324 if ( m_pFormatter
&& !m_sNumToken
.isEmpty() )
326 LanguageType eNumLang
= LANGUAGE_NONE
;
327 sal_uInt32
nNumberFormat2( nNumberFormat
);
328 fOutNumber
= SfxHTMLParser::GetTableDataOptionsValNum(nNumberFormat2
,eNumLang
,m_sTextToken
,m_sNumToken
,*m_pFormatter
);
329 if ( eNumLang
!= LANGUAGE_NONE
)
331 nNumberFormat2
= m_pFormatter
->GetFormatForLanguageIfBuiltIn( nNumberFormat2
, eNumLang
);
332 m_pFormatter
->IsNumberFormat( m_sTextToken
, nNumberFormat2
, fOutNumber
);
334 nNumberFormat
= static_cast<sal_Int32
>(nNumberFormat2
);
338 Reference
< XNumberFormatsSupplier
> xSupplier
= m_xFormatter
->getNumberFormatsSupplier();
339 Reference
<XNumberFormatTypes
> xNumType(xSupplier
->getNumberFormats(),UNO_QUERY
);
340 const sal_Int16 nFormats
[] = {
341 NumberFormat::DATETIME
344 ,NumberFormat::CURRENCY
345 ,NumberFormat::NUMBER
346 ,NumberFormat::LOGICAL
348 for (short nFormat
: nFormats
)
352 nNumberFormat
= m_xFormatter
->detectNumberFormat(xNumType
->getStandardFormat(nFormat
,m_aLocale
),m_sTextToken
);
361 fOutNumber
= m_xFormatter
->convertStringToNumber(nNumberFormat
,m_sTextToken
);
365 bNumberFormatError
= true;
366 m_pUpdateHelper
->updateString(nPos
,m_sTextToken
);
369 if ( !bNumberFormatError
)
373 Reference
< XNumberFormatsSupplier
> xSupplier
= m_xFormatter
->getNumberFormatsSupplier();
374 Reference
< XNumberFormats
> xFormats
= xSupplier
->getNumberFormats();
375 Reference
<XPropertySet
> xProp
= xFormats
->getByKey(nNumberFormat
);
377 xProp
->getPropertyValue(PROPERTY_TYPE
) >>= nType
;
380 case NumberFormat::DATE
:
381 m_pUpdateHelper
->updateDate(nPos
,::dbtools::DBTypeConversion::toDate(fOutNumber
,m_aNullDate
));
383 case NumberFormat::DATETIME
:
384 m_pUpdateHelper
->updateTimestamp(nPos
,::dbtools::DBTypeConversion::toDateTime(fOutNumber
,m_aNullDate
));
386 case NumberFormat::TIME
:
387 m_pUpdateHelper
->updateTime(nPos
,::dbtools::DBTypeConversion::toTime(fOutNumber
));
390 m_pUpdateHelper
->updateDouble(nPos
,fOutNumber
);
395 m_pUpdateHelper
->updateString(nPos
,m_sTextToken
);
401 m_pUpdateHelper
->updateString(nPos
,m_sTextToken
);
410 sal_Int16
ODatabaseExport::CheckString(const OUString
& aCheckToken
, sal_Int16 _nOldNumberFormat
)
412 sal_Int16 nNumberFormat
= 0;
416 Reference
< XNumberFormatsSupplier
> xSupplier
= m_xFormatter
->getNumberFormatsSupplier();
417 Reference
< XNumberFormats
> xFormats
= xSupplier
->getNumberFormats();
420 if ( m_pFormatter
&& !m_sNumToken
.isEmpty() )
422 LanguageType eNumLang
;
423 sal_uInt32
nFormatKey(0);
424 double fOutNumber
= SfxHTMLParser::GetTableDataOptionsValNum(nFormatKey
,eNumLang
,m_sTextToken
,m_sNumToken
,*m_pFormatter
);
425 if ( eNumLang
!= LANGUAGE_NONE
)
427 nFormatKey
= m_pFormatter
->GetFormatForLanguageIfBuiltIn( nFormatKey
, eNumLang
);
428 if ( !m_pFormatter
->IsNumberFormat( m_sTextToken
, nFormatKey
, fOutNumber
) )
429 return NumberFormat::TEXT
;
431 Reference
<XPropertySet
> xProp
= xFormats
->getByKey(nFormatKey
);
432 xProp
->getPropertyValue(PROPERTY_TYPE
) >>= nNumberFormat
;
436 Reference
<XNumberFormatTypes
> xNumType(xFormats
,UNO_QUERY
);
437 sal_Int32 nFormatKey
= m_xFormatter
->detectNumberFormat(xNumType
->getStandardFormat(NumberFormat::ALL
,m_aLocale
),aCheckToken
);
438 m_xFormatter
->convertStringToNumber(nFormatKey
,aCheckToken
);
440 Reference
<XPropertySet
> xProp
= xFormats
->getByKey(nFormatKey
);
442 xProp
->getPropertyValue(PROPERTY_TYPE
) >>= nType
;
446 case NumberFormat::ALL
:
447 nNumberFormat
= NumberFormat::ALL
;
449 case NumberFormat::DEFINED
:
450 nNumberFormat
= NumberFormat::TEXT
;
452 case NumberFormat::DATE
:
453 switch(_nOldNumberFormat
)
455 case NumberFormat::DATETIME
:
456 case NumberFormat::TEXT
:
457 case NumberFormat::DATE
:
458 nNumberFormat
= _nOldNumberFormat
;
460 case NumberFormat::ALL
:
461 nNumberFormat
= NumberFormat::DATE
;
464 nNumberFormat
= NumberFormat::TEXT
;
468 case NumberFormat::TIME
:
469 switch(_nOldNumberFormat
)
471 case NumberFormat::DATETIME
:
472 case NumberFormat::TEXT
:
473 case NumberFormat::TIME
:
474 nNumberFormat
= _nOldNumberFormat
;
476 case NumberFormat::ALL
:
477 nNumberFormat
= NumberFormat::TIME
;
480 nNumberFormat
= NumberFormat::TEXT
;
484 case NumberFormat::CURRENCY
:
485 switch(_nOldNumberFormat
)
487 case NumberFormat::NUMBER
:
488 nNumberFormat
= NumberFormat::CURRENCY
;
490 case NumberFormat::CURRENCY
:
491 nNumberFormat
= _nOldNumberFormat
;
493 case NumberFormat::ALL
:
494 nNumberFormat
= NumberFormat::CURRENCY
;
497 nNumberFormat
= NumberFormat::TEXT
;
501 case NumberFormat::NUMBER
:
502 case NumberFormat::SCIENTIFIC
:
503 case NumberFormat::FRACTION
:
504 case NumberFormat::PERCENT
:
505 switch(_nOldNumberFormat
)
507 case NumberFormat::NUMBER
:
508 nNumberFormat
= _nOldNumberFormat
;
510 case NumberFormat::CURRENCY
:
511 nNumberFormat
= NumberFormat::CURRENCY
;
513 case NumberFormat::ALL
:
514 nNumberFormat
= nType
;
517 nNumberFormat
= NumberFormat::TEXT
;
521 case NumberFormat::TEXT
:
522 case NumberFormat::UNDEFINED
:
523 case NumberFormat::LOGICAL
:
524 nNumberFormat
= NumberFormat::TEXT
; // Text "uberschreibt alles
526 case NumberFormat::DATETIME
:
527 switch(_nOldNumberFormat
)
529 case NumberFormat::DATETIME
:
530 case NumberFormat::TEXT
:
531 case NumberFormat::TIME
:
532 nNumberFormat
= _nOldNumberFormat
;
534 case NumberFormat::ALL
:
535 nNumberFormat
= NumberFormat::DATETIME
;
538 nNumberFormat
= NumberFormat::TEXT
;
543 SAL_WARN("dbaccess.ui", "ODatabaseExport: Unbekanntes Format");
549 nNumberFormat
= NumberFormat::TEXT
; // Text "uberschreibt alles
552 return nNumberFormat
;
555 void ODatabaseExport::SetColumnTypes(const TColumnVector
* _pList
,const OTypeInfoMap
* _pInfoMap
)
557 if(_pList
&& _pInfoMap
)
559 OSL_ENSURE(m_vNumberFormat
.size() == m_vColumnSize
.size() && m_vColumnSize
.size() == _pList
->size(),"Illegal columns in list");
560 Reference
< XNumberFormatsSupplier
> xSupplier
= m_xFormatter
->getNumberFormatsSupplier();
561 Reference
< XNumberFormats
> xFormats
= xSupplier
->getNumberFormats();
562 TColumnVector::const_iterator aIter
= _pList
->begin();
563 TColumnVector::const_iterator aEnd
= _pList
->end();
564 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
)
567 sal_Int32
nLength(0),nScale(0);
568 sal_Int16 nType
= m_vNumberFormat
[i
] & ~NumberFormat::DEFINED
;
572 case NumberFormat::ALL
:
573 nDataType
= DataType::DOUBLE
;
575 case NumberFormat::DEFINED
:
576 nDataType
= DataType::VARCHAR
;
577 nLength
= ((m_vColumnSize
[i
] % 10 ) ? m_vColumnSize
[i
]/ 10 + 1: m_vColumnSize
[i
]/ 10) * 10;
579 case NumberFormat::DATE
:
580 nDataType
= DataType::DATE
;
582 case NumberFormat::TIME
:
583 nDataType
= DataType::TIME
;
585 case NumberFormat::DATETIME
:
586 nDataType
= DataType::TIMESTAMP
;
588 case NumberFormat::CURRENCY
:
589 nDataType
= DataType::NUMERIC
;
593 case NumberFormat::NUMBER
:
594 case NumberFormat::SCIENTIFIC
:
595 case NumberFormat::FRACTION
:
596 case NumberFormat::PERCENT
:
597 nDataType
= DataType::DOUBLE
;
599 case NumberFormat::TEXT
:
600 case NumberFormat::UNDEFINED
:
601 case NumberFormat::LOGICAL
:
603 nDataType
= DataType::VARCHAR
;
604 nLength
= ((m_vColumnSize
[i
] % 10 ) ? m_vColumnSize
[i
]/ 10 + 1: m_vColumnSize
[i
]/ 10) * 10;
607 OTypeInfoMap::const_iterator aFind
= _pInfoMap
->find(nDataType
);
608 if(aFind
!= _pInfoMap
->end())
610 (*aIter
)->second
->SetType(aFind
->second
);
611 (*aIter
)->second
->SetPrecision(::std::min
<sal_Int32
>(aFind
->second
->nPrecision
,nLength
));
612 (*aIter
)->second
->SetScale(::std::min
<sal_Int32
>(aFind
->second
->nMaximumScale
,nScale
));
614 sal_Int32 nFormatKey
= ::dbtools::getDefaultNumberFormat( nDataType
,
615 (*aIter
)->second
->GetScale(),
616 (*aIter
)->second
->IsCurrency(),
617 Reference
< XNumberFormatTypes
>(xFormats
,UNO_QUERY
),
620 (*aIter
)->second
->SetFormatKey(nFormatKey
);
626 void ODatabaseExport::CreateDefaultColumn(const OUString
& _rColumnName
)
628 Reference
< XDatabaseMetaData
> xDestMetaData(m_xConnection
->getMetaData());
629 sal_Int32
nMaxNameLen(xDestMetaData
->getMaxColumnNameLength());
630 OUString aAlias
= _rColumnName
;
631 if ( isSQL92CheckEnabled(m_xConnection
) )
632 aAlias
= ::dbtools::convertName2SQLName(_rColumnName
,xDestMetaData
->getExtraNameCharacters());
634 if(nMaxNameLen
&& aAlias
.getLength() > nMaxNameLen
)
635 aAlias
= aAlias
.copy(0, ::std::min
<sal_Int32
>( nMaxNameLen
-1, aAlias
.getLength() ) );
637 OUString
sName(aAlias
);
638 if(m_aDestColumns
.find(sName
) != m_aDestColumns
.end())
641 sal_Int32 nCount
= 2;
642 while(m_aDestColumns
.find(sName
) != m_aDestColumns
.end())
645 sName
+= OUString::number(++nPos
);
646 if(nMaxNameLen
&& sName
.getLength() > nMaxNameLen
)
648 aAlias
= aAlias
.copy(0,::std::min
<sal_Int32
>( nMaxNameLen
-nCount
, aAlias
.getLength() ));
650 sName
+= OUString::number(nPos
);
656 // now create a column
657 OFieldDescription
* pField
= new OFieldDescription();
658 pField
->SetType(m_pTypeInfo
);
659 pField
->SetName(aAlias
);
660 pField
->SetPrecision(::std::min
<sal_Int32
>((sal_Int32
)255,m_pTypeInfo
->nPrecision
));
662 pField
->SetIsNullable(ColumnValue::NULLABLE
);
663 pField
->SetAutoIncrement(false);
664 pField
->SetPrimaryKey(false);
665 pField
->SetCurrency(false);
667 TColumns::const_iterator aFind
= m_aDestColumns
.find( aAlias
);
668 if ( aFind
!= m_aDestColumns
.end() )
670 delete aFind
->second
;
671 m_aDestColumns
.erase(aFind
);
674 m_vDestVector
.push_back(m_aDestColumns
.insert(TColumns::value_type(aAlias
,pField
)).first
);
677 bool ODatabaseExport::createRowSet()
679 m_pUpdateHelper
.reset(new OParameterUpdateHelper(createPreparedStatment(m_xConnection
->getMetaData(),m_xTable
,m_vColumns
)));
681 return m_pUpdateHelper
.get() != nullptr;
684 bool ODatabaseExport::executeWizard(const OUString
& _rTableName
, const Any
& _aTextColor
, const FontDescriptor
& _rFont
)
686 bool bHaveDefaultTable
= !m_sDefaultTableName
.isEmpty();
687 OUString
sTableName( bHaveDefaultTable
? m_sDefaultTableName
: _rTableName
);
688 ScopedVclPtrInstance
<OCopyTableWizard
> aWizard(
691 bHaveDefaultTable
? CopyTableOperation::AppendData
: CopyTableOperation::CopyDefinitionAndData
,
696 getTypeSelectionPageFactory(),
704 if (aWizard
->Execute())
706 switch(aWizard
->getOperation())
708 case CopyTableOperation::CopyDefinitionAndData
:
709 case CopyTableOperation::AppendData
:
711 m_xTable
= aWizard
->createTable();
712 bError
= !m_xTable
.is();
715 m_xTable
->setPropertyValue(PROPERTY_FONT
,makeAny(_rFont
));
716 if(_aTextColor
.hasValue())
717 m_xTable
->setPropertyValue(PROPERTY_TEXTCOLOR
,_aTextColor
);
719 m_bIsAutoIncrement
= aWizard
->shouldCreatePrimaryKey();
720 m_vColumns
= aWizard
->GetColumnPositions();
721 m_vColumnTypes
= aWizard
->GetColumnTypes();
722 m_bAppendFirstLine
= !aWizard
->UseHeaderLine();
726 bError
= true; // there is no error but I have nothing more to do
733 bError
= !createRowSet();
735 catch( const SQLException
&)
737 ::dbaui::showError( ::dbtools::SQLExceptionInfo( ::cppu::getCaughtException() ), aWizard
.get(), m_xContext
);
740 catch( const Exception
& )
742 DBG_UNHANDLED_EXCEPTION();
748 void ODatabaseExport::showErrorDialog(const css::sdbc::SQLException
& e
)
752 OUString
aMsg(e
.Message
);
754 aMsg
+= ModuleRes( STR_QRY_CONTINUE
);
755 ScopedVclPtrInstance
< OSQLWarningBox
> aBox( nullptr, aMsg
, WB_YES_NO
| WB_DEF_NO
);
757 if (aBox
->Execute() == RET_YES
)
758 m_bDontAskAgain
= true;
764 void ODatabaseExport::adjustFormat()
766 if ( !m_sTextToken
.isEmpty() )
768 sal_Int32 nNewPos
= m_bIsAutoIncrement
? m_nColumnPos
+1 : m_nColumnPos
;
769 OSL_ENSURE((nNewPos
) < static_cast<sal_Int32
>(m_vColumns
.size()),"Illegal index for vector");
770 if ( (nNewPos
) < static_cast<sal_Int32
>(m_vColumns
.size()) )
772 sal_Int32 nColPos
= m_vColumns
[nNewPos
].first
;
773 if( nColPos
!= sal::static_int_cast
< long >(CONTAINER_ENTRY_NOTFOUND
))
776 OSL_ENSURE((nColPos
) < static_cast<sal_Int32
>(m_vNumberFormat
.size()),"m_vFormatKey: Illegal index for vector");
777 OSL_ENSURE((nColPos
) < static_cast<sal_Int32
>(m_vColumnSize
.size()),"m_vColumnSize: Illegal index for vector");
778 m_vNumberFormat
[nColPos
] = CheckString(m_sTextToken
,m_vNumberFormat
[nColPos
]);
779 m_vColumnSize
[nColPos
] = ::std::max
<sal_Int32
>((sal_Int32
)m_vColumnSize
[nColPos
], m_sTextToken
.getLength());
786 void ODatabaseExport::eraseTokens()
788 m_sTextToken
.clear();
793 void ODatabaseExport::ensureFormatter()
797 Reference
< XNumberFormatsSupplier
> xSupplier
= m_xFormatter
->getNumberFormatsSupplier();
798 Reference
< XUnoTunnel
> xTunnel(xSupplier
,UNO_QUERY
);
799 SvNumberFormatsSupplierObj
* pSupplierImpl
= reinterpret_cast<SvNumberFormatsSupplierObj
*>(xTunnel
->getSomething(SvNumberFormatsSupplierObj::getUnoTunnelId()));
800 m_pFormatter
= pSupplierImpl
? pSupplierImpl
->GetNumberFormatter() : nullptr;
801 Reference
<XPropertySet
> xNumberFormatSettings
= xSupplier
->getNumberFormatSettings();
802 xNumberFormatSettings
->getPropertyValue("NullDate") >>= m_aNullDate
;
806 Reference
< XPreparedStatement
> ODatabaseExport::createPreparedStatment( const Reference
<XDatabaseMetaData
>& _xMetaData
807 ,const Reference
<XPropertySet
>& _xDestTable
808 ,const TPositions
& _rvColumns
)
810 OUString
aSql("INSERT INTO ");
811 OUString sComposedTableName
= ::dbtools::composeTableName( _xMetaData
, _xDestTable
, ::dbtools::EComposeRule::InDataManipulation
, false, false, true );
813 aSql
+= sComposedTableName
;
815 // set values and column names
816 OUString
aValues(" VALUES ( ");
819 if ( _xMetaData
.is() )
820 aQuote
= _xMetaData
->getIdentifierQuoteString();
822 Reference
<XColumnsSupplier
> xDestColsSup(_xDestTable
,UNO_QUERY_THROW
);
824 // create sql string and set column types
825 Sequence
< OUString
> aDestColumnNames
= xDestColsSup
->getColumns()->getElementNames();
826 if ( aDestColumnNames
.getLength() == 0 )
828 return Reference
< XPreparedStatement
> ();
830 const OUString
* pIter
= aDestColumnNames
.getConstArray();
831 ::std::vector
< OUString
> aInsertList
;
832 aInsertList
.resize(aDestColumnNames
.getLength()+1);
833 for(size_t j
=0; j
< aInsertList
.size(); ++j
)
835 ODatabaseExport::TPositions::const_iterator aFind
= ::std::find_if(_rvColumns
.begin(),_rvColumns
.end(),
836 [j
] (const ODatabaseExport::TPositions::value_type
& tPos
)
837 { return tPos
.second
== (sal_Int32
)(j
+1); });
838 if ( _rvColumns
.end() != aFind
&& aFind
->second
!= sal::static_int_cast
< long >(CONTAINER_ENTRY_NOTFOUND
) && aFind
->first
!= sal::static_int_cast
< long >(CONTAINER_ENTRY_NOTFOUND
) )
840 OSL_ENSURE((aFind
->first
) < static_cast<sal_Int32
>(aInsertList
.size()),"aInsertList: Illegal index for vector");
841 aInsertList
[aFind
->first
] = ::dbtools::quoteName( aQuote
,*(pIter
+j
));
845 // create the sql string
846 ::std::vector
< OUString
>::const_iterator aInsertEnd
= aInsertList
.end();
847 for (::std::vector
< OUString
>::const_iterator aInsertIter
= aInsertList
.begin(); aInsertIter
!= aInsertEnd
; ++aInsertIter
)
849 if ( !aInsertIter
->isEmpty() )
851 aSql
+= *aInsertIter
;
857 aSql
= aSql
.replaceAt(aSql
.getLength()-1, 1, ")");
858 aValues
= aValues
.replaceAt(aValues
.getLength()-1, 1, ")");
861 // now create,fill and execute the prepared statement
862 return Reference
< XPreparedStatement
>(_xMetaData
->getConnection()->prepareStatement(aSql
));
865 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */