19b5730f6SAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 39b5730f6SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 49b5730f6SAndrew Rist * or more contributor license agreements. See the NOTICE file 59b5730f6SAndrew Rist * distributed with this work for additional information 69b5730f6SAndrew Rist * regarding copyright ownership. The ASF licenses this file 79b5730f6SAndrew Rist * to you under the Apache License, Version 2.0 (the 89b5730f6SAndrew Rist * "License"); you may not use this file except in compliance 99b5730f6SAndrew Rist * with the License. You may obtain a copy of the License at 10cdf0e10cSrcweir * 119b5730f6SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12cdf0e10cSrcweir * 139b5730f6SAndrew Rist * Unless required by applicable law or agreed to in writing, 149b5730f6SAndrew Rist * software distributed under the License is distributed on an 159b5730f6SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 169b5730f6SAndrew Rist * KIND, either express or implied. See the License for the 179b5730f6SAndrew Rist * specific language governing permissions and limitations 189b5730f6SAndrew Rist * under the License. 19cdf0e10cSrcweir * 209b5730f6SAndrew Rist *************************************************************/ 219b5730f6SAndrew Rist 229b5730f6SAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 25cdf0e10cSrcweir #include "precompiled_connectivity.hxx" 26cdf0e10cSrcweir 27cdf0e10cSrcweir #include <ctype.h> 28cdf0e10cSrcweir #include "flat/ETable.hxx" 29cdf0e10cSrcweir #include <com/sun/star/sdbc/ColumnValue.hpp> 30cdf0e10cSrcweir #include <com/sun/star/sdbc/DataType.hpp> 31cdf0e10cSrcweir #include <com/sun/star/ucb/XContentAccess.hpp> 32cdf0e10cSrcweir #include <svl/converter.hxx> 33cdf0e10cSrcweir #include "flat/EConnection.hxx" 34cdf0e10cSrcweir #include "flat/EColumns.hxx" 35cdf0e10cSrcweir #include <osl/thread.h> 36cdf0e10cSrcweir #include <tools/config.hxx> 37cdf0e10cSrcweir #include <comphelper/sequence.hxx> 38cdf0e10cSrcweir #include <svl/zforlist.hxx> 39cdf0e10cSrcweir #include <rtl/math.hxx> 40cdf0e10cSrcweir #include <stdio.h> //sprintf 41cdf0e10cSrcweir #include <comphelper/extract.hxx> 42cdf0e10cSrcweir #include <comphelper/numbers.hxx> 43cdf0e10cSrcweir #include "flat/EDriver.hxx" 44cdf0e10cSrcweir #include <com/sun/star/util/NumberFormat.hpp> 45cdf0e10cSrcweir #include <unotools/configmgr.hxx> 46cdf0e10cSrcweir #include <i18npool/mslangid.hxx> 47cdf0e10cSrcweir #include "connectivity/dbconversion.hxx" 48cdf0e10cSrcweir #include <comphelper/types.hxx> 49cdf0e10cSrcweir #include "file/quotedstring.hxx" 50cdf0e10cSrcweir #include <unotools/syslocale.hxx> 51cdf0e10cSrcweir #include <rtl/logfile.hxx> 52cdf0e10cSrcweir 53cdf0e10cSrcweir using namespace ::comphelper; 54cdf0e10cSrcweir using namespace connectivity; 55cdf0e10cSrcweir using namespace connectivity::flat; 56cdf0e10cSrcweir using namespace connectivity::file; 57cdf0e10cSrcweir using namespace ::cppu; 58cdf0e10cSrcweir using namespace utl; 59cdf0e10cSrcweir using namespace ::com::sun::star::uno; 60cdf0e10cSrcweir using namespace ::com::sun::star::ucb; 61cdf0e10cSrcweir using namespace ::com::sun::star::beans; 62cdf0e10cSrcweir using namespace ::com::sun::star::sdbcx; 63cdf0e10cSrcweir using namespace ::com::sun::star::sdbc; 64cdf0e10cSrcweir using namespace ::com::sun::star::container; 65cdf0e10cSrcweir using namespace ::com::sun::star::lang; 66cdf0e10cSrcweir 67cdf0e10cSrcweir // ------------------------------------------------------------------------- 68cdf0e10cSrcweir void OFlatTable::fillColumns(const ::com::sun::star::lang::Locale& _aLocale) 69cdf0e10cSrcweir { 70cdf0e10cSrcweir RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "flat", "Ocke.Janssen@sun.com", "OFlatTable::fillColumns" ); 71cdf0e10cSrcweir sal_Bool bRead = sal_True; 72cdf0e10cSrcweir 73cdf0e10cSrcweir QuotedTokenizedString aHeaderLine; 74cdf0e10cSrcweir OFlatConnection* pConnection = (OFlatConnection*)m_pConnection; 75cdf0e10cSrcweir const sal_Bool bHasHeaderLine = pConnection->isHeaderLine(); 766b41ff7aSdamjan sal_Int32 nCurPos; 77cdf0e10cSrcweir if ( bHasHeaderLine ) 78cdf0e10cSrcweir { 79cdf0e10cSrcweir while(bRead && !aHeaderLine.Len()) 80cdf0e10cSrcweir { 816b41ff7aSdamjan bRead = readLine(aHeaderLine, nCurPos); 82cdf0e10cSrcweir } 83cdf0e10cSrcweir m_nStartRowFilePos = m_pFileStream->Tell(); 84cdf0e10cSrcweir } 85cdf0e10cSrcweir 86cdf0e10cSrcweir // read first row 87cdf0e10cSrcweir QuotedTokenizedString aFirstLine; 886b41ff7aSdamjan bRead = readLine(aFirstLine, nCurPos); 89cdf0e10cSrcweir 90cdf0e10cSrcweir if ( !bHasHeaderLine || !aHeaderLine.Len()) 91cdf0e10cSrcweir { 92cdf0e10cSrcweir while(bRead && !aFirstLine.Len()) 93cdf0e10cSrcweir { 946b41ff7aSdamjan bRead = readLine(aFirstLine, nCurPos); 95cdf0e10cSrcweir } 96cdf0e10cSrcweir // use first row as headerline because we need the number of columns 97cdf0e10cSrcweir aHeaderLine = aFirstLine; 98cdf0e10cSrcweir } 99cdf0e10cSrcweir // column count 100*7b2bc0e6SDamjan Jovanovic const sal_Int32 nFieldCount = aHeaderLine.GetTokenCount(m_cFieldDelimiter,m_cStringDelimiter); 101cdf0e10cSrcweir 102cdf0e10cSrcweir if(!m_aColumns.isValid()) 103cdf0e10cSrcweir m_aColumns = new OSQLColumns(); 104cdf0e10cSrcweir else 105cdf0e10cSrcweir m_aColumns->get().clear(); 106cdf0e10cSrcweir 107cdf0e10cSrcweir m_aTypes.clear(); 108cdf0e10cSrcweir m_aPrecisions.clear(); 109cdf0e10cSrcweir m_aScales.clear(); 110cdf0e10cSrcweir // reserve some space 111cdf0e10cSrcweir m_aColumns->get().reserve(nFieldCount+1); 112cdf0e10cSrcweir m_aTypes.assign(nFieldCount+1,DataType::SQLNULL); 113cdf0e10cSrcweir m_aPrecisions.assign(nFieldCount+1,-1); 114cdf0e10cSrcweir m_aScales.assign(nFieldCount+1,-1); 115cdf0e10cSrcweir 116cdf0e10cSrcweir const sal_Bool bCase = m_pConnection->getMetaData()->supportsMixedCaseQuotedIdentifiers(); 117cdf0e10cSrcweir CharClass aCharClass(pConnection->getDriver()->getFactory(),_aLocale); 118cdf0e10cSrcweir // read description 119cdf0e10cSrcweir const sal_Unicode cDecimalDelimiter = pConnection->getDecimalDelimiter(); 120cdf0e10cSrcweir const sal_Unicode cThousandDelimiter = pConnection->getThousandDelimiter(); 121*7b2bc0e6SDamjan Jovanovic ::rtl::OUString aColumnName; 122cdf0e10cSrcweir ::rtl::OUString aTypeName; 123cdf0e10cSrcweir ::comphelper::UStringMixEqual aCase(bCase); 124cdf0e10cSrcweir ::std::vector<String> aColumnNames,m_aTypeNames; 125cdf0e10cSrcweir m_aTypeNames.resize(nFieldCount); 126cdf0e10cSrcweir const sal_Int32 nMaxRowsToScan = pConnection->getMaxRowsToScan(); 127cdf0e10cSrcweir sal_Int32 nRowCount = 0; 128cdf0e10cSrcweir do 129cdf0e10cSrcweir { 130*7b2bc0e6SDamjan Jovanovic sal_Int32 nStartPosHeaderLine = 0; // use for eficient way to get the tokens 131*7b2bc0e6SDamjan Jovanovic sal_Int32 nStartPosFirstLine = 0; // use for eficient way to get the tokens 132*7b2bc0e6SDamjan Jovanovic sal_Int32 nStartPosFirstLine2 = 0; 133*7b2bc0e6SDamjan Jovanovic for (sal_Int32 i = 0; i < nFieldCount; i++) 134cdf0e10cSrcweir { 135cdf0e10cSrcweir if ( nRowCount == 0) 136cdf0e10cSrcweir { 137cdf0e10cSrcweir if ( bHasHeaderLine ) 138cdf0e10cSrcweir { 139*7b2bc0e6SDamjan Jovanovic aHeaderLine.GetTokenSpecial(&aColumnName,nStartPosHeaderLine,m_cFieldDelimiter,m_cStringDelimiter); 140*7b2bc0e6SDamjan Jovanovic if ( aColumnName.isEmpty() ) 141cdf0e10cSrcweir { 142*7b2bc0e6SDamjan Jovanovic aColumnName = ::rtl::OUString::createFromAscii( "C" ); 143cdf0e10cSrcweir aColumnName += String::CreateFromInt32(i+1); 144cdf0e10cSrcweir } 145cdf0e10cSrcweir } 146cdf0e10cSrcweir else 147cdf0e10cSrcweir { 148cdf0e10cSrcweir // no column name so ... 149*7b2bc0e6SDamjan Jovanovic aColumnName = ::rtl::OUString::createFromAscii( "C" ); 150cdf0e10cSrcweir aColumnName += String::CreateFromInt32(i+1); 151cdf0e10cSrcweir } 152cdf0e10cSrcweir aColumnNames.push_back(aColumnName); 153cdf0e10cSrcweir } 154cdf0e10cSrcweir impl_fillColumnInfo_nothrow(aFirstLine,nStartPosFirstLine,nStartPosFirstLine2,m_aTypes[i],m_aPrecisions[i],m_aScales[i],m_aTypeNames[i],cDecimalDelimiter,cThousandDelimiter,aCharClass); 155cdf0e10cSrcweir } 156cdf0e10cSrcweir ++nRowCount; 157cdf0e10cSrcweir } 1586b41ff7aSdamjan while(nRowCount < nMaxRowsToScan && readLine(aFirstLine,nCurPos) && !m_pFileStream->IsEof()); 159cdf0e10cSrcweir 160*7b2bc0e6SDamjan Jovanovic for (sal_Int32 i = 0; i < nFieldCount; i++) 161cdf0e10cSrcweir { 162cdf0e10cSrcweir // check if the columname already exists 163cdf0e10cSrcweir String aAlias(aColumnNames[i]); 164cdf0e10cSrcweir OSQLColumns::Vector::const_iterator aFind = connectivity::find(m_aColumns->get().begin(),m_aColumns->get().end(),aAlias,aCase); 165cdf0e10cSrcweir sal_Int32 nExprCnt = 0; 166cdf0e10cSrcweir while(aFind != m_aColumns->get().end()) 167cdf0e10cSrcweir { 168cdf0e10cSrcweir (aAlias = aColumnNames[i]) += String::CreateFromInt32(++nExprCnt); 169cdf0e10cSrcweir aFind = connectivity::find(m_aColumns->get().begin(),m_aColumns->get().end(),aAlias,aCase); 170cdf0e10cSrcweir } 171cdf0e10cSrcweir 172cdf0e10cSrcweir sdbcx::OColumn* pColumn = new sdbcx::OColumn(aAlias,m_aTypeNames[i],::rtl::OUString(),::rtl::OUString(), 173cdf0e10cSrcweir ColumnValue::NULLABLE, 174cdf0e10cSrcweir m_aPrecisions[i], 175cdf0e10cSrcweir m_aScales[i], 176cdf0e10cSrcweir m_aTypes[i], 177cdf0e10cSrcweir sal_False, 178cdf0e10cSrcweir sal_False, 179cdf0e10cSrcweir sal_False, 180cdf0e10cSrcweir bCase); 181cdf0e10cSrcweir Reference< XPropertySet> xCol = pColumn; 182cdf0e10cSrcweir m_aColumns->get().push_back(xCol); 183cdf0e10cSrcweir } 184cdf0e10cSrcweir m_pFileStream->Seek(m_nStartRowFilePos); 185cdf0e10cSrcweir } 186*7b2bc0e6SDamjan Jovanovic void OFlatTable::impl_fillColumnInfo_nothrow(QuotedTokenizedString& aFirstLine,sal_Int32& nStartPosFirstLine,sal_Int32& nStartPosFirstLine2 187cdf0e10cSrcweir ,sal_Int32& io_nType,sal_Int32& io_nPrecisions,sal_Int32& io_nScales,String& o_sTypeName 188cdf0e10cSrcweir ,const sal_Unicode cDecimalDelimiter,const sal_Unicode cThousandDelimiter,const CharClass& aCharClass) 189cdf0e10cSrcweir { 190cdf0e10cSrcweir if ( io_nType != DataType::VARCHAR ) 191cdf0e10cSrcweir { 192cdf0e10cSrcweir sal_Bool bNumeric = io_nType == DataType::SQLNULL || io_nType == DataType::DOUBLE || io_nType == DataType::DECIMAL || io_nType == DataType::INTEGER; 193cdf0e10cSrcweir sal_uLong nIndex = 0; 194cdf0e10cSrcweir 195cdf0e10cSrcweir if ( bNumeric ) 196cdf0e10cSrcweir { 197cdf0e10cSrcweir // first without fielddelimiter 198*7b2bc0e6SDamjan Jovanovic ::rtl::OUString aField; 199*7b2bc0e6SDamjan Jovanovic aFirstLine.GetTokenSpecial(&aField,nStartPosFirstLine,m_cFieldDelimiter,'\0'); 200*7b2bc0e6SDamjan Jovanovic if ( aField.isEmpty() || 201*7b2bc0e6SDamjan Jovanovic (m_cStringDelimiter && m_cStringDelimiter == aField[0])) 202cdf0e10cSrcweir { 203cdf0e10cSrcweir bNumeric = sal_False; 204cdf0e10cSrcweir if ( m_cStringDelimiter != '\0' ) 205*7b2bc0e6SDamjan Jovanovic aFirstLine.GetTokenSpecial(&aField,nStartPosFirstLine2,m_cFieldDelimiter,m_cStringDelimiter); 206cdf0e10cSrcweir else 207cdf0e10cSrcweir nStartPosFirstLine2 = nStartPosFirstLine; 208cdf0e10cSrcweir } 209cdf0e10cSrcweir else 210cdf0e10cSrcweir { 211*7b2bc0e6SDamjan Jovanovic ::rtl::OUString aField2; 212cdf0e10cSrcweir if ( m_cStringDelimiter != '\0' ) 213*7b2bc0e6SDamjan Jovanovic aFirstLine.GetTokenSpecial(&aField2,nStartPosFirstLine2,m_cFieldDelimiter,m_cStringDelimiter); 214cdf0e10cSrcweir else 215cdf0e10cSrcweir aField2 = aField; 216cdf0e10cSrcweir 217*7b2bc0e6SDamjan Jovanovic if ( aField2.isEmpty() ) 218cdf0e10cSrcweir { 219cdf0e10cSrcweir bNumeric = sal_False; 220cdf0e10cSrcweir } 221cdf0e10cSrcweir else 222cdf0e10cSrcweir { 223cdf0e10cSrcweir bNumeric = sal_True; 224cdf0e10cSrcweir xub_StrLen nDot = 0; 225cdf0e10cSrcweir xub_StrLen nDecimalDelCount = 0; 226cdf0e10cSrcweir xub_StrLen nSpaceCount = 0; 227*7b2bc0e6SDamjan Jovanovic for (sal_Int32 j = 0; j < aField2.getLength(); j++) 228cdf0e10cSrcweir { 229*7b2bc0e6SDamjan Jovanovic const sal_Unicode c = aField2[j]; 230cdf0e10cSrcweir if ( j == nSpaceCount && m_cFieldDelimiter != 32 && c == 32 ) 231cdf0e10cSrcweir { 232cdf0e10cSrcweir ++nSpaceCount; 233cdf0e10cSrcweir continue; 234cdf0e10cSrcweir } 235cdf0e10cSrcweir // nur Ziffern und Dezimalpunkt und Tausender-Trennzeichen? 236cdf0e10cSrcweir if ( ( !cDecimalDelimiter || c != cDecimalDelimiter ) && 237cdf0e10cSrcweir ( !cThousandDelimiter || c != cThousandDelimiter ) && 238cdf0e10cSrcweir !aCharClass.isDigit(aField2,j) && 239cdf0e10cSrcweir ( j != 0 || (c != '+' && c != '-' ) ) ) 240cdf0e10cSrcweir { 241cdf0e10cSrcweir bNumeric = sal_False; 242cdf0e10cSrcweir break; 243cdf0e10cSrcweir } 244cdf0e10cSrcweir if (cDecimalDelimiter && c == cDecimalDelimiter) 245cdf0e10cSrcweir { 246cdf0e10cSrcweir io_nPrecisions = 15; // we have an decimal value 247cdf0e10cSrcweir io_nScales = 2; 248cdf0e10cSrcweir ++nDecimalDelCount; 249cdf0e10cSrcweir } // if (cDecimalDelimiter && c == cDecimalDelimiter) 250cdf0e10cSrcweir if ( c == '.' ) 251cdf0e10cSrcweir ++nDot; 252cdf0e10cSrcweir } 253cdf0e10cSrcweir 254cdf0e10cSrcweir if (nDecimalDelCount > 1 || nDot > 1 ) // if there is more than one dot it isn't a number 255cdf0e10cSrcweir bNumeric = sal_False; 256cdf0e10cSrcweir if (bNumeric && cThousandDelimiter) 257cdf0e10cSrcweir { 258cdf0e10cSrcweir // Ist der Trenner richtig angegeben? 259*7b2bc0e6SDamjan Jovanovic sal_Int32 tokenIdx = 0; 260*7b2bc0e6SDamjan Jovanovic const ::rtl::OUString aValue = aField2.getToken(0,cDecimalDelimiter,tokenIdx); 261*7b2bc0e6SDamjan Jovanovic for (sal_Int32 j = aValue.getLength() - 4; j >= 0; j -= 4) 262cdf0e10cSrcweir { 263*7b2bc0e6SDamjan Jovanovic const sal_Unicode c = aValue[j]; 264cdf0e10cSrcweir // nur Ziffern und Dezimalpunkt und Tausender-Trennzeichen? 265cdf0e10cSrcweir if (c == cThousandDelimiter && j) 266cdf0e10cSrcweir continue; 267cdf0e10cSrcweir else 268cdf0e10cSrcweir { 269cdf0e10cSrcweir bNumeric = sal_False; 270cdf0e10cSrcweir break; 271cdf0e10cSrcweir } 272cdf0e10cSrcweir } 273cdf0e10cSrcweir } 274cdf0e10cSrcweir 275cdf0e10cSrcweir // jetzt koennte es noch ein Datumsfeld sein 276cdf0e10cSrcweir if (!bNumeric) 277cdf0e10cSrcweir { 278cdf0e10cSrcweir try 279cdf0e10cSrcweir { 280cdf0e10cSrcweir nIndex = m_xNumberFormatter->detectNumberFormat(::com::sun::star::util::NumberFormat::ALL,aField2); 281cdf0e10cSrcweir } 282cdf0e10cSrcweir catch(Exception&) 283cdf0e10cSrcweir { 284cdf0e10cSrcweir } 285cdf0e10cSrcweir } 286cdf0e10cSrcweir } 287cdf0e10cSrcweir } 288cdf0e10cSrcweir } 289cdf0e10cSrcweir else if ( io_nType == DataType::DATE || io_nType == DataType::TIMESTAMP || io_nType == DataType::TIME) 290cdf0e10cSrcweir { 291*7b2bc0e6SDamjan Jovanovic ::rtl::OUString aField; 292*7b2bc0e6SDamjan Jovanovic aFirstLine.GetTokenSpecial(&aField,nStartPosFirstLine,m_cFieldDelimiter,'\0'); 293*7b2bc0e6SDamjan Jovanovic if ( aField.isEmpty() || 294*7b2bc0e6SDamjan Jovanovic (m_cStringDelimiter && m_cStringDelimiter == aField[0])) 295cdf0e10cSrcweir { 296cdf0e10cSrcweir } 297cdf0e10cSrcweir else 298cdf0e10cSrcweir { 299*7b2bc0e6SDamjan Jovanovic ::rtl::OUString aField2; 300cdf0e10cSrcweir if ( m_cStringDelimiter != '\0' ) 301*7b2bc0e6SDamjan Jovanovic aFirstLine.GetTokenSpecial(&aField2,nStartPosFirstLine2,m_cFieldDelimiter,m_cStringDelimiter); 302cdf0e10cSrcweir else 303cdf0e10cSrcweir aField2 = aField; 304*7b2bc0e6SDamjan Jovanovic if ( !aField2.isEmpty() ) 305cdf0e10cSrcweir { 306cdf0e10cSrcweir try 307cdf0e10cSrcweir { 308cdf0e10cSrcweir nIndex = m_xNumberFormatter->detectNumberFormat(::com::sun::star::util::NumberFormat::ALL,aField2); 309cdf0e10cSrcweir } 310cdf0e10cSrcweir catch(Exception&) 311cdf0e10cSrcweir { 312cdf0e10cSrcweir } 313cdf0e10cSrcweir } 314cdf0e10cSrcweir } 315cdf0e10cSrcweir } 316cdf0e10cSrcweir 317cdf0e10cSrcweir sal_Int32 nFlags = 0; 318cdf0e10cSrcweir if (bNumeric) 319cdf0e10cSrcweir { 320cdf0e10cSrcweir if (cDecimalDelimiter) 321cdf0e10cSrcweir { 322cdf0e10cSrcweir if(io_nPrecisions) 323cdf0e10cSrcweir { 324cdf0e10cSrcweir io_nType = DataType::DECIMAL; 325cdf0e10cSrcweir static const ::rtl::OUString s_sDECIMAL(RTL_CONSTASCII_USTRINGPARAM("DECIMAL")); 326cdf0e10cSrcweir o_sTypeName = s_sDECIMAL; 327cdf0e10cSrcweir } 328cdf0e10cSrcweir else 329cdf0e10cSrcweir { 330cdf0e10cSrcweir io_nType = DataType::DOUBLE; 331cdf0e10cSrcweir static const ::rtl::OUString s_sDOUBLE(RTL_CONSTASCII_USTRINGPARAM("DOUBLE")); 332cdf0e10cSrcweir o_sTypeName = s_sDOUBLE; 333cdf0e10cSrcweir } 334cdf0e10cSrcweir } 335cdf0e10cSrcweir else 336cdf0e10cSrcweir { 337cdf0e10cSrcweir io_nType = DataType::INTEGER; 338cdf0e10cSrcweir io_nPrecisions = 0; 339cdf0e10cSrcweir io_nScales = 0; 340cdf0e10cSrcweir } 341cdf0e10cSrcweir nFlags = ColumnSearch::BASIC; 342cdf0e10cSrcweir } 343cdf0e10cSrcweir else 344cdf0e10cSrcweir { 345cdf0e10cSrcweir switch (comphelper::getNumberFormatType(m_xNumberFormatter,nIndex)) 346cdf0e10cSrcweir { 347cdf0e10cSrcweir case NUMBERFORMAT_DATE: 348cdf0e10cSrcweir io_nType = DataType::DATE; 349cdf0e10cSrcweir { 350cdf0e10cSrcweir static const ::rtl::OUString s_sDATE(RTL_CONSTASCII_USTRINGPARAM("DATE")); 351cdf0e10cSrcweir o_sTypeName = s_sDATE; 352cdf0e10cSrcweir } 353cdf0e10cSrcweir break; 354cdf0e10cSrcweir case NUMBERFORMAT_DATETIME: 355cdf0e10cSrcweir io_nType = DataType::TIMESTAMP; 356cdf0e10cSrcweir { 357cdf0e10cSrcweir static const ::rtl::OUString s_sTIMESTAMP(RTL_CONSTASCII_USTRINGPARAM("TIMESTAMP")); 358cdf0e10cSrcweir o_sTypeName = s_sTIMESTAMP; 359cdf0e10cSrcweir } 360cdf0e10cSrcweir break; 361cdf0e10cSrcweir case NUMBERFORMAT_TIME: 362cdf0e10cSrcweir io_nType = DataType::TIME; 363cdf0e10cSrcweir { 364cdf0e10cSrcweir static const ::rtl::OUString s_sTIME(RTL_CONSTASCII_USTRINGPARAM("TIME")); 365cdf0e10cSrcweir o_sTypeName = s_sTIME; 366cdf0e10cSrcweir } 367cdf0e10cSrcweir break; 368cdf0e10cSrcweir default: 369cdf0e10cSrcweir io_nType = DataType::VARCHAR; 370cdf0e10cSrcweir io_nPrecisions = 0; // nyi: Daten koennen aber laenger sein! 371cdf0e10cSrcweir io_nScales = 0; 372cdf0e10cSrcweir { 373cdf0e10cSrcweir static const ::rtl::OUString s_sVARCHAR(RTL_CONSTASCII_USTRINGPARAM("VARCHAR")); 374cdf0e10cSrcweir o_sTypeName = s_sVARCHAR; 375cdf0e10cSrcweir } 376cdf0e10cSrcweir }; 377cdf0e10cSrcweir nFlags |= ColumnSearch::CHAR; 378cdf0e10cSrcweir } 379cdf0e10cSrcweir } 380cdf0e10cSrcweir else 381cdf0e10cSrcweir { 382*7b2bc0e6SDamjan Jovanovic ::rtl::OUString aField; 383*7b2bc0e6SDamjan Jovanovic aFirstLine.GetTokenSpecial(&aField,nStartPosFirstLine,m_cFieldDelimiter,'\0'); 384*7b2bc0e6SDamjan Jovanovic if ( aField.isEmpty() || 385*7b2bc0e6SDamjan Jovanovic (m_cStringDelimiter && m_cStringDelimiter == aField[0])) 386cdf0e10cSrcweir { 387cdf0e10cSrcweir if ( m_cStringDelimiter != '\0' ) 388*7b2bc0e6SDamjan Jovanovic aFirstLine.GetTokenSpecial(&aField,nStartPosFirstLine2,m_cFieldDelimiter,m_cStringDelimiter); 389cdf0e10cSrcweir else 390cdf0e10cSrcweir nStartPosFirstLine2 = nStartPosFirstLine; 391cdf0e10cSrcweir } 392cdf0e10cSrcweir else 393cdf0e10cSrcweir { 394*7b2bc0e6SDamjan Jovanovic ::rtl::OUString aField2; 395cdf0e10cSrcweir if ( m_cStringDelimiter != '\0' ) 396*7b2bc0e6SDamjan Jovanovic aFirstLine.GetTokenSpecial(&aField2,nStartPosFirstLine2,m_cFieldDelimiter,m_cStringDelimiter); 397cdf0e10cSrcweir } 398cdf0e10cSrcweir } 399cdf0e10cSrcweir } 400cdf0e10cSrcweir // ------------------------------------------------------------------------- 401cdf0e10cSrcweir OFlatTable::OFlatTable(sdbcx::OCollection* _pTables,OFlatConnection* _pConnection, 402cdf0e10cSrcweir const ::rtl::OUString& _Name, 403cdf0e10cSrcweir const ::rtl::OUString& _Type, 404cdf0e10cSrcweir const ::rtl::OUString& _Description , 405cdf0e10cSrcweir const ::rtl::OUString& _SchemaName, 406cdf0e10cSrcweir const ::rtl::OUString& _CatalogName 407cdf0e10cSrcweir ) : OFlatTable_BASE(_pTables,_pConnection,_Name, 408cdf0e10cSrcweir _Type, 409cdf0e10cSrcweir _Description, 410cdf0e10cSrcweir _SchemaName, 411cdf0e10cSrcweir _CatalogName) 412cdf0e10cSrcweir ,m_nStartRowFilePos(0) 413cdf0e10cSrcweir ,m_nRowPos(0) 414cdf0e10cSrcweir ,m_nMaxRowCount(0) 415cdf0e10cSrcweir ,m_cStringDelimiter(_pConnection->getStringDelimiter()) 416cdf0e10cSrcweir ,m_cFieldDelimiter(_pConnection->getFieldDelimiter()) 417cdf0e10cSrcweir ,m_bNeedToReadLine(false) 418cdf0e10cSrcweir { 419cdf0e10cSrcweir RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "flat", "Ocke.Janssen@sun.com", "OFlatTable::OFlatTable" ); 420cdf0e10cSrcweir 421cdf0e10cSrcweir } 422cdf0e10cSrcweir // ----------------------------------------------------------------------------- 423cdf0e10cSrcweir void OFlatTable::construct() 424cdf0e10cSrcweir { 425cdf0e10cSrcweir RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "flat", "Ocke.Janssen@sun.com", "OFlatTable::construct" ); 426cdf0e10cSrcweir SvtSysLocale aLocale; 427cdf0e10cSrcweir ::com::sun::star::lang::Locale aAppLocale(aLocale.GetLocaleDataPtr()->getLocale()); 428cdf0e10cSrcweir Sequence< ::com::sun::star::uno::Any > aArg(1); 429cdf0e10cSrcweir aArg[0] <<= aAppLocale; 430cdf0e10cSrcweir 431cdf0e10cSrcweir Reference< ::com::sun::star::util::XNumberFormatsSupplier > xSupplier(m_pConnection->getDriver()->getFactory()->createInstanceWithArguments(::rtl::OUString::createFromAscii("com.sun.star.util.NumberFormatsSupplier"),aArg),UNO_QUERY); 432cdf0e10cSrcweir m_xNumberFormatter = Reference< ::com::sun::star::util::XNumberFormatter >(m_pConnection->getDriver()->getFactory()->createInstance(::rtl::OUString::createFromAscii("com.sun.star.util.NumberFormatter")),UNO_QUERY); 433cdf0e10cSrcweir m_xNumberFormatter->attachNumberFormatsSupplier(xSupplier); 434cdf0e10cSrcweir Reference<XPropertySet> xProp(xSupplier->getNumberFormatSettings(),UNO_QUERY); 435cdf0e10cSrcweir xProp->getPropertyValue(::rtl::OUString::createFromAscii("NullDate")) >>= m_aNullDate; 436cdf0e10cSrcweir 437cdf0e10cSrcweir INetURLObject aURL; 438cdf0e10cSrcweir aURL.SetURL(getEntry()); 439cdf0e10cSrcweir 440cdf0e10cSrcweir if(aURL.getExtension() != rtl::OUString(m_pConnection->getExtension())) 441cdf0e10cSrcweir aURL.setExtension(m_pConnection->getExtension()); 442cdf0e10cSrcweir 443cdf0e10cSrcweir String aFileName = aURL.GetMainURL(INetURLObject::NO_DECODE); 444cdf0e10cSrcweir 445cdf0e10cSrcweir m_pFileStream = createStream_simpleError( aFileName,STREAM_READWRITE | STREAM_NOCREATE | STREAM_SHARE_DENYWRITE); 446cdf0e10cSrcweir 447cdf0e10cSrcweir if(!m_pFileStream) 448cdf0e10cSrcweir m_pFileStream = createStream_simpleError( aFileName,STREAM_READ | STREAM_NOCREATE | STREAM_SHARE_DENYNONE); 449cdf0e10cSrcweir 450cdf0e10cSrcweir if(m_pFileStream) 451cdf0e10cSrcweir { 452cdf0e10cSrcweir m_pFileStream->Seek(STREAM_SEEK_TO_END); 453cdf0e10cSrcweir sal_Int32 nSize = m_pFileStream->Tell(); 454cdf0e10cSrcweir m_pFileStream->Seek(STREAM_SEEK_TO_BEGIN); 455cdf0e10cSrcweir 456cdf0e10cSrcweir // Buffersize abhaengig von der Filegroesse 457cdf0e10cSrcweir m_pFileStream->SetBufferSize(nSize > 1000000 ? 32768 : 458cdf0e10cSrcweir nSize > 100000 ? 16384 : 459cdf0e10cSrcweir nSize > 10000 ? 4096 : 1024); 460cdf0e10cSrcweir 461cdf0e10cSrcweir fillColumns(aAppLocale); 462cdf0e10cSrcweir 463cdf0e10cSrcweir refreshColumns(); 464cdf0e10cSrcweir } 465cdf0e10cSrcweir } 466cdf0e10cSrcweir // ------------------------------------------------------------------------- 467cdf0e10cSrcweir String OFlatTable::getEntry() 468cdf0e10cSrcweir { 469cdf0e10cSrcweir RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "flat", "Ocke.Janssen@sun.com", "OFlatTable::getEntry" ); 470cdf0e10cSrcweir ::rtl::OUString sURL; 471cdf0e10cSrcweir try 472cdf0e10cSrcweir { 473cdf0e10cSrcweir Reference< XResultSet > xDir = m_pConnection->getDir()->getStaticResultSet(); 474cdf0e10cSrcweir Reference< XRow> xRow(xDir,UNO_QUERY); 475cdf0e10cSrcweir ::rtl::OUString sName; 476cdf0e10cSrcweir ::rtl::OUString sExt; 477cdf0e10cSrcweir 478cdf0e10cSrcweir INetURLObject aURL; 479cdf0e10cSrcweir xDir->beforeFirst(); 480cdf0e10cSrcweir static const ::rtl::OUString s_sSeparator(RTL_CONSTASCII_USTRINGPARAM("/")); 481cdf0e10cSrcweir while(xDir->next()) 482cdf0e10cSrcweir { 483cdf0e10cSrcweir sName = xRow->getString(1); 484cdf0e10cSrcweir aURL.SetSmartProtocol(INET_PROT_FILE); 485cdf0e10cSrcweir String sUrl = m_pConnection->getURL() + s_sSeparator + sName; 486cdf0e10cSrcweir aURL.SetSmartURL( sUrl ); 487cdf0e10cSrcweir 488cdf0e10cSrcweir // cut the extension 489cdf0e10cSrcweir sExt = aURL.getExtension(); 490cdf0e10cSrcweir 491cdf0e10cSrcweir // name and extension have to coincide 492cdf0e10cSrcweir if ( m_pConnection->matchesExtension( sExt ) ) 493cdf0e10cSrcweir { 494*7b2bc0e6SDamjan Jovanovic if ( !sExt.isEmpty() ) 495cdf0e10cSrcweir sName = sName.replaceAt(sName.getLength()-(sExt.getLength()+1),sExt.getLength()+1,::rtl::OUString()); 496cdf0e10cSrcweir if ( sName == m_Name ) 497cdf0e10cSrcweir { 498cdf0e10cSrcweir Reference< XContentAccess > xContentAccess( xDir, UNO_QUERY ); 499cdf0e10cSrcweir sURL = xContentAccess->queryContentIdentifierString(); 500cdf0e10cSrcweir break; 501cdf0e10cSrcweir } 502cdf0e10cSrcweir } 503cdf0e10cSrcweir } 504cdf0e10cSrcweir xDir->beforeFirst(); // move back to before first record 505cdf0e10cSrcweir } 506cdf0e10cSrcweir catch(Exception&) 507cdf0e10cSrcweir { 508cdf0e10cSrcweir OSL_ASSERT(0); 509cdf0e10cSrcweir } 510cdf0e10cSrcweir return sURL.getStr(); 511cdf0e10cSrcweir } 512cdf0e10cSrcweir // ------------------------------------------------------------------------- 513cdf0e10cSrcweir void OFlatTable::refreshColumns() 514cdf0e10cSrcweir { 515cdf0e10cSrcweir RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "flat", "Ocke.Janssen@sun.com", "OFlatTable::refreshColumns" ); 516cdf0e10cSrcweir ::osl::MutexGuard aGuard( m_aMutex ); 517cdf0e10cSrcweir 518cdf0e10cSrcweir TStringVector aVector; 519cdf0e10cSrcweir aVector.reserve(m_aColumns->get().size()); 520cdf0e10cSrcweir 521cdf0e10cSrcweir for(OSQLColumns::Vector::const_iterator aIter = m_aColumns->get().begin();aIter != m_aColumns->get().end();++aIter) 522cdf0e10cSrcweir aVector.push_back(Reference< XNamed>(*aIter,UNO_QUERY)->getName()); 523cdf0e10cSrcweir 524cdf0e10cSrcweir if(m_pColumns) 525cdf0e10cSrcweir m_pColumns->reFill(aVector); 526cdf0e10cSrcweir else 527cdf0e10cSrcweir m_pColumns = new OFlatColumns(this,m_aMutex,aVector); 528cdf0e10cSrcweir } 529cdf0e10cSrcweir 530cdf0e10cSrcweir // ------------------------------------------------------------------------- 531cdf0e10cSrcweir void SAL_CALL OFlatTable::disposing(void) 532cdf0e10cSrcweir { 533cdf0e10cSrcweir RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "flat", "Ocke.Janssen@sun.com", "OFlatTable::disposing" ); 534cdf0e10cSrcweir OFileTable::disposing(); 535cdf0e10cSrcweir ::osl::MutexGuard aGuard(m_aMutex); 536cdf0e10cSrcweir m_aColumns = NULL; 537cdf0e10cSrcweir } 538cdf0e10cSrcweir // ------------------------------------------------------------------------- 539cdf0e10cSrcweir Sequence< Type > SAL_CALL OFlatTable::getTypes( ) throw(RuntimeException) 540cdf0e10cSrcweir { 541cdf0e10cSrcweir Sequence< Type > aTypes = OTable_TYPEDEF::getTypes(); 542cdf0e10cSrcweir ::std::vector<Type> aOwnTypes; 543cdf0e10cSrcweir aOwnTypes.reserve(aTypes.getLength()); 544cdf0e10cSrcweir const Type* pBegin = aTypes.getConstArray(); 545cdf0e10cSrcweir const Type* pEnd = pBegin + aTypes.getLength(); 546cdf0e10cSrcweir for(;pBegin != pEnd;++pBegin) 547cdf0e10cSrcweir { 548cdf0e10cSrcweir if(!(*pBegin == ::getCppuType((const Reference<XKeysSupplier>*)0) || 549cdf0e10cSrcweir *pBegin == ::getCppuType((const Reference<XRename>*)0) || 550cdf0e10cSrcweir *pBegin == ::getCppuType((const Reference<XIndexesSupplier>*)0) || 551cdf0e10cSrcweir *pBegin == ::getCppuType((const Reference<XAlterTable>*)0) || 552cdf0e10cSrcweir *pBegin == ::getCppuType((const Reference<XDataDescriptorFactory>*)0))) 553cdf0e10cSrcweir { 554cdf0e10cSrcweir aOwnTypes.push_back(*pBegin); 555cdf0e10cSrcweir } 556cdf0e10cSrcweir } 557cdf0e10cSrcweir Type *pTypes = aOwnTypes.empty() ? 0 : &aOwnTypes[0]; 558cdf0e10cSrcweir return Sequence< Type >(pTypes, aOwnTypes.size()); 559cdf0e10cSrcweir } 560cdf0e10cSrcweir 561cdf0e10cSrcweir // ------------------------------------------------------------------------- 562cdf0e10cSrcweir Any SAL_CALL OFlatTable::queryInterface( const Type & rType ) throw(RuntimeException) 563cdf0e10cSrcweir { 564cdf0e10cSrcweir if( rType == ::getCppuType((const Reference<XKeysSupplier>*)0) || 565cdf0e10cSrcweir rType == ::getCppuType((const Reference<XIndexesSupplier>*)0) || 566cdf0e10cSrcweir rType == ::getCppuType((const Reference<XRename>*)0) || 567cdf0e10cSrcweir rType == ::getCppuType((const Reference<XAlterTable>*)0) || 568cdf0e10cSrcweir rType == ::getCppuType((const Reference<XDataDescriptorFactory>*)0)) 569cdf0e10cSrcweir return Any(); 570cdf0e10cSrcweir 571cdf0e10cSrcweir Any aRet = OTable_TYPEDEF::queryInterface(rType); 572cdf0e10cSrcweir return aRet.hasValue() ? aRet : ::cppu::queryInterface(rType,static_cast< ::com::sun::star::lang::XUnoTunnel*> (this)); 573cdf0e10cSrcweir } 574cdf0e10cSrcweir 575cdf0e10cSrcweir //-------------------------------------------------------------------------- 576cdf0e10cSrcweir Sequence< sal_Int8 > OFlatTable::getUnoTunnelImplementationId() 577cdf0e10cSrcweir { 578cdf0e10cSrcweir static ::cppu::OImplementationId * pId = 0; 579cdf0e10cSrcweir if (! pId) 580cdf0e10cSrcweir { 581cdf0e10cSrcweir ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); 582cdf0e10cSrcweir if (! pId) 583cdf0e10cSrcweir { 584cdf0e10cSrcweir static ::cppu::OImplementationId aId; 585cdf0e10cSrcweir pId = &aId; 586cdf0e10cSrcweir } 587cdf0e10cSrcweir } 588cdf0e10cSrcweir return pId->getImplementationId(); 589cdf0e10cSrcweir } 590cdf0e10cSrcweir 591cdf0e10cSrcweir // com::sun::star::lang::XUnoTunnel 592cdf0e10cSrcweir //------------------------------------------------------------------ 593cdf0e10cSrcweir sal_Int64 OFlatTable::getSomething( const Sequence< sal_Int8 > & rId ) throw (RuntimeException) 594cdf0e10cSrcweir { 595cdf0e10cSrcweir RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "flat", "Ocke.Janssen@sun.com", "OFlatTable::getSomething" ); 596cdf0e10cSrcweir return (rId.getLength() == 16 && 0 == rtl_compareMemory(getUnoTunnelImplementationId().getConstArray(), rId.getConstArray(), 16 ) ) 597cdf0e10cSrcweir ? reinterpret_cast< sal_Int64 >( this ) 598cdf0e10cSrcweir : OFlatTable_BASE::getSomething(rId); 599cdf0e10cSrcweir } 600cdf0e10cSrcweir //------------------------------------------------------------------ 601cdf0e10cSrcweir sal_Bool OFlatTable::fetchRow(OValueRefRow& _rRow,const OSQLColumns & _rCols,sal_Bool bIsTable,sal_Bool bRetrieveData) 602cdf0e10cSrcweir { 603cdf0e10cSrcweir RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "flat", "Ocke.Janssen@sun.com", "OFlatTable::fetchRow" ); 604cdf0e10cSrcweir *(_rRow->get())[0] = m_nFilePos; 605cdf0e10cSrcweir 606cdf0e10cSrcweir if (!bRetrieveData) 607cdf0e10cSrcweir return sal_True; 608cdf0e10cSrcweir if ( m_bNeedToReadLine ) 609cdf0e10cSrcweir { 610cdf0e10cSrcweir sal_Int32 nCurrentPos = 0; 611cdf0e10cSrcweir m_pFileStream->Seek(m_nFilePos); 612cdf0e10cSrcweir readLine(nCurrentPos); 613cdf0e10cSrcweir m_bNeedToReadLine = false; 614cdf0e10cSrcweir } 615cdf0e10cSrcweir 616cdf0e10cSrcweir OFlatConnection* pConnection = (OFlatConnection*)m_pConnection; 617cdf0e10cSrcweir const sal_Unicode cDecimalDelimiter = pConnection->getDecimalDelimiter(); 618cdf0e10cSrcweir const sal_Unicode cThousandDelimiter = pConnection->getThousandDelimiter(); 619cdf0e10cSrcweir // Felder: 620*7b2bc0e6SDamjan Jovanovic sal_Int32 nStartPos = 0; 621*7b2bc0e6SDamjan Jovanovic ::rtl::OUString aStr; 622cdf0e10cSrcweir OSQLColumns::Vector::const_iterator aIter = _rCols.get().begin(); 623cdf0e10cSrcweir OSQLColumns::Vector::const_iterator aEnd = _rCols.get().end(); 624cdf0e10cSrcweir const OValueRefVector::Vector::size_type nCount = _rRow->get().size(); 625cdf0e10cSrcweir for (OValueRefVector::Vector::size_type i = 1; aIter != aEnd && i < nCount; 626cdf0e10cSrcweir ++aIter, i++) 627cdf0e10cSrcweir { 628*7b2bc0e6SDamjan Jovanovic m_aCurrentLine.GetTokenSpecial(&aStr,nStartPos,m_cFieldDelimiter,m_cStringDelimiter); 629cdf0e10cSrcweir 630*7b2bc0e6SDamjan Jovanovic if (aStr.isEmpty()) 631cdf0e10cSrcweir (_rRow->get())[i]->setNull(); 632cdf0e10cSrcweir else 633cdf0e10cSrcweir { 634cdf0e10cSrcweir // Laengen je nach Datentyp: 635cdf0e10cSrcweir sal_Int32 nLen, 636cdf0e10cSrcweir nType = 0; 637cdf0e10cSrcweir if(bIsTable) 638cdf0e10cSrcweir { 639cdf0e10cSrcweir nLen = m_aPrecisions[i-1]; 640cdf0e10cSrcweir nType = m_aTypes[i-1]; 641cdf0e10cSrcweir } 642cdf0e10cSrcweir else 643cdf0e10cSrcweir { 644cdf0e10cSrcweir Reference< XPropertySet> xColumn = *aIter; 645cdf0e10cSrcweir xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_PRECISION)) >>= nLen; 646cdf0e10cSrcweir xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TYPE)) >>= nType; 647cdf0e10cSrcweir } 648cdf0e10cSrcweir switch(nType) 649cdf0e10cSrcweir { 650cdf0e10cSrcweir case DataType::TIMESTAMP: 651cdf0e10cSrcweir case DataType::DATE: 652cdf0e10cSrcweir case DataType::TIME: 653cdf0e10cSrcweir { 654cdf0e10cSrcweir try 655cdf0e10cSrcweir { 656cdf0e10cSrcweir double nRes = m_xNumberFormatter->convertStringToNumber(::com::sun::star::util::NumberFormat::ALL,aStr); 657cdf0e10cSrcweir 658cdf0e10cSrcweir switch(nType) 659cdf0e10cSrcweir { 660cdf0e10cSrcweir case DataType::DATE: 661cdf0e10cSrcweir *(_rRow->get())[i] = ::dbtools::DBTypeConversion::toDouble(::dbtools::DBTypeConversion::toDate(nRes,m_aNullDate)); 662cdf0e10cSrcweir break; 663cdf0e10cSrcweir case DataType::TIMESTAMP: 664cdf0e10cSrcweir *(_rRow->get())[i] = ::dbtools::DBTypeConversion::toDouble(::dbtools::DBTypeConversion::toDateTime(nRes,m_aNullDate)); 665cdf0e10cSrcweir break; 666cdf0e10cSrcweir default: 667cdf0e10cSrcweir *(_rRow->get())[i] = ::dbtools::DBTypeConversion::toDouble(::dbtools::DBTypeConversion::toTime(nRes)); 668cdf0e10cSrcweir } 669cdf0e10cSrcweir } 670cdf0e10cSrcweir catch(Exception&) 671cdf0e10cSrcweir { 672cdf0e10cSrcweir (_rRow->get())[i]->setNull(); 673cdf0e10cSrcweir } 674cdf0e10cSrcweir } break; 675cdf0e10cSrcweir case DataType::DOUBLE: 676cdf0e10cSrcweir case DataType::INTEGER: 677cdf0e10cSrcweir case DataType::DECIMAL: // #99178# OJ 678cdf0e10cSrcweir case DataType::NUMERIC: 679cdf0e10cSrcweir { 680cdf0e10cSrcweir 681cdf0e10cSrcweir String aStrConverted; 682cdf0e10cSrcweir if ( DataType::INTEGER != nType ) 683cdf0e10cSrcweir { 684*7b2bc0e6SDamjan Jovanovic sal_Unicode* pData = aStrConverted.AllocBuffer(aStr.getLength()); 685cdf0e10cSrcweir const sal_Unicode* pStart = pData; 686cdf0e10cSrcweir 687cdf0e10cSrcweir OSL_ENSURE(cDecimalDelimiter && nType != DataType::INTEGER || 688cdf0e10cSrcweir !cDecimalDelimiter && nType == DataType::INTEGER, 689cdf0e10cSrcweir "FalscherTyp"); 690cdf0e10cSrcweir 691cdf0e10cSrcweir // In Standard-Notation (DezimalPUNKT ohne Tausender-Komma) umwandeln: 692*7b2bc0e6SDamjan Jovanovic for (sal_Int32 j = 0; j < aStr.getLength(); ++j) 693cdf0e10cSrcweir { 694*7b2bc0e6SDamjan Jovanovic const sal_Unicode cChar = aStr[j]; 695cdf0e10cSrcweir if (cDecimalDelimiter && cChar == cDecimalDelimiter) 696cdf0e10cSrcweir *pData++ = '.'; 697cdf0e10cSrcweir //aStrConverted.Append( '.' ); 698cdf0e10cSrcweir else if ( cChar == '.' ) // special case, if decimal seperator isn't '.' we have to put the string after it 699cdf0e10cSrcweir continue; // #99189# OJ 700cdf0e10cSrcweir else if (cThousandDelimiter && cChar == cThousandDelimiter) 701cdf0e10cSrcweir { 702cdf0e10cSrcweir // weglassen 703cdf0e10cSrcweir } 704cdf0e10cSrcweir else 705cdf0e10cSrcweir *pData++ = cChar; 706cdf0e10cSrcweir //aStrConverted.Append(cChar); 707*7b2bc0e6SDamjan Jovanovic } // for (sal_Int32 j = 0; j < aStr.Len(); ++j) 708cdf0e10cSrcweir aStrConverted.ReleaseBufferAccess(xub_StrLen(pData - pStart)); 709cdf0e10cSrcweir } // if ( DataType::INTEGER != nType ) 710cdf0e10cSrcweir else 711cdf0e10cSrcweir { 712cdf0e10cSrcweir aStrConverted = aStr; 713cdf0e10cSrcweir if ( cThousandDelimiter ) 714cdf0e10cSrcweir aStrConverted.EraseAllChars(cThousandDelimiter); 715cdf0e10cSrcweir } 716cdf0e10cSrcweir const double nVal = ::rtl::math::stringToDouble(aStrConverted,'.',',',NULL,NULL); 717cdf0e10cSrcweir 718cdf0e10cSrcweir // #99178# OJ 719cdf0e10cSrcweir if ( DataType::DECIMAL == nType || DataType::NUMERIC == nType ) 720cdf0e10cSrcweir *(_rRow->get())[i] = ::rtl::OUString::valueOf(nVal); 721cdf0e10cSrcweir else 722cdf0e10cSrcweir *(_rRow->get())[i] = nVal; 723cdf0e10cSrcweir } break; 724cdf0e10cSrcweir 725cdf0e10cSrcweir default: 726cdf0e10cSrcweir { 727cdf0e10cSrcweir // Wert als String in Variable der Row uebernehmen 728cdf0e10cSrcweir *(_rRow->get())[i] = ORowSetValue(aStr); 729cdf0e10cSrcweir } 730cdf0e10cSrcweir break; 731cdf0e10cSrcweir } // switch(nType) 732cdf0e10cSrcweir (_rRow->get())[i]->setTypeKind(nType); 733cdf0e10cSrcweir } 734cdf0e10cSrcweir } 735cdf0e10cSrcweir return sal_True; 736cdf0e10cSrcweir } 737cdf0e10cSrcweir void OFlatTable::refreshHeader() 738cdf0e10cSrcweir { 739cdf0e10cSrcweir m_nRowPos = 0; 740cdf0e10cSrcweir } 741cdf0e10cSrcweir // ----------------------------------------------------------------------------- 742cdf0e10cSrcweir sal_Bool OFlatTable::seekRow(IResultSetHelper::Movement eCursorPosition, sal_Int32 nOffset, sal_Int32& nCurPos) 743cdf0e10cSrcweir { 744cdf0e10cSrcweir RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "flat", "Ocke.Janssen@sun.com", "OFlatTable::seekRow" ); 745cdf0e10cSrcweir OSL_ENSURE(m_pFileStream,"OFlatTable::seekRow: FileStream is NULL!"); 746cdf0e10cSrcweir // ---------------------------------------------------------- 747cdf0e10cSrcweir // Positionierung vorbereiten: 748cdf0e10cSrcweir m_nFilePos = nCurPos; 749cdf0e10cSrcweir 750cdf0e10cSrcweir switch(eCursorPosition) 751cdf0e10cSrcweir { 752cdf0e10cSrcweir case IResultSetHelper::FIRST: 753cdf0e10cSrcweir m_nRowPos = 0; 754cdf0e10cSrcweir // run through 755cdf0e10cSrcweir case IResultSetHelper::NEXT: 756cdf0e10cSrcweir { 757cdf0e10cSrcweir ++m_nRowPos; 758cdf0e10cSrcweir ::std::map<sal_Int32,TRowPositionsInFile::iterator>::const_iterator aFind = m_aRowPosToFilePos.find(m_nRowPos); 759cdf0e10cSrcweir m_bNeedToReadLine = aFind != m_aRowPosToFilePos.end(); 760cdf0e10cSrcweir if ( m_bNeedToReadLine ) 761cdf0e10cSrcweir { 762cdf0e10cSrcweir m_nFilePos = aFind->second->first; 763cdf0e10cSrcweir nCurPos = aFind->second->second; 764cdf0e10cSrcweir } // if ( m_bNeedToReadLine ) 765cdf0e10cSrcweir else 766cdf0e10cSrcweir { 767cdf0e10cSrcweir if ( m_nRowPos == 1 ) 768cdf0e10cSrcweir m_nFilePos = m_nStartRowFilePos; 769cdf0e10cSrcweir m_pFileStream->Seek(m_nFilePos); 770cdf0e10cSrcweir if ( m_pFileStream->IsEof() || !readLine(nCurPos) /*|| !checkHeaderLine()*/) 771cdf0e10cSrcweir { 772cdf0e10cSrcweir m_nMaxRowCount = m_nRowPos -1; 773cdf0e10cSrcweir return sal_False; 774cdf0e10cSrcweir } // if ( m_pFileStream->IsEof() || !readLine(nCurPos) /*|| !checkHeaderLine()*/) 775cdf0e10cSrcweir 776cdf0e10cSrcweir TRowPositionsInFile::iterator aPos = m_aFilePosToEndLinePos.insert(TRowPositionsInFile::value_type(m_nFilePos,nCurPos)).first; 777cdf0e10cSrcweir m_aRowPosToFilePos.insert(::std::map<sal_Int32,TRowPositionsInFile::iterator>::value_type(m_nRowPos,aPos)); 778cdf0e10cSrcweir } 779cdf0e10cSrcweir } 780cdf0e10cSrcweir 781cdf0e10cSrcweir break; 782cdf0e10cSrcweir case IResultSetHelper::PRIOR: 783cdf0e10cSrcweir --m_nRowPos; 784cdf0e10cSrcweir if(m_nRowPos > 0) 785cdf0e10cSrcweir { 786cdf0e10cSrcweir TRowPositionsInFile::iterator aPositions = m_aRowPosToFilePos[m_nRowPos]; 787cdf0e10cSrcweir m_nFilePos = aPositions->first; 788cdf0e10cSrcweir nCurPos = aPositions->second; 789cdf0e10cSrcweir m_bNeedToReadLine = true; 790cdf0e10cSrcweir } 791cdf0e10cSrcweir else 792cdf0e10cSrcweir m_nRowPos = 0; 793cdf0e10cSrcweir 794cdf0e10cSrcweir break; 795cdf0e10cSrcweir case IResultSetHelper::LAST: 796cdf0e10cSrcweir if ( m_nMaxRowCount ) 797cdf0e10cSrcweir { 798cdf0e10cSrcweir ::std::map<sal_Int32,TRowPositionsInFile::iterator>::reverse_iterator aLastPos = m_aRowPosToFilePos.rbegin(); 799cdf0e10cSrcweir m_nRowPos = aLastPos->first; 800cdf0e10cSrcweir m_nFilePos = aLastPos->second->first; 801cdf0e10cSrcweir nCurPos = aLastPos->second->second; 802cdf0e10cSrcweir 803cdf0e10cSrcweir //m_pFileStream->Seek(m_nFilePos); 804cdf0e10cSrcweir m_bNeedToReadLine = true; 805cdf0e10cSrcweir //if ( m_pFileStream->IsEof() /*|| !checkHeaderLine()*/ || !readLine(nCurPos) ) 806cdf0e10cSrcweir // return sal_False; 807cdf0e10cSrcweir } 808cdf0e10cSrcweir else 809cdf0e10cSrcweir { 810cdf0e10cSrcweir while(seekRow(IResultSetHelper::NEXT,1,nCurPos)) ; // run through after last row 811cdf0e10cSrcweir // now I know all 812cdf0e10cSrcweir seekRow(IResultSetHelper::PRIOR,1,nCurPos); 813cdf0e10cSrcweir } 814cdf0e10cSrcweir break; 815cdf0e10cSrcweir case IResultSetHelper::RELATIVE: 816cdf0e10cSrcweir if(nOffset > 0) 817cdf0e10cSrcweir { 818cdf0e10cSrcweir for(sal_Int32 i = 0;i<nOffset;++i) 819cdf0e10cSrcweir seekRow(IResultSetHelper::NEXT,1,nCurPos); 820cdf0e10cSrcweir } 821cdf0e10cSrcweir else if(nOffset < 0) 822cdf0e10cSrcweir { 823cdf0e10cSrcweir for(sal_Int32 i = nOffset;i;++i) 824cdf0e10cSrcweir seekRow(IResultSetHelper::PRIOR,1,nCurPos); 825cdf0e10cSrcweir } 826cdf0e10cSrcweir break; 827cdf0e10cSrcweir case IResultSetHelper::ABSOLUTE: 828cdf0e10cSrcweir { 829cdf0e10cSrcweir if(nOffset < 0) 830cdf0e10cSrcweir nOffset = m_nRowPos + nOffset; 831cdf0e10cSrcweir ::std::map<sal_Int32,TRowPositionsInFile::iterator>::const_iterator aIter = m_aRowPosToFilePos.find(nOffset); 832cdf0e10cSrcweir if(aIter != m_aRowPosToFilePos.end()) 833cdf0e10cSrcweir { 834cdf0e10cSrcweir m_nFilePos = aIter->second->first; 835cdf0e10cSrcweir nCurPos = aIter->second->second; 836cdf0e10cSrcweir //m_pFileStream->Seek(m_nFilePos); 837cdf0e10cSrcweir m_bNeedToReadLine = true; 838cdf0e10cSrcweir //if ( m_pFileStream->IsEof() /*|| !checkHeaderLine()*/ || !readLine(nCurPos) ) 839cdf0e10cSrcweir // return sal_False; 840cdf0e10cSrcweir } 841cdf0e10cSrcweir else if(m_nMaxRowCount && nOffset > m_nMaxRowCount) // offset is outside the table 842cdf0e10cSrcweir { 843cdf0e10cSrcweir m_nRowPos = m_nMaxRowCount; 844cdf0e10cSrcweir return sal_False; 845cdf0e10cSrcweir } 846cdf0e10cSrcweir else 847cdf0e10cSrcweir { 848cdf0e10cSrcweir aIter = m_aRowPosToFilePos.upper_bound(nOffset); 849cdf0e10cSrcweir if(aIter == m_aRowPosToFilePos.end()) 850cdf0e10cSrcweir { 851cdf0e10cSrcweir ::std::map<sal_Int32,TRowPositionsInFile::iterator>::reverse_iterator aLastPos = m_aRowPosToFilePos.rbegin(); 852cdf0e10cSrcweir m_nRowPos = aLastPos->first; 853cdf0e10cSrcweir nCurPos = m_nFilePos = aLastPos->second->first; 854cdf0e10cSrcweir while(m_nRowPos != nOffset) 855cdf0e10cSrcweir seekRow(IResultSetHelper::NEXT,1,nCurPos); 856cdf0e10cSrcweir } 857cdf0e10cSrcweir else 858cdf0e10cSrcweir { 859cdf0e10cSrcweir --aIter; 860cdf0e10cSrcweir m_nRowPos = aIter->first; 861cdf0e10cSrcweir m_nFilePos = aIter->second->first; 862cdf0e10cSrcweir nCurPos = aIter->second->second; 863cdf0e10cSrcweir //m_pFileStream->Seek(m_nFilePos); 864cdf0e10cSrcweir m_bNeedToReadLine = true; 865cdf0e10cSrcweir //if ( m_pFileStream->IsEof() /*|| !checkHeaderLine()*/ || !readLine(nCurPos) ) 866cdf0e10cSrcweir // return sal_False; 867cdf0e10cSrcweir } 868cdf0e10cSrcweir } 869cdf0e10cSrcweir } 870cdf0e10cSrcweir 871cdf0e10cSrcweir break; 872cdf0e10cSrcweir case IResultSetHelper::BOOKMARK: 873cdf0e10cSrcweir { 874cdf0e10cSrcweir TRowPositionsInFile::const_iterator aFind = m_aFilePosToEndLinePos.find(nOffset); 875cdf0e10cSrcweir m_bNeedToReadLine = aFind != m_aFilePosToEndLinePos.end(); 876cdf0e10cSrcweir if ( m_bNeedToReadLine ) 877cdf0e10cSrcweir { 878cdf0e10cSrcweir m_nFilePos = aFind->first; 879cdf0e10cSrcweir nCurPos = aFind->second; 880cdf0e10cSrcweir } 881cdf0e10cSrcweir else 882cdf0e10cSrcweir { 883cdf0e10cSrcweir m_nFilePos = nOffset; 884cdf0e10cSrcweir m_pFileStream->Seek(nOffset); 885cdf0e10cSrcweir if (m_pFileStream->IsEof() || !readLine(nCurPos) ) 886cdf0e10cSrcweir return sal_False; 887cdf0e10cSrcweir } 888cdf0e10cSrcweir break; 889cdf0e10cSrcweir } 890cdf0e10cSrcweir } 891cdf0e10cSrcweir 892cdf0e10cSrcweir //nCurPos = m_nFilePos; 893cdf0e10cSrcweir 894cdf0e10cSrcweir return sal_True; 895cdf0e10cSrcweir } 896cdf0e10cSrcweir // ----------------------------------------------------------------------------- 897cdf0e10cSrcweir sal_Bool OFlatTable::readLine(sal_Int32& _rnCurrentPos) 898cdf0e10cSrcweir { 8996b41ff7aSdamjan return readLine(m_aCurrentLine, _rnCurrentPos); 9006b41ff7aSdamjan } 9016b41ff7aSdamjan // ----------------------------------------------------------------------------- 902*7b2bc0e6SDamjan Jovanovic sal_Bool OFlatTable::readLine(QuotedTokenizedString& lineOut, sal_Int32& _rnCurrentPos) 9036b41ff7aSdamjan { 904cdf0e10cSrcweir RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "flat", "Ocke.Janssen@sun.com", "OFlatTable::readLine" ); 905cdf0e10cSrcweir const rtl_TextEncoding nEncoding = m_pConnection->getTextEncoding(); 906*7b2bc0e6SDamjan Jovanovic ::rtl::OUStringBuffer lineBuffer( 4096 ); 907*7b2bc0e6SDamjan Jovanovic ::rtl::OUString separator = ::rtl::OUString(); 908*7b2bc0e6SDamjan Jovanovic static ::rtl::OUString lf = ::rtl::OUString::createFromAscii( "\n" ); 909*7b2bc0e6SDamjan Jovanovic bool isFieldStarting = true; 910*7b2bc0e6SDamjan Jovanovic bool inQuotedField = false; 911*7b2bc0e6SDamjan Jovanovic sal_Bool result = sal_True; 912*7b2bc0e6SDamjan Jovanovic do 913*7b2bc0e6SDamjan Jovanovic { 914*7b2bc0e6SDamjan Jovanovic ::rtl::OUString line; 9156b41ff7aSdamjan m_pFileStream->ReadByteStringLine(line,nEncoding); 916cdf0e10cSrcweir if (m_pFileStream->IsEof()) 917*7b2bc0e6SDamjan Jovanovic { 918*7b2bc0e6SDamjan Jovanovic result = sal_False; 919*7b2bc0e6SDamjan Jovanovic break; 920*7b2bc0e6SDamjan Jovanovic } 921cdf0e10cSrcweir 922*7b2bc0e6SDamjan Jovanovic bool wasPreviousQuote = false; 923*7b2bc0e6SDamjan Jovanovic for ( sal_Int32 i = 0; i < line.getLength(); i++ ) 924cdf0e10cSrcweir { 925*7b2bc0e6SDamjan Jovanovic sal_Unicode ch = line[i]; 926*7b2bc0e6SDamjan Jovanovic if ( ch == m_cStringDelimiter ) 927bc1fc15fSdamjan { 928bc1fc15fSdamjan if ( isFieldStarting ) 929bc1fc15fSdamjan { 930bc1fc15fSdamjan isFieldStarting = false; 931*7b2bc0e6SDamjan Jovanovic inQuotedField = true; 932cdf0e10cSrcweir } 933cdf0e10cSrcweir else 934*7b2bc0e6SDamjan Jovanovic { 935*7b2bc0e6SDamjan Jovanovic wasPreviousQuote = !wasPreviousQuote; 936*7b2bc0e6SDamjan Jovanovic } 937*7b2bc0e6SDamjan Jovanovic } 938*7b2bc0e6SDamjan Jovanovic else if ( ch == m_cFieldDelimiter ) 939*7b2bc0e6SDamjan Jovanovic { 940*7b2bc0e6SDamjan Jovanovic if ( !inQuotedField ) 941*7b2bc0e6SDamjan Jovanovic isFieldStarting = true; 942cdf0e10cSrcweir } 943bc1fc15fSdamjan else 944*7b2bc0e6SDamjan Jovanovic { 945*7b2bc0e6SDamjan Jovanovic if ( wasPreviousQuote ) 946*7b2bc0e6SDamjan Jovanovic inQuotedField = false; 947*7b2bc0e6SDamjan Jovanovic wasPreviousQuote = false; 948bc1fc15fSdamjan } 949*7b2bc0e6SDamjan Jovanovic } 950*7b2bc0e6SDamjan Jovanovic if ( wasPreviousQuote ) 951*7b2bc0e6SDamjan Jovanovic inQuotedField = false; 952*7b2bc0e6SDamjan Jovanovic 953*7b2bc0e6SDamjan Jovanovic lineBuffer.append( separator ); 954*7b2bc0e6SDamjan Jovanovic separator = lf; 955*7b2bc0e6SDamjan Jovanovic lineBuffer.append( line ); 956*7b2bc0e6SDamjan Jovanovic 957*7b2bc0e6SDamjan Jovanovic } while ( inQuotedField ); 958*7b2bc0e6SDamjan Jovanovic 959*7b2bc0e6SDamjan Jovanovic lineOut = lineBuffer.makeStringAndClear(); 960cdf0e10cSrcweir _rnCurrentPos = m_pFileStream->Tell(); 961*7b2bc0e6SDamjan Jovanovic return result; 962cdf0e10cSrcweir } 963