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