Bump version to 5.0-14
[LibreOffice.git] / dbaccess / source / ui / misc / DExport.cxx
blob67d464ada1887565826659cd2e1a4f29546c2a0c
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 <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"
56 #include "WCPage.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;
70 using namespace utl;
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;
83 // ODatabaseExport
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)
93 ,m_aDestColumns(true)
94 ,m_xFormatter(_rxNumberF)
95 ,m_xContext(_rxContext)
96 ,m_pFormatter(NULL)
97 ,m_rInputStream( _rInputStream )
98 ,m_pTypeInfo()
99 ,m_pColumnList(pList)
100 ,m_pInfoMap(_pInfoMap)
101 ,m_nColumnPos(0)
102 ,m_nRows(1)
103 ,m_nRowCount(0)
104 ,m_nDefToken( osl_getThreadTextEncoding() )
105 ,m_bError(false)
106 ,m_bInTbl(false)
107 ,m_bHead(true)
108 ,m_bDontAskAgain(false)
109 ,m_bIsAutoIncrement(_bAutoIncrementEnabled)
110 ,m_bFoundTable(false)
111 ,m_bCheckOnly(false)
112 ,m_bAppendFirstLine(false)
114 m_nRows += nRows;
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 )
118 ++nCount;
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();
133 catch(Exception&)
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)
150 ,m_pFormatter(NULL)
151 ,m_rInputStream( _rInputStream )
152 ,m_pTypeInfo()
153 ,m_pColumnList(NULL)
154 ,m_pInfoMap(NULL)
155 ,m_nColumnPos(0)
156 ,m_nRows(1)
157 ,m_nRowCount(0)
158 ,m_nDefToken( osl_getThreadTextEncoding() )
159 ,m_bError(false)
160 ,m_bInTbl(false)
161 ,m_bHead(true)
162 ,m_bDontAskAgain(false)
163 ,m_bIsAutoIncrement(false)
164 ,m_bFoundTable(false)
165 ,m_bCheckOnly(false)
166 ,m_bAppendFirstLine(false)
170 SvtSysLocale aSysLocale;
171 m_aLocale = aSysLocale.GetLanguageTag().getLocale();
173 catch(Exception&)
177 Reference<XTablesSupplier> xTablesSup(m_xConnection,UNO_QUERY);
178 if(xTablesSup.is())
179 m_xTables = xTablesSup->getTables();
181 Reference<XDatabaseMetaData> xMeta = m_xConnection->getMetaData();
182 Reference<XResultSet> xSet = xMeta.is() ? xMeta->getTypeInfo() : Reference<XResultSet>();
183 if(xSet.is())
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);
190 while(xSet->next())
192 if ( aTypes.empty() )
194 sal_Int32 nCount = xResultSetMetaData->getColumnCount();
195 if ( nCount < 1 )
196 nCount = 18;
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));
208 sal_Int32 nPos = 1;
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;
212 ++nPos;
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;
216 ++nPos;
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;
228 ++nPos;
229 aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
230 m_pTypeInfo->aLiteralPrefix = aValue;
231 ++nPos;
232 aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
233 m_pTypeInfo->aLiteralSuffix = aValue;
234 ++nPos;
235 aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
236 m_pTypeInfo->aCreateParams = aValue;
237 ++nPos;
238 aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
239 m_pTypeInfo->bNullable = (sal_Int32)aValue == ColumnValue::NULLABLE;
240 ++nPos;
241 aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
242 m_pTypeInfo->bCaseSensitive = aValue;
243 ++nPos;
244 aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
245 m_pTypeInfo->nSearchType = aValue;
246 ++nPos;
247 aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
248 m_pTypeInfo->bUnsigned = aValue;
249 ++nPos;
250 aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
251 m_pTypeInfo->bCurrency = aValue;
252 ++nPos;
253 aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
254 m_pTypeInfo->bAutoIncrement = aValue;
255 ++nPos;
256 aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
257 m_pTypeInfo->aLocalTypeName = aValue;
258 ++nPos;
259 aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
260 m_pTypeInfo->nMinimumScale = aValue;
261 ++nPos;
262 aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
263 m_pTypeInfo->nMaximumScale = aValue;
264 nPos = 18;
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;
277 break;
281 if ( !m_pTypeInfo )
282 m_pTypeInfo = TOTypeInfoSP(new OTypeInfo());
283 SetColumnTypes(pList,_pInfoMap);
286 ODatabaseExport::~ODatabaseExport()
288 m_pFormatter = NULL;
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;
303 if(pField)
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());
315 else
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" );
321 ensureFormatter();
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);
337 else
339 Reference< XNumberFormatsSupplier > xSupplier = m_xFormatter->getNumberFormatsSupplier();
340 Reference<XNumberFormatTypes> xNumType(xSupplier->getNumberFormats(),UNO_QUERY);
341 sal_Int16 nFormats[] = {
342 NumberFormat::DATETIME
343 ,NumberFormat::DATE
344 ,NumberFormat::TIME
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);
354 break;
356 catch(Exception&)
362 fOutNumber = m_xFormatter->convertStringToNumber(nNumberFormat,m_sTextToken);
364 catch(Exception&)
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);
377 sal_Int16 nType = 0;
378 xProp->getPropertyValue(PROPERTY_TYPE) >>= nType;
379 switch(nType)
381 case NumberFormat::DATE:
382 m_pUpdateHelper->updateDate(nPos,::dbtools::DBTypeConversion::toDate(fOutNumber,m_aNullDate));
383 break;
384 case NumberFormat::DATETIME:
385 m_pUpdateHelper->updateTimestamp(nPos,::dbtools::DBTypeConversion::toDateTime(fOutNumber,m_aNullDate));
386 break;
387 case NumberFormat::TIME:
388 m_pUpdateHelper->updateTime(nPos,::dbtools::DBTypeConversion::toTime(fOutNumber));
389 break;
390 default:
391 m_pUpdateHelper->updateDouble(nPos,fOutNumber);
394 catch(Exception&)
396 m_pUpdateHelper->updateString(nPos,m_sTextToken);
401 else
402 m_pUpdateHelper->updateString(nPos,m_sTextToken);
406 eraseTokens();
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();
420 ensureFormatter();
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;
436 else
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);
443 sal_Int16 nType = 0;
444 xProp->getPropertyValue(PROPERTY_TYPE) >>= nType;
446 switch(nType)
448 case NumberFormat::ALL:
449 nNumberFormat = NumberFormat::ALL;
450 break;
451 case NumberFormat::DEFINED:
452 nNumberFormat = NumberFormat::TEXT;
453 break;
454 case NumberFormat::DATE:
455 switch(_nOldNumberFormat)
457 case NumberFormat::DATETIME:
458 case NumberFormat::TEXT:
459 case NumberFormat::DATE:
460 nNumberFormat = _nOldNumberFormat;
461 break;
462 case NumberFormat::ALL:
463 nNumberFormat = NumberFormat::DATE;
464 break;
465 default:
466 nNumberFormat = NumberFormat::TEXT;
469 break;
470 case NumberFormat::TIME:
471 switch(_nOldNumberFormat)
473 case NumberFormat::DATETIME:
474 case NumberFormat::TEXT:
475 case NumberFormat::TIME:
476 nNumberFormat = _nOldNumberFormat;
477 break;
478 case NumberFormat::ALL:
479 nNumberFormat = NumberFormat::TIME;
480 break;
481 default:
482 nNumberFormat = NumberFormat::TEXT;
483 break;
485 break;
486 case NumberFormat::CURRENCY:
487 switch(_nOldNumberFormat)
489 case NumberFormat::NUMBER:
490 nNumberFormat = NumberFormat::CURRENCY;
491 break;
492 case NumberFormat::CURRENCY:
493 nNumberFormat = _nOldNumberFormat;
494 break;
495 case NumberFormat::ALL:
496 nNumberFormat = NumberFormat::CURRENCY;
497 break;
498 default:
499 nNumberFormat = NumberFormat::TEXT;
500 break;
502 break;
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;
511 break;
512 case NumberFormat::CURRENCY:
513 nNumberFormat = NumberFormat::CURRENCY;
514 break;
515 case NumberFormat::ALL:
516 nNumberFormat = nType;
517 break;
518 default:
519 nNumberFormat = NumberFormat::TEXT;
520 break;
522 break;
523 case NumberFormat::TEXT:
524 case NumberFormat::UNDEFINED:
525 case NumberFormat::LOGICAL:
526 nNumberFormat = NumberFormat::TEXT; // Text "uberschreibt alles
527 break;
528 case NumberFormat::DATETIME:
529 switch(_nOldNumberFormat)
531 case NumberFormat::DATETIME:
532 case NumberFormat::TEXT:
533 case NumberFormat::TIME:
534 nNumberFormat = _nOldNumberFormat;
535 break;
536 case NumberFormat::ALL:
537 nNumberFormat = NumberFormat::DATETIME;
538 break;
539 default:
540 nNumberFormat = NumberFormat::TEXT;
541 break;
543 break;
544 default:
545 SAL_WARN("dbaccess.ui", "ODatabaseExport: Unbekanntes Format");
549 catch(Exception&)
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)
568 sal_Int32 nDataType;
569 sal_Int32 nLength(0),nScale(0);
570 sal_Int16 nType = m_vNumberFormat[i] & ~NumberFormat::DEFINED;
572 switch ( nType )
574 case NumberFormat::ALL:
575 nDataType = DataType::DOUBLE;
576 break;
577 case NumberFormat::DEFINED:
578 nDataType = DataType::VARCHAR;
579 nLength = ((m_vColumnSize[i] % 10 ) ? m_vColumnSize[i]/ 10 + 1: m_vColumnSize[i]/ 10) * 10;
580 break;
581 case NumberFormat::DATE:
582 nDataType = DataType::DATE;
583 break;
584 case NumberFormat::TIME:
585 nDataType = DataType::TIME;
586 break;
587 case NumberFormat::DATETIME:
588 nDataType = DataType::TIMESTAMP;
589 break;
590 case NumberFormat::CURRENCY:
591 nDataType = DataType::NUMERIC;
592 nScale = 4;
593 nLength = 19;
594 break;
595 case NumberFormat::NUMBER:
596 case NumberFormat::SCIENTIFIC:
597 case NumberFormat::FRACTION:
598 case NumberFormat::PERCENT:
599 nDataType = DataType::DOUBLE;
600 break;
601 case NumberFormat::TEXT:
602 case NumberFormat::UNDEFINED:
603 case NumberFormat::LOGICAL:
604 default:
605 nDataType = DataType::VARCHAR;
606 nLength = ((m_vColumnSize[i] % 10 ) ? m_vColumnSize[i]/ 10 + 1: m_vColumnSize[i]/ 10) * 10;
607 break;
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),
620 m_aLocale);
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())
642 sal_Int32 nPos = 0;
643 sal_Int32 nCount = 2;
644 while(m_aDestColumns.find(sName) != m_aDestColumns.end())
646 sName = aAlias;
647 sName += OUString::number(++nPos);
648 if(nMaxNameLen && sName.getLength() > nMaxNameLen)
650 aAlias = aAlias.copy(0,::std::min<sal_Int32>( nMaxNameLen-nCount, aAlias.getLength() ));
651 sName = aAlias;
652 sName += OUString::number(nPos);
653 ++nCount;
657 aAlias = sName;
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));
663 pField->SetScale(0);
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(
691 nullptr,
692 sTableName,
693 bHaveDefaultTable ? CopyTableOperation::AppendData : CopyTableOperation::CopyDefinitionAndData,
694 m_aDestColumns,
695 m_vDestVector,
696 m_xConnection,
697 m_xFormatter,
698 getTypeSelectionPageFactory(),
699 m_rInputStream,
700 m_xContext
703 bool bError = false;
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();
715 if(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();
726 break;
727 default:
728 bError = true; // there is no error but I have nothing more to do
731 else
732 bError = true;
734 if(!bError)
735 bError = !createRowSet();
737 catch( const SQLException&)
739 ::dbaui::showError( ::dbtools::SQLExceptionInfo( ::cppu::getCaughtException() ), aWizard.get(), m_xContext );
740 bError = true;
742 catch( const Exception& )
744 DBG_UNHANDLED_EXCEPTION();
747 return bError;
750 void ODatabaseExport::showErrorDialog(const ::com::sun::star::sdbc::SQLException& e)
752 if(!m_bDontAskAgain)
754 OUString aMsg(e.Message);
755 aMsg += "\n";
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;
761 else
762 m_bError = 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))
777 --nColPos;
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());
784 eraseTokens();
788 void ODatabaseExport::eraseTokens()
790 m_sTextToken.clear();
791 m_sNumToken.clear();
792 m_sValToken.clear();
795 void ODatabaseExport::ensureFormatter()
797 if ( !m_pFormatter )
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;
816 aSql += " ( ";
817 // set values and column names
818 OUString aValues(" VALUES ( ");
820 OUString aQuote;
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);
835 sal_Int32 i = 0;
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));
847 i = 1;
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;
855 aSql += ",";
856 aValues += "?,";
860 aSql = aSql.replaceAt(aSql.getLength()-1, 1, ")");
861 aValues = aValues.replaceAt(aValues.getLength()-1, 1, ")");
863 aSql += aValues;
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: */