/src/libreoffice/connectivity/source/inc/dbase/DTable.hxx
Line | Count | Source |
1 | | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
2 | | /* |
3 | | * This file is part of the LibreOffice project. |
4 | | * |
5 | | * This Source Code Form is subject to the terms of the Mozilla Public |
6 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
7 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. |
8 | | * |
9 | | * This file incorporates work covered by the following license notice: |
10 | | * |
11 | | * Licensed to the Apache Software Foundation (ASF) under one or more |
12 | | * contributor license agreements. See the NOTICE file distributed |
13 | | * with this work for additional information regarding copyright |
14 | | * ownership. The ASF licenses this file to you under the Apache |
15 | | * License, Version 2.0 (the "License"); you may not use this file |
16 | | * except in compliance with the License. You may obtain a copy of |
17 | | * the License at http://www.apache.org/licenses/LICENSE-2.0 . |
18 | | */ |
19 | | |
20 | | #pragma once |
21 | | |
22 | | #include <file/FTable.hxx> |
23 | | #include <connectivity/CommonTools.hxx> |
24 | | #include <tools/urlobj.hxx> |
25 | | |
26 | | |
27 | | namespace connectivity::dbase |
28 | | { |
29 | | typedef file::OFileTable ODbaseTable_BASE; |
30 | | class ODbaseConnection; |
31 | | |
32 | | class ODbaseTable : public ODbaseTable_BASE |
33 | | { |
34 | | // The first byte of a dBase file specifies its type |
35 | | public: |
36 | | enum DBFType { dBaseIII = 0x03, |
37 | | dBaseIV = 0x04, |
38 | | dBaseV = 0x05, |
39 | | VisualFoxPro = 0x30, |
40 | | VisualFoxProAuto = 0x31, // Visual FoxPro with AutoIncrement field |
41 | | dBaseFS = 0x43, |
42 | | dBaseFSMemo = 0xB3, |
43 | | dBaseIIIMemo = 0x83, |
44 | | dBaseIVMemo = 0x8B, |
45 | | dBaseIVMemoSQL = 0x8E, |
46 | | FoxProMemo = 0xF5 |
47 | | }; |
48 | | enum DBFMemoType { MemodBaseIII = 0, |
49 | | MemodBaseIV, |
50 | | MemoFoxPro |
51 | | }; |
52 | | |
53 | | private: |
54 | | // sources: https://www.clicketyclick.dk/databases/xbase/format/dbf.html (dBASE III and 5) |
55 | | // http://www.dbase.com/KnowledgeBase/int/db7_file_fmt.htm (dBASE 7) which is similar at least for this part |
56 | | struct DBFHeader { // address/pos in trailer |
57 | | DBFType type; // dBASE/xBASE type, see DBFType 00h |
58 | | sal_uInt8 dateElems[3]; // Date of last change (YYMMDD) 01h |
59 | | sal_uInt32 nbRecords; // Number of records 04h |
60 | | sal_uInt16 headerLength; // 08h |
61 | | sal_uInt16 recordLength; // Length of 1 record 10h |
62 | | sal_uInt8 trailer[20]; |
63 | | // this last field contains these data: |
64 | | // - reserved:2 bytes:should be filled with 0 12h/0 |
65 | | // - incomplete transaction:1 byte:dBASE IV 14h/2 |
66 | | // 00h Transaction ended (or rolled back) |
67 | | // 01h Transaction started |
68 | | // - encryptionFlag:1 byte: dBASE IV 15h/3 |
69 | | // 00h not encrypted |
70 | | // 01h for encrypted |
71 | | // - freeRecordThread:4 bytes:reserved for LAN only 16h/4 |
72 | | // - multiUserdBASE:8 bytes:reserved for multi-user dBASE (dBASE III+) 20h/8 |
73 | | // - MDXFlag:1 byte:dBASE IV 28h/16 |
74 | | // 0x01 if a production .MDX file exists for this table |
75 | | // 0x00 if no .MDX file exists |
76 | | // - languageDriver:1 byte:codepage (from Foxpro) 29h/17 |
77 | | // - reserved:2 bytes: should be filled with 0 30h/18 |
78 | | }; |
79 | | struct DBFColumn { /* Column descriptors */ |
80 | | sal_uInt8 db_fnm[11]; /* Field name */ |
81 | | sal_uInt8 db_typ; /* Field type */ |
82 | | sal_uInt32 db_adr; /* Field address */ |
83 | | sal_uInt8 db_flng; /* Field length */ |
84 | | sal_uInt8 db_dez; /* Decimal places for N */ |
85 | | sal_uInt8 db_free2[14]; /* Reserved */ |
86 | | }; |
87 | | struct DBFMemoHeader |
88 | | { |
89 | | DBFMemoType db_typ; /* File type */ |
90 | | sal_uInt32 db_next; /* Next free block */ |
91 | | sal_uInt16 db_size; /* Block size: dBase 3 fixed */ |
92 | | DBFMemoHeader() |
93 | 40.7k | : db_typ(MemodBaseIII) |
94 | 40.7k | , db_next(0) |
95 | 40.7k | , db_size(0) |
96 | 40.7k | { |
97 | 40.7k | } |
98 | | }; |
99 | | |
100 | | std::vector<sal_Int32> m_aTypes; // holds all types for columns just to avoid to ask the propertyset |
101 | | std::vector<sal_Int32> m_aPrecisions; // same as above |
102 | | std::vector<sal_Int32> m_aScales; |
103 | | std::vector<sal_Int32> m_aRealFieldLengths; |
104 | | DBFHeader m_aHeader = {}; |
105 | | DBFMemoHeader m_aMemoHeader; |
106 | | std::unique_ptr<SvStream> m_pMemoStream; |
107 | | rtl_TextEncoding m_eEncoding; |
108 | | |
109 | | void alterColumn(sal_Int32 index, |
110 | | const css::uno::Reference< css::beans::XPropertySet>& descriptor , |
111 | | const css::uno::Reference< css::sdbcx::XDataDescriptorFactory>& xOldColumn ); |
112 | | void readHeader(); |
113 | | void fillColumns(); |
114 | | OUString createTempFile(); |
115 | | void copyData(ODbaseTable* _pNewTable,sal_Int32 _nPos); |
116 | | bool CreateFile(const INetURLObject& aFile, bool& bCreateMemo); |
117 | | bool CreateMemoFile(const INetURLObject& aFile); |
118 | | bool HasMemoFields() const; |
119 | | void ReadMemoHeader(); |
120 | | bool ReadMemo(std::size_t nBlockNo, ORowSetValue& aVariable); |
121 | | |
122 | | void WriteMemo(const ORowSetValue& aVariable, std::size_t& rBlockNr); |
123 | | bool WriteBuffer(); |
124 | | bool UpdateBuffer(OValueRefVector& rRow, const OValueRefRow& pOrgRow, const css::uno::Reference< css::container::XIndexAccess>& _xCols, bool bForceAllFields); |
125 | | css::uno::Reference< css::beans::XPropertySet> isUniqueByColumnName(sal_Int32 _nColumnPos); |
126 | | bool AllocBuffer(); |
127 | | |
128 | | void throwInvalidDbaseFormat(); |
129 | | /// @throws css::sdbc::SQLException |
130 | | /// @throws css::container::ElementExistException |
131 | | /// @throws css::uno::RuntimeException |
132 | | void renameImpl( const OUString& newName ); |
133 | | void throwInvalidColumnType(TranslateId pErrorId, const OUString& _sColumnName); |
134 | | |
135 | | protected: |
136 | | virtual void FileClose() override; |
137 | | // using ::connectivity::sdbcx::OTableDescriptor_BASE::rBHelper; |
138 | | |
139 | | public: |
140 | | virtual void refreshColumns() override; |
141 | | virtual void refreshIndexes() override; |
142 | | |
143 | | public: |
144 | | ODbaseTable( sdbcx::OCollection* _pTables,ODbaseConnection* _pConnection); |
145 | | ODbaseTable( sdbcx::OCollection* _pTables,ODbaseConnection* _pConnection, |
146 | | const OUString& Name, |
147 | | const OUString& Type, |
148 | | const OUString& Description = OUString(), |
149 | | const OUString& SchemaName = OUString(), |
150 | | const OUString& CatalogName = OUString() |
151 | | ); |
152 | | |
153 | | void construct() override; // can throw any exception |
154 | | |
155 | | virtual sal_Int32 getCurrentLastPos() const override; |
156 | | virtual bool seekRow(IResultSetHelper::Movement eCursorPosition, sal_Int32 nOffset, sal_Int32& nCurPos) override; |
157 | | virtual bool fetchRow(OValueRefRow& _rRow,const OSQLColumns& _rCols, bool bRetrieveData) override; |
158 | | |
159 | | virtual css::uno::Any SAL_CALL queryInterface( const css::uno::Type & rType ) override; |
160 | | //XTypeProvider |
161 | | virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes( ) override; |
162 | | virtual void SAL_CALL disposing() override; |
163 | | |
164 | | // XAlterTable |
165 | | virtual void SAL_CALL alterColumnByName( const OUString& colName, const css::uno::Reference< css::beans::XPropertySet >& descriptor ) override; |
166 | | virtual void SAL_CALL alterColumnByIndex( sal_Int32 index, const css::uno::Reference< css::beans::XPropertySet >& descriptor ) override; |
167 | | // XRename |
168 | | virtual void SAL_CALL rename( const OUString& newName ) override; |
169 | | |
170 | | bool DropImpl(); |
171 | | bool CreateImpl(); |
172 | | |
173 | | |
174 | | virtual bool InsertRow(OValueRefVector& rRow, const css::uno::Reference< css::container::XIndexAccess>& _xCols) override; |
175 | | virtual bool DeleteRow(const OSQLColumns& _rCols) override; |
176 | | virtual bool UpdateRow(OValueRefVector& rRow, OValueRefRow& pOrgRow,const css::uno::Reference< css::container::XIndexAccess>& _xCols) override; |
177 | | |
178 | | virtual void addColumn(const css::uno::Reference< css::beans::XPropertySet>& descriptor) override; |
179 | | virtual void dropColumn(sal_Int32 _nPos) override; |
180 | | |
181 | | static OUString getEntry(file::OConnection const * _pConnection, std::u16string_view _sURL ); |
182 | | static bool Drop_Static(std::u16string_view _sUrl, bool _bHasMemoFields, sdbcx::OCollection* _pIndexes ); |
183 | | |
184 | | virtual void refreshHeader() override; |
185 | | |
186 | | virtual css::uno::Reference< css::sdbc::XDatabaseMetaData> getMetaData() const override; |
187 | | }; |
188 | | |
189 | | } |
190 | | |
191 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |