Improved GC and Shadow File Handling

- Every command now returns an output string, or at least has an
  opportunity to do so.
- TDB::gc is only performed a) when allowed, and b) when the command
  will display line numbers.
- updateShadowFile is only performed when a) shadow updates are allowed,
  and either b) when a command is guaranteed to have modified a task or
  c) when TDB:gc has already made changes.
This commit is contained in:
Paul Beckingham 2009-03-14 12:05:32 -04:00
parent 64cfc26ff3
commit c9a6d2a750
3 changed files with 107 additions and 74 deletions

View file

@ -48,8 +48,10 @@
#endif #endif
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void handleAdd (TDB& tdb, T& task, Config& conf) std::string handleAdd (TDB& tdb, T& task, Config& conf)
{ {
std::stringstream out;
char entryTime[16]; char entryTime[16];
sprintf (entryTime, "%u", (unsigned int) time (NULL)); sprintf (entryTime, "%u", (unsigned int) time (NULL));
task.setAttribute ("entry", entryTime); task.setAttribute ("entry", entryTime);
@ -86,6 +88,8 @@ void handleAdd (TDB& tdb, T& task, Config& conf)
if (!tdb.addT (task)) if (!tdb.addT (task))
throw std::string ("Could not create new task."); throw std::string ("Could not create new task.");
return out.str ();
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -547,8 +551,10 @@ std::string handleStop (TDB& tdb, T& task, Config& conf)
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void handleDone (TDB& tdb, T& task, Config& conf) std::string handleDone (TDB& tdb, T& task, Config& conf)
{ {
std::stringstream out;
if (!tdb.completeT (task)) if (!tdb.completeT (task))
throw std::string ("Could not mark task as completed."); throw std::string ("Could not mark task as completed.");
@ -566,11 +572,14 @@ void handleDone (TDB& tdb, T& task, Config& conf)
} }
nag (tdb, task, conf); nag (tdb, task, conf);
return out.str ();
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void handleExport (TDB& tdb, T& task, Config& conf) std::string handleExport (TDB& tdb, T& task, Config& conf)
{ {
std::stringstream out;
// Use the description as a file name, then clobber the description so the // Use the description as a file name, then clobber the description so the
// file name isn't used for filtering. // file name isn't used for filtering.
std::string file = trim (task.getDescription ()); std::string file = trim (task.getDescription ());
@ -610,11 +619,14 @@ void handleExport (TDB& tdb, T& task, Config& conf)
} }
else else
throw std::string ("You must specify a file to write to."); throw std::string ("You must specify a file to write to.");
return out.str ();
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void handleModify (TDB& tdb, T& task, Config& conf) std::string handleModify (TDB& tdb, T& task, Config& conf)
{ {
std::stringstream out;
std::vector <T> all; std::vector <T> all;
tdb.pendingT (all); tdb.pendingT (all);
@ -695,11 +707,12 @@ void handleModify (TDB& tdb, T& task, Config& conf)
tdb.modifyT (original); tdb.modifyT (original);
} }
return; return out.str ();
} }
} }
throw std::string ("Task not found."); throw std::string ("Task not found.");
return out.str ();
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////

View file

