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