1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
22 #include <file/FTable.hxx>
23 #include <connectivity/CommonTools.hxx>
24 #include <tools/urlobj.hxx>
27 namespace connectivity::dbase
29 typedef file::OFileTable ODbaseTable_BASE
;
30 class ODbaseConnection
;
32 class ODbaseTable
: public ODbaseTable_BASE
34 // The first byte of a dBase file specifies its type
36 enum DBFType
{ dBaseIII
= 0x03,
40 VisualFoxProAuto
= 0x31, // Visual FoxPro with AutoIncrement field
45 dBaseIVMemoSQL
= 0x8E,
48 enum DBFMemoType
{ MemodBaseIII
= 0,
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
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
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 */
89 DBFMemoType db_typ
; /* File type */
90 sal_uInt32 db_next
; /* Next free block */
91 sal_uInt16 db_size
; /* Block size: dBase 3 fixed */
93 : db_typ(MemodBaseIII
)
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
;
109 void alterColumn(sal_Int32 index
,
110 const css::uno::Reference
< css::beans::XPropertySet
>& descriptor
,
111 const css::uno::Reference
< css::sdbcx::XDataDescriptorFactory
>& xOldColumn
);
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
);
122 void WriteMemo(const ORowSetValue
& aVariable
, std::size_t& rBlockNr
);
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
);
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
);
136 virtual void FileClose() override
;
137 // using ::connectivity::sdbcx::OTableDescriptor_BASE::rBHelper;
140 virtual void refreshColumns() override
;
141 virtual void refreshIndexes() override
;
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()
153 void construct() override
; // can throw any exception
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
;
159 virtual css::uno::Any SAL_CALL
queryInterface( const css::uno::Type
& rType
) override
;
161 virtual css::uno::Sequence
< css::uno::Type
> SAL_CALL
getTypes( ) override
;
162 virtual void SAL_CALL
disposing() override
;
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
;
168 virtual void SAL_CALL
rename( const OUString
& newName
) override
;
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
;
178 virtual void addColumn(const css::uno::Reference
< css::beans::XPropertySet
>& descriptor
) override
;
179 virtual void dropColumn(sal_Int32 _nPos
) override
;
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
);
184 virtual void refreshHeader() override
;
186 virtual css::uno::Reference
< css::sdbc::XDatabaseMetaData
> getMetaData() const override
;
191 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */