LibreOffice Module dbaccess (master) 1
DExport.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20#include <DExport.hxx>
21#include <core_resource.hxx>
22
23#include <com/sun/star/sdbcx/XTablesSupplier.hpp>
24#include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
25#include <com/sun/star/sdbc/DataType.hpp>
26#include <com/sun/star/sdbc/ColumnValue.hpp>
27#include <com/sun/star/sdb/CommandType.hpp>
28#include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp>
29#include <com/sun/star/sdbc/XRow.hpp>
30#include <com/sun/star/uno/XComponentContext.hpp>
31#include <com/sun/star/util/NumberFormat.hpp>
32#include <com/sun/star/util/XNumberFormatTypes.hpp>
33#include <strings.hrc>
34#include <strings.hxx>
36#include <sal/log.hxx>
37#include <sfx2/sfxhtml.hxx>
38#include <svl/numuno.hxx>
40#include <TypeInfo.hxx>
41#include <FieldDescriptions.hxx>
42#include <UITools.hxx>
44#include <com/sun/star/awt/FontDescriptor.hpp>
45#include <WCopyTable.hxx>
47#include <svl/numformat.hxx>
50#include <com/sun/star/sdb/application/CopyTableOperation.hpp>
51#include <sqlmessage.hxx>
52#include "UpdateHelperImpl.hxx"
54
55using namespace dbaui;
56using namespace utl;
57using namespace ::com::sun::star::uno;
58using namespace ::com::sun::star::beans;
59using namespace ::com::sun::star::container;
60using namespace ::com::sun::star::util;
61using namespace ::com::sun::star::sdbc;
62using namespace ::com::sun::star::sdbcx;
63using namespace ::com::sun::star::sdb;
64using namespace ::com::sun::star::lang;
65using namespace ::com::sun::star::awt;
66
67namespace CopyTableOperation = ::com::sun::star::sdb::application::CopyTableOperation;
68
69// ODatabaseExport
70ODatabaseExport::ODatabaseExport(sal_Int32 nRows,
71 TPositions&&_rColumnPositions,
72 const Reference< XNumberFormatter >& _rxNumberF,
74 const TColumnVector* pList,
75 const OTypeInfoMap* _pInfoMap,
76 bool _bAutoIncrementEnabled,
77 SvStream& _rInputStream)
78 :m_vColumnPositions(std::move(_rColumnPositions))
79 ,m_aDestColumns(true)
80 ,m_xFormatter(_rxNumberF)
81 ,m_xContext(_rxContext)
82 ,m_pFormatter(nullptr)
83 ,m_rInputStream( _rInputStream )
84 ,m_pColumnList(pList)
85 ,m_pInfoMap(_pInfoMap)
86 ,m_nColumnPos(0)
87 ,m_nRows(1)
88 ,m_nRowCount(0)
89 ,m_bError(false)
90 ,m_bInTbl(false)
91 ,m_bHead(true)
92 ,m_bDontAskAgain(false)
93 ,m_bIsAutoIncrement(_bAutoIncrementEnabled)
94 ,m_bFoundTable(false)
95 ,m_bCheckOnly(false)
96 ,m_bAppendFirstLine(false)
97{
98 m_nRows += nRows;
99 sal_Int32 nCount = 0;
100 for(const std::pair<sal_Int32,sal_Int32> & rPair : m_vColumnPositions)
101 if ( rPair.first != COLUMN_POSITION_NOT_FOUND )
102 ++nCount;
103
104 m_vColumnSize.resize(nCount);
105 m_vNumberFormat.resize(nCount);
106 for(sal_Int32 i=0;i<nCount;++i)
107 {
108 m_vColumnSize[i] = 0;
109 m_vNumberFormat[i] = 0;
110 }
111
112 try
113 {
114 SvtSysLocale aSysLocale;
115 m_aLocale = aSysLocale.GetLanguageTag().getLocale();
116 }
117 catch(Exception&)
118 {
119 }
120
121 SetColumnTypes(pList,_pInfoMap);
122}
123
124ODatabaseExport::ODatabaseExport(const SharedConnection& _rxConnection,
125 const Reference< XNumberFormatter >& _rxNumberF,
127 SvStream& _rInputStream)
128 :m_aDestColumns(_rxConnection->getMetaData().is() && _rxConnection->getMetaData()->supportsMixedCaseQuotedIdentifiers())
129 ,m_xConnection(_rxConnection)
130 ,m_xFormatter(_rxNumberF)
131 ,m_xContext(_rxContext)
132 ,m_pFormatter(nullptr)
133 ,m_rInputStream( _rInputStream )
134 ,m_pColumnList(nullptr)
135 ,m_pInfoMap(nullptr)
136 ,m_nColumnPos(0)
137 ,m_nRows(1)
138 ,m_nRowCount(0)
139 ,m_bError(false)
140 ,m_bInTbl(false)
141 ,m_bHead(true)
142 ,m_bDontAskAgain(false)
143 ,m_bIsAutoIncrement(false)
144 ,m_bFoundTable(false)
145 ,m_bCheckOnly(false)
146 ,m_bAppendFirstLine(false)
147{
148 try
149 {
150 SvtSysLocale aSysLocale;
151 m_aLocale = aSysLocale.GetLanguageTag().getLocale();
152 }
153 catch(Exception&)
154 {
155 }
156
157 Reference<XTablesSupplier> xTablesSup(m_xConnection,UNO_QUERY);
158 if(xTablesSup.is())
159 m_xTables = xTablesSup->getTables();
160
161 Reference<XDatabaseMetaData> xMeta = m_xConnection->getMetaData();
162 Reference<XResultSet> xSet = xMeta.is() ? xMeta->getTypeInfo() : Reference<XResultSet>();
163 if(xSet.is())
164 {
166 std::vector<sal_Int32> aTypes;
167 std::vector<bool> aNullable;
168 Reference<XResultSetMetaData> xResultSetMetaData = Reference<XResultSetMetaDataSupplier>(xSet,UNO_QUERY_THROW)->getMetaData();
169 Reference<XRow> xRow(xSet,UNO_QUERY_THROW);
170 while(xSet->next())
171 {
172 if ( aTypes.empty() )
173 {
174 sal_Int32 nCount = xResultSetMetaData->getColumnCount();
175 if ( nCount < 1 )
176 nCount = 18;
177 aTypes.reserve(nCount+1);
178 aNullable.reserve(nCount+1);
179 aTypes.push_back(-1);
180 aNullable.push_back(false);
181 for (sal_Int32 j = 1; j <= nCount ; ++j)
182 {
183 aNullable.push_back(xResultSetMetaData->isNullable(j) != ColumnValue::NO_NULLS );
184 aTypes.push_back(xResultSetMetaData->getColumnType(j));
185 }
186 }
187
188 sal_Int32 nPos = 1;
189 OSL_ENSURE((nPos) < static_cast<sal_Int32>(aTypes.size()),"aTypes: Illegal index for vector");
190 aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
191 OUString sTypeName = aValue.getString();
192 ++nPos;
193 OSL_ENSURE((nPos) < static_cast<sal_Int32>(aTypes.size()),"aTypes: Illegal index for vector");
194 aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
195 sal_Int32 nType = aValue.getInt32();
196 ++nPos;
197
198 if( nType == DataType::VARCHAR )
199 {
200 m_pTypeInfo = std::make_shared<OTypeInfo>();
201
202 m_pTypeInfo->aTypeName = sTypeName;
203 m_pTypeInfo->nType = nType;
204
205 OSL_ENSURE((nPos) < static_cast<sal_Int32>(aTypes.size()),"aTypes: Illegal index for vector");
206 aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
207 m_pTypeInfo->nPrecision = aValue.getInt32();
208 ++nPos;
209 aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow); //LiteralPrefix
210 ++nPos;
211 aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow); //LiteralSuffix
212 ++nPos;
213 aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
214 m_pTypeInfo->aCreateParams = aValue.getString();
215 ++nPos;
216 aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
217 m_pTypeInfo->bNullable = aValue.getInt32() == ColumnValue::NULLABLE;
218 ++nPos;
219 aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
220 // bCaseSensitive
221 ++nPos;
222 aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
223 m_pTypeInfo->nSearchType = aValue.getInt16();
224 ++nPos;
225 aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
226 // bUnsigned
227 ++nPos;
228 aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
229 m_pTypeInfo->bCurrency = aValue.getBool();
230 ++nPos;
231 aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
232 m_pTypeInfo->bAutoIncrement = aValue.getBool();
233 ++nPos;
234 aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
235 m_pTypeInfo->aLocalTypeName = aValue.getString();
236 ++nPos;
237 aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
238 m_pTypeInfo->nMinimumScale = aValue.getInt16();
239 ++nPos;
240 aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
241 m_pTypeInfo->nMaximumScale = aValue.getInt16();
242 nPos = 18;
243 aValue.fill(nPos,aTypes[nPos],xRow);
244 m_pTypeInfo->nNumPrecRadix = aValue.getInt32();
245
246 // check if values are less than zero like it happens in a oracle jdbc driver
247 if( m_pTypeInfo->nPrecision < 0)
248 m_pTypeInfo->nPrecision = 0;
249 if( m_pTypeInfo->nMinimumScale < 0)
250 m_pTypeInfo->nMinimumScale = 0;
251 if( m_pTypeInfo->nMaximumScale < 0)
252 m_pTypeInfo->nMaximumScale = 0;
253 if( m_pTypeInfo->nNumPrecRadix <= 1)
254 m_pTypeInfo->nNumPrecRadix = 10;
255 break;
256 }
257 }
258 }
259 if ( !m_pTypeInfo )
260 m_pTypeInfo = std::make_shared<OTypeInfo>();
261}
262
263ODatabaseExport::~ODatabaseExport()
264{
265 m_pFormatter = nullptr;
266 for (auto const& destColumn : m_aDestColumns)
267 delete destColumn.second;
268 m_vDestVector.clear();
269 m_aDestColumns.clear();
270}
271
273{
274 if(m_nColumnPos >= sal_Int32(m_vDestVector.size()))
275 return;
276
278 if(!pField)
279 return;
280
281 sal_Int32 nNewPos = m_bIsAutoIncrement ? m_nColumnPos+1 : m_nColumnPos;
282 OSL_ENSURE(nNewPos < static_cast<sal_Int32>(m_vColumnPositions.size()),"m_vColumnPositions: Illegal index for vector");
283
284 if ( nNewPos < static_cast<sal_Int32>(m_vColumnPositions.size() ) )
285 {
286 sal_Int32 nPos = m_vColumnPositions[nNewPos].first;
288 {
289 if ( m_sTextToken.isEmpty() && pField->IsNullable() )
290 m_pUpdateHelper->updateNull(nPos,pField->GetType());
291 else
292 {
293 OSL_ENSURE((nNewPos) < static_cast<sal_Int32>(m_vColumnTypes.size()),"Illegal index for vector");
294 if (m_vColumnTypes[nNewPos] != DataType::VARCHAR && m_vColumnTypes[nNewPos] != DataType::CHAR && m_vColumnTypes[nNewPos] != DataType::LONGVARCHAR )
295 {
296 SAL_INFO("dbaccess.ui", "ODatabaseExport::insertValueIntoColumn != DataType::VARCHAR" );
298 sal_Int32 nNumberFormat = 0;
299 double fOutNumber = 0.0;
300 bool bNumberFormatError = false;
301 if ( m_pFormatter && !m_sNumToken.isEmpty() )
302 {
303 LanguageType eNumLang = LANGUAGE_NONE;
304 sal_uInt32 nNumberFormat2( nNumberFormat );
306 if ( eNumLang != LANGUAGE_NONE )
307 {
308 nNumberFormat2 = m_pFormatter->GetFormatForLanguageIfBuiltIn( nNumberFormat2, eNumLang );
309 (void)m_pFormatter->IsNumberFormat( m_sTextToken, nNumberFormat2, fOutNumber );
310 }
311 nNumberFormat = static_cast<sal_Int32>(nNumberFormat2);
312 }
313 else
314 {
315 Reference< XNumberFormatsSupplier > xSupplier = m_xFormatter->getNumberFormatsSupplier();
316 Reference<XNumberFormatTypes> xNumType(xSupplier->getNumberFormats(),UNO_QUERY);
317 const sal_Int16 nFormats[] = {
318 NumberFormat::DATETIME
319 ,NumberFormat::DATE
320 ,NumberFormat::TIME
321 ,NumberFormat::CURRENCY
322 ,NumberFormat::NUMBER
323 ,NumberFormat::LOGICAL
324 };
325 for (short nFormat : nFormats)
326 {
327 try
328 {
329 nNumberFormat = m_xFormatter->detectNumberFormat(xNumType->getStandardFormat(nFormat,m_aLocale),m_sTextToken);
330 break;
331 }
332 catch(Exception&)
333 {
334 }
335 }
336 try
337 {
338 fOutNumber = m_xFormatter->convertStringToNumber(nNumberFormat,m_sTextToken);
339 }
340 catch(Exception&)
341 {
342 bNumberFormatError = true;
343 m_pUpdateHelper->updateString(nPos,m_sTextToken);
344 }
345 }
346 if ( !bNumberFormatError )
347 {
348 try
349 {
350 Reference< XNumberFormatsSupplier > xSupplier = m_xFormatter->getNumberFormatsSupplier();
351 Reference< XNumberFormats > xFormats = xSupplier->getNumberFormats();
352 Reference<XPropertySet> xProp = xFormats->getByKey(nNumberFormat);
353 sal_Int16 nType = 0;
354 xProp->getPropertyValue(PROPERTY_TYPE) >>= nType;
355 switch(nType)
356 {
357 case NumberFormat::DATE:
358 m_pUpdateHelper->updateDate(nPos,::dbtools::DBTypeConversion::toDate(fOutNumber,m_aNullDate));
359 break;
360 case NumberFormat::DATETIME:
361 m_pUpdateHelper->updateTimestamp(nPos,::dbtools::DBTypeConversion::toDateTime(fOutNumber,m_aNullDate));
362 break;
363 case NumberFormat::TIME:
364 m_pUpdateHelper->updateTime(nPos,::dbtools::DBTypeConversion::toTime(fOutNumber));
365 break;
366 default:
367 m_pUpdateHelper->updateDouble(nPos,fOutNumber);
368 }
369 }
370 catch(Exception&)
371 {
372 m_pUpdateHelper->updateString(nPos,m_sTextToken);
373 }
374 }
375
376 }
377 else
378 m_pUpdateHelper->updateString(nPos,m_sTextToken);
379 }
380 }
381 }
382 eraseTokens();
383}
384
385sal_Int16 ODatabaseExport::CheckString(const OUString& aCheckToken, sal_Int16 _nOldNumberFormat)
386{
387 sal_Int16 nNumberFormat = 0;
388
389 try
390 {
391 Reference< XNumberFormatsSupplier > xSupplier = m_xFormatter->getNumberFormatsSupplier();
392 Reference< XNumberFormats > xFormats = xSupplier->getNumberFormats();
393
395 if ( m_pFormatter && !m_sNumToken.isEmpty() )
396 {
397 LanguageType eNumLang;
398 sal_uInt32 nFormatKey(0);
399 double fOutNumber = SfxHTMLParser::GetTableDataOptionsValNum(nFormatKey,eNumLang,m_sTextToken,m_sNumToken,*m_pFormatter);
400 if ( eNumLang != LANGUAGE_NONE )
401 {
402 nFormatKey = m_pFormatter->GetFormatForLanguageIfBuiltIn( nFormatKey, eNumLang );
403 if ( !m_pFormatter->IsNumberFormat( m_sTextToken, nFormatKey, fOutNumber ) )
404 return NumberFormat::TEXT;
405 }
406 Reference<XPropertySet> xProp = xFormats->getByKey(nFormatKey);
407 xProp->getPropertyValue(PROPERTY_TYPE) >>= nNumberFormat;
408 }
409 else
410 {
411 Reference<XNumberFormatTypes> xNumType(xFormats,UNO_QUERY);
412 sal_Int32 nFormatKey = m_xFormatter->detectNumberFormat(xNumType->getStandardFormat(NumberFormat::ALL,m_aLocale),aCheckToken);
413 m_xFormatter->convertStringToNumber(nFormatKey,aCheckToken);
414
415 Reference<XPropertySet> xProp = xFormats->getByKey(nFormatKey);
416 sal_Int16 nType = 0;
417 xProp->getPropertyValue(PROPERTY_TYPE) >>= nType;
418
419 switch(nType)
420 {
421 case NumberFormat::ALL:
422 nNumberFormat = NumberFormat::ALL;
423 break;
424 case NumberFormat::DEFINED:
425 nNumberFormat = NumberFormat::TEXT;
426 break;
427 case NumberFormat::DATE:
428 switch(_nOldNumberFormat)
429 {
430 case NumberFormat::DATETIME:
431 case NumberFormat::TEXT:
432 case NumberFormat::DATE:
433 nNumberFormat = _nOldNumberFormat;
434 break;
435 case NumberFormat::ALL:
436 nNumberFormat = NumberFormat::DATE;
437 break;
438 default:
439 nNumberFormat = NumberFormat::TEXT;
440
441 }
442 break;
443 case NumberFormat::TIME:
444 switch(_nOldNumberFormat)
445 {
446 case NumberFormat::DATETIME:
447 case NumberFormat::TEXT:
448 case NumberFormat::TIME:
449 nNumberFormat = _nOldNumberFormat;
450 break;
451 case NumberFormat::ALL:
452 nNumberFormat = NumberFormat::TIME;
453 break;
454 default:
455 nNumberFormat = NumberFormat::TEXT;
456 break;
457 }
458 break;
459 case NumberFormat::CURRENCY:
460 switch(_nOldNumberFormat)
461 {
462 case NumberFormat::NUMBER:
463 nNumberFormat = NumberFormat::CURRENCY;
464 break;
465 case NumberFormat::CURRENCY:
466 nNumberFormat = _nOldNumberFormat;
467 break;
468 case NumberFormat::ALL:
469 nNumberFormat = NumberFormat::CURRENCY;
470 break;
471 default:
472 nNumberFormat = NumberFormat::TEXT;
473 break;
474 }
475 break;
476 case NumberFormat::NUMBER:
477 case NumberFormat::SCIENTIFIC:
478 case NumberFormat::FRACTION:
479 case NumberFormat::PERCENT:
480 switch(_nOldNumberFormat)
481 {
482 case NumberFormat::NUMBER:
483 nNumberFormat = _nOldNumberFormat;
484 break;
485 case NumberFormat::CURRENCY:
486 nNumberFormat = NumberFormat::CURRENCY;
487 break;
488 case NumberFormat::ALL:
489 nNumberFormat = nType;
490 break;
491 default:
492 nNumberFormat = NumberFormat::TEXT;
493 break;
494 }
495 break;
496 case NumberFormat::TEXT:
497 case NumberFormat::UNDEFINED:
498 case NumberFormat::LOGICAL:
499 nNumberFormat = NumberFormat::TEXT; // Text overwrites everything
500 break;
501 case NumberFormat::DATETIME:
502 switch(_nOldNumberFormat)
503 {
504 case NumberFormat::DATETIME:
505 case NumberFormat::TEXT:
506 case NumberFormat::TIME:
507 nNumberFormat = _nOldNumberFormat;
508 break;
509 case NumberFormat::ALL:
510 nNumberFormat = NumberFormat::DATETIME;
511 break;
512 default:
513 nNumberFormat = NumberFormat::TEXT;
514 break;
515 }
516 break;
517 default:
518 SAL_WARN("dbaccess.ui", "ODatabaseExport: Unknown NumberFormat");
519 }
520 }
521 }
522 catch(Exception&)
523 {
524 nNumberFormat = NumberFormat::TEXT; // Text overwrites everything
525 }
526
527 return nNumberFormat;
528}
529
531{
532 if(!(_pList && _pInfoMap))
533 return;
534
535 OSL_ENSURE(m_vNumberFormat.size() == m_vColumnSize.size() && m_vColumnSize.size() == _pList->size(),"Illegal columns in list");
536 Reference< XNumberFormatsSupplier > xSupplier = m_xFormatter->getNumberFormatsSupplier();
537 Reference< XNumberFormats > xFormats = xSupplier->getNumberFormats();
538 sal_Int32 minBothSize = std::min<sal_Int32>(m_vNumberFormat.size(), m_vColumnSize.size());
539 sal_Int32 i = 0;
540 for (auto const& elem : *_pList)
541 {
542 if (i >= minBothSize)
543 break;
544
545 sal_Int32 nDataType;
546 sal_Int32 nLength(0),nScale(0);
547 sal_Int16 nType = m_vNumberFormat[i] & ~NumberFormat::DEFINED;
548
549 switch ( nType )
550 {
551 case NumberFormat::ALL:
552 nDataType = DataType::DOUBLE;
553 break;
554 case NumberFormat::DEFINED:
555 nDataType = DataType::VARCHAR;
556 nLength = ((m_vColumnSize[i] % 10 ) ? m_vColumnSize[i]/ 10 + 1: m_vColumnSize[i]/ 10) * 10;
557 break;
558 case NumberFormat::DATE:
559 nDataType = DataType::DATE;
560 break;
561 case NumberFormat::TIME:
562 nDataType = DataType::TIME;
563 break;
564 case NumberFormat::DATETIME:
565 nDataType = DataType::TIMESTAMP;
566 break;
567 case NumberFormat::CURRENCY:
568 nDataType = DataType::NUMERIC;
569 nScale = 4;
570 nLength = 19;
571 break;
572 case NumberFormat::NUMBER:
573 case NumberFormat::SCIENTIFIC:
574 case NumberFormat::FRACTION:
575 case NumberFormat::PERCENT:
576 nDataType = DataType::DOUBLE;
577 break;
578 case NumberFormat::TEXT:
579 case NumberFormat::UNDEFINED:
580 case NumberFormat::LOGICAL:
581 default:
582 nDataType = DataType::VARCHAR;
583 nLength = ((m_vColumnSize[i] % 10 ) ? m_vColumnSize[i]/ 10 + 1: m_vColumnSize[i]/ 10) * 10;
584 break;
585 }
586 OTypeInfoMap::const_iterator aFind = _pInfoMap->find(nDataType);
587 if(aFind != _pInfoMap->end())
588 {
589 elem->second->SetType(aFind->second);
590 elem->second->SetPrecision(std::min<sal_Int32>(aFind->second->nPrecision,nLength));
591 elem->second->SetScale(std::min<sal_Int32>(aFind->second->nMaximumScale,nScale));
592
593 sal_Int32 nFormatKey = ::dbtools::getDefaultNumberFormat( nDataType,
594 elem->second->GetScale(),
595 elem->second->IsCurrency(),
596 Reference< XNumberFormatTypes>(xFormats,UNO_QUERY),
597 m_aLocale);
598
599 elem->second->SetFormatKey(nFormatKey);
600 }
601 ++i;
602 }
603}
604
605void ODatabaseExport::CreateDefaultColumn(const OUString& _rColumnName)
606{
607 Reference< XDatabaseMetaData> xDestMetaData(m_xConnection->getMetaData());
608 sal_Int32 nMaxNameLen(xDestMetaData->getMaxColumnNameLength());
609 OUString aAlias = _rColumnName;
611 aAlias = ::dbtools::convertName2SQLName(_rColumnName,xDestMetaData->getExtraNameCharacters());
612
613 if(nMaxNameLen && aAlias.getLength() > nMaxNameLen)
614 aAlias = aAlias.copy(0, std::min<sal_Int32>( nMaxNameLen-1, aAlias.getLength() ) );
615
616 OUString sName(aAlias);
617 if(m_aDestColumns.find(sName) != m_aDestColumns.end())
618 {
619 sal_Int32 nPos = 0;
620 sal_Int32 nCount = 2;
621 while(m_aDestColumns.find(sName) != m_aDestColumns.end())
622 {
623 sName = aAlias
624 + OUString::number(++nPos);
625 if(nMaxNameLen && sName.getLength() > nMaxNameLen)
626 {
627 aAlias = aAlias.copy(0,std::min<sal_Int32>( nMaxNameLen-nCount, aAlias.getLength() ));
628 sName = aAlias
629 + OUString::number(nPos);
630 ++nCount;
631 }
632 }
633 }
634 aAlias = sName;
635 // now create a column
636 OFieldDescription* pField = new OFieldDescription();
637 pField->SetType(m_pTypeInfo);
638 pField->SetName(aAlias);
639 pField->SetPrecision(std::min<sal_Int32>(sal_Int32(255),m_pTypeInfo->nPrecision));
640 pField->SetScale(0);
641 pField->SetIsNullable(ColumnValue::NULLABLE);
642 pField->SetAutoIncrement(false);
643 pField->SetPrimaryKey(false);
644 pField->SetCurrency(false);
645
646 TColumns::const_iterator aFind = m_aDestColumns.find( aAlias );
647 if ( aFind != m_aDestColumns.end() )
648 {
649 delete aFind->second;
650 m_aDestColumns.erase(aFind);
651 }
652
653 m_vDestVector.emplace_back(m_aDestColumns.emplace(aAlias,pField).first);
654}
655
657{
658 m_pUpdateHelper = std::make_shared<OParameterUpdateHelper>(createPreparedStatement(m_xConnection->getMetaData(),m_xTable,m_vColumnPositions));
659}
660
661bool ODatabaseExport::executeWizard(const OUString& _rTableName, const Any& _aTextColor, const FontDescriptor& _rFont)
662{
663 bool bHaveDefaultTable = !m_sDefaultTableName.isEmpty();
664 OUString sTableName( bHaveDefaultTable ? m_sDefaultTableName : _rTableName );
665 OCopyTableWizard aWizard(
666 nullptr,
667 sTableName,
668 bHaveDefaultTable ? CopyTableOperation::AppendData : CopyTableOperation::CopyDefinitionAndData,
676 );
677
678 bool bError = false;
679 try
680 {
681 if (aWizard.run())
682 {
683 switch(aWizard.getOperation())
684 {
685 case CopyTableOperation::CopyDefinitionAndData:
686 case CopyTableOperation::AppendData:
687 {
688 m_xTable = aWizard.returnTable();
689 bError = !m_xTable.is();
690 if(m_xTable.is())
691 {
692 m_xTable->setPropertyValue(PROPERTY_FONT,Any(_rFont));
693 if(_aTextColor.hasValue())
694 m_xTable->setPropertyValue(PROPERTY_TEXTCOLOR,_aTextColor);
695 }
698 m_vColumnTypes = aWizard.GetColumnTypes();
700 }
701 break;
702 default:
703 bError = true; // there is no error but I have nothing more to do
704 }
705 }
706 else
707 bError = true;
708
709 if(!bError)
710 createRowSet();
711 }
712 catch( const SQLException&)
713 {
714 ::dbtools::showError( ::dbtools::SQLExceptionInfo( ::cppu::getCaughtException() ), aWizard.getDialog()->GetXWindow(), m_xContext );
715 bError = true;
716 }
717 catch( const Exception& )
718 {
719 DBG_UNHANDLED_EXCEPTION("dbaccess");
720 }
721
722 return bError;
723}
724
725void ODatabaseExport::showErrorDialog(const css::sdbc::SQLException& e)
726{
727 if(!m_bDontAskAgain)
728 {
729 OUString aMsg = e.Message
730 + "\n"
731 + DBA_RES( STR_QRY_CONTINUE );
733
734 if (aBox.run() == RET_YES)
735 m_bDontAskAgain = true;
736 else
737 m_bError = true;
738 }
739}
740
742{
743 if ( m_sTextToken.isEmpty() )
744 return;
745
746 sal_Int32 nNewPos = m_bIsAutoIncrement ? m_nColumnPos+1 : m_nColumnPos;
747 OSL_ENSURE(nNewPos < static_cast<sal_Int32>(m_vColumnPositions.size()),"Illegal index for vector");
748 if ( nNewPos < static_cast<sal_Int32>(m_vColumnPositions.size()) )
749 {
750 sal_Int32 nColPos = m_vColumnPositions[nNewPos].first;
751 if( nColPos != COLUMN_POSITION_NOT_FOUND)
752 {
753 --nColPos;
754 OSL_ENSURE((nColPos) < static_cast<sal_Int32>(m_vNumberFormat.size()),"m_vFormatKey: Illegal index for vector");
755 OSL_ENSURE((nColPos) < static_cast<sal_Int32>(m_vColumnSize.size()),"m_vColumnSize: Illegal index for vector");
757 m_vColumnSize[nColPos] = std::max<sal_Int32>(static_cast<sal_Int32>(m_vColumnSize[nColPos]), m_sTextToken.getLength());
758 }
759 }
760 eraseTokens();
761}
762
764{
765 m_sTextToken.clear();
766 m_sNumToken.clear();
767}
768
770{
771 if ( !m_pFormatter )
772 {
773 Reference< XNumberFormatsSupplier > xSupplier = m_xFormatter->getNumberFormatsSupplier();
774 auto pSupplierImpl = comphelper::getFromUnoTunnel<SvNumberFormatsSupplierObj>(xSupplier);
775 m_pFormatter = pSupplierImpl ? pSupplierImpl->GetNumberFormatter() : nullptr;
776 Reference<XPropertySet> xNumberFormatSettings = xSupplier->getNumberFormatSettings();
777 xNumberFormatSettings->getPropertyValue("NullDate") >>= m_aNullDate;
778 }
779}
780
782 ,const Reference<XPropertySet>& _xDestTable
783 ,const TPositions& _rvColumns)
784{
785 OUString sComposedTableName = ::dbtools::composeTableName( _xMetaData, _xDestTable, ::dbtools::EComposeRule::InDataManipulation, true );
786
787 OUStringBuffer aSql = "INSERT INTO "
788 + sComposedTableName
789 + " ( ";
790
791 // set values and column names
792 OUStringBuffer aValues(" VALUES ( ");
793
794 OUString aQuote;
795 if ( _xMetaData.is() )
796 aQuote = _xMetaData->getIdentifierQuoteString();
797
798 Reference<XColumnsSupplier> xDestColsSup(_xDestTable,UNO_QUERY_THROW);
799
800 // create sql string and set column types
801 Sequence< OUString> aDestColumnNames = xDestColsSup->getColumns()->getElementNames();
802 if ( !aDestColumnNames.hasElements() )
803 {
805 }
806 const OUString* pIter = aDestColumnNames.getConstArray();
807 std::vector< OUString> aInsertList;
808 aInsertList.resize(aDestColumnNames.getLength()+1);
809 for(size_t j=0; j < aInsertList.size(); ++j)
810 {
811 ODatabaseExport::TPositions::const_iterator aFind = std::find_if(_rvColumns.begin(),_rvColumns.end(),
812 [j] (const ODatabaseExport::TPositions::value_type& tPos)
813 { return tPos.second == static_cast<sal_Int32>(j+1); });
814 if ( _rvColumns.end() != aFind && aFind->second != COLUMN_POSITION_NOT_FOUND && aFind->first != COLUMN_POSITION_NOT_FOUND )
815 {
816 OSL_ENSURE((aFind->first) < static_cast<sal_Int32>(aInsertList.size()),"aInsertList: Illegal index for vector");
817 aInsertList[aFind->first] = ::dbtools::quoteName( aQuote,*(pIter+j));
818 }
819 }
820
821 // create the sql string
822 for (auto const& elem : aInsertList)
823 {
824 if ( !elem.isEmpty() )
825 {
826 aSql.append(elem + ",");
827 aValues.append("?,");
828 }
829 }
830
831 aSql[aSql.getLength()-1] = ')';
832 aValues[aValues.getLength()-1] = ')';
833
834 aSql.append(aValues);
835 // now create,fill and execute the prepared statement
836 return _xMetaData->getConnection()->prepareStatement(aSql.makeStringAndClear());
837}
838
839/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
#define COLUMN_POSITION_NOT_FOUND
Definition: DExport.hxx:48
sal_Int32 nDataType
OptionalString sName
bool m_bError
const css::lang::Locale & getLocale(bool bResolveSystem=true) const
static double GetTableDataOptionsValNum(sal_uInt32 &nNumForm, LanguageType &eNumLang, const OUString &aValStr, std::u16string_view aNumStr, SvNumberFormatter &rFormatter)
sal_uInt32 GetFormatForLanguageIfBuiltIn(sal_uInt32 nFormat, LanguageType eLnge=LANGUAGE_DONTKNOW)
bool IsNumberFormat(const OUString &sString, sal_uInt32 &F_Index, double &fOutNumber, SvNumInputOptions eInputOptions=SvNumInputOptions::NONE)
const LanguageTag & GetLanguageTag() const
sal_Int32 getInt32() const
OUString getString() const
sal_Int16 getInt16() const
void fill(sal_Int32 _nPos, sal_Int32 _nType, const css::uno::Reference< css::sdbc::XRow > &_xRow)
sal_Int16 getOperation() const
Definition: WCopyTable.hxx:394
const ODatabaseExport::TPositions & GetColumnPositions() const
Definition: WCopyTable.hxx:334
css::uno::Reference< css::beans::XPropertySet > returnTable()
const std::vector< sal_Int32 > & GetColumnTypes() const
Definition: WCopyTable.hxx:335
bool shouldCreatePrimaryKey() const
returns whether a primary key should be created in the target database
Definition: WCopyTable.hxx:353
bool UseHeaderLine() const
Definition: WCopyTable.hxx:336
SvNumberFormatter * m_pFormatter
Definition: DExport.hxx:80
sal_Int16 CheckString(const OUString &aToken, sal_Int16 _nOldNumberFormat)
Definition: DExport.cxx:385
TColumns m_aDestColumns
container for new created columns
Definition: DExport.hxx:68
OUString m_sDefaultTableName
for saving the selected tablename
Definition: DExport.hxx:83
std::map< OUString, OFieldDescription *, ::comphelper::UStringMixLess > TColumns
Definition: DExport.hxx:57
static css::uno::Reference< css::sdbc::XPreparedStatement > createPreparedStatement(const css::uno::Reference< css::sdbc::XDatabaseMetaData > &_xMetaData, const css::uno::Reference< css::beans::XPropertySet > &_xDestTable, const TPositions &_rvColumnPositions)
Definition: DExport.cxx:781
OUString m_sTextToken
cell content
Definition: DExport.hxx:85
void CreateDefaultColumn(const OUString &_rColumnName)
Definition: DExport.cxx:605
TColumnVector m_vDestVector
Definition: DExport.hxx:69
bool m_bDontAskAgain
if there is an error when pasting, don't show it again
Definition: DExport.hxx:96
css::uno::Reference< css::util::XNumberFormatter > m_xFormatter
a number formatter working with the connection's NumberFormatsSupplier
Definition: DExport.hxx:76
bool m_bError
error and termination code
Definition: DExport.hxx:93
css::uno::Reference< css::uno::XComponentContext > m_xContext
Definition: DExport.hxx:77
std::vector< sal_Int16 > m_vNumberFormat
Definition: DExport.hxx:65
std::vector< std::pair< sal_Int32, sal_Int32 > > TPositions
Definition: DExport.hxx:59
std::shared_ptr< IUpdateHelper > m_pUpdateHelper
Definition: DExport.hxx:75
std::vector< sal_Int32 > m_vColumnSize
Definition: DExport.hxx:64
sal_Int32 m_nColumnPos
current column position
Definition: DExport.hxx:90
css::util::Date m_aNullDate
Definition: DExport.hxx:78
OUString m_sNumToken
SDNUM value.
Definition: DExport.hxx:86
css::uno::Reference< css::beans::XPropertySet > m_xTable
dest table
Definition: DExport.hxx:71
bool executeWizard(const OUString &_sTableName, const css::uno::Any &_aTextColor, const css::awt::FontDescriptor &_rFont)
executeWizard calls a wizard to create/append data
Definition: DExport.cxx:661
bool m_bIsAutoIncrement
if PKey is set by user
Definition: DExport.hxx:97
void showErrorDialog(const css::sdbc::SQLException &e)
Definition: DExport.cxx:725
css::lang::Locale m_aLocale
Definition: DExport.hxx:66
virtual TypeSelectionPageFactory getTypeSelectionPageFactory()=0
void SetColumnTypes(const TColumnVector *rList, const OTypeInfoMap *_pInfoMap)
Definition: DExport.cxx:530
std::vector< sal_Int32 > m_vColumnTypes
ColumnTypes for faster access.
Definition: DExport.hxx:63
TOTypeInfoSP m_pTypeInfo
contains the default type
Definition: DExport.hxx:87
void insertValueIntoColumn()
Definition: DExport.cxx:272
std::vector< TColumns::const_iterator > TColumnVector
Definition: DExport.hxx:58
SvStream & m_rInputStream
Definition: DExport.hxx:81
TPositions m_vColumnPositions
columns to be used
Definition: DExport.hxx:62
SharedConnection m_xConnection
dest conn
Definition: DExport.hxx:73
void SetPrecision(sal_Int32 _rPrecision)
void SetIsNullable(sal_Int32 _rIsNullable)
void SetPrimaryKey(bool _bPKey)
void SetType(const TOTypeInfoSP &_pType)
void SetAutoIncrement(bool _bAuto)
void SetName(const OUString &_rName)
void SetCurrency(bool _bIsCurrency)
void SetScale(sal_Int32 _rScale)
virtual Dialog * getDialog() override
virtual short run()
virtual css::uno::Reference< css::awt::XWindow > GetXWindow()=0
Reference< XComponentContext > m_xContext
#define DBA_RES(id)
int nCount
#define DBG_UNHANDLED_EXCEPTION(...)
#define LANGUAGE_NONE
sal_uInt16 nPos
#define SAL_WARN(area, stream)
#define SAL_INFO(area, stream)
@ Exception
std::multimap< DataTypeEnum, OExtendedTypeInfo * > OTypeInfoMap
std::multimap< sal_Int32, TOTypeInfoSP > OTypeInfoMap
Definition: TypeInfo.hxx:100
bool isSQL92CheckEnabled(const css::uno::Reference< css::sdbc::XConnection > &_xConnection)
check if SQL92 name checking is enabled
int i
Reference< XConnection > m_xConnection
Definition: objectnames.cxx:79
QPRO_FUNC_TYPE nType
std::locale m_aLocale
constexpr OUStringLiteral PROPERTY_TEXTCOLOR(u"TextColor")
constexpr OUStringLiteral PROPERTY_FONT(u"FontDescriptor")
constexpr OUStringLiteral PROPERTY_TYPE(u"Type")
RET_YES
const SvXMLTokenMapEntry aTypes[]
sal_Int32 nLength