1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #ifndef _CONNECTIVITY_DBASE_TABLE_HXX_
25 #define _CONNECTIVITY_DBASE_TABLE_HXX_
26 
27 #include "file/FTable.hxx"
28 #include "connectivity/sdbcx/VColumn.hxx"
29 #include "connectivity/CommonTools.hxx"
30 #include <tools/urlobj.hxx>
31 
32 
33 namespace connectivity
34 {
35 	namespace dbase
36 	{
37 		typedef file::OFileTable ODbaseTable_BASE;
38 		class ODbaseConnection;
39 
40 		typedef ::std::map< ::rtl::OUString,
41 						::com::sun::star::uno::Reference< ::com::sun::star::container::XNamed>, comphelper::UStringMixLess > OContainer;
42 
43 		class ODbaseTable :	public ODbaseTable_BASE
44 		{
45 			// der Typ einer dBase datei wird mit dem ersten Byte bestimmt
46 		public:
47 			enum DBFType  {	dBaseIII         = 0x03,
48 							dBaseIV          = 0x04,
49 							dBaseV	         = 0x05,
50                             VisualFoxPro	 = 0x30,
51                             VisualFoxProAuto = 0x31, // Visual FoxPro w. AutoIncrement field
52 							dBaseFS          = 0x43,
53 							dBaseFSMemo      = 0xB3,
54 							dBaseIIIMemo     = 0x83,
55 							dBaseIVMemo      = 0x8B,
56 							dBaseIVMemoSQL   = 0x8E,
57 							FoxProMemo       = 0xF5
58 						  };
59 			enum DBFMemoType {	MemodBaseIII = 0,
60 								MemodBaseIV,
61 								MemoFoxPro
62 							};
63 
64 		private:
65 			struct DBFHeader {                       /* Kopfsatz-Struktur            */
66 								DBFType	db_typ;		                    /* Dateityp						*/
67 								sal_uInt8    db_aedat[3];                    /* Datum der letzen Aenderung   */
68 																		/* JJ MM TT                     */
69 								sal_uInt32   db_anz;                         /* Anzahl der Saetze            */
70 								sal_uInt16  db_kopf;                        /* laenge Kopfsatz-Struktur     */
71 								sal_uInt16  db_slng;                        /* laenge der Daten-Saetze      */
72 								sal_uInt8    db_frei[20];                    /* reserviert                   */
73 							};
74 			struct DBFColumn {                       /* Feldbezeichner               */
75 								sal_uInt8    db_fnm[11];                     /* Feldname                     */
76 								sal_uInt8    db_typ;                         /* Feldtyp                      */
77 								sal_uInt32  db_adr;                         /* Feldadresse                  */
78 								sal_uInt8    db_flng;                        /* Feldlaenge                   */
79 								sal_uInt8    db_dez;                         /* Dezimalstellen fuer N        */
80 								sal_uInt8    db_frei2[14];                   /* reserviert                   */
81 							};
82 			struct DBFMemoHeader
83 							{
84 								DBFMemoType	db_typ;						/* Dateityp						*/
85                                 sal_uInt32  db_next;                        /* naechster freier Block       */
86                                 sal_uInt16  db_size;                        /* Blockgroesse: dBase 3 fest   */
87 							};
88 
89 			::std::vector<sal_Int32> m_aTypes;		// holds all type for columns just to avoid to ask the propertyset
90 			::std::vector<sal_Int32> m_aPrecisions;	// same as aboth
91 			::std::vector<sal_Int32> m_aScales;
92             ::std::vector<sal_Int32> m_aRealFieldLengths;
93 			DBFHeader		m_aHeader;
94 			DBFMemoHeader	m_aMemoHeader;
95 			SvStream*		m_pMemoStream;
96             rtl_TextEncoding m_eEncoding;
97 			sal_Bool		m_bWriteableMemo;
98 
99 			void alterColumn(sal_Int32 index,
100 							 const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet>& descriptor ,
101 							 const ::com::sun::star::uno::Reference< ::com::sun::star::sdbcx::XDataDescriptorFactory>& xOldColumn );
102 			void readHeader();
103 			void fillColumns();
104 			String createTempFile();
105 			void copyData(ODbaseTable* _pNewTable,sal_Int32 _nPos);
106 			sal_Bool CreateFile(const INetURLObject& aFile, sal_Bool& bCreateMemo);
107 			sal_Bool CreateMemoFile(const INetURLObject& aFile);
HasMemoFields() const108 			sal_Bool HasMemoFields() const { return m_aHeader.db_typ > dBaseIV;}
109 			sal_Bool ReadMemoHeader();
110 			sal_Bool ReadMemo(sal_uIntPtr nBlockNo, ORowSetValue& aVariable);
111 
112 			sal_Bool WriteMemo(ORowSetValue& aVariable, sal_uIntPtr& rBlockNr);
113 			sal_Bool WriteBuffer();
114 			sal_Bool UpdateBuffer(OValueRefVector& rRow, OValueRefRow pOrgRow,const ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexAccess>& _xCols);
115 			::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet> isUniqueByColumnName(sal_Int32 _nColumnPos);
116 			void AllocBuffer();
117 
118 			void throwInvalidDbaseFormat();
119 			void SAL_CALL renameImpl( const ::rtl::OUString& newName ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::container::ElementExistException, ::com::sun::star::uno::RuntimeException);
120 			void throwInvalidColumnType(const sal_uInt16 _nErrorId,const ::rtl::OUString& _sColumnName);
121 
122 		protected:
123 			virtual void FileClose();
124 //			using ::connectivity::sdbcx::OTableDescriptor_BASE::rBHelper;
125 
126 		public:
127 			virtual void refreshColumns();
128 			virtual void refreshIndexes();
129 
130 		public:
131 			ODbaseTable( sdbcx::OCollection* _pTables,ODbaseConnection* _pConnection);
132 			ODbaseTable( sdbcx::OCollection* _pTables,ODbaseConnection* _pConnection,
133 					const ::rtl::OUString& _Name,
134 					const ::rtl::OUString& _Type,
135 					const ::rtl::OUString& _Description = ::rtl::OUString(),
136 					const ::rtl::OUString& _SchemaName = ::rtl::OUString(),
137 					const ::rtl::OUString& _CatalogName = ::rtl::OUString()
138 				);
139 
140 			void construct(); // can throw any exception
141 
142 			virtual sal_Int32 getCurrentLastPos() const;
143 			virtual sal_Bool seekRow(IResultSetHelper::Movement eCursorPosition, sal_Int32 nOffset, sal_Int32& nCurPos);
144 			virtual sal_Bool fetchRow(OValueRefRow& _rRow,const OSQLColumns& _rCols, sal_Bool _bUseTableDefs,sal_Bool bRetrieveData);
145 
146 			virtual ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException);
147 			//XTypeProvider
148 			virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL getTypes(  ) throw(::com::sun::star::uno::RuntimeException);
149 			virtual void SAL_CALL disposing(void);
150 
151 			// com::sun::star::lang::XUnoTunnel
152 			virtual sal_Int64 SAL_CALL getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& aIdentifier ) throw(::com::sun::star::uno::RuntimeException);
153 			static ::com::sun::star::uno::Sequence< sal_Int8 > getUnoTunnelImplementationId();
154 			// XAlterTable
155             virtual void SAL_CALL alterColumnByName( const ::rtl::OUString& colName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& descriptor ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::container::NoSuchElementException, ::com::sun::star::uno::RuntimeException);
156             virtual void SAL_CALL alterColumnByIndex( sal_Int32 index, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& descriptor ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
157 			// XRename
158 			virtual void SAL_CALL rename( const ::rtl::OUString& newName ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::container::ElementExistException, ::com::sun::star::uno::RuntimeException);
159 
160 			sal_Bool	DropImpl();
161 			sal_Bool	CreateImpl();
162 
163 
164 			virtual sal_Bool InsertRow(OValueRefVector& rRow, sal_Bool bFlush,const ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexAccess>& _xCols);
165 			virtual sal_Bool DeleteRow(const OSQLColumns& _rCols);
166 			virtual sal_Bool UpdateRow(OValueRefVector& rRow, OValueRefRow& pOrgRow,const ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexAccess>& _xCols);
167 
168 			virtual void addColumn(const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet>& descriptor);
169 			virtual void dropColumn(sal_Int32 _nPos);
170 
171 			static String	getEntry(file::OConnection* _pConnection,const ::rtl::OUString& _sURL );
172 			static sal_Bool		Drop_Static(const ::rtl::OUString& _sUrl,sal_Bool _bHasMemoFields,sdbcx::OCollection* _pIndexes );
173 
174 			virtual void refreshHeader();
175 
176 			virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XDatabaseMetaData> getMetaData() const;
177 		};
178 	}
179 }
180 #endif // _CONNECTIVITY_DBASE_TABLE_HXX_
181 
182