source: gs2-extensions/tdb-edit/trunk/src/src/lib/tdbclass.cpp@ 24090

Last change on this file since 24090 was 24090, checked in by jmt12, 13 years ago

tdb datasource support for Greenstone runtime

File size: 6.5 KB
Line 
1/**********************************************************************
2 *
3 * tdbclass.cpp --
4 *
5 * Copyright (C) 2011 The New Zealand Digital Library Project
6 *
7 * A component of the Greenstone digital library software
8 * from the New Zealand Digital Library Project at the
9 * University of Waikato, New Zealand.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 *********************************************************************/
26
27#include "tdbclass.h"
28
29#include "gsdltools.h"
30#include "gsdlunicode.h"
31#include "fileutil.h"
32#include "stdlib.h"
33#include <cstring>
34
35
36tdbclass::tdbclass(const text_t& gsdlhome)
37 : dbclass(gsdlhome)
38{
39 tdb = NULL;
40}
41
42tdbclass::~tdbclass()
43{
44 closedatabase();
45}
46
47
48// returns true if opened
49bool
50tdbclass::opendatabase (const text_t &filename, int mode, int num_retrys, bool need_filelock)
51{
52
53 if (tdb != NULL)
54 {
55 if (openfile == filename)
56 {
57 return true;
58 }
59 else
60 {
61 closedatabase();
62 }
63 }
64
65 // Map the DB mode values into TDB mode values
66 int file_mode = O_RDONLY;
67 if (mode == DB_WRITER)
68 {
69 file_mode = O_RDWR;
70 }
71 else if (mode == DB_WRITER_CREATE)
72 {
73 file_mode = O_RDWR | O_CREAT;
74 }
75
76 char *namebuffer = filename.getcstr();
77 int hash_size = 0;
78 do
79 {
80 tdb = tdb_open(namebuffer, hash_size, TDB_DEFAULT, file_mode, 0664);
81 --num_retrys;
82 } while (num_retrys > 0 && tdb==NULL);
83
84 delete []namebuffer;
85
86 if (tdb == NULL && logout != NULL)
87 {
88 outconvertclass text_t2ascii;
89 (*logout) << text_t2ascii << "database open failed on: " << filename << "\n";
90 }
91
92 openfile = filename;
93
94 return (tdb != NULL);
95}
96/** opendatabase() **/
97
98
99/**
100 */
101void
102tdbclass::closedatabase ()
103{
104 if (tdb == NULL)
105 {
106 return;
107 }
108 tdb_close (tdb);
109 tdb = NULL;
110 openfile.clear();
111}
112/** closedatabase() **/
113
114
115/**
116 */
117void
118tdbclass::deletekey (const text_t &key)
119{
120 if (tdb == NULL)
121 {
122 return;
123 }
124 // get a utf-8 encoded c string of the unicode key
125 TDB_DATA key_data;
126 key_data.dptr = (unsigned char*)(to_utf8(key)).getcstr();
127 if (key_data.dptr == NULL)
128 {
129 return;
130 }
131 key_data.dsize = strlen((const char *)key_data.dptr);
132 // delete the key
133 tdb_delete(tdb, key_data);
134 // free up the key memory
135 delete []key_data.dptr;
136}
137/** deletekey() **/
138
139// returns file extension string
140text_t
141tdbclass::getfileextension ()
142{
143 return ".tdb";
144}
145/** getfileextension() **/
146
147// returns true on success
148bool
149tdbclass::getkeydata (const text_t& key, text_t &data)
150{
151 if (tdb == NULL)
152 {
153 return false;
154 }
155
156 // get a utf-8 encoded c string of the unicode key
157 TDB_DATA key_data;
158 key_data.dptr = (unsigned char *)(to_utf8(key)).getcstr();
159 if (key_data.dptr == NULL)
160 {
161 if (logout != NULL)
162 {
163 (*logout) << "tdbclass: out of memory" << endl;
164 }
165 return false;
166 }
167 key_data.dsize = strlen((const char *)key_data.dptr);
168
169 // fetch the result
170 TDB_DATA return_data = tdb_fetch(tdb, key_data);
171 delete []key_data.dptr;
172
173 if (return_data.dptr == NULL)
174 {
175 return false;
176 }
177 data.setcarr((char *)return_data.dptr, return_data.dsize);
178 free(return_data.dptr);
179 data = to_uni(data); // convert to unicode
180
181 return true;
182}
183/** getkeydata() **/
184
185
186// returns array of keys
187text_tarray
188tdbclass::getkeys ()
189{
190 text_tarray keys;
191
192 text_t key = getfirstkey();
193 while (!key.empty())
194 {
195 keys.push_back(key);
196 key = getnextkey(key);
197 }
198
199 return keys;
200}
201/** getkeys() **/
202
203
204// returns true on success
205bool
206tdbclass::setkeydata (const text_t &key, const text_t &data)
207{
208 if (tdb == NULL)
209 {
210 return false;
211 }
212
213 // get a utf-8 encoded c string of the unicode key
214 TDB_DATA key_data;
215 key_data.dptr = (unsigned char *)(to_utf8(key)).getcstr();
216 if (key_data.dptr == NULL)
217 {
218 if (logout != NULL)
219 {
220 (*logout) << "tdbclass: out of memory" << endl;
221 }
222 return false;
223 }
224 key_data.dsize = strlen((const char *)key_data.dptr);
225
226 TDB_DATA data_data;
227 data_data.dptr = (unsigned char *)(to_utf8(data)).getcstr();
228 if (data_data.dptr == NULL)
229 {
230 if (logout != NULL)
231 {
232 (*logout) << "tdbclass: out of memory" << endl;
233 }
234 delete []key_data.dptr;
235 return false;
236 }
237 data_data.dsize = strlen((const char *)data_data.dptr);
238
239 int ret = tdb_store (tdb, key_data, data_data, TDB_DEFAULT);
240 delete []key_data.dptr;
241 delete []data_data.dptr;
242
243 return (ret == 0);
244}
245/** setkeydata() **/
246
247// ----------------------------------------------------------------------------------------
248// TDB-ONLY FUNCTIONS
249// ----------------------------------------------------------------------------------------
250
251// getfirstkey and getnextkey are used for traversing the database
252// no insertions or deletions should be carried out while traversing
253// the database. when there are no keys left to visit in the database
254// an empty string is returned.
255text_t
256tdbclass::getfirstkey ()
257{
258 if (tdb == NULL)
259 {
260 return g_EmptyText;
261 }
262 // get the first key
263 TDB_DATA firstkey_data = tdb_firstkey(tdb);
264 if (firstkey_data.dptr == NULL)
265 {
266 return g_EmptyText;
267 }
268 // convert it to text_t
269 text_t firstkey;
270 firstkey.setcarr((char *)firstkey_data.dptr, firstkey_data.dsize);
271 free(firstkey_data.dptr);
272
273 return to_uni(firstkey); // convert to unicode
274}
275/** getfirstkey() **/
276
277/**
278 */
279text_t
280tdbclass::getnextkey (const text_t &key)
281{
282 if (tdb == NULL || key.empty())
283 {
284 return g_EmptyText;
285 }
286 // get a utf-8 encoded c string of the unicode key
287 TDB_DATA key_data;
288 key_data.dptr = (unsigned char *)(to_utf8(key)).getcstr();
289 if (key_data.dptr == NULL)
290 {
291 return g_EmptyText;
292 }
293 key_data.dsize = strlen((const char *)key_data.dptr);
294
295 // get the next key
296 TDB_DATA nextkey_data = tdb_nextkey(tdb, key_data);
297 if (nextkey_data.dptr == NULL)
298 {
299 delete []key_data.dptr;
300 return g_EmptyText;
301 }
302
303 // convert it to text_t
304 text_t nextkey;
305 nextkey.setcarr((char *)nextkey_data.dptr, nextkey_data.dsize);
306 free(nextkey_data.dptr);
307 delete []key_data.dptr;
308 return to_uni(nextkey); // convert to unicode
309}
310/** getnextkey() **/
311
Note: See TracBrowser for help on using the repository browser.