greenstone.org greenstone wiki greenstone trac planet greenstone

Changeset 1913

Show
Ignore:
Timestamp:
2001-02-07 12:07:28 (8 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.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • 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