source: main/trunk/greenstone2/runtime-src/src/recpt/historydb.cpp@ 21808

Last change on this file since 21808 was 21485, checked in by mdewsnip, 14 years ago

Modifying historydb.cpp so it uses the more general dbclass object instead of being hard-wired to use gdbmclass. However, this class is still set up to use gdbm, provided USE_GDBM is set (which it always is in the main Greenstone). The problem with the history database is it is Greenstone-specific, not collection-specific, so there is no infodbtype option to check to see what database type should be used (a new option will need to be created in the main.cfg file). If USE_GDBM isn't set, the historydb class will do nothing.

  • Property svn:keywords set to Author Date Id Revision
File size: 8.7 KB
Line 
1/**********************************************************************
2 *
3 * historydb.cpp --
4 * Copyright (C) 1999 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 "historydb.h"
27#include "fileutil.h"
28#include "cgiutils.h"
29#include "recptproto.h"
30#include "recptprototools.h"
31#include "dbclass.h"
32
33#ifdef USE_GDBM
34#include "gdbmclass.h"
35#endif
36
37
38#define MAX_RECORDS 20
39#define HIST_SEP ';'
40
41
42dbclass* get_history_db_ptr ()
43{
44 // Create a dbclass of the correct type
45 dbclass *historydb = NULL;
46
47 // Use GDBM only at this stage
48#ifdef USE_GDBM
49 historydb = new gdbmclass();
50#endif
51
52 return historydb;
53}
54
55
56// returns true on success (in which case historyinfo will contain
57// the information for this history)
58bool get_history_info (const text_t &userid, text_tarray &historyinfo,
59 const text_t &gsdlhome, ostream &logout) {
60
61 bool result = false;
62
63 // Create a dbclass of the correct type
64 dbclass *historydb = get_history_db_ptr();
65 if (historydb == NULL) return false;
66 text_t historyfile = filename_cat(gsdlhome, "etc", "history") + historydb->getfileextension();
67
68 // open the history database
69 if (historydb->opendatabase(historyfile, DB_READER, 1000, true)) {
70 // get history list
71 text_t historyresult;
72
73 historydb->getkeydata(userid, historyresult);
74
75 if (historyresult != "") { // there are entries, process them
76
77 splitchar(historyresult.begin(), historyresult.end(), '\n', historyinfo);
78 result = true;
79 }
80 historydb->closedatabase();
81
82 } else {
83 outconvertclass text_t2ascii;
84 logout << text_t2ascii << "couldn't open history database " << historyfile << "\n";
85 }
86
87 delete historydb;
88 return result;
89}
90
91
92// returns true on success
93// changed to only save 20 records per user, numbers not included
94// only save if there are already entries there, or if display=true
95bool set_history_info (const text_t &userid, const text_t &history, const text_t &gsdlhome, bool display) {
96
97 bool result = false;
98
99 // Create a dbclass of the correct type
100 dbclass *historydb = get_history_db_ptr();
101 if (historydb == NULL) return false;
102 text_t historyfile = filename_cat(gsdlhome, "etc", "history") + historydb->getfileextension();
103
104 text_t oldhistoryresult;
105 text_t newhistoryresult;
106 int numentries=0;
107
108 // open the history database
109 if (!historydb->opendatabase(historyfile, DB_READER, 1000, true)) {
110 // not created yet
111 oldhistoryresult="";
112 if (!display) return true; // dont need to save
113 }
114 else {
115
116 // get history list
117 if (! historydb->getkeydata(userid, oldhistoryresult)) {
118 oldhistoryresult="";
119 if (!display) return true; // dont need to save
120 }
121 historydb->closedatabase();
122 }
123
124 text_tarray entries;
125
126 if (oldhistoryresult!="") {
127 splitchar(oldhistoryresult.begin(), oldhistoryresult.end(), '\n', entries);
128 numentries = entries.size();
129 if (numentries >= MAX_RECORDS) numentries = MAX_RECORDS-1;
130 }
131
132 // open for writing
133 if (!historydb->opendatabase(historyfile, DB_WRITER_CREATE, 1000, true)) return false;
134
135 // add on new linethe new record to the front of the list, then add the
136 // appropriate entries from the old stuff
137 newhistoryresult += history;
138 newhistoryresult += "\n";
139 for (int i=0; i<numentries;++i) {
140 newhistoryresult += entries[i]+"\n";
141 }
142
143 if (historydb->setkeydata(userid, newhistoryresult))
144 result=true;
145
146 historydb->closedatabase();
147 delete historydb;
148 return result;
149}
150
151// deletes all a users history
152bool delete_all_history_info (const text_t &userid, const text_t &gsdlhome) {
153
154 // Create a dbclass of the correct type
155 dbclass *historydb = get_history_db_ptr();
156 if (historydb == NULL) return false;
157 text_t historyfile = filename_cat(gsdlhome, "etc", "history") + historydb->getfileextension();
158
159 // open the history database
160 if (!historydb->opendatabase(historyfile, DB_WRITER, 1000, true)) return false;
161
162 historydb->deletekey(userid);
163 historydb->closedatabase();
164 delete historydb;
165 return true;
166
167}
168
169// retrieves the value of one of the arguments
170void parse_saved_args(text_t &args, text_t key, text_t &value)
171{
172 text_t::iterator here = args.begin();
173 text_t::iterator end = args.end();
174 text_t::iterator it;
175 while (here != end) {
176 if(*here==key[0]) {
177 it=findchar(here, end, '=');
178 if (it==end) {
179 value=""; return;
180 }
181 text_t entry = substr(here, it);
182 if (entry==key) {
183 here=it+1;
184 it=findchar(here, end, HIST_SEP);
185 value = substr(here, it);
186 return;
187 }
188 }
189 ++here;
190 }// while
191}
192
193// retrieves the value of all of the arguments
194void parse_saved_args(text_t &args, infodbclass &info)
195{
196 text_t::iterator here = args.begin();
197 text_t::iterator end = args.end();
198 text_t::iterator it;
199 text_tarray values;
200
201 splitchar(here, end, HIST_SEP, values);
202
203 text_tarray::iterator start = values.begin();
204 text_tarray::iterator stop = values.end();
205
206 text_t key;
207 text_t value;
208 while(start!=stop) {
209
210 here=(*start).begin();
211 end=(*start).end();
212 it=findchar(here, end, '=');
213 if (it!=end) {
214 key = substr(here, it);
215 value = substr(it+1, end);
216
217 info[key]=value;
218 }
219 ++start;
220 }
221}
222
223
224void split_saved_query(text_t &query, text_t &numdocs, text_t &cgiargs)
225{
226 text_t::iterator begin = query.begin();
227 text_t::iterator end = query.end();
228
229 while (*begin >='0'&& *begin <='9') { // get the digits for numdocs
230 numdocs.push_back(*begin);
231 ++begin;
232 }
233
234 if (*begin == '+') { // get the + if there
235 numdocs.push_back(*begin);
236 ++begin;
237 }
238 if (*begin == ':') { // have the old format - previous bit was record number
239 numdocs.clear();
240 ++begin;
241
242 while(*begin >='0' && *begin <='9') { // get the digits
243 numdocs.push_back(*begin);
244 ++begin;
245 }
246 if (*begin == '+') { // get the + if there
247 numdocs.push_back(*begin);
248 ++begin;
249 }
250 }
251 cgiargs += (substr(begin, end)); // put rest of query into cgiargs
252
253}
254
255void format_user_info (text_t &historyargs, text_t &userinfo,
256 cgiargsclass &args,
257 recptprotolistclass *protos, ostream &logout)
258{
259 text_tset metadata;
260 userinfo.clear();
261
262 infodbclass argsinfo;
263 parse_saved_args(historyargs, argsinfo);
264 text_t collect = argsinfo["c"];
265 if (collect=="") {
266 userinfo="";
267 return;
268 }
269
270 if (collect != args["c"]) {
271 userinfo += collect+", ";
272 }
273
274 if (argsinfo["h"] != args["h"]) {
275
276 recptproto *collectproto = protos->getrecptproto(collect,logout);
277 if (collectproto == NULL) {
278 userinfo="";
279 return;
280 }
281 metadata.insert(argsinfo["h"]);
282 FilterResponse_t response;
283
284 get_info("collection", collect, args["l"], metadata, false, collectproto, response, logout);
285 text_t index = response.docInfo[0].metadata[argsinfo["h"]].values[0];
286 if (!index.empty()) {
287 userinfo += index+", ";
288 }
289 }
290
291 if (argsinfo["b"] != args["b"] || argsinfo["t"] != args["t"]) {
292 if (argsinfo["b"]=="0") { // simple mode
293 if (argsinfo["t"]=="0") {
294 userinfo += " _texthallwords_, ";
295 }
296 else if (argsinfo["t"]=="1"){
297 userinfo += " _texthsomewords_, ";
298 }
299
300 }
301 else if (argsinfo["b"] == "1") { // advanced mode
302 if (argsinfo["t"]=="0") {
303 userinfo += " _texthboolean_, ";
304 }
305 else if (argsinfo["t"]=="1") {
306 userinfo += " _texthranked_, ";
307 }
308 }
309 }
310
311 if (argsinfo["k"] != "" && argsinfo["k"] != args["k"]) {
312 text_t options;
313 // the text translations are the wrong way round
314 if (argsinfo["k"]=="1") {
315 userinfo += " _texthcaseoff_, ";
316 }
317 else if (argsinfo["k"]=="0") {
318 userinfo += " _texthcaseon_, ";
319 }
320 }
321
322 if (argsinfo["s"] != "" && argsinfo["s"] != args["s"]) {
323 if (argsinfo["s"]=="0") {
324 userinfo += " _texthstemoff_, ";
325 }
326 else if (argsinfo["s"]=="1") {
327 userinfo += " _texthstemon_, ";
328 }
329 }
330
331}
Note: See TracBrowser for help on using the repository browser.