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