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