Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*
3 : : * This file is part of the LibreOffice project.
4 : : *
5 : : * This Source Code Form is subject to the terms of the Mozilla Public
6 : : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : : *
9 : : * This file incorporates work covered by the following license notice:
10 : : *
11 : : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : : * contributor license agreements. See the NOTICE file distributed
13 : : * with this work for additional information regarding copyright
14 : : * ownership. The ASF licenses this file to you under the Apache
15 : : * License, Version 2.0 (the "License"); you may not use this file
16 : : * except in compliance with the License. You may obtain a copy of
17 : : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : : */
19 : :
20 : : #include "dbase/DTable.hxx"
21 : : #include <com/sun/star/sdbc/ColumnValue.hpp>
22 : : #include <com/sun/star/sdbc/DataType.hpp>
23 : : #include <com/sun/star/ucb/XContentAccess.hpp>
24 : : #include <com/sun/star/sdbc/XRow.hpp>
25 : : #include <svl/converter.hxx>
26 : : #include "dbase/DConnection.hxx"
27 : : #include "dbase/DColumns.hxx"
28 : : #include <osl/thread.h>
29 : : #include <tools/config.hxx>
30 : : #include "dbase/DIndex.hxx"
31 : : #include "dbase/DIndexes.hxx"
32 : : #include <comphelper/sequence.hxx>
33 : : #include <svl/zforlist.hxx>
34 : : #include <unotools/syslocale.hxx>
35 : : #include <rtl/math.hxx>
36 : : #include <stdio.h> //sprintf
37 : : #include <ucbhelper/content.hxx>
38 : : #include <comphelper/extract.hxx>
39 : : #include <connectivity/dbexception.hxx>
40 : : #include <connectivity/dbconversion.hxx>
41 : : #include <com/sun/star/lang/DisposedException.hpp>
42 : : #include <comphelper/property.hxx>
43 : : #include <comphelper/string.hxx>
44 : : #include <unotools/tempfile.hxx>
45 : : #include <unotools/ucbhelper.hxx>
46 : : #include <comphelper/types.hxx>
47 : : #include <cppuhelper/exc_hlp.hxx>
48 : : #include "connectivity/PColumn.hxx"
49 : : #include "connectivity/dbtools.hxx"
50 : : #include "connectivity/FValue.hxx"
51 : : #include "connectivity/dbconversion.hxx"
52 : : #include "resource/dbase_res.hrc"
53 : : #include <rtl/logfile.hxx>
54 : : #include <rtl/strbuf.hxx>
55 : :
56 : : #include <algorithm>
57 : :
58 : : using namespace ::comphelper;
59 : : using namespace connectivity;
60 : : using namespace connectivity::sdbcx;
61 : : using namespace connectivity::dbase;
62 : : using namespace connectivity::file;
63 : : using namespace ::ucbhelper;
64 : : using namespace ::utl;
65 : : using namespace ::cppu;
66 : : using namespace ::dbtools;
67 : : using namespace ::com::sun::star::uno;
68 : : using namespace ::com::sun::star::ucb;
69 : : using namespace ::com::sun::star::beans;
70 : : using namespace ::com::sun::star::sdbcx;
71 : : using namespace ::com::sun::star::sdbc;
72 : : using namespace ::com::sun::star::container;
73 : : using namespace ::com::sun::star::lang;
74 : : using namespace ::com::sun::star::i18n;
75 : :
76 : : // stored as the Field Descriptor terminator
77 : : #define FIELD_DESCRIPTOR_TERMINATOR 0x0D
78 : : #define DBF_EOL 0x1A
79 : :
80 : : namespace
81 : : {
82 : 30 : sal_Int32 lcl_getFileSize(SvStream& _rStream)
83 : : {
84 : 30 : sal_Int32 nFileSize = 0;
85 [ + - ]: 30 : _rStream.Seek(STREAM_SEEK_TO_END);
86 [ + - ]: 30 : _rStream.SeekRel(-1);
87 : : char cEOL;
88 [ + - ]: 30 : _rStream >> cEOL;
89 : 30 : nFileSize = _rStream.Tell();
90 [ + + ]: 30 : if ( cEOL == DBF_EOL )
91 : 14 : nFileSize -= 1;
92 : 30 : return nFileSize;
93 : : }
94 : : /**
95 : : calculates the Julian date
96 : : */
97 : 0 : void lcl_CalcJulDate(sal_Int32& _nJulianDate,sal_Int32& _nJulianTime,const com::sun::star::util::DateTime _aDateTime)
98 : : {
99 : 0 : com::sun::star::util::DateTime aDateTime = _aDateTime;
100 : : // weird: months fix
101 [ # # ]: 0 : if (aDateTime.Month > 12)
102 : : {
103 : 0 : aDateTime.Month--;
104 : 0 : sal_uInt16 delta = _aDateTime.Month / 12;
105 : 0 : aDateTime.Year += delta;
106 : 0 : aDateTime.Month -= delta * 12;
107 : 0 : aDateTime.Month++;
108 : : }
109 : :
110 : 0 : _nJulianTime = ((aDateTime.Hours*3600000)+(aDateTime.Minutes*60000)+(aDateTime.Seconds*1000)+(aDateTime.HundredthSeconds*10));
111 : : /* conversion factors */
112 : : sal_uInt16 iy0;
113 : : sal_uInt16 im0;
114 [ # # ]: 0 : if ( aDateTime.Month <= 2 )
115 : : {
116 : 0 : iy0 = aDateTime.Year - 1;
117 : 0 : im0 = aDateTime.Month + 12;
118 : : }
119 : : else
120 : : {
121 : 0 : iy0 = aDateTime.Year;
122 : 0 : im0 = aDateTime.Month;
123 : : }
124 : 0 : sal_Int32 ia = iy0 / 100;
125 : 0 : sal_Int32 ib = 2 - ia + (ia >> 2);
126 : : /* calculate julian date */
127 [ # # ]: 0 : if ( aDateTime.Year <= 0 )
128 : : {
129 : : _nJulianDate = (sal_Int32) ((365.25 * iy0) - 0.75)
130 : : + (sal_Int32) (30.6001 * (im0 + 1) )
131 : 0 : + aDateTime.Day + 1720994;
132 : : } // if ( _aDateTime.Year <= 0 )
133 : : else
134 : : {
135 : : _nJulianDate = static_cast<sal_Int32>( ((365.25 * iy0)
136 : : + (sal_Int32) (30.6001 * (im0 + 1))
137 : 0 : + aDateTime.Day + 1720994));
138 : : }
139 : 0 : double JD = _nJulianDate + 0.5;
140 : 0 : _nJulianDate = (sal_Int32)( JD + 0.5);
141 : 0 : const double gyr = aDateTime.Year + (0.01 * aDateTime.Month) + (0.0001 * aDateTime.Day);
142 [ # # ]: 0 : if ( gyr >= 1582.1015 ) /* on or after 15 October 1582 */
143 : 0 : _nJulianDate += ib;
144 : 0 : }
145 : :
146 : : /**
147 : : calculates date time from the Julian Date
148 : : */
149 : 0 : void lcl_CalDate(sal_Int32 _nJulianDate,sal_Int32 _nJulianTime,com::sun::star::util::DateTime& _rDateTime)
150 : : {
151 [ # # ]: 0 : if ( _nJulianDate )
152 : : {
153 : : sal_Int32 ialp;
154 : 0 : sal_Int32 ka = _nJulianDate;
155 [ # # ]: 0 : if ( _nJulianDate >= 2299161 )
156 : : {
157 : 0 : ialp = (sal_Int32)( ((double) _nJulianDate - 1867216.25 ) / ( 36524.25 ));
158 : 0 : ka = _nJulianDate + 1 + ialp - ( ialp >> 2 );
159 : : }
160 : 0 : sal_Int32 kb = ka + 1524;
161 : 0 : sal_Int32 kc = (sal_Int32) ( ((double) kb - 122.1 ) / 365.25 );
162 : 0 : sal_Int32 kd = (sal_Int32) ((double) kc * 365.25);
163 : 0 : sal_Int32 ke = (sal_Int32) ((double) ( kb - kd ) / 30.6001 );
164 : 0 : _rDateTime.Day = static_cast<sal_uInt16>(kb - kd - ((sal_Int32) ( (double) ke * 30.6001 )));
165 [ # # ]: 0 : if ( ke > 13 )
166 : 0 : _rDateTime.Month = static_cast<sal_uInt16>(ke - 13);
167 : : else
168 : 0 : _rDateTime.Month = static_cast<sal_uInt16>(ke - 1);
169 [ # # ][ # # ]: 0 : if ( (_rDateTime.Month == 2) && (_rDateTime.Day > 28) )
170 : 0 : _rDateTime.Day = 29;
171 [ # # ][ # # ]: 0 : if ( (_rDateTime.Month == 2) && (_rDateTime.Day == 29) && (ke == 3) )
[ # # ]
172 : 0 : _rDateTime.Year = static_cast<sal_uInt16>(kc - 4716);
173 [ # # ]: 0 : else if ( _rDateTime.Month > 2 )
174 : 0 : _rDateTime.Year = static_cast<sal_uInt16>(kc - 4716);
175 : : else
176 : 0 : _rDateTime.Year = static_cast<sal_uInt16>(kc - 4715);
177 : : }
178 : :
179 [ # # ]: 0 : if ( _nJulianTime )
180 : : {
181 : 0 : double d_s = _nJulianTime / 1000;
182 : 0 : double d_m = d_s / 60;
183 : 0 : double d_h = d_m / 60;
184 : 0 : _rDateTime.Hours = (sal_uInt16) (d_h);
185 : 0 : _rDateTime.Minutes = (sal_uInt16) d_m;
186 : 0 : _rDateTime.Seconds = static_cast<sal_uInt16>(( d_m - (double) _rDateTime.Minutes ) * 60.0);
187 : : }
188 : 0 : }
189 : :
190 : : }
191 : :
192 : : // -------------------------------------------------------------------------
193 : 28 : void ODbaseTable::readHeader()
194 : : {
195 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ODbaseTable::readHeader" );
196 : : OSL_ENSURE(m_pFileStream,"No Stream available!");
197 [ + - ]: 28 : if(!m_pFileStream)
198 : 28 : return;
199 [ + - ]: 28 : m_pFileStream->RefreshBuffer(); // Make sure, that the header information actually is read again
200 [ + - ]: 28 : m_pFileStream->Seek(STREAM_SEEK_TO_BEGIN);
201 : :
202 : 28 : sal_uInt8 nType=0;
203 [ + - ]: 28 : (*m_pFileStream) >> nType;
204 [ - + ]: 28 : if(ERRCODE_NONE != m_pFileStream->GetErrorCode())
205 [ # # ]: 0 : throwInvalidDbaseFormat();
206 : :
207 [ + - ]: 28 : m_pFileStream->Read((char*)(&m_aHeader.db_aedat), 3*sizeof(sal_uInt8));
208 [ - + ]: 28 : if(ERRCODE_NONE != m_pFileStream->GetErrorCode())
209 [ # # ]: 0 : throwInvalidDbaseFormat();
210 [ + - ]: 28 : (*m_pFileStream) >> m_aHeader.db_anz;
211 [ - + ]: 28 : if(ERRCODE_NONE != m_pFileStream->GetErrorCode())
212 [ # # ]: 0 : throwInvalidDbaseFormat();
213 [ + - ]: 28 : (*m_pFileStream) >> m_aHeader.db_kopf;
214 [ - + ]: 28 : if(ERRCODE_NONE != m_pFileStream->GetErrorCode())
215 [ # # ]: 0 : throwInvalidDbaseFormat();
216 [ + - ]: 28 : (*m_pFileStream) >> m_aHeader.db_slng;
217 [ - + ]: 28 : if(ERRCODE_NONE != m_pFileStream->GetErrorCode())
218 [ # # ]: 0 : throwInvalidDbaseFormat();
219 [ + - ]: 28 : m_pFileStream->Read((char*)(&m_aHeader.db_frei), 20*sizeof(sal_uInt8));
220 [ - + ]: 28 : if(ERRCODE_NONE != m_pFileStream->GetErrorCode())
221 [ # # ]: 0 : throwInvalidDbaseFormat();
222 : :
223 [ - + ]: 28 : if ( ( ( m_aHeader.db_kopf - 1 ) / 32 - 1 ) <= 0 ) // number of fields
224 : : {
225 : : // no dbase file
226 [ # # ]: 0 : throwInvalidDbaseFormat();
227 : : }
228 : : else
229 : : {
230 : : // Consistency check of the header:
231 : 28 : m_aHeader.db_typ = (DBFType)nType;
232 [ + - - ]: 28 : switch (m_aHeader.db_typ)
233 : : {
234 : : case dBaseIII:
235 : : case dBaseIV:
236 : : case dBaseV:
237 : : case VisualFoxPro:
238 : : case VisualFoxProAuto:
239 : : case dBaseFS:
240 : : case dBaseFSMemo:
241 : : case dBaseIVMemoSQL:
242 : : case dBaseIIIMemo:
243 : : case FoxProMemo:
244 [ + - ]: 28 : m_pFileStream->SetNumberFormatInt(NUMBERFORMAT_INT_LITTLEENDIAN);
245 [ - + ][ # # ]: 28 : if ( m_aHeader.db_frei[17] != 0x00
[ # # # # ]
[ - + ]
246 : 0 : && !m_aHeader.db_frei[18] && !m_aHeader.db_frei[19] && getConnection()->isTextEncodingDefaulted() )
247 : : {
248 [ # # # # : 0 : switch(m_aHeader.db_frei[17])
# # # # #
# # # # #
# # # # #
# # # # #
# # # ]
249 : : {
250 : 0 : case 0x01: m_eEncoding = RTL_TEXTENCODING_IBM_437; break; // DOS USA code page 437
251 : 0 : case 0x02: m_eEncoding = RTL_TEXTENCODING_IBM_850; break; // DOS Multilingual code page 850
252 : 0 : case 0x03: m_eEncoding = RTL_TEXTENCODING_MS_1252; break; // Windows ANSI code page 1252
253 : 0 : case 0x04: m_eEncoding = RTL_TEXTENCODING_APPLE_ROMAN; break; // Standard Macintosh
254 : 0 : case 0x64: m_eEncoding = RTL_TEXTENCODING_IBM_852; break; // EE MS-DOS code page 852
255 : 0 : case 0x65: m_eEncoding = RTL_TEXTENCODING_IBM_865; break; // Nordic MS-DOS code page 865
256 : 0 : case 0x66: m_eEncoding = RTL_TEXTENCODING_IBM_866; break; // Russian MS-DOS code page 866
257 : 0 : case 0x67: m_eEncoding = RTL_TEXTENCODING_IBM_861; break; // Icelandic MS-DOS
258 : : //case 0x68: m_eEncoding = ; break; // Kamenicky (Czech) MS-DOS
259 : : //case 0x69: m_eEncoding = ; break; // Mazovia (Polish) MS-DOS
260 : 0 : case 0x6A: m_eEncoding = RTL_TEXTENCODING_IBM_737; break; // Greek MS-DOS (437G)
261 : 0 : case 0x6B: m_eEncoding = RTL_TEXTENCODING_IBM_857; break; // Turkish MS-DOS
262 : 0 : case 0x6C: m_eEncoding = RTL_TEXTENCODING_IBM_863; break; // MS-DOS, Canada
263 : 0 : case 0x78: m_eEncoding = RTL_TEXTENCODING_MS_950; break; // Windows, Traditional Chinese
264 : 0 : case 0x79: m_eEncoding = RTL_TEXTENCODING_MS_949; break; // Windows, Korean (Hangul)
265 : 0 : case 0x7A: m_eEncoding = RTL_TEXTENCODING_MS_936; break; // Windows, Simplified Chinese
266 : 0 : case 0x7B: m_eEncoding = RTL_TEXTENCODING_MS_932; break; // Windows, Japanese (Shift-jis)
267 : 0 : case 0x7C: m_eEncoding = RTL_TEXTENCODING_MS_874; break; // Windows, Thai
268 : 0 : case 0x7D: m_eEncoding = RTL_TEXTENCODING_MS_1255; break; // Windows, Hebrew
269 : 0 : case 0x7E: m_eEncoding = RTL_TEXTENCODING_MS_1256; break; // Windows, Arabic
270 : 0 : case 0x96: m_eEncoding = RTL_TEXTENCODING_APPLE_CYRILLIC; break; // Russian Macintosh
271 : 0 : case 0x97: m_eEncoding = RTL_TEXTENCODING_APPLE_CENTEURO; break; // Eastern European Macintosh
272 : 0 : case 0x98: m_eEncoding = RTL_TEXTENCODING_APPLE_GREEK; break; // Greek Macintosh
273 : 0 : case 0xC8: m_eEncoding = RTL_TEXTENCODING_MS_1250; break; // Windows EE code page 1250
274 : 0 : case 0xC9: m_eEncoding = RTL_TEXTENCODING_MS_1251; break; // Russian Windows
275 : 0 : case 0xCA: m_eEncoding = RTL_TEXTENCODING_MS_1254; break; // Turkish Windows
276 : 0 : case 0xCB: m_eEncoding = RTL_TEXTENCODING_MS_1253; break; // Greek Windows
277 : 0 : case 0xCC: m_eEncoding = RTL_TEXTENCODING_MS_1257; break; // Windows, Baltic
278 : : default:
279 : : // Default Encoding
280 : 0 : m_eEncoding = RTL_TEXTENCODING_IBM_850;
281 : 0 : break;
282 : : }
283 : : }
284 : 28 : break;
285 : : case dBaseIVMemo:
286 [ # # ]: 0 : m_pFileStream->SetNumberFormatInt(NUMBERFORMAT_INT_LITTLEENDIAN);
287 : 0 : break;
288 : : default:
289 : : {
290 [ # # ]: 28 : throwInvalidDbaseFormat();
291 : : }
292 : : }
293 : : }
294 : : }
295 : : // -------------------------------------------------------------------------
296 : 28 : void ODbaseTable::fillColumns()
297 : : {
298 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ODbaseTable::fillColumns" );
299 [ + - ]: 28 : m_pFileStream->Seek(STREAM_SEEK_TO_BEGIN);
300 [ + - ]: 28 : m_pFileStream->Seek(32L);
301 : :
302 [ - + ]: 28 : if(!m_aColumns.is())
303 [ # # ][ # # ]: 0 : m_aColumns = new OSQLColumns();
304 : : else
305 : 28 : m_aColumns->get().clear();
306 : :
307 : 28 : m_aTypes.clear();
308 : 28 : m_aPrecisions.clear();
309 : 28 : m_aScales.clear();
310 : :
311 : : // Number of fields:
312 : 28 : const sal_Int32 nFieldCount = (m_aHeader.db_kopf - 1) / 32 - 1;
313 : : OSL_ENSURE(nFieldCount,"No columns in table!");
314 : :
315 [ + - ]: 28 : m_aColumns->get().reserve(nFieldCount);
316 [ + - ]: 28 : m_aTypes.reserve(nFieldCount);
317 [ + - ]: 28 : m_aPrecisions.reserve(nFieldCount);
318 [ + - ]: 28 : m_aScales.reserve(nFieldCount);
319 : :
320 [ + - ]: 28 : String aStrFieldName;
321 [ + - ]: 28 : aStrFieldName.AssignAscii("Column");
322 : 28 : ::rtl::OUString aTypeName;
323 [ + - ][ + - ]: 28 : const sal_Bool bCase = getConnection()->getMetaData()->supportsMixedCaseQuotedIdentifiers();
[ + - ]
324 [ + - ][ - + ]: 28 : const bool bFoxPro = m_aHeader.db_typ == VisualFoxPro || m_aHeader.db_typ == VisualFoxProAuto || m_aHeader.db_typ == FoxProMemo;
[ + - ]
325 : :
326 : 28 : sal_Int32 i = 0;
327 [ + + ]: 576 : for (; i < nFieldCount; i++)
328 : : {
329 : : DBFColumn aDBFColumn;
330 [ + - ]: 548 : m_pFileStream->Read((char*)&aDBFColumn, sizeof(aDBFColumn));
331 [ + - ]: 548 : if ( FIELD_DESCRIPTOR_TERMINATOR == aDBFColumn.db_fnm[0] ) // 0x0D stored as the Field Descriptor terminator.
332 : : break;
333 : :
334 [ - + ][ # # ]: 548 : sal_Bool bIsRowVersion = bFoxPro && ( aDBFColumn.db_frei2[0] & 0x01 ) == 0x01;
335 [ + - ]: 548 : const String aColumnName((const char *)aDBFColumn.db_fnm,m_eEncoding);
336 : :
337 [ + - ]: 548 : m_aRealFieldLengths.push_back(aDBFColumn.db_flng);
338 : 548 : sal_Int32 nPrecision = aDBFColumn.db_flng;
339 : : sal_Int32 eType;
340 : 548 : sal_Bool bIsCurrency = sal_False;
341 : :
342 : : char cType[2];
343 : 548 : cType[0] = aDBFColumn.db_typ;
344 : 548 : cType[1] = 0;
345 : 548 : aTypeName = ::rtl::OUString::createFromAscii(cType);
346 : : OSL_TRACE("column type: %c",aDBFColumn.db_typ);
347 : :
348 [ + - + + : 548 : switch (aDBFColumn.db_typ)
- + - - +
- - - ]
349 : : {
350 : : case 'C':
351 : 184 : eType = DataType::VARCHAR;
352 : 184 : aTypeName = ::rtl::OUString("VARCHAR");
353 : 184 : break;
354 : : case 'F':
355 : 0 : aTypeName = ::rtl::OUString("DECIMAL");
356 : : case 'N':
357 [ + - ]: 80 : if ( aDBFColumn.db_typ == 'N' )
358 : 80 : aTypeName = ::rtl::OUString("NUMERIC");
359 : 80 : eType = DataType::DECIMAL;
360 : :
361 : : // for numeric fields two characters more are written, than the precision of the column description predescribes,
362 : : // to keep room for the possible sign and the comma. This has to be considered...
363 [ + - ]: 80 : nPrecision = SvDbaseConverter::ConvertPrecisionToOdbc(nPrecision,aDBFColumn.db_dez);
364 : : // This is not true for older versions ....
365 : 80 : break;
366 : : case 'L':
367 : 16 : eType = DataType::BIT;
368 : 16 : aTypeName = ::rtl::OUString("BOOLEAN");
369 : 16 : break;
370 : : case 'Y':
371 : 0 : bIsCurrency = sal_True;
372 : 0 : eType = DataType::DOUBLE;
373 : 0 : aTypeName = ::rtl::OUString("DOUBLE");
374 : 0 : break;
375 : : case 'D':
376 : 32 : eType = DataType::DATE;
377 : 32 : aTypeName = ::rtl::OUString("DATE");
378 : 32 : break;
379 : : case 'T':
380 : 0 : eType = DataType::TIMESTAMP;
381 : 0 : aTypeName = ::rtl::OUString("TIMESTAMP");
382 : 0 : break;
383 : : case 'I':
384 : 0 : eType = DataType::INTEGER;
385 : 0 : aTypeName = ::rtl::OUString("INTEGER");
386 : 0 : break;
387 : : case 'M':
388 [ - + ][ # # ]: 236 : if ( bFoxPro && ( aDBFColumn.db_frei2[0] & 0x04 ) == 0x04 )
389 : : {
390 : 0 : eType = DataType::LONGVARBINARY;
391 : 0 : aTypeName = ::rtl::OUString("LONGVARBINARY");
392 : : }
393 : : else
394 : : {
395 : 236 : aTypeName = ::rtl::OUString("LONGVARCHAR");
396 : 236 : eType = DataType::LONGVARCHAR;
397 : : }
398 : 236 : nPrecision = 2147483647;
399 : 236 : break;
400 : : case 'P':
401 : 0 : aTypeName = ::rtl::OUString("LONGVARBINARY");
402 : 0 : eType = DataType::LONGVARBINARY;
403 : 0 : nPrecision = 2147483647;
404 : 0 : break;
405 : : case '0':
406 : : case 'B':
407 [ # # ][ # # ]: 0 : if ( m_aHeader.db_typ == VisualFoxPro || m_aHeader.db_typ == VisualFoxProAuto )
408 : : {
409 : 0 : aTypeName = ::rtl::OUString("DOUBLE");
410 : 0 : eType = DataType::DOUBLE;
411 : : }
412 : : else
413 : : {
414 : 0 : aTypeName = ::rtl::OUString("LONGVARBINARY");
415 : 0 : eType = DataType::LONGVARBINARY;
416 : 0 : nPrecision = 2147483647;
417 : : }
418 : 0 : break;
419 : : default:
420 : 0 : eType = DataType::OTHER;
421 : : }
422 : :
423 [ + - ]: 548 : m_aTypes.push_back(eType);
424 [ + - ]: 548 : m_aPrecisions.push_back(nPrecision);
425 [ + - ]: 548 : m_aScales.push_back(aDBFColumn.db_dez);
426 : :
427 : : Reference< XPropertySet> xCol = new sdbcx::OColumn(aColumnName,
428 : : aTypeName,
429 : : ::rtl::OUString(),
430 : : ::rtl::OUString(),
431 : : ColumnValue::NULLABLE,
432 : : nPrecision,
433 : : aDBFColumn.db_dez,
434 : : eType,
435 : : sal_False,
436 : : bIsRowVersion,
437 : : bIsCurrency,
438 [ + - ][ + - ]: 548 : bCase);
[ + - ][ + - ]
439 [ + - ]: 548 : m_aColumns->get().push_back(xCol);
440 [ + - ]: 548 : } // for (; i < nFieldCount; i++)
441 [ + - ]: 28 : OSL_ENSURE(i,"No columns in table!");
442 : 28 : }
443 : : // -------------------------------------------------------------------------
444 : 0 : ODbaseTable::ODbaseTable(sdbcx::OCollection* _pTables,ODbaseConnection* _pConnection)
445 : : :ODbaseTable_BASE(_pTables,_pConnection)
446 : : ,m_pMemoStream(NULL)
447 [ # # ][ # # ]: 0 : ,m_bWriteableMemo(sal_False)
[ # # ][ # # ]
448 : : {
449 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ODbaseTable::ODbaseTable" );
450 : : // initialize the header
451 : 0 : m_aHeader.db_typ = dBaseIII;
452 : 0 : m_aHeader.db_anz = 0;
453 : 0 : m_aHeader.db_kopf = 0;
454 : 0 : m_aHeader.db_slng = 0;
455 : 0 : m_eEncoding = getConnection()->getTextEncoding();
456 : 0 : }
457 : : // -------------------------------------------------------------------------
458 : 28 : ODbaseTable::ODbaseTable(sdbcx::OCollection* _pTables,ODbaseConnection* _pConnection,
459 : : const ::rtl::OUString& _Name,
460 : : const ::rtl::OUString& _Type,
461 : : const ::rtl::OUString& _Description ,
462 : : const ::rtl::OUString& _SchemaName,
463 : : const ::rtl::OUString& _CatalogName
464 : : ) : ODbaseTable_BASE(_pTables,_pConnection,_Name,
465 : : _Type,
466 : : _Description,
467 : : _SchemaName,
468 : : _CatalogName)
469 : : ,m_pMemoStream(NULL)
470 [ + - ][ + - ]: 28 : ,m_bWriteableMemo(sal_False)
[ + - ][ + - ]
471 : : {
472 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ODbaseTable::ODbaseTable" );
473 : 28 : m_eEncoding = getConnection()->getTextEncoding();
474 : 28 : }
475 : :
476 : : // -----------------------------------------------------------------------------
477 : 28 : void ODbaseTable::construct()
478 : : {
479 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ODbaseTable::construct" );
480 : : // initialize the header
481 : 28 : m_aHeader.db_typ = dBaseIII;
482 : 28 : m_aHeader.db_anz = 0;
483 : 28 : m_aHeader.db_kopf = 0;
484 : 28 : m_aHeader.db_slng = 0;
485 : 28 : m_aMemoHeader.db_size = 0;
486 : :
487 [ + - ]: 28 : String sFileName(getEntry(m_pConnection,m_Name));
488 : :
489 [ + - ]: 28 : INetURLObject aURL;
490 [ + - ][ + - ]: 28 : aURL.SetURL(sFileName);
491 : :
492 : : OSL_ENSURE( m_pConnection->matchesExtension( aURL.getExtension() ),
493 : : "ODbaseTable::ODbaseTable: invalid extension!");
494 : : // getEntry is expected to ensure the corect file name
495 : :
496 [ + - ]: 28 : m_pFileStream = createStream_simpleError( sFileName, STREAM_READWRITE | STREAM_NOCREATE | STREAM_SHARE_DENYWRITE);
497 : 28 : m_bWriteable = ( m_pFileStream != NULL );
498 : :
499 [ - + ]: 28 : if ( !m_pFileStream )
500 : : {
501 : 0 : m_bWriteable = sal_False;
502 [ # # ]: 0 : m_pFileStream = createStream_simpleError( sFileName, STREAM_READ | STREAM_NOCREATE | STREAM_SHARE_DENYNONE);
503 : : }
504 : :
505 [ + - ]: 28 : if(m_pFileStream)
506 : : {
507 [ + - ]: 28 : readHeader();
508 [ + - ]: 28 : if (HasMemoFields())
509 : : {
510 : : // Create Memo-Filename (.DBT):
511 : : // nyi: Ugly for Unix and Mac!
512 : :
513 [ + - ][ + - ]: 28 : if ( m_aHeader.db_typ == FoxProMemo || VisualFoxPro == m_aHeader.db_typ || VisualFoxProAuto == m_aHeader.db_typ ) // foxpro uses another extension
[ - + ]
514 [ # # ]: 0 : aURL.SetExtension(rtl::OUString("fpt"));
515 : : else
516 [ + - ]: 28 : aURL.SetExtension(rtl::OUString("dbt"));
517 : :
518 : : // If the memo file isn't found, the data will be displayed anyhow.
519 : : // However, updates can't be done
520 : : // but the operation is executed
521 [ + - ][ + - ]: 28 : m_pMemoStream = createStream_simpleError( aURL.GetMainURL(INetURLObject::NO_DECODE), STREAM_READWRITE | STREAM_NOCREATE | STREAM_SHARE_DENYWRITE);
[ + - ][ + - ]
522 [ + + ]: 28 : if ( !m_pMemoStream )
523 : : {
524 : 16 : m_bWriteableMemo = sal_False;
525 [ + - ][ + - ]: 16 : m_pMemoStream = createStream_simpleError( aURL.GetMainURL(INetURLObject::NO_DECODE), STREAM_READ | STREAM_NOCREATE | STREAM_SHARE_DENYNONE);
[ + - ][ + - ]
526 : : }
527 [ + + ]: 28 : if (m_pMemoStream)
528 [ + - ]: 12 : ReadMemoHeader();
529 : : }
530 [ + - ]: 28 : fillColumns();
531 : :
532 [ + - ]: 28 : sal_uInt32 nFileSize = lcl_getFileSize(*m_pFileStream);
533 [ + - ]: 28 : m_pFileStream->Seek(STREAM_SEEK_TO_BEGIN);
534 [ - + ][ # # ]: 28 : if ( m_aHeader.db_anz == 0 && ((nFileSize-m_aHeader.db_kopf)/m_aHeader.db_slng) > 0) // seems to be empty or someone wrote bullshit into the dbase file
535 : 0 : m_aHeader.db_anz = ((nFileSize-m_aHeader.db_kopf)/m_aHeader.db_slng);
536 : :
537 : : // Buffersize dependent on the file size
538 : : m_pFileStream->SetBufferSize(nFileSize > 1000000 ? 32768 :
539 : : nFileSize > 100000 ? 16384 :
540 [ + - ][ + + ]: 28 : nFileSize > 10000 ? 4096 : 1024);
[ - + ][ + - ]
541 : :
542 [ + + ]: 28 : if (m_pMemoStream)
543 : : {
544 : : // set the buffer extactly to the length of a record
545 [ + - ]: 12 : m_pMemoStream->Seek(STREAM_SEEK_TO_END);
546 : 12 : nFileSize = m_pMemoStream->Tell();
547 [ + - ]: 12 : m_pMemoStream->Seek(STREAM_SEEK_TO_BEGIN);
548 : :
549 : : // Buffersize dependent on the file size
550 : : m_pMemoStream->SetBufferSize(nFileSize > 1000000 ? 32768 :
551 : : nFileSize > 100000 ? 16384 :
552 : : nFileSize > 10000 ? 4096 :
553 [ + - ][ - + ]: 12 : m_aMemoHeader.db_size);
[ # # ][ + - ]
554 : : }
555 : :
556 [ + - ]: 28 : AllocBuffer();
557 [ + - ][ + - ]: 28 : }
558 : 28 : }
559 : : //------------------------------------------------------------------
560 : 12 : sal_Bool ODbaseTable::ReadMemoHeader()
561 : : {
562 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ODbaseTable::ReadMemoHeader" );
563 : 12 : m_pMemoStream->SetNumberFormatInt(NUMBERFORMAT_INT_LITTLEENDIAN);
564 : 12 : m_pMemoStream->RefreshBuffer(); // make sure that the header information is actually read again
565 : 12 : m_pMemoStream->Seek(0L);
566 : :
567 : 12 : (*m_pMemoStream) >> m_aMemoHeader.db_next;
568 [ + - - ]: 12 : switch (m_aHeader.db_typ)
569 : : {
570 : : case dBaseIIIMemo: // dBase III: fixed block size
571 : : case dBaseIVMemo:
572 : : // sometimes dBase3 is attached to dBase4 memo
573 : 12 : m_pMemoStream->Seek(20L);
574 : 12 : (*m_pMemoStream) >> m_aMemoHeader.db_size;
575 [ # # ][ - + ]: 12 : if (m_aMemoHeader.db_size > 1 && m_aMemoHeader.db_size != 512) // 1 is also for dBase 3
576 : 0 : m_aMemoHeader.db_typ = MemodBaseIV;
577 [ - + ][ # # ]: 12 : else if (m_aMemoHeader.db_size > 1 && m_aMemoHeader.db_size == 512)
578 : : {
579 : : // There are files using size specification, though they are dBase-files
580 : : char sHeader[4];
581 [ # # ]: 0 : m_pMemoStream->Seek(m_aMemoHeader.db_size);
582 [ # # ]: 0 : m_pMemoStream->Read(sHeader,4);
583 : :
584 [ # # ][ # # ]: 0 : if ((m_pMemoStream->GetErrorCode() != ERRCODE_NONE) || ((sal_uInt8)sHeader[0]) != 0xFF || ((sal_uInt8)sHeader[1]) != 0xFF || ((sal_uInt8)sHeader[2]) != 0x08)
[ # # ][ # # ]
[ # # ]
585 : 0 : m_aMemoHeader.db_typ = MemodBaseIII;
586 : : else
587 : 0 : m_aMemoHeader.db_typ = MemodBaseIV;
588 : : }
589 : : else
590 : : {
591 : 12 : m_aMemoHeader.db_typ = MemodBaseIII;
592 : 12 : m_aMemoHeader.db_size = 512;
593 : : }
594 : 12 : break;
595 : : case VisualFoxPro:
596 : : case VisualFoxProAuto:
597 : : case FoxProMemo:
598 : 0 : m_aMemoHeader.db_typ = MemoFoxPro;
599 : 0 : m_pMemoStream->Seek(6L);
600 : 0 : m_pMemoStream->SetNumberFormatInt(NUMBERFORMAT_INT_BIGENDIAN);
601 : 0 : (*m_pMemoStream) >> m_aMemoHeader.db_size;
602 : 0 : break;
603 : : default:
604 : : OSL_FAIL( "ODbaseTable::ReadMemoHeader: unsupported memo type!" );
605 : 0 : break;
606 : : }
607 : 12 : return sal_True;
608 : : }
609 : : // -------------------------------------------------------------------------
610 : 56 : String ODbaseTable::getEntry(OConnection* _pConnection,const ::rtl::OUString& _sName )
611 : : {
612 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ODbaseTable::getEntry" );
613 : 56 : ::rtl::OUString sURL;
614 : : try
615 : : {
616 [ + - ][ + - ]: 56 : Reference< XResultSet > xDir = _pConnection->getDir()->getStaticResultSet();
[ + - ]
617 [ + - ]: 56 : Reference< XRow> xRow(xDir,UNO_QUERY);
618 : 56 : ::rtl::OUString sName;
619 : 56 : ::rtl::OUString sExt;
620 [ + - ]: 56 : INetURLObject aURL;
621 [ + + ][ + - ]: 56 : static const ::rtl::OUString s_sSeparator("/");
622 [ + - ][ + - ]: 56 : xDir->beforeFirst();
623 [ + - ][ + - ]: 284 : while(xDir->next())
[ + - ]
624 : : {
625 [ + - ][ + - ]: 284 : sName = xRow->getString(1);
626 : 284 : aURL.SetSmartProtocol(INET_PROT_FILE);
627 [ + - ]: 284 : String sUrl = _pConnection->getURL() + s_sSeparator + sName;
628 [ + - ][ + - ]: 284 : aURL.SetSmartURL( sUrl );
629 : :
630 : : // cut the extension
631 [ + - ]: 284 : sExt = aURL.getExtension();
632 : :
633 : : // name and extension have to coincide
634 [ + - ][ + - ]: 284 : if ( _pConnection->matchesExtension( sExt ) )
[ + + ][ + - ]
635 : : {
636 : 92 : sName = sName.replaceAt(sName.getLength()-(sExt.getLength()+1),sExt.getLength()+1,::rtl::OUString());
637 [ + + ]: 92 : if ( sName == _sName )
638 : : {
639 [ + - ]: 56 : Reference< XContentAccess > xContentAccess( xDir, UNO_QUERY );
640 [ + - ][ + - ]: 56 : sURL = xContentAccess->queryContentIdentifierString();
641 : 284 : break;
642 : : }
643 : : }
644 [ + - ][ + + ]: 284 : }
645 [ + - ][ + - ]: 56 : xDir->beforeFirst(); // move back to before first record
[ + - ][ # # ]
646 : : }
647 [ # # ]: 0 : catch(const Exception&)
648 : : {
649 : : OSL_ASSERT(0);
650 : : }
651 [ + - ]: 56 : return sURL;
652 : : }
653 : : // -------------------------------------------------------------------------
654 : 28 : void ODbaseTable::refreshColumns()
655 : : {
656 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ODbaseTable::refreshColumns" );
657 [ + - ]: 28 : ::osl::MutexGuard aGuard( m_aMutex );
658 : :
659 [ + - ]: 28 : TStringVector aVector;
660 [ + - ]: 28 : aVector.reserve(m_aColumns->get().size());
661 : :
662 [ + - ][ + - ]: 576 : for(OSQLColumns::Vector::const_iterator aIter = m_aColumns->get().begin();aIter != m_aColumns->get().end();++aIter)
[ + + ]
663 [ + - ][ + - ]: 548 : aVector.push_back(Reference< XNamed>(*aIter,UNO_QUERY)->getName());
[ + - ][ + - ]
664 : :
665 [ - + ]: 28 : if(m_pColumns)
666 [ # # ]: 0 : m_pColumns->reFill(aVector);
667 : : else
668 [ + - ][ + - ]: 28 : m_pColumns = new ODbaseColumns(this,m_aMutex,aVector);
[ + - ]
669 : 28 : }
670 : : // -------------------------------------------------------------------------
671 : 28 : void ODbaseTable::refreshIndexes()
672 : : {
673 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ODbaseTable::refreshIndexes" );
674 [ + - ]: 28 : TStringVector aVector;
675 [ + - ][ - + ]: 28 : if(m_pFileStream && (!m_pIndexes || m_pIndexes->getCount() == 0))
[ # # ][ # # ]
[ + - ]
676 : : {
677 [ + - ]: 28 : INetURLObject aURL;
678 [ + - ][ + - ]: 28 : aURL.SetURL(getEntry(m_pConnection,m_Name));
[ + - ][ + - ]
679 : :
680 [ + - ]: 28 : aURL.setExtension(rtl::OUString("inf"));
681 [ + - ][ + - ]: 28 : Config aInfFile(aURL.getFSysPath(INetURLObject::FSYS_DETECT));
682 [ + - ]: 28 : aInfFile.SetGroup(dBASE_III_GROUP);
683 [ + - ]: 28 : sal_uInt16 nKeyCnt = aInfFile.GetKeyCount();
684 : 28 : rtl::OString aKeyName;
685 : :
686 [ - + ]: 28 : for (sal_uInt16 nKey = 0; nKey < nKeyCnt; nKey++)
687 : : {
688 : : // Refences the key an index-file?
689 [ # # ]: 0 : aKeyName = aInfFile.GetKeyName( nKey );
690 : : //...if yes, add the index list of the table
691 [ # # ]: 0 : if (aKeyName.copy(0,3).equalsL(RTL_CONSTASCII_STRINGPARAM("NDX")))
692 : : {
693 [ # # ]: 0 : rtl::OString aIndexName = aInfFile.ReadKey(aKeyName);
694 [ # # ][ # # ]: 0 : aURL.setName(rtl::OStringToOUString(aIndexName, m_eEncoding));
695 : : try
696 : : {
697 [ # # ][ # # ]: 0 : Content aCnt(aURL.GetMainURL(INetURLObject::NO_DECODE),Reference<XCommandEnvironment>());
698 [ # # ][ # # ]: 0 : if (aCnt.isDocument())
699 : : {
700 [ # # ][ # # ]: 0 : aVector.push_back(aURL.getBase());
701 [ # # ][ # # ]: 0 : }
702 : : }
703 [ # # ]: 0 : catch(const Exception&) // an exception is thrown when no file exists
704 : : {
705 : 0 : }
706 : : }
707 [ + - ][ + - ]: 28 : }
708 : : }
709 [ - + ]: 28 : if(m_pIndexes)
710 [ # # ]: 0 : m_pIndexes->reFill(aVector);
711 : : else
712 [ + - ][ + - ]: 28 : m_pIndexes = new ODbaseIndexes(this,m_aMutex,aVector);
713 : 28 : }
714 : :
715 : : // -------------------------------------------------------------------------
716 : 28 : void SAL_CALL ODbaseTable::disposing(void)
717 : : {
718 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ODbaseTable::disposing" );
719 [ + - ]: 28 : OFileTable::disposing();
720 [ + - ]: 28 : ::osl::MutexGuard aGuard(m_aMutex);
721 [ + - ][ + - ]: 28 : m_aColumns = NULL;
722 : 28 : }
723 : : // -------------------------------------------------------------------------
724 : 0 : Sequence< Type > SAL_CALL ODbaseTable::getTypes( ) throw(RuntimeException)
725 : : {
726 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ODbaseTable::getTypes" );
727 [ # # ]: 0 : Sequence< Type > aTypes = OTable_TYPEDEF::getTypes();
728 [ # # ]: 0 : ::std::vector<Type> aOwnTypes;
729 [ # # ]: 0 : aOwnTypes.reserve(aTypes.getLength());
730 : :
731 : 0 : const Type* pBegin = aTypes.getConstArray();
732 : 0 : const Type* pEnd = pBegin + aTypes.getLength();
733 [ # # ]: 0 : for(;pBegin != pEnd;++pBegin)
734 : : {
735 [ # # ][ # # ]: 0 : if(!(*pBegin == ::getCppuType((const Reference<XKeysSupplier>*)0) ||
736 [ # # ][ # # ]: 0 : *pBegin == ::getCppuType((const Reference<XDataDescriptorFactory>*)0)))
[ # # ]
737 : : {
738 [ # # ]: 0 : aOwnTypes.push_back(*pBegin);
739 : : }
740 : : }
741 [ # # ][ # # ]: 0 : aOwnTypes.push_back(::getCppuType( (const Reference< ::com::sun::star::lang::XUnoTunnel > *)0 ));
742 [ # # ]: 0 : Type *pTypes = aOwnTypes.empty() ? 0 : &aOwnTypes[0];
743 [ # # ][ # # ]: 0 : return Sequence< Type >(pTypes, aOwnTypes.size());
744 : : }
745 : :
746 : : // -------------------------------------------------------------------------
747 : 5248 : Any SAL_CALL ODbaseTable::queryInterface( const Type & rType ) throw(RuntimeException)
748 : : {
749 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ODbaseTable::queryInterface" );
750 [ + - ]: 10496 : if( rType == ::getCppuType((const Reference<XKeysSupplier>*)0) ||
[ + - - + ]
[ - + ]
751 [ + - ]: 5248 : rType == ::getCppuType((const Reference<XDataDescriptorFactory>*)0))
752 : 0 : return Any();
753 : :
754 [ + - ]: 5248 : Any aRet = OTable_TYPEDEF::queryInterface(rType);
755 [ + + ][ + - ]: 5248 : return aRet.hasValue() ? aRet : ::cppu::queryInterface(rType,static_cast< ::com::sun::star::lang::XUnoTunnel*> (this));
756 : : }
757 : :
758 : : //--------------------------------------------------------------------------
759 : 128 : Sequence< sal_Int8 > ODbaseTable::getUnoTunnelImplementationId()
760 : : {
761 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ODbaseTable::getUnoTunnelImplementationId" );
762 : : static ::cppu::OImplementationId * pId = 0;
763 [ + + ]: 128 : if (! pId)
764 : : {
765 [ + - ][ + - ]: 7 : ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
766 [ + - ]: 7 : if (! pId)
767 : : {
768 [ + - ][ + - ]: 7 : static ::cppu::OImplementationId aId;
769 : 7 : pId = &aId;
770 [ + - ]: 7 : }
771 : : }
772 : 128 : return pId->getImplementationId();
773 : : }
774 : :
775 : : // com::sun::star::lang::XUnoTunnel
776 : : //------------------------------------------------------------------
777 : 128 : sal_Int64 ODbaseTable::getSomething( const Sequence< sal_Int8 > & rId ) throw (RuntimeException)
778 : : {
779 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ODbaseTable::getSomething" );
780 [ + - ][ + - ]: 384 : return (rId.getLength() == 16 && 0 == memcmp(getUnoTunnelImplementationId().getConstArray(), rId.getConstArray(), 16 ) )
[ # # ]
781 : : ? reinterpret_cast< sal_Int64 >( this )
782 [ + - ]: 384 : : ODbaseTable_BASE::getSomething(rId);
[ + - - + ]
783 : : }
784 : : //------------------------------------------------------------------
785 : 3124 : sal_Bool ODbaseTable::fetchRow(OValueRefRow& _rRow,const OSQLColumns & _rCols, sal_Bool _bUseTableDefs,sal_Bool bRetrieveData)
786 : : {
787 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ODbaseTable::fetchRow" );
788 : : // Read the data
789 : 3124 : bool bIsCurRecordDeleted = (char)m_pBuffer[0] == '*';
790 : :
791 : : // only read the bookmark
792 : :
793 : : // Mark record as deleted
794 : 3124 : _rRow->setDeleted(bIsCurRecordDeleted);
795 [ + - ][ + - ]: 3124 : *(_rRow->get())[0] = m_nFilePos;
[ + - ]
796 : :
797 [ + + ]: 3124 : if (!bRetrieveData)
798 : 228 : return sal_True;
799 : :
800 : 2896 : sal_Size nByteOffset = 1;
801 : : // Fields:
802 : 2896 : OSQLColumns::Vector::const_iterator aIter = _rCols.get().begin();
803 : 2896 : OSQLColumns::Vector::const_iterator aEnd = _rCols.get().end();
804 : 2896 : const sal_Size nCount = _rRow->get().size();
805 [ + - ][ + + ]: 87272 : for (sal_Size i = 1; aIter != aEnd && nByteOffset <= m_nBufferSize && i < nCount;++aIter, i++)
[ + - ][ + - ]
[ + + ]
806 : : {
807 : : // Lengths depending on data type:
808 : 84376 : sal_Int32 nLen = 0;
809 : 84376 : sal_Int32 nType = 0;
810 [ + - ]: 84376 : if(_bUseTableDefs)
811 : : {
812 [ + - ]: 84376 : nLen = m_aPrecisions[i-1];
813 [ + - ]: 84376 : nType = m_aTypes[i-1];
814 : : }
815 : : else
816 : : {
817 [ # # ][ # # ]: 0 : (*aIter)->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_PRECISION)) >>= nLen;
[ # # ][ # # ]
818 [ # # ][ # # ]: 0 : (*aIter)->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TYPE)) >>= nType;
[ # # ][ # # ]
819 : : }
820 [ + + - + ]: 84376 : switch(nType)
821 : : {
822 : : case DataType::INTEGER:
823 : : case DataType::DOUBLE:
824 : : case DataType::TIMESTAMP:
825 : : case DataType::DATE:
826 : : case DataType::BIT:
827 : : case DataType::LONGVARCHAR:
828 : : case DataType::LONGVARBINARY:
829 [ + - ]: 45992 : nLen = m_aRealFieldLengths[i-1];
830 : 45992 : break;
831 : : case DataType::DECIMAL:
832 [ + - ]: 1350 : if(_bUseTableDefs)
833 [ + - ][ + - ]: 1350 : nLen = SvDbaseConverter::ConvertPrecisionToDbase(nLen,m_aScales[i-1]);
834 : : else
835 [ # # ][ # # ]: 0 : nLen = SvDbaseConverter::ConvertPrecisionToDbase(nLen,getINT32((*aIter)->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_SCALE))));
[ # # ][ # # ]
[ # # ][ # # ]
836 : 1350 : break; // the sign and the comma
837 : :
838 : : case DataType::BINARY:
839 : : case DataType::OTHER:
840 : 0 : nByteOffset += nLen;
841 : 0 : continue;
842 : : }
843 : :
844 : : // Is the variable bound?
845 [ + + ]: 84376 : if ( !(_rRow->get())[i]->isBound() )
846 : : {
847 : : // No - next field.
848 : 27540 : nByteOffset += nLen;
849 : : OSL_ENSURE( nByteOffset <= m_nBufferSize ,"ByteOffset > m_nBufferSize!");
850 : 27540 : continue;
851 : : } // if ( !(_rRow->get())[i]->isBound() )
852 [ + - ]: 56836 : if ( ( nByteOffset + nLen) > m_nBufferSize )
853 : : break; // length doesn't match buffer size.
854 : :
855 : 56836 : char *pData = (char *) (m_pBuffer + nByteOffset);
856 : :
857 [ + - ][ + + ]: 56836 : if (nType == DataType::CHAR || nType == DataType::VARCHAR)
858 : : {
859 : 24992 : sal_Int32 nLastPos = -1;
860 [ + + ]: 6317880 : for (sal_Int32 k = 0; k < nLen; ++k)
861 : : {
862 [ + + ]: 6292888 : if (pData[k] != ' ')
863 : : // Record last non-empty position.
864 : 93794 : nLastPos = k;
865 : : }
866 [ + + ]: 24992 : if (nLastPos < 0)
867 : : {
868 : : // Empty string. Skip it.
869 [ + - ]: 15628 : (_rRow->get())[i]->setNull();
870 : : }
871 : : else
872 : : {
873 : : // Commit the string. Use intern() to ref-count it.
874 [ + - ][ + - ]: 9364 : *(_rRow->get())[i] = ::rtl::OUString::intern(pData, static_cast<sal_Int32>(nLastPos+1), m_eEncoding);
[ + - ][ + - ]
875 : 24992 : }
876 : : } // if (nType == DataType::CHAR || nType == DataType::VARCHAR)
877 [ - + ]: 31844 : else if ( DataType::TIMESTAMP == nType )
878 : : {
879 : 0 : sal_Int32 nDate = 0,nTime = 0;
880 : 0 : memcpy(&nDate, pData, 4);
881 : 0 : memcpy(&nTime, pData+ 4, 4);
882 [ # # ][ # # ]: 0 : if ( !nDate && !nTime )
883 : : {
884 [ # # ]: 0 : (_rRow->get())[i]->setNull();
885 : : }
886 : : else
887 : : {
888 : 0 : ::com::sun::star::util::DateTime aDateTime;
889 : 0 : lcl_CalDate(nDate,nTime,aDateTime);
890 [ # # ][ # # ]: 0 : *(_rRow->get())[i] = aDateTime;
[ # # ]
891 : : }
892 : : }
893 [ - + ]: 31844 : else if ( DataType::INTEGER == nType )
894 : : {
895 : 0 : sal_Int32 nValue = 0;
896 : 0 : memcpy(&nValue, pData, nLen);
897 [ # # ][ # # ]: 0 : *(_rRow->get())[i] = nValue;
[ # # ]
898 : : }
899 [ - + ]: 31844 : else if ( DataType::DOUBLE == nType )
900 : : {
901 : 0 : double d = 0.0;
902 [ # # ][ # # ]: 0 : if (getBOOL((*aIter)->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_ISCURRENCY)))) // Currency is treated separately
[ # # ][ # # ]
[ # # ][ # # ]
903 : : {
904 : 0 : sal_Int64 nValue = 0;
905 : 0 : memcpy(&nValue, pData, nLen);
906 : :
907 [ # # ][ # # ]: 0 : if ( m_aScales[i-1] )
908 [ # # ]: 0 : d = (double)(nValue / pow(10.0,(int)m_aScales[i-1]));
909 : : else
910 : 0 : d = (double)(nValue);
911 : : }
912 : : else
913 : : {
914 : 0 : memcpy(&d, pData, nLen);
915 : : }
916 : :
917 [ # # ][ # # ]: 0 : *(_rRow->get())[i] = d;
[ # # ]
918 : : }
919 : : else
920 : : {
921 : 31844 : sal_Int32 nPos1 = -1, nPos2 = -1;
922 : : // If the string contains Nul-characters, then convert them to blanks!
923 [ + + ]: 357388 : for (sal_Int32 k = 0; k < nLen; k++)
924 : : {
925 [ + + ]: 325544 : if (pData[k] == '\0')
926 : 36836 : pData[k] = ' ';
927 : :
928 [ + + ]: 325544 : if (pData[k] != ' ')
929 : : {
930 [ + + ]: 193732 : if (nPos1 < 0)
931 : : // first non-empty char position.
932 : 19466 : nPos1 = k;
933 : :
934 : : // last non-empty char position.
935 : 193732 : nPos2 = k;
936 : : }
937 : : }
938 : :
939 [ + + ]: 31844 : if (nPos1 < 0)
940 : : {
941 : : // Empty string. Skip it.
942 : 12378 : nByteOffset += nLen;
943 [ + - ]: 12378 : (_rRow->get())[i]->setNull(); // no values -> done
944 : 12378 : continue;
945 : : }
946 : :
947 [ + - ]: 19466 : ::rtl::OUString aStr = ::rtl::OUString::intern(pData+nPos1, nPos2-nPos1+1, m_eEncoding);
948 : :
949 [ + + - + : 19466 : switch (nType)
- ]
950 : : {
951 : : case DataType::DATE:
952 : : {
953 [ - + ]: 116 : if (aStr.getLength() != nLen)
954 : : {
955 [ # # ]: 0 : (_rRow->get())[i]->setNull();
956 : : break;
957 : : }
958 : 116 : const sal_uInt16 nYear = (sal_uInt16)aStr.copy( 0, 4 ).toInt32();
959 : 116 : const sal_uInt16 nMonth = (sal_uInt16)aStr.copy( 4, 2 ).toInt32();
960 : 116 : const sal_uInt16 nDay = (sal_uInt16)aStr.copy( 6, 2 ).toInt32();
961 : :
962 : 116 : const ::com::sun::star::util::Date aDate(nDay,nMonth,nYear);
963 [ + - ][ + - ]: 116 : *(_rRow->get())[i] = aDate;
[ + - ]
964 : : }
965 : 116 : break;
966 : : case DataType::DECIMAL:
967 [ + - ][ + - ]: 232 : *(_rRow->get())[i] = ORowSetValue(aStr);
[ + - ]
968 : 232 : break;
969 : : case DataType::BIT:
970 : : {
971 : : sal_Bool b;
972 [ # # ]: 0 : switch (* ((const char *)pData))
973 : : {
974 : : case 'T':
975 : : case 'Y':
976 : 0 : case 'J': b = sal_True; break;
977 : 0 : default: b = sal_False; break;
978 : : }
979 [ # # ][ # # ]: 0 : *(_rRow->get())[i] = b;
[ # # ]
980 : : }
981 : 0 : break;
982 : : case DataType::LONGVARBINARY:
983 : : case DataType::BINARY:
984 : : case DataType::LONGVARCHAR:
985 : : {
986 : 19118 : const long nBlockNo = aStr.toInt32(); // read blocknumber
987 [ + - ][ + - ]: 19118 : if (nBlockNo > 0 && m_pMemoStream) // Read data from memo-file, only if
988 : : {
989 [ + - ][ - + ]: 19118 : if ( !ReadMemo(nBlockNo, (_rRow->get())[i]->get()) )
990 : 0 : break;
991 : : }
992 : : else
993 [ # # ]: 0 : (_rRow->get())[i]->setNull();
994 : 19118 : } break;
995 : : default:
996 : : OSL_FAIL("Falscher Type");
997 : : }
998 [ + - ]: 19466 : (_rRow->get())[i]->setTypeKind(nType);
999 : : }
1000 : :
1001 : 84376 : nByteOffset += nLen;
1002 : : OSL_ENSURE( nByteOffset <= m_nBufferSize ,"ByteOffset > m_nBufferSize!");
1003 : : }
1004 : 3124 : return sal_True;
1005 : : }
1006 : : //------------------------------------------------------------------
1007 : : // -------------------------------------------------------------------------
1008 : 28 : void ODbaseTable::FileClose()
1009 : : {
1010 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ODbaseTable::FileClose" );
1011 [ + - ]: 28 : ::osl::MutexGuard aGuard(m_aMutex);
1012 : : // if not everything has been written yet
1013 [ + + ][ + - ]: 28 : if (m_pMemoStream && m_pMemoStream->IsWritable())
[ + + ]
1014 [ + - ]: 12 : m_pMemoStream->Flush();
1015 : :
1016 [ + + ][ + - ]: 28 : delete m_pMemoStream;
1017 : 28 : m_pMemoStream = NULL;
1018 : :
1019 [ + - ][ + - ]: 28 : ODbaseTable_BASE::FileClose();
1020 : 28 : }
1021 : : // -------------------------------------------------------------------------
1022 : 0 : sal_Bool ODbaseTable::CreateImpl()
1023 : : {
1024 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ODbaseTable::CreateImpl" );
1025 : : OSL_ENSURE(!m_pFileStream, "SequenceError");
1026 : :
1027 [ # # ][ # # ]: 0 : if ( m_pConnection->isCheckEnabled() && ::dbtools::convertName2SQLName(m_Name,::rtl::OUString()) != m_Name )
[ # # ][ # # ]
[ # # ][ # #
# # # # ]
1028 : : {
1029 : 0 : const ::rtl::OUString sError( getConnection()->getResources().getResourceStringWithSubstitution(
1030 : : STR_SQL_NAME_ERROR,
1031 : : "$name$", m_Name
1032 [ # # ]: 0 : ) );
1033 [ # # ][ # # ]: 0 : ::dbtools::throwGenericSQLException( sError, *this );
1034 : : }
1035 : :
1036 [ # # ]: 0 : INetURLObject aURL;
1037 : 0 : aURL.SetSmartProtocol(INET_PROT_FILE);
1038 [ # # ]: 0 : String aName = getEntry(m_pConnection,m_Name);
1039 [ # # ]: 0 : if(!aName.Len())
1040 : : {
1041 [ # # ][ # # ]: 0 : ::rtl::OUString aIdent = m_pConnection->getContent()->getIdentifier()->getContentIdentifier();
[ # # ][ # # ]
[ # # ]
1042 [ # # ]: 0 : if ( aIdent.lastIndexOf('/') != (aIdent.getLength()-1) )
1043 : 0 : aIdent += ::rtl::OUString("/");
1044 : 0 : aIdent += m_Name;
1045 [ # # ]: 0 : aName = aIdent.getStr();
1046 : : }
1047 [ # # ][ # # ]: 0 : aURL.SetURL(aName);
1048 : :
1049 [ # # ][ # # ]: 0 : if ( !m_pConnection->matchesExtension( aURL.getExtension() ) )
[ # # ][ # # ]
[ # # ]
1050 [ # # ][ # # ]: 0 : aURL.setExtension(m_pConnection->getExtension());
1051 : :
1052 : : try
1053 : : {
1054 [ # # ][ # # ]: 0 : Content aContent(aURL.GetMainURL(INetURLObject::NO_DECODE),Reference<XCommandEnvironment>());
1055 [ # # ][ # # ]: 0 : if (aContent.isDocument())
1056 : : {
1057 : : // Only if the file exists with length > 0 raise an error
1058 [ # # ][ # # ]: 0 : SvStream* pFileStream = createStream_simpleError( aURL.GetMainURL(INetURLObject::NO_DECODE),STREAM_READ);
[ # # ][ # # ]
1059 : :
1060 [ # # ][ # # ]: 0 : if (pFileStream && pFileStream->Seek(STREAM_SEEK_TO_END))
[ # # ][ # # ]
1061 : : {
1062 : 0 : return sal_False;
1063 : : }
1064 [ # # ][ # # ]: 0 : delete pFileStream;
1065 [ # # ][ # # ]: 0 : }
[ # # ]
1066 : : }
1067 [ # # ]: 0 : catch(const Exception&) // an exception is thrown when no file exists
1068 : : {
1069 : : }
1070 : :
1071 : 0 : sal_Bool bMemoFile = sal_False;
1072 : :
1073 [ # # ]: 0 : sal_Bool bOk = CreateFile(aURL, bMemoFile);
1074 : :
1075 [ # # ]: 0 : FileClose();
1076 : :
1077 [ # # ]: 0 : if (!bOk)
1078 : : {
1079 : : try
1080 : : {
1081 [ # # ][ # # ]: 0 : Content aContent(aURL.GetMainURL(INetURLObject::NO_DECODE),Reference<XCommandEnvironment>());
1082 [ # # ][ # # ]: 0 : aContent.executeCommand( rtl::OUString("delete"),bool2any( sal_True ) );
[ # # ][ # # ]
1083 : : }
1084 [ # # ]: 0 : catch(const Exception&) // an exception is thrown when no file exists
1085 : : {
1086 : : }
1087 : 0 : return sal_False;
1088 : : }
1089 : :
1090 [ # # ]: 0 : if (bMemoFile)
1091 : : {
1092 [ # # ][ # # ]: 0 : String aExt = aURL.getExtension();
1093 [ # # ]: 0 : aURL.setExtension(rtl::OUString("dbt")); // extension for memo file
1094 [ # # ][ # # ]: 0 : Content aMemo1Content(aURL.GetMainURL(INetURLObject::NO_DECODE),Reference<XCommandEnvironment>());
[ # # ]
1095 : :
1096 : 0 : sal_Bool bMemoAlreadyExists = sal_False;
1097 : : try
1098 : : {
1099 [ # # ]: 0 : bMemoAlreadyExists = aMemo1Content.isDocument();
1100 : : }
1101 [ # # ]: 0 : catch(const Exception&) // an exception is thrown when no file exists
1102 : : {
1103 : : }
1104 [ # # ]: 0 : if (bMemoAlreadyExists)
1105 : : {
1106 [ # # ][ # # ]: 0 : aURL.setExtension(aExt); // kill dbf file
1107 : : try
1108 : : {
1109 [ # # ][ # # ]: 0 : Content aMemoContent(aURL.GetMainURL(INetURLObject::NO_DECODE),Reference<XCommandEnvironment>());
1110 [ # # ][ # # ]: 0 : aMemoContent.executeCommand( rtl::OUString("delete"),bool2any( sal_True ) );
[ # # ]
1111 : : }
1112 [ # # # # ]: 0 : catch(const Exception&)
1113 : : {
1114 : :
1115 : 0 : const ::rtl::OUString sError( getConnection()->getResources().getResourceStringWithSubstitution(
1116 : : STR_COULD_NOT_DELETE_FILE,
1117 : : "$name$", aName
1118 [ # # # # ]: 0 : ) );
1119 [ # # # # ]: 0 : ::dbtools::throwGenericSQLException( sError, *this );
1120 : : }
1121 : : }
1122 [ # # ][ # # ]: 0 : if (!CreateMemoFile(aURL))
1123 : : {
1124 [ # # ][ # # ]: 0 : aURL.setExtension(aExt); // kill dbf file
1125 [ # # ][ # # ]: 0 : Content aMemoContent(aURL.GetMainURL(INetURLObject::NO_DECODE),Reference<XCommandEnvironment>());
1126 [ # # ][ # # ]: 0 : aMemoContent.executeCommand( rtl::OUString("delete"),bool2any( sal_True ) );
1127 [ # # ]: 0 : return sal_False;
1128 : : }
1129 [ # # ][ # # ]: 0 : m_aHeader.db_typ = dBaseIIIMemo;
[ # # ][ # # ]
1130 : : }
1131 : : else
1132 : 0 : m_aHeader.db_typ = dBaseIII;
1133 : :
1134 [ # # ][ # # ]: 0 : return sal_True;
1135 : : }
1136 : : // -----------------------------------------------------------------------------
1137 : 0 : void ODbaseTable::throwInvalidColumnType(const sal_uInt16 _nErrorId,const ::rtl::OUString& _sColumnName)
1138 : : {
1139 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ODbaseTable::throwInvalidColumnType" );
1140 : : try
1141 : : {
1142 : : // we have to drop the file because it is corrupted now
1143 [ # # ]: 0 : DropImpl();
1144 : : }
1145 [ # # ]: 0 : catch(const Exception&)
1146 : : {
1147 : : }
1148 : :
1149 : 0 : const ::rtl::OUString sError( getConnection()->getResources().getResourceStringWithSubstitution(
1150 : : _nErrorId,
1151 : : "$columnname$", _sColumnName
1152 [ # # ]: 0 : ) );
1153 [ # # ][ # # ]: 0 : ::dbtools::throwGenericSQLException( sError, *this );
1154 [ # # ]: 0 : }
1155 : : //------------------------------------------------------------------
1156 : : // creates in principle dBase IV file format
1157 : 0 : sal_Bool ODbaseTable::CreateFile(const INetURLObject& aFile, sal_Bool& bCreateMemo)
1158 : : {
1159 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ODbaseTable::CreateFile" );
1160 : 0 : bCreateMemo = sal_False;
1161 [ # # ]: 0 : Date aDate( Date::SYSTEM ); // current date
1162 : :
1163 [ # # ][ # # ]: 0 : m_pFileStream = createStream_simpleError( aFile.GetMainURL(INetURLObject::NO_DECODE),STREAM_READWRITE | STREAM_SHARE_DENYWRITE | STREAM_TRUNC );
[ # # ][ # # ]
1164 : :
1165 [ # # ]: 0 : if (!m_pFileStream)
1166 : 0 : return sal_False;
1167 : :
1168 : 0 : sal_uInt8 nDbaseType = dBaseIII;
1169 [ # # ][ # # ]: 0 : Reference<XIndexAccess> xColumns(getColumns(),UNO_QUERY);
1170 : 0 : Reference<XPropertySet> xCol;
1171 [ # # ][ # # ]: 0 : const ::rtl::OUString sPropType = OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TYPE);
1172 : :
1173 : : try
1174 : : {
1175 [ # # ][ # # ]: 0 : const sal_Int32 nCount = xColumns->getCount();
1176 [ # # ]: 0 : for(sal_Int32 i=0;i<nCount;++i)
1177 : : {
1178 [ # # ][ # # ]: 0 : xColumns->getByIndex(i) >>= xCol;
[ # # ]
1179 : : OSL_ENSURE(xCol.is(),"This should be a column!");
1180 : :
1181 [ # # ][ # # ]: 0 : switch (getINT32(xCol->getPropertyValue(sPropType)))
[ # # # # ]
[ # # ]
1182 : : {
1183 : : case DataType::DOUBLE:
1184 : : case DataType::INTEGER:
1185 : : case DataType::TIMESTAMP:
1186 : : case DataType::LONGVARBINARY:
1187 : 0 : nDbaseType = VisualFoxPro;
1188 : 0 : i = nCount; // no more columns need to be checked
1189 : 0 : break;
1190 : : } // switch (getINT32(xCol->getPropertyValue(sPropType)))
1191 : : }
1192 : : }
1193 [ # # ]: 0 : catch ( const Exception& e )
1194 : : {
1195 : : (void)e;
1196 : :
1197 : : try
1198 : : {
1199 : : // we have to drop the file because it is corrupted now
1200 [ # # ]: 0 : DropImpl();
1201 : : }
1202 [ # # ]: 0 : catch(const Exception&) { }
1203 : 0 : throw;
1204 : : }
1205 : :
1206 : : char aBuffer[21]; // write buffer
1207 : 0 : memset(aBuffer,0,sizeof(aBuffer));
1208 : :
1209 [ # # ]: 0 : m_pFileStream->Seek(0L);
1210 [ # # ]: 0 : (*m_pFileStream) << (sal_uInt8) nDbaseType; // dBase format
1211 [ # # ]: 0 : (*m_pFileStream) << (sal_uInt8) (aDate.GetYear() % 100); // current date
1212 : :
1213 : :
1214 [ # # ]: 0 : (*m_pFileStream) << (sal_uInt8) aDate.GetMonth();
1215 [ # # ]: 0 : (*m_pFileStream) << (sal_uInt8) aDate.GetDay();
1216 [ # # ]: 0 : (*m_pFileStream) << (sal_uInt32)0; // number of data records
1217 [ # # ][ # # ]: 0 : (*m_pFileStream) << (sal_uInt16)((m_pColumns->getCount()+1) * 32 + 1); // header information,
1218 : : // pColumns contains always an additional column
1219 [ # # ]: 0 : (*m_pFileStream) << (sal_uInt16) 0; // record length will be determined later
1220 [ # # ]: 0 : m_pFileStream->Write(aBuffer, 20);
1221 : :
1222 : 0 : sal_uInt16 nRecLength = 1; // Length 1 for deleted flag
1223 [ # # ][ # # ]: 0 : sal_Int32 nMaxFieldLength = m_pConnection->getMetaData()->getMaxColumnNameLength();
[ # # ]
1224 : 0 : ::rtl::OUString aName;
1225 [ # # ][ # # ]: 0 : const ::rtl::OUString sPropName = OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_NAME);
1226 [ # # ][ # # ]: 0 : const ::rtl::OUString sPropPrec = OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_PRECISION);
1227 [ # # ][ # # ]: 0 : const ::rtl::OUString sPropScale = OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_SCALE);
1228 : :
1229 : : try
1230 : : {
1231 [ # # ][ # # ]: 0 : const sal_Int32 nCount = xColumns->getCount();
1232 [ # # ]: 0 : for(sal_Int32 i=0;i<nCount;++i)
1233 : : {
1234 [ # # ][ # # ]: 0 : xColumns->getByIndex(i) >>= xCol;
[ # # ]
1235 : : OSL_ENSURE(xCol.is(),"This should be a column!");
1236 : :
1237 : 0 : char cTyp( 'C' );
1238 : :
1239 [ # # ][ # # ]: 0 : xCol->getPropertyValue(sPropName) >>= aName;
1240 : :
1241 : 0 : ::rtl::OString aCol;
1242 [ # # ][ # # ]: 0 : if ( DBTypeConversion::convertUnicodeString( aName, aCol, m_eEncoding ) > nMaxFieldLength)
1243 : : {
1244 [ # # ]: 0 : throwInvalidColumnType( STR_INVALID_COLUMN_NAME_LENGTH, aName );
1245 : : }
1246 : :
1247 [ # # ]: 0 : (*m_pFileStream) << aCol.getStr();
1248 [ # # ]: 0 : m_pFileStream->Write(aBuffer, 11 - aCol.getLength());
1249 : :
1250 : 0 : sal_Int32 nPrecision = 0;
1251 [ # # ][ # # ]: 0 : xCol->getPropertyValue(sPropPrec) >>= nPrecision;
1252 : 0 : sal_Int32 nScale = 0;
1253 [ # # ][ # # ]: 0 : xCol->getPropertyValue(sPropScale) >>= nScale;
1254 : :
1255 : 0 : bool bBinary = false;
1256 : :
1257 [ # # ][ # # ]: 0 : switch (getINT32(xCol->getPropertyValue(sPropType)))
[ # # # #
# # # # #
# ][ # # ]
1258 : : {
1259 : : case DataType::CHAR:
1260 : : case DataType::VARCHAR:
1261 : 0 : cTyp = 'C';
1262 : 0 : break;
1263 : : case DataType::DOUBLE:
1264 [ # # ][ # # ]: 0 : if (getBOOL(xCol->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_ISCURRENCY)))) // Currency will be treated separately
[ # # ][ # # ]
[ # # ][ # # ]
1265 : 0 : cTyp = 'Y';
1266 : : else
1267 : 0 : cTyp = 'B';
1268 : 0 : break;
1269 : : case DataType::INTEGER:
1270 : 0 : cTyp = 'I';
1271 : 0 : break;
1272 : : case DataType::TINYINT:
1273 : : case DataType::SMALLINT:
1274 : : case DataType::BIGINT:
1275 : : case DataType::DECIMAL:
1276 : : case DataType::NUMERIC:
1277 : : case DataType::REAL:
1278 : 0 : cTyp = 'N'; // only dBase 3 format
1279 : 0 : break;
1280 : : case DataType::TIMESTAMP:
1281 : 0 : cTyp = 'T';
1282 : 0 : break;
1283 : : case DataType::DATE:
1284 : 0 : cTyp = 'D';
1285 : 0 : break;
1286 : : case DataType::BIT:
1287 : 0 : cTyp = 'L';
1288 : 0 : break;
1289 : : case DataType::LONGVARBINARY:
1290 : 0 : bBinary = true;
1291 : : // run through
1292 : : case DataType::LONGVARCHAR:
1293 : 0 : cTyp = 'M';
1294 : 0 : break;
1295 : : default:
1296 : : {
1297 [ # # ]: 0 : throwInvalidColumnType(STR_INVALID_COLUMN_TYPE, aName);
1298 : : }
1299 : : }
1300 : :
1301 [ # # ]: 0 : (*m_pFileStream) << cTyp;
1302 [ # # ]: 0 : if ( nDbaseType == VisualFoxPro )
1303 [ # # ]: 0 : (*m_pFileStream) << sal_uInt32(nRecLength-1);
1304 : : else
1305 [ # # ]: 0 : m_pFileStream->Write(aBuffer, 4);
1306 : :
1307 [ # # # # : 0 : switch(cTyp)
# # # ]
1308 : : {
1309 : : case 'C':
1310 : : OSL_ENSURE(nPrecision < 255, "ODbaseTable::Create: Column zu lang!");
1311 [ # # ]: 0 : if (nPrecision > 254)
1312 : : {
1313 [ # # ]: 0 : throwInvalidColumnType(STR_INVALID_COLUMN_PRECISION, aName);
1314 : : }
1315 [ # # ]: 0 : (*m_pFileStream) << (sal_uInt8) Min((unsigned)nPrecision, 255U); // field length
1316 [ # # ]: 0 : nRecLength = nRecLength + (sal_uInt16)::std::min((sal_uInt16)nPrecision, (sal_uInt16)255UL);
1317 [ # # ]: 0 : (*m_pFileStream) << (sal_uInt8)0; // decimals
1318 : 0 : break;
1319 : : case 'F':
1320 : : case 'N':
1321 : : OSL_ENSURE(nPrecision >= nScale,
1322 : : "ODbaseTable::Create: Feldlaenge muss groesser Nachkommastellen sein!");
1323 [ # # ]: 0 : if (nPrecision < nScale)
1324 : : {
1325 [ # # ]: 0 : throwInvalidColumnType(STR_INVALID_PRECISION_SCALE, aName);
1326 : : }
1327 [ # # ][ # # ]: 0 : if (getBOOL(xCol->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_ISCURRENCY)))) // Currency will be treated separately
[ # # ][ # # ]
[ # # ][ # # ]
1328 : : {
1329 [ # # ]: 0 : (*m_pFileStream) << (sal_uInt8)10; // standard length
1330 [ # # ]: 0 : (*m_pFileStream) << (sal_uInt8)4;
1331 : 0 : nRecLength += 10;
1332 : : }
1333 : : else
1334 : : {
1335 [ # # ]: 0 : sal_Int32 nPrec = SvDbaseConverter::ConvertPrecisionToDbase(nPrecision,nScale);
1336 : :
1337 [ # # ]: 0 : (*m_pFileStream) << (sal_uInt8)( nPrec);
1338 [ # # ]: 0 : (*m_pFileStream) << (sal_uInt8)nScale;
1339 : 0 : nRecLength += (sal_uInt16)nPrec;
1340 : : }
1341 : 0 : break;
1342 : : case 'L':
1343 [ # # ]: 0 : (*m_pFileStream) << (sal_uInt8)1;
1344 [ # # ]: 0 : (*m_pFileStream) << (sal_uInt8)0;
1345 : 0 : ++nRecLength;
1346 : 0 : break;
1347 : : case 'I':
1348 [ # # ]: 0 : (*m_pFileStream) << (sal_uInt8)4;
1349 [ # # ]: 0 : (*m_pFileStream) << (sal_uInt8)0;
1350 : 0 : nRecLength += 4;
1351 : 0 : break;
1352 : : case 'Y':
1353 : : case 'B':
1354 : : case 'T':
1355 : : case 'D':
1356 [ # # ]: 0 : (*m_pFileStream) << (sal_uInt8)8;
1357 [ # # ]: 0 : (*m_pFileStream) << (sal_uInt8)0;
1358 : 0 : nRecLength += 8;
1359 : 0 : break;
1360 : : case 'M':
1361 : 0 : bCreateMemo = sal_True;
1362 [ # # ]: 0 : (*m_pFileStream) << (sal_uInt8)10;
1363 [ # # ]: 0 : (*m_pFileStream) << (sal_uInt8)0;
1364 : 0 : nRecLength += 10;
1365 [ # # ]: 0 : if ( bBinary )
1366 : 0 : aBuffer[0] = 0x06;
1367 : 0 : break;
1368 : : default:
1369 [ # # ]: 0 : throwInvalidColumnType(STR_INVALID_COLUMN_TYPE, aName);
1370 : : }
1371 [ # # ]: 0 : m_pFileStream->Write(aBuffer, 14);
1372 : 0 : aBuffer[0] = 0x00;
1373 [ # # ]: 0 : }
1374 : :
1375 [ # # ]: 0 : (*m_pFileStream) << (sal_uInt8)FIELD_DESCRIPTOR_TERMINATOR; // end of header
1376 [ # # ]: 0 : (*m_pFileStream) << (char)DBF_EOL;
1377 [ # # ]: 0 : m_pFileStream->Seek(10L);
1378 [ # # ]: 0 : (*m_pFileStream) << nRecLength; // set record length afterwards
1379 : :
1380 [ # # ]: 0 : if (bCreateMemo)
1381 : : {
1382 [ # # ]: 0 : m_pFileStream->Seek(0L);
1383 [ # # ]: 0 : if (nDbaseType == VisualFoxPro)
1384 [ # # ]: 0 : (*m_pFileStream) << (sal_uInt8) FoxProMemo;
1385 : : else
1386 [ # # ]: 0 : (*m_pFileStream) << (sal_uInt8) dBaseIIIMemo;
1387 : : } // if (bCreateMemo)
1388 : : }
1389 [ # # ]: 0 : catch ( const Exception& e )
1390 : : {
1391 : : (void)e;
1392 : :
1393 : : try
1394 : : {
1395 : : // we have to drop the file because it is corrupted now
1396 [ # # ]: 0 : DropImpl();
1397 : : }
1398 [ # # ]: 0 : catch(const Exception&) { }
1399 : 0 : throw;
1400 : : }
1401 : 0 : return sal_True;
1402 : : }
1403 : :
1404 : : //------------------------------------------------------------------
1405 : : // creates in principle dBase III file format
1406 : 0 : sal_Bool ODbaseTable::CreateMemoFile(const INetURLObject& aFile)
1407 : : {
1408 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ODbaseTable::CreateMemoFile" );
1409 : : // filehandling macro for table creation
1410 [ # # ][ # # ]: 0 : m_pMemoStream = createStream_simpleError( aFile.GetMainURL(INetURLObject::NO_DECODE),STREAM_READWRITE | STREAM_SHARE_DENYWRITE);
[ # # ]
1411 : :
1412 [ # # ]: 0 : if (!m_pMemoStream)
1413 : 0 : return sal_False;
1414 : :
1415 : 0 : m_pMemoStream->SetStreamSize(512);
1416 : :
1417 : 0 : m_pMemoStream->Seek(0L);
1418 : 0 : (*m_pMemoStream) << sal_uInt32(1); // pointer to the first free block
1419 : :
1420 : 0 : m_pMemoStream->Flush();
1421 [ # # ]: 0 : delete m_pMemoStream;
1422 : 0 : m_pMemoStream = NULL;
1423 : 0 : return sal_True;
1424 : : }
1425 : : //------------------------------------------------------------------
1426 : 0 : sal_Bool ODbaseTable::Drop_Static(const ::rtl::OUString& _sUrl,sal_Bool _bHasMemoFields,OCollection* _pIndexes )
1427 : : {
1428 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ODbaseTable::Drop_Static" );
1429 [ # # ]: 0 : INetURLObject aURL;
1430 [ # # ]: 0 : aURL.SetURL(_sUrl);
1431 : :
1432 [ # # ][ # # ]: 0 : sal_Bool bDropped = ::utl::UCBContentHelper::Kill(aURL.GetMainURL(INetURLObject::NO_DECODE));
1433 : :
1434 [ # # ]: 0 : if(bDropped)
1435 : : {
1436 [ # # ]: 0 : if (_bHasMemoFields)
1437 : : { // delete the memo fields
1438 [ # # ]: 0 : aURL.setExtension(rtl::OUString("dbt"));
1439 [ # # ][ # # ]: 0 : bDropped = ::utl::UCBContentHelper::Kill(aURL.GetMainURL(INetURLObject::NO_DECODE));
[ # # ]
1440 : : }
1441 : :
1442 [ # # ]: 0 : if(bDropped)
1443 : : {
1444 [ # # ]: 0 : if(_pIndexes)
1445 : : {
1446 : : try
1447 : : {
1448 [ # # ]: 0 : sal_Int32 i = _pIndexes->getCount();
1449 [ # # ]: 0 : while (i)
1450 : : {
1451 [ # # ]: 0 : _pIndexes->dropByIndex(--i);
1452 : : }
1453 : : }
1454 [ # # ]: 0 : catch(const SQLException&)
1455 : : {
1456 : : }
1457 : : }
1458 [ # # ]: 0 : aURL.setExtension(rtl::OUString("inf"));
1459 : :
1460 : : // as the inf file does not necessarily exist, we aren't allowed to use UCBContentHelper::Kill
1461 : : try
1462 : : {
1463 [ # # ][ # # ]: 0 : ::ucbhelper::Content aDeleteContent( aURL.GetMainURL( INetURLObject::NO_DECODE ), Reference< XCommandEnvironment > () );
1464 [ # # ][ # # ]: 0 : aDeleteContent.executeCommand( ::rtl::OUString("delete"), makeAny( sal_Bool( sal_True ) ) );
[ # # ][ # # ]
1465 : : }
1466 [ # # ]: 0 : catch(const Exception&)
1467 : : {
1468 : : // silently ignore this ....
1469 : : }
1470 : : }
1471 : : }
1472 [ # # ]: 0 : return bDropped;
1473 : : }
1474 : : // -----------------------------------------------------------------------------
1475 : 0 : sal_Bool ODbaseTable::DropImpl()
1476 : : {
1477 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ODbaseTable::DropImpl" );
1478 : 0 : FileClose();
1479 : :
1480 [ # # ]: 0 : if(!m_pIndexes)
1481 : 0 : refreshIndexes(); // look for indexes which must be deleted as well
1482 : :
1483 [ # # ][ # # ]: 0 : sal_Bool bDropped = Drop_Static(getEntry(m_pConnection,m_Name),HasMemoFields(),m_pIndexes);
1484 [ # # ]: 0 : if(!bDropped)
1485 : : {// we couldn't drop the table so we have to reopen it
1486 : 0 : construct();
1487 [ # # ]: 0 : if(m_pColumns)
1488 : 0 : m_pColumns->refresh();
1489 : : }
1490 : 0 : return bDropped;
1491 : : }
1492 : :
1493 : : //------------------------------------------------------------------
1494 : 2 : sal_Bool ODbaseTable::InsertRow(OValueRefVector& rRow, sal_Bool bFlush,const Reference<XIndexAccess>& _xCols)
1495 : : {
1496 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ODbaseTable::InsertRow" );
1497 : : // fill buffer with blanks
1498 : 2 : AllocBuffer();
1499 : 2 : memset(m_pBuffer, 0, m_aHeader.db_slng);
1500 : 2 : m_pBuffer[0] = ' ';
1501 : :
1502 : : // Copy new row completely:
1503 : : // ... and add at the end as new Record:
1504 : 2 : sal_uInt32 nTempPos = m_nFilePos;
1505 : :
1506 : 2 : m_nFilePos = (sal_uIntPtr)m_aHeader.db_anz + 1;
1507 [ + - ]: 2 : sal_Bool bInsertRow = UpdateBuffer( rRow, NULL, _xCols );
1508 [ + - ]: 2 : if ( bInsertRow )
1509 : : {
1510 : 2 : sal_uInt32 nFileSize = 0, nMemoFileSize = 0;
1511 : :
1512 : 2 : nFileSize = lcl_getFileSize(*m_pFileStream);
1513 : :
1514 [ + - ][ + - ]: 2 : if (HasMemoFields() && m_pMemoStream)
[ + - ]
1515 : : {
1516 : 2 : m_pMemoStream->Seek(STREAM_SEEK_TO_END);
1517 : 2 : nMemoFileSize = m_pMemoStream->Tell();
1518 : : }
1519 : :
1520 [ - + ]: 2 : if (!WriteBuffer())
1521 : : {
1522 : 0 : m_pFileStream->SetStreamSize(nFileSize); // restore old size
1523 : :
1524 [ # # ][ # # ]: 0 : if (HasMemoFields() && m_pMemoStream)
[ # # ]
1525 : 0 : m_pMemoStream->SetStreamSize(nMemoFileSize); // restore old size
1526 : 0 : m_nFilePos = nTempPos; // restore file position
1527 : : }
1528 : : else
1529 : : {
1530 : 2 : (*m_pFileStream) << (char)DBF_EOL; // write EOL
1531 : : // raise number of datasets in the header:
1532 : 2 : m_pFileStream->Seek( 4L );
1533 : 2 : (*m_pFileStream) << (m_aHeader.db_anz + 1);
1534 : :
1535 : : // if AppendOnly no flush!
1536 [ + - ]: 2 : if (bFlush)
1537 : 2 : m_pFileStream->Flush();
1538 : :
1539 : : // raise number if successfully
1540 : 2 : m_aHeader.db_anz++;
1541 [ + - ]: 2 : *rRow.get()[0] = m_nFilePos; // set bookmark
1542 : 2 : m_nFilePos = nTempPos;
1543 : : }
1544 : : }
1545 : : else
1546 : 0 : m_nFilePos = nTempPos;
1547 : :
1548 : 2 : return bInsertRow;
1549 : : }
1550 : :
1551 : : //------------------------------------------------------------------
1552 : 8 : sal_Bool ODbaseTable::UpdateRow(OValueRefVector& rRow, OValueRefRow& pOrgRow,const Reference<XIndexAccess>& _xCols)
1553 : : {
1554 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ODbaseTable::UpdateRow" );
1555 : : // fill buffer with blanks
1556 : 8 : AllocBuffer();
1557 : :
1558 : : // position on desired record:
1559 : 8 : long nPos = m_aHeader.db_kopf + (long)(m_nFilePos-1) * m_aHeader.db_slng;
1560 : 8 : m_pFileStream->Seek(nPos);
1561 : 8 : m_pFileStream->Read((char*)m_pBuffer, m_aHeader.db_slng);
1562 : :
1563 : 8 : sal_uInt32 nMemoFileSize( 0 );
1564 [ - + ][ - + ]: 8 : if (HasMemoFields() && m_pMemoStream)
[ + - ]
1565 : : {
1566 : 0 : m_pMemoStream->Seek(STREAM_SEEK_TO_END);
1567 : 0 : nMemoFileSize = m_pMemoStream->Tell();
1568 : : }
1569 [ + - ][ + - ]: 8 : if (!UpdateBuffer(rRow, pOrgRow,_xCols) || !WriteBuffer())
[ + - ][ + - ]
[ - + ][ + - ]
[ - + # # ]
1570 : : {
1571 [ # # ][ # # ]: 0 : if (HasMemoFields() && m_pMemoStream)
[ # # ]
1572 : 0 : m_pMemoStream->SetStreamSize(nMemoFileSize); // restore old size
1573 : : }
1574 : : else
1575 : : {
1576 : 8 : m_pFileStream->Flush();
1577 : : }
1578 : 8 : return sal_True;
1579 : : }
1580 : :
1581 : : //------------------------------------------------------------------
1582 : 2 : sal_Bool ODbaseTable::DeleteRow(const OSQLColumns& _rCols)
1583 : : {
1584 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ODbaseTable::DeleteRow" );
1585 : : // Set the Delete-Flag (be it set or not):
1586 : : // Position on desired record:
1587 : 2 : long nFilePos = m_aHeader.db_kopf + (long)(m_nFilePos-1) * m_aHeader.db_slng;
1588 [ + - ]: 2 : m_pFileStream->Seek(nFilePos);
1589 : :
1590 [ + - ][ + - ]: 2 : OValueRefRow aRow = new OValueRefVector(_rCols.get().size());
1591 : :
1592 [ + - ][ - + ]: 2 : if (!fetchRow(aRow,_rCols,sal_True,sal_True))
1593 : 0 : return sal_False;
1594 : :
1595 : 2 : Reference<XPropertySet> xCol;
1596 : 2 : ::rtl::OUString aColName;
1597 : 2 : ::comphelper::UStringMixEqual aCase(isCaseSensitive());
1598 [ + - ][ + + ]: 64 : for (sal_uInt16 i = 0; i < m_pColumns->getCount(); i++)
1599 : : {
1600 [ + - ]: 62 : Reference<XPropertySet> xIndex = isUniqueByColumnName(i);
1601 [ - + ]: 62 : if (xIndex.is())
1602 : : {
1603 [ # # ][ # # ]: 0 : ::cppu::extractInterface(xCol,m_pColumns->getByIndex(i));
1604 : : OSL_ENSURE(xCol.is(),"ODbaseTable::DeleteRow column is null!");
1605 [ # # ]: 0 : if(xCol.is())
1606 : : {
1607 [ # # ][ # # ]: 0 : xCol->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_NAME)) >>= aColName;
[ # # ][ # # ]
1608 : :
1609 [ # # ]: 0 : Reference<XUnoTunnel> xTunnel(xIndex,UNO_QUERY);
1610 : : OSL_ENSURE(xTunnel.is(),"No TunnelImplementation!");
1611 [ # # ][ # # ]: 0 : ODbaseIndex* pIndex = reinterpret_cast< ODbaseIndex* >( xTunnel->getSomething(ODbaseIndex::getUnoTunnelImplementationId()) );
[ # # ][ # # ]
1612 : : OSL_ENSURE(pIndex,"ODbaseTable::DeleteRow: No Index returned!");
1613 : :
1614 : 0 : OSQLColumns::Vector::const_iterator aIter = _rCols.get().begin();
1615 : 0 : sal_Int32 nPos = 1;
1616 [ # # ][ # # ]: 0 : for(;aIter != _rCols.get().end();++aIter,++nPos)
1617 : : {
1618 [ # # ][ # # ]: 0 : if(aCase(getString((*aIter)->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_REALNAME))),aColName))
[ # # ][ # # ]
[ # # ][ # # ]
1619 : 0 : break;
1620 : : }
1621 [ # # ][ # # ]: 0 : if (aIter == _rCols.get().end())
1622 : 0 : continue;
1623 : :
1624 [ # # ][ # # ]: 62 : pIndex->Delete(m_nFilePos,*(aRow->get())[nPos]);
1625 : : }
1626 : : }
1627 [ + - ]: 62 : }
1628 : :
1629 [ + - ]: 2 : m_pFileStream->Seek(nFilePos);
1630 [ + - ]: 2 : (*m_pFileStream) << (sal_uInt8)'*'; // mark the row in the table as deleted
1631 [ + - ]: 2 : m_pFileStream->Flush();
1632 [ + - ]: 2 : return sal_True;
1633 : : }
1634 : : // -------------------------------------------------------------------------
1635 : 212 : Reference<XPropertySet> ODbaseTable::isUniqueByColumnName(sal_Int32 _nColumnPos)
1636 : : {
1637 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ODbaseTable::isUniqueByColumnName" );
1638 [ - + ]: 212 : if(!m_pIndexes)
1639 : 0 : refreshIndexes();
1640 [ - + ]: 212 : if(m_pIndexes->hasElements())
1641 : : {
1642 : 0 : Reference<XPropertySet> xCol;
1643 [ # # ][ # # ]: 0 : m_pColumns->getByIndex(_nColumnPos) >>= xCol;
1644 : : OSL_ENSURE(xCol.is(),"ODbaseTable::isUniqueByColumnName column is null!");
1645 : 0 : ::rtl::OUString sColName;
1646 [ # # ][ # # ]: 0 : xCol->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_NAME)) >>= sColName;
[ # # ][ # # ]
1647 : :
1648 : 0 : Reference<XPropertySet> xIndex;
1649 [ # # ][ # # ]: 0 : for(sal_Int32 i=0;i<m_pIndexes->getCount();++i)
1650 : : {
1651 [ # # ][ # # ]: 0 : ::cppu::extractInterface(xIndex,m_pIndexes->getByIndex(i));
1652 [ # # ][ # # ]: 0 : if(xIndex.is() && getBOOL(xIndex->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_ISUNIQUE))))
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # # #
# # ][ # # ]
1653 : : {
1654 [ # # ][ # # ]: 0 : Reference<XNameAccess> xCols(Reference<XColumnsSupplier>(xIndex,UNO_QUERY)->getColumns());
[ # # ]
1655 [ # # ][ # # ]: 0 : if(xCols->hasByName(sColName))
[ # # ]
1656 [ # # ]: 0 : return xIndex;
1657 : :
1658 : : }
1659 [ # # ][ # # ]: 0 : }
[ # # ]
1660 : : }
1661 : 212 : return Reference<XPropertySet>();
1662 : : }
1663 : : //------------------------------------------------------------------
1664 : 0 : static double toDouble(const rtl::OString& rString)
1665 : : {
1666 : 0 : return ::rtl::math::stringToDouble( rString, '.', ',', NULL, NULL );
1667 : : }
1668 : :
1669 : : //------------------------------------------------------------------
1670 : 10 : sal_Bool ODbaseTable::UpdateBuffer(OValueRefVector& rRow, OValueRefRow pOrgRow,const Reference<XIndexAccess>& _xCols)
1671 : : {
1672 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ODbaseTable::UpdateBuffer" );
1673 : : OSL_ENSURE(m_pBuffer,"Buffer is NULL!");
1674 [ - + ]: 10 : if ( !m_pBuffer )
1675 : 0 : return sal_False;
1676 : 10 : sal_Int32 nByteOffset = 1;
1677 : :
1678 : : // Update fields:
1679 : 10 : Reference<XPropertySet> xCol;
1680 : 10 : Reference<XPropertySet> xIndex;
1681 : : sal_uInt16 i;
1682 : 10 : ::rtl::OUString aColName;
1683 [ + - ]: 10 : const sal_Int32 nColumnCount = m_pColumns->getCount();
1684 [ + - ]: 10 : ::std::vector< Reference<XPropertySet> > aIndexedCols(nColumnCount);
1685 : :
1686 : 10 : ::comphelper::UStringMixEqual aCase(isCaseSensitive());
1687 : :
1688 [ + - ][ + - ]: 10 : Reference<XIndexAccess> xColumns = m_pColumns;
1689 : : // first search a key that exist already in the table
1690 [ + + ]: 160 : for (i = 0; i < nColumnCount; ++i)
1691 : : {
1692 : 150 : sal_Int32 nPos = i;
1693 [ + - ][ - + ]: 150 : if(_xCols != xColumns)
1694 : : {
1695 [ # # ][ # # ]: 0 : m_pColumns->getByIndex(i) >>= xCol;
1696 : : OSL_ENSURE(xCol.is(),"ODbaseTable::UpdateBuffer column is null!");
1697 [ # # ][ # # ]: 0 : xCol->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_NAME)) >>= aColName;
[ # # ][ # # ]
1698 : :
1699 [ # # ][ # # ]: 0 : for(nPos = 0;nPos<_xCols->getCount();++nPos)
[ # # ]
1700 : : {
1701 : 0 : Reference<XPropertySet> xFindCol;
1702 [ # # ][ # # ]: 0 : ::cppu::extractInterface(xFindCol,_xCols->getByIndex(nPos));
[ # # ]
1703 : : OSL_ENSURE(xFindCol.is(),"ODbaseTable::UpdateBuffer column is null!");
1704 [ # # ][ # # ]: 0 : if(aCase(getString(xFindCol->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_NAME))),aColName))
[ # # ][ # # ]
[ # # ][ # # ]
1705 : : break;
1706 [ # # ]: 0 : }
1707 [ # # ][ # # ]: 0 : if (nPos >= _xCols->getCount())
[ # # ]
1708 : 0 : continue;
1709 : : }
1710 : :
1711 : 150 : ++nPos;
1712 [ + - ][ + - ]: 150 : xIndex = isUniqueByColumnName(i);
1713 [ + - ]: 150 : aIndexedCols[i] = xIndex;
1714 [ - + ]: 150 : if (xIndex.is())
1715 : : {
1716 : : // first check if the value is different to the old one and when if it conform to the index
1717 [ # # ][ # # ]: 0 : if(pOrgRow.is() && (rRow.get()[nPos]->getValue().isNull() || rRow.get()[nPos] == (pOrgRow->get())[nPos]))
[ # # ][ # # ]
1718 : 0 : continue;
1719 : : else
1720 : : {
1721 [ # # ]: 0 : Reference<XUnoTunnel> xTunnel(xIndex,UNO_QUERY);
1722 : : OSL_ENSURE(xTunnel.is(),"No TunnelImplementation!");
1723 [ # # ][ # # ]: 0 : ODbaseIndex* pIndex = reinterpret_cast< ODbaseIndex* >( xTunnel->getSomething(ODbaseIndex::getUnoTunnelImplementationId()) );
[ # # ][ # # ]
1724 : : OSL_ENSURE(pIndex,"ODbaseTable::UpdateBuffer: No Index returned!");
1725 : :
1726 [ # # ][ # # ]: 0 : if (pIndex->Find(0,*rRow.get()[nPos]))
1727 : : {
1728 : : // There is no unique value
1729 [ # # ]: 0 : if ( aColName.isEmpty() )
1730 : : {
1731 [ # # ][ # # ]: 0 : m_pColumns->getByIndex(i) >>= xCol;
1732 : : OSL_ENSURE(xCol.is(),"ODbaseTable::UpdateBuffer column is null!");
1733 [ # # ][ # # ]: 0 : xCol->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_NAME)) >>= aColName;
[ # # ][ # # ]
1734 : 0 : xCol.clear();
1735 : : } // if ( !aColName.getLength() )
1736 : 0 : const ::rtl::OUString sError( getConnection()->getResources().getResourceStringWithSubstitution(
1737 : : STR_DUPLICATE_VALUE_IN_COLUMN
1738 : : ,"$columnname$", aColName
1739 [ # # ]: 0 : ) );
1740 [ # # ][ # # ]: 0 : ::dbtools::throwGenericSQLException( sError, *this );
1741 : 0 : }
1742 : : }
1743 : : }
1744 : : }
1745 : :
1746 : : // when we are here there is no double key in the table
1747 : :
1748 [ + + ][ + - ]: 160 : for (i = 0; i < nColumnCount && nByteOffset <= m_nBufferSize ; ++i)
[ + + ]
1749 : : {
1750 : : // Lengths for each data type:
1751 : : OSL_ENSURE(i < m_aPrecisions.size(),"Illegal index!");
1752 : 150 : sal_Int32 nLen = 0;
1753 : 150 : sal_Int32 nType = 0;
1754 : 150 : sal_Int32 nScale = 0;
1755 [ + - ]: 150 : if ( i < m_aPrecisions.size() )
1756 : : {
1757 [ + - ]: 150 : nLen = m_aPrecisions[i];
1758 [ + - ]: 150 : nType = m_aTypes[i];
1759 [ + - ]: 150 : nScale = m_aScales[i];
1760 : : }
1761 : : else
1762 : : {
1763 [ # # ][ # # ]: 0 : m_pColumns->getByIndex(i) >>= xCol;
1764 [ # # ]: 0 : if ( xCol.is() )
1765 : : {
1766 [ # # ][ # # ]: 0 : xCol->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_PRECISION)) >>= nLen;
[ # # ][ # # ]
1767 [ # # ][ # # ]: 0 : xCol->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TYPE)) >>= nType;
[ # # ][ # # ]
1768 [ # # ][ # # ]: 0 : xCol->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_SCALE)) >>= nScale;
[ # # ][ # # ]
1769 : : }
1770 : : }
1771 : :
1772 : 150 : bool bSetZero = false;
1773 [ - + + + ]: 150 : switch (nType)
1774 : : {
1775 : : case DataType::INTEGER:
1776 : : case DataType::DOUBLE:
1777 : : case DataType::TIMESTAMP:
1778 : 0 : bSetZero = true;
1779 : : case DataType::LONGVARBINARY:
1780 : : case DataType::DATE:
1781 : : case DataType::BIT:
1782 : : case DataType::LONGVARCHAR:
1783 [ + - ]: 74 : nLen = m_aRealFieldLengths[i];
1784 : 74 : break;
1785 : : case DataType::DECIMAL:
1786 [ + - ]: 40 : nLen = SvDbaseConverter::ConvertPrecisionToDbase(nLen,nScale);
1787 : 40 : break; // The sign and the comma
1788 : : default:
1789 : 36 : break;
1790 : :
1791 : : } // switch (nType)
1792 : :
1793 : 150 : sal_Int32 nPos = i;
1794 [ + - ][ - + ]: 150 : if(_xCols != xColumns)
1795 : : {
1796 [ # # ][ # # ]: 0 : m_pColumns->getByIndex(i) >>= xCol;
1797 : : OSL_ENSURE(xCol.is(),"ODbaseTable::UpdateBuffer column is null!");
1798 [ # # ][ # # ]: 0 : xCol->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_NAME)) >>= aColName;
[ # # ][ # # ]
1799 [ # # ][ # # ]: 0 : for(nPos = 0;nPos<_xCols->getCount();++nPos)
[ # # ]
1800 : : {
1801 : 0 : Reference<XPropertySet> xFindCol;
1802 [ # # ][ # # ]: 0 : ::cppu::extractInterface(xFindCol,_xCols->getByIndex(nPos));
[ # # ]
1803 [ # # ][ # # ]: 0 : if(aCase(getString(xFindCol->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_NAME))),aColName))
[ # # ][ # # ]
[ # # ][ # # ]
1804 : : break;
1805 [ # # ]: 0 : }
1806 [ # # ][ # # ]: 0 : if (nPos >= _xCols->getCount())
[ # # ]
1807 : : {
1808 : 0 : nByteOffset += nLen;
1809 : 0 : continue;
1810 : : }
1811 : : }
1812 : :
1813 : :
1814 : :
1815 : 150 : ++nPos; // the row values start at 1
1816 : : // If the variable is bound at all?
1817 [ + + ]: 150 : if ( !rRow.get()[nPos]->isBound() )
1818 : : {
1819 : : // No - the next field.
1820 : 140 : nByteOffset += nLen;
1821 : 140 : continue;
1822 : : }
1823 [ - + ]: 10 : if (aIndexedCols[i].is())
1824 : : {
1825 [ # # ]: 0 : Reference<XUnoTunnel> xTunnel(aIndexedCols[i],UNO_QUERY);
1826 : : OSL_ENSURE(xTunnel.is(),"No TunnelImplementation!");
1827 [ # # ][ # # ]: 0 : ODbaseIndex* pIndex = reinterpret_cast< ODbaseIndex* >( xTunnel->getSomething(ODbaseIndex::getUnoTunnelImplementationId()) );
[ # # ][ # # ]
1828 : : OSL_ENSURE(pIndex,"ODbaseTable::UpdateBuffer: No Index returned!");
1829 : : // Update !!
1830 [ # # ][ # # ]: 0 : if (pOrgRow.is() && !rRow.get()[nPos]->getValue().isNull() )
[ # # ]
1831 [ # # ]: 0 : pIndex->Update(m_nFilePos,*(pOrgRow->get())[nPos],*rRow.get()[nPos]);
1832 : : else
1833 [ # # ]: 0 : pIndex->Insert(m_nFilePos,*rRow.get()[nPos]);
1834 : : }
1835 : :
1836 : 10 : char* pData = (char *)(m_pBuffer + nByteOffset);
1837 [ - + ]: 10 : if (rRow.get()[nPos]->getValue().isNull())
1838 : : {
1839 [ # # ]: 0 : if ( bSetZero )
1840 : 0 : memset(pData,0,nLen); // Clear to NULL
1841 : : else
1842 : 0 : memset(pData,' ',nLen); // Clear to NULL
1843 : 0 : nByteOffset += nLen;
1844 : : OSL_ENSURE( nByteOffset <= m_nBufferSize ,"ByteOffset > m_nBufferSize!");
1845 : 0 : continue;
1846 : : }
1847 : :
1848 : : try
1849 : : {
1850 [ - - - - : 10 : switch (nType)
- - + + ]
1851 : : {
1852 : : case DataType::TIMESTAMP:
1853 : : {
1854 : 0 : sal_Int32 nJulianDate = 0, nJulianTime = 0;
1855 [ # # ]: 0 : lcl_CalcJulDate(nJulianDate,nJulianTime,rRow.get()[nPos]->getValue());
1856 : : // Exactly 8 bytes to copy:
1857 : 0 : memcpy(pData,&nJulianDate,4);
1858 : 0 : memcpy(pData+4,&nJulianTime,4);
1859 : : }
1860 : 0 : break;
1861 : : case DataType::DATE:
1862 : : {
1863 : 0 : ::com::sun::star::util::Date aDate;
1864 [ # # ]: 0 : if(rRow.get()[nPos]->getValue().getTypeKind() == DataType::DOUBLE)
1865 [ # # ][ # # ]: 0 : aDate = ::dbtools::DBTypeConversion::toDate(rRow.get()[nPos]->getValue().getDouble());
[ # # ]
1866 : : else
1867 [ # # ]: 0 : aDate = rRow.get()[nPos]->getValue();
1868 : : char s[9];
1869 : : snprintf(s,
1870 : : sizeof(s),
1871 : : "%04d%02d%02d",
1872 : : (int)aDate.Year,
1873 : : (int)aDate.Month,
1874 : 0 : (int)aDate.Day);
1875 : :
1876 : : // Exactly 8 bytes to copy:
1877 : 0 : strncpy(pData,s,sizeof s - 1);
1878 : 0 : } break;
1879 : : case DataType::INTEGER:
1880 : : {
1881 [ # # ]: 0 : sal_Int32 nValue = rRow.get()[nPos]->getValue();
1882 : 0 : memcpy(pData,&nValue,nLen);
1883 : : }
1884 : 0 : break;
1885 : : case DataType::DOUBLE:
1886 : : {
1887 [ # # ]: 0 : const double d = rRow.get()[nPos]->getValue();
1888 [ # # ][ # # ]: 0 : m_pColumns->getByIndex(i) >>= xCol;
1889 : :
1890 [ # # ][ # # ]: 0 : if (getBOOL(xCol->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_ISCURRENCY)))) // Currency is treated separately
[ # # ][ # # ]
[ # # ][ # # ]
1891 : : {
1892 : 0 : sal_Int64 nValue = 0;
1893 [ # # ][ # # ]: 0 : if ( m_aScales[i] )
1894 [ # # ]: 0 : nValue = (sal_Int64)(d * pow(10.0,(int)m_aScales[i]));
1895 : : else
1896 : 0 : nValue = (sal_Int64)(d);
1897 : 0 : memcpy(pData,&nValue,nLen);
1898 : : } // if (getBOOL(xCol->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_ISCURRENCY)))) // Currency is treated separately
1899 : : else
1900 : 0 : memcpy(pData,&d,nLen);
1901 : : }
1902 : 0 : break;
1903 : : case DataType::DECIMAL:
1904 : : {
1905 : 0 : memset(pData,' ',nLen); // Clear to NULL
1906 : :
1907 [ # # ]: 0 : const double n = rRow.get()[nPos]->getValue();
1908 : :
1909 : : // one, because const_cast GetFormatPrecision on SvNumberFormat is not constant,
1910 : : // even though it really could and should be
1911 : 0 : const rtl::OString aDefaultValue( ::rtl::math::doubleToString( n, rtl_math_StringFormat_F, nScale, '.', NULL, 0));
1912 : 0 : const sal_Int32 nValueLen = aDefaultValue.getLength();
1913 [ # # ]: 0 : if ( nValueLen <= nLen )
1914 : : {
1915 : : // Write value right-justified, padded with blanks to the left.
1916 : 0 : memcpy(pData+nLen-nValueLen,aDefaultValue.getStr(),nValueLen);
1917 : : // write the resulting double back
1918 [ # # ][ # # ]: 0 : *rRow.get()[nPos] = toDouble(aDefaultValue);
[ # # ]
1919 : : }
1920 : : else
1921 : : {
1922 [ # # ][ # # ]: 0 : m_pColumns->getByIndex(i) >>= xCol;
1923 : : OSL_ENSURE(xCol.is(),"ODbaseTable::UpdateBuffer column is null!");
1924 [ # # ][ # # ]: 0 : xCol->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_NAME)) >>= aColName;
[ # # ][ # # ]
1925 [ # # ]: 0 : ::std::list< ::std::pair<const sal_Char* , ::rtl::OUString > > aStringToSubstitutes;
1926 [ # # ]: 0 : aStringToSubstitutes.push_back(::std::pair<const sal_Char* , ::rtl::OUString >("$columnname$", aColName));
1927 [ # # ][ # # ]: 0 : aStringToSubstitutes.push_back(::std::pair<const sal_Char* , ::rtl::OUString >("$precision$", String::CreateFromInt32(nLen)));
[ # # ][ # # ]
1928 [ # # ][ # # ]: 0 : aStringToSubstitutes.push_back(::std::pair<const sal_Char* , ::rtl::OUString >("$scale$", String::CreateFromInt32(nScale)));
[ # # ][ # # ]
1929 [ # # ][ # # ]: 0 : aStringToSubstitutes.push_back(::std::pair<const sal_Char* , ::rtl::OUString >("$value$", ::rtl::OStringToOUString(aDefaultValue,RTL_TEXTENCODING_UTF8)));
1930 : :
1931 : 0 : const ::rtl::OUString sError( getConnection()->getResources().getResourceStringWithSubstitution(
1932 : : STR_INVALID_COLUMN_DECIMAL_VALUE
1933 : : ,aStringToSubstitutes
1934 [ # # # # ]: 0 : ) );
1935 [ # # ][ # # ]: 0 : ::dbtools::throwGenericSQLException( sError, *this );
1936 : 0 : }
1937 : 0 : } break;
1938 : : case DataType::BIT:
1939 [ # # ][ # # ]: 0 : *pData = rRow.get()[nPos]->getValue().getBool() ? 'T' : 'F';
1940 : 0 : break;
1941 : : case DataType::LONGVARBINARY:
1942 : : case DataType::LONGVARCHAR:
1943 : : {
1944 : 2 : char cNext = pData[nLen]; // Mark's scratch and replaced by 0
1945 : 2 : pData[nLen] = '\0'; // This is because the buffer is always a sign of greater ...
1946 : :
1947 : 2 : sal_uIntPtr nBlockNo = strtol((const char *)pData,NULL,10); // Block number read
1948 : :
1949 : : // Next initial character restore again:
1950 : 2 : pData[nLen] = cNext;
1951 [ + - ][ - + ]: 2 : if (!m_pMemoStream || !WriteMemo(rRow.get()[nPos]->get(), nBlockNo))
[ + - ][ + - ]
1952 : : break;
1953 : :
1954 : 2 : rtl::OString aBlock(rtl::OString::valueOf(static_cast<sal_Int32>(nBlockNo)));
1955 : : //align aBlock at the right of a nLen sequence, fill to the left with '0'
1956 : 2 : rtl::OStringBuffer aStr;
1957 [ + - ]: 2 : comphelper::string::padToLength(aStr, nLen - aBlock.getLength(), '0');
1958 [ + - ]: 2 : aStr.append(aBlock);
1959 : :
1960 : : // Copy characters:
1961 : 2 : memcpy(pData, aStr.getStr(), nLen);
1962 : 2 : } break;
1963 : : default:
1964 : : {
1965 : 8 : memset(pData,' ',nLen); // Clear to NULL
1966 : :
1967 [ + - ]: 8 : ::rtl::OUString sStringToWrite( rRow.get()[nPos]->getValue().getString() );
1968 : :
1969 : : // convert the string, using the connection's encoding
1970 : 8 : ::rtl::OString sEncoded;
1971 : :
1972 [ + - ]: 8 : DBTypeConversion::convertUnicodeStringToLength( sStringToWrite, sEncoded, nLen, m_eEncoding );
1973 : 8 : memcpy( pData, sEncoded.getStr(), sEncoded.getLength() );
1974 : :
1975 : : }
1976 : 8 : break;
1977 : : }
1978 : : }
1979 : 0 : catch( const SQLException& )
1980 : : {
1981 : 0 : throw;
1982 : : }
1983 [ # # # # : 0 : catch ( const Exception& )
# ]
1984 : : {
1985 [ # # # # ]: 0 : m_pColumns->getByIndex(i) >>= xCol;
1986 : : OSL_ENSURE( xCol.is(), "ODbaseTable::UpdateBuffer column is null!" );
1987 [ # # ]: 0 : if ( xCol.is() )
1988 [ # # # # : 0 : xCol->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_NAME)) >>= aColName;
# # # # ]
1989 : :
1990 : 0 : const ::rtl::OUString sError( getConnection()->getResources().getResourceStringWithSubstitution(
1991 : : STR_INVALID_COLUMN_VALUE,
1992 : : "$columnname$", aColName
1993 [ # # ]: 0 : ) );
1994 [ # # # # ]: 0 : ::dbtools::throwGenericSQLException( sError, *this );
1995 : : }
1996 : : // And more ...
1997 : 150 : nByteOffset += nLen;
1998 : : OSL_ENSURE( nByteOffset <= m_nBufferSize ,"ByteOffset > m_nBufferSize!");
1999 : : }
2000 : 10 : return sal_True;
2001 : : }
2002 : :
2003 : : // -----------------------------------------------------------------------------
2004 : 2 : sal_Bool ODbaseTable::WriteMemo(ORowSetValue& aVariable, sal_uIntPtr& rBlockNr)
2005 : : {
2006 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ODbaseTable::WriteMemo" );
2007 : : // if the BlockNo 0 is given, the block will be appended at the end
2008 : 2 : sal_uIntPtr nSize = 0;
2009 : 2 : ::rtl::OString aStr;
2010 [ + - ]: 2 : ::com::sun::star::uno::Sequence<sal_Int8> aValue;
2011 : : sal_uInt8 nHeader[4];
2012 [ - + ][ # # ]: 2 : const bool bBinary = aVariable.getTypeKind() == DataType::LONGVARBINARY && m_aMemoHeader.db_typ == MemoFoxPro;
2013 [ - + ]: 2 : if ( bBinary )
2014 : : {
2015 [ # # ][ # # ]: 0 : aValue = aVariable.getSequence();
[ # # ]
2016 : 0 : nSize = aValue.getLength();
2017 : : }
2018 : : else
2019 : : {
2020 [ + - ][ + - ]: 2 : nSize = DBTypeConversion::convertUnicodeString( aVariable.getString(), aStr, m_eEncoding );
2021 : : }
2022 : :
2023 : : // append or overwrite
2024 : 2 : sal_Bool bAppend = rBlockNr == 0;
2025 : :
2026 [ - + ]: 2 : if (!bAppend)
2027 : : {
2028 [ # # # ]: 0 : switch (m_aMemoHeader.db_typ)
2029 : : {
2030 : : case MemodBaseIII: // dBase III-Memofield, ends with 2 * Ctrl-Z
2031 : 0 : bAppend = nSize > (512 - 2);
2032 : 0 : break;
2033 : : case MemoFoxPro:
2034 : : case MemodBaseIV: // dBase IV-Memofield with length
2035 : : {
2036 : : char sHeader[4];
2037 [ # # ]: 0 : m_pMemoStream->Seek(rBlockNr * m_aMemoHeader.db_size);
2038 [ # # ]: 0 : m_pMemoStream->SeekRel(4L);
2039 [ # # ]: 0 : m_pMemoStream->Read(sHeader,4);
2040 : :
2041 : : sal_uIntPtr nOldSize;
2042 [ # # ]: 0 : if (m_aMemoHeader.db_typ == MemoFoxPro)
2043 : 0 : nOldSize = ((((unsigned char)sHeader[0]) * 256 +
2044 : 0 : (unsigned char)sHeader[1]) * 256 +
2045 : 0 : (unsigned char)sHeader[2]) * 256 +
2046 : 0 : (unsigned char)sHeader[3];
2047 : : else
2048 : 0 : nOldSize = ((((unsigned char)sHeader[3]) * 256 +
2049 : 0 : (unsigned char)sHeader[2]) * 256 +
2050 : 0 : (unsigned char)sHeader[1]) * 256 +
2051 : 0 : (unsigned char)sHeader[0] - 8;
2052 : :
2053 : : // fits the new length in the used blocks
2054 [ # # ]: 0 : sal_uIntPtr nUsedBlocks = ((nSize + 8) / m_aMemoHeader.db_size) + (((nSize + 8) % m_aMemoHeader.db_size > 0) ? 1 : 0),
2055 [ # # ]: 0 : nOldUsedBlocks = ((nOldSize + 8) / m_aMemoHeader.db_size) + (((nOldSize + 8) % m_aMemoHeader.db_size > 0) ? 1 : 0);
2056 : 0 : bAppend = nUsedBlocks > nOldUsedBlocks;
2057 : : }
2058 : : }
2059 : : }
2060 : :
2061 [ + - ]: 2 : if (bAppend)
2062 : : {
2063 [ + - ]: 2 : sal_uIntPtr nStreamSize = m_pMemoStream->Seek(STREAM_SEEK_TO_END);
2064 : : // fill last block
2065 [ + - ]: 2 : rBlockNr = (nStreamSize / m_aMemoHeader.db_size) + ((nStreamSize % m_aMemoHeader.db_size) > 0 ? 1 : 0);
2066 : :
2067 [ + - ]: 2 : m_pMemoStream->SetStreamSize(rBlockNr * m_aMemoHeader.db_size);
2068 [ + - ]: 2 : m_pMemoStream->Seek(STREAM_SEEK_TO_END);
2069 : : }
2070 : : else
2071 : : {
2072 [ # # ]: 0 : m_pMemoStream->Seek(rBlockNr * m_aMemoHeader.db_size);
2073 : : }
2074 : :
2075 [ + - - ]: 2 : switch (m_aMemoHeader.db_typ)
2076 : : {
2077 : : case MemodBaseIII: // dBase III-Memofield, ends with Ctrl-Z
2078 : : {
2079 : 2 : const char cEOF = (char) DBF_EOL;
2080 : 2 : nSize++;
2081 [ + - ]: 2 : m_pMemoStream->Write( aStr.getStr(), aStr.getLength() );
2082 [ + - ][ + - ]: 2 : (*m_pMemoStream) << cEOF << cEOF;
2083 : 2 : } break;
2084 : : case MemoFoxPro:
2085 : : case MemodBaseIV: // dBase IV-Memofeld with length
2086 : : {
2087 [ # # ]: 0 : if ( MemodBaseIV == m_aMemoHeader.db_typ )
2088 [ # # ]: 0 : (*m_pMemoStream) << (sal_uInt8)0xFF
2089 [ # # ]: 0 : << (sal_uInt8)0xFF
2090 [ # # ]: 0 : << (sal_uInt8)0x08;
2091 : : else
2092 [ # # ]: 0 : (*m_pMemoStream) << (sal_uInt8)0x00
2093 [ # # ]: 0 : << (sal_uInt8)0x00
2094 [ # # ]: 0 : << (sal_uInt8)0x00;
2095 : :
2096 : 0 : sal_uInt32 nWriteSize = nSize;
2097 [ # # ]: 0 : if (m_aMemoHeader.db_typ == MemoFoxPro)
2098 : : {
2099 [ # # ]: 0 : if ( bBinary )
2100 [ # # ]: 0 : (*m_pMemoStream) << (sal_uInt8) 0x00; // Picture
2101 : : else
2102 [ # # ]: 0 : (*m_pMemoStream) << (sal_uInt8) 0x01; // Memo
2103 [ # # ]: 0 : for (int i = 4; i > 0; nWriteSize >>= 8)
2104 : 0 : nHeader[--i] = (sal_uInt8) (nWriteSize % 256);
2105 : : }
2106 : : else
2107 : : {
2108 [ # # ]: 0 : (*m_pMemoStream) << (sal_uInt8) 0x00;
2109 : 0 : nWriteSize += 8;
2110 [ # # ]: 0 : for (int i = 0; i < 4; nWriteSize >>= 8)
2111 : 0 : nHeader[i++] = (sal_uInt8) (nWriteSize % 256);
2112 : : }
2113 : :
2114 [ # # ]: 0 : m_pMemoStream->Write(nHeader,4);
2115 [ # # ]: 0 : if ( bBinary )
2116 [ # # ]: 0 : m_pMemoStream->Write( aValue.getConstArray(), aValue.getLength() );
2117 : : else
2118 [ # # ]: 0 : m_pMemoStream->Write( aStr.getStr(), aStr.getLength() );
2119 [ # # ]: 0 : m_pMemoStream->Flush();
2120 : : }
2121 : : }
2122 : :
2123 : :
2124 : : // Write the new block number
2125 [ + - ]: 2 : if (bAppend)
2126 : : {
2127 [ + - ]: 2 : sal_uIntPtr nStreamSize = m_pMemoStream->Seek(STREAM_SEEK_TO_END);
2128 [ + - ]: 2 : m_aMemoHeader.db_next = (nStreamSize / m_aMemoHeader.db_size) + ((nStreamSize % m_aMemoHeader.db_size) > 0 ? 1 : 0);
2129 : :
2130 : : // Write the new block number
2131 [ + - ]: 2 : m_pMemoStream->Seek(0L);
2132 [ + - ]: 2 : (*m_pMemoStream) << m_aMemoHeader.db_next;
2133 [ + - ]: 2 : m_pMemoStream->Flush();
2134 : : }
2135 [ + - ]: 2 : return sal_True;
2136 : : }
2137 : :
2138 : : // -----------------------------------------------------------------------------
2139 : : // XAlterTable
2140 : 0 : void SAL_CALL ODbaseTable::alterColumnByName( const ::rtl::OUString& colName, const Reference< XPropertySet >& descriptor ) throw(SQLException, NoSuchElementException, RuntimeException)
2141 : : {
2142 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ODbaseTable::alterColumnByName" );
2143 [ # # ]: 0 : ::osl::MutexGuard aGuard(m_aMutex);
2144 [ # # ]: 0 : checkDisposed(OTableDescriptor_BASE::rBHelper.bDisposed);
2145 : :
2146 : :
2147 : 0 : Reference<XDataDescriptorFactory> xOldColumn;
2148 [ # # ][ # # ]: 0 : m_pColumns->getByName(colName) >>= xOldColumn;
2149 : :
2150 [ # # ][ # # ]: 0 : alterColumn(m_pColumns->findColumn(colName)-1,descriptor,xOldColumn);
[ # # ]
2151 : 0 : }
2152 : : // -------------------------------------------------------------------------
2153 : 0 : void SAL_CALL ODbaseTable::alterColumnByIndex( sal_Int32 index, const Reference< XPropertySet >& descriptor ) throw(SQLException, ::com::sun::star::lang::IndexOutOfBoundsException, RuntimeException)
2154 : : {
2155 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ODbaseTable::alterColumnByIndex" );
2156 [ # # ]: 0 : ::osl::MutexGuard aGuard(m_aMutex);
2157 [ # # ]: 0 : checkDisposed(OTableDescriptor_BASE::rBHelper.bDisposed);
2158 : :
2159 [ # # ][ # # ]: 0 : if(index < 0 || index >= m_pColumns->getCount())
[ # # ][ # # ]
2160 [ # # ][ # # ]: 0 : throw IndexOutOfBoundsException(::rtl::OUString::valueOf(index),*this);
2161 : :
2162 : 0 : Reference<XDataDescriptorFactory> xOldColumn;
2163 [ # # ][ # # ]: 0 : m_pColumns->getByIndex(index) >>= xOldColumn;
2164 [ # # ][ # # ]: 0 : alterColumn(index,descriptor,xOldColumn);
2165 : 0 : }
2166 : : // -----------------------------------------------------------------------------
2167 : 0 : void ODbaseTable::alterColumn(sal_Int32 index,
2168 : : const Reference< XPropertySet >& descriptor ,
2169 : : const Reference< XDataDescriptorFactory >& xOldColumn )
2170 : : {
2171 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ODbaseTable::alterColumn" );
2172 [ # # ][ # # ]: 0 : if(index < 0 || index >= m_pColumns->getCount())
[ # # ]
2173 [ # # ][ # # ]: 0 : throw IndexOutOfBoundsException(::rtl::OUString::valueOf(index),*this);
2174 : :
2175 : 0 : ODbaseTable* pNewTable = NULL;
2176 : : try
2177 : : {
2178 : : OSL_ENSURE(descriptor.is(),"ODbaseTable::alterColumn: descriptor can not be null!");
2179 : : // creates a copy of the the original column and copy all properties from descriptor in xCopyColumn
2180 : 0 : Reference<XPropertySet> xCopyColumn;
2181 [ # # ]: 0 : if(xOldColumn.is())
2182 [ # # ][ # # ]: 0 : xCopyColumn = xOldColumn->createDataDescriptor();
[ # # ]
2183 : : else
2184 [ # # ][ # # ]: 0 : xCopyColumn = new OColumn(getConnection()->getMetaData()->supportsMixedCaseQuotedIdentifiers());
[ # # ][ # # ]
[ # # ][ # # ]
2185 : :
2186 [ # # ]: 0 : ::comphelper::copyProperties(descriptor,xCopyColumn);
2187 : :
2188 : : // creates a temp file
2189 : :
2190 [ # # ]: 0 : String sTempName = createTempFile();
2191 : :
2192 [ # # ]: 0 : pNewTable = new ODbaseTable(m_pTables,static_cast<ODbaseConnection*>(m_pConnection));
2193 [ # # ][ # # ]: 0 : Reference<XPropertySet> xHoldTable = pNewTable;
2194 [ # # ][ # # ]: 0 : pNewTable->setPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_NAME),makeAny(::rtl::OUString(sTempName)));
[ # # ][ # # ]
[ # # ]
2195 [ # # ][ # # ]: 0 : Reference<XAppend> xAppend(pNewTable->getColumns(),UNO_QUERY);
2196 : : OSL_ENSURE(xAppend.is(),"ODbaseTable::alterColumn: No XAppend interface!");
2197 : :
2198 : : // copy the structure
2199 : 0 : sal_Int32 i=0;
2200 [ # # ]: 0 : for(;i < index;++i)
2201 : : {
2202 : 0 : Reference<XPropertySet> xProp;
2203 [ # # ][ # # ]: 0 : m_pColumns->getByIndex(i) >>= xProp;
2204 [ # # ]: 0 : Reference<XDataDescriptorFactory> xColumn(xProp,UNO_QUERY);
2205 : 0 : Reference<XPropertySet> xCpy;
2206 [ # # ]: 0 : if(xColumn.is())
2207 [ # # ][ # # ]: 0 : xCpy = xColumn->createDataDescriptor();
[ # # ]
2208 : : else
2209 [ # # ][ # # ]: 0 : xCpy = new OColumn(getConnection()->getMetaData()->supportsMixedCaseQuotedIdentifiers());
[ # # ][ # # ]
[ # # ][ # # ]
2210 [ # # ]: 0 : ::comphelper::copyProperties(xProp,xCpy);
2211 [ # # ][ # # ]: 0 : xAppend->appendByDescriptor(xCpy);
2212 : 0 : }
2213 : 0 : ++i; // now insert our new column
2214 [ # # ][ # # ]: 0 : xAppend->appendByDescriptor(xCopyColumn);
2215 : :
2216 [ # # ][ # # ]: 0 : for(;i < m_pColumns->getCount();++i)
2217 : : {
2218 : 0 : Reference<XPropertySet> xProp;
2219 [ # # ][ # # ]: 0 : m_pColumns->getByIndex(i) >>= xProp;
2220 [ # # ]: 0 : Reference<XDataDescriptorFactory> xColumn(xProp,UNO_QUERY);
2221 : 0 : Reference<XPropertySet> xCpy;
2222 [ # # ]: 0 : if(xColumn.is())
2223 [ # # ][ # # ]: 0 : xCpy = xColumn->createDataDescriptor();
[ # # ]
2224 : : else
2225 [ # # ][ # # ]: 0 : xCpy = new OColumn(getConnection()->getMetaData()->supportsMixedCaseQuotedIdentifiers());
[ # # ][ # # ]
[ # # ][ # # ]
2226 [ # # ]: 0 : ::comphelper::copyProperties(xProp,xCpy);
2227 [ # # ][ # # ]: 0 : xAppend->appendByDescriptor(xCpy);
2228 : 0 : }
2229 : :
2230 : : // construct the new table
2231 [ # # ][ # # ]: 0 : if(!pNewTable->CreateImpl())
2232 : : {
2233 : 0 : const ::rtl::OUString sError( getConnection()->getResources().getResourceStringWithSubstitution(
2234 : : STR_COLUMN_NOT_ALTERABLE,
2235 [ # # ][ # # ]: 0 : "$columnname$", ::comphelper::getString(descriptor->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_NAME)))
2236 [ # # ][ # # ]: 0 : ) );
[ # # # # ]
2237 [ # # ][ # # ]: 0 : ::dbtools::throwGenericSQLException( sError, *this );
2238 : : }
2239 : :
2240 [ # # ]: 0 : pNewTable->construct();
2241 : :
2242 : : // copy the data
2243 [ # # ]: 0 : copyData(pNewTable,0);
2244 : :
2245 : : // now drop the old one
2246 [ # # ][ # # ]: 0 : if( DropImpl() ) // we don't want to delete the memo columns too
2247 : : {
2248 : : // rename the new one to the old one
2249 [ # # ]: 0 : pNewTable->renameImpl(m_Name);
2250 : : // release the temp file
2251 : 0 : pNewTable = NULL;
2252 [ # # ]: 0 : ::comphelper::disposeComponent(xHoldTable);
2253 : : }
2254 : : else
2255 : : {
2256 : 0 : pNewTable = NULL;
2257 : : }
2258 [ # # ]: 0 : FileClose();
2259 [ # # ]: 0 : construct();
2260 [ # # ]: 0 : if(m_pColumns)
2261 [ # # ][ # # ]: 0 : m_pColumns->refresh();
2262 : :
2263 : : }
2264 : 0 : catch(const SQLException&)
2265 : : {
2266 : 0 : throw;
2267 : : }
2268 [ # # # ]: 0 : catch(const Exception&)
2269 : : {
2270 : : OSL_FAIL("ODbaseTable::alterColumn: Exception occurred!");
2271 : 0 : throw;
2272 : : }
2273 : 0 : }
2274 : : // -----------------------------------------------------------------------------
2275 : 0 : Reference< XDatabaseMetaData> ODbaseTable::getMetaData() const
2276 : : {
2277 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ODbaseTable::getMetaData" );
2278 : 0 : return getConnection()->getMetaData();
2279 : : }
2280 : : // -------------------------------------------------------------------------
2281 : 0 : void SAL_CALL ODbaseTable::rename( const ::rtl::OUString& newName ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::container::ElementExistException, ::com::sun::star::uno::RuntimeException)
2282 : : {
2283 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ODbaseTable::rename" );
2284 [ # # ]: 0 : ::osl::MutexGuard aGuard(m_aMutex);
2285 [ # # ]: 0 : checkDisposed(OTableDescriptor_BASE::rBHelper.bDisposed);
2286 [ # # ][ # # ]: 0 : if(m_pTables && m_pTables->hasByName(newName))
[ # # ][ # # ]
2287 [ # # ][ # # ]: 0 : throw ElementExistException(newName,*this);
2288 : :
2289 : :
2290 [ # # ]: 0 : renameImpl(newName);
2291 : :
2292 [ # # ]: 0 : ODbaseTable_BASE::rename(newName);
2293 : :
2294 [ # # ]: 0 : construct();
2295 [ # # ]: 0 : if(m_pColumns)
2296 [ # # ][ # # ]: 0 : m_pColumns->refresh();
2297 : 0 : }
2298 : : namespace
2299 : : {
2300 : 0 : void renameFile(OConnection* _pConenction,const ::rtl::OUString& oldName,
2301 : : const ::rtl::OUString& newName,const String& _sExtension)
2302 : : {
2303 [ # # ]: 0 : String aName = ODbaseTable::getEntry(_pConenction,oldName);
2304 [ # # ]: 0 : if(!aName.Len())
2305 : : {
2306 [ # # ][ # # ]: 0 : ::rtl::OUString aIdent = _pConenction->getContent()->getIdentifier()->getContentIdentifier();
[ # # ][ # # ]
[ # # ]
2307 [ # # ]: 0 : if ( aIdent.lastIndexOf('/') != (aIdent.getLength()-1) )
2308 : 0 : aIdent += ::rtl::OUString("/");
2309 : 0 : aIdent += oldName;
2310 [ # # ]: 0 : aName = aIdent;
2311 : : }
2312 [ # # ]: 0 : INetURLObject aURL;
2313 [ # # ][ # # ]: 0 : aURL.SetURL(aName);
2314 : :
2315 [ # # ][ # # ]: 0 : aURL.setExtension( _sExtension );
2316 [ # # ]: 0 : String sNewName(newName);
2317 [ # # ]: 0 : sNewName.AppendAscii(".");
2318 [ # # ]: 0 : sNewName += _sExtension;
2319 : :
2320 : : try
2321 : : {
2322 [ # # ][ # # ]: 0 : Content aContent(aURL.GetMainURL(INetURLObject::NO_DECODE),Reference<XCommandEnvironment>());
2323 : :
2324 [ # # ]: 0 : Sequence< PropertyValue > aProps( 1 );
2325 [ # # ]: 0 : aProps[0].Name = ::rtl::OUString("Title");
2326 [ # # ]: 0 : aProps[0].Handle = -1; // n/a
2327 [ # # ][ # # ]: 0 : aProps[0].Value = makeAny( ::rtl::OUString(sNewName) );
[ # # ]
2328 [ # # ]: 0 : Sequence< Any > aValues;
2329 [ # # ][ # # ]: 0 : aContent.executeCommand( rtl::OUString("setPropertyValues"),makeAny(aProps) ) >>= aValues;
[ # # ]
2330 [ # # ][ # # ]: 0 : if(aValues.getLength() && aValues[0].hasValue())
[ # # ][ # # ]
2331 [ # # ][ # # ]: 0 : throw Exception();
[ # # ][ # # ]
2332 : : }
2333 [ # # ]: 0 : catch(const Exception&)
2334 : : {
2335 [ # # # # ]: 0 : throw ElementExistException(newName,NULL);
2336 [ # # ][ # # ]: 0 : }
[ # # ]
2337 : 0 : }
2338 : : }
2339 : : // -------------------------------------------------------------------------
2340 : 0 : void SAL_CALL ODbaseTable::renameImpl( const ::rtl::OUString& newName ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::container::ElementExistException, ::com::sun::star::uno::RuntimeException)
2341 : : {
2342 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ODbaseTable::getEntry" );
2343 [ # # ]: 0 : ::osl::MutexGuard aGuard(m_aMutex);
2344 : :
2345 [ # # ]: 0 : FileClose();
2346 : :
2347 : :
2348 [ # # ]: 0 : renameFile(m_pConnection,m_Name,newName,m_pConnection->getExtension());
2349 [ # # ]: 0 : if ( HasMemoFields() )
2350 : : { // delete the memo fields
2351 : 0 : rtl::OUString sExt("dbt");
2352 [ # # ][ # # ]: 0 : renameFile(m_pConnection,m_Name,newName,sExt);
[ # # ]
2353 [ # # ]: 0 : }
2354 : 0 : }
2355 : : // -----------------------------------------------------------------------------
2356 : 0 : void ODbaseTable::addColumn(const Reference< XPropertySet >& _xNewColumn)
2357 : : {
2358 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ODbaseTable::addColumn" );
2359 [ # # ]: 0 : String sTempName = createTempFile();
2360 : :
2361 [ # # ]: 0 : ODbaseTable* pNewTable = new ODbaseTable(m_pTables,static_cast<ODbaseConnection*>(m_pConnection));
2362 [ # # ][ # # ]: 0 : Reference< XPropertySet > xHold = pNewTable;
2363 [ # # ][ # # ]: 0 : pNewTable->setPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_NAME),makeAny(::rtl::OUString(sTempName)));
[ # # ][ # # ]
[ # # ]
2364 : : {
2365 [ # # ][ # # ]: 0 : Reference<XAppend> xAppend(pNewTable->getColumns(),UNO_QUERY);
2366 [ # # ][ # # ]: 0 : sal_Bool bCase = getConnection()->getMetaData()->supportsMixedCaseQuotedIdentifiers();
[ # # ]
2367 : : // copy the structure
2368 [ # # ][ # # ]: 0 : for(sal_Int32 i=0;i < m_pColumns->getCount();++i)
2369 : : {
2370 : 0 : Reference<XPropertySet> xProp;
2371 [ # # ][ # # ]: 0 : m_pColumns->getByIndex(i) >>= xProp;
2372 [ # # ]: 0 : Reference<XDataDescriptorFactory> xColumn(xProp,UNO_QUERY);
2373 : 0 : Reference<XPropertySet> xCpy;
2374 [ # # ]: 0 : if(xColumn.is())
2375 [ # # ][ # # ]: 0 : xCpy = xColumn->createDataDescriptor();
[ # # ]
2376 : : else
2377 : : {
2378 [ # # ][ # # ]: 0 : xCpy = new OColumn(bCase);
[ # # ]
2379 [ # # ]: 0 : ::comphelper::copyProperties(xProp,xCpy);
2380 : : }
2381 : :
2382 [ # # ][ # # ]: 0 : xAppend->appendByDescriptor(xCpy);
2383 : 0 : }
2384 [ # # ][ # # ]: 0 : Reference<XPropertySet> xCpy = new OColumn(bCase);
[ # # ]
2385 [ # # ]: 0 : ::comphelper::copyProperties(_xNewColumn,xCpy);
2386 [ # # ][ # # ]: 0 : xAppend->appendByDescriptor(xCpy);
2387 : : }
2388 : :
2389 : : // construct the new table
2390 [ # # ][ # # ]: 0 : if(!pNewTable->CreateImpl())
2391 : : {
2392 : 0 : const ::rtl::OUString sError( getConnection()->getResources().getResourceStringWithSubstitution(
2393 : : STR_COLUMN_NOT_ADDABLE,
2394 [ # # ][ # # ]: 0 : "$columnname$", ::comphelper::getString(_xNewColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_NAME)))
2395 [ # # ][ # # ]: 0 : ) );
[ # # # # ]
2396 [ # # ][ # # ]: 0 : ::dbtools::throwGenericSQLException( sError, *this );
2397 : : }
2398 : :
2399 : 0 : sal_Bool bAlreadyDroped = sal_False;
2400 : : try
2401 : : {
2402 [ # # ]: 0 : pNewTable->construct();
2403 : : // copy the data
2404 [ # # ][ # # ]: 0 : copyData(pNewTable,pNewTable->m_pColumns->getCount());
2405 : : // drop the old table
2406 [ # # ][ # # ]: 0 : if(DropImpl())
2407 : : {
2408 : 0 : bAlreadyDroped = sal_True;
2409 [ # # ]: 0 : pNewTable->renameImpl(m_Name);
2410 : : // release the temp file
2411 : : }
2412 [ # # ][ # # ]: 0 : xHold = pNewTable = NULL;
2413 : :
2414 [ # # ]: 0 : FileClose();
2415 [ # # ]: 0 : construct();
2416 [ # # ]: 0 : if(m_pColumns)
2417 [ # # ]: 0 : m_pColumns->refresh();
2418 : : }
2419 [ # # ]: 0 : catch(const SQLException&)
2420 : : {
2421 : : // here we know that the old table wasn't droped before
2422 [ # # ]: 0 : if(!bAlreadyDroped)
2423 [ # # # # ]: 0 : xHold = pNewTable = NULL;
2424 : :
2425 : 0 : throw;
2426 [ # # ]: 0 : }
2427 : 0 : }
2428 : : // -----------------------------------------------------------------------------
2429 : 0 : void ODbaseTable::dropColumn(sal_Int32 _nPos)
2430 : : {
2431 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ODbaseTable::dropColumn" );
2432 [ # # ]: 0 : String sTempName = createTempFile();
2433 : :
2434 [ # # ]: 0 : ODbaseTable* pNewTable = new ODbaseTable(m_pTables,static_cast<ODbaseConnection*>(m_pConnection));
2435 [ # # ][ # # ]: 0 : Reference< XPropertySet > xHold = pNewTable;
2436 [ # # ][ # # ]: 0 : pNewTable->setPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_NAME),makeAny(::rtl::OUString(sTempName)));
[ # # ][ # # ]
[ # # ]
2437 : : {
2438 [ # # ][ # # ]: 0 : Reference<XAppend> xAppend(pNewTable->getColumns(),UNO_QUERY);
2439 [ # # ][ # # ]: 0 : sal_Bool bCase = getConnection()->getMetaData()->supportsMixedCaseQuotedIdentifiers();
[ # # ]
2440 : : // copy the structure
2441 [ # # ][ # # ]: 0 : for(sal_Int32 i=0;i < m_pColumns->getCount();++i)
2442 : : {
2443 [ # # ]: 0 : if(_nPos != i)
2444 : : {
2445 : 0 : Reference<XPropertySet> xProp;
2446 [ # # ][ # # ]: 0 : m_pColumns->getByIndex(i) >>= xProp;
2447 [ # # ]: 0 : Reference<XDataDescriptorFactory> xColumn(xProp,UNO_QUERY);
2448 : 0 : Reference<XPropertySet> xCpy;
2449 [ # # ]: 0 : if(xColumn.is())
2450 [ # # ][ # # ]: 0 : xCpy = xColumn->createDataDescriptor();
[ # # ]
2451 : : else
2452 : : {
2453 [ # # ][ # # ]: 0 : xCpy = new OColumn(bCase);
[ # # ]
2454 [ # # ]: 0 : ::comphelper::copyProperties(xProp,xCpy);
2455 : : }
2456 [ # # ][ # # ]: 0 : xAppend->appendByDescriptor(xCpy);
2457 : : }
2458 : 0 : }
2459 : : }
2460 : :
2461 : : // construct the new table
2462 [ # # ][ # # ]: 0 : if(!pNewTable->CreateImpl())
2463 : : {
2464 [ # # ][ # # ]: 0 : xHold = pNewTable = NULL;
2465 : 0 : const ::rtl::OUString sError( getConnection()->getResources().getResourceStringWithSubstitution(
2466 : : STR_COLUMN_NOT_DROP,
2467 : : "$position$", ::rtl::OUString::valueOf(_nPos)
2468 [ # # ]: 0 : ) );
2469 [ # # ][ # # ]: 0 : ::dbtools::throwGenericSQLException( sError, *this );
2470 : : }
2471 [ # # ]: 0 : pNewTable->construct();
2472 : : // copy the data
2473 [ # # ]: 0 : copyData(pNewTable,_nPos);
2474 : : // drop the old table
2475 [ # # ][ # # ]: 0 : if(DropImpl())
2476 [ # # ]: 0 : pNewTable->renameImpl(m_Name);
2477 : : // release the temp file
2478 : :
2479 [ # # ][ # # ]: 0 : xHold = pNewTable = NULL;
2480 : :
2481 [ # # ]: 0 : FileClose();
2482 [ # # ][ # # ]: 0 : construct();
2483 : 0 : }
2484 : : // -----------------------------------------------------------------------------
2485 : 0 : String ODbaseTable::createTempFile()
2486 : : {
2487 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ODbaseTable::createTempFile" );
2488 [ # # ][ # # ]: 0 : ::rtl::OUString aIdent = m_pConnection->getContent()->getIdentifier()->getContentIdentifier();
[ # # ][ # # ]
[ # # ]
2489 [ # # ]: 0 : if ( aIdent.lastIndexOf('/') != (aIdent.getLength()-1) )
2490 : 0 : aIdent += ::rtl::OUString("/");
2491 [ # # ]: 0 : String sTempName(aIdent);
2492 [ # # ]: 0 : String sExt;
2493 [ # # ]: 0 : sExt.AssignAscii(".");
2494 [ # # ]: 0 : sExt += m_pConnection->getExtension();
2495 : :
2496 [ # # ]: 0 : String sName(m_Name);
2497 [ # # ]: 0 : TempFile aTempFile(sName,&sExt,&sTempName);
2498 [ # # ][ # # ]: 0 : if(!aTempFile.IsValid())
2499 [ # # ][ # # ]: 0 : getConnection()->throwGenericSQLException(STR_COULD_NOT_ALTER_TABLE,*this);
2500 : :
2501 [ # # ]: 0 : INetURLObject aURL;
2502 : 0 : aURL.SetSmartProtocol(INET_PROT_FILE);
2503 [ # # ][ # # ]: 0 : aURL.SetURL(aTempFile.GetURL());
[ # # ][ # # ]
2504 : :
2505 [ # # ][ # # ]: 0 : String sNewName(aURL.getName());
2506 [ # # ]: 0 : sNewName.Erase(sNewName.Len() - sExt.Len());
2507 [ # # ][ # # ]: 0 : return sNewName;
[ # # ][ # # ]
[ # # ]
2508 : : }
2509 : : // -----------------------------------------------------------------------------
2510 : 0 : void ODbaseTable::copyData(ODbaseTable* _pNewTable,sal_Int32 _nPos)
2511 : : {
2512 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ODbaseTable::copyData" );
2513 : 0 : sal_Int32 nPos = _nPos + 1; // +1 because we always have the bookmark clumn as well
2514 [ # # ][ # # ]: 0 : OValueRefRow aRow = new OValueRefVector(m_pColumns->getCount());
[ # # ]
2515 : 0 : OValueRefRow aInsertRow;
2516 [ # # ]: 0 : if(_nPos)
2517 : : {
2518 [ # # ][ # # ]: 0 : aInsertRow = new OValueRefVector(_pNewTable->m_pColumns->getCount());
[ # # ]
2519 [ # # ]: 0 : ::std::for_each(aInsertRow->get().begin(),aInsertRow->get().end(),TSetRefBound(sal_True));
2520 : : }
2521 : : else
2522 [ # # ]: 0 : aInsertRow = aRow;
2523 : :
2524 : : // we only have to bind the values which we need to copy into the new table
2525 [ # # ]: 0 : ::std::for_each(aRow->get().begin(),aRow->get().end(),TSetRefBound(sal_True));
2526 [ # # ][ # # ]: 0 : if(_nPos && (_nPos < (sal_Int32)aRow->get().size()))
[ # # ]
2527 : 0 : (aRow->get())[nPos]->setBound(sal_False);
2528 : :
2529 : :
2530 : 0 : sal_Bool bOk = sal_True;
2531 : : sal_Int32 nCurPos;
2532 : 0 : OValueRefVector::Vector::iterator aIter;
2533 [ # # ]: 0 : for(sal_uInt32 nRowPos = 0; nRowPos < m_aHeader.db_anz;++nRowPos)
2534 : : {
2535 [ # # ]: 0 : bOk = seekRow( IResultSetHelper::BOOKMARK, nRowPos+1, nCurPos );
2536 [ # # ]: 0 : if ( bOk )
2537 : : {
2538 [ # # ]: 0 : bOk = fetchRow( aRow, *m_aColumns, sal_True, sal_True);
2539 [ # # ][ # # ]: 0 : if ( bOk && !aRow->isDeleted() ) // copy only not deleted rows
[ # # ]
2540 : : {
2541 : : // special handling when pos == 0 then we don't have to distinguish between the two rows
2542 [ # # ]: 0 : if(_nPos)
2543 : : {
2544 [ # # ]: 0 : aIter = aRow->get().begin()+1;
2545 : 0 : sal_Int32 nCount = 1;
2546 [ # # ][ # # ]: 0 : for(OValueRefVector::Vector::iterator aInsertIter = aInsertRow->get().begin()+1; aIter != aRow->get().end() && aInsertIter != aInsertRow->get().end();++aIter,++nCount)
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # # # ]
2547 : : {
2548 [ # # ]: 0 : if(nPos != nCount)
2549 : : {
2550 [ # # ]: 0 : (*aInsertIter)->setValue( (*aIter)->getValue() );
2551 : 0 : ++aInsertIter;
2552 : : }
2553 : : }
2554 : : }
2555 [ # # ][ # # ]: 0 : bOk = _pNewTable->InsertRow(*aInsertRow,sal_True,_pNewTable->m_pColumns);
[ # # ]
2556 : : OSL_ENSURE(bOk,"Row could not be inserted!");
2557 : : }
2558 : : else
2559 : : OSL_ENSURE(bOk,"Row could not be fetched!");
2560 : : }
2561 : : else
2562 : : {
2563 : : OSL_ASSERT(0);
2564 : : }
2565 [ # # ][ # # ]: 0 : } // for(sal_uInt32 nRowPos = 0; nRowPos < m_aHeader.db_anz;++nRowPos)
2566 : 0 : }
2567 : : // -----------------------------------------------------------------------------
2568 : 0 : void ODbaseTable::throwInvalidDbaseFormat()
2569 : : {
2570 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ODbaseTable::throwInvalidDbaseFormat" );
2571 [ # # ]: 0 : FileClose();
2572 : : // no dbase file
2573 : :
2574 : 0 : const ::rtl::OUString sError( getConnection()->getResources().getResourceStringWithSubstitution(
2575 : : STR_INVALID_DBASE_FILE,
2576 : : "$filename$", getEntry(m_pConnection,m_Name)
2577 [ # # ]: 0 : ) );
[ # # # # ]
[ # # ]
2578 [ # # ][ # # ]: 0 : ::dbtools::throwGenericSQLException( sError, *this );
2579 : 0 : }
2580 : : // -----------------------------------------------------------------------------
2581 : 40 : void ODbaseTable::refreshHeader()
2582 : : {
2583 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ODbaseTable::refreshHeader" );
2584 [ - + ]: 40 : if ( m_aHeader.db_anz == 0 )
2585 : 0 : readHeader();
2586 : 40 : }
2587 : : //------------------------------------------------------------------
2588 : 3148 : sal_Bool ODbaseTable::seekRow(IResultSetHelper::Movement eCursorPosition, sal_Int32 nOffset, sal_Int32& nCurPos)
2589 : : {
2590 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ODbaseTable::seekRow" );
2591 : : // ----------------------------------------------------------
2592 : : // prepare positioning:
2593 : : OSL_ENSURE(m_pFileStream,"ODbaseTable::seekRow: FileStream is NULL!");
2594 : :
2595 : 3148 : sal_uInt32 nNumberOfRecords = (sal_uInt32)m_aHeader.db_anz;
2596 : 3148 : sal_uInt32 nTempPos = m_nFilePos;
2597 : 3148 : m_nFilePos = nCurPos;
2598 : :
2599 [ + - - - : 3148 : switch(eCursorPosition)
- + - ]
2600 : : {
2601 : : case IResultSetHelper::NEXT:
2602 : 260 : ++m_nFilePos;
2603 : 260 : break;
2604 : : case IResultSetHelper::PRIOR:
2605 [ # # ]: 0 : if (m_nFilePos > 0)
2606 : 0 : --m_nFilePos;
2607 : 0 : break;
2608 : : case IResultSetHelper::FIRST:
2609 : 0 : m_nFilePos = 1;
2610 : 0 : break;
2611 : : case IResultSetHelper::LAST:
2612 : 0 : m_nFilePos = nNumberOfRecords;
2613 : 0 : break;
2614 : : case IResultSetHelper::RELATIVE:
2615 : : m_nFilePos = (((sal_Int32)m_nFilePos) + nOffset < 0) ? 0L
2616 : 0 : : (sal_uInt32)(((sal_Int32)m_nFilePos) + nOffset);
2617 : 0 : break;
2618 : : case IResultSetHelper::ABSOLUTE:
2619 : : case IResultSetHelper::BOOKMARK:
2620 : 2888 : m_nFilePos = (sal_uInt32)nOffset;
2621 : 2888 : break;
2622 : : }
2623 : :
2624 [ - + ]: 3148 : if (m_nFilePos > (sal_Int32)nNumberOfRecords)
2625 : 0 : m_nFilePos = (sal_Int32)nNumberOfRecords + 1;
2626 : :
2627 [ + - ][ + - ]: 3148 : if (m_nFilePos == 0 || m_nFilePos == (sal_Int32)nNumberOfRecords + 1)
2628 : : goto Error;
2629 : : else
2630 : : {
2631 : 3148 : sal_uInt16 nEntryLen = m_aHeader.db_slng;
2632 : :
2633 : : OSL_ENSURE(m_nFilePos >= 1,"SdbDBFCursor::FileFetchRow: ungueltige Record-Position");
2634 : 3148 : sal_Int32 nPos = m_aHeader.db_kopf + (sal_Int32)(m_nFilePos-1) * nEntryLen;
2635 : :
2636 : 3148 : m_pFileStream->Seek(nPos);
2637 [ - + ]: 3148 : if (m_pFileStream->GetError() != ERRCODE_NONE)
2638 : 0 : goto Error;
2639 : :
2640 : 3148 : m_pFileStream->Read((char*)m_pBuffer, nEntryLen);
2641 [ - + ]: 3148 : if (m_pFileStream->GetError() != ERRCODE_NONE)
2642 : 0 : goto Error;
2643 : : }
2644 : 3148 : goto End;
2645 : :
2646 : : Error:
2647 [ # # # # ]: 0 : switch(eCursorPosition)
2648 : : {
2649 : : case IResultSetHelper::PRIOR:
2650 : : case IResultSetHelper::FIRST:
2651 : 0 : m_nFilePos = 0;
2652 : 0 : break;
2653 : : case IResultSetHelper::LAST:
2654 : : case IResultSetHelper::NEXT:
2655 : : case IResultSetHelper::ABSOLUTE:
2656 : : case IResultSetHelper::RELATIVE:
2657 [ # # ]: 0 : if (nOffset > 0)
2658 : 0 : m_nFilePos = nNumberOfRecords + 1;
2659 [ # # ]: 0 : else if (nOffset < 0)
2660 : 0 : m_nFilePos = 0;
2661 : 0 : break;
2662 : : case IResultSetHelper::BOOKMARK:
2663 : 0 : m_nFilePos = nTempPos; // last position
2664 : : }
2665 : 0 : return sal_False;
2666 : :
2667 : : End:
2668 : 3148 : nCurPos = m_nFilePos;
2669 : 3148 : return sal_True;
2670 : : }
2671 : : // -----------------------------------------------------------------------------
2672 : 19118 : sal_Bool ODbaseTable::ReadMemo(sal_uIntPtr nBlockNo, ORowSetValue& aVariable)
2673 : : {
2674 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ODbaseTable::ReadMemo" );
2675 : 19118 : bool bIsText = true;
2676 : :
2677 : 19118 : m_pMemoStream->Seek(nBlockNo * m_aMemoHeader.db_size);
2678 [ + - - ]: 19118 : switch (m_aMemoHeader.db_typ)
2679 : : {
2680 : : case MemodBaseIII: // dBase III-Memofield, ends with Ctrl-Z
2681 : : {
2682 : 19118 : const char cEOF = (char) DBF_EOL;
2683 : 19118 : rtl::OStringBuffer aBStr;
2684 : : static char aBuf[514];
2685 : 19118 : aBuf[512] = 0; // avoid random value
2686 : 19118 : sal_Bool bReady = sal_False;
2687 : :
2688 [ - + # # ]: 19118 : do
[ - + ]
2689 : : {
2690 [ + - ]: 19118 : m_pMemoStream->Read(&aBuf,512);
2691 : :
2692 : 19118 : sal_uInt16 i = 0;
2693 [ + + ][ + - ]: 156188 : while (aBuf[i] != cEOF && ++i < 512)
[ + + ]
2694 : : ;
2695 : 19118 : bReady = aBuf[i] == cEOF;
2696 : :
2697 : 19118 : aBuf[i] = 0;
2698 [ + - ]: 19118 : aBStr.append(aBuf);
2699 : :
2700 : 0 : } while (!bReady && !m_pMemoStream->IsEof());
2701 : :
2702 : : aVariable = rtl::OStringToOUString(aBStr.makeStringAndClear(),
2703 [ + - ][ + - ]: 19118 : m_eEncoding);
2704 : :
2705 : 19118 : } break;
2706 : : case MemoFoxPro:
2707 : : case MemodBaseIV: // dBase IV-Memofield with length
2708 : : {
2709 : : char sHeader[4];
2710 [ # # ]: 0 : m_pMemoStream->Read(sHeader,4);
2711 : : // Foxpro stores text and binary data
2712 [ # # ]: 0 : if (m_aMemoHeader.db_typ == MemoFoxPro)
2713 : : {
2714 : 0 : bIsText = sHeader[3] != 0;
2715 : : }
2716 [ # # ][ # # ]: 0 : else if (((sal_uInt8)sHeader[0]) != 0xFF || ((sal_uInt8)sHeader[1]) != 0xFF || ((sal_uInt8)sHeader[2]) != 0x08)
[ # # ]
2717 : : {
2718 : 0 : return sal_False;
2719 : : }
2720 : :
2721 : 0 : sal_uInt32 nLength(0);
2722 [ # # ]: 0 : (*m_pMemoStream) >> nLength;
2723 : :
2724 [ # # ]: 0 : if (m_aMemoHeader.db_typ == MemodBaseIV)
2725 : 0 : nLength -= 8;
2726 : :
2727 [ # # ]: 0 : if ( nLength )
2728 : : {
2729 [ # # ]: 0 : if ( bIsText )
2730 : : {
2731 [ # # ][ # # ]: 0 : rtl::OStringBuffer aBuffer(read_uInt8s_ToOString(*m_pMemoStream, nLength));
2732 : : //pad it out with ' ' to expected length on short read
2733 : 0 : sal_Int32 nRequested = sal::static_int_cast<sal_Int32>(nLength);
2734 [ # # ]: 0 : comphelper::string::padToLength(aBuffer, nRequested, ' ');
2735 [ # # ][ # # ]: 0 : aVariable = rtl::OStringToOUString(aBuffer.makeStringAndClear(), m_eEncoding);
2736 : : } // if ( bIsText )
2737 : : else
2738 : : {
2739 [ # # ]: 0 : ::com::sun::star::uno::Sequence< sal_Int8 > aData(nLength);
2740 [ # # ][ # # ]: 0 : m_pMemoStream->Read(aData.getArray(),nLength);
2741 [ # # ][ # # ]: 0 : aVariable = aData;
2742 : : }
2743 : : } // if ( nLength )
2744 : : }
2745 : : }
2746 : 19118 : return sal_True;
2747 : : }
2748 : : // -----------------------------------------------------------------------------
2749 : 38 : void ODbaseTable::AllocBuffer()
2750 : : {
2751 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ODbaseTable::AllocBuffer" );
2752 : 38 : sal_uInt16 nSize = m_aHeader.db_slng;
2753 : : OSL_ENSURE(nSize > 0, "Size too small");
2754 : :
2755 [ + + ]: 38 : if (m_nBufferSize != nSize)
2756 : : {
2757 : 28 : delete m_pBuffer;
2758 : 28 : m_pBuffer = NULL;
2759 : : }
2760 : :
2761 : : // if there is no buffer available: allocate:
2762 [ + + ][ + - ]: 38 : if (m_pBuffer == NULL && nSize > 0)
2763 : : {
2764 : 28 : m_nBufferSize = nSize;
2765 : 28 : m_pBuffer = new sal_uInt8[m_nBufferSize+1];
2766 : : }
2767 : 38 : }
2768 : : // -----------------------------------------------------------------------------
2769 : 10 : sal_Bool ODbaseTable::WriteBuffer()
2770 : : {
2771 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ODbaseTable::WriteBuffer" );
2772 : : OSL_ENSURE(m_nFilePos >= 1,"SdbDBFCursor::FileFetchRow: ungueltige Record-Position");
2773 : :
2774 : : // postion on desired record:
2775 : 10 : long nPos = m_aHeader.db_kopf + (long)(m_nFilePos-1) * m_aHeader.db_slng;
2776 : 10 : m_pFileStream->Seek(nPos);
2777 : 10 : return m_pFileStream->Write((char*) m_pBuffer, m_aHeader.db_slng) > 0;
2778 : : }
2779 : : // -----------------------------------------------------------------------------
2780 : 40 : sal_Int32 ODbaseTable::getCurrentLastPos() const
2781 : : {
2782 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ODbaseTable::getCurrentLastPos" );
2783 : 40 : return m_aHeader.db_anz;
2784 : : }
2785 : :
2786 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|