source: gsdl/trunk/lib/gdbmclass.cpp@ 15679

Last change on this file since 15679 was 15679, checked in by mdewsnip, 16 years ago

(Adding new DB support) Adding a new "getfileextension()" function that is implemented differently between gdbmclass (which is endian-specific) and sqlitedbclass (which isn't).

File size: 6.3 KB
RevLine 
[15429]1/**********************************************************************
2 *
3 * gdbmclass.cpp --
4 * Copyright (C) 1999-2008 The New Zealand Digital Library Project
5 *
6 * A component of the Greenstone digital library software
7 * from the New Zealand Digital Library Project at the
8 * University of Waikato, New Zealand.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program 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 General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 *
24 *********************************************************************/
25
26#include "gdbmclass.h"
[15679]27#include "gsdltools.h"
[15429]28#include "gsdlunicode.h"
29
30
31gdbmclass::~gdbmclass()
32{
33 closedatabase();
34}
35
[15644]36
[15429]37// returns true if opened
38bool gdbmclass::opendatabase (const text_t &filename, int mode, int num_retrys,
39#ifdef __WIN32__
40 bool need_filelock
41#else
42 bool
43#endif
44 )
45{
46 text_t data_location;
47 int block_size = 512;
48
49 if (gdbmfile != NULL) {
50 if (openfile == filename) return true;
51 else closedatabase ();
52 }
53
54 openfile = filename;
[15557]55
56 // Map the DB mode values into GDBM mode values
57 int gdbm_mode = GDBM_READER;
58 if (mode == DB_WRITER)
59 {
60 gdbm_mode = GDBM_WRITER;
61 }
62 else if (mode == DB_WRITER_CREATE)
63 {
64 gdbm_mode = GDBM_WRCREAT;
65 }
66
[15429]67 char *namebuffer = filename.getcstr();
68 do {
69#ifdef __WIN32__
[15557]70 gdbmfile = gdbm_open (namebuffer, block_size, gdbm_mode, 00664, NULL, (need_filelock) ? 1 : 0);
[15429]71#else
[15557]72 gdbmfile = gdbm_open (namebuffer, block_size, gdbm_mode, 00664, NULL);
[15429]73#endif
74 --num_retrys;
75 } while (num_retrys>0 && gdbmfile==NULL &&
76 (gdbm_errno==GDBM_CANT_BE_READER || gdbm_errno==GDBM_CANT_BE_WRITER));
77 delete []namebuffer;
78
79 if (gdbmfile == NULL && logout != NULL) {
80 outconvertclass text_t2ascii;
81 (*logout) << text_t2ascii << "database open failed on: " << filename << "\n";
82 }
83
84 return (gdbmfile != NULL);
85}
86
87
88void gdbmclass::closedatabase ()
89{
90 if (gdbmfile == NULL) return;
91
92 gdbm_close (gdbmfile);
93 gdbmfile = NULL;
94 openfile.clear();
95}
96
97
[15644]98void gdbmclass::deletekey (const text_t &key)
99{
100 if (gdbmfile == NULL) return;
101
102 // get a utf-8 encoded c string of the unicode key
103 datum key_data;
104 key_data.dptr = (to_utf8(key)).getcstr();
105 if (key_data.dptr == NULL) return;
106 key_data.dsize = strlen (key_data.dptr);
107
108 // delete the key
109 gdbm_delete (gdbmfile, key_data);
110
111 // free up the key memory
112 delete []key_data.dptr;
113}
114
115
[15679]116// returns file extension string
117text_t gdbmclass::getfileextension ()
118{
119 if (littleEndian()) return ".ldb";
120 return ".bdb";
121}
122
123
[15429]124// returns true on success
[15644]125bool gdbmclass::getkeydata (const text_t& key, text_t &data)
126{
127 datum key_data;
128 datum return_data;
129
130 if (gdbmfile == NULL) return false;
131
132 // get a utf-8 encoded c string of the unicode key
133 key_data.dptr = (to_utf8(key)).getcstr();
134 if (key_data.dptr == NULL) {
135 if (logout != NULL) (*logout) << "gdbmclass: out of memory\n";
136 return false;
137 }
138 key_data.dsize = strlen (key_data.dptr);
139
140 // fetch the result
141 return_data = gdbm_fetch (gdbmfile, key_data);
142 delete []key_data.dptr;
143
144 if (return_data.dptr == NULL) return false;
145
146 data.setcarr (return_data.dptr, return_data.dsize);
147 free (return_data.dptr);
148 data = to_uni(data); // convert to unicode
149
150 return true;
151}
152
153
154// returns array of keys
155text_tarray gdbmclass::getkeys ()
156{
157 text_tarray keys;
158
159 text_t key = getfirstkey();
160 while (!key.empty())
161 {
162 keys.push_back(key);
163 key = getnextkey(key);
164 }
165
166 return keys;
167}
168
169
170// returns true on success
[15649]171bool gdbmclass::setkeydata (const text_t &key, const text_t &data)
[15429]172{
173 if (gdbmfile == NULL) return false;
174
175 // store the value
176 datum key_data;
177 datum data_data;
178
179 // get a utf-8 encoded c string of the unicode key
180 key_data.dptr = (to_utf8(key)).getcstr();
181 if (key_data.dptr == NULL) {
182 if (logout != NULL) (*logout) << "gdbmclass: out of memory\n";
183 return false;
184 }
185 key_data.dsize = strlen (key_data.dptr);
186
187 data_data.dptr = (to_utf8(data)).getcstr();
188 if (data_data.dptr == NULL) {
189 if (logout != NULL) (*logout) << "gdbmclass: out of memory\n";
190 delete []key_data.dptr;
191 return false;
192 }
193 data_data.dsize = strlen (data_data.dptr);
194
195 int ret = gdbm_store (gdbmfile, key_data, data_data, GDBM_REPLACE);
196 delete []key_data.dptr;
197 delete []data_data.dptr;
198
199 return (ret == 0);
200}
201
202
[15644]203// ----------------------------------------------------------------------------------------
204// GDBM-ONLY FUNCTIONS
205// ----------------------------------------------------------------------------------------
[15429]206
207// getfirstkey and getnextkey are used for traversing the database
208// no insertions or deletions should be carried out while traversing
209// the database. when there are no keys left to visit in the database
210// an empty string is returned.
211text_t gdbmclass::getfirstkey ()
212{
213 if (gdbmfile == NULL) return g_EmptyText;
214
215 // get the first key
216 datum firstkey_data = gdbm_firstkey (gdbmfile);
217 if (firstkey_data.dptr == NULL) return g_EmptyText;
218
219 // convert it to text_t
220 text_t firstkey;
221 firstkey.setcarr (firstkey_data.dptr, firstkey_data.dsize);
222 free (firstkey_data.dptr);
223 return to_uni(firstkey); // convert to unicode
224}
225
226
227text_t gdbmclass::getnextkey (const text_t &key)
228{
229 if (gdbmfile == NULL || key.empty()) return g_EmptyText;
230
231 // get a utf-8 encoded c string of the unicode key
232 datum key_data;
233 key_data.dptr = (to_utf8(key)).getcstr();
234 if (key_data.dptr == NULL) return g_EmptyText;
235 key_data.dsize = strlen (key_data.dptr);
236
237 // get the next key
238 datum nextkey_data = gdbm_nextkey (gdbmfile, key_data);
239 if (nextkey_data.dptr == NULL) {
240 delete []key_data.dptr;
241 return g_EmptyText;
242 }
243
244 // convert it to text_t
245 text_t nextkey;
246 nextkey.setcarr (nextkey_data.dptr, nextkey_data.dsize);
247 free (nextkey_data.dptr);
248 delete []key_data.dptr;
249 return to_uni(nextkey); // convert to unicode
250}
Note: See TracBrowser for help on using the repository browser.