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 #ifndef BERKELEYDBPROXY_DB_HXX_
28 #define BERKELEYDBPROXY_DB_HXX_
29 
30 #ifdef SYSTEM_DB
31 #include <db.h>
32 #else
33 #include <berkeleydb/db.h>
34 #endif
35 
36 #include "com/sun/star/ucb/XSimpleFileAccess.hpp"
37 
38 #include <hash_map>
39 #include <rtl/string.hxx>
40 
41 extern "C" {
42   typedef void *(*db_malloc_fcn_type)(size_t);
43   typedef void *(*db_realloc_fcn_type)(void *, size_t);
44   typedef void (*db_free_fcn_type)(void *);
45 }
46 
47 
48 namespace berkeleydbproxy {
49 
50     class Dbc;
51     class Dbt;
52 
53     namespace db_internal
54     {
55         class Noncopyable
56         {
57             // not implemented
58             Noncopyable(const Noncopyable&);
59             void operator=(const Noncopyable&);
60         protected:
61             Noncopyable() {}
62             ~Noncopyable() {}
63         };
64     }
65 
66     class DbException
67     {
68         rtl::OString what_;
69     public:
70         explicit DbException(rtl::OString const & whatparam)
71         : what_(whatparam)
72         {}
73 
74 	    const char *what() const
75         { return what_.getStr(); }
76     };
77 
78 	struct eq
79 	{
80 		bool operator()( const rtl::OString& rKey1, const rtl::OString& rKey2 ) const
81 			{ return rKey1.compareTo( rKey2 ) == 0; }
82 	};
83 
84 	struct ha
85 	{
86 		size_t operator()( const rtl::OString& rName ) const
87 			{ return rName.hashCode(); }
88 	};
89 
90 
91 //#define TEST_DBHELP
92 
93 	class DBData
94 	{
95 		friend class		DBHelp;
96 
97 		int					m_nSize;
98 		char*				m_pBuffer;
99 
100 		void copyToBuffer( const char* pSrcData, int nSize );
101 
102 	public:
103 		DBData( void )
104 			: m_nSize( 0 )
105 			, m_pBuffer( NULL )
106 		{}
107 		~DBData()
108 			{ delete [] m_pBuffer; }
109 
110   	    int getSize() const
111 			{ return m_nSize; }
112   	    const char* getData() const
113 			{ return m_pBuffer; }
114 	};
115 
116 	typedef std::hash_map< rtl::OString,std::pair<int,int>,ha,eq >	StringToValPosMap;
117 	typedef std::hash_map< rtl::OString,rtl::OString,ha,eq >		StringToDataMap;
118 
119 	class DBHelp
120 	{
121 		rtl::OUString		m_aFileURL;
122 		StringToDataMap*	m_pStringToDataMap;
123 		StringToValPosMap*	m_pStringToValPosMap;
124 		com::sun::star::uno::Reference< com::sun::star::ucb::XSimpleFileAccess >
125 							m_xSFA;
126 
127 		com::sun::star::uno::Sequence< sal_Int8 >
128 							m_aItData;
129 		const char*			m_pItData;
130 		int					m_nItRead;
131 		int					m_iItPos;
132 
133 		bool implReadLenAndData( const char* pData, int& riPos, DBData& rValue );
134 
135 	public:
136         //DBHelp must get a fileURL which can then directly be used by simple file access.
137         //SimpleFileAccess requires file URLs as arguments. Passing file path may work but fails
138         //for example when using long file paths on Windows, which start with "\\?\"
139 		DBHelp( const rtl::OUString& rFileURL,
140 			com::sun::star::uno::Reference< com::sun::star::ucb::XSimpleFileAccess > xSFA )
141 				: m_aFileURL( rFileURL )
142 				, m_pStringToDataMap( NULL )
143 				, m_pStringToValPosMap( NULL )
144 				, m_xSFA( xSFA )
145 				, m_pItData( NULL )
146 				, m_nItRead( -1 )
147 				, m_iItPos( -1 )
148 		{
149             OSL_ASSERT(!rFileURL.compareTo(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("file:")), 5));
150         }
151 		~DBHelp()
152 			{ releaseHashMap(); }
153 
154 		void createHashMap( bool bOptimizeForPerformance = false );
155 		void releaseHashMap( void );
156 
157 #ifdef TEST_DBHELP
158 		bool testAgainstDb( const rtl::OUString& fileURL, bool bOldDbAccess );
159 #endif
160 
161 		bool getValueForKey( const rtl::OString& rKey, DBData& rValue );
162 
163 		bool startIteration( void );
164 		bool getNextKeyAndValue( DBData& rKey, DBData& rValue );
165 		void stopIteration( void );
166 	};
167 
168     class Db : db_internal::Noncopyable
169     {
170     private:
171 	    DB* m_pDBP;
172 	    DBHelp* m_pDBHelp;
173 
174     public:
175 	    Db();
176 	    ~Db();
177 
178 	    void setDBHelp( DBHelp* pDBHelp )
179 			{ m_pDBHelp = pDBHelp; }
180 	    DBHelp* getDBHelp( void )
181 			{ return m_pDBHelp; }
182 
183 	    int close(u_int32_t flags);
184 
185 	    int open(DB_TXN *txnid,
186 			     const char *file,
187 			     const char *database,
188 			     DBTYPE type,
189 			     u_int32_t flags,
190 			     int mode);
191 
192         int open(DB_TXN *txnid,
193 			     ::rtl::OUString const & fileURL,
194 			     DBTYPE type,
195 			     u_int32_t flags,
196 			     int mode);
197 
198 
199     	int get(DB_TXN* txnid, Dbt *key, Dbt *data, u_int32_t flags);
200 
201 	    int cursor(DB_TXN *txnid, Dbc **cursorp, u_int32_t flags);
202     };
203 
204     class Dbc : db_internal::Noncopyable
205     {
206     	friend class Db;
207 	    friend class Dbt;
208 
209     private:
210 	    DBC* m_pDBC;
211 
212 	    explicit Dbc(DBC* pDBC);
213 	    ~Dbc();
214 
215     public:
216 	    int close();
217 
218 	    int get(Dbt *key, Dbt *data, u_int32_t flags);
219     };
220 
221     class Dbt: private DBT
222     {
223 	    friend class Db;
224 	    friend class Dbc;
225 
226     public:
227 	    Dbt(void *data_arg, u_int32_t size_arg);
228 
229 	    Dbt();
230         //Dbt(const Dbt & other);
231         //Dbt & operator=(const Dbt & other);
232 
233 	    ~Dbt();
234 
235   	    void *get_data() const;
236 	    void set_data(void *value);
237 
238   	    u_int32_t get_size() const;
239 	    void set_size(u_int32_t value);
240 
241 	    void set_flags(u_int32_t);
242     };
243 }
244 
245 #endif
246 
247 
248 
249 
250 
251 
252 
253 
254 
255 
256 
257 
258 
259 
260 
261 
262