GUI+RPC: Action history for individual files
In .js GUI now it is possible to click on file to get history for
individual files
Change-Id: Ia50d1d14019b4ea0d39940da566b43927dd73fa2
diff --git a/src/action-log.cc b/src/action-log.cc
index 740430f..71ee782 100644
--- a/src/action-log.cc
+++ b/src/action-log.cc
@@ -727,6 +727,78 @@
return (limit == 1); // more data is available
}
+/**
+ * @todo Figure out the way to minimize code duplication
+ */
+bool
+ActionLog::LookupActionsForFile (const boost::function<void (const Ccnx::Name &name, sqlite3_int64 seq_no, const ActionItem &)> &visitor,
+ const std::string &file, int offset/*=0*/, int limit/*=-1*/)
+{
+ _LOG_DEBUG ("LookupActionsInFolderRecursively: [" << file << "]");
+ if (file.empty ())
+ return false;
+
+ if (limit >= 0)
+ limit += 1; // to check if there is more data
+
+ sqlite3_stmt *stmt;
+ sqlite3_prepare_v2 (m_db,
+ "SELECT device_name,seq_no,action,filename,directory,version,strftime('%s', action_timestamp), "
+ " file_hash,strftime('%s', file_mtime),file_chmod,file_seg_num, "
+ " parent_device_name,parent_seq_no "
+ " FROM ActionLog "
+ " WHERE filename=? "
+ " ORDER BY action_timestamp DESC "
+ " LIMIT ? OFFSET ?", -1, &stmt, 0); // there is a small ambiguity with is_prefix matching, but should be ok for now
+ _LOG_DEBUG_COND (sqlite3_errcode (m_db) != SQLITE_OK, sqlite3_errmsg (m_db));
+
+ sqlite3_bind_text (stmt, 1, file.c_str (), file.size (), SQLITE_STATIC);
+ _LOG_DEBUG_COND (sqlite3_errcode (m_db) != SQLITE_OK, sqlite3_errmsg (m_db));
+
+ sqlite3_bind_int (stmt, 2, limit);
+ sqlite3_bind_int (stmt, 3, offset);
+
+ _LOG_DEBUG_COND (sqlite3_errcode (m_db) != SQLITE_OK, sqlite3_errmsg (m_db));
+
+ while (sqlite3_step (stmt) == SQLITE_ROW)
+ {
+ if (limit == 1)
+ break;
+
+ ActionItem action;
+
+ Ccnx::Name device_name (sqlite3_column_blob (stmt, 0), sqlite3_column_bytes (stmt, 0));
+ sqlite3_int64 seq_no = sqlite3_column_int64 (stmt, 1);
+ action.set_action (static_cast<ActionItem_ActionType> (sqlite3_column_int (stmt, 2)));
+ action.set_filename (reinterpret_cast<const char *> (sqlite3_column_text (stmt, 3)), sqlite3_column_bytes (stmt, 3));
+ std::string directory (reinterpret_cast<const char *> (sqlite3_column_text (stmt, 4)), sqlite3_column_bytes (stmt, 4));
+ if (action.action () == 0)
+ {
+ action.set_version (sqlite3_column_int64 (stmt, 5));
+ action.set_timestamp (sqlite3_column_int64 (stmt, 6));
+ action.set_file_hash (sqlite3_column_blob (stmt, 7), sqlite3_column_bytes (stmt, 7));
+ action.set_mtime (sqlite3_column_int (stmt, 8));
+ action.set_mode (sqlite3_column_int (stmt, 9));
+ action.set_seg_num (sqlite3_column_int64 (stmt, 10));
+ }
+ if (sqlite3_column_bytes (stmt, 11) > 0)
+ {
+ action.set_parent_device_name (sqlite3_column_blob (stmt, 11), sqlite3_column_bytes (stmt, 11));
+ action.set_parent_seq_no (sqlite3_column_int64 (stmt, 12));
+ }
+
+ visitor (device_name, seq_no, action);
+ limit --;
+ }
+
+ _LOG_DEBUG_COND (sqlite3_errcode (m_db) != SQLITE_DONE, sqlite3_errmsg (m_db));
+
+ sqlite3_finalize (stmt);
+
+ return (limit == 1); // more data is available
+}
+
+
void
ActionLog::LookupRecentFileActions(const boost::function<void (const string &, int, int)> &visitor, int limit)
{
diff --git a/src/action-log.h b/src/action-log.h
index 6345281..96ccd51 100644
--- a/src/action-log.h
+++ b/src/action-log.h
@@ -109,6 +109,10 @@
LookupActionsInFolderRecursively (const boost::function<void (const Ccnx::Name &name, sqlite3_int64 seq_no, const ActionItem &)> &visitor,
const std::string &folder, int offset=0, int limit=-1);
+ bool
+ LookupActionsForFile (const boost::function<void (const Ccnx::Name &name, sqlite3_int64 seq_no, const ActionItem &)> &visitor,
+ const std::string &file, int offset=0, int limit=-1);
+
void
LookupRecentFileActions(const boost::function<void (const std::string &, int, int)> &visitor, int limit = 5);
diff --git a/src/state-server.cc b/src/state-server.cc
index fa8517c..43f15e3 100644
--- a/src/state-server.cc
+++ b/src/state-server.cc
@@ -79,6 +79,7 @@
// <PREFIX_INFO>/"actions"/"all"/<nonce>/<segment> get list of all actions
m_ccnx->setInterestFilter (Name (m_PREFIX_INFO)("actions")("folder"), bind(&StateServer::info_actions_folder, this, _1));
+ m_ccnx->setInterestFilter (Name (m_PREFIX_INFO)("actions")("file"), bind(&StateServer::info_actions_file, this, _1));
// <PREFIX_INFO>/"filestate"/"all"/<nonce>/<segment>
m_ccnx->setInterestFilter (Name (m_PREFIX_INFO)("files")("folder"), bind(&StateServer::info_files_folder, this, _1));
@@ -91,37 +92,11 @@
StateServer::deregisterPrefixes ()
{
m_ccnx->clearInterestFilter (Name (m_PREFIX_INFO)("actions")("folder"));
+ m_ccnx->clearInterestFilter (Name (m_PREFIX_INFO)("actions")("file"));
m_ccnx->clearInterestFilter (Name (m_PREFIX_INFO)("files")("folder"));
m_ccnx->clearInterestFilter (Name (m_PREFIX_CMD) ("restore")("file"));
}
-// void
-// StateServer::info_actions_all (const Name &interest)
-// {
-// _LOG_DEBUG (">> info_actions_all: " << interest);
-// m_executor.execute (bind (&StateServer::info_actions_all_Execute, this, interest));
-// }
-
-// void
-// StateServer::info_actions_all_Execute (const Name &interest)
-// {
-// // <PREFIX_INFO>/"actions"/"all"/<nonce>/<offset> get list of all actions
-
-// try
-// {
-// int offset = interest.getCompFromBackAsInt (0);
-
-// // LookupActionsInFolderRecursively
-// /// @todo !!! add security checking
-// m_ccnx->publishData (interest, "FAIL: Not implemented", 1);
-// }
-// catch (Ccnx::NameException &ne)
-// {
-// // ignore any unexpected interests and errors
-// _LOG_ERROR (*boost::get_error_info<Ccnx::error_info_str>(ne));
-// }
-// }
-
void
StateServer::formatActionJson (json_spirit::Array &actions,
const Ccnx::Name &name, sqlite3_int64 seq_no, const ActionItem &action)
@@ -206,14 +181,29 @@
return;
}
- _LOG_DEBUG (">> info_actions_all: " << interest);
- m_executor.execute (bind (&StateServer::info_actions_folder_Execute, this, interest));
+ _LOG_DEBUG (">> info_actions_folder: " << interest);
+ m_executor.execute (bind (&StateServer::info_actions_fileOrFolder_Execute, this, interest, true));
}
void
-StateServer::info_actions_folder_Execute (const Name &interest)
+StateServer::info_actions_file (const Name &interest)
{
- // <PREFIX_INFO>/"actions"/"folder"/<folder>/<nonce>/<offset> get list of all actions
+ if (interest.size () - m_PREFIX_INFO.size () != 4 &&
+ interest.size () - m_PREFIX_INFO.size () != 5)
+ {
+ _LOG_DEBUG ("Invalid interest: " << interest);
+ return;
+ }
+
+ _LOG_DEBUG (">> info_actions_file: " << interest);
+ m_executor.execute (bind (&StateServer::info_actions_fileOrFolder_Execute, this, interest, false));
+}
+
+
+void
+StateServer::info_actions_fileOrFolder_Execute (const Ccnx::Name &interest, bool isFolder/* = true*/)
+{
+ // <PREFIX_INFO>/"actions"/"folder|file"/<folder|file>/<nonce>/<offset> get list of all actions
try
{
@@ -221,11 +211,11 @@
/// @todo !!! add security checking
- string folder;
+ string fileOrFolderName;
if (interest.size () - m_PREFIX_INFO.size () == 5)
- folder = interest.getCompFromBackAsString (2);
+ fileOrFolderName = interest.getCompFromBackAsString (2);
else // == 4
- folder = "";
+ fileOrFolderName = "";
/*
* {
* "actions": [
@@ -241,9 +231,19 @@
Object json;
Array actions;
- bool more = m_actionLog->LookupActionsInFolderRecursively
- (boost::bind (StateServer::formatActionJson, boost::ref(actions), _1, _2, _3),
- folder, offset*10, 10);
+ bool more;
+ if (isFolder)
+ {
+ m_actionLog->LookupActionsInFolderRecursively
+ (boost::bind (StateServer::formatActionJson, boost::ref(actions), _1, _2, _3),
+ fileOrFolderName, offset*10, 10);
+ }
+ else
+ {
+ m_actionLog->LookupActionsForFile
+ (boost::bind (StateServer::formatActionJson, boost::ref(actions), _1, _2, _3),
+ fileOrFolderName, offset*10, 10);
+ }
json.push_back (Pair ("actions", actions));
@@ -331,7 +331,7 @@
return;
}
- _LOG_DEBUG (">> info_filestate_folder: " << interest);
+ _LOG_DEBUG (">> info_files_folder: " << interest);
m_executor.execute (bind (&StateServer::info_files_folder_Execute, this, interest));
}
diff --git a/src/state-server.h b/src/state-server.h
index 4a68594..22caf89 100644
--- a/src/state-server.h
+++ b/src/state-server.h
@@ -163,7 +163,10 @@
info_actions_folder (const Ccnx::Name &interest);
void
- info_actions_folder_Execute (const Ccnx::Name &interest);
+ info_actions_file (const Ccnx::Name &interest);
+
+ void
+ info_actions_fileOrFolder_Execute (const Ccnx::Name &interest, bool isFolder = true);
void
info_files_folder (const Ccnx::Name &interest);