diff --git a/src/lib/Makefile b/src/lib/Makefile index 29599540..2116a93d 100644 --- a/src/lib/Makefile +++ b/src/lib/Makefile @@ -6,8 +6,8 @@ LIBS = librcl.a all: $(LIBS) -OBJS = rclaspell.o rclconfig.o rclinit.o textsplit.o unacpp.o beaglequeue.o csguess.o fsindexer.o indexer.o mimetype.o htmlparse.o myhtmlparse.o mimehandler.o internfile.o mh_exec.o mh_execm.o mh_html.o mh_mail.o mh_mbox.o mh_text.o docseq.o docseqdb.o docseqhist.o filtseq.o history.o plaintorich.o recollq.o reslistpager.o sortseq.o wasastringtoquery.o wasatorcl.o rcldb.o rcldoc.o rclquery.o searchdata.o stemdb.o stoplist.o base64.o circache.o closefrom.o conftree.o copyfile.o debuglog.o execmd.o fstreewalk.o idfile.o fileudi.o md5.o mimeparse.o netcon.o pathut.o pxattr.o readfile.o smallut.o transcode.o wipedir.o x11mon.o mime-getpart.o mime-parsefull.o mime-parseonlyheader.o mime-printbody.o mime-printdoc.o mime-printheader.o mime.o convert.o iodevice.o iofactory.o -DEPS = rclaspell.dep.stamp rclconfig.dep.stamp rclinit.dep.stamp textsplit.dep.stamp unacpp.dep.stamp beaglequeue.dep.stamp csguess.dep.stamp fsindexer.dep.stamp indexer.dep.stamp mimetype.dep.stamp htmlparse.dep.stamp myhtmlparse.dep.stamp mimehandler.dep.stamp internfile.dep.stamp mh_exec.dep.stamp mh_execm.dep.stamp mh_html.dep.stamp mh_mail.dep.stamp mh_mbox.dep.stamp mh_text.dep.stamp docseq.dep.stamp docseqdb.dep.stamp docseqhist.dep.stamp filtseq.dep.stamp history.dep.stamp plaintorich.dep.stamp recollq.dep.stamp reslistpager.dep.stamp sortseq.dep.stamp wasastringtoquery.dep.stamp wasatorcl.dep.stamp rcldb.dep.stamp rcldoc.dep.stamp rclquery.dep.stamp searchdata.dep.stamp stemdb.dep.stamp stoplist.dep.stamp base64.dep.stamp circache.dep.stamp closefrom.dep.stamp conftree.dep.stamp copyfile.dep.stamp debuglog.dep.stamp execmd.dep.stamp fstreewalk.dep.stamp idfile.dep.stamp fileudi.dep.stamp md5.dep.stamp mimeparse.dep.stamp netcon.dep.stamp pathut.dep.stamp pxattr.dep.stamp readfile.dep.stamp smallut.dep.stamp transcode.dep.stamp wipedir.dep.stamp x11mon.dep.stamp mime-getpart.dep.stamp mime-parsefull.dep.stamp mime-parseonlyheader.dep.stamp mime-printbody.dep.stamp mime-printdoc.dep.stamp mime-printheader.dep.stamp mime.dep.stamp convert.dep.stamp iodevice.dep.stamp iofactory.dep.stamp +OBJS = rclaspell.o rclconfig.o rclinit.o textsplit.o unacpp.o beaglequeue.o csguess.o fsindexer.o indexer.o mimetype.o htmlparse.o myhtmlparse.o mimehandler.o internfile.o mh_exec.o mh_execm.o mh_html.o mh_mail.o mh_mbox.o mh_text.o docseq.o docseqdb.o docseqhist.o filtseq.o dynconf.o plaintorich.o recollq.o reslistpager.o sortseq.o wasastringtoquery.o wasatorcl.o rcldb.o rcldoc.o rclquery.o searchdata.o stemdb.o stoplist.o base64.o circache.o closefrom.o conftree.o copyfile.o debuglog.o execmd.o fstreewalk.o idfile.o fileudi.o md5.o mimeparse.o netcon.o pathut.o pxattr.o readfile.o smallut.o transcode.o wipedir.o x11mon.o mime-getpart.o mime-parsefull.o mime-parseonlyheader.o mime-printbody.o mime-printdoc.o mime-printheader.o mime.o convert.o iodevice.o iofactory.o +DEPS = rclaspell.dep.stamp rclconfig.dep.stamp rclinit.dep.stamp textsplit.dep.stamp unacpp.dep.stamp beaglequeue.dep.stamp csguess.dep.stamp fsindexer.dep.stamp indexer.dep.stamp mimetype.dep.stamp htmlparse.dep.stamp myhtmlparse.dep.stamp mimehandler.dep.stamp internfile.dep.stamp mh_exec.dep.stamp mh_execm.dep.stamp mh_html.dep.stamp mh_mail.dep.stamp mh_mbox.dep.stamp mh_text.dep.stamp docseq.dep.stamp docseqdb.dep.stamp docseqhist.dep.stamp filtseq.dep.stamp dynconf.dep.stamp plaintorich.dep.stamp recollq.dep.stamp reslistpager.dep.stamp sortseq.dep.stamp wasastringtoquery.dep.stamp wasatorcl.dep.stamp rcldb.dep.stamp rcldoc.dep.stamp rclquery.dep.stamp searchdata.dep.stamp stemdb.dep.stamp stoplist.dep.stamp base64.dep.stamp circache.dep.stamp closefrom.dep.stamp conftree.dep.stamp copyfile.dep.stamp debuglog.dep.stamp execmd.dep.stamp fstreewalk.dep.stamp idfile.dep.stamp fileudi.dep.stamp md5.dep.stamp mimeparse.dep.stamp netcon.dep.stamp pathut.dep.stamp pxattr.dep.stamp readfile.dep.stamp smallut.dep.stamp transcode.dep.stamp wipedir.dep.stamp x11mon.dep.stamp mime-getpart.dep.stamp mime-parsefull.dep.stamp mime-parseonlyheader.dep.stamp mime-printbody.dep.stamp mime-printdoc.dep.stamp mime-printheader.dep.stamp mime.dep.stamp convert.dep.stamp iodevice.dep.stamp iofactory.dep.stamp librcl.a : $(DEPS) $(OBJS) unac.o ar ru librcl.a $(OBJS) unac.o @@ -63,8 +63,8 @@ docseqhist.o : ../query/docseqhist.cpp $(CXX) $(ALL_CXXFLAGS) -c ../query/docseqhist.cpp filtseq.o : ../query/filtseq.cpp $(CXX) $(ALL_CXXFLAGS) -c ../query/filtseq.cpp -history.o : ../query/history.cpp - $(CXX) $(ALL_CXXFLAGS) -c ../query/history.cpp +dynconf.o : ../query/dynconf.cpp + $(CXX) $(ALL_CXXFLAGS) -c ../query/dynconf.cpp plaintorich.o : ../query/plaintorich.cpp $(CXX) $(ALL_CXXFLAGS) -c ../query/plaintorich.cpp recollq.o : ../query/recollq.cpp @@ -227,9 +227,9 @@ docseqhist.dep.stamp : ../query/docseqhist.cpp filtseq.dep.stamp : ../query/filtseq.cpp $(CXX) -M $(ALL_CXXFLAGS) ../query/filtseq.cpp > filtseq.dep touch filtseq.dep.stamp -history.dep.stamp : ../query/history.cpp - $(CXX) -M $(ALL_CXXFLAGS) ../query/history.cpp > history.dep - touch history.dep.stamp +dynconf.dep.stamp : ../query/dynconf.cpp + $(CXX) -M $(ALL_CXXFLAGS) ../query/dynconf.cpp > dynconf.dep + touch dynconf.dep.stamp plaintorich.dep.stamp : ../query/plaintorich.cpp $(CXX) -M $(ALL_CXXFLAGS) ../query/plaintorich.cpp > plaintorich.dep touch plaintorich.dep.stamp @@ -350,7 +350,7 @@ include docseq.dep include docseqdb.dep include docseqhist.dep include filtseq.dep -include history.dep +include dynconf.dep include plaintorich.dep include recollq.dep include reslistpager.dep diff --git a/src/lib/mkMake b/src/lib/mkMake index 508ef77f..3b3527c7 100755 --- a/src/lib/mkMake +++ b/src/lib/mkMake @@ -28,7 +28,7 @@ ${depth}/query/docseq.cpp \ ${depth}/query/docseqdb.cpp \ ${depth}/query/docseqhist.cpp \ ${depth}/query/filtseq.cpp \ -${depth}/query/history.cpp \ +${depth}/query/dynconf.cpp \ ${depth}/query/plaintorich.cpp \ ${depth}/query/recollq.cpp \ ${depth}/query/reslistpager.cpp \ diff --git a/src/qtgui/guiutils.cpp b/src/qtgui/guiutils.cpp index 34eba66f..0eae58f0 100644 --- a/src/qtgui/guiutils.cpp +++ b/src/qtgui/guiutils.cpp @@ -184,8 +184,6 @@ void rwSettings(bool writing) // variable. // This are stored inside the dynamic configuration file (aka: history), // as they are likely to depend on RECOLL_CONFDIR. - const string allEdbsSk = "allExtDbs"; - const string actEdbsSk = "actExtDbs"; if (writing) { g_dynconf->eraseAll(allEdbsSk); for (list::const_iterator it = prefs.allExtraDbs.begin(); diff --git a/src/qtgui/main.cpp b/src/qtgui/main.cpp index b9e19774..3eae8274 100644 --- a/src/qtgui/main.cpp +++ b/src/qtgui/main.cpp @@ -83,7 +83,7 @@ RclConfig* RclConfig::getMainConfig() return rclconfig; } -RclHistory *g_dynconf; +RclDynConf *g_dynconf; int recollNeedsExit; int startIndexingAfterConfig; RclMain *mainWindow; @@ -276,7 +276,7 @@ int main(int argc, char **argv) #endif string historyfile = path_cat(rclconfig->getConfDir(), "history"); - g_dynconf = new RclHistory(historyfile); + g_dynconf = new RclDynConf(historyfile); if (!g_dynconf || !g_dynconf->ok()) { QString msg = app.translate("Main", "Configuration problem (dynconf"); QMessageBox::critical(0, "Recoll", msg); diff --git a/src/qtgui/preview_w.cpp b/src/qtgui/preview_w.cpp index 6fbf2d00..909628a9 100644 --- a/src/qtgui/preview_w.cpp +++ b/src/qtgui/preview_w.cpp @@ -75,6 +75,7 @@ using std::pair; #include "cancelcheck.h" #include "preview_w.h" #include "guiutils.h" +#include "docseqhist.h" #if (QT_VERSION < 0x030300) #define wasCanceled wasCancelled @@ -950,7 +951,9 @@ bool Preview::loadDocInCurrentTab(const Rcl::Doc &idoc, int docnum) } // Enter document in document history - g_dynconf->enterDoc(idoc.url, idoc.ipath); + map::const_iterator udit = idoc.meta.find(Rcl::Doc::keyudi); + if (udit != idoc.meta.end()) + historyEnterDoc(g_dynconf, udit->second); editor->setFocus(); emit(previewExposed(this, m_searchId, docnum)); diff --git a/src/qtgui/rclmain_w.cpp b/src/qtgui/rclmain_w.cpp index 9931f5f6..7ed7dd85 100644 --- a/src/qtgui/rclmain_w.cpp +++ b/src/qtgui/rclmain_w.cpp @@ -779,7 +779,6 @@ void RclMain::previewPrevOrNextInTab(Preview * w, int sid, int docnum, bool nxt) return; } - // Check that file exists in file system w->makeDocCurrent(doc, docnum, true); } @@ -910,7 +909,7 @@ void RclMain::startNativeViewer(Rcl::Doc doc) return; } - // Extract possible attributes + // Extract possible viewer attributes ConfSimple attrs; string cmd; rclconfig->valueSplitAttributes(cmdplusattr, cmd, attrs); @@ -1037,8 +1036,9 @@ void RclMain::startNativeViewer(Rcl::Doc doc) QString::fromUtf8(prcmd.c_str()) + "]"; stb->message(msg, 5000); } + if (!istempfile) - g_dynconf->enterDoc(fn, doc.ipath); + historyEnterDoc(g_dynconf, doc.meta[Rcl::Doc::keyudi]); // We should actually monitor these processes so that we can // delete the temp files when they exit LOGDEB(("Executing: [%s]\n", ncmd.c_str())); @@ -1124,7 +1124,7 @@ void RclMain::eraseDocHistory() { // Clear file storage if (g_dynconf) - g_dynconf->eraseAll(RclHistory::docSubkey); + g_dynconf->eraseAll(docHistSubKey); // Clear possibly displayed history if (resList->displayingHistory()) { showDocHistory(); diff --git a/src/qtgui/recoll.h b/src/qtgui/recoll.h index 3b53b469..89b7b9e8 100644 --- a/src/qtgui/recoll.h +++ b/src/qtgui/recoll.h @@ -22,7 +22,7 @@ #include "rclconfig.h" #include "rcldb.h" #include "idxthread.h" -#include "history.h" +#include "dynconf.h" // Misc declarations in need of sharing between the UI files @@ -33,7 +33,7 @@ extern RclConfig *rclconfig; extern Rcl::Db *rcldb; extern int recollNeedsExit; extern int startIndexingAfterConfig; // 1st startup -extern RclHistory *g_dynconf; +extern RclDynConf *g_dynconf; extern void startManual(const string& helpindex); #ifdef RCL_USE_ASPELL diff --git a/src/query/docseqhist.cpp b/src/query/docseqhist.cpp index d661ddb6..8b309b01 100644 --- a/src/query/docseqhist.cpp +++ b/src/query/docseqhist.cpp @@ -25,6 +25,84 @@ static char rcsid[] = "@(#$Id: docseqhist.cpp,v 1.4 2008-09-29 08:59:20 dockes E #include "rcldb.h" #include "fileudi.h" #include "internfile.h" +#include "base64.h" +#include "debuglog.h" +#include "smallut.h" + +// Encode document history entry: +// U + Unix time + base64 of udi +// The U distinguishes udi-based entries from older fn+ipath ones +bool RclDHistoryEntry::encode(string& value) +{ + char chartime[20]; + sprintf(chartime, "%ld", unixtime); + string budi; + base64_encode(udi, budi); + value = string("U ") + string(chartime) + " " + budi; + return true; +} + +// Decode. We support historical entries which were like "time b64fn [b64ipath]" +// Current entry format is "U time b64udi" +bool RclDHistoryEntry::decode(const string &value) +{ + list vall; + stringToStrings(value, vall); + + list::const_iterator it = vall.begin(); + udi.erase(); + string fn, ipath; + switch (vall.size()) { + case 2: + // Old fn+ipath, null ipath case + unixtime = atol((*it++).c_str()); + base64_decode(*it++, fn); + break; + case 3: + if (!it->compare("U")) { + // New udi-based entry + it++; + unixtime = atol((*it++).c_str()); + base64_decode(*it++, udi); + } else { + // Old fn + ipath. We happen to know how to build an udi + unixtime = atol((*it++).c_str()); + base64_decode(*it++, fn); + base64_decode(*it, ipath); + } + break; + default: + return false; + } + + if (!fn.empty()) { + // Old style entry found, make an udi, using the fs udi maker + make_udi(fn, ipath, udi); + } + LOGDEB(("RclDHistoryEntry::decode: udi [%s]\n", udi.c_str())); + return true; +} + +bool RclDHistoryEntry::equal(const DynConfEntry& other) +{ + const RclDHistoryEntry& e = dynamic_cast(other); + return e.udi == udi; +} + +bool historyEnterDoc(RclDynConf *dncf, const string& udi) +{ + LOGDEB(("historyEnterDoc: [%s] into %s\n", + udi.c_str(), dncf->getFilename().c_str())); + RclDHistoryEntry ne(time(0), udi); + RclDHistoryEntry scratch; + return dncf->insertNew(docHistSubKey, ne, scratch, 200); +} + +list getDocHistory(RclDynConf* dncf) +{ + return dncf->getList(docHistSubKey); +} + bool DocSequenceHistory::getDoc(int num, Rcl::Doc &doc, string *sh) { @@ -32,7 +110,7 @@ bool DocSequenceHistory::getDoc(int num, Rcl::Doc &doc, string *sh) if (!m_hist) return false; if (m_hlist.empty()) - m_hlist = m_hist->getDocHistory(); + m_hlist = getDocHistory(m_hist); if (num < 0 || num >= (int)m_hlist.size()) return false; @@ -48,7 +126,8 @@ bool DocSequenceHistory::getDoc(int num, Rcl::Doc &doc, string *sh) while (skip--) m_it++; if (sh) { - if (m_prevtime < 0 || abs (float(m_prevtime) - float(m_it->unixtime)) > 86400) { + if (m_prevtime < 0 || + abs (float(m_prevtime) - float(m_it->unixtime)) > 86400) { m_prevtime = m_it->unixtime; time_t t = (time_t)(m_it->unixtime); *sh = string(ctime(&t)); @@ -57,12 +136,10 @@ bool DocSequenceHistory::getDoc(int num, Rcl::Doc &doc, string *sh) } else sh->erase(); } - string udi; - make_udi(m_it->fn, m_it->ipath, udi); - bool ret = m_db->getDoc(udi, doc); + bool ret = m_db->getDoc(m_it->udi, doc); if (!ret) { - doc.url = string("file://") + m_it->fn; - doc.ipath = m_it->ipath; + doc.url = "UNKNOWN"; + doc.ipath = ""; } return ret; } @@ -79,6 +156,6 @@ bool DocSequenceHistory::getEnclosing(Rcl::Doc& doc, Rcl::Doc& pdoc) int DocSequenceHistory::getResCnt() { if (m_hlist.empty()) - m_hlist = m_hist->getDocHistory(); + m_hlist = getDocHistory(m_hist); return m_hlist.size(); } diff --git a/src/query/docseqhist.h b/src/query/docseqhist.h index c3ee72ce..be0a4152 100644 --- a/src/query/docseqhist.h +++ b/src/query/docseqhist.h @@ -19,18 +19,32 @@ /* @(#$Id: docseqhist.h,v 1.3 2008-09-29 08:59:20 dockes Exp $ (C) 2004 J.F.Dockes */ #include "docseq.h" -#include "history.h" +#include "dynconf.h" namespace Rcl { class Db; } +/** DynConf Document history entry */ +class RclDHistoryEntry : public DynConfEntry { + public: + RclDHistoryEntry() : unixtime(0) {} + RclDHistoryEntry(long t, const string& u) + : unixtime(t), udi(u) {} + virtual ~RclDHistoryEntry() {} + virtual bool decode(const string &value); + virtual bool encode(string& value); + virtual bool equal(const DynConfEntry& other); + long unixtime; + string udi; +}; + /** A DocSequence coming from the history file. * History is kept as a list of urls. This queries the db to fetch * metadata for an url key */ class DocSequenceHistory : public DocSequence { public: - DocSequenceHistory(Rcl::Db *d, RclHistory *h, const string &t) + DocSequenceHistory(Rcl::Db *d, RclDynConf *h, const string &t) : DocSequence(t), m_db(d), m_hist(h), m_prevnum(-1), m_prevtime(-1) {} virtual ~DocSequenceHistory() {} @@ -41,7 +55,7 @@ class DocSequenceHistory : public DocSequence { void setDescription(const string& desc) {m_description = desc;} private: Rcl::Db *m_db; - RclHistory *m_hist; + RclDynConf *m_hist; int m_prevnum; long m_prevtime; string m_description; // This is just an nls translated 'doc history' @@ -49,4 +63,6 @@ class DocSequenceHistory : public DocSequence { list::const_iterator m_it; }; +extern bool historyEnterDoc(RclDynConf *dncf, const string& udi); + #endif /* _DOCSEQ_H_INCLUDED_ */ diff --git a/src/query/history.cpp b/src/query/dynconf.cpp similarity index 63% rename from src/query/history.cpp rename to src/query/dynconf.cpp index f3982573..823439b9 100644 --- a/src/query/history.cpp +++ b/src/query/dynconf.cpp @@ -1,5 +1,5 @@ #ifndef lint -static char rcsid[] = "@(#$Id: history.cpp,v 1.9 2007-12-13 06:58:21 dockes Exp $ (C) 2005 J.F.Dockes"; +static char rcsid[] = "@(#$Id: dynconf.cpp,v 1.9 2007-12-13 06:58:21 dockes Exp $ (C) 2005 J.F.Dockes"; #endif /* * This program is free software; you can redistribute it and/or modify @@ -23,7 +23,7 @@ static char rcsid[] = "@(#$Id: history.cpp,v 1.9 2007-12-13 06:58:21 dockes Exp #include #include -#include "history.h" +#include "dynconf.h" #include "base64.h" #include "smallut.h" #include "debuglog.h" @@ -32,63 +32,20 @@ static char rcsid[] = "@(#$Id: history.cpp,v 1.9 2007-12-13 06:58:21 dockes Exp using namespace std; #endif - -// Encode/decode document history entry: Unix time + base64 of fn + -// base64 of ipath separated by a space. If ipath is not set, there -// are only 2 parts -bool RclDHistoryEntry::encode(string& value) -{ - char chartime[20]; - sprintf(chartime, "%ld", unixtime); - string bfn, bipath; - base64_encode(fn, bfn); - base64_encode(ipath, bipath); - value = string(chartime) + " " + bfn + " " + bipath; - return true; -} -bool RclDHistoryEntry::decode(const string &value) -{ - list vall; - stringToStrings(value, vall); - list::const_iterator it1 = vall.begin(); - if (vall.size() < 2) - return false; - unixtime = atol((*it1++).c_str()); - base64_decode(*it1++, fn); - if (vall.size() == 3) - base64_decode(*it1, ipath); - else - ipath.erase(); - return true; -} -bool RclDHistoryEntry::equal(const HistoryEntry& other) -{ - const RclDHistoryEntry& e = dynamic_cast(other); - return e.fn == fn && e.ipath == ipath; -} +// Well known keys for history and external indexes. +const string docHistSubKey = "docs"; +const string allEdbsSk = "allExtDbs"; +const string actEdbsSk = "actExtDbs"; -// Encode/decode simple string. base64 used to avoid problems with -// strange chars -bool RclSListEntry::encode(string& enc) +// @param sk section this is for +// @param n new entry +// @param s a scratch entry used for decoding and comparisons. +// This avoids templating this routine for the actual entry type. +bool RclDynConf::insertNew(const string &sk, DynConfEntry &n, DynConfEntry &s, + int maxlen) { - base64_encode(value, enc); - return true; -} -bool RclSListEntry::decode(const string &enc) -{ - base64_decode(enc, value); - return true; -} -bool RclSListEntry::equal(const HistoryEntry& other) -{ - const RclSListEntry& e = dynamic_cast(other); - return e.value == value; -} - -bool RclHistory::insertNew(const string &sk, HistoryEntry &n, HistoryEntry &s) -{ - // Is this doc already in history ? If it is we remove the old entry + // Is this doc already in list ? If it is we remove the old entry list names = m_data.getNames(sk); list::const_iterator it; bool changed = false; @@ -111,13 +68,13 @@ bool RclHistory::insertNew(const string &sk, HistoryEntry &n, HistoryEntry &s) if (changed) names = m_data.getNames(sk); - // How many do we have - if (names.size() >= m_mlen) { + // Need to prune ? + if (maxlen > 0 && names.size() >= (unsigned int)maxlen) { // Need to erase entries until we're back to size. Note that // we don't ever reset numbers. Problems will arise when // history is 4 billion entries old it = names.begin(); - for (unsigned int i = 0; i < names.size() - m_mlen + 1; i++, it++) { + for (unsigned int i = 0; i < names.size() - maxlen + 1; i++, it++) { m_data.erase(*it, sk); } } @@ -137,12 +94,10 @@ bool RclHistory::insertNew(const string &sk, HistoryEntry &n, HistoryEntry &s) return false; } return true; - } -bool RclHistory::eraseAll(const string &sk) +bool RclDynConf::eraseAll(const string &sk) { - // Is this doc already in history ? If it is we remove the old entry list names = m_data.getNames(sk); list::const_iterator it; for (it = names.begin(); it != names.end(); it++) { @@ -150,31 +105,36 @@ bool RclHistory::eraseAll(const string &sk) } return true; } -bool RclHistory::truncate(const string &sk, unsigned int n) + + +// Generic string list specialization /////////////////////////////////// + +// Encode/decode simple string. base64 used to avoid problems with +// strange chars +bool RclSListEntry::encode(string& enc) { - // Is this doc already in history ? If it is we remove the old entry - list names = m_data.getNames(sk); - if (names.size() <= n) - return true; - unsigned int i = 0; - for (list::const_iterator it = names.begin(); - it != names.end(); it++, i++) { - if (i >= n) - m_data.erase(*it, sk); - } + base64_encode(value, enc); return true; } - - -bool RclHistory::enterString(const string sk, const string value) +bool RclSListEntry::decode(const string &enc) +{ + base64_decode(enc, value); + return true; +} +bool RclSListEntry::equal(const DynConfEntry& other) +{ + const RclSListEntry& e = dynamic_cast(other); + return e.value == value; +} +bool RclDynConf::enterString(const string sk, const string value, int maxlen) { RclSListEntry ne(value); RclSListEntry scratch; - return insertNew(sk, ne, scratch); + return insertNew(sk, ne, scratch, maxlen); } -list RclHistory::getStringList(const string sk) +list RclDynConf::getStringList(const string sk) { - list el = getHistory(sk); + list el = getList(sk); list sl; for (list::const_iterator it = el.begin(); it != el.end(); it++) @@ -182,26 +142,8 @@ list RclHistory::getStringList(const string sk) return sl; } -string RclHistory::docSubkey = "docs"; - -/// *************** History entries specific methods -bool RclHistory::enterDoc(const string fn, const string ipath) -{ - LOGDEB(("RclDHistory::enterDoc: [%s] [%s] into %s\n", - fn.c_str(), ipath.c_str(), m_data.getFilename().c_str())); - RclDHistoryEntry ne(time(0), fn, ipath); - RclDHistoryEntry scratch; - return insertNew(docSubkey, ne, scratch); -} - -list RclHistory::getDocHistory() -{ - return getHistory(docSubkey); -} - - - #else + #include #include @@ -216,7 +158,7 @@ static string thisprog; static string usage = "trhist [opts] \n" - " [-s ]: specify subkey (default: RclHistory::docSubkey)\n" + " [-s ]: specify subkey (default: RclDynConf::docHistSubKey)\n" " [-e] : erase all\n" " [-a ] enter string (needs -s, no good for history entries\n" "\n" @@ -236,7 +178,7 @@ static int op_flags; int main(int argc, char **argv) { - string sk = RclHistory::docSubkey; + string sk = "docs"; string value; thisprog = argv[0]; @@ -264,7 +206,7 @@ int main(int argc, char **argv) Usage(); string filename = *argv++;argc--; - RclHistory hist(filename, 5); + RclDynConf hist(filename, 5); DebugLog::getdbl()->setloglevel(DEBDEB1); DebugLog::setfilename("stderr"); diff --git a/src/query/dynconf.h b/src/query/dynconf.h new file mode 100644 index 00000000..37ddef46 --- /dev/null +++ b/src/query/dynconf.h @@ -0,0 +1,123 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the + * Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ +#ifndef _DYNCONF_H_INCLUDED_ +#define _DYNCONF_H_INCLUDED_ +/* @(#$Id: dynconf.h,v 1.7 2007-06-20 13:16:11 dockes Exp $ (C) 2004 J.F.Dockes */ + +/** + * Dynamic configuration storage + * + * This used to be called "history" because of the initial usage. + * Used to store some parameters which would fit neither in recoll.conf, + * basically because they change a lot, nor in the QT preferences file, mostly + * because they are specific to a configuration directory. + * Examples: + * - History of documents selected for preview + * - Active and inactive external databases (depend on the + * configuration directory) + * - ... + * + * The storage is performed in a ConfSimple file, with subkeys and + * encodings which depend on the data stored. Under each section, the keys + * are sequential numeric, so this basically manages a set of lists. + * + */ + +#include +#include +#include + +#include "conftree.h" + +#ifndef NO_NAMESPACES +using namespace std; +#endif + +// Entry interface. +class DynConfEntry { + public: + virtual ~DynConfEntry() {} + virtual bool decode(const string &value) = 0; + virtual bool encode(string& value) = 0; + virtual bool equal(const DynConfEntry &other) = 0; +}; + + +/** String storage generic object */ +class RclSListEntry : public DynConfEntry { + public: + RclSListEntry() {} + RclSListEntry(const string& v) : value(v) {} + virtual ~RclSListEntry() {} + virtual bool decode(const string &enc); + virtual bool encode(string& enc); + virtual bool equal(const DynConfEntry& other); + + string value; +}; + +/** The dynamic configuration class */ +class RclDynConf { + public: + RclDynConf(const string &fn) + : m_data(fn.c_str()) {} + bool ok() {return m_data.getStatus() == ConfSimple::STATUS_RW;} + string getFilename() {return m_data.getFilename();} + + // Generic methods + bool eraseAll(const string& sk); + bool insertNew(const string& sk, DynConfEntry &n, DynConfEntry &s, + int maxlen = -1); + template list getList(const string& sk); + + // Specialized methods for simple string lists, designated by the + // subkey value + bool enterString(const string sk, const string value, int maxlen = -1); + list getStringList(const string sk); + + private: + unsigned int m_mlen; + ConfSimple m_data; + +}; + +template list RclDynConf::getList(const string &sk) +{ + list mlist; + Tp entry; + list names = m_data.getNames(sk); + for (list::const_iterator it = names.begin(); + it != names.end(); it++) { + string value; + if (m_data.get(*it, value, sk)) { + if (!entry.decode(value)) + continue; + mlist.push_front(entry); + } + } + return mlist; +} + +// Defined subkeys. Values in dynconf.cpp +// History +extern const string docHistSubKey; +// All external indexes +extern const string allEdbsSk; +// Active external indexes +extern const string actEdbsSk; + +#endif /* _DYNCONF_H_INCLUDED_ */ diff --git a/src/query/history.h b/src/query/history.h deleted file mode 100644 index 7320a323..00000000 --- a/src/query/history.h +++ /dev/null @@ -1,134 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the - * Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ -#ifndef _HISTORY_H_INCLUDED_ -#define _HISTORY_H_INCLUDED_ -/* @(#$Id: history.h,v 1.7 2007-06-20 13:16:11 dockes Exp $ (C) 2004 J.F.Dockes */ - -/** - * Dynamic configuration storage - * - * The term "history" is a misnomer as this code is now used to save - * all dynamic parameters except those that are stored in the global - * recollrc QT preferences file. Examples: - * - History of documents selected for preview - * - Active and inactive external databases (these should depend on the - * configuration directory and cant be stored in recollrc). - * - ... - * - * The storage is performed in a ConSimple file, with subkeys and - * encodings which depend on the data stored. - * - */ - -#include -#include -#include - -#include "conftree.h" - -#ifndef NO_NAMESPACES -using namespace std; -#endif - -class HistoryEntry { - public: - virtual ~HistoryEntry() {} - virtual bool decode(const string &value) = 0; - virtual bool encode(string& value) = 0; - virtual bool equal(const HistoryEntry &other) = 0; -}; - - -/** Document history entry */ -class RclDHistoryEntry : public HistoryEntry { - public: - RclDHistoryEntry() : unixtime(0) {} - RclDHistoryEntry(long t, const string& f, const string& i) - : unixtime(t), fn(f), ipath(i) {} - virtual ~RclDHistoryEntry() {} - virtual bool decode(const string &value); - virtual bool encode(string& value); - virtual bool equal(const HistoryEntry& other); - long unixtime; - string fn; - string ipath; -}; - - -/** String storage generic object */ -class RclSListEntry : public HistoryEntry { - public: - RclSListEntry() {} - RclSListEntry(const string& v) : value(v) {} - virtual ~RclSListEntry() {} - virtual bool decode(const string &enc); - virtual bool encode(string& enc); - virtual bool equal(const HistoryEntry& other); - - string value; -}; - -/** - * The history class. This uses a ConfSimple for storage, and should be - * renamed something like dynconf, as it is used to stored quite a few - * things beyond doc history: all dynamic configuration parameters that are - * not suitable for QT settings because they are specific to a RECOLL_CONFDIR - */ -class RclHistory { - public: - RclHistory(const string &fn, unsigned int maxsize=100) - : m_mlen(maxsize), m_data(fn.c_str()) {} - bool ok() {return m_data.getStatus() == ConfSimple::STATUS_RW;} - - // Specific methods for history entries. These are for convenience, they - // just call regular methods with key RclHistory::docSubkey; - bool enterDoc(const string fn, const string ipath); - list getDocHistory(); - - // Generic methods used for string lists, designated by the subkey value - bool enterString(const string sk, const string value); - list getStringList(const string sk); - bool eraseAll(const string& sk); - bool truncate(const string& sk, unsigned int n); - - static string docSubkey; - - private: - unsigned int m_mlen; - ConfSimple m_data; - bool insertNew(const string& sk, HistoryEntry &n, HistoryEntry &s); - template list getHistory(const string& sk); -}; - -template list RclHistory::getHistory(const string &sk) -{ - list mlist; - Tp entry; - list names = m_data.getNames(sk); - for (list::const_iterator it = names.begin(); - it != names.end(); it++) { - string value; - if (m_data.get(*it, value, sk)) { - if (!entry.decode(value)) - continue; - mlist.push_front(entry); - } - } - return mlist; -} - -#endif /* _HISTORY_H_INCLUDED_ */