@ -27,6 +27,7 @@
#include <iostream> #include <iostream>
#include <iomanip> #include <iomanip>
#include <fstream> #include <fstream>
#include <sstream>
#include <sys/types.h> #include <sys/types.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@ -47,8 +48,9 @@
#endif #endif
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
static void shortUsage (Config& conf) static std::string shortUsage (Config& conf)
{ {
std::stringstream out;
Table table; Table table;
int width = conf.get ("defaultwidth", 80); int width = conf.get ("defaultwidth", 80);
#ifdef HAVE_LIBNCURSES #ifdef HAVE_LIBNCURSES
@ -192,21 +194,22 @@ static void shortUsage (Config& conf)
table.addCell (row, 2, description); table.addCell (row, 2, description);
} }
std::cout << table.render () out << table.render ()
<< std::endl << std::endl
<< "See http://www.beckingham.net/task.html for the latest releases and a " << "See http://www.beckingham.net/task.html for the latest releases and a "
<< "full tutorial. New releases containing fixes and enhancements are " << "full tutorial. New releases containing fixes and enhancements are "
<< "made frequently." << "made frequently."
<< std::endl << std::endl
<< std::endl; << std::endl;
return out.str ();
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
static void longUsage (Config& conf) static std::string longUsage (Config& conf)
{ {
shortUsage (conf); std::stringstream out;
out << shortUsage (conf)
std::cout
<< "ID is the numeric identifier displayed by the 'task list' command." << "\n" << "ID is the numeric identifier displayed by the 'task list' command." << "\n"
<< "\n" << "\n"
<< "Tags are arbitrary words, any quantity:" << "\n" << "Tags are arbitrary words, any quantity:" << "\n"
@ -234,6 +237,8 @@ static void longUsage (Config& conf)
<< "Many characters have special meaning to the shell, including:" << "\n" << "Many characters have special meaning to the shell, including:" << "\n"
<< " $ ! ' \" ( ) ; \\ ` * ? { } [ ] < > | & % # ~" << "\n" << " $ ! ' \" ( ) ; \\ ` * ? { } [ ] < > | & % # ~" << "\n"
<< std::endl; << std::endl;
return out.str ();
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -790,34 +795,49 @@ std::string runTaskCommand (
T task; T task;
parse (args, command, task, conf); parse (args, command, task, conf);
std::string out = ""; bool gcMod = false; // Change occurred by way of gc.
bool cmdMod = false; // Change occurred by way of command type.
std::string out;
if (command == "" && task.getId ()) { handleModify (tdb, task, conf ); if (shadow) updateShadowFile (tdb, conf); } // Read-only commands with no side effects.
else if (command == "add") { handleAdd (tdb, task, conf ); if (shadow) updateShadowFile (tdb, conf); } if (command == "export") { out = handleExport (tdb, task, conf); }
else if (command == "done") { handleDone (tdb, task, conf ); if (shadow) updateShadowFile (tdb, conf); } else if (command == "projects") { out = handleProjects (tdb, task, conf); }
else if (command == "export") { handleExport (tdb, task, conf ); } else if (command == "tags") { out = handleTags (tdb, task, conf); }
else if (command == "projects") { out = handleProjects (tdb, task, conf ); } else if (command == "info") { out = handleInfo (tdb, task, conf); }
else if (command == "tags") { out = handleTags (tdb, task, conf ); } else if (command == "stats") { out = handleReportStats (tdb, task, conf); }
else if (command == "info") { out = handleInfo (tdb, task, conf ); } else if (command == "history") { out = handleReportHistory (tdb, task, conf); }
else if (command == "undelete") { out = handleUndelete (tdb, task, conf ); if (shadow) updateShadowFile (tdb, conf); } else if (command == "ghistory") { out = handleReportGHistory (tdb, task, conf); }
else if (command == "delete") { out = handleDelete (tdb, task, conf ); if (shadow) updateShadowFile (tdb, conf); } else if (command == "calendar") { out = handleReportCalendar (tdb, task, conf); }
else if (command == "start") { out = handleStart (tdb, task, conf ); if (shadow) updateShadowFile (tdb, conf); } else if (command == "summary") { out = handleReportSummary (tdb, task, conf); }
else if (command == "stop") { out = handleStop (tdb, task, conf ); if (shadow) updateShadowFile (tdb, conf); } else if (command == "colors") { out = handleColor ( conf); }
else if (command == "undo") { out = handleUndo (tdb, task, conf ); if (shadow) updateShadowFile (tdb, conf); } else if (command == "version") { out = handleVersion ( conf); }
else if (command == "stats") { out = handleReportStats (tdb, task, conf ); } else if (command == "help") { out = longUsage ( conf); }
else if (command == "completed") { if (gc) tdb.gc (); out = handleCompleted (tdb, task, conf ); if (shadow) updateShadowFile (tdb, conf); } // TODO replace with Custom
else if (command == "summary") { if (gc) tdb.gc (); out = handleReportSummary (tdb, task, conf ); if (shadow) updateShadowFile (tdb, conf); } // Commands that cause updates.
else if (command == "next") { if (gc) tdb.gc (); out = handleReportNext (tdb, task, conf ); if (shadow) updateShadowFile (tdb, conf); } // TODO replace with Custom else if (command == "" && task.getId ()) { cmdMod = true; out = handleModify (tdb, task, conf); }
else if (command == "history") { if (gc) tdb.gc (); out = handleReportHistory (tdb, task, conf ); if (shadow) updateShadowFile (tdb, conf); } else if (command == "add") { cmdMod = true; out = handleAdd (tdb, task, conf); }
else if (command == "ghistory") { if (gc) tdb.gc (); out = handleReportGHistory (tdb, task, conf ); if (shadow) updateShadowFile (tdb, conf); } else if (command == "done") { cmdMod = true; out = handleDone (tdb, task, conf); }
else if (command == "calendar") { if (gc) tdb.gc (); out = handleReportCalendar (tdb, task, conf ); if (shadow) updateShadowFile (tdb, conf); } else if (command == "undelete") { cmdMod = true; out = handleUndelete (tdb, task, conf); }
else if (command == "active") { if (gc) tdb.gc (); out = handleReportActive (tdb, task, conf ); if (shadow) updateShadowFile (tdb, conf); } // TODO replace with Custom else if (command == "delete") { cmdMod = true; out = handleDelete (tdb, task, conf); }
else if (command == "overdue") { if (gc) tdb.gc (); out = handleReportOverdue (tdb, task, conf ); if (shadow) updateShadowFile (tdb, conf); } // TODO replace with Custom else if (command == "start") { cmdMod = true; out = handleStart (tdb, task, conf); }
else if (command == "colors") { out = handleColor ( conf ); } else if (command == "stop") { cmdMod = true; out = handleStop (tdb, task, conf); }
else if (command == "version") { out = handleVersion ( conf ); } else if (command == "undo") { cmdMod = true; out = handleUndo (tdb, task, conf); }
else if (command == "help") { longUsage ( conf ); }
else if (isCustomReport (command)) { if (gc) tdb.gc (); out = handleCustomReport (tdb, task, conf, command); if (shadow) updateShadowFile (tdb, conf); } // New Custom reports // Command that display IDs and therefore need TDB::gc first.
else { shortUsage ( conf ); }
else if (command == "completed") { if (gc) gcMod = tdb.gc (); out = handleCompleted (tdb, task, conf); }
else if (command == "next") { if (gc) gcMod = tdb.gc (); out = handleReportNext (tdb, task, conf); }
else if (command == "active") { if (gc) gcMod = tdb.gc (); out = handleReportActive (tdb, task, conf); }
else if (command == "overdue") { if (gc) gcMod = tdb.gc (); out = handleReportOverdue (tdb, task, conf); }
else if (isCustomReport (command)) { if (gc) gcMod = tdb.gc (); out = handleCustomReport (tdb, task, conf, command); }
// If the command is not recognized, display usage.
else { out = shortUsage (conf); }
// Only update the shadow file if such an update was not suppressed (shadow),
// and if an actual change occurred (gcMod || cmdMod).
if (shadow && (gcMod || cmdMod))
updateShadowFile (tdb, conf);
return out; return out;
} }

View file

@ -74,10 +74,10 @@ std::string runTaskCommand (int, char**, TDB&, Config&, bool gc = true, bool sha
std::string runTaskCommand (std::vector <std::string>&, TDB&, Config&, bool gc = false, bool shadow = false); std::string runTaskCommand (std::vector <std::string>&, TDB&, Config&, bool gc = false, bool shadow = false);
// command.cpp // command.cpp
void handleAdd (TDB&, T&, Config&); std::string handleAdd (TDB&, T&, Config&);
void handleExport (TDB&, T&, Config&); std::string handleExport (TDB&, T&, Config&);
void handleDone (TDB&, T&, Config&); std::string handleDone (TDB&, T&, Config&);
void handleModify (TDB&, T&, Config&); std::string handleModify (TDB&, T&, Config&);
std::string handleProjects (TDB&, T&, Config&); std::string handleProjects (TDB&, T&, Config&);
std::string handleTags (TDB&, T&, Config&); std::string handleTags (TDB&, T&, Config&);
std::string handleUndelete (TDB&, T&, Config&); std::string handleUndelete (TDB&, T&, Config&);