xref: /trunk/main/dbaccess/source/ui/misc/DExport.cxx (revision b63233d8)
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