xref: /trunk/main/connectivity/source/drivers/flat/ETable.cxx (revision 9b5730f6ddef7eb82608ca4d31dc0d7678e652cf)
1*9b5730f6SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*9b5730f6SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*9b5730f6SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*9b5730f6SAndrew Rist  * distributed with this work for additional information
6*9b5730f6SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*9b5730f6SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*9b5730f6SAndrew Rist  * "License"); you may not use this file except in compliance
9*9b5730f6SAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
11*9b5730f6SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
13*9b5730f6SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*9b5730f6SAndrew Rist  * software distributed under the License is distributed on an
15*9b5730f6SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*9b5730f6SAndrew Rist  * KIND, either express or implied.  See the License for the
17*9b5730f6SAndrew Rist  * specific language governing permissions and limitations
18*9b5730f6SAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
20*9b5730f6SAndrew Rist  *************************************************************/
21*9b5730f6SAndrew Rist 
22*9b5730f6SAndrew 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 rtl_TextEncoding nEncoding = m_pConnection->getTextEncoding();
76cdf0e10cSrcweir     const sal_Bool bHasHeaderLine = pConnection->isHeaderLine();
77cdf0e10cSrcweir     if ( bHasHeaderLine )
78cdf0e10cSrcweir     {
79cdf0e10cSrcweir         while(bRead && !aHeaderLine.Len())
80cdf0e10cSrcweir         {
81cdf0e10cSrcweir             bRead = m_pFileStream->ReadByteStringLine(aHeaderLine,nEncoding);
82cdf0e10cSrcweir         }
83cdf0e10cSrcweir         m_nStartRowFilePos = m_pFileStream->Tell();
84cdf0e10cSrcweir     }
85cdf0e10cSrcweir 
86cdf0e10cSrcweir     // read first row
87cdf0e10cSrcweir     QuotedTokenizedString aFirstLine;
88cdf0e10cSrcweir     bRead = m_pFileStream->ReadByteStringLine(aFirstLine,nEncoding);
89cdf0e10cSrcweir 
90cdf0e10cSrcweir     if ( !bHasHeaderLine || !aHeaderLine.Len())
91cdf0e10cSrcweir     {
92cdf0e10cSrcweir         while(bRead && !aFirstLine.Len())
93cdf0e10cSrcweir         {
94cdf0e10cSrcweir             bRead = m_pFileStream->ReadByteStringLine(aFirstLine,nEncoding);
95cdf0e10cSrcweir         }
96cdf0e10cSrcweir         // use first row as headerline because we need the number of columns
97cdf0e10cSrcweir         aHeaderLine = aFirstLine;
98cdf0e10cSrcweir     }
99cdf0e10cSrcweir     // column count
100cdf0e10cSrcweir     const xub_StrLen 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();
121cdf0e10cSrcweir     String 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     {
130cdf0e10cSrcweir         xub_StrLen nStartPosHeaderLine = 0; // use for eficient way to get the tokens
131cdf0e10cSrcweir         xub_StrLen nStartPosFirstLine = 0; // use for eficient way to get the tokens
132cdf0e10cSrcweir         xub_StrLen nStartPosFirstLine2 = 0;
133cdf0e10cSrcweir         for (xub_StrLen i = 0; i < nFieldCount; i++)
134cdf0e10cSrcweir         {
135cdf0e10cSrcweir             if ( nRowCount == 0)
136cdf0e10cSrcweir             {
137cdf0e10cSrcweir                 if ( bHasHeaderLine )
138cdf0e10cSrcweir                 {
139cdf0e10cSrcweir                     aHeaderLine.GetTokenSpecial(aColumnName,nStartPosHeaderLine,m_cFieldDelimiter,m_cStringDelimiter);
140cdf0e10cSrcweir                     if ( !aColumnName.Len() )
141cdf0e10cSrcweir                     {
142cdf0e10cSrcweir                         aColumnName = 'C';
143cdf0e10cSrcweir                         aColumnName += String::CreateFromInt32(i+1);
144cdf0e10cSrcweir                     }
145cdf0e10cSrcweir                 }
146cdf0e10cSrcweir                 else
147cdf0e10cSrcweir                 {
148cdf0e10cSrcweir                     // no column name so ...
149cdf0e10cSrcweir                     aColumnName = '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     }
158cdf0e10cSrcweir     while(nRowCount < nMaxRowsToScan && m_pFileStream->ReadByteStringLine(aFirstLine,nEncoding) && !m_pFileStream->IsEof());
159cdf0e10cSrcweir 
160cdf0e10cSrcweir     for (xub_StrLen 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 }
186cdf0e10cSrcweir void OFlatTable::impl_fillColumnInfo_nothrow(QuotedTokenizedString& aFirstLine,xub_StrLen& nStartPosFirstLine,xub_StrLen& 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
198cdf0e10cSrcweir             String aField;
199cdf0e10cSrcweir             aFirstLine.GetTokenSpecial(aField,nStartPosFirstLine,m_cFieldDelimiter,'\0');
200cdf0e10cSrcweir             if (aField.Len() == 0 ||
201cdf0e10cSrcweir                 (m_cStringDelimiter && m_cStringDelimiter == aField.GetChar(0)))
202cdf0e10cSrcweir             {
203cdf0e10cSrcweir                 bNumeric = sal_False;
204cdf0e10cSrcweir                 if ( m_cStringDelimiter != '\0' )
205cdf0e10cSrcweir                     aFirstLine.GetTokenSpecial(aField,nStartPosFirstLine2,m_cFieldDelimiter,m_cStringDelimiter);
206cdf0e10cSrcweir                 else
207cdf0e10cSrcweir                     nStartPosFirstLine2 = nStartPosFirstLine;
208cdf0e10cSrcweir             }
209cdf0e10cSrcweir             else
210cdf0e10cSrcweir             {
211cdf0e10cSrcweir                 String aField2;
212cdf0e10cSrcweir                 if ( m_cStringDelimiter != '\0' )
213cdf0e10cSrcweir                     aFirstLine.GetTokenSpecial(aField2,nStartPosFirstLine2,m_cFieldDelimiter,m_cStringDelimiter);
214cdf0e10cSrcweir                 else
215cdf0e10cSrcweir                     aField2 = aField;
216cdf0e10cSrcweir 
217cdf0e10cSrcweir                 if (aField2.Len() == 0)
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;
227cdf0e10cSrcweir                     for (xub_StrLen j = 0; j < aField2.Len(); j++)
228cdf0e10cSrcweir                     {
229cdf0e10cSrcweir                         const sal_Unicode c = aField2.GetChar(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?
259cdf0e10cSrcweir                         const String aValue = aField2.GetToken(0,cDecimalDelimiter);
260cdf0e10cSrcweir                         for (sal_Int32 j = aValue.Len() - 4; j >= 0; j -= 4)
261cdf0e10cSrcweir                         {
262cdf0e10cSrcweir                             const sal_Unicode c = aValue.GetChar(static_cast<sal_uInt16>(j));
263cdf0e10cSrcweir                             // nur Ziffern und Dezimalpunkt und Tausender-Trennzeichen?
264cdf0e10cSrcweir                             if (c == cThousandDelimiter && j)
265cdf0e10cSrcweir                                 continue;
266cdf0e10cSrcweir                             else
267cdf0e10cSrcweir                             {
268cdf0e10cSrcweir                                 bNumeric = sal_False;
269cdf0e10cSrcweir                                 break;
270cdf0e10cSrcweir                             }
271cdf0e10cSrcweir                         }
272cdf0e10cSrcweir                     }
273cdf0e10cSrcweir 
274cdf0e10cSrcweir                     // jetzt koennte es noch ein Datumsfeld sein
275cdf0e10cSrcweir                     if (!bNumeric)
276cdf0e10cSrcweir                     {
277cdf0e10cSrcweir                         try
278cdf0e10cSrcweir                         {
279cdf0e10cSrcweir                             nIndex = m_xNumberFormatter->detectNumberFormat(::com::sun::star::util::NumberFormat::ALL,aField2);
280cdf0e10cSrcweir                         }
281cdf0e10cSrcweir                         catch(Exception&)
282cdf0e10cSrcweir                         {
283cdf0e10cSrcweir                         }
284cdf0e10cSrcweir                     }
285cdf0e10cSrcweir                 }
286cdf0e10cSrcweir             }
287cdf0e10cSrcweir         }
288cdf0e10cSrcweir         else if ( io_nType == DataType::DATE || io_nType == DataType::TIMESTAMP || io_nType == DataType::TIME)
289cdf0e10cSrcweir         {
290cdf0e10cSrcweir             String aField;
291cdf0e10cSrcweir             aFirstLine.GetTokenSpecial(aField,nStartPosFirstLine,m_cFieldDelimiter,'\0');
292cdf0e10cSrcweir             if (aField.Len() == 0 ||
293cdf0e10cSrcweir                 (m_cStringDelimiter && m_cStringDelimiter == aField.GetChar(0)))
294cdf0e10cSrcweir             {
295cdf0e10cSrcweir             }
296cdf0e10cSrcweir             else
297cdf0e10cSrcweir             {
298cdf0e10cSrcweir                 String aField2;
299cdf0e10cSrcweir                 if ( m_cStringDelimiter != '\0' )
300cdf0e10cSrcweir                     aFirstLine.GetTokenSpecial(aField2,nStartPosFirstLine2,m_cFieldDelimiter,m_cStringDelimiter);
301cdf0e10cSrcweir                 else
302cdf0e10cSrcweir                     aField2 = aField;
303cdf0e10cSrcweir                 if (aField2.Len() )
304cdf0e10cSrcweir                 {
305cdf0e10cSrcweir                     try
306cdf0e10cSrcweir                     {
307cdf0e10cSrcweir                         nIndex = m_xNumberFormatter->detectNumberFormat(::com::sun::star::util::NumberFormat::ALL,aField2);
308cdf0e10cSrcweir                     }
309cdf0e10cSrcweir                     catch(Exception&)
310cdf0e10cSrcweir                     {
311cdf0e10cSrcweir                     }
312cdf0e10cSrcweir                 }
313cdf0e10cSrcweir             }
314cdf0e10cSrcweir         }
315cdf0e10cSrcweir 
316cdf0e10cSrcweir         sal_Int32 nFlags = 0;
317cdf0e10cSrcweir         if (bNumeric)
318cdf0e10cSrcweir         {
319cdf0e10cSrcweir             if (cDecimalDelimiter)
320cdf0e10cSrcweir             {
321cdf0e10cSrcweir                 if(io_nPrecisions)
322cdf0e10cSrcweir                 {
323cdf0e10cSrcweir                     io_nType = DataType::DECIMAL;
324cdf0e10cSrcweir                     static const ::rtl::OUString s_sDECIMAL(RTL_CONSTASCII_USTRINGPARAM("DECIMAL"));
325cdf0e10cSrcweir                     o_sTypeName = s_sDECIMAL;
326cdf0e10cSrcweir                 }
327cdf0e10cSrcweir                 else
328cdf0e10cSrcweir                 {
329cdf0e10cSrcweir                     io_nType = DataType::DOUBLE;
330cdf0e10cSrcweir                     static const ::rtl::OUString s_sDOUBLE(RTL_CONSTASCII_USTRINGPARAM("DOUBLE"));
331cdf0e10cSrcweir                     o_sTypeName = s_sDOUBLE;
332cdf0e10cSrcweir                 }
333cdf0e10cSrcweir             }
334cdf0e10cSrcweir             else
335cdf0e10cSrcweir             {
336cdf0e10cSrcweir                 io_nType = DataType::INTEGER;
337cdf0e10cSrcweir                 io_nPrecisions = 0;
338cdf0e10cSrcweir                 io_nScales = 0;
339cdf0e10cSrcweir             }
340cdf0e10cSrcweir             nFlags = ColumnSearch::BASIC;
341cdf0e10cSrcweir         }
342cdf0e10cSrcweir         else
343cdf0e10cSrcweir         {
344cdf0e10cSrcweir             switch (comphelper::getNumberFormatType(m_xNumberFormatter,nIndex))
345cdf0e10cSrcweir             {
346cdf0e10cSrcweir                 case NUMBERFORMAT_DATE:
347cdf0e10cSrcweir                     io_nType = DataType::DATE;
348cdf0e10cSrcweir                     {
349cdf0e10cSrcweir                         static const ::rtl::OUString s_sDATE(RTL_CONSTASCII_USTRINGPARAM("DATE"));
350cdf0e10cSrcweir                         o_sTypeName = s_sDATE;
351cdf0e10cSrcweir                     }
352cdf0e10cSrcweir                     break;
353cdf0e10cSrcweir                 case NUMBERFORMAT_DATETIME:
354cdf0e10cSrcweir                     io_nType = DataType::TIMESTAMP;
355cdf0e10cSrcweir                     {
356cdf0e10cSrcweir                         static const ::rtl::OUString s_sTIMESTAMP(RTL_CONSTASCII_USTRINGPARAM("TIMESTAMP"));
357cdf0e10cSrcweir                         o_sTypeName = s_sTIMESTAMP;
358cdf0e10cSrcweir                     }
359cdf0e10cSrcweir                     break;
360cdf0e10cSrcweir                 case NUMBERFORMAT_TIME:
361cdf0e10cSrcweir                     io_nType = DataType::TIME;
362cdf0e10cSrcweir                     {
363cdf0e10cSrcweir                         static const ::rtl::OUString s_sTIME(RTL_CONSTASCII_USTRINGPARAM("TIME"));
364cdf0e10cSrcweir                         o_sTypeName = s_sTIME;
365cdf0e10cSrcweir                     }
366cdf0e10cSrcweir                     break;
367cdf0e10cSrcweir                 default:
368cdf0e10cSrcweir                     io_nType = DataType::VARCHAR;
369cdf0e10cSrcweir                     io_nPrecisions = 0; // nyi: Daten koennen aber laenger sein!
370cdf0e10cSrcweir                     io_nScales = 0;
371cdf0e10cSrcweir                     {
372cdf0e10cSrcweir                         static const ::rtl::OUString s_sVARCHAR(RTL_CONSTASCII_USTRINGPARAM("VARCHAR"));
373cdf0e10cSrcweir                         o_sTypeName = s_sVARCHAR;
374cdf0e10cSrcweir                     }
375cdf0e10cSrcweir             };
376cdf0e10cSrcweir             nFlags |= ColumnSearch::CHAR;
377cdf0e10cSrcweir         }
378cdf0e10cSrcweir     }
379cdf0e10cSrcweir     else
380cdf0e10cSrcweir     {
381cdf0e10cSrcweir         String aField;
382cdf0e10cSrcweir         aFirstLine.GetTokenSpecial(aField,nStartPosFirstLine,m_cFieldDelimiter,'\0');
383cdf0e10cSrcweir         if (aField.Len() == 0 ||
384cdf0e10cSrcweir                 (m_cStringDelimiter && m_cStringDelimiter == aField.GetChar(0)))
385cdf0e10cSrcweir         {
386cdf0e10cSrcweir             if ( m_cStringDelimiter != '\0' )
387cdf0e10cSrcweir                 aFirstLine.GetTokenSpecial(aField,nStartPosFirstLine2,m_cFieldDelimiter,m_cStringDelimiter);
388cdf0e10cSrcweir             else
389cdf0e10cSrcweir                 nStartPosFirstLine2 = nStartPosFirstLine;
390cdf0e10cSrcweir         }
391cdf0e10cSrcweir         else
392cdf0e10cSrcweir         {
393cdf0e10cSrcweir             String aField2;
394cdf0e10cSrcweir             if ( m_cStringDelimiter != '\0' )
395cdf0e10cSrcweir                 aFirstLine.GetTokenSpecial(aField2,nStartPosFirstLine2,m_cFieldDelimiter,m_cStringDelimiter);
396cdf0e10cSrcweir         }
397cdf0e10cSrcweir     }
398cdf0e10cSrcweir }
399cdf0e10cSrcweir // -------------------------------------------------------------------------
400cdf0e10cSrcweir OFlatTable::OFlatTable(sdbcx::OCollection* _pTables,OFlatConnection* _pConnection,
401cdf0e10cSrcweir                     const ::rtl::OUString& _Name,
402cdf0e10cSrcweir                     const ::rtl::OUString& _Type,
403cdf0e10cSrcweir                     const ::rtl::OUString& _Description ,
404cdf0e10cSrcweir                     const ::rtl::OUString& _SchemaName,
405cdf0e10cSrcweir                     const ::rtl::OUString& _CatalogName
406cdf0e10cSrcweir                 ) : OFlatTable_BASE(_pTables,_pConnection,_Name,
407cdf0e10cSrcweir                                   _Type,
408cdf0e10cSrcweir                                   _Description,
409cdf0e10cSrcweir                                   _SchemaName,
410cdf0e10cSrcweir                                   _CatalogName)
411cdf0e10cSrcweir     ,m_nStartRowFilePos(0)
412cdf0e10cSrcweir     ,m_nRowPos(0)
413cdf0e10cSrcweir     ,m_nMaxRowCount(0)
414cdf0e10cSrcweir     ,m_cStringDelimiter(_pConnection->getStringDelimiter())
415cdf0e10cSrcweir     ,m_cFieldDelimiter(_pConnection->getFieldDelimiter())
416cdf0e10cSrcweir     ,m_bNeedToReadLine(false)
417cdf0e10cSrcweir {
418cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "flat", "Ocke.Janssen@sun.com", "OFlatTable::OFlatTable" );
419cdf0e10cSrcweir 
420cdf0e10cSrcweir }
421cdf0e10cSrcweir // -----------------------------------------------------------------------------
422cdf0e10cSrcweir void OFlatTable::construct()
423cdf0e10cSrcweir {
424cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "flat", "Ocke.Janssen@sun.com", "OFlatTable::construct" );
425cdf0e10cSrcweir     SvtSysLocale aLocale;
426cdf0e10cSrcweir     ::com::sun::star::lang::Locale aAppLocale(aLocale.GetLocaleDataPtr()->getLocale());
427cdf0e10cSrcweir     Sequence< ::com::sun::star::uno::Any > aArg(1);
428cdf0e10cSrcweir     aArg[0] <<= aAppLocale;
429cdf0e10cSrcweir 
430cdf0e10cSrcweir     Reference< ::com::sun::star::util::XNumberFormatsSupplier >  xSupplier(m_pConnection->getDriver()->getFactory()->createInstanceWithArguments(::rtl::OUString::createFromAscii("com.sun.star.util.NumberFormatsSupplier"),aArg),UNO_QUERY);
431cdf0e10cSrcweir     m_xNumberFormatter = Reference< ::com::sun::star::util::XNumberFormatter >(m_pConnection->getDriver()->getFactory()->createInstance(::rtl::OUString::createFromAscii("com.sun.star.util.NumberFormatter")),UNO_QUERY);
432cdf0e10cSrcweir     m_xNumberFormatter->attachNumberFormatsSupplier(xSupplier);
433cdf0e10cSrcweir     Reference<XPropertySet> xProp(xSupplier->getNumberFormatSettings(),UNO_QUERY);
434cdf0e10cSrcweir     xProp->getPropertyValue(::rtl::OUString::createFromAscii("NullDate")) >>= m_aNullDate;
435cdf0e10cSrcweir 
436cdf0e10cSrcweir     INetURLObject aURL;
437cdf0e10cSrcweir     aURL.SetURL(getEntry());
438cdf0e10cSrcweir 
439cdf0e10cSrcweir     if(aURL.getExtension() != rtl::OUString(m_pConnection->getExtension()))
440cdf0e10cSrcweir         aURL.setExtension(m_pConnection->getExtension());
441cdf0e10cSrcweir 
442cdf0e10cSrcweir     String aFileName = aURL.GetMainURL(INetURLObject::NO_DECODE);
443cdf0e10cSrcweir 
444cdf0e10cSrcweir     m_pFileStream = createStream_simpleError( aFileName,STREAM_READWRITE | STREAM_NOCREATE | STREAM_SHARE_DENYWRITE);
445cdf0e10cSrcweir 
446cdf0e10cSrcweir     if(!m_pFileStream)
447cdf0e10cSrcweir         m_pFileStream = createStream_simpleError( aFileName,STREAM_READ | STREAM_NOCREATE | STREAM_SHARE_DENYNONE);
448cdf0e10cSrcweir 
449cdf0e10cSrcweir     if(m_pFileStream)
450cdf0e10cSrcweir     {
451cdf0e10cSrcweir         m_pFileStream->Seek(STREAM_SEEK_TO_END);
452cdf0e10cSrcweir         sal_Int32 nSize = m_pFileStream->Tell();
453cdf0e10cSrcweir         m_pFileStream->Seek(STREAM_SEEK_TO_BEGIN);
454cdf0e10cSrcweir 
455cdf0e10cSrcweir         // Buffersize abhaengig von der Filegroesse
456cdf0e10cSrcweir         m_pFileStream->SetBufferSize(nSize > 1000000 ? 32768 :
457cdf0e10cSrcweir                                     nSize > 100000  ? 16384 :
458cdf0e10cSrcweir                                     nSize > 10000   ? 4096  : 1024);
459cdf0e10cSrcweir 
460cdf0e10cSrcweir         fillColumns(aAppLocale);
461cdf0e10cSrcweir 
462cdf0e10cSrcweir         refreshColumns();
463cdf0e10cSrcweir     }
464cdf0e10cSrcweir }
465cdf0e10cSrcweir // -------------------------------------------------------------------------
466cdf0e10cSrcweir String OFlatTable::getEntry()
467cdf0e10cSrcweir {
468cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "flat", "Ocke.Janssen@sun.com", "OFlatTable::getEntry" );
469cdf0e10cSrcweir     ::rtl::OUString sURL;
470cdf0e10cSrcweir     try
471cdf0e10cSrcweir     {
472cdf0e10cSrcweir         Reference< XResultSet > xDir = m_pConnection->getDir()->getStaticResultSet();
473cdf0e10cSrcweir         Reference< XRow> xRow(xDir,UNO_QUERY);
474cdf0e10cSrcweir         ::rtl::OUString sName;
475cdf0e10cSrcweir         ::rtl::OUString sExt;
476cdf0e10cSrcweir 
477cdf0e10cSrcweir         INetURLObject aURL;
478cdf0e10cSrcweir         xDir->beforeFirst();
479cdf0e10cSrcweir         static const ::rtl::OUString s_sSeparator(RTL_CONSTASCII_USTRINGPARAM("/"));
480cdf0e10cSrcweir         while(xDir->next())
481cdf0e10cSrcweir         {
482cdf0e10cSrcweir             sName = xRow->getString(1);
483cdf0e10cSrcweir             aURL.SetSmartProtocol(INET_PROT_FILE);
484cdf0e10cSrcweir             String sUrl = m_pConnection->getURL() +  s_sSeparator + sName;
485cdf0e10cSrcweir             aURL.SetSmartURL( sUrl );
486cdf0e10cSrcweir 
487cdf0e10cSrcweir             // cut the extension
488cdf0e10cSrcweir             sExt = aURL.getExtension();
489cdf0e10cSrcweir 
490cdf0e10cSrcweir             // name and extension have to coincide
491cdf0e10cSrcweir             if ( m_pConnection->matchesExtension( sExt ) )
492cdf0e10cSrcweir             {
493cdf0e10cSrcweir                 if ( sExt.getLength() )
494cdf0e10cSrcweir                     sName = sName.replaceAt(sName.getLength()-(sExt.getLength()+1),sExt.getLength()+1,::rtl::OUString());
495cdf0e10cSrcweir                 if ( sName == m_Name )
496cdf0e10cSrcweir                 {
497cdf0e10cSrcweir                     Reference< XContentAccess > xContentAccess( xDir, UNO_QUERY );
498cdf0e10cSrcweir                     sURL = xContentAccess->queryContentIdentifierString();
499cdf0e10cSrcweir                     break;
500cdf0e10cSrcweir                 }
501cdf0e10cSrcweir             }
502cdf0e10cSrcweir         }
503cdf0e10cSrcweir         xDir->beforeFirst(); // move back to before first record
504cdf0e10cSrcweir     }
505cdf0e10cSrcweir     catch(Exception&)
506cdf0e10cSrcweir     {
507cdf0e10cSrcweir         OSL_ASSERT(0);
508cdf0e10cSrcweir     }
509cdf0e10cSrcweir     return sURL.getStr();
510cdf0e10cSrcweir }
511cdf0e10cSrcweir // -------------------------------------------------------------------------
512cdf0e10cSrcweir void OFlatTable::refreshColumns()
513cdf0e10cSrcweir {
514cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "flat", "Ocke.Janssen@sun.com", "OFlatTable::refreshColumns" );
515cdf0e10cSrcweir     ::osl::MutexGuard aGuard( m_aMutex );
516cdf0e10cSrcweir 
517cdf0e10cSrcweir     TStringVector aVector;
518cdf0e10cSrcweir     aVector.reserve(m_aColumns->get().size());
519cdf0e10cSrcweir 
520cdf0e10cSrcweir     for(OSQLColumns::Vector::const_iterator aIter = m_aColumns->get().begin();aIter != m_aColumns->get().end();++aIter)
521cdf0e10cSrcweir         aVector.push_back(Reference< XNamed>(*aIter,UNO_QUERY)->getName());
522cdf0e10cSrcweir 
523cdf0e10cSrcweir     if(m_pColumns)
524cdf0e10cSrcweir         m_pColumns->reFill(aVector);
525cdf0e10cSrcweir     else
526cdf0e10cSrcweir         m_pColumns  = new OFlatColumns(this,m_aMutex,aVector);
527cdf0e10cSrcweir }
528cdf0e10cSrcweir 
529cdf0e10cSrcweir // -------------------------------------------------------------------------
530cdf0e10cSrcweir void SAL_CALL OFlatTable::disposing(void)
531cdf0e10cSrcweir {
532cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "flat", "Ocke.Janssen@sun.com", "OFlatTable::disposing" );
533cdf0e10cSrcweir     OFileTable::disposing();
534cdf0e10cSrcweir     ::osl::MutexGuard aGuard(m_aMutex);
535cdf0e10cSrcweir     m_aColumns = NULL;
536cdf0e10cSrcweir }
537cdf0e10cSrcweir // -------------------------------------------------------------------------
538cdf0e10cSrcweir Sequence< Type > SAL_CALL OFlatTable::getTypes(  ) throw(RuntimeException)
539cdf0e10cSrcweir {
540cdf0e10cSrcweir     Sequence< Type > aTypes = OTable_TYPEDEF::getTypes();
541cdf0e10cSrcweir     ::std::vector<Type> aOwnTypes;
542cdf0e10cSrcweir     aOwnTypes.reserve(aTypes.getLength());
543cdf0e10cSrcweir     const Type* pBegin = aTypes.getConstArray();
544cdf0e10cSrcweir     const Type* pEnd = pBegin + aTypes.getLength();
545cdf0e10cSrcweir     for(;pBegin != pEnd;++pBegin)
546cdf0e10cSrcweir     {
547cdf0e10cSrcweir         if(!(*pBegin == ::getCppuType((const Reference<XKeysSupplier>*)0)   ||
548cdf0e10cSrcweir             *pBegin == ::getCppuType((const Reference<XRename>*)0)          ||
549cdf0e10cSrcweir             *pBegin == ::getCppuType((const Reference<XIndexesSupplier>*)0) ||
550cdf0e10cSrcweir             *pBegin == ::getCppuType((const Reference<XAlterTable>*)0)      ||
551cdf0e10cSrcweir             *pBegin == ::getCppuType((const Reference<XDataDescriptorFactory>*)0)))
552cdf0e10cSrcweir         {
553cdf0e10cSrcweir             aOwnTypes.push_back(*pBegin);
554cdf0e10cSrcweir         }
555cdf0e10cSrcweir     }
556cdf0e10cSrcweir     Type *pTypes = aOwnTypes.empty() ? 0 : &aOwnTypes[0];
557cdf0e10cSrcweir     return Sequence< Type >(pTypes, aOwnTypes.size());
558cdf0e10cSrcweir }
559cdf0e10cSrcweir 
560cdf0e10cSrcweir // -------------------------------------------------------------------------
561cdf0e10cSrcweir Any SAL_CALL OFlatTable::queryInterface( const Type & rType ) throw(RuntimeException)
562cdf0e10cSrcweir {
563cdf0e10cSrcweir     if( rType == ::getCppuType((const Reference<XKeysSupplier>*)0)      ||
564cdf0e10cSrcweir         rType == ::getCppuType((const Reference<XIndexesSupplier>*)0)   ||
565cdf0e10cSrcweir         rType == ::getCppuType((const Reference<XRename>*)0)            ||
566cdf0e10cSrcweir         rType == ::getCppuType((const Reference<XAlterTable>*)0)        ||
567cdf0e10cSrcweir         rType == ::getCppuType((const Reference<XDataDescriptorFactory>*)0))
568cdf0e10cSrcweir         return Any();
569cdf0e10cSrcweir 
570cdf0e10cSrcweir     Any aRet = OTable_TYPEDEF::queryInterface(rType);
571cdf0e10cSrcweir     return aRet.hasValue() ? aRet : ::cppu::queryInterface(rType,static_cast< ::com::sun::star::lang::XUnoTunnel*> (this));
572cdf0e10cSrcweir }
573cdf0e10cSrcweir 
574cdf0e10cSrcweir //--------------------------------------------------------------------------
575cdf0e10cSrcweir Sequence< sal_Int8 > OFlatTable::getUnoTunnelImplementationId()
576cdf0e10cSrcweir {
577cdf0e10cSrcweir     static ::cppu::OImplementationId * pId = 0;
578cdf0e10cSrcweir     if (! pId)
579cdf0e10cSrcweir     {
580cdf0e10cSrcweir         ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
581cdf0e10cSrcweir         if (! pId)
582cdf0e10cSrcweir         {
583cdf0e10cSrcweir             static ::cppu::OImplementationId aId;
584cdf0e10cSrcweir             pId = &aId;
585cdf0e10cSrcweir         }
586cdf0e10cSrcweir     }
587cdf0e10cSrcweir     return pId->getImplementationId();
588cdf0e10cSrcweir }
589cdf0e10cSrcweir 
590cdf0e10cSrcweir // com::sun::star::lang::XUnoTunnel
591cdf0e10cSrcweir //------------------------------------------------------------------
592cdf0e10cSrcweir sal_Int64 OFlatTable::getSomething( const Sequence< sal_Int8 > & rId ) throw (RuntimeException)
593cdf0e10cSrcweir {
594cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "flat", "Ocke.Janssen@sun.com", "OFlatTable::getSomething" );
595cdf0e10cSrcweir     return (rId.getLength() == 16 && 0 == rtl_compareMemory(getUnoTunnelImplementationId().getConstArray(),  rId.getConstArray(), 16 ) )
596cdf0e10cSrcweir                 ? reinterpret_cast< sal_Int64 >( this )
597cdf0e10cSrcweir                 : OFlatTable_BASE::getSomething(rId);
598cdf0e10cSrcweir }
599cdf0e10cSrcweir //------------------------------------------------------------------
600cdf0e10cSrcweir sal_Bool OFlatTable::fetchRow(OValueRefRow& _rRow,const OSQLColumns & _rCols,sal_Bool bIsTable,sal_Bool bRetrieveData)
601cdf0e10cSrcweir {
602cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "flat", "Ocke.Janssen@sun.com", "OFlatTable::fetchRow" );
603cdf0e10cSrcweir     *(_rRow->get())[0] = m_nFilePos;
604cdf0e10cSrcweir 
605cdf0e10cSrcweir     if (!bRetrieveData)
606cdf0e10cSrcweir         return sal_True;
607cdf0e10cSrcweir     if ( m_bNeedToReadLine )
608cdf0e10cSrcweir     {
609cdf0e10cSrcweir         sal_Int32 nCurrentPos = 0;
610cdf0e10cSrcweir         m_pFileStream->Seek(m_nFilePos);
611cdf0e10cSrcweir         readLine(nCurrentPos);
612cdf0e10cSrcweir         m_bNeedToReadLine = false;
613cdf0e10cSrcweir     }
614cdf0e10cSrcweir 
615cdf0e10cSrcweir     OFlatConnection* pConnection = (OFlatConnection*)m_pConnection;
616cdf0e10cSrcweir     const sal_Unicode cDecimalDelimiter = pConnection->getDecimalDelimiter();
617cdf0e10cSrcweir     const sal_Unicode cThousandDelimiter = pConnection->getThousandDelimiter();
618cdf0e10cSrcweir     // Felder:
619cdf0e10cSrcweir     xub_StrLen nStartPos = 0;
620cdf0e10cSrcweir     String aStr;
621cdf0e10cSrcweir     OSQLColumns::Vector::const_iterator aIter = _rCols.get().begin();
622cdf0e10cSrcweir     OSQLColumns::Vector::const_iterator aEnd = _rCols.get().end();
623cdf0e10cSrcweir     const OValueRefVector::Vector::size_type nCount = _rRow->get().size();
624cdf0e10cSrcweir     for (OValueRefVector::Vector::size_type i = 1; aIter != aEnd && i < nCount;
625cdf0e10cSrcweir          ++aIter, i++)
626cdf0e10cSrcweir     {
627cdf0e10cSrcweir         m_aCurrentLine.GetTokenSpecial(aStr,nStartPos,m_cFieldDelimiter,m_cStringDelimiter);
628cdf0e10cSrcweir 
629cdf0e10cSrcweir         if (aStr.Len() == 0)
630cdf0e10cSrcweir             (_rRow->get())[i]->setNull();
631cdf0e10cSrcweir         else
632cdf0e10cSrcweir         {
633cdf0e10cSrcweir             // Laengen je nach Datentyp:
634cdf0e10cSrcweir             sal_Int32   nLen,
635cdf0e10cSrcweir                         nType = 0;
636cdf0e10cSrcweir             if(bIsTable)
637cdf0e10cSrcweir             {
638cdf0e10cSrcweir                 nLen    = m_aPrecisions[i-1];
639cdf0e10cSrcweir                 nType   = m_aTypes[i-1];
640cdf0e10cSrcweir             }
641cdf0e10cSrcweir             else
642cdf0e10cSrcweir             {
643cdf0e10cSrcweir                 Reference< XPropertySet> xColumn = *aIter;
644cdf0e10cSrcweir                 xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_PRECISION))  >>= nLen;
645cdf0e10cSrcweir                 xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TYPE))       >>= nType;
646cdf0e10cSrcweir             }
647cdf0e10cSrcweir             switch(nType)
648cdf0e10cSrcweir             {
649cdf0e10cSrcweir                 case DataType::TIMESTAMP:
650cdf0e10cSrcweir                 case DataType::DATE:
651cdf0e10cSrcweir                 case DataType::TIME:
652cdf0e10cSrcweir                 {
653cdf0e10cSrcweir                     try
654cdf0e10cSrcweir                     {
655cdf0e10cSrcweir                         double nRes = m_xNumberFormatter->convertStringToNumber(::com::sun::star::util::NumberFormat::ALL,aStr);
656cdf0e10cSrcweir 
657cdf0e10cSrcweir                         switch(nType)
658cdf0e10cSrcweir                         {
659cdf0e10cSrcweir                             case DataType::DATE:
660cdf0e10cSrcweir                                 *(_rRow->get())[i] = ::dbtools::DBTypeConversion::toDouble(::dbtools::DBTypeConversion::toDate(nRes,m_aNullDate));
661cdf0e10cSrcweir                                 break;
662cdf0e10cSrcweir                             case DataType::TIMESTAMP:
663cdf0e10cSrcweir                                 *(_rRow->get())[i] = ::dbtools::DBTypeConversion::toDouble(::dbtools::DBTypeConversion::toDateTime(nRes,m_aNullDate));
664cdf0e10cSrcweir                                 break;
665cdf0e10cSrcweir                             default:
666cdf0e10cSrcweir                                 *(_rRow->get())[i] = ::dbtools::DBTypeConversion::toDouble(::dbtools::DBTypeConversion::toTime(nRes));
667cdf0e10cSrcweir                         }
668cdf0e10cSrcweir                     }
669cdf0e10cSrcweir                     catch(Exception&)
670cdf0e10cSrcweir                     {
671cdf0e10cSrcweir                         (_rRow->get())[i]->setNull();
672cdf0e10cSrcweir                     }
673cdf0e10cSrcweir                 }   break;
674cdf0e10cSrcweir                 case DataType::DOUBLE:
675cdf0e10cSrcweir                 case DataType::INTEGER:
676cdf0e10cSrcweir                 case DataType::DECIMAL:             // #99178# OJ
677cdf0e10cSrcweir                 case DataType::NUMERIC:
678cdf0e10cSrcweir                 {
679cdf0e10cSrcweir 
680cdf0e10cSrcweir                     String aStrConverted;
681cdf0e10cSrcweir                     if ( DataType::INTEGER != nType )
682cdf0e10cSrcweir                     {
683cdf0e10cSrcweir                         sal_Unicode* pData = aStrConverted.AllocBuffer(aStr.Len());
684cdf0e10cSrcweir                         const sal_Unicode* pStart = pData;
685cdf0e10cSrcweir 
686cdf0e10cSrcweir                         OSL_ENSURE(cDecimalDelimiter && nType != DataType::INTEGER ||
687cdf0e10cSrcweir                                    !cDecimalDelimiter && nType == DataType::INTEGER,
688cdf0e10cSrcweir                                    "FalscherTyp");
689cdf0e10cSrcweir 
690cdf0e10cSrcweir                         // In Standard-Notation (DezimalPUNKT ohne Tausender-Komma) umwandeln:
691cdf0e10cSrcweir                         for (xub_StrLen j = 0; j < aStr.Len(); ++j)
692cdf0e10cSrcweir                         {
693cdf0e10cSrcweir                             const sal_Unicode cChar = aStr.GetChar(j);
694cdf0e10cSrcweir                             if (cDecimalDelimiter && cChar == cDecimalDelimiter)
695cdf0e10cSrcweir                                 *pData++ = '.';
696cdf0e10cSrcweir                                 //aStrConverted.Append( '.' );
697cdf0e10cSrcweir                             else if ( cChar == '.' ) // special case, if decimal seperator isn't '.' we have to put the string after it
698cdf0e10cSrcweir                                 continue; // #99189# OJ
699cdf0e10cSrcweir                             else if (cThousandDelimiter && cChar == cThousandDelimiter)
700cdf0e10cSrcweir                             {
701cdf0e10cSrcweir                                 // weglassen
702cdf0e10cSrcweir                             }
703cdf0e10cSrcweir                             else
704cdf0e10cSrcweir                                 *pData++ = cChar;
705cdf0e10cSrcweir                                 //aStrConverted.Append(cChar);
706cdf0e10cSrcweir                         } // for (xub_StrLen j = 0; j < aStr.Len(); ++j)
707cdf0e10cSrcweir                         aStrConverted.ReleaseBufferAccess(xub_StrLen(pData - pStart));
708cdf0e10cSrcweir                     } // if ( DataType::INTEGER != nType )
709cdf0e10cSrcweir                     else
710cdf0e10cSrcweir                     {
711cdf0e10cSrcweir                         aStrConverted = aStr;
712cdf0e10cSrcweir                         if ( cThousandDelimiter )
713cdf0e10cSrcweir                             aStrConverted.EraseAllChars(cThousandDelimiter);
714cdf0e10cSrcweir                     }
715cdf0e10cSrcweir                     const double nVal = ::rtl::math::stringToDouble(aStrConverted,'.',',',NULL,NULL);
716cdf0e10cSrcweir 
717cdf0e10cSrcweir                     // #99178# OJ
718cdf0e10cSrcweir                     if ( DataType::DECIMAL == nType || DataType::NUMERIC == nType )
719cdf0e10cSrcweir                         *(_rRow->get())[i] = ::rtl::OUString::valueOf(nVal);
720cdf0e10cSrcweir                     else
721cdf0e10cSrcweir                         *(_rRow->get())[i] = nVal;
722cdf0e10cSrcweir                 } break;
723cdf0e10cSrcweir 
724cdf0e10cSrcweir                 default:
725cdf0e10cSrcweir                 {
726cdf0e10cSrcweir                     // Wert als String in Variable der Row uebernehmen
727cdf0e10cSrcweir                     *(_rRow->get())[i] = ORowSetValue(aStr);
728cdf0e10cSrcweir                 }
729cdf0e10cSrcweir                 break;
730cdf0e10cSrcweir             } // switch(nType)
731cdf0e10cSrcweir             (_rRow->get())[i]->setTypeKind(nType);
732cdf0e10cSrcweir         }
733cdf0e10cSrcweir     }
734cdf0e10cSrcweir     return sal_True;
735cdf0e10cSrcweir }
736cdf0e10cSrcweir void OFlatTable::refreshHeader()
737cdf0e10cSrcweir {
738cdf0e10cSrcweir     m_nRowPos = 0;
739cdf0e10cSrcweir }
740cdf0e10cSrcweir // -----------------------------------------------------------------------------
741cdf0e10cSrcweir sal_Bool OFlatTable::seekRow(IResultSetHelper::Movement eCursorPosition, sal_Int32 nOffset, sal_Int32& nCurPos)
742cdf0e10cSrcweir {
743cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "flat", "Ocke.Janssen@sun.com", "OFlatTable::seekRow" );
744cdf0e10cSrcweir     OSL_ENSURE(m_pFileStream,"OFlatTable::seekRow: FileStream is NULL!");
745cdf0e10cSrcweir     // ----------------------------------------------------------
746cdf0e10cSrcweir     // Positionierung vorbereiten:
747cdf0e10cSrcweir     m_nFilePos = nCurPos;
748cdf0e10cSrcweir 
749cdf0e10cSrcweir     switch(eCursorPosition)
750cdf0e10cSrcweir     {
751cdf0e10cSrcweir         case IResultSetHelper::FIRST:
752cdf0e10cSrcweir             m_nRowPos = 0;
753cdf0e10cSrcweir             // run through
754cdf0e10cSrcweir         case IResultSetHelper::NEXT:
755cdf0e10cSrcweir             {
756cdf0e10cSrcweir                 ++m_nRowPos;
757cdf0e10cSrcweir                 ::std::map<sal_Int32,TRowPositionsInFile::iterator>::const_iterator aFind = m_aRowPosToFilePos.find(m_nRowPos);
758cdf0e10cSrcweir                 m_bNeedToReadLine = aFind != m_aRowPosToFilePos.end();
759cdf0e10cSrcweir                 if ( m_bNeedToReadLine )
760cdf0e10cSrcweir                 {
761cdf0e10cSrcweir                     m_nFilePos  = aFind->second->first;
762cdf0e10cSrcweir                     nCurPos     = aFind->second->second;
763cdf0e10cSrcweir                 } // if ( m_bNeedToReadLine )
764cdf0e10cSrcweir                 else
765cdf0e10cSrcweir                 {
766cdf0e10cSrcweir                     if ( m_nRowPos == 1 )
767cdf0e10cSrcweir                         m_nFilePos = m_nStartRowFilePos;
768cdf0e10cSrcweir                     m_pFileStream->Seek(m_nFilePos);
769cdf0e10cSrcweir                     if ( m_pFileStream->IsEof() || !readLine(nCurPos) /*|| !checkHeaderLine()*/)
770cdf0e10cSrcweir                     {
771cdf0e10cSrcweir                         m_nMaxRowCount = m_nRowPos -1;
772cdf0e10cSrcweir                         return sal_False;
773cdf0e10cSrcweir                     } // if ( m_pFileStream->IsEof() || !readLine(nCurPos) /*|| !checkHeaderLine()*/)
774cdf0e10cSrcweir 
775cdf0e10cSrcweir                     TRowPositionsInFile::iterator aPos = m_aFilePosToEndLinePos.insert(TRowPositionsInFile::value_type(m_nFilePos,nCurPos)).first;
776cdf0e10cSrcweir                     m_aRowPosToFilePos.insert(::std::map<sal_Int32,TRowPositionsInFile::iterator>::value_type(m_nRowPos,aPos));
777cdf0e10cSrcweir                 }
778cdf0e10cSrcweir             }
779cdf0e10cSrcweir 
780cdf0e10cSrcweir             break;
781cdf0e10cSrcweir         case IResultSetHelper::PRIOR:
782cdf0e10cSrcweir             --m_nRowPos;
783cdf0e10cSrcweir             if(m_nRowPos > 0)
784cdf0e10cSrcweir             {
785cdf0e10cSrcweir                 TRowPositionsInFile::iterator aPositions = m_aRowPosToFilePos[m_nRowPos];
786cdf0e10cSrcweir                 m_nFilePos = aPositions->first;
787cdf0e10cSrcweir                 nCurPos = aPositions->second;
788cdf0e10cSrcweir                 m_bNeedToReadLine = true;
789cdf0e10cSrcweir             }
790cdf0e10cSrcweir             else
791cdf0e10cSrcweir                 m_nRowPos = 0;
792cdf0e10cSrcweir 
793cdf0e10cSrcweir             break;
794cdf0e10cSrcweir         case IResultSetHelper::LAST:
795cdf0e10cSrcweir             if ( m_nMaxRowCount )
796cdf0e10cSrcweir             {
797cdf0e10cSrcweir                 ::std::map<sal_Int32,TRowPositionsInFile::iterator>::reverse_iterator aLastPos = m_aRowPosToFilePos.rbegin();
798cdf0e10cSrcweir                 m_nRowPos  = aLastPos->first;
799cdf0e10cSrcweir                 m_nFilePos = aLastPos->second->first;
800cdf0e10cSrcweir                 nCurPos    = aLastPos->second->second;
801cdf0e10cSrcweir 
802cdf0e10cSrcweir                 //m_pFileStream->Seek(m_nFilePos);
803cdf0e10cSrcweir                 m_bNeedToReadLine = true;
804cdf0e10cSrcweir                 //if ( m_pFileStream->IsEof() /*|| !checkHeaderLine()*/ || !readLine(nCurPos) )
805cdf0e10cSrcweir                 //  return sal_False;
806cdf0e10cSrcweir             }
807cdf0e10cSrcweir             else
808cdf0e10cSrcweir             {
809cdf0e10cSrcweir                 while(seekRow(IResultSetHelper::NEXT,1,nCurPos)) ; // run through after last row
810cdf0e10cSrcweir                 // now I know all
811cdf0e10cSrcweir                 seekRow(IResultSetHelper::PRIOR,1,nCurPos);
812cdf0e10cSrcweir             }
813cdf0e10cSrcweir             break;
814cdf0e10cSrcweir         case IResultSetHelper::RELATIVE:
815cdf0e10cSrcweir             if(nOffset > 0)
816cdf0e10cSrcweir             {
817cdf0e10cSrcweir                 for(sal_Int32 i = 0;i<nOffset;++i)
818cdf0e10cSrcweir                     seekRow(IResultSetHelper::NEXT,1,nCurPos);
819cdf0e10cSrcweir             }
820cdf0e10cSrcweir             else if(nOffset < 0)
821cdf0e10cSrcweir             {
822cdf0e10cSrcweir                 for(sal_Int32 i = nOffset;i;++i)
823cdf0e10cSrcweir                     seekRow(IResultSetHelper::PRIOR,1,nCurPos);
824cdf0e10cSrcweir             }
825cdf0e10cSrcweir             break;
826cdf0e10cSrcweir         case IResultSetHelper::ABSOLUTE:
827cdf0e10cSrcweir             {
828cdf0e10cSrcweir                 if(nOffset < 0)
829cdf0e10cSrcweir                     nOffset = m_nRowPos + nOffset;
830cdf0e10cSrcweir                 ::std::map<sal_Int32,TRowPositionsInFile::iterator>::const_iterator aIter = m_aRowPosToFilePos.find(nOffset);
831cdf0e10cSrcweir                 if(aIter != m_aRowPosToFilePos.end())
832cdf0e10cSrcweir                 {
833cdf0e10cSrcweir                     m_nFilePos  = aIter->second->first;
834cdf0e10cSrcweir                     nCurPos     = aIter->second->second;
835cdf0e10cSrcweir                     //m_pFileStream->Seek(m_nFilePos);
836cdf0e10cSrcweir                     m_bNeedToReadLine = true;
837cdf0e10cSrcweir                     //if ( m_pFileStream->IsEof() /*|| !checkHeaderLine()*/ || !readLine(nCurPos) )
838cdf0e10cSrcweir                     //  return sal_False;
839cdf0e10cSrcweir                 }
840cdf0e10cSrcweir                 else if(m_nMaxRowCount && nOffset > m_nMaxRowCount) // offset is outside the table
841cdf0e10cSrcweir                 {
842cdf0e10cSrcweir                     m_nRowPos = m_nMaxRowCount;
843cdf0e10cSrcweir                     return sal_False;
844cdf0e10cSrcweir                 }
845cdf0e10cSrcweir                 else
846cdf0e10cSrcweir                 {
847cdf0e10cSrcweir                     aIter = m_aRowPosToFilePos.upper_bound(nOffset);
848cdf0e10cSrcweir                     if(aIter == m_aRowPosToFilePos.end())
849cdf0e10cSrcweir                     {
850cdf0e10cSrcweir                         ::std::map<sal_Int32,TRowPositionsInFile::iterator>::reverse_iterator aLastPos = m_aRowPosToFilePos.rbegin();
851cdf0e10cSrcweir                         m_nRowPos   = aLastPos->first;
852cdf0e10cSrcweir                         nCurPos = m_nFilePos = aLastPos->second->first;
853cdf0e10cSrcweir                         while(m_nRowPos != nOffset)
854cdf0e10cSrcweir                             seekRow(IResultSetHelper::NEXT,1,nCurPos);
855cdf0e10cSrcweir                     }
856cdf0e10cSrcweir                     else
857cdf0e10cSrcweir                     {
858cdf0e10cSrcweir                         --aIter;
859cdf0e10cSrcweir                         m_nRowPos   = aIter->first;
860cdf0e10cSrcweir                         m_nFilePos  = aIter->second->first;
861cdf0e10cSrcweir                         nCurPos     = aIter->second->second;
862cdf0e10cSrcweir                         //m_pFileStream->Seek(m_nFilePos);
863cdf0e10cSrcweir                         m_bNeedToReadLine = true;
864cdf0e10cSrcweir                         //if ( m_pFileStream->IsEof() /*|| !checkHeaderLine()*/ || !readLine(nCurPos) )
865cdf0e10cSrcweir                         //  return sal_False;
866cdf0e10cSrcweir                     }
867cdf0e10cSrcweir                 }
868cdf0e10cSrcweir             }
869cdf0e10cSrcweir 
870cdf0e10cSrcweir             break;
871cdf0e10cSrcweir         case IResultSetHelper::BOOKMARK:
872cdf0e10cSrcweir             {
873cdf0e10cSrcweir                 TRowPositionsInFile::const_iterator aFind = m_aFilePosToEndLinePos.find(nOffset);
874cdf0e10cSrcweir                 m_bNeedToReadLine = aFind != m_aFilePosToEndLinePos.end();
875cdf0e10cSrcweir                 if ( m_bNeedToReadLine )
876cdf0e10cSrcweir                 {
877cdf0e10cSrcweir                     m_nFilePos  = aFind->first;
878cdf0e10cSrcweir                     nCurPos = aFind->second;
879cdf0e10cSrcweir                 }
880cdf0e10cSrcweir                 else
881cdf0e10cSrcweir                 {
882cdf0e10cSrcweir                     m_nFilePos = nOffset;
883cdf0e10cSrcweir                     m_pFileStream->Seek(nOffset);
884cdf0e10cSrcweir                     if (m_pFileStream->IsEof() || !readLine(nCurPos) )
885cdf0e10cSrcweir                         return sal_False;
886cdf0e10cSrcweir                 }
887cdf0e10cSrcweir                 break;
888cdf0e10cSrcweir             }
889cdf0e10cSrcweir     }
890cdf0e10cSrcweir 
891cdf0e10cSrcweir     //nCurPos = m_nFilePos;
892cdf0e10cSrcweir 
893cdf0e10cSrcweir     return sal_True;
894cdf0e10cSrcweir }
895cdf0e10cSrcweir // -----------------------------------------------------------------------------
896cdf0e10cSrcweir sal_Bool OFlatTable::readLine(sal_Int32& _rnCurrentPos)
897cdf0e10cSrcweir {
898cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "flat", "Ocke.Janssen@sun.com", "OFlatTable::readLine" );
899cdf0e10cSrcweir     const rtl_TextEncoding nEncoding = m_pConnection->getTextEncoding();
900cdf0e10cSrcweir     m_pFileStream->ReadByteStringLine(m_aCurrentLine,nEncoding);
901cdf0e10cSrcweir     if (m_pFileStream->IsEof())
902cdf0e10cSrcweir         return sal_False;
903cdf0e10cSrcweir 
904cdf0e10cSrcweir     QuotedTokenizedString sLine = m_aCurrentLine; // check if the string continues on next line
905cdf0e10cSrcweir     while( (sLine.GetString().GetTokenCount(m_cStringDelimiter) % 2) != 1 )
906cdf0e10cSrcweir     {
907cdf0e10cSrcweir         m_pFileStream->ReadByteStringLine(sLine,nEncoding);
908cdf0e10cSrcweir         if ( !m_pFileStream->IsEof() )
909cdf0e10cSrcweir         {
910cdf0e10cSrcweir             m_aCurrentLine.GetString().Append('\n');
911cdf0e10cSrcweir             m_aCurrentLine.GetString() += sLine.GetString();
912cdf0e10cSrcweir             sLine = m_aCurrentLine;
913cdf0e10cSrcweir         }
914cdf0e10cSrcweir         else
915cdf0e10cSrcweir             break;
916cdf0e10cSrcweir     }
917cdf0e10cSrcweir     _rnCurrentPos = m_pFileStream->Tell();
918cdf0e10cSrcweir     return sal_True;
919cdf0e10cSrcweir }
920cdf0e10cSrcweir 
921