--- a/src/query/docseqhist.cpp
+++ b/src/query/docseqhist.cpp
@@ -25,6 +25,84 @@
#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<string> vall;
+ stringToStrings(value, vall);
+
+ list<string>::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<const RclDHistoryEntry&>(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<RclDHistoryEntry> getDocHistory(RclDynConf* dncf)
+{
+ return dncf->getList<RclDHistoryEntry>(docHistSubKey);
+}
+
bool DocSequenceHistory::getDoc(int num, Rcl::Doc &doc, string *sh)
{
@@ -32,7 +110,7 @@
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 @@
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 @@
} 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 @@
int DocSequenceHistory::getResCnt()
{
if (m_hlist.empty())
- m_hlist = m_hist->getDocHistory();
+ m_hlist = getDocHistory(m_hist);
return m_hlist.size();
}