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