Changeset 1913


Ignore:
Timestamp:
2001-02-07T12:07:28+13:00 (23 years ago)
Author:
kjm18
Message:

history revamp. new format: numdocs args. query num no longer saved, so
#x in a query no longer references previous queries. deletion of history no
longer provided, max saved queries per user set in MAX_RECORDS (20).
For new user, history only saved once history display has been turned on.

Location:
trunk/gsdl/src/recpt
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/gsdl/src/recpt/historydb.cpp

    r1786 r1913  
    3030#include "OIDtools.h"
    3131
     32#define MAX_RECORDS 20
    3233
    3334// returns true on success (in which case historyinfo will contain
     
    6465
    6566// returns true on success
    66 bool set_history_info (const text_t &userid, const text_t &history, const text_t &gsdlhome) {
     67// changed to only save 20 records per user, numbers not included
     68// only save if there are already entries there, or if display=true
     69bool set_history_info (const text_t &userid, const text_t &history, const text_t &gsdlhome, bool display) {
    6770
    6871  text_t historyfile = filename_cat(gsdlhome, "etc", "history.db");
     
    7275  gdbmclass historydb;
    7376 
    74   text_t querynum;
    75   text_t historyresult;
    76 
    77  
     77  text_t oldhistoryresult;
     78  text_t newhistoryresult;
     79  int numentries=0;
     80
    7881  if ( !historydb.opendatabase(historyfile, GDBM_READER, 1000, true)) {
    7982    // not created yet
    80     historyresult="";
    81     querynum="1";
     83    oldhistoryresult="";
     84    if (!display) return true; // dont need to save
    8285  }
    8386  else {
    8487
    8588    // get history list
    86    if (! historydb.getkeydata(userid, historyresult)) {
    87      historyresult="";
    88      querynum="1";
     89   if (! historydb.getkeydata(userid, oldhistoryresult)) {
     90     oldhistoryresult="";
     91     if (!display) return true; // dont need to save
    8992   }
    9093   historydb.closedatabase();
    9194  }
    9295
    93   // get next query num
    94   if (historyresult!="") {
    95     text_tarray entries;
    96     splitchar(historyresult.begin(), historyresult.end(), '\n', entries);
    97     get_query_num(entries.back(), querynum);
    98     querynum.setint(querynum.getint()+1);
     96  text_tarray entries;
     97 
     98  if (oldhistoryresult!="") {
     99    splitchar(oldhistoryresult.begin(), oldhistoryresult.end(), '\n', entries);
     100    numentries = entries.size();
     101    if (numentries >= MAX_RECORDS) numentries = MAX_RECORDS-1;
    99102  }
    100103 
    101104  // open for writing
    102105  if (!historydb.opendatabase(historyfile, GDBM_WRCREAT, 1000, true)) return false;
    103    
    104   // add on new line
    105   historyresult += querynum;
    106   historyresult += ":";
    107   historyresult += history;
    108   historyresult += "\n";
    109  
    110     if (historydb.setinfo(userid, historyresult))
    111       result=true;
    112    
    113     historydb.closedatabase();
    114     return result;
     106 
     107  // add on new linethe new record to the front of the list, then add the
     108  // appropriate entries from the old stuff
     109  newhistoryresult += history;
     110  newhistoryresult += "\n";
     111  for (int i=0; i<numentries;i++) {
     112    newhistoryresult +=  entries[i]+"\n";
     113  }
     114 
     115  if (historydb.setinfo(userid, newhistoryresult))
     116    result=true;
     117 
     118  historydb.closedatabase();
     119  return result;
    115120}
    116121
     
    130135 
    131136}
    132 
    133 //deletes only the selected records
    134 bool delete_history_info (const text_t &userid, const text_t &deletemode,
    135               const text_t &selection, const text_t &gsdlhome) {
    136 
    137   text_t historyfile = filename_cat(gsdlhome, "etc", "history.db");
    138   bool result = false;
    139   // open the history database 
    140   gdbmclass historydb;
    141  
    142   if ( !historydb.opendatabase(historyfile, GDBM_READER, 1000, true)) return false;
    143 
    144   // get history list
    145   text_t historyresult;
    146 
    147   if (! historydb.getkeydata(userid, historyresult)) return false;
    148    
    149   historydb.closedatabase();
    150 
    151   text_t newhistory; // for the new list of search history
    152   // get list of queries
    153   text_tarray queries;
    154   splitchar(historyresult.begin(), historyresult.end(), '\n', queries);
    155   text_tarray::iterator begin=queries.begin();
    156   text_tarray::iterator end=queries.end();
    157  
    158   // get list of numbers to delete
    159   text_tarray numbers;
    160   splitchar(selection.begin(), selection.end(), ',', numbers);
    161   text_tarray::iterator numbegin=numbers.begin();
    162   text_tarray::iterator numend=numbers.end();
    163 
    164   bool tdefault, tset;
    165   if (deletemode=="delete") {
    166     tdefault=true;
    167     tset=false;
    168   }
    169   else {// deletemode == save
    170     tdefault=false;
    171     tset=true;
    172   }
    173 
    174   // create a HistRecord map of all the entries
    175   HistRecordmap records;
    176   while (begin != end) {
    177     HistRecord rec;
    178     rec.entry=*begin;
    179     rec.save=tdefault;
    180     text_t num;
    181     get_query_num(*begin, num);
    182     records[num] = rec;
    183     begin++;
    184   }
    185 
    186  
    187   // now set the save field for all records that are selected
    188   while(numbegin != numend) {
    189    
    190     if (is_number(*numbegin)) {
    191       if (records.count(*numbegin)==1) {
    192     records[*numbegin].save=tset;
    193       } // else invalid number
    194     }
    195     else{
    196       int start, stop;
    197       if (get_selection_params(*numbegin, start, stop)) {
    198     for (int i=start; i<=stop; i++) {
    199       text_t num = i;
    200       if (records.count(num)==1) {
    201         records[num].save=tset;
    202       }
    203     }
    204       }
    205       else { // dodgy format
    206     // error message
    207       }
    208      
    209     }
    210     numbegin++;
    211   } // while
    212  
    213   HistRecordmap::iterator recbegin = records.begin();
    214   HistRecordmap::iterator recend = records.end();
    215  
    216   //create new history record - go through all Records
    217   // and add to new history those with save set to true
    218   while (recbegin != recend) {
    219     if ((*recbegin).second.save) {
    220       expand_query((*recbegin).second, records);
    221       newhistory += (*recbegin).second.entry + "\n";
    222     }
    223     recbegin++;
    224   }
    225  
    226   // open for writing
    227   if (!historydb.opendatabase(historyfile, GDBM_WRITER, 1000, true)) return false;
    228  
    229   if (historydb.setinfo(userid, newhistory)) result = true;
    230  
    231   historydb.closedatabase();
    232   return result;
    233 }
    234 
    235 bool get_selection_params (text_t &data, int &start, int &stop) {
    236  
    237   text_tarray results;
    238  
    239   splitchar(data.begin(), data.end(), '-', results);
    240   if (results.size()==2 && is_number(results[0]) && is_number(results[1])) {
    241     start=results[0].getint();
    242     stop=results[1].getint();
    243     return true;
    244   }
    245  
    246   // error message
    247   return false;
    248 }
    249 
    250 // expand query takes a HistRecord, and expands out any hashes in
    251 // the query string for queries that aren't to be saved
    252 bool expand_query(HistRecord &record,  HistRecordmap &records) {
    253 
    254   text_tarray args;
    255   splitchar(record.entry.begin(), record.entry.end(), '&', args);
    256 
    257   text_tarray::iterator begin=args.begin();
    258   text_tarray::iterator end=args.end();
    259 
    260   text_t query;
    261   // find the q argument
    262   while(begin != end) {
    263     if ((*begin)[0] == 'q'&& (*begin)[1] == '=') {
    264       query=*begin;
    265       args.erase(begin);
    266       break;
    267     } else begin++;
    268   }
    269   if (query !="") {
    270    
    271     //remove the q=
    272     text_t::iterator front = query.begin();
    273     query.erase(front);
    274     front=query.begin();
    275    
    276     query.erase(front);
    277     decode_cgi_arg(query);
    278     // now have just the query string
    279     // check any refs in it to see if they are still valid
    280     combine_query(query, records);
    281     text_t formattedquery = cgi_safe(query);
    282     text_t newquery = "q=";
    283     newquery += formattedquery;
    284 
    285     args.push_back(newquery);
    286     joinchar(args, '&', record.entry);
    287    
    288     return true;
    289   }
    290   return false;
    291 }
    292 
    293 // replaces a reference to a previous query with the search
    294 // string from that query
    295 bool combine_query(text_t &userid, text_t &query, const text_t &gsdlhome)
    296 {
    297   text_t::iterator begin = query.begin();
    298   text_t::iterator end = query.end();
    299   text_t::iterator it = findchar(begin, end, '#');
    300   if (it==end) return true;  // no need to swap anything
    301    
    302   bool result=true;
    303   text_t queryresult = "";
    304   text_t historyfile = filename_cat(gsdlhome, "etc", "history.db");
    305   text_t historyresult;
    306   // open the history database 
    307   gdbmclass historydb;
    308   bool exists = false;
    309   if (historydb.opendatabase(historyfile, GDBM_READER, 1000, true)) {
    310     // get history list
    311     if (historydb.getkeydata(userid, historyresult)) {
    312       exists=true;
    313      
    314       historydb.closedatabase();
    315     }
    316   }
    317   if (!exists) {// cant open history file, or user entry doesn't exist. replace #x with blanks
    318     while(it !=end) {
    319       queryresult += substr(begin, it);
    320       it++;
    321       if (*it<'0' || *it>'9') {
    322     queryresult.push_back('#'); // put the hash back if its not next to a number
    323       }     
    324       else {
    325     while(*it>='0'&&*it<='9') it++;
    326     result = false;
    327       }
    328       begin=it;
    329       it=findchar(begin, end, '#');
    330     }
    331     queryresult += substr(begin, end);
    332     query = queryresult;
    333     return result;
    334   }
    335 
    336   // if have got to here, have a previous history in historyresult
    337   text_tarray historyinfo;
    338   splitchar(historyresult.begin(), historyresult.end(), '\n', historyinfo);
    339   text_tarray::iterator histbegin = historyinfo.begin();
    340   text_tarray::iterator histend = historyinfo.end();
    341  
    342   text_tmap historymap;
    343   // put all entries into a map, so can pull out the appropriate one easily
    344   while (histbegin != histend) {
    345     text_t num;
    346     get_query_num(*histbegin, num);
    347     historymap[num]=*histbegin;
    348     histbegin++;
    349   }
    350   while(it!=end) { // while there still is a hash present
    351     text_t querynum;
    352     text_t newquery;
    353    
    354     while (begin!=end) {
    355       if (*begin==text_t('#')) {
    356     begin++;
    357     if(*begin<'0'||*begin>'9') { // not a history ref, leave in
    358       queryresult.push_back('#');
    359     }
    360     else { // history ref
    361       while(begin !=end && *begin>='0'&&*begin<='9') {
    362         querynum.push_back(*begin);
    363         begin++;
    364       }
    365       text_t oldquery = historymap[querynum];
    366       if (oldquery !="") {   // valid entry
    367         parse_saved_args(oldquery, "q", newquery);
    368         decode_cgi_arg(newquery);
    369         queryresult += newquery;
    370       }
    371       else {
    372         result=false; // have replaced #n with nothing
    373       }
    374       querynum.clear();
    375     }
    376       } // if #
    377       else {
    378     queryresult.push_back(*begin);
    379     begin++;
    380       }
    381     } // while begin!=end
    382    
    383     // have got to end of query string,
    384     // now go back and check for internal #
    385     query = queryresult;
    386     begin = query.begin();
    387     end = query.end();
    388     it = findchar(begin, end, '#');
    389     queryresult.clear();
    390    
    391   } // while it !=end
    392  
    393  
    394   return result;
    395  
    396 } // combine query
    397 
    398 
    399 // replaces a reference to a previous query with the search
    400 // string from that query, uses the Histrecordmap rather than the GDBM file
    401 bool combine_query( text_t &query, HistRecordmap &records)
    402 {
    403   text_t::iterator begin = query.begin();
    404   text_t::iterator end = query.end();
    405   text_t::iterator it = findchar(begin, end, '#');
    406   if (it==end) return true;  // no need to swap anything
    407    
    408   text_t queryresult = "";
    409   bool changed=true;
    410   while(it!=end && changed) { // while there still is a hash present
    411                               // and query has changed since last time round
    412                               // we are leaving some #X in
    413     text_t querynum;
    414     text_t newquery;
    415     changed=false;
    416     while (begin!=end) { // go through the query looking for hash
    417       if (*begin==text_t('#')) {
    418     begin++;
    419     if ( *begin<'0' || *begin>'9') { // not a ref
    420       queryresult.push_back('#');
    421     }
    422     else {
    423       while(begin !=end && *begin>='0'&&*begin<='9') {
    424         querynum.push_back(*begin);
    425         begin++;
    426       }
    427       if(records.count(querynum)>0) { // valid entry
    428         if (!records[querynum].save){ // referenced record to be deleted
    429           // get the q arg out of referenced query
    430           parse_saved_args(records[querynum].entry, "q", newquery);
    431           decode_cgi_arg(newquery);
    432           queryresult += newquery;
    433           changed=true;
    434         }
    435         else { // leave the #x in
    436           queryresult.push_back('#');
    437           queryresult +=  querynum;
    438         }
    439       }// else do nothing (replace #x with nothing)
    440       querynum.clear();
    441       newquery.clear();
    442     }
    443       } // if its a hash
    444       else {
    445     queryresult.push_back(*begin);
    446     begin++;
    447       }
    448     } // while begin!=end
    449    
    450     // have got to end of query string,
    451     // now go back and check for internal #
    452     query = queryresult;
    453     begin = query.begin();
    454     end = query.end();
    455     it = findchar(begin, end, '#');
    456     queryresult.clear();
    457    
    458   } // while it !=end
    459  
    460   return true;
    461 } // combine query
    462137
    463138// retrieves the value of one of the arguments
     
    515190}
    516191
    517 void get_query_num(text_t &query, text_t &querynum)
    518 {
    519   text_t::iterator begin = query.begin();
    520 
    521   while (*begin >='0'&& *begin <='9') { // get the digits
    522     querynum.push_back(*begin);
    523     begin++;
    524   }
    525   if (*begin != ':') {
    526     // something has gone wrong
    527   }   
    528 }
    529 
    530 void split_saved_query(text_t &query, text_t &querynum, text_t &numdocs, text_t &cgiargs)
     192
     193void split_saved_query(text_t &query, text_t &numdocs, text_t &cgiargs)
    531194{
    532195  text_t::iterator begin = query.begin();
    533196  text_t::iterator end = query.end();
    534197 
    535   while (*begin >='0'&& *begin <='9') { // get the digits
    536     querynum.push_back(*begin);
    537     begin++;
    538   }
    539   if (*begin != ':') {
    540     // something has gone wrong
    541   }
    542   else begin++;
    543   while (*begin >='0'&& *begin <='9') { // get the digits
     198  while (*begin >='0'&& *begin <='9') { // get the digits for numdocs
    544199    numdocs.push_back(*begin);
    545200    begin++;
    546   }                                                                                                                         
     201  }         
     202                 
    547203  if (*begin == '+') {  // get the + if there
    548204    numdocs.push_back(*begin);
    549205    begin++;
    550206  }
    551 
     207  if (*begin == ':') { // have the old format - previous bit was record number
     208    numdocs.clear();
     209    begin++;
     210
     211    while(*begin >='0' && *begin <='9') { // get the digits
     212      numdocs.push_back(*begin);
     213      begin++;
     214    }
     215    if (*begin == '+') { // get the + if there
     216      numdocs.push_back(*begin);
     217      begin++;
     218    }
     219  }
    552220  cgiargs += (substr(begin, end));  // put rest of query into cgiargs
    553221
    554222}
    555223
    556 void format_user_info (text_t &cgiargs, text_t &userinfo,  recptprotolistclass *protos, ostream &logout)
     224void format_user_info (text_t &historyargs, text_t &userinfo, 
     225               cgiargsclass &args,
     226               recptprotolistclass *protos, ostream &logout)
    557227{
    558   logout << "in format user info";
    559228  text_tset metadata;
    560  
     229  userinfo.clear();
     230
    561231  infodbclass argsinfo;
    562   parse_saved_args(cgiargs, argsinfo);
     232  parse_saved_args(historyargs, argsinfo);
    563233 
    564234  text_t collect = argsinfo["c"];
     
    567237    return;
    568238  }
    569   recptproto *collectproto = protos->getrecptproto(collect,logout);
    570   if (collectproto == NULL) {
    571     userinfo="";
    572     return;
    573   }
    574   metadata.insert(argsinfo["h"]);
    575   FilterResponse_t response;
    576 
    577   get_info("collection", collect, metadata, false, collectproto, response, logout);
    578 
    579   text_t index = response.docInfo[0].metadata[argsinfo["h"]].values[0];
    580  
    581   text_t mode;
    582   if (argsinfo["b"]=="0") { // simple mode
    583     if (argsinfo["t"]=="0") {
    584       mode = "all words";
    585     }
    586     else { // t=1
    587       mode = "some words";
    588     }
     239
     240  if (collect != args["c"]) {
     241    userinfo += collect+", ";
     242  }
     243 
     244  if (argsinfo["h"] != args["h"]) {
     245 
     246    recptproto *collectproto = protos->getrecptproto(collect,logout);
     247    if (collectproto == NULL) {
     248      userinfo="";
     249      return;
     250    }
     251    metadata.insert(argsinfo["h"]);
     252    FilterResponse_t response;
    589253   
    590   }
    591   else { // advanced mode
    592     if (argsinfo["t"]=="0") {
    593       mode = "boolean";
     254    get_info("collection", collect, metadata, false, collectproto, response, logout);
     255    text_t index = response.docInfo[0].metadata[argsinfo["h"]].values[0];
     256    if (!index.empty()) {
     257      userinfo += index+", ";
     258    }
     259  }
     260
     261  if (argsinfo["b"] != args["b"] || argsinfo["t"] != args["t"]) {
     262    text_t mode;
     263    if (argsinfo["b"]=="0") { // simple mode
     264      if (argsinfo["t"]=="0") {
     265    mode = " _texthallwords_";
     266      }
     267      else { // t=1
     268    mode = " _texthsomewords_";
     269      }
     270     
     271    }
     272    else { // advanced mode
     273      if (argsinfo["t"]=="0") {
     274    mode = " _texthboolean_";
     275      }
     276      else {
     277    mode = " _texthranked_";
     278      }
     279    }
     280    userinfo += mode+", ";
     281  }
     282 
     283  if (argsinfo["k"] != args["k"]) {
     284    text_t options;
     285    if (argsinfo["k"]=="0") {
     286      options = " _texthcaseoff_";
    594287    }
    595288    else {
    596       mode = "ranked";
    597     }
    598   }
    599  
    600   text_t options;
    601   if (argsinfo["k"]=="0") {
    602     options = "case must match";
    603   }
    604   else {
    605     options = "ignore case";
    606   }
    607   if (argsinfo["s"]=="0") {
    608     options += ", whole word must match";
    609   }
    610   else {
    611     options += ", ignore word endings";
    612   }
    613  
    614   userinfo.clear();
    615   userinfo = "collection ("+argsinfo["c"] + ") ";
    616   userinfo += "search (" + index + ") ";
    617   userinfo += "mode (" + mode +") ";
    618   userinfo += "options (" + options + ")";
    619 
    620   logout << "in format user info - end";
    621 }
     289      options = " _texthcaseon_";
     290    }
     291    userinfo += options+", ";
     292  }
     293
     294  if (argsinfo["s"] != args["s"]) {
     295    text_t stem;
     296    if (argsinfo["s"]=="0") {
     297      stem = " _texthstemoff_";
     298    }
     299    else {
     300      stem = " _texthstemon_";
     301    }
     302    userinfo += stem+", ";
     303  }
     304
     305}
  • trunk/gsdl/src/recpt/historydb.h

    r1285 r1913  
    3131#include "text_t.h"
    3232#include "recptproto.h"
     33#include "cgiargs.h"
    3334
     35/*
    3436struct HistRecord {
    3537  text_t entry;
     
    4648typedef map<text_t, HistRecord, ltinttext_t> HistRecordmap;
    4749
     50*/
    4851// returns true on success (in which case historyinfo will contain
    4952// the information for this history)
     
    5356// returns true on success
    5457bool set_history_info (const text_t &userid, const text_t &historyinfo,
    55                const text_t &gsdlhome);
     58               const text_t &gsdlhome, bool display);
    5659
     60// delete all history for one user
    5761bool delete_all_history_info (const text_t &userid, const text_t &gsdlhome);
    58 
    59 // deletes only the entries specified
    60 bool delete_history_info(const text_t &userid, const text_t &deletemode,
    61              const text_t &selection, const text_t &gsdlhome);
    62 
    63 // takes a text_t with x-y, and retrieves the x and y params
    64 bool get_selection_params (text_t &data, int &start, int &stop);
    65 
    66 bool expand_query(HistRecord &query, HistRecordmap &records);
    67 
    68 // combine query looks for #x and replaces it with the query
    69 // string from the xth entry. THe first one looks up the xth
    70 // query in the database (used before running a query), the
    71 // second version looks it up inthe records map (used in
    72 // delete history -are doing a lotof #x replacing at once.
    73 bool combine_query(text_t &userid, text_t &query, const text_t &gsdlhome);
    74 bool combine_query(text_t &userid, HistRecordmap  &records);
    7562
    7663// retrieves the value of an arg (key) from a list of cgi args
     
    8067// extracts out the components of an entry in the database
    8168// currently:
    82 // querynum:numdocs cgiargs
    83 void split_saved_query(text_t &query, text_t &querynum, text_t &numdocs, text_t &cgiargs);
    84 
    85 // just extracts the query number out of the entry
    86 void get_query_num(text_t &query, text_t &querynum);
     69// numdocs cgiargs
     70void split_saved_query(text_t &query,  text_t &numdocs, text_t &cgiargs);
    8771
    8872// takes the cgiarg string, and outputs it in some form useful
    8973// to the user
    9074void format_user_info (text_t &cgiargs, text_t &info,
     75               cgiargsclass &args,
    9176               recptprotolistclass *protos, ostream &logout);
    9277
Note: See TracChangeset for help on using the changeset viewer.