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 "dbase/DIndex.hxx" 32*cdf0e10cSrcweir #include "dbase/dindexnode.hxx" 33*cdf0e10cSrcweir #include <tools/debug.hxx> 34*cdf0e10cSrcweir #include "diagnose_ex.h" 35*cdf0e10cSrcweir 36*cdf0e10cSrcweir #include <sal/types.h> 37*cdf0e10cSrcweir #include <algorithm> 38*cdf0e10cSrcweir #include <rtl/logfile.hxx> 39*cdf0e10cSrcweir 40*cdf0e10cSrcweir using namespace connectivity; 41*cdf0e10cSrcweir using namespace connectivity::dbase; 42*cdf0e10cSrcweir using namespace com::sun::star::uno; 43*cdf0e10cSrcweir using namespace com::sun::star::sdbc; 44*cdf0e10cSrcweir //------------------------------------------------------------------ 45*cdf0e10cSrcweir sal_Bool ODbaseTable::seekRow(IResultSetHelper::Movement eCursorPosition, sal_Int32 nOffset, sal_Int32& nCurPos) 46*cdf0e10cSrcweir { 47*cdf0e10cSrcweir RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ODbaseTable::seekRow" ); 48*cdf0e10cSrcweir // ---------------------------------------------------------- 49*cdf0e10cSrcweir // Positionierung vorbereiten: 50*cdf0e10cSrcweir OSL_ENSURE(m_pFileStream,"ODbaseTable::seekRow: FileStream is NULL!"); 51*cdf0e10cSrcweir 52*cdf0e10cSrcweir sal_uInt32 nNumberOfRecords = (sal_uInt32)m_aHeader.db_anz; 53*cdf0e10cSrcweir sal_uInt32 nTempPos = m_nFilePos; 54*cdf0e10cSrcweir m_nFilePos = nCurPos; 55*cdf0e10cSrcweir 56*cdf0e10cSrcweir switch(eCursorPosition) 57*cdf0e10cSrcweir { 58*cdf0e10cSrcweir case IResultSetHelper::NEXT: 59*cdf0e10cSrcweir ++m_nFilePos; 60*cdf0e10cSrcweir break; 61*cdf0e10cSrcweir case IResultSetHelper::PRIOR: 62*cdf0e10cSrcweir if (m_nFilePos > 0) 63*cdf0e10cSrcweir --m_nFilePos; 64*cdf0e10cSrcweir break; 65*cdf0e10cSrcweir case IResultSetHelper::FIRST: 66*cdf0e10cSrcweir m_nFilePos = 1; 67*cdf0e10cSrcweir break; 68*cdf0e10cSrcweir case IResultSetHelper::LAST: 69*cdf0e10cSrcweir m_nFilePos = nNumberOfRecords; 70*cdf0e10cSrcweir break; 71*cdf0e10cSrcweir case IResultSetHelper::RELATIVE: 72*cdf0e10cSrcweir m_nFilePos = (((sal_Int32)m_nFilePos) + nOffset < 0) ? 0L 73*cdf0e10cSrcweir : (sal_uInt32)(((sal_Int32)m_nFilePos) + nOffset); 74*cdf0e10cSrcweir break; 75*cdf0e10cSrcweir case IResultSetHelper::ABSOLUTE: 76*cdf0e10cSrcweir case IResultSetHelper::BOOKMARK: 77*cdf0e10cSrcweir m_nFilePos = (sal_uInt32)nOffset; 78*cdf0e10cSrcweir break; 79*cdf0e10cSrcweir } 80*cdf0e10cSrcweir 81*cdf0e10cSrcweir if (m_nFilePos > (sal_Int32)nNumberOfRecords) 82*cdf0e10cSrcweir m_nFilePos = (sal_Int32)nNumberOfRecords + 1; 83*cdf0e10cSrcweir 84*cdf0e10cSrcweir if (m_nFilePos == 0 || m_nFilePos == (sal_Int32)nNumberOfRecords + 1) 85*cdf0e10cSrcweir goto Error; 86*cdf0e10cSrcweir else 87*cdf0e10cSrcweir { 88*cdf0e10cSrcweir sal_uInt16 nEntryLen = m_aHeader.db_slng; 89*cdf0e10cSrcweir 90*cdf0e10cSrcweir OSL_ENSURE(m_nFilePos >= 1,"SdbDBFCursor::FileFetchRow: ungueltige Record-Position"); 91*cdf0e10cSrcweir sal_Int32 nPos = m_aHeader.db_kopf + (sal_Int32)(m_nFilePos-1) * nEntryLen; 92*cdf0e10cSrcweir 93*cdf0e10cSrcweir sal_uIntPtr nLen = m_pFileStream->Seek(nPos); 94*cdf0e10cSrcweir if (m_pFileStream->GetError() != ERRCODE_NONE) 95*cdf0e10cSrcweir goto Error; 96*cdf0e10cSrcweir 97*cdf0e10cSrcweir nLen = m_pFileStream->Read((char*)m_pBuffer, nEntryLen); 98*cdf0e10cSrcweir if (m_pFileStream->GetError() != ERRCODE_NONE) 99*cdf0e10cSrcweir goto Error; 100*cdf0e10cSrcweir } 101*cdf0e10cSrcweir goto End; 102*cdf0e10cSrcweir 103*cdf0e10cSrcweir Error: 104*cdf0e10cSrcweir switch(eCursorPosition) 105*cdf0e10cSrcweir { 106*cdf0e10cSrcweir case IResultSetHelper::PRIOR: 107*cdf0e10cSrcweir case IResultSetHelper::FIRST: 108*cdf0e10cSrcweir m_nFilePos = 0; 109*cdf0e10cSrcweir break; 110*cdf0e10cSrcweir case IResultSetHelper::LAST: 111*cdf0e10cSrcweir case IResultSetHelper::NEXT: 112*cdf0e10cSrcweir case IResultSetHelper::ABSOLUTE: 113*cdf0e10cSrcweir case IResultSetHelper::RELATIVE: 114*cdf0e10cSrcweir if (nOffset > 0) 115*cdf0e10cSrcweir m_nFilePos = nNumberOfRecords + 1; 116*cdf0e10cSrcweir else if (nOffset < 0) 117*cdf0e10cSrcweir m_nFilePos = 0; 118*cdf0e10cSrcweir break; 119*cdf0e10cSrcweir case IResultSetHelper::BOOKMARK: 120*cdf0e10cSrcweir m_nFilePos = nTempPos; // vorherige Position 121*cdf0e10cSrcweir } 122*cdf0e10cSrcweir // aStatus.Set(SDB_STAT_NO_DATA_FOUND); 123*cdf0e10cSrcweir return sal_False; 124*cdf0e10cSrcweir 125*cdf0e10cSrcweir End: 126*cdf0e10cSrcweir nCurPos = m_nFilePos; 127*cdf0e10cSrcweir return sal_True; 128*cdf0e10cSrcweir } 129*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 130*cdf0e10cSrcweir sal_Bool ODbaseTable::ReadMemo(sal_uIntPtr nBlockNo, ORowSetValue& aVariable) 131*cdf0e10cSrcweir { 132*cdf0e10cSrcweir RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ODbaseTable::ReadMemo" ); 133*cdf0e10cSrcweir sal_Bool bIsText = sal_True; 134*cdf0e10cSrcweir // SdbConnection* pConnection = GetConnection(); 135*cdf0e10cSrcweir 136*cdf0e10cSrcweir m_pMemoStream->Seek(nBlockNo * m_aMemoHeader.db_size); 137*cdf0e10cSrcweir switch (m_aMemoHeader.db_typ) 138*cdf0e10cSrcweir { 139*cdf0e10cSrcweir case MemodBaseIII: // dBase III-Memofeld, endet mit Ctrl-Z 140*cdf0e10cSrcweir { 141*cdf0e10cSrcweir const char cEOF = (char) 0x1a; 142*cdf0e10cSrcweir ByteString aBStr; 143*cdf0e10cSrcweir static char aBuf[514]; 144*cdf0e10cSrcweir aBuf[512] = 0; // sonst kann der Zufall uebel mitspielen 145*cdf0e10cSrcweir sal_Bool bReady = sal_False; 146*cdf0e10cSrcweir 147*cdf0e10cSrcweir do 148*cdf0e10cSrcweir { 149*cdf0e10cSrcweir m_pMemoStream->Read(&aBuf,512); 150*cdf0e10cSrcweir 151*cdf0e10cSrcweir sal_uInt16 i = 0; 152*cdf0e10cSrcweir while (aBuf[i] != cEOF && ++i < 512) 153*cdf0e10cSrcweir ; 154*cdf0e10cSrcweir bReady = aBuf[i] == cEOF; 155*cdf0e10cSrcweir 156*cdf0e10cSrcweir aBuf[i] = 0; 157*cdf0e10cSrcweir aBStr += aBuf; 158*cdf0e10cSrcweir 159*cdf0e10cSrcweir } while (!bReady && !m_pMemoStream->IsEof() && aBStr.Len() < STRING_MAXLEN); 160*cdf0e10cSrcweir 161*cdf0e10cSrcweir ::rtl::OUString aStr(aBStr.GetBuffer(), aBStr.Len(),getConnection()->getTextEncoding()); 162*cdf0e10cSrcweir aVariable = aStr; 163*cdf0e10cSrcweir 164*cdf0e10cSrcweir } break; 165*cdf0e10cSrcweir case MemoFoxPro: 166*cdf0e10cSrcweir case MemodBaseIV: // dBase IV-Memofeld mit Laengenangabe 167*cdf0e10cSrcweir { 168*cdf0e10cSrcweir char sHeader[4]; 169*cdf0e10cSrcweir m_pMemoStream->Read(sHeader,4); 170*cdf0e10cSrcweir // Foxpro stores text and binary data 171*cdf0e10cSrcweir if (m_aMemoHeader.db_typ == MemoFoxPro) 172*cdf0e10cSrcweir { 173*cdf0e10cSrcweir if (((sal_uInt8)sHeader[0]) != 0 || ((sal_uInt8)sHeader[1]) != 0 || ((sal_uInt8)sHeader[2]) != 0) 174*cdf0e10cSrcweir { 175*cdf0e10cSrcweir // String aText = String(SdbResId(STR_STAT_IResultSetHelper::INVALID)); 176*cdf0e10cSrcweir // aText.SearchAndReplace(String::CreateFromAscii("%%d"),m_pMemoStream->GetFileName()); 177*cdf0e10cSrcweir // aText.SearchAndReplace(String::CreateFromAscii("%%t"),aStatus.TypeToString(MEMO)); 178*cdf0e10cSrcweir // aStatus.Set(SDB_STAT_ERROR, 179*cdf0e10cSrcweir // String::CreateFromAscii("01000"), 180*cdf0e10cSrcweir // aStatus.CreateErrorMessage(aText), 181*cdf0e10cSrcweir // 0, String() ); 182*cdf0e10cSrcweir return sal_False; 183*cdf0e10cSrcweir } 184*cdf0e10cSrcweir 185*cdf0e10cSrcweir bIsText = sHeader[3] != 0; 186*cdf0e10cSrcweir } 187*cdf0e10cSrcweir else if (((sal_uInt8)sHeader[0]) != 0xFF || ((sal_uInt8)sHeader[1]) != 0xFF || ((sal_uInt8)sHeader[2]) != 0x08) 188*cdf0e10cSrcweir { 189*cdf0e10cSrcweir // String aText = String(SdbResId(STR_STAT_IResultSetHelper::INVALID)); 190*cdf0e10cSrcweir // aText.SearchAndReplace(String::CreateFromAscii("%%d"),m_pMemoStream->GetFileName()); 191*cdf0e10cSrcweir // aText.SearchAndReplace(String::CreateFromAscii("%%t"),aStatus.TypeToString(MEMO)); 192*cdf0e10cSrcweir // aStatus.Set(SDB_STAT_ERROR, 193*cdf0e10cSrcweir // String::CreateFromAscii("01000"), 194*cdf0e10cSrcweir // aStatus.CreateErrorMessage(aText), 195*cdf0e10cSrcweir // 0, String() ); 196*cdf0e10cSrcweir return sal_False; 197*cdf0e10cSrcweir } 198*cdf0e10cSrcweir 199*cdf0e10cSrcweir sal_uInt32 nLength; 200*cdf0e10cSrcweir (*m_pMemoStream) >> nLength; 201*cdf0e10cSrcweir 202*cdf0e10cSrcweir if (m_aMemoHeader.db_typ == MemodBaseIV) 203*cdf0e10cSrcweir nLength -= 8; 204*cdf0e10cSrcweir 205*cdf0e10cSrcweir // char cChar; 206*cdf0e10cSrcweir ::rtl::OUString aStr; 207*cdf0e10cSrcweir while ( nLength > STRING_MAXLEN ) 208*cdf0e10cSrcweir { 209*cdf0e10cSrcweir ByteString aBStr; 210*cdf0e10cSrcweir aBStr.Expand(STRING_MAXLEN); 211*cdf0e10cSrcweir m_pMemoStream->Read(aBStr.AllocBuffer(STRING_MAXLEN),STRING_MAXLEN); 212*cdf0e10cSrcweir aStr += ::rtl::OUString(aBStr.GetBuffer(),aBStr.Len(), getConnection()->getTextEncoding()); 213*cdf0e10cSrcweir nLength -= STRING_MAXLEN; 214*cdf0e10cSrcweir } 215*cdf0e10cSrcweir if ( nLength > 0 ) 216*cdf0e10cSrcweir { 217*cdf0e10cSrcweir ByteString aBStr; 218*cdf0e10cSrcweir aBStr.Expand(static_cast<xub_StrLen>(nLength)); 219*cdf0e10cSrcweir m_pMemoStream->Read(aBStr.AllocBuffer(static_cast<xub_StrLen>(nLength)),nLength); 220*cdf0e10cSrcweir // aBStr.ReleaseBufferAccess(); 221*cdf0e10cSrcweir 222*cdf0e10cSrcweir aStr += ::rtl::OUString(aBStr.GetBuffer(),aBStr.Len(), getConnection()->getTextEncoding()); 223*cdf0e10cSrcweir 224*cdf0e10cSrcweir } 225*cdf0e10cSrcweir if ( aStr.getLength() ) 226*cdf0e10cSrcweir aVariable = aStr; 227*cdf0e10cSrcweir } 228*cdf0e10cSrcweir } 229*cdf0e10cSrcweir return sal_True; 230*cdf0e10cSrcweir } 231*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 232*cdf0e10cSrcweir void ODbaseTable::AllocBuffer() 233*cdf0e10cSrcweir { 234*cdf0e10cSrcweir RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ODbaseTable::AllocBuffer" ); 235*cdf0e10cSrcweir sal_uInt16 nSize = m_aHeader.db_slng; 236*cdf0e10cSrcweir OSL_ENSURE(nSize > 0, "Size too small"); 237*cdf0e10cSrcweir 238*cdf0e10cSrcweir if (m_nBufferSize != nSize) 239*cdf0e10cSrcweir { 240*cdf0e10cSrcweir delete[] m_pBuffer; 241*cdf0e10cSrcweir m_pBuffer = NULL; 242*cdf0e10cSrcweir } 243*cdf0e10cSrcweir 244*cdf0e10cSrcweir // Falls noch kein Puffer vorhanden: allozieren: 245*cdf0e10cSrcweir if (m_pBuffer == NULL && nSize > 0) 246*cdf0e10cSrcweir { 247*cdf0e10cSrcweir m_nBufferSize = nSize; 248*cdf0e10cSrcweir m_pBuffer = new sal_uInt8[m_nBufferSize+1]; 249*cdf0e10cSrcweir } 250*cdf0e10cSrcweir } 251*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 252*cdf0e10cSrcweir sal_Bool ODbaseTable::WriteBuffer() 253*cdf0e10cSrcweir { 254*cdf0e10cSrcweir RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ODbaseTable::WriteBuffer" ); 255*cdf0e10cSrcweir OSL_ENSURE(m_nFilePos >= 1,"SdbDBFCursor::FileFetchRow: ungueltige Record-Position"); 256*cdf0e10cSrcweir 257*cdf0e10cSrcweir // Auf gewuenschten Record positionieren: 258*cdf0e10cSrcweir long nPos = m_aHeader.db_kopf + (long)(m_nFilePos-1) * m_aHeader.db_slng; 259*cdf0e10cSrcweir m_pFileStream->Seek(nPos); 260*cdf0e10cSrcweir return m_pFileStream->Write((char*) m_pBuffer, m_aHeader.db_slng) > 0; 261*cdf0e10cSrcweir } 262*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 263*cdf0e10cSrcweir sal_Int32 ODbaseTable::getCurrentLastPos() const 264*cdf0e10cSrcweir { 265*cdf0e10cSrcweir RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ODbaseTable::getCurrentLastPos" ); 266*cdf0e10cSrcweir return m_aHeader.db_anz; 267*cdf0e10cSrcweir } 268*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 269*cdf0e10cSrcweir //================================================================== 270*cdf0e10cSrcweir // ONDXNode 271*cdf0e10cSrcweir //================================================================== 272*cdf0e10cSrcweir 273*cdf0e10cSrcweir //------------------------------------------------------------------ 274*cdf0e10cSrcweir void ONDXNode::Read(SvStream &rStream, ODbaseIndex& rIndex) 275*cdf0e10cSrcweir { 276*cdf0e10cSrcweir RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ONDXNode::Read" ); 277*cdf0e10cSrcweir rStream >> aKey.nRecord; // schluessel 278*cdf0e10cSrcweir 279*cdf0e10cSrcweir if (rIndex.getHeader().db_keytype) 280*cdf0e10cSrcweir { 281*cdf0e10cSrcweir double aDbl; 282*cdf0e10cSrcweir rStream >> aDbl; 283*cdf0e10cSrcweir aKey = ONDXKey(aDbl,aKey.nRecord); 284*cdf0e10cSrcweir } 285*cdf0e10cSrcweir else 286*cdf0e10cSrcweir { 287*cdf0e10cSrcweir ByteString aBuf; 288*cdf0e10cSrcweir sal_uInt16 nLen = rIndex.getHeader().db_keylen; 289*cdf0e10cSrcweir char* pStr = aBuf.AllocBuffer(nLen+1); 290*cdf0e10cSrcweir 291*cdf0e10cSrcweir rStream.Read(pStr,nLen); 292*cdf0e10cSrcweir pStr[nLen] = 0; 293*cdf0e10cSrcweir aBuf.ReleaseBufferAccess(); 294*cdf0e10cSrcweir aBuf.EraseTrailingChars(); 295*cdf0e10cSrcweir 296*cdf0e10cSrcweir // aKey = ONDXKey((aBuf,rIndex.GetDBFConnection()->GetCharacterSet()) ,aKey.nRecord); 297*cdf0e10cSrcweir aKey = ONDXKey(::rtl::OUString(aBuf.GetBuffer(),aBuf.Len(),rIndex.m_pTable->getConnection()->getTextEncoding()) ,aKey.nRecord); 298*cdf0e10cSrcweir } 299*cdf0e10cSrcweir rStream >> aChild; 300*cdf0e10cSrcweir } 301*cdf0e10cSrcweir 302*cdf0e10cSrcweir union 303*cdf0e10cSrcweir { 304*cdf0e10cSrcweir double aDbl; 305*cdf0e10cSrcweir char aData[128]; 306*cdf0e10cSrcweir } aNodeData; 307*cdf0e10cSrcweir //------------------------------------------------------------------ 308*cdf0e10cSrcweir void ONDXNode::Write(SvStream &rStream, const ONDXPage& rPage) const 309*cdf0e10cSrcweir { 310*cdf0e10cSrcweir RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ONDXNode::Write" ); 311*cdf0e10cSrcweir const ODbaseIndex& rIndex = rPage.GetIndex(); 312*cdf0e10cSrcweir if (!rIndex.isUnique() || rPage.IsLeaf()) 313*cdf0e10cSrcweir rStream << (sal_uInt32)aKey.nRecord; // schluessel 314*cdf0e10cSrcweir else 315*cdf0e10cSrcweir rStream << (sal_uInt32)0; // schluessel 316*cdf0e10cSrcweir 317*cdf0e10cSrcweir if (rIndex.getHeader().db_keytype) // double 318*cdf0e10cSrcweir { 319*cdf0e10cSrcweir if (aKey.getValue().isNull()) 320*cdf0e10cSrcweir { 321*cdf0e10cSrcweir memset(aNodeData.aData,0,rIndex.getHeader().db_keylen); 322*cdf0e10cSrcweir rStream.Write((sal_uInt8*)aNodeData.aData,rIndex.getHeader().db_keylen); 323*cdf0e10cSrcweir } 324*cdf0e10cSrcweir else 325*cdf0e10cSrcweir rStream << (double) aKey.getValue(); 326*cdf0e10cSrcweir } 327*cdf0e10cSrcweir else 328*cdf0e10cSrcweir { 329*cdf0e10cSrcweir memset(aNodeData.aData,0x20,rIndex.getHeader().db_keylen); 330*cdf0e10cSrcweir if (!aKey.getValue().isNull()) 331*cdf0e10cSrcweir { 332*cdf0e10cSrcweir ::rtl::OUString sValue = aKey.getValue(); 333*cdf0e10cSrcweir ByteString aText(sValue.getStr(), rIndex.m_pTable->getConnection()->getTextEncoding()); 334*cdf0e10cSrcweir strncpy(aNodeData.aData,aText.GetBuffer(),std::min(rIndex.getHeader().db_keylen, aText.Len())); 335*cdf0e10cSrcweir } 336*cdf0e10cSrcweir rStream.Write((sal_uInt8*)aNodeData.aData,rIndex.getHeader().db_keylen); 337*cdf0e10cSrcweir } 338*cdf0e10cSrcweir rStream << aChild; 339*cdf0e10cSrcweir } 340*cdf0e10cSrcweir 341*cdf0e10cSrcweir 342*cdf0e10cSrcweir //------------------------------------------------------------------ 343*cdf0e10cSrcweir ONDXPagePtr& ONDXNode::GetChild(ODbaseIndex* pIndex, ONDXPage* pParent) 344*cdf0e10cSrcweir { 345*cdf0e10cSrcweir RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ONDXNode::GetChild" ); 346*cdf0e10cSrcweir if (!aChild.Is() && pIndex) 347*cdf0e10cSrcweir { 348*cdf0e10cSrcweir aChild = pIndex->CreatePage(aChild.GetPagePos(),pParent,aChild.HasPage()); 349*cdf0e10cSrcweir } 350*cdf0e10cSrcweir return aChild; 351*cdf0e10cSrcweir } 352*cdf0e10cSrcweir 353*cdf0e10cSrcweir //================================================================== 354*cdf0e10cSrcweir // ONDXKey 355*cdf0e10cSrcweir //================================================================== 356*cdf0e10cSrcweir //------------------------------------------------------------------ 357*cdf0e10cSrcweir sal_Bool ONDXKey::IsText(sal_Int32 eType) 358*cdf0e10cSrcweir { 359*cdf0e10cSrcweir RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ONDXKey::IsText" ); 360*cdf0e10cSrcweir return eType == DataType::VARCHAR || eType == DataType::CHAR; 361*cdf0e10cSrcweir } 362*cdf0e10cSrcweir 363*cdf0e10cSrcweir //------------------------------------------------------------------ 364*cdf0e10cSrcweir StringCompare ONDXKey::Compare(const ONDXKey& rKey) const 365*cdf0e10cSrcweir { 366*cdf0e10cSrcweir RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ONDXKey::Compare" ); 367*cdf0e10cSrcweir // DBG_ASSERT(is(), "Falscher Indexzugriff"); 368*cdf0e10cSrcweir StringCompare eResult; 369*cdf0e10cSrcweir 370*cdf0e10cSrcweir if (getValue().isNull()) 371*cdf0e10cSrcweir { 372*cdf0e10cSrcweir if (rKey.getValue().isNull() || (rKey.IsText(getDBType()) && !rKey.getValue().getString().getLength())) 373*cdf0e10cSrcweir eResult = COMPARE_EQUAL; 374*cdf0e10cSrcweir else 375*cdf0e10cSrcweir eResult = COMPARE_LESS; 376*cdf0e10cSrcweir } 377*cdf0e10cSrcweir else if (rKey.getValue().isNull()) 378*cdf0e10cSrcweir { 379*cdf0e10cSrcweir if (getValue().isNull() || (IsText(getDBType()) && !getValue().getString().getLength())) 380*cdf0e10cSrcweir eResult = COMPARE_EQUAL; 381*cdf0e10cSrcweir else 382*cdf0e10cSrcweir eResult = COMPARE_GREATER; 383*cdf0e10cSrcweir } 384*cdf0e10cSrcweir else if (IsText(getDBType())) 385*cdf0e10cSrcweir { 386*cdf0e10cSrcweir sal_Int32 nRes = getValue().getString().compareTo(rKey.getValue()); 387*cdf0e10cSrcweir eResult = (nRes > 0) ? COMPARE_GREATER : (nRes == 0) ? COMPARE_EQUAL : COMPARE_LESS; 388*cdf0e10cSrcweir } 389*cdf0e10cSrcweir else 390*cdf0e10cSrcweir { 391*cdf0e10cSrcweir double m = getValue(),n = rKey.getValue(); 392*cdf0e10cSrcweir eResult = (m > n) ? COMPARE_GREATER : (n == m) ? COMPARE_EQUAL : COMPARE_LESS; 393*cdf0e10cSrcweir } 394*cdf0e10cSrcweir 395*cdf0e10cSrcweir // Record vergleich, wenn Index !Unique 396*cdf0e10cSrcweir if (eResult == COMPARE_EQUAL && nRecord && rKey.nRecord) 397*cdf0e10cSrcweir eResult = (nRecord > rKey.nRecord) ? COMPARE_GREATER : 398*cdf0e10cSrcweir (nRecord == rKey.nRecord) ? COMPARE_EQUAL : COMPARE_LESS; 399*cdf0e10cSrcweir 400*cdf0e10cSrcweir return eResult; 401*cdf0e10cSrcweir } 402*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 403*cdf0e10cSrcweir void ONDXKey::setValue(const ORowSetValue& _rVal) 404*cdf0e10cSrcweir { 405*cdf0e10cSrcweir RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ONDXKey::setValue" ); 406*cdf0e10cSrcweir xValue = _rVal; 407*cdf0e10cSrcweir } 408*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 409*cdf0e10cSrcweir const ORowSetValue& ONDXKey::getValue() const 410*cdf0e10cSrcweir { 411*cdf0e10cSrcweir RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ONDXKey::getValue" ); 412*cdf0e10cSrcweir return xValue; 413*cdf0e10cSrcweir } 414*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 415*cdf0e10cSrcweir SvStream& connectivity::dbase::operator >> (SvStream &rStream, ONDXPagePtr& rPage) 416*cdf0e10cSrcweir { 417*cdf0e10cSrcweir rStream >> rPage.nPagePos; 418*cdf0e10cSrcweir return rStream; 419*cdf0e10cSrcweir } 420*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 421*cdf0e10cSrcweir SvStream& connectivity::dbase::operator << (SvStream &rStream, const ONDXPagePtr& rPage) 422*cdf0e10cSrcweir { 423*cdf0e10cSrcweir rStream << rPage.nPagePos; 424*cdf0e10cSrcweir return rStream; 425*cdf0e10cSrcweir } 426*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 427*cdf0e10cSrcweir //================================================================== 428*cdf0e10cSrcweir // ONDXPagePtr 429*cdf0e10cSrcweir //================================================================== 430*cdf0e10cSrcweir //------------------------------------------------------------------ 431*cdf0e10cSrcweir ONDXPagePtr::ONDXPagePtr(const ONDXPagePtr& rRef) 432*cdf0e10cSrcweir :ONDXPageRef(rRef) 433*cdf0e10cSrcweir ,nPagePos(rRef.nPagePos) 434*cdf0e10cSrcweir { 435*cdf0e10cSrcweir RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ONDXPagePtr::ONDXPagePtr" ); 436*cdf0e10cSrcweir } 437*cdf0e10cSrcweir 438*cdf0e10cSrcweir //------------------------------------------------------------------ 439*cdf0e10cSrcweir ONDXPagePtr::ONDXPagePtr(ONDXPage* pRefPage) 440*cdf0e10cSrcweir :ONDXPageRef(pRefPage) 441*cdf0e10cSrcweir ,nPagePos(0) 442*cdf0e10cSrcweir { 443*cdf0e10cSrcweir RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ONDXPagePtr::ONDXPagePtr" ); 444*cdf0e10cSrcweir if (pRefPage) 445*cdf0e10cSrcweir nPagePos = pRefPage->GetPagePos(); 446*cdf0e10cSrcweir } 447*cdf0e10cSrcweir //------------------------------------------------------------------ 448*cdf0e10cSrcweir ONDXPagePtr& ONDXPagePtr::operator=(const ONDXPagePtr& rRef) 449*cdf0e10cSrcweir { 450*cdf0e10cSrcweir ONDXPageRef::operator=(rRef); 451*cdf0e10cSrcweir nPagePos = rRef.nPagePos; 452*cdf0e10cSrcweir return *this; 453*cdf0e10cSrcweir } 454*cdf0e10cSrcweir 455*cdf0e10cSrcweir //------------------------------------------------------------------ 456*cdf0e10cSrcweir ONDXPagePtr& ONDXPagePtr::operator= (ONDXPage* pRef) 457*cdf0e10cSrcweir { 458*cdf0e10cSrcweir ONDXPageRef::operator=(pRef); 459*cdf0e10cSrcweir nPagePos = (pRef) ? pRef->GetPagePos() : 0; 460*cdf0e10cSrcweir return *this; 461*cdf0e10cSrcweir } 462*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 463*cdf0e10cSrcweir static sal_uInt32 nValue; 464*cdf0e10cSrcweir //------------------------------------------------------------------ 465*cdf0e10cSrcweir SvStream& connectivity::dbase::operator >> (SvStream &rStream, ONDXPage& rPage) 466*cdf0e10cSrcweir { 467*cdf0e10cSrcweir rStream.Seek(rPage.GetPagePos() * 512); 468*cdf0e10cSrcweir rStream >> nValue >> rPage.aChild; 469*cdf0e10cSrcweir rPage.nCount = sal_uInt16(nValue); 470*cdf0e10cSrcweir 471*cdf0e10cSrcweir // DBG_ASSERT(rPage.nCount && rPage.nCount < rPage.GetIndex().GetMaxNodes(), "Falscher Count"); 472*cdf0e10cSrcweir for (sal_uInt16 i = 0; i < rPage.nCount; i++) 473*cdf0e10cSrcweir rPage[i].Read(rStream, rPage.GetIndex()); 474*cdf0e10cSrcweir return rStream; 475*cdf0e10cSrcweir } 476*cdf0e10cSrcweir 477*cdf0e10cSrcweir //------------------------------------------------------------------ 478*cdf0e10cSrcweir SvStream& connectivity::dbase::operator << (SvStream &rStream, const ONDXPage& rPage) 479*cdf0e10cSrcweir { 480*cdf0e10cSrcweir // Seite existiert noch nicht 481*cdf0e10cSrcweir sal_uIntPtr nSize = (rPage.GetPagePos() + 1) * 512; 482*cdf0e10cSrcweir if (nSize > rStream.Seek(STREAM_SEEK_TO_END)) 483*cdf0e10cSrcweir { 484*cdf0e10cSrcweir rStream.SetStreamSize(nSize); 485*cdf0e10cSrcweir rStream.Seek(rPage.GetPagePos() * 512); 486*cdf0e10cSrcweir 487*cdf0e10cSrcweir char aEmptyData[512]; 488*cdf0e10cSrcweir memset(aEmptyData,0x00,512); 489*cdf0e10cSrcweir rStream.Write((sal_uInt8*)aEmptyData,512); 490*cdf0e10cSrcweir } 491*cdf0e10cSrcweir sal_uIntPtr nCurrentPos = rStream.Seek(rPage.GetPagePos() * 512); 492*cdf0e10cSrcweir OSL_UNUSED( nCurrentPos ); 493*cdf0e10cSrcweir 494*cdf0e10cSrcweir nValue = rPage.nCount; 495*cdf0e10cSrcweir rStream << nValue << rPage.aChild; 496*cdf0e10cSrcweir 497*cdf0e10cSrcweir sal_uInt16 i = 0; 498*cdf0e10cSrcweir for (; i < rPage.nCount; i++) 499*cdf0e10cSrcweir rPage[i].Write(rStream, rPage); 500*cdf0e10cSrcweir 501*cdf0e10cSrcweir // check if we have to fill the stream with '\0' 502*cdf0e10cSrcweir if(i < rPage.rIndex.getHeader().db_maxkeys) 503*cdf0e10cSrcweir { 504*cdf0e10cSrcweir sal_uIntPtr nTell = rStream.Tell() % 512; 505*cdf0e10cSrcweir sal_uInt16 nBufferSize = rStream.GetBufferSize(); 506*cdf0e10cSrcweir sal_uIntPtr nSize = nBufferSize - nTell; 507*cdf0e10cSrcweir if ( nSize <= nBufferSize ) 508*cdf0e10cSrcweir { 509*cdf0e10cSrcweir char* pEmptyData = new char[nSize]; 510*cdf0e10cSrcweir memset(pEmptyData,0x00,nSize); 511*cdf0e10cSrcweir rStream.Write((sal_uInt8*)pEmptyData,nSize); 512*cdf0e10cSrcweir rStream.Seek(nTell); 513*cdf0e10cSrcweir delete [] pEmptyData; 514*cdf0e10cSrcweir } 515*cdf0e10cSrcweir } 516*cdf0e10cSrcweir return rStream; 517*cdf0e10cSrcweir } 518*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 519*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 520*cdf0e10cSrcweir //------------------------------------------------------------------ 521*cdf0e10cSrcweir void ONDXPage::PrintPage() 522*cdf0e10cSrcweir { 523*cdf0e10cSrcweir RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ONDXPage::PrintPage" ); 524*cdf0e10cSrcweir DBG_TRACE4("\nSDB: -----------Page: %d Parent: %d Count: %d Child: %d-----", 525*cdf0e10cSrcweir nPagePos, HasParent() ? aParent->GetPagePos() : 0 ,nCount, aChild.GetPagePos()); 526*cdf0e10cSrcweir 527*cdf0e10cSrcweir for (sal_uInt16 i = 0; i < nCount; i++) 528*cdf0e10cSrcweir { 529*cdf0e10cSrcweir ONDXNode rNode = (*this)[i]; 530*cdf0e10cSrcweir ONDXKey& rKey = rNode.GetKey(); 531*cdf0e10cSrcweir if (!IsLeaf()) 532*cdf0e10cSrcweir rNode.GetChild(&rIndex, this); 533*cdf0e10cSrcweir 534*cdf0e10cSrcweir if (rKey.getValue().isNull()) 535*cdf0e10cSrcweir { 536*cdf0e10cSrcweir DBG_TRACE2("SDB: [%d,NULL,%d]",rKey.GetRecord(), rNode.GetChild().GetPagePos()); 537*cdf0e10cSrcweir } 538*cdf0e10cSrcweir else if (rIndex.getHeader().db_keytype) 539*cdf0e10cSrcweir { 540*cdf0e10cSrcweir DBG_TRACE3("SDB: [%d,%f,%d]",rKey.GetRecord(), rKey.getValue().getDouble(),rNode.GetChild().GetPagePos()); 541*cdf0e10cSrcweir } 542*cdf0e10cSrcweir else 543*cdf0e10cSrcweir { 544*cdf0e10cSrcweir DBG_TRACE3("SDB: [%d,%s,%d]",rKey.GetRecord(), (const char* )ByteString(rKey.getValue().getString().getStr(), rIndex.m_pTable->getConnection()->getTextEncoding()).GetBuffer(),rNode.GetChild().GetPagePos()); 545*cdf0e10cSrcweir } 546*cdf0e10cSrcweir } 547*cdf0e10cSrcweir DBG_TRACE("SDB: -----------------------------------------------\n"); 548*cdf0e10cSrcweir if (!IsLeaf()) 549*cdf0e10cSrcweir { 550*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 551*cdf0e10cSrcweir GetChild(&rIndex)->PrintPage(); 552*cdf0e10cSrcweir for (sal_uInt16 i = 0; i < nCount; i++) 553*cdf0e10cSrcweir { 554*cdf0e10cSrcweir ONDXNode rNode = (*this)[i]; 555*cdf0e10cSrcweir rNode.GetChild(&rIndex,this)->PrintPage(); 556*cdf0e10cSrcweir } 557*cdf0e10cSrcweir #endif 558*cdf0e10cSrcweir } 559*cdf0e10cSrcweir DBG_TRACE("SDB: ===============================================\n"); 560*cdf0e10cSrcweir } 561*cdf0e10cSrcweir #endif 562*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 563*cdf0e10cSrcweir sal_Bool ONDXPage::IsFull() const 564*cdf0e10cSrcweir { 565*cdf0e10cSrcweir RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ONDXPage::IsFull" ); 566*cdf0e10cSrcweir return Count() == rIndex.getHeader().db_maxkeys; 567*cdf0e10cSrcweir } 568*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 569*cdf0e10cSrcweir //------------------------------------------------------------------ 570*cdf0e10cSrcweir sal_uInt16 ONDXPage::Search(const ONDXKey& rSearch) 571*cdf0e10cSrcweir { 572*cdf0e10cSrcweir RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ONDXPage::Search" ); 573*cdf0e10cSrcweir // binare Suche spaeter 574*cdf0e10cSrcweir sal_uInt16 i = 0xFFFF; 575*cdf0e10cSrcweir while (++i < Count()) 576*cdf0e10cSrcweir if ((*this)[i].GetKey() == rSearch) 577*cdf0e10cSrcweir break; 578*cdf0e10cSrcweir 579*cdf0e10cSrcweir return (i < Count()) ? i : NODE_NOTFOUND; 580*cdf0e10cSrcweir } 581*cdf0e10cSrcweir 582*cdf0e10cSrcweir //------------------------------------------------------------------ 583*cdf0e10cSrcweir sal_uInt16 ONDXPage::Search(const ONDXPage* pPage) 584*cdf0e10cSrcweir { 585*cdf0e10cSrcweir RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ONDXPage::Search" ); 586*cdf0e10cSrcweir sal_uInt16 i = 0xFFFF; 587*cdf0e10cSrcweir while (++i < Count()) 588*cdf0e10cSrcweir if (((*this)[i]).GetChild() == pPage) 589*cdf0e10cSrcweir break; 590*cdf0e10cSrcweir 591*cdf0e10cSrcweir // wenn nicht gefunden, dann wird davon ausgegangen, dass die Seite selbst 592*cdf0e10cSrcweir // auf die Page zeigt 593*cdf0e10cSrcweir return (i < Count()) ? i : NODE_NOTFOUND; 594*cdf0e10cSrcweir } 595*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 596*cdf0e10cSrcweir // laeuft rekursiv 597*cdf0e10cSrcweir void ONDXPage::SearchAndReplace(const ONDXKey& rSearch, 598*cdf0e10cSrcweir ONDXKey& rReplace) 599*cdf0e10cSrcweir { 600*cdf0e10cSrcweir RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ONDXPage::SearchAndReplace" ); 601*cdf0e10cSrcweir OSL_ENSURE(rSearch != rReplace,"Invalid here:rSearch == rReplace"); 602*cdf0e10cSrcweir if (rSearch != rReplace) 603*cdf0e10cSrcweir { 604*cdf0e10cSrcweir sal_uInt16 nPos = NODE_NOTFOUND; 605*cdf0e10cSrcweir ONDXPage* pPage = this; 606*cdf0e10cSrcweir 607*cdf0e10cSrcweir while (pPage && (nPos = pPage->Search(rSearch)) == NODE_NOTFOUND) 608*cdf0e10cSrcweir pPage = pPage->aParent; 609*cdf0e10cSrcweir 610*cdf0e10cSrcweir if (pPage) 611*cdf0e10cSrcweir { 612*cdf0e10cSrcweir (*pPage)[nPos].GetKey() = rReplace; 613*cdf0e10cSrcweir pPage->SetModified(sal_True); 614*cdf0e10cSrcweir } 615*cdf0e10cSrcweir } 616*cdf0e10cSrcweir } 617*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 618*cdf0e10cSrcweir ONDXNode& ONDXPage::operator[] (sal_uInt16 nPos) 619*cdf0e10cSrcweir { 620*cdf0e10cSrcweir DBG_ASSERT(nCount > nPos, "falscher Indexzugriff"); 621*cdf0e10cSrcweir return ppNodes[nPos]; 622*cdf0e10cSrcweir } 623*cdf0e10cSrcweir 624*cdf0e10cSrcweir //------------------------------------------------------------------ 625*cdf0e10cSrcweir const ONDXNode& ONDXPage::operator[] (sal_uInt16 nPos) const 626*cdf0e10cSrcweir { 627*cdf0e10cSrcweir DBG_ASSERT(nCount > nPos, "falscher Indexzugriff"); 628*cdf0e10cSrcweir return ppNodes[nPos]; 629*cdf0e10cSrcweir } 630*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 631*cdf0e10cSrcweir void ONDXPage::Remove(sal_uInt16 nPos) 632*cdf0e10cSrcweir { 633*cdf0e10cSrcweir RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ONDXPage::Remove" ); 634*cdf0e10cSrcweir DBG_ASSERT(nCount > nPos, "falscher Indexzugriff"); 635*cdf0e10cSrcweir 636*cdf0e10cSrcweir for (sal_uInt16 i = nPos; i < (nCount-1); i++) 637*cdf0e10cSrcweir (*this)[i] = (*this)[i+1]; 638*cdf0e10cSrcweir 639*cdf0e10cSrcweir nCount--; 640*cdf0e10cSrcweir bModified = sal_True; 641*cdf0e10cSrcweir } 642*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 643*cdf0e10cSrcweir 644*cdf0e10cSrcweir 645*cdf0e10cSrcweir 646*cdf0e10cSrcweir 647*cdf0e10cSrcweir 648*cdf0e10cSrcweir 649*cdf0e10cSrcweir 650*cdf0e10cSrcweir 651*cdf0e10cSrcweir 652*cdf0e10cSrcweir 653*cdf0e10cSrcweir 654