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

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