1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_dbui.hxx"
26
27 #include "DExport.hxx"
28 #include "moduledbu.hxx"
29
30 #include <com/sun/star/sdbcx/XTablesSupplier.hpp>
31 #include <com/sun/star/sdbcx/XDataDescriptorFactory.hpp>
32 #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
33 #include <com/sun/star/sdbcx/XAppend.hpp>
34 #include <com/sun/star/sdbcx/KeyType.hpp>
35 #include <com/sun/star/sdbc/DataType.hpp>
36 #include <com/sun/star/sdbc/ColumnValue.hpp>
37 #include <com/sun/star/sdb/CommandType.hpp>
38 #include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp>
39 #include <com/sun/star/sdbc/XRow.hpp>
40 #include <com/sun/star/util/NumberFormat.hpp>
41 #include <com/sun/star/util/XNumberFormatTypes.hpp>
42 #include "dbustrings.hrc"
43 #include "dbu_misc.hrc"
44 #include <connectivity/dbconversion.hxx>
45 #include <sfx2/sfxhtml.hxx>
46 #include <svl/numuno.hxx>
47 #include <connectivity/dbtools.hxx>
48 #include <comphelper/extract.hxx>
49 #include "TypeInfo.hxx"
50 #include "FieldDescriptions.hxx"
51 #include "UITools.hxx"
52 #include <unotools/configmgr.hxx>
53 #include <memory>
54 #include <tools/debug.hxx>
55 #include <tools/diagnose_ex.h>
56 #include <i18npool/mslangid.hxx>
57 #include <com/sun/star/awt/FontDescriptor.hpp>
58 #include "WCopyTable.hxx"
59 #include "WExtendPages.hxx"
60 #include "WCPage.hxx"
61 #include <unotools/syslocale.hxx>
62 #include <svl/zforlist.hxx>
63 #include <connectivity/dbexception.hxx>
64 #include <connectivity/FValue.hxx>
65 #include <com/sun/star/sdbc/SQLWarning.hpp>
66 #include <com/sun/star/sdb/SQLContext.hpp>
67 #include <com/sun/star/sdb/application/CopyTableOperation.hpp>
68 #include "sqlmessage.hxx"
69 #include "UpdateHelperImpl.hxx"
70 #include <vcl/msgbox.hxx>
71 #include <cppuhelper/exc_hlp.hxx>
72 #include <rtl/logfile.hxx>
73
74 using namespace dbaui;
75 using namespace utl;
76 using namespace ::com::sun::star::uno;
77 using namespace ::com::sun::star::beans;
78 using namespace ::com::sun::star::container;
79 using namespace ::com::sun::star::util;
80 using namespace ::com::sun::star::sdbc;
81 using namespace ::com::sun::star::sdbcx;
82 using namespace ::com::sun::star::sdb;
83 using namespace ::com::sun::star::lang;
84 using namespace ::com::sun::star::awt;
85
86 namespace CopyTableOperation = ::com::sun::star::sdb::application::CopyTableOperation;
87
88 // ==========================================================================
89 // ODatabaseExport
90 // ==========================================================================
DBG_NAME(ODatabaseExport)91 DBG_NAME(ODatabaseExport)
92 ODatabaseExport::ODatabaseExport(sal_Int32 nRows,
93 const TPositions &_rColumnPositions,
94 const Reference< XNumberFormatter >& _rxNumberF,
95 const Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rM,
96 const TColumnVector* pList,
97 const OTypeInfoMap* _pInfoMap,
98 sal_Bool _bAutoIncrementEnabled,
99 SvStream& _rInputStream)
100 :m_vColumns(_rColumnPositions)
101 ,m_aDestColumns(sal_True)
102 ,m_xFormatter(_rxNumberF)
103 ,m_xFactory(_rM)
104 ,m_pFormatter(NULL)
105 ,m_rInputStream( _rInputStream )
106 ,m_pTypeInfo()
107 ,m_pColumnList(pList)
108 ,m_pInfoMap(_pInfoMap)
109 ,m_nColumnPos(0)
110 ,m_nRows(1)
111 ,m_nRowCount(0)
112 ,m_nDefToken( gsl_getSystemTextEncoding() )
113 ,m_bError(sal_False)
114 ,m_bInTbl(sal_False)
115 ,m_bHead(sal_True)
116 ,m_bDontAskAgain(sal_False)
117 ,m_bIsAutoIncrement(_bAutoIncrementEnabled)
118 ,m_bFoundTable(sal_False)
119 ,m_bCheckOnly(sal_False)
120 ,m_bAppendFirstLine(false)
121 {
122 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "misc", "Ocke.Janssen@sun.com", "ODatabaseExport::ODatabaseExport" );
123 DBG_CTOR(ODatabaseExport,NULL);
124
125 m_nRows += nRows;
126 sal_Int32 nCount = 0;
127 for(sal_Int32 j=0;j < (sal_Int32)m_vColumns.size();++j)
128 if ( m_vColumns[j].first != COLUMN_POSITION_NOT_FOUND )
129 ++nCount;
130
131 m_vColumnSize.resize(nCount);
132 m_vNumberFormat.resize(nCount);
133 for(sal_Int32 i=0;i<nCount;++i)
134 {
135 m_vColumnSize[i] = 0;
136 m_vNumberFormat[i] = 0;
137 }
138
139 try
140 {
141 SvtSysLocale aSysLocale;
142 m_aLocale = aSysLocale.GetLocaleData().getLocale();
143 }
144 catch(Exception&)
145 {
146 }
147
148 SetColumnTypes(pList,_pInfoMap);
149 }
150 //---------------------------------------------------------------------------
ODatabaseExport(const SharedConnection & _rxConnection,const Reference<XNumberFormatter> & _rxNumberF,const Reference<::com::sun::star::lang::XMultiServiceFactory> & _rM,const TColumnVector * pList,const OTypeInfoMap * _pInfoMap,SvStream & _rInputStream)151 ODatabaseExport::ODatabaseExport(const SharedConnection& _rxConnection,
152 const Reference< XNumberFormatter >& _rxNumberF,
153 const Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rM,
154 const TColumnVector* pList,
155 const OTypeInfoMap* _pInfoMap,
156 SvStream& _rInputStream)
157 :m_aDestColumns(_rxConnection->getMetaData().is() && _rxConnection->getMetaData()->supportsMixedCaseQuotedIdentifiers() == sal_True)
158 ,m_xConnection(_rxConnection)
159 ,m_xFormatter(_rxNumberF)
160 ,m_xFactory(_rM)
161 ,m_pFormatter(NULL)
162 ,m_rInputStream( _rInputStream )
163 ,m_pTypeInfo()
164 ,m_pColumnList(NULL)
165 ,m_pInfoMap(NULL)
166 ,m_nColumnPos(0)
167 ,m_nRows(1)
168 ,m_nRowCount(0)
169 ,m_nDefToken( gsl_getSystemTextEncoding() )
170 ,m_bError(sal_False)
171 ,m_bInTbl(sal_False)
172 ,m_bHead(sal_True)
173 ,m_bDontAskAgain(sal_False)
174 ,m_bIsAutoIncrement(sal_False)
175 ,m_bFoundTable(sal_False)
176 ,m_bCheckOnly(sal_False)
177 ,m_bAppendFirstLine(false)
178 {
179 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "misc", "Ocke.Janssen@sun.com", "ODatabaseExport::ODatabaseExport" );
180 DBG_CTOR(ODatabaseExport,NULL);
181 try
182 {
183 SvtSysLocale aSysLocale;
184 m_aLocale = aSysLocale.GetLocaleData().getLocale();
185 }
186 catch(Exception&)
187 {
188 }
189
190 Reference<XTablesSupplier> xTablesSup(m_xConnection,UNO_QUERY);
191 if(xTablesSup.is())
192 m_xTables = xTablesSup->getTables();
193
194 Reference<XDatabaseMetaData> xMeta = m_xConnection->getMetaData();
195 Reference<XResultSet> xSet = xMeta.is() ? xMeta->getTypeInfo() : Reference<XResultSet>();
196 if(xSet.is())
197 {
198 ::connectivity::ORowSetValue aValue;
199 ::std::vector<sal_Int32> aTypes;
200 ::std::vector<sal_Bool> aNullable;
201 Reference<XResultSetMetaData> xResultSetMetaData = Reference<XResultSetMetaDataSupplier>(xSet,UNO_QUERY_THROW)->getMetaData();
202 Reference<XRow> xRow(xSet,UNO_QUERY_THROW);
203 while(xSet->next())
204 {
205 if ( aTypes.empty() )
206 {
207 sal_Int32 nCount = xResultSetMetaData->getColumnCount();
208 if ( nCount < 1 )
209 nCount = 18;
210 aTypes.reserve(nCount+1);
211 aNullable.reserve(nCount+1);
212 aTypes.push_back(-1);
213 aNullable.push_back(sal_False);
214 for (sal_Int32 j = 1; j <= nCount ; ++j)
215 {
216 aNullable.push_back(xResultSetMetaData->isNullable(j) != ColumnValue::NO_NULLS );
217 aTypes.push_back(xResultSetMetaData->getColumnType(j));
218 }
219 }
220
221 sal_Int32 nPos = 1;
222 OSL_ENSURE((nPos) < static_cast<sal_Int32>(aTypes.size()),"aTypes: Illegal index for vector");
223 aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
224 ::rtl::OUString sTypeName = aValue;
225 ++nPos;
226 OSL_ENSURE((nPos) < static_cast<sal_Int32>(aTypes.size()),"aTypes: Illegal index for vector");
227 aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
228 sal_Int32 nType = aValue;
229 ++nPos;
230
231 if( nType == DataType::VARCHAR )
232 {
233 m_pTypeInfo = TOTypeInfoSP(new OTypeInfo());
234
235 m_pTypeInfo->aTypeName = sTypeName;
236 m_pTypeInfo->nType = nType;
237
238 OSL_ENSURE((nPos) < static_cast<sal_Int32>(aTypes.size()),"aTypes: Illegal index for vector");
239 aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
240 m_pTypeInfo->nPrecision = aValue;
241 ++nPos;
242 aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
243 m_pTypeInfo->aLiteralPrefix = aValue;
244 ++nPos;
245 aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
246 m_pTypeInfo->aLiteralSuffix = aValue;
247 ++nPos;
248 aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
249 m_pTypeInfo->aCreateParams = aValue;
250 ++nPos;
251 aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
252 m_pTypeInfo->bNullable = (sal_Int32)aValue == ColumnValue::NULLABLE;
253 ++nPos;
254 aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
255 m_pTypeInfo->bCaseSensitive = (sal_Bool)aValue;
256 ++nPos;
257 aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
258 m_pTypeInfo->nSearchType = aValue;
259 ++nPos;
260 aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
261 m_pTypeInfo->bUnsigned = (sal_Bool)aValue;
262 ++nPos;
263 aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
264 m_pTypeInfo->bCurrency = (sal_Bool)aValue;
265 ++nPos;
266 aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
267 m_pTypeInfo->bAutoIncrement = (sal_Bool)aValue;
268 ++nPos;
269 aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
270 m_pTypeInfo->aLocalTypeName = aValue;
271 ++nPos;
272 aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
273 m_pTypeInfo->nMinimumScale = aValue;
274 ++nPos;
275 aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
276 m_pTypeInfo->nMaximumScale = aValue;
277
278 // check if values are less than zero like it happens in a oracle jdbc driver
279 if( m_pTypeInfo->nPrecision < 0)
280 m_pTypeInfo->nPrecision = 0;
281 if( m_pTypeInfo->nMinimumScale < 0)
282 m_pTypeInfo->nMinimumScale = 0;
283 if( m_pTypeInfo->nMaximumScale < 0)
284 m_pTypeInfo->nMaximumScale = 0;
285 break;
286 }
287 }
288 } // if(xSet.is())
289 if ( !m_pTypeInfo )
290 m_pTypeInfo = TOTypeInfoSP(new OTypeInfo());
291 SetColumnTypes(pList,_pInfoMap);
292 }
293 //---------------------------------------------------------------------------
~ODatabaseExport()294 ODatabaseExport::~ODatabaseExport()
295 {
296 DBG_DTOR(ODatabaseExport,NULL);
297 m_pFormatter = NULL;
298 ODatabaseExport::TColumns::iterator aIter = m_aDestColumns.begin();
299 ODatabaseExport::TColumns::iterator aEnd = m_aDestColumns.end();
300
301 for(;aIter != aEnd;++aIter)
302 delete aIter->second;
303 m_vDestVector.clear();
304 m_aDestColumns.clear();
305 }
306 // -----------------------------------------------------------------------------
insertValueIntoColumn()307 void ODatabaseExport::insertValueIntoColumn()
308 {
309 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "misc", "Ocke.Janssen@sun.com", "ODatabaseExport::insertValueIntoColumn" );
310 DBG_CHKTHIS(ODatabaseExport,NULL);
311 if(m_nColumnPos < sal_Int32(m_vDestVector.size()))
312 {
313 OFieldDescription* pField = m_vDestVector[m_nColumnPos]->second;
314 if(pField)
315 {
316 sal_Int32 nNewPos = m_bIsAutoIncrement ? m_nColumnPos+1 : m_nColumnPos;
317 OSL_ENSURE((nNewPos) < static_cast<sal_Int32>(m_vColumns.size()),"m_vColumns: Illegal index for vector");
318
319 if ( (nNewPos) < static_cast<sal_Int32>(m_vColumns.size() ) )
320 {
321 sal_Int32 nPos = m_vColumns[nNewPos].first;
322 if ( nPos != COLUMN_POSITION_NOT_FOUND )
323 {
324 // if(m_nDefToken != LANGUAGE_DONTKNOW) // falls Sprache anders als Systemsprache
325 // m_pNF->ChangeIntl((LanguageType)m_nDefToken);
326
327 if ( !m_sTextToken.Len() && pField->IsNullable() )
328 m_pUpdateHelper->updateNull(nPos,pField->GetType());
329 else
330 {
331 sal_Int32 nNumberFormat = 0;
332 double fOutNumber = 0.0;
333 OSL_ENSURE((nNewPos) < static_cast<sal_Int32>(m_vColumnTypes.size()),"Illegal index for vector");
334 if (m_vColumnTypes[nNewPos] != DataType::VARCHAR && m_vColumnTypes[nNewPos] != DataType::CHAR && m_vColumnTypes[nNewPos] != DataType::LONGVARCHAR )
335 {
336 RTL_LOGFILE_CONTEXT_TRACE( aLogger, "ODatabaseExport::insertValueIntoColumn != DataType::VARCHAR" );
337 ensureFormatter();
338 bool bNumberFormatError = false;
339 if ( m_pFormatter && m_sNumToken.Len() )
340 {
341 LanguageType eNumLang = LANGUAGE_NONE;
342 sal_uInt32 nNumberFormat2( nNumberFormat );
343 fOutNumber = SfxHTMLParser::GetTableDataOptionsValNum(nNumberFormat2,eNumLang,m_sTextToken,m_sNumToken,*m_pFormatter);
344 if ( eNumLang != LANGUAGE_NONE )
345 {
346 nNumberFormat2 = m_pFormatter->GetFormatForLanguageIfBuiltIn( nNumberFormat2, eNumLang );
347 m_pFormatter->IsNumberFormat( m_sTextToken, nNumberFormat2, fOutNumber );
348 }
349 nNumberFormat = static_cast<sal_Int32>(nNumberFormat2);
350 }
351 else
352 {
353 Reference< XNumberFormatsSupplier > xSupplier = m_xFormatter->getNumberFormatsSupplier();
354 Reference<XNumberFormatTypes> xNumType(xSupplier->getNumberFormats(),UNO_QUERY);
355 sal_Int16 nFormats[] = {
356 NumberFormat::DATETIME
357 ,NumberFormat::DATE
358 ,NumberFormat::TIME
359 ,NumberFormat::CURRENCY
360 ,NumberFormat::NUMBER
361 ,NumberFormat::LOGICAL
362 };
363 for (size_t i = 0; i < sizeof(nFormats)/sizeof(nFormats[0]); ++i)
364 {
365 try
366 {
367 nNumberFormat = m_xFormatter->detectNumberFormat(xNumType->getStandardFormat(nFormats[i],m_aLocale),m_sTextToken);
368 break;
369 }
370 catch(Exception&)
371 {
372 }
373 }
374 try
375 {
376 fOutNumber = m_xFormatter->convertStringToNumber(nNumberFormat,m_sTextToken);
377 }
378 catch(Exception&)
379 {
380 bNumberFormatError = true;
381 m_pUpdateHelper->updateString(nPos,m_sTextToken);
382 }
383 }
384 if ( !bNumberFormatError )
385 {
386 try
387 {
388 Reference< XNumberFormatsSupplier > xSupplier = m_xFormatter->getNumberFormatsSupplier();
389 Reference< XNumberFormats > xFormats = xSupplier->getNumberFormats();
390 Reference<XPropertySet> xProp = xFormats->getByKey(nNumberFormat);
391 sal_Int16 nType = 0;
392 xProp->getPropertyValue(PROPERTY_TYPE) >>= nType;
393 switch(nType)
394 {
395 case NumberFormat::DATE:
396 m_pUpdateHelper->updateDate(nPos,::dbtools::DBTypeConversion::toDate(fOutNumber,m_aNullDate));
397 break;
398 case NumberFormat::DATETIME:
399 m_pUpdateHelper->updateTimestamp(nPos,::dbtools::DBTypeConversion::toDateTime(fOutNumber,m_aNullDate));
400 break;
401 case NumberFormat::TIME:
402 m_pUpdateHelper->updateTime(nPos,::dbtools::DBTypeConversion::toTime(fOutNumber));
403 break;
404 default:
405 m_pUpdateHelper->updateDouble(nPos,fOutNumber);
406 }
407 }
408 catch(Exception&)
409 {
410 m_pUpdateHelper->updateString(nPos,m_sTextToken);
411 }
412 }
413
414 }
415 else
416 m_pUpdateHelper->updateString(nPos,m_sTextToken);
417 }
418 }
419 }
420 eraseTokens();
421 }
422 }
423 }
424 // -----------------------------------------------------------------------------
CheckString(const String & aCheckToken,sal_Int16 _nOldNumberFormat)425 sal_Int16 ODatabaseExport::CheckString(const String& aCheckToken, sal_Int16 _nOldNumberFormat)
426 {
427 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "misc", "Ocke.Janssen@sun.com", "ODatabaseExport::CheckString" );
428 DBG_CHKTHIS(ODatabaseExport,NULL);
429 double fOutNumber = 0.0;
430 sal_Int16 nNumberFormat = 0;
431
432 try
433 {
434 Reference< XNumberFormatsSupplier > xSupplier = m_xFormatter->getNumberFormatsSupplier();
435 Reference< XNumberFormats > xFormats = xSupplier->getNumberFormats();
436
437 ensureFormatter();
438 if ( m_pFormatter && m_sNumToken.Len() )
439 {
440 LanguageType eNumLang;
441 sal_uInt32 nFormatKey(0);
442 fOutNumber = SfxHTMLParser::GetTableDataOptionsValNum(nFormatKey,eNumLang,m_sTextToken,m_sNumToken,*m_pFormatter);
443 if ( eNumLang != LANGUAGE_NONE )
444 {
445 nFormatKey = m_pFormatter->GetFormatForLanguageIfBuiltIn( nFormatKey, eNumLang );
446 if ( !m_pFormatter->IsNumberFormat( m_sTextToken, nFormatKey, fOutNumber ) )
447 return NumberFormat::TEXT;
448 }
449 Reference<XPropertySet> xProp = xFormats->getByKey(nFormatKey);
450 xProp->getPropertyValue(PROPERTY_TYPE) >>= nNumberFormat;
451 }
452 else
453 {
454 Reference<XNumberFormatTypes> xNumType(xFormats,UNO_QUERY);
455 sal_Int32 nFormatKey = m_xFormatter->detectNumberFormat(xNumType->getStandardFormat(NumberFormat::ALL,m_aLocale),aCheckToken);
456 fOutNumber = m_xFormatter->convertStringToNumber(nFormatKey,aCheckToken);
457
458 Reference<XPropertySet> xProp = xFormats->getByKey(nFormatKey);
459 sal_Int16 nType = 0;
460 xProp->getPropertyValue(PROPERTY_TYPE) >>= nType;
461
462 switch(nType)
463 {
464 case NumberFormat::ALL:
465 nNumberFormat = NumberFormat::ALL;
466 break;
467 case NumberFormat::DEFINED:
468 nNumberFormat = NumberFormat::TEXT;
469 break;
470 case NumberFormat::DATE:
471 switch(_nOldNumberFormat)
472 {
473 case NumberFormat::DATETIME:
474 case NumberFormat::TEXT:
475 case NumberFormat::DATE:
476 nNumberFormat = _nOldNumberFormat;
477 break;
478 case NumberFormat::ALL:
479 nNumberFormat = NumberFormat::DATE;
480 break;
481 default:
482 nNumberFormat = NumberFormat::TEXT;
483
484 }
485 break;
486 case NumberFormat::TIME:
487 switch(_nOldNumberFormat)
488 {
489 case NumberFormat::DATETIME:
490 case NumberFormat::TEXT:
491 case NumberFormat::TIME:
492 nNumberFormat = _nOldNumberFormat;
493 break;
494 case NumberFormat::ALL:
495 nNumberFormat = NumberFormat::TIME;
496 break;
497 default:
498 nNumberFormat = NumberFormat::TEXT;
499 break;
500 }
501 break;
502 case NumberFormat::CURRENCY:
503 switch(_nOldNumberFormat)
504 {
505 case NumberFormat::NUMBER:
506 nNumberFormat = NumberFormat::CURRENCY;
507 break;
508 case NumberFormat::CURRENCY:
509 nNumberFormat = _nOldNumberFormat;
510 break;
511 case NumberFormat::ALL:
512 nNumberFormat = NumberFormat::CURRENCY;
513 break;
514 default:
515 nNumberFormat = NumberFormat::TEXT;
516 break;
517 }
518 break;
519 case NumberFormat::NUMBER:
520 case NumberFormat::SCIENTIFIC:
521 case NumberFormat::FRACTION:
522 case NumberFormat::PERCENT:
523 switch(_nOldNumberFormat)
524 {
525 case NumberFormat::NUMBER:
526 nNumberFormat = _nOldNumberFormat;
527 break;
528 case NumberFormat::CURRENCY:
529 nNumberFormat = NumberFormat::CURRENCY;
530 break;
531 case NumberFormat::ALL:
532 nNumberFormat = nType;
533 break;
534 default:
535 nNumberFormat = NumberFormat::TEXT;
536 break;
537 }
538 break;
539 case NumberFormat::TEXT:
540 case NumberFormat::UNDEFINED:
541 case NumberFormat::LOGICAL:
542 nNumberFormat = NumberFormat::TEXT; // Text "uberschreibt alles
543 break;
544 case NumberFormat::DATETIME:
545 switch(_nOldNumberFormat)
546 {
547 case NumberFormat::DATETIME:
548 case NumberFormat::TEXT:
549 case NumberFormat::TIME:
550 nNumberFormat = _nOldNumberFormat;
551 break;
552 case NumberFormat::ALL:
553 nNumberFormat = NumberFormat::DATETIME;
554 break;
555 default:
556 nNumberFormat = NumberFormat::TEXT;
557 break;
558 }
559 break;
560 default:
561 OSL_ENSURE(0,"ODatabaseExport: Unbekanntes Format");
562 }
563 }
564 }
565 catch(Exception&)
566 {
567 nNumberFormat = NumberFormat::TEXT; // Text "uberschreibt alles
568 }
569
570 return nNumberFormat;
571 }
572 // -----------------------------------------------------------------------------
SetColumnTypes(const TColumnVector * _pList,const OTypeInfoMap * _pInfoMap)573 void ODatabaseExport::SetColumnTypes(const TColumnVector* _pList,const OTypeInfoMap* _pInfoMap)
574 {
575 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "misc", "Ocke.Janssen@sun.com", "ODatabaseExport::SetColumnTypes" );
576 DBG_CHKTHIS(ODatabaseExport,NULL);
577 if(_pList && _pInfoMap)
578 {
579 OSL_ENSURE(m_vNumberFormat.size() == m_vColumnSize.size() && m_vColumnSize.size() == _pList->size(),"Illegal columns in list");
580 Reference< XNumberFormatsSupplier > xSupplier = m_xFormatter->getNumberFormatsSupplier();
581 Reference< XNumberFormats > xFormats = xSupplier->getNumberFormats();
582 TColumnVector::const_iterator aIter = _pList->begin();
583 TColumnVector::const_iterator aEnd = _pList->end();
584 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)
585 {
586 sal_Int32 nDataType;
587 sal_Int32 nLength(0),nScale(0);
588 sal_Int16 nType = m_vNumberFormat[i] & ~NumberFormat::DEFINED;
589
590 switch ( nType )
591 {
592 case NumberFormat::ALL:
593 nDataType = DataType::DOUBLE;
594 break;
595 case NumberFormat::DEFINED:
596 nDataType = DataType::VARCHAR;
597 nLength = ((m_vColumnSize[i] % 10 ) ? m_vColumnSize[i]/ 10 + 1: m_vColumnSize[i]/ 10) * 10;
598 break;
599 case NumberFormat::DATE:
600 nDataType = DataType::DATE;
601 break;
602 case NumberFormat::TIME:
603 nDataType = DataType::TIME;
604 break;
605 case NumberFormat::DATETIME:
606 nDataType = DataType::TIMESTAMP;
607 break;
608 case NumberFormat::CURRENCY:
609 nDataType = DataType::NUMERIC;
610 nScale = 4;
611 nLength = 19;
612 break;
613 case NumberFormat::NUMBER:
614 case NumberFormat::SCIENTIFIC:
615 case NumberFormat::FRACTION:
616 case NumberFormat::PERCENT:
617 nDataType = DataType::DOUBLE;
618 break;
619 case NumberFormat::TEXT:
620 case NumberFormat::UNDEFINED:
621 case NumberFormat::LOGICAL:
622 default:
623 nDataType = DataType::VARCHAR;
624 nLength = ((m_vColumnSize[i] % 10 ) ? m_vColumnSize[i]/ 10 + 1: m_vColumnSize[i]/ 10) * 10;
625 break;
626 }
627 OTypeInfoMap::const_iterator aFind = _pInfoMap->find(nDataType);
628 if(aFind != _pInfoMap->end())
629 {
630 (*aIter)->second->SetType(aFind->second);
631 (*aIter)->second->SetPrecision(::std::min<sal_Int32>(aFind->second->nPrecision,nLength));
632 (*aIter)->second->SetScale(::std::min<sal_Int32>(aFind->second->nMaximumScale,nScale));
633
634 sal_Int32 nFormatKey = ::dbtools::getDefaultNumberFormat( nDataType,
635 (*aIter)->second->GetScale(),
636 (*aIter)->second->IsCurrency(),
637 Reference< XNumberFormatTypes>(xFormats,UNO_QUERY),
638 m_aLocale);
639
640 (*aIter)->second->SetFormatKey(nFormatKey);
641 }
642 }
643 }
644 }
645 // -----------------------------------------------------------------------------
CreateDefaultColumn(const::rtl::OUString & _rColumnName)646 void ODatabaseExport::CreateDefaultColumn(const ::rtl::OUString& _rColumnName)
647 {
648 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "misc", "Ocke.Janssen@sun.com", "ODatabaseExport::CreateDefaultColumn" );
649 DBG_CHKTHIS(ODatabaseExport,NULL);
650 Reference< XDatabaseMetaData> xDestMetaData(m_xConnection->getMetaData());
651 sal_Int32 nMaxNameLen(xDestMetaData->getMaxColumnNameLength());
652 ::rtl::OUString aAlias = _rColumnName;
653 if ( isSQL92CheckEnabled(m_xConnection) )
654 aAlias = ::dbtools::convertName2SQLName(_rColumnName,xDestMetaData->getExtraNameCharacters());
655
656 if(nMaxNameLen && aAlias.getLength() > nMaxNameLen)
657 aAlias = aAlias.copy(0, ::std::min<sal_Int32>( nMaxNameLen-1, aAlias.getLength() ) );
658
659 ::rtl::OUString sName(aAlias);
660 if(m_aDestColumns.find(sName) != m_aDestColumns.end())
661 {
662 sal_Int32 nPos = 0;
663 sal_Int32 nCount = 2;
664 while(m_aDestColumns.find(sName) != m_aDestColumns.end())
665 {
666 sName = aAlias;
667 sName += ::rtl::OUString::valueOf(++nPos);
668 if(nMaxNameLen && sName.getLength() > nMaxNameLen)
669 {
670 aAlias = aAlias.copy(0,::std::min<sal_Int32>( nMaxNameLen-nCount, aAlias.getLength() ));
671 sName = aAlias;
672 sName += ::rtl::OUString::valueOf(nPos);
673 ++nCount;
674 }
675 }
676 }
677 aAlias = sName;
678 // now create a column
679 OFieldDescription* pField = new OFieldDescription();
680 pField->SetType(m_pTypeInfo);
681 pField->SetName(aAlias);
682 pField->SetPrecision(::std::min<sal_Int32>((sal_Int32)255,m_pTypeInfo->nPrecision));
683 pField->SetScale(0);
684 pField->SetIsNullable(ColumnValue::NULLABLE);
685 pField->SetAutoIncrement(sal_False);
686 pField->SetPrimaryKey(sal_False);
687 pField->SetCurrency(sal_False);
688
689 TColumns::iterator aFind = m_aDestColumns.find( aAlias );
690 if ( aFind != m_aDestColumns.end() )
691 {
692 delete aFind->second;
693 m_aDestColumns.erase(aFind);
694 }
695
696 m_vDestVector.push_back(m_aDestColumns.insert(TColumns::value_type(aAlias,pField)).first);
697 }
698 // -----------------------------------------------------------------------------
createRowSet()699 sal_Bool ODatabaseExport::createRowSet()
700 {
701 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "misc", "Ocke.Janssen@sun.com", "ODatabaseExport::createRowSet" );
702 DBG_CHKTHIS(ODatabaseExport,NULL);
703 m_pUpdateHelper.reset(new OParameterUpdateHelper(createPreparedStatment(m_xConnection->getMetaData(),m_xTable,m_vColumns)));
704
705 return m_pUpdateHelper.get() != NULL;
706 }
707 // -----------------------------------------------------------------------------
executeWizard(const::rtl::OUString & _rTableName,const Any & _aTextColor,const FontDescriptor & _rFont)708 sal_Bool ODatabaseExport::executeWizard(const ::rtl::OUString& _rTableName,const Any& _aTextColor,const FontDescriptor& _rFont)
709 {
710 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "misc", "Ocke.Janssen@sun.com", "ODatabaseExport::executeWizard" );
711 DBG_CHKTHIS(ODatabaseExport,NULL);
712
713 bool bHaveDefaultTable = ( m_sDefaultTableName.getLength() != 0 );
714 ::rtl::OUString sTableName( bHaveDefaultTable ? m_sDefaultTableName : _rTableName );
715 OCopyTableWizard aWizard(
716 NULL,
717 sTableName,
718 bHaveDefaultTable ? CopyTableOperation::AppendData : CopyTableOperation::CopyDefinitionAndData,
719 m_aDestColumns,
720 m_vDestVector,
721 m_xConnection,
722 m_xFormatter,
723 getTypeSelectionPageFactory(),
724 m_rInputStream,
725 m_xFactory
726 );
727
728 sal_Bool bError = sal_False;
729 try
730 {
731 if (aWizard.Execute())
732 {
733 switch(aWizard.getOperation())
734 {
735 case CopyTableOperation::CopyDefinitionAndData:
736 case CopyTableOperation::AppendData:
737 {
738 m_xTable = aWizard.createTable();
739 bError = !m_xTable.is();
740 if(m_xTable.is())
741 {
742 m_xTable->setPropertyValue(PROPERTY_FONT,makeAny(_rFont));
743 if(_aTextColor.hasValue())
744 m_xTable->setPropertyValue(PROPERTY_TEXTCOLOR,_aTextColor);
745 }
746 m_bIsAutoIncrement = aWizard.shouldCreatePrimaryKey();
747 m_vColumns = aWizard.GetColumnPositions();
748 m_vColumnTypes = aWizard.GetColumnTypes();
749 m_bAppendFirstLine = !aWizard.UseHeaderLine();
750 }
751 break;
752 default:
753 bError = sal_True; // there is no error but I have nothing more to do
754 }
755 }
756 else
757 bError = sal_True;
758
759 if(!bError)
760 bError = !createRowSet();
761 }
762 catch( const SQLException&)
763 {
764 ::dbaui::showError( ::dbtools::SQLExceptionInfo( ::cppu::getCaughtException() ), &aWizard, m_xFactory );
765 bError = sal_True;
766 }
767 catch( const Exception& )
768 {
769 DBG_UNHANDLED_EXCEPTION();
770 }
771
772 return bError;
773 }
774 //---------------------------------------------------------------------------------
showErrorDialog(const::com::sun::star::sdbc::SQLException & e)775 void ODatabaseExport::showErrorDialog(const ::com::sun::star::sdbc::SQLException& e)
776 {
777 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "misc", "Ocke.Janssen@sun.com", "ODatabaseExport::showErrorDialog" );
778 if(!m_bDontAskAgain)
779 {
780 String aMsg(e.Message);
781 aMsg += '\n';
782 aMsg += String( ModuleRes( STR_QRY_CONTINUE ) );
783 OSQLWarningBox aBox( NULL, aMsg, WB_YES_NO | WB_DEF_NO );
784
785 if (aBox.Execute() == RET_YES)
786 m_bDontAskAgain = sal_True;
787 else
788 m_bError = sal_True;
789 } // if(!m_bDontAskAgain)
790 }
791 // -----------------------------------------------------------------------------
adjustFormat()792 void ODatabaseExport::adjustFormat()
793 {
794 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "misc", "Ocke.Janssen@sun.com", "ODatabaseExport::adjustFormat" );
795 if ( m_sTextToken.Len() )
796 {
797 sal_Int32 nNewPos = m_bIsAutoIncrement ? m_nColumnPos+1 : m_nColumnPos;
798 OSL_ENSURE((nNewPos) < static_cast<sal_Int32>(m_vColumns.size()),"Illegal index for vector");
799 if ( (nNewPos) < static_cast<sal_Int32>(m_vColumns.size()) )
800 {
801 sal_Int32 nColPos = m_vColumns[nNewPos].first;
802 if( nColPos != sal::static_int_cast< long >(CONTAINER_ENTRY_NOTFOUND))
803 {
804 --nColPos;
805 OSL_ENSURE((nColPos) < static_cast<sal_Int32>(m_vNumberFormat.size()),"m_vFormatKey: Illegal index for vector");
806 OSL_ENSURE((nColPos) < static_cast<sal_Int32>(m_vColumnSize.size()),"m_vColumnSize: Illegal index for vector");
807 m_vNumberFormat[nColPos] = CheckString(m_sTextToken,m_vNumberFormat[nColPos]);
808 m_vColumnSize[nColPos] = ::std::max<sal_Int32>((sal_Int32)m_vColumnSize[nColPos],(sal_Int32)m_sTextToken.Len());
809 }
810 }
811 eraseTokens();
812 }
813 }
814 // -----------------------------------------------------------------------------
eraseTokens()815 void ODatabaseExport::eraseTokens()
816 {
817 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "misc", "Ocke.Janssen@sun.com", "ODatabaseExport::eraseTokens" );
818 m_sTextToken.Erase();
819 m_sNumToken.Erase();
820 m_sValToken.Erase();
821 }
822 // -----------------------------------------------------------------------------
ensureFormatter()823 void ODatabaseExport::ensureFormatter()
824 {
825 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "misc", "Ocke.Janssen@sun.com", "ODatabaseExport::ensureFormatter" );
826 if ( !m_pFormatter )
827 {
828 Reference< XNumberFormatsSupplier > xSupplier = m_xFormatter->getNumberFormatsSupplier();
829 Reference< XUnoTunnel > xTunnel(xSupplier,UNO_QUERY);
830 SvNumberFormatsSupplierObj* pSupplierImpl = (SvNumberFormatsSupplierObj*)sal::static_int_cast< sal_IntPtr >(xTunnel->getSomething(SvNumberFormatsSupplierObj::getUnoTunnelId()));
831 m_pFormatter = pSupplierImpl ? pSupplierImpl->GetNumberFormatter() : NULL;
832 Reference<XPropertySet> xNumberFormatSettings = xSupplier->getNumberFormatSettings();
833 xNumberFormatSettings->getPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("NullDate"))) >>= m_aNullDate;
834 }
835 }
836 // -----------------------------------------------------------------------------
createPreparedStatment(const Reference<XDatabaseMetaData> & _xMetaData,const Reference<XPropertySet> & _xDestTable,const TPositions & _rvColumns)837 Reference< XPreparedStatement > ODatabaseExport::createPreparedStatment( const Reference<XDatabaseMetaData>& _xMetaData
838 ,const Reference<XPropertySet>& _xDestTable
839 ,const TPositions& _rvColumns)
840 {
841 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "misc", "Ocke.Janssen@sun.com", "ODatabaseExport::createPreparedStatment" );
842 ::rtl::OUString aSql(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("INSERT INTO ")));
843 ::rtl::OUString sComposedTableName = ::dbtools::composeTableName( _xMetaData, _xDestTable, ::dbtools::eInDataManipulation, false, false, true );
844
845 aSql += sComposedTableName;
846 aSql += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" ( "));
847 // set values and column names
848 ::rtl::OUString aValues(RTL_CONSTASCII_USTRINGPARAM(" VALUES ( "));
849 static ::rtl::OUString aPara(RTL_CONSTASCII_USTRINGPARAM("?,"));
850 static ::rtl::OUString aComma(RTL_CONSTASCII_USTRINGPARAM(","));
851
852 ::rtl::OUString aQuote;
853 if ( _xMetaData.is() )
854 aQuote = _xMetaData->getIdentifierQuoteString();
855
856 Reference<XColumnsSupplier> xDestColsSup(_xDestTable,UNO_QUERY_THROW);
857
858 // create sql string and set column types
859 Sequence< ::rtl::OUString> aDestColumnNames = xDestColsSup->getColumns()->getElementNames();
860 if ( aDestColumnNames.getLength() == 0 )
861 {
862 return Reference< XPreparedStatement > ();
863 }
864 const ::rtl::OUString* pIter = aDestColumnNames.getConstArray();
865 ::std::vector< ::rtl::OUString> aInsertList;
866 aInsertList.resize(aDestColumnNames.getLength()+1);
867 sal_Int32 i = 0;
868 for(sal_uInt32 j=0; j < aInsertList.size() ;++i,++j)
869 {
870 ODatabaseExport::TPositions::const_iterator aFind = ::std::find_if(_rvColumns.begin(),_rvColumns.end(),
871 ::std::compose1(::std::bind2nd(::std::equal_to<sal_Int32>(),i+1),::std::select2nd<ODatabaseExport::TPositions::value_type>()));
872 if ( _rvColumns.end() != aFind && aFind->second != sal::static_int_cast< long >(CONTAINER_ENTRY_NOTFOUND) && aFind->first != sal::static_int_cast< long >(CONTAINER_ENTRY_NOTFOUND) )
873 {
874 OSL_ENSURE((aFind->first) < static_cast<sal_Int32>(aInsertList.size()),"aInsertList: Illegal index for vector");
875 aInsertList[aFind->first] = ::dbtools::quoteName( aQuote,*(pIter+i));
876 }
877 }
878
879 i = 1;
880 // create the sql string
881 ::std::vector< ::rtl::OUString>::iterator aInsertEnd = aInsertList.end();
882 for (::std::vector< ::rtl::OUString>::iterator aInsertIter = aInsertList.begin(); aInsertIter != aInsertEnd; ++aInsertIter)
883 {
884 if ( aInsertIter->getLength() )
885 {
886 aSql += *aInsertIter;
887 aSql += aComma;
888 aValues += aPara;
889 }
890 }
891
892 aSql = aSql.replaceAt(aSql.getLength()-1,1,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(")")));
893 aValues = aValues.replaceAt(aValues.getLength()-1,1,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(")")));
894
895 aSql += aValues;
896 // now create,fill and execute the prepared statement
897 return Reference< XPreparedStatement >(_xMetaData->getConnection()->prepareStatement(aSql));
898 }
899 // -----------------------------------------------------------------------------
900
901
902