summaryrefslogtreecommitdiffstats
path: root/connectivity/source/inc/dbase/DIndex.hxx
blob: 3cc7da9ad1d34d206e0522c14cc6c195aa4e2481 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

#pragma once

#include <sdbcx/VIndex.hxx>
#include <dbase/DTable.hxx>
#include <dbase/dindexnode.hxx>

inline constexpr OString dBASE_III_GROUP = "dBase III"_ostr;

namespace connectivity::dbase
    {
        class OIndexIterator;
        class ONDXKey;

        typedef sdbcx::OIndex ODbaseIndex_BASE;

        class ODbaseIndex : public ODbaseIndex_BASE
        {
            friend SvStream& WriteODbaseIndex(SvStream &rStream, const ODbaseIndex&);
            friend SvStream& operator >> (SvStream &rStream, ODbaseIndex&);

            friend class ONDXNode;
            friend class ONDXPage;
            friend class ONDXPagePtr;
            friend class OIndexIterator;

        public:

            // Header struct - stays in memory

            struct NDXHeader
            {
                sal_uInt32  db_rootpage;                    /* Rootpage position                */
                sal_uInt32  db_pagecount;                   /* Page count                       */
                sal_uInt8   db_free[4];                     /* Reserved                         */
                sal_uInt16  db_keylen;                      /* Key length                       */
                sal_uInt16  db_maxkeys;                     /* Maximum number of keys per page  */
                sal_uInt16  db_keytype;                     /* Type of key:
                                                               0 = Text
                                                               1 = Numerical                    */
                sal_uInt16  db_keyrec;                      /* Length of an index record
                                                               RecordNumber + keylen            */
                sal_uInt8   db_free1[3];                    /* Reserved                         */
                sal_uInt8   db_unique;                      /* Unique                           */
                char        db_name[488];                   /* index_name (field name)          */
            };

        private:
            std::unique_ptr<SvStream> m_pFileStream;        // Stream to read/write the index
            NDXHeader       m_aHeader = {};
            std::vector<ONDXPage*>
                            m_aCollector;                   // Pool of obsolete pages
            ONDXPagePtr     m_aRoot,                        // Root of the B+ tree
                            m_aCurLeaf;                     // Current leaf
            sal_uInt16      m_nCurNode;                     // Position of the current node

            sal_uInt32      m_nPageCount,
                            m_nRootPage;

            ODbaseTable*    m_pTable;
            bool        m_bUseCollector : 1;            // Use the Garbage Collector

            OUString getCompletePath() const;
            void closeImpl();
            // Closes and kills the index file and throws an error
            void impl_killFileAndthrowError_throw(TranslateId pErrorId, const OUString& _sFile);
        protected:
            virtual ~ODbaseIndex() override;
        public:
            ODbaseIndex(ODbaseTable* _pTable);
            ODbaseIndex(ODbaseTable* _pTable,const NDXHeader& _aHeader,const OUString& Name);

            void openIndexFile();
            virtual void refreshColumns() override;

            const ODbaseTable* getTable() const { return m_pTable; }
            const NDXHeader& getHeader() const { return m_aHeader; }
            std::unique_ptr<OIndexIterator> createIterator();

            void SetRootPos(sal_uInt32 nPos)        {m_nRootPage = nPos;}
            void SetPageCount(sal_uInt32 nCount)    {m_nPageCount = nCount;}

            sal_uInt32 GetPageCount() const         {return m_nPageCount;}

            sal_uInt16 GetMaxNodes() const          {return m_aHeader.db_maxkeys;}

            bool Insert(sal_uInt32 nRec, const ORowSetValue& rValue);
            bool Update(sal_uInt32 nRec, const ORowSetValue&, const ORowSetValue&);
            bool Delete(sal_uInt32 nRec, const ORowSetValue& rValue);
            bool Find(sal_uInt32 nRec, const ORowSetValue& rValue);

            void createINFEntry();
            void CreateImpl();
            void DropImpl();

            DECLARE_SERVICE_INFO();
        protected:

            ONDXPage* CreatePage(sal_uInt32 nPagePos, ONDXPage* pParent = nullptr, bool bLoad = false);
            void Collect(ONDXPage*);
            ONDXPagePtr const & getRoot();

            bool isUnique() const { return m_IsUnique; }
            bool UseCollector() const {return m_bUseCollector;}
            // Tree operations
            void Release(bool bSave = true);
            bool ConvertToKey(ONDXKey* rKey, sal_uInt32 nRec, const ORowSetValue& rValue);
        };

        SvStream& WriteODbaseIndex(SvStream &rStream, const ODbaseIndex&);
        SvStream& operator >> (SvStream &rStream, ODbaseIndex&);

        void ReadHeader(SvStream & rStream, ODbaseIndex::NDXHeader & rHeader);
}


/* vim:set shiftwidth=4 softtabstop=4 expandtab: */