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

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

(Adding new DB support) Created default implementations of getinfo() and setinfo() in dbclass so they don't necessarily be re-implemented for every subclass.

File size: 6.2 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"
27#include "unitool.h"
28#include "gsdlunicode.h"
29#include "OIDtools.h"
30
31
32gdbmclass::~gdbmclass()
33{
34 closedatabase();
35}
36
[15644]37
[15429]38// returns true if opened
39bool gdbmclass::opendatabase (const text_t &filename, int mode, int num_retrys,
40#ifdef __WIN32__
41 bool need_filelock
42#else
43 bool
44#endif
45 )
46{
47 text_t data_location;
48 int block_size = 512;
49
50 if (gdbmfile != NULL) {
51 if (openfile == filename) return true;
52 else closedatabase ();
53 }
54
55 openfile = filename;
[15557]56
57 // Map the DB mode values into GDBM mode values
58 int gdbm_mode = GDBM_READER;
59 if (mode == DB_WRITER)
60 {
61 gdbm_mode = GDBM_WRITER;
62 }
63 else if (mode == DB_WRITER_CREATE)
64 {
65 gdbm_mode = GDBM_WRCREAT;
66 }
67
[15429]68 char *namebuffer = filename.getcstr();
69 do {
70#ifdef __WIN32__
[15557]71 gdbmfile = gdbm_open (namebuffer, block_size, gdbm_mode, 00664, NULL, (need_filelock) ? 1 : 0);
[15429]72#else
[15557]73 gdbmfile = gdbm_open (namebuffer, block_size, gdbm_mode, 00664, NULL);
[15429]74#endif
75 --num_retrys;
76 } while (num_retrys>0 && gdbmfile==NULL &&
77 (gdbm_errno==GDBM_CANT_BE_READER || gdbm_errno==GDBM_CANT_BE_WRITER));
78 delete []namebuffer;
79
80 if (gdbmfile == NULL && logout != NULL) {
81 outconvertclass text_t2ascii;
82 (*logout) << text_t2ascii << "database open failed on: " << filename << "\n";
83 }
84
85 return (gdbmfile != NULL);
86}
87
88
89void gdbmclass::closedatabase ()
90{
91 if (gdbmfile == NULL) return;
92
93 gdbm_close (gdbmfile);
94 gdbmfile = NULL;
95 openfile.clear();
96}
97
98
[15644]99void gdbmclass::deletekey (const text_t &key)
100{
101 if (gdbmfile == NULL) return;
102
103 // get a utf-8 encoded c string of the unicode key
104 datum key_data;
105 key_data.dptr = (to_utf8(key)).getcstr();
106 if (key_data.dptr == NULL) return;
107 key_data.dsize = strlen (key_data.dptr);
108
109 // delete the key
110 gdbm_delete (gdbmfile, key_data);
111
112 // free up the key memory
113 delete []key_data.dptr;
114}
115
116
[15429]117// returns true on success
[15644]118bool gdbmclass::getkeydata (const text_t& key, text_t &data)
119{
120 datum key_data;
121 datum return_data;
122
123 if (gdbmfile == NULL) return false;
124
125 // get a utf-8 encoded c string of the unicode key
126 key_data.dptr = (to_utf8(key)).getcstr();
127 if (key_data.dptr == NULL) {
128 if (logout != NULL) (*logout) << "gdbmclass: out of memory\n";
129 return false;
130 }
131 key_data.dsize = strlen (key_data.dptr);
132
133 // fetch the result
134 return_data = gdbm_fetch (gdbmfile, key_data);
135 delete []key_data.dptr;
136
137 if (return_data.dptr == NULL) return false;
138
139 data.setcarr (return_data.dptr, return_data.dsize);
140 free (return_data.dptr);
141 data = to_uni(data); // convert to unicode
142
143 return true;
144}
145
146
147// returns array of keys
148text_tarray gdbmclass::getkeys ()
149{
150 text_tarray keys;
151
152 text_t key = getfirstkey();
153 while (!key.empty())
154 {
155 keys.push_back(key);
156 key = getnextkey(key);
157 }
158
159 return keys;
160}
161
162
163// returns true on success
[15649]164bool gdbmclass::setkeydata (const text_t &key, const text_t &data)
[15429]165{
166 if (gdbmfile == NULL) return false;
167
168 // store the value
169 datum key_data;
170 datum data_data;
171
172 // get a utf-8 encoded c string of the unicode key
173 key_data.dptr = (to_utf8(key)).getcstr();
174 if (key_data.dptr == NULL) {
175 if (logout != NULL) (*logout) << "gdbmclass: out of memory\n";
176 return false;
177 }
178 key_data.dsize = strlen (key_data.dptr);
179
180 data_data.dptr = (to_utf8(data)).getcstr();
181 if (data_data.dptr == NULL) {
182 if (logout != NULL) (*logout) << "gdbmclass: out of memory\n";
183 delete []key_data.dptr;
184 return false;
185 }
186 data_data.dsize = strlen (data_data.dptr);
187
188 int ret = gdbm_store (gdbmfile, key_data, data_data, GDBM_REPLACE);
189 delete []key_data.dptr;
190 delete []data_data.dptr;
191
192 return (ret == 0);
193}
194
195
[15644]196// ----------------------------------------------------------------------------------------
197// GDBM-ONLY FUNCTIONS
198// ----------------------------------------------------------------------------------------
[15429]199
200// getfirstkey and getnextkey are used for traversing the database
201// no insertions or deletions should be carried out while traversing
202// the database. when there are no keys left to visit in the database
203// an empty string is returned.
204text_t gdbmclass::getfirstkey ()
205{
206 if (gdbmfile == NULL) return g_EmptyText;
207
208 // get the first key
209 datum firstkey_data = gdbm_firstkey (gdbmfile);
210 if (firstkey_data.dptr == NULL) return g_EmptyText;
211
212 // convert it to text_t
213 text_t firstkey;
214 firstkey.setcarr (firstkey_data.dptr, firstkey_data.dsize);
215 free (firstkey_data.dptr);
216 return to_uni(firstkey); // convert to unicode
217}
218
219
220text_t gdbmclass::getnextkey (const text_t &key)
221{
222 if (gdbmfile == NULL || key.empty()) return g_EmptyText;
223
224 // get a utf-8 encoded c string of the unicode key
225 datum key_data;
226 key_data.dptr = (to_utf8(key)).getcstr();
227 if (key_data.dptr == NULL) return g_EmptyText;
228 key_data.dsize = strlen (key_data.dptr);
229
230 // get the next key
231 datum nextkey_data = gdbm_nextkey (gdbmfile, key_data);
232 if (nextkey_data.dptr == NULL) {
233 delete []key_data.dptr;
234 return g_EmptyText;
235 }
236
237 // convert it to text_t
238 text_t nextkey;
239 nextkey.setcarr (nextkey_data.dptr, nextkey_data.dsize);
240 free (nextkey_data.dptr);
241 delete []key_data.dptr;
242 return to_uni(nextkey); // convert to unicode
243}
Note: See TracBrowser for help on using the repository browser.