Version 5.2.6.1, tag libreoffice-5.2.6.1
[LibreOffice.git] / dbaccess / source / ui / misc / DExport.cxx
blob5739239a7045012ccd12d3b760f865cebaf01dbd
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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"
55 #include "WCPage.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;
69 using namespace utl;
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;
82 // ODatabaseExport
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)
92 ,m_aDestColumns(true)
93 ,m_xFormatter(_rxNumberF)
94 ,m_xContext(_rxContext)
95 ,m_pFormatter(nullptr)
96 ,m_rInputStream( _rInputStream )
97 ,m_pTypeInfo()
98 ,m_pColumnList(pList)
99 ,m_pInfoMap(_pInfoMap)
100 ,m_nColumnPos(0)
101 ,m_nRows(1)
102 ,m_nRowCount(0)
103 ,m_nDefToken( osl_getThreadTextEncoding() )
104 ,m_bError(false)
105 ,m_bInTbl(false)
106 ,m_bHead(true)
107 ,m_bDontAskAgain(false)
108 ,m_bIsAutoIncrement(_bAutoIncrementEnabled)
109 ,m_bFoundTable(false)
110 ,m_bCheckOnly(false)
111 ,m_bAppendFirstLine(false)
113 m_nRows += nRows;
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 )
117 ++nCount;
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();
132 catch(Exception&)
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 )
151 ,m_pTypeInfo()
152 ,m_pColumnList(nullptr)
153 ,m_pInfoMap(nullptr)
154 ,m_nColumnPos(0)
155 ,m_nRows(1)
156 ,m_nRowCount(0)
157 ,m_nDefToken( osl_getThreadTextEncoding() )
158 ,m_bError(false)
159 ,m_bInTbl(false)
160 ,m_bHead(true)
161 ,m_bDontAskAgain(false)
162 ,m_bIsAutoIncrement(false)
163 ,m_bFoundTable(false)
164 ,m_bCheckOnly(false)
165 ,m_bAppendFirstLine(false)
169 SvtSysLocale aSysLocale;
170 m_aLocale = aSysLocale.GetLanguageTag().getLocale();
172 catch(Exception&)
176 Reference<XTablesSupplier> xTablesSup(m_xConnection,UNO_QUERY);
177 if(xTablesSup.is())
178 m_xTables = xTablesSup->getTables();
180 Reference<XDatabaseMetaData> xMeta = m_xConnection->getMetaData();
181 Reference<XResultSet> xSet = xMeta.is() ? xMeta->getTypeInfo() : Reference<XResultSet>();
182 if(xSet.is())
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);
189 while(xSet->next())
191 if ( aTypes.empty() )
193 sal_Int32 nCount = xResultSetMetaData->getColumnCount();
194 if ( nCount < 1 )
195 nCount = 18;
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));
207 sal_Int32 nPos = 1;
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;
211 ++nPos;
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;
215 ++nPos;
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;
227 ++nPos;
228 aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
229 m_pTypeInfo->aLiteralPrefix = aValue;
230 ++nPos;
231 aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
232 m_pTypeInfo->aLiteralSuffix = aValue;
233 ++nPos;
234 aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
235 m_pTypeInfo->aCreateParams = aValue;
236 ++nPos;
237 aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
238 m_pTypeInfo->bNullable = (sal_Int32)aValue == ColumnValue::NULLABLE;
239 ++nPos;
240 aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
241 m_pTypeInfo->bCaseSensitive = aValue;
242 ++nPos;
243 aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
244 m_pTypeInfo->nSearchType = aValue;
245 ++nPos;
246 aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
247 m_pTypeInfo->bUnsigned = aValue;
248 ++nPos;
249 aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
250 m_pTypeInfo->bCurrency = aValue;
251 ++nPos;
252 aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
253 m_pTypeInfo->bAutoIncrement = aValue;
254 ++nPos;
255 aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
256 m_pTypeInfo->aLocalTypeName = aValue;
257 ++nPos;
258 aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
259 m_pTypeInfo->nMinimumScale = aValue;
260 ++nPos;
261 aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
262 m_pTypeInfo->nMaximumScale = aValue;
263 nPos = 18;
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;
276 break;
280 if ( !m_pTypeInfo )
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;
302 if(pField)
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());
314 else
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" );
320 ensureFormatter();
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);
336 else
338 Reference< XNumberFormatsSupplier > xSupplier = m_xFormatter->getNumberFormatsSupplier();
339 Reference<XNumberFormatTypes> xNumType(xSupplier->getNumberFormats(),UNO_QUERY);
340 const sal_Int16 nFormats[] = {
341 NumberFormat::DATETIME
342 ,NumberFormat::DATE
343 ,NumberFormat::TIME
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);
353 break;
355 catch(Exception&)
361 fOutNumber = m_xFormatter->convertStringToNumber(nNumberFormat,m_sTextToken);
363 catch(Exception&)
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);
376 sal_Int16 nType = 0;
377 xProp->getPropertyValue(PROPERTY_TYPE) >>= nType;
378 switch(nType)
380 case NumberFormat::DATE:
381 m_pUpdateHelper->updateDate(nPos,::dbtools::DBTypeConversion::toDate(fOutNumber,m_aNullDate));
382 break;
383 case NumberFormat::DATETIME:
384 m_pUpdateHelper->updateTimestamp(nPos,::dbtools::DBTypeConversion::toDateTime(fOutNumber,m_aNullDate));
385 break;
386 case NumberFormat::TIME:
387 m_pUpdateHelper->updateTime(nPos,::dbtools::DBTypeConversion::toTime(fOutNumber));
388 break;
389 default:
390 m_pUpdateHelper->updateDouble(nPos,fOutNumber);
393 catch(Exception&)
395 m_pUpdateHelper->updateString(nPos,m_sTextToken);
400 else
401 m_pUpdateHelper->updateString(nPos,m_sTextToken);
405 eraseTokens();
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();
419 ensureFormatter();
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;
434 else
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);
441 sal_Int16 nType = 0;
442 xProp->getPropertyValue(PROPERTY_TYPE) >>= nType;
444 switch(nType)
446 case NumberFormat::ALL:
447 nNumberFormat = NumberFormat::ALL;
448 break;
449 case NumberFormat::DEFINED:
450 nNumberFormat = NumberFormat::TEXT;
451 break;
452 case NumberFormat::DATE:
453 switch(_nOldNumberFormat)
455 case NumberFormat::DATETIME:
456 case NumberFormat::TEXT:
457 case NumberFormat::DATE:
458 nNumberFormat = _nOldNumberFormat;
459 break;
460 case NumberFormat::ALL:
461 nNumberFormat = NumberFormat::DATE;
462 break;
463 default:
464 nNumberFormat = NumberFormat::TEXT;
467 break;
468 case NumberFormat::TIME:
469 switch(_nOldNumberFormat)
471 case NumberFormat::DATETIME:
472 case NumberFormat::TEXT:
473 case NumberFormat::TIME:
474 nNumberFormat = _nOldNumberFormat;
475 break;
476 case NumberFormat::ALL:
477 nNumberFormat = NumberFormat::TIME;
478 break;
479 default:
480 nNumberFormat = NumberFormat::TEXT;
481 break;
483 break;
484 case NumberFormat::CURRENCY:
485 switch(_nOldNumberFormat)
487 case NumberFormat::NUMBER:
488 nNumberFormat = NumberFormat::CURRENCY;
489 break;
490 case NumberFormat::CURRENCY:
491 nNumberFormat = _nOldNumberFormat;
492 break;
493 case NumberFormat::ALL:
494 nNumberFormat = NumberFormat::CURRENCY;
495 break;
496 default:
497 nNumberFormat = NumberFormat::TEXT;
498 break;
500 break;
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;
509 break;
510 case NumberFormat::CURRENCY:
511 nNumberFormat = NumberFormat::CURRENCY;
512 break;
513 case NumberFormat::ALL:
514 nNumberFormat = nType;
515 break;
516 default:
517 nNumberFormat = NumberFormat::TEXT;
518 break;
520 break;
521 case NumberFormat::TEXT:
522 case NumberFormat::UNDEFINED:
523 case NumberFormat::LOGICAL:
524 nNumberFormat = NumberFormat::TEXT; // Text "uberschreibt alles
525 break;
526 case NumberFormat::DATETIME:
527 switch(_nOldNumberFormat)
529 case NumberFormat::DATETIME:
530 case NumberFormat::TEXT:
531 case NumberFormat::TIME:
532 nNumberFormat = _nOldNumberFormat;
533 break;
534 case NumberFormat::ALL:
535 nNumberFormat = NumberFormat::DATETIME;
536 break;
537 default:
538 nNumberFormat = NumberFormat::TEXT;
539 break;
541 break;
542 default:
543 SAL_WARN("dbaccess.ui", "ODatabaseExport: Unbekanntes Format");
547 catch(Exception&)
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)
566 sal_Int32 nDataType;
567 sal_Int32 nLength(0),nScale(0);
568 sal_Int16 nType = m_vNumberFormat[i] & ~NumberFormat::DEFINED;
570 switch ( nType )
572 case NumberFormat::ALL:
573 nDataType = DataType::DOUBLE;
574 break;
575 case NumberFormat::DEFINED:
576 nDataType = DataType::VARCHAR;
577 nLength = ((m_vColumnSize[i] % 10 ) ? m_vColumnSize[i]/ 10 + 1: m_vColumnSize[i]/ 10) * 10;
578 break;
579 case NumberFormat::DATE:
580 nDataType = DataType::DATE;
581 break;
582 case NumberFormat::TIME:
583 nDataType = DataType::TIME;
584 break;
585 case NumberFormat::DATETIME:
586 nDataType = DataType::TIMESTAMP;
587 break;
588 case NumberFormat::CURRENCY:
589 nDataType = DataType::NUMERIC;
590 nScale = 4;
591 nLength = 19;
592 break;
593 case NumberFormat::NUMBER:
594 case NumberFormat::SCIENTIFIC:
595 case NumberFormat::FRACTION:
596 case NumberFormat::PERCENT:
597 nDataType = DataType::DOUBLE;
598 break;
599 case NumberFormat::TEXT:
600 case NumberFormat::UNDEFINED:
601 case NumberFormat::LOGICAL:
602 default:
603 nDataType = DataType::VARCHAR;
604 nLength = ((m_vColumnSize[i] % 10 ) ? m_vColumnSize[i]/ 10 + 1: m_vColumnSize[i]/ 10) * 10;
605 break;
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),
618 m_aLocale);
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())
640 sal_Int32 nPos = 0;
641 sal_Int32 nCount = 2;
642 while(m_aDestColumns.find(sName) != m_aDestColumns.end())
644 sName = aAlias;
645 sName += OUString::number(++nPos);
646 if(nMaxNameLen && sName.getLength() > nMaxNameLen)
648 aAlias = aAlias.copy(0,::std::min<sal_Int32>( nMaxNameLen-nCount, aAlias.getLength() ));
649 sName = aAlias;
650 sName += OUString::number(nPos);
651 ++nCount;
655 aAlias = sName;
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));
661 pField->SetScale(0);
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(
689 nullptr,
690 sTableName,
691 bHaveDefaultTable ? CopyTableOperation::AppendData : CopyTableOperation::CopyDefinitionAndData,
692 m_aDestColumns,
693 m_vDestVector,
694 m_xConnection,
695 m_xFormatter,
696 getTypeSelectionPageFactory(),
697 m_rInputStream,
698 m_xContext
701 bool bError = false;
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();
713 if(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();
724 break;
725 default:
726 bError = true; // there is no error but I have nothing more to do
729 else
730 bError = true;
732 if(!bError)
733 bError = !createRowSet();
735 catch( const SQLException&)
737 ::dbaui::showError( ::dbtools::SQLExceptionInfo( ::cppu::getCaughtException() ), aWizard.get(), m_xContext );
738 bError = true;
740 catch( const Exception& )
742 DBG_UNHANDLED_EXCEPTION();
745 return bError;
748 void ODatabaseExport::showErrorDialog(const css::sdbc::SQLException& e)
750 if(!m_bDontAskAgain)
752 OUString aMsg(e.Message);
753 aMsg += "\n";
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;
759 else
760 m_bError = 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))
775 --nColPos;
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());
782 eraseTokens();
786 void ODatabaseExport::eraseTokens()
788 m_sTextToken.clear();
789 m_sNumToken.clear();
790 m_sValToken.clear();
793 void ODatabaseExport::ensureFormatter()
795 if ( !m_pFormatter )
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;
814 aSql += " ( ";
815 // set values and column names
816 OUString aValues(" VALUES ( ");
818 OUString aQuote;
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;
852 aSql += ",";
853 aValues += "?,";
857 aSql = aSql.replaceAt(aSql.getLength()-1, 1, ")");
858 aValues = aValues.replaceAt(aValues.getLength()-1, 1, ")");
860 aSql += aValues;
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: */