merge the formfield patch from ooo-build
[ooovba.git] / connectivity / source / drivers / evoab / LTable.cxx
blob47e836869408fa57df054b146416d1c9f182a663
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: LTable.cxx,v $
10 * $Revision: 1.18 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_connectivity.hxx"
34 #include <ctype.h>
35 #include "LTable.hxx"
36 #include <com/sun/star/sdbc/ColumnValue.hpp>
37 #include <com/sun/star/sdbc/DataType.hpp>
38 #include <com/sun/star/ucb/XContentAccess.hpp>
39 #ifndef _COM_SUN_STAR_SQLC_XROW_HPP_
40 //#include <com/sun/star/sdbc/XRow.hpp>
41 #endif
42 #include <svtools/converter.hxx>
43 #include "LConnection.hxx"
44 #include "LColumns.hxx"
45 #include <osl/thread.h>
46 #include <tools/config.hxx>
47 #include <comphelper/sequence.hxx>
48 #include <svtools/zforlist.hxx>
49 #include <rtl/math.hxx>
50 #include <stdio.h> //sprintf
51 #include <comphelper/extract.hxx>
52 #include <comphelper/numbers.hxx>
53 #include "LDriver.hxx"
54 #include <com/sun/star/util/NumberFormat.hpp>
55 #include <unotools/configmgr.hxx>
56 #include <i18npool/mslangid.hxx>
57 #include "connectivity/dbconversion.hxx"
58 #include <comphelper/types.hxx>
59 #include <svtools/syslocale.hxx>
60 #ifndef CONNECTIVITY_EVOAB_DEBUG_HELPER_HXX
61 #include "LDebug.hxx"
62 #endif
63 #include <map>
65 using namespace ::comphelper;
66 using namespace connectivity;
67 using namespace connectivity::evoab;
68 using namespace connectivity::file;
69 using namespace ::cppu;
70 using namespace utl;
71 using namespace ::com::sun::star::uno;
72 using namespace ::com::sun::star::ucb;
73 using namespace ::com::sun::star::beans;
74 using namespace ::com::sun::star::sdbcx;
75 using namespace ::com::sun::star::sdbc;
76 using namespace ::com::sun::star::container;
77 using namespace ::com::sun::star::lang;
79 // -------------------------------------------------------------------------
80 void OEvoabTable::fillColumns(const ::com::sun::star::lang::Locale& _aLocale)
82 BOOL bRead = TRUE;
84 QuotedTokenizedString aHeaderLine;
85 OEvoabConnection* pConnection = (OEvoabConnection*)m_pConnection;
86 if (pConnection->isHeaderLine())
88 while(bRead && !aHeaderLine.Len())
90 bRead = m_pFileStream->ReadByteStringLine(aHeaderLine,pConnection->getTextEncoding());
94 // read first row
95 QuotedTokenizedString aFirstLine;
96 bRead = m_pFileStream->ReadByteStringLine(aFirstLine,pConnection->getTextEncoding());
98 if (!pConnection->isHeaderLine() || !aHeaderLine.Len())
100 while(bRead && !aFirstLine.Len())
102 bRead = m_pFileStream->ReadByteStringLine(aFirstLine,pConnection->getTextEncoding());
104 // use first row as headerline because we need the number of columns
105 aHeaderLine = aFirstLine;
107 // column count
108 xub_StrLen nFieldCount = aHeaderLine.GetTokenCount(pConnection->getFieldDelimiter(),pConnection->getStringDelimiter());
110 if(!m_aColumns.isValid())
111 m_aColumns = new OSQLColumns();
112 else
113 m_aColumns->get().clear();
115 m_aTypes.clear();
116 m_aPrecisions.clear();
117 m_aScales.clear();
118 // reserve some space
119 m_aColumnRawNames.reserve(nFieldCount);
120 m_aColumns->get().reserve(nFieldCount);
121 m_aTypes.reserve(nFieldCount);
122 m_aPrecisions.reserve(nFieldCount);
123 m_aScales.reserve(nFieldCount);
125 sal_Bool bCase = getConnection()->getMetaData()->storesMixedCaseQuotedIdentifiers();
126 CharClass aCharClass(pConnection->getDriver()->getFactory(),_aLocale);
127 // read description
128 sal_Unicode cDecimalDelimiter = pConnection->getDecimalDelimiter();
129 sal_Unicode cThousandDelimiter = pConnection->getThousandDelimiter();
130 String aColumnName;
131 ::rtl::OUString aTypeName;
132 ::comphelper::UStringMixEqual aCase(bCase);
133 xub_StrLen nStartPosHeaderLine = 0; // use for eficient way to get the tokens
134 xub_StrLen nStartPosFirstLine = 0; // use for eficient way to get the tokens
135 xub_StrLen nStartPosFirstLine2 = 0;
136 for (xub_StrLen i = 0; i < nFieldCount; i++)
138 if (pConnection->isHeaderLine())
140 aHeaderLine.GetTokenSpecial(aColumnName,nStartPosHeaderLine,pConnection->getFieldDelimiter(),pConnection->getStringDelimiter());
142 else
144 // no column name so ...
145 aColumnName = 'C';
146 aColumnName += String::CreateFromInt32(i+1);
148 //OSL_TRACE("OEvoabTable::aColumnName = %s\n", ((OUtoCStr(::rtl::OUString(aColumnName))) ? (OUtoCStr(::rtl::OUString(aColumnName))):("NULL")) );
150 sal_Int32 eType;
151 UINT16 nPrecision = 0;
152 UINT16 nScale = 0;
154 BOOL bNumeric = FALSE;
155 ULONG nIndex = 0;
157 // first without fielddelimiter
158 String aField;
159 aFirstLine.GetTokenSpecial(aField,nStartPosFirstLine,pConnection->getFieldDelimiter(),'\0');
160 //OSL_TRACE("OEvoabTable::aField = %s\n", ((OUtoCStr(::rtl::OUString(aField))) ? (OUtoCStr(::rtl::OUString(aField))):("NULL")) );
162 if (aField.Len() == 0 ||
163 (pConnection->getStringDelimiter() && pConnection->getStringDelimiter() == aField.GetChar(0)))
165 bNumeric = FALSE;
167 else
169 String aField2;
170 if ( pConnection->getStringDelimiter() != '\0' )
171 aFirstLine.GetTokenSpecial(aField2,nStartPosFirstLine2,pConnection->getFieldDelimiter(),pConnection->getStringDelimiter());
172 else
173 aField2 = aField;
175 //OSL_TRACE("OEvoabTable::aField2 = %s\n", ((OUtoCStr(::rtl::OUString(aField2))) ? (OUtoCStr(::rtl::OUString(aField2))):("NULL")) );
177 if (aField2.Len() == 0)
179 bNumeric = FALSE;
181 else
183 bNumeric = TRUE;
184 xub_StrLen nDot = 0;
185 for (xub_StrLen j = 0; j < aField2.Len(); j++)
187 sal_Unicode c = aField2.GetChar(j);
188 // nur Ziffern und Dezimalpunkt und Tausender-Trennzeichen?
189 if ((!cDecimalDelimiter || c != cDecimalDelimiter) &&
190 (!cThousandDelimiter || c != cThousandDelimiter) &&
191 !aCharClass.isDigit(aField2,j))
193 bNumeric = FALSE;
194 break;
196 if (cDecimalDelimiter && c == cDecimalDelimiter)
198 nPrecision = 15; // we have an decimal value
199 nScale = 2;
200 nDot++;
204 if (nDot > 1) // if there is more than one dot it isn't a number
205 bNumeric = FALSE;
206 if (bNumeric && cThousandDelimiter)
208 // Ist der Trenner richtig angegeben?
209 String aValue = aField2.GetToken(0,cDecimalDelimiter);
210 for (sal_Int32 j = aValue.Len() - 4; j >= 0; j -= 4)
212 sal_Unicode c = aValue.GetChar(j);
213 // nur Ziffern und Dezimalpunkt und Tausender-Trennzeichen?
214 if (c == cThousandDelimiter && j)
215 continue;
216 else
218 bNumeric = FALSE;
219 break;
224 // jetzt koennte es noch ein Datumsfeld sein
225 if (!bNumeric)
229 nIndex = m_xNumberFormatter->detectNumberFormat(::com::sun::star::util::NumberFormat::ALL,aField2);
231 catch(Exception&)
238 sal_Int32 nFlags = 0;
239 if (bNumeric)
241 if (cDecimalDelimiter)
243 if(nPrecision)
245 eType = DataType::DECIMAL;
246 aTypeName = ::rtl::OUString::createFromAscii("DECIMAL");
248 else
250 eType = DataType::DOUBLE;
251 aTypeName = ::rtl::OUString::createFromAscii("DOUBLE");
254 else
255 eType = DataType::INTEGER;
256 nFlags = ColumnSearch::BASIC;
258 else
261 switch (comphelper::getNumberFormatType(m_xNumberFormatter,nIndex))
263 case NUMBERFORMAT_DATE:
264 eType = DataType::DATE;
265 aTypeName = ::rtl::OUString::createFromAscii("DATE");
266 break;
267 case NUMBERFORMAT_DATETIME:
268 eType = DataType::TIMESTAMP;
269 aTypeName = ::rtl::OUString::createFromAscii("TIMESTAMP");
270 break;
271 case NUMBERFORMAT_TIME:
272 eType = DataType::TIME;
273 aTypeName = ::rtl::OUString::createFromAscii("TIME");
274 break;
275 default:
276 eType = DataType::VARCHAR;
277 nPrecision = 0; // nyi: Daten koennen aber laenger sein!
278 nScale = 0;
279 aTypeName = ::rtl::OUString::createFromAscii("VARCHAR");
281 nFlags |= ColumnSearch::CHAR;
284 // check if the columname already exists
285 String aAlias(aColumnName);
286 OSQLColumns::Vector::const_iterator aFind = connectivity::find(m_aColumns->get().begin(),m_aColumns->get().end(),aAlias,aCase);
287 sal_Int32 nExprCnt = 0;
288 while(aFind != m_aColumns->get().end())
290 (aAlias = aColumnName) += String::CreateFromInt32(++nExprCnt);
291 aFind = connectivity::find(m_aColumns->get().begin(),m_aColumns->get().end(),aAlias,aCase);
294 m_aColumnRawNames.push_back(::rtl::OUString(aAlias));
296 //~ sdbcx::OColumn* pColumn = new sdbcx::OColumn(aAlias,aTypeName,::rtl::OUString(),
297 //~ ColumnValue::NULLABLE,
298 //~ nPrecision,
299 //~ nScale,
300 //~ eType,
301 //~ sal_False,
302 //~ sal_False,
303 //~ sal_False,
304 //~ bCase);
305 //~ Reference< XPropertySet> xCol = pColumn;
306 //~ m_aColumns->push_back(xCol);
307 m_aTypes.push_back(eType);
308 m_aPrecisions.push_back(nPrecision);
309 m_aScales.push_back(nScale);
311 setColumnAliases();
312 m_pFileStream->Seek(STREAM_SEEK_TO_BEGIN);
314 // -------------------------------------------------------------------------
315 OEvoabTable::OEvoabTable(sdbcx::OCollection* _pTables,OEvoabConnection* _pConnection) : OEvoabTable_BASE(_pTables,_pConnection)
319 // -------------------------------------------------------------------------
320 OEvoabTable::OEvoabTable(sdbcx::OCollection* _pTables,OEvoabConnection* _pConnection,
321 const ::rtl::OUString& _Name,
322 const ::rtl::OUString& _Type,
323 const ::rtl::OUString& _Description ,
324 const ::rtl::OUString& _SchemaName,
325 const ::rtl::OUString& _CatalogName
326 ) : OEvoabTable_BASE(_pTables,_pConnection,_Name,
327 _Type,
328 _Description,
329 _SchemaName,
330 _CatalogName)
331 ,m_nRowPos(0)
332 ,m_nMaxRowCount(0)
334 //~ OSL_TRACE("OEvoabTable::(in constructor)_Name = %s\n", ((OUtoCStr(_Name)) ? (OUtoCStr(_Name)):("NULL")) );
335 //~ OSL_TRACE("OEvoabTable::(in constructor)_Type = %s\n", ((OUtoCStr(_Type)) ? (OUtoCStr(_Type)):("NULL")) );
336 //~ OSL_TRACE("OEvoabTable::(in constructor)_Description = %s\n", ((OUtoCStr(_Description)) ? (OUtoCStr(_Description)):("NULL")) );
337 //~ OSL_TRACE("OEvoabTable::(in constructor)_SchemaName = %s\n", ((OUtoCStr(_SchemaName)) ? (OUtoCStr(_SchemaName)):("NULL")) );
338 //~ OSL_TRACE("OEvoabTable::(in constructor)_CatalogName = %s\n", ((OUtoCStr(_CatalogName)) ? (OUtoCStr(_CatalogName)):("NULL")) );
340 // -----------------------------------------------------------------------------
341 void OEvoabTable::construct()
343 SvtSysLocale aLocale;
344 ::com::sun::star::lang::Locale aAppLocale(aLocale.GetLocaleDataPtr()->getLocale());
345 Sequence< ::com::sun::star::uno::Any > aArg(1);
346 aArg[0] <<= aAppLocale;
348 Reference< ::com::sun::star::util::XNumberFormatsSupplier > xSupplier(m_pConnection->getDriver()->getFactory()->createInstanceWithArguments(::rtl::OUString::createFromAscii("com.sun.star.util.NumberFormatsSupplier"),aArg),UNO_QUERY);
349 m_xNumberFormatter = Reference< ::com::sun::star::util::XNumberFormatter >(m_pConnection->getDriver()->getFactory()->createInstance(::rtl::OUString::createFromAscii("com.sun.star.util.NumberFormatter")),UNO_QUERY);
350 m_xNumberFormatter->attachNumberFormatsSupplier(xSupplier);
352 INetURLObject aURL;
353 aURL.SetURL(getEntry());
355 if(aURL.getExtension() != rtl::OUString(m_pConnection->getExtension()))
356 aURL.setExtension(m_pConnection->getExtension());
358 String aFileName = aURL.GetMainURL(INetURLObject::NO_DECODE);
360 m_pFileStream = createStream_simpleError( aFileName,STREAM_READWRITE | STREAM_NOCREATE | STREAM_SHARE_DENYWRITE);
362 if(!m_pFileStream)
363 m_pFileStream = createStream_simpleError( aFileName,STREAM_READ | STREAM_NOCREATE | STREAM_SHARE_DENYNONE);
365 if(m_pFileStream)
367 OSL_TRACE("OEvoabTable::construct()::m_pFileStream created\n" );
368 m_pFileStream->Seek(STREAM_SEEK_TO_END);
369 sal_Int32 nSize = m_pFileStream->Tell();
370 m_pFileStream->Seek(STREAM_SEEK_TO_BEGIN);
372 // Buffersize abhaengig von der Filegroesse
373 m_pFileStream->SetBufferSize(nSize > 1000000 ? 32768 :
374 nSize > 100000 ? 16384 :
375 nSize > 10000 ? 4096 : 1024);
376 OSL_TRACE("OEvoabTable::construct()::m_pFileStream->Tell() = %d\n", nSize );
378 fillColumns(aAppLocale);
380 refreshColumns();
383 // -------------------------------------------------------------------------
384 String OEvoabTable::getEntry()
386 ::rtl::OUString sURL;
389 Reference< XResultSet > xDir = m_pConnection->getDir()->getStaticResultSet();
390 Reference< XRow> xRow(xDir,UNO_QUERY);
391 ::rtl::OUString sName;
392 ::rtl::OUString sExt;
394 INetURLObject aURL;
395 xDir->beforeFirst();
396 static const ::rtl::OUString s_sSeparator(RTL_CONSTASCII_USTRINGPARAM("/"));
397 while(xDir->next())
399 sName = xRow->getString(1);
400 aURL.SetSmartProtocol(INET_PROT_FILE);
401 String sUrl = m_pConnection->getURL() + s_sSeparator + sName;
402 aURL.SetSmartURL( sUrl );
404 // cut the extension
405 sExt = aURL.getExtension();
407 // name and extension have to coincide
408 if ( m_pConnection->matchesExtension( sExt ) )
410 sName = sName.replaceAt(sName.getLength()-(sExt.getLength()+1),sExt.getLength()+1,::rtl::OUString());
411 if ( sName == m_Name )
413 Reference< XContentAccess > xContentAccess( xDir, UNO_QUERY );
414 sURL = xContentAccess->queryContentIdentifierString();
415 break;
419 xDir->beforeFirst(); // move back to before first record
421 catch(Exception&)
423 OSL_ASSERT(0);
425 return sURL.getStr();
427 // -------------------------------------------------------------------------
428 void OEvoabTable::refreshColumns()
430 ::osl::MutexGuard aGuard( m_aMutex );
432 TStringVector aVector;
433 aVector.reserve(m_aColumns->get().size());
435 for(OSQLColumns::Vector::const_iterator aIter = m_aColumns->get().begin();aIter != m_aColumns->get().end();++aIter)
436 aVector.push_back(Reference< XNamed>(*aIter,UNO_QUERY)->getName());
438 if(m_pColumns)
439 m_pColumns->reFill(aVector);
440 else
441 m_pColumns = new OEvoabColumns(this,m_aMutex,aVector);
443 OSL_TRACE("OEvoabTable::refreshColumns()::end\n" );
446 // -------------------------------------------------------------------------
447 void SAL_CALL OEvoabTable::disposing(void)
449 OFileTable::disposing();
450 ::osl::MutexGuard aGuard(m_aMutex);
451 m_aColumns = NULL;
453 // -------------------------------------------------------------------------
454 Sequence< Type > SAL_CALL OEvoabTable::getTypes( ) throw(RuntimeException)
456 Sequence< Type > aTypes = OTable_TYPEDEF::getTypes();
457 ::std::vector<Type> aOwnTypes;
458 aOwnTypes.reserve(aTypes.getLength());
459 const Type* pBegin = aTypes.getConstArray();
460 const Type* pEnd = pBegin + aTypes.getLength();
461 for(;pBegin != pEnd;++pBegin)
463 if(!(*pBegin == ::getCppuType((const Reference<XKeysSupplier>*)0) ||
464 *pBegin == ::getCppuType((const Reference<XRename>*)0) ||
465 *pBegin == ::getCppuType((const Reference<XIndexesSupplier>*)0) ||
466 *pBegin == ::getCppuType((const Reference<XAlterTable>*)0) ||
467 *pBegin == ::getCppuType((const Reference<XDataDescriptorFactory>*)0)))
469 aOwnTypes.push_back(*pBegin);
472 Type *pTypes = aOwnTypes.empty() ? 0 : &aOwnTypes[0];
473 return Sequence< Type >(pTypes, aOwnTypes.size());
476 // -------------------------------------------------------------------------
477 Any SAL_CALL OEvoabTable::queryInterface( const Type & rType ) throw(RuntimeException)
479 if( rType == ::getCppuType((const Reference<XKeysSupplier>*)0) ||
480 rType == ::getCppuType((const Reference<XIndexesSupplier>*)0) ||
481 rType == ::getCppuType((const Reference<XRename>*)0) ||
482 rType == ::getCppuType((const Reference<XAlterTable>*)0) ||
483 rType == ::getCppuType((const Reference<XDataDescriptorFactory>*)0))
484 return Any();
486 Any aRet = OTable_TYPEDEF::queryInterface(rType);
487 return aRet.hasValue() ? aRet : ::cppu::queryInterface(rType,static_cast< ::com::sun::star::lang::XUnoTunnel*> (this));
490 //--------------------------------------------------------------------------
491 Sequence< sal_Int8 > OEvoabTable::getUnoTunnelImplementationId()
493 static ::cppu::OImplementationId * pId = 0;
494 if (! pId)
496 ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
497 if (! pId)
499 static ::cppu::OImplementationId aId;
500 pId = &aId;
503 return pId->getImplementationId();
506 // com::sun::star::lang::XUnoTunnel
507 //------------------------------------------------------------------
508 sal_Int64 OEvoabTable::getSomething( const Sequence< sal_Int8 > & rId ) throw (RuntimeException)
510 return (rId.getLength() == 16 && 0 == rtl_compareMemory(getUnoTunnelImplementationId().getConstArray(), rId.getConstArray(), 16 ) )
511 ? reinterpret_cast< sal_Int64 >( this )
512 : OEvoabTable_BASE::getSomething(rId);
514 //------------------------------------------------------------------
515 sal_Bool OEvoabTable::fetchRow(OValueRefRow& _rRow,const OSQLColumns & _rCols,sal_Bool bIsTable,sal_Bool bRetrieveData)
517 *(_rRow->get())[0] = m_nFilePos;
519 if (!bRetrieveData)
520 return TRUE;
522 OEvoabConnection* pConnection = (OEvoabConnection*)m_pConnection;
523 // Felder:
524 xub_StrLen nStartPos = 0;
525 String aStr;
526 OSQLColumns::Vector::const_iterator aIter = _rCols.get().begin();
527 for (sal_Int32 i = 0; aIter != _rCols.get().end();++aIter, ++i)
529 m_aCurrentLine.GetTokenSpecial(aStr,nStartPos,pConnection->getFieldDelimiter(),pConnection->getStringDelimiter());
530 //OSL_TRACE("OEvoabTable::fetchRow()::aStr = %s\n", ((OUtoCStr(::rtl::OUString(aStr))) ? (OUtoCStr(::rtl::OUString(aStr))):("NULL")) );
532 if (aStr.Len() == 0)
533 (_rRow->get())[i+1]->setNull();
534 else
536 // Laengen je nach Datentyp:
537 sal_Int32 nLen,
538 nType = 0;
539 if(bIsTable)
541 nLen = m_aPrecisions[i];
542 nType = m_aTypes[i];
544 else
546 Reference< XPropertySet> xColumn = *aIter;
547 xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_PRECISION)) >>= nLen;
548 xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TYPE)) >>= nType;
550 switch(nType)
552 case DataType::TIMESTAMP:
553 case DataType::DATE:
554 case DataType::TIME:
556 double nRes = 0.0;
559 nRes = m_xNumberFormatter->convertStringToNumber(::com::sun::star::util::NumberFormat::ALL,aStr);
560 Reference<XPropertySet> xProp(m_xNumberFormatter->getNumberFormatsSupplier()->getNumberFormatSettings(),UNO_QUERY);
561 com::sun::star::util::Date aDate;
562 xProp->getPropertyValue(::rtl::OUString::createFromAscii("NullDate")) >>= aDate;
564 switch(nType)
566 case DataType::DATE:
567 *(_rRow->get())[i+1] = ::dbtools::DBTypeConversion::toDouble(::dbtools::DBTypeConversion::toDate(nRes,aDate));
568 break;
569 case DataType::TIMESTAMP:
570 *(_rRow->get())[i+1] = ::dbtools::DBTypeConversion::toDouble(::dbtools::DBTypeConversion::toDateTime(nRes,aDate));
571 break;
572 default:
573 *(_rRow->get())[i+1] = ::dbtools::DBTypeConversion::toDouble(::dbtools::DBTypeConversion::toTime(nRes));
576 catch(Exception&)
578 (_rRow->get())[i+1]->setNull();
580 } break;
581 case DataType::DOUBLE:
582 case DataType::INTEGER:
583 case DataType::DECIMAL: // #99178# OJ
584 case DataType::NUMERIC:
586 sal_Unicode cDecimalDelimiter = pConnection->getDecimalDelimiter();
587 sal_Unicode cThousandDelimiter = pConnection->getThousandDelimiter();
588 String aStrConverted;
590 OSL_ENSURE(cDecimalDelimiter && nType != DataType::INTEGER ||
591 !cDecimalDelimiter && nType == DataType::INTEGER,
592 "FalscherTyp");
594 // In Standard-Notation (DezimalPUNKT ohne Tausender-Komma) umwandeln:
595 for (xub_StrLen j = 0; j < aStr.Len(); ++j)
597 if (cDecimalDelimiter && aStr.GetChar(j) == cDecimalDelimiter)
598 aStrConverted += '.';
599 else if ( aStr.GetChar(j) == '.' ) // special case, if decimal seperator isn't '.' we have to vut the string after it
600 break; // #99189# OJ
601 else if (cThousandDelimiter && aStr.GetChar(j) == cThousandDelimiter)
603 // weglassen
605 else
606 aStrConverted += aStr.GetChar(j) ;
608 double nVal = ::rtl::math::stringToDouble(aStrConverted.GetBuffer(),',','.',NULL,NULL);
610 // #99178# OJ
611 if ( DataType::DECIMAL == nType || DataType::NUMERIC == nType )
612 *(_rRow->get())[i+1] = ORowSetValue(String::CreateFromDouble(nVal));
613 else
614 *(_rRow->get())[i+1] = nVal;
615 } break;
617 default:
619 // Wert als String in Variable der Row uebernehmen
620 *(_rRow->get())[i+1] = ORowSetValue(aStr);
622 break;
626 return sal_True;
628 // -----------------------------------------------------------------------------
629 sal_Bool OEvoabTable::setColumnAliases()
632 size_t nSize = m_aColumnRawNames.size();
633 if(nSize == 0 || m_aPrecisions.size() != nSize || m_aScales.size() != nSize || m_aTypes.size() != nSize)
634 return sal_False;
635 m_aColumns->get().clear();
636 m_aColumns->get().reserve(nSize);
637 ::rtl::OUString aColumnReadName;
638 ::rtl::OUString aColumnHeadlineName;
639 ::rtl::OUString aColumnDisplayName;
640 ::rtl::OUString aColumnFinalName;
641 String sColumnFinalName;
643 const TStringVector& colAliasNames = ((OEvoabConnection*)m_pConnection)->getColumnAlias().getAlias();
644 const ::std::map< ::rtl::OUString, ::rtl::OUString > & colMap = ((OEvoabConnection*)m_pConnection)->getColumnAlias().getAliasMap();
645 ::osl::MutexGuard aGuard( m_aMutex );
647 for(size_t i = 0;i < nSize; ++i)
649 aColumnReadName = m_aColumnRawNames[i];
650 //OSL_TRACE("OEvoabTable::getColumnRows()::aColumnReadName = %s\n", ((OUtoCStr(aColumnReadName)) ? (OUtoCStr(aColumnReadName)):("NULL")) );
651 sal_Bool bFound = sal_False;
652 for ( size_t j = 0; j < colAliasNames.size(); ++j )
654 aColumnDisplayName = colAliasNames[j];
656 ::std::map< ::rtl::OUString, ::rtl::OUString >::const_iterator aPos = colMap.find( aColumnDisplayName );
657 if ( colMap.end() != aPos )
659 aColumnHeadlineName = aPos->second;
660 EVO_TRACE_STRING( "OEvoabTable::getColumnRows()::aColumnDisplayName = %s\n", aColumnDisplayName );
661 EVO_TRACE_STRING( "OEvoabTable::getColumnRows()::aColumnHeadlineName= %s\n", aColumnHeadlineName );
662 if(aColumnReadName == aColumnHeadlineName)
664 //OSL_TRACE("OEvoabTable::getColumnRows()::aColumnHeadlineName = %s\n", ((OUtoCStr(aColumnHeadlineName)) ? (OUtoCStr(aColumnHeadlineName)):("NULL")) );
665 //OSL_TRACE("OEvoabTable::getColumnRows()::aColumnDisplayName = %s\n", ((OUtoCStr(aColumnDisplayName)) ? (OUtoCStr(aColumnDisplayName)):("NULL")) );
666 aColumnFinalName = aColumnDisplayName;
667 bFound = sal_True;
668 //OSL_TRACE("OEvoabTable::getColumnRows()::j = %d\n", j );
670 break;
673 else
674 OSL_ENSURE( sal_False, "OEvoabTable::setColumnAliases: did not find one of the aliases!" );
676 if(!bFound)
677 aColumnFinalName = aColumnReadName;
678 sColumnFinalName = aColumnFinalName;
680 sal_Bool bCase = getConnection()->getMetaData()->storesMixedCaseQuotedIdentifiers();
681 ::rtl::OUString aTypeName;
682 aTypeName = ::rtl::OUString::createFromAscii("VARCHAR");
683 sdbcx::OColumn* pColumn = new sdbcx::OColumn(sColumnFinalName,aTypeName,::rtl::OUString(),
684 ColumnValue::NULLABLE,
685 m_aPrecisions[i],
686 m_aScales[i],
687 m_aTypes[i],
688 sal_False,
689 sal_False,
690 sal_False,
691 bCase);
692 Reference< XPropertySet> xCol = pColumn;
693 m_aColumns->get().push_back(xCol);
695 return sal_True;
697 // -----------------------------------------------------------------------------
698 void OEvoabTable::refreshIndexes()
701 // -----------------------------------------------------------------------------
702 sal_Bool OEvoabTable::checkHeaderLine()
704 if (m_nFilePos == 0 && ((OEvoabConnection*)m_pConnection)->isHeaderLine())
706 BOOL bRead2;
709 bRead2 = m_pFileStream->ReadByteStringLine(m_aCurrentLine,m_pConnection->getTextEncoding());
711 while(bRead2 && !m_aCurrentLine.Len());
713 m_nFilePos = m_pFileStream->Tell();
714 if (m_pFileStream->IsEof())
715 return sal_False;
717 return sal_True;
719 //------------------------------------------------------------------
720 sal_Bool OEvoabTable::seekRow(IResultSetHelper::Movement eCursorPosition, sal_Int32 nOffset, sal_Int32& nCurPos)
722 //OSL_TRACE("OEvoabTable::(before SeekRow)m_aCurrentLine = %d\n", ((OUtoCStr(::rtl::OUString(m_aCurrentLine))) ? (OUtoCStr(::rtl::OUString(m_aCurrentLine))):("NULL")) );
724 if ( !m_pFileStream )
725 return sal_False;
726 OEvoabConnection* pConnection = (OEvoabConnection*)m_pConnection;
727 // ----------------------------------------------------------
728 // Positionierung vorbereiten:
729 //OSL_TRACE("OEvoabTable::(before SeekRow,m_pFileStriam Exist)m_aCurrentLine = %d\n", ((OUtoCStr(::rtl::OUString(m_aCurrentLine))) ? (OUtoCStr(::rtl::OUString(m_aCurrentLine))):("NULL")) );
731 m_nFilePos = nCurPos;
733 switch(eCursorPosition)
735 case IResultSetHelper::FIRST:
736 m_nFilePos = 0;
737 m_nRowPos = 1;
738 // run through
739 case IResultSetHelper::NEXT:
740 if(eCursorPosition != IResultSetHelper::FIRST)
741 ++m_nRowPos;
742 m_pFileStream->Seek(m_nFilePos);
743 if (m_pFileStream->IsEof() || !checkHeaderLine())
745 m_nMaxRowCount = m_nRowPos;
746 return sal_False;
749 m_aRowToFilePos.insert(::std::map<sal_Int32,sal_Int32>::value_type(m_nRowPos,m_nFilePos));
751 m_pFileStream->ReadByteStringLine(m_aCurrentLine,pConnection->getTextEncoding());
752 if (m_pFileStream->IsEof())
754 m_nMaxRowCount = m_nRowPos;
755 return sal_False;
757 nCurPos = m_pFileStream->Tell();
758 break;
759 case IResultSetHelper::PRIOR:
760 --m_nRowPos;
761 if(m_nRowPos > 0)
763 m_nFilePos = m_aRowToFilePos.find(m_nRowPos)->second;
764 m_pFileStream->Seek(m_nFilePos);
765 if (m_pFileStream->IsEof() || !checkHeaderLine())
766 return sal_False;
767 m_pFileStream->ReadByteStringLine(m_aCurrentLine,pConnection->getTextEncoding());
768 if (m_pFileStream->IsEof())
769 return sal_False;
770 nCurPos = m_pFileStream->Tell();
772 else
773 m_nRowPos = 0;
775 break;
776 case IResultSetHelper::LAST:
777 if(m_nMaxRowCount)
779 m_nFilePos = m_aRowToFilePos.rbegin()->second;
780 m_nRowPos = m_aRowToFilePos.rbegin()->first;
781 m_pFileStream->Seek(m_nFilePos);
782 if (m_pFileStream->IsEof() || !checkHeaderLine())
783 return sal_False;
784 m_pFileStream->ReadByteStringLine(m_aCurrentLine,pConnection->getTextEncoding());
785 if (m_pFileStream->IsEof())
786 return sal_False;
787 nCurPos = m_pFileStream->Tell();
789 else
791 while(seekRow(IResultSetHelper::NEXT,1,nCurPos)) ; // run through after last row
792 // now I know all
793 seekRow(IResultSetHelper::PRIOR,1,nCurPos);
795 break;
796 case IResultSetHelper::RELATIVE:
797 if(nOffset > 0)
799 for(sal_Int32 i = 0;i<nOffset;++i)
800 seekRow(IResultSetHelper::NEXT,1,nCurPos);
802 else if(nOffset < 0)
804 for(sal_Int32 i = nOffset;i;++i)
805 seekRow(IResultSetHelper::PRIOR,1,nCurPos);
807 break;
808 case IResultSetHelper::ABSOLUTE:
810 if(nOffset < 0)
811 nOffset = m_nRowPos + nOffset;
812 ::std::map<sal_Int32,sal_Int32>::const_iterator aIter = m_aRowToFilePos.find(nOffset);
813 if(aIter != m_aRowToFilePos.end())
815 m_nFilePos = aIter->second;
816 m_pFileStream->Seek(m_nFilePos);
817 if (m_pFileStream->IsEof() || !checkHeaderLine())
818 return sal_False;
819 m_pFileStream->ReadByteStringLine(m_aCurrentLine,pConnection->getTextEncoding());
820 if (m_pFileStream->IsEof())
821 return sal_False;
822 nCurPos = m_pFileStream->Tell();
824 else if(m_nMaxRowCount && nOffset > m_nMaxRowCount) // offset is outside the table
826 m_nRowPos = m_nMaxRowCount;
827 return sal_False;
829 else
831 aIter = m_aRowToFilePos.upper_bound(nOffset);
832 if(aIter == m_aRowToFilePos.end())
834 m_nRowPos = m_aRowToFilePos.rbegin()->first;
835 nCurPos = m_nFilePos = m_aRowToFilePos.rbegin()->second;
836 while(m_nRowPos != nOffset)
837 seekRow(IResultSetHelper::NEXT,1,nCurPos);
839 else
841 --aIter;
842 m_nRowPos = aIter->first;
843 m_nFilePos = aIter->second;
844 m_pFileStream->Seek(m_nFilePos);
845 if (m_pFileStream->IsEof() || !checkHeaderLine())
846 return sal_False;
847 m_pFileStream->ReadByteStringLine(m_aCurrentLine,pConnection->getTextEncoding());
848 if (m_pFileStream->IsEof())
849 return sal_False;
850 nCurPos = m_pFileStream->Tell();
855 break;
856 case IResultSetHelper::BOOKMARK:
857 m_pFileStream->Seek(nOffset);
858 if (m_pFileStream->IsEof())
859 return sal_False;
861 m_nFilePos = m_pFileStream->Tell(); // Byte-Position in der Datei merken (am ZeilenANFANG)
862 m_pFileStream->ReadByteStringLine(m_aCurrentLine,pConnection->getTextEncoding());
863 if (m_pFileStream->IsEof())
864 return sal_False;
865 nCurPos = m_pFileStream->Tell();
866 break;
869 //OSL_TRACE("OEvoabTable::(after SeekRow)m_aCurrentLine = %d\n", ((OUtoCStr(::rtl::OUString(m_aCurrentLine))) ? (OUtoCStr(::rtl::OUString(m_aCurrentLine))):("NULL")) );
871 return sal_True;
873 // -----------------------------------------------------------------------------