From 7b9cb12308f317f5064c906f0f16bbef4b076b25 Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Thu, 11 Jun 2009 00:11:11 -0400 Subject: [PATCH] Enhancement - add - Modified Record::get* methods to be const. - Implemented TDB2::add. - Renamed Task::valid to Task::validate. - Implemented Task::setEntry to default creation time. - Fixed bug where TDB2 was opening files "rw" instead of "r+". --- src/Context.cpp | 16 +++++++++------- src/Record.cpp | 25 ++++++++++++++----------- src/Record.h | 4 ++-- src/TDB.cpp | 1 - src/TDB2.cpp | 19 +++++++++++++------ src/Task.cpp | 16 +++++++++++++--- src/Task.h | 6 ++++-- src/command.cpp | 38 +++++++++++++++----------------------- 8 files changed, 70 insertions(+), 55 deletions(-) diff --git a/src/Context.cpp b/src/Context.cpp index b4c17ca18..0f18d49f0 100644 --- a/src/Context.cpp +++ b/src/Context.cpp @@ -173,10 +173,12 @@ void Context::dispatch () else if (command == "calendar") { out = handleReportCalendar (); } else if (command == "summary") { out = handleReportSummary (); } else if (command == "timesheet") { out = handleReportTimesheet (); } +*/ // Commands that cause updates. + else if (cmd.command == "add") { cmdMod = true; out = handleAdd (); } +/* else if (command == "" && task.getId ()) { cmdMod = true; out = handleModify (); } - else if (command == "add") { cmdMod = true; out = handleAdd (); } else if (command == "append") { cmdMod = true; out = handleAppend (); } else if (command == "annotate") { cmdMod = true; out = handleAnnotate (); } else if (command == "done") { cmdMod = true; out = handleDone (); } @@ -188,24 +190,24 @@ void Context::dispatch () else if (command == "import") { cmdMod = true; out = handleImport (); } else if (command == "duplicate") { cmdMod = true; out = handleDuplicate (); } else if (command == "edit") { cmdMod = true; out = handleEdit (); } +*/ // Command that display IDs and therefore need TDB::gc first. +/* else if (command == "completed") { if (gc) gcMod = tdb.gc (); out = handleCompleted (); } else if (command == "next") { if (gc) gcMod = tdb.gc (); out = handleReportNext (); } else if (command == "active") { if (gc) gcMod = tdb.gc (); out = handleReportActive (); } else if (command == "overdue") { if (gc) gcMod = tdb.gc (); out = handleReportOverdue (); } - else if (isCustomReport (command)) { if (gc) gcMod = tdb.gc (); out = handleCustomReport (command); } + else if (cmd.validCustom (command)) { if (gc) gcMod = tdb.gc (); out = handleCustomReport (command); } +*/ // If the command is not recognized, display usage. -*/ else { out = shortUsage (); } -/* // 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); -*/ +// if (shadow && (gcMod || cmdMod)) +// updateShadowFile (tdb); std::cout << out; } diff --git a/src/Record.cpp b/src/Record.cpp index 76a03a9eb..50cb3d9a0 100644 --- a/src/Record.cpp +++ b/src/Record.cpp @@ -62,12 +62,13 @@ std::string Record::composeF4 () std::string ff4 = "["; bool first = true; - foreach (r, (*this)) + foreach (att, (*this)) { - if (r->second.value () != "") - ff4 += (first ? "" : " ") + r->second.composeF4 (); - - first = false; + if (att->second.value () != "") + { + ff4 += (first ? "" : " ") + att->second.composeF4 (); + first = false; + } } ff4 += "]"; @@ -126,19 +127,21 @@ std::vector Record::all () } //////////////////////////////////////////////////////////////////////////////// -const std::string Record::get (const std::string& name) +const std::string Record::get (const std::string& name) const { - if (this->find (name) != this->end ()) - return (*this)[name].value (); + Record::const_iterator i = this->find (name); + if (i != this->end ()) + return i->second.value (); return ""; } //////////////////////////////////////////////////////////////////////////////// -int Record::get_int (const std::string& name) +int Record::get_int (const std::string& name) const { - if (this->find (name) != this->end ()) - return ::atoi ((*this)[name].value ().c_str ()); + Record::const_iterator i = this->find (name); + if (i != this->end ()) + return ::atoi (i->second.value ().c_str ()); return 0; } diff --git a/src/Record.h b/src/Record.h index 93b1a85f7..5fb6380d2 100644 --- a/src/Record.h +++ b/src/Record.h @@ -44,8 +44,8 @@ public: void parse (const std::string&); std::vector all (); - const std::string get (const std::string&); - int get_int (const std::string&); + const std::string get (const std::string&) const; + int get_int (const std::string&) const; void set (const std::string&, const std::string&); void set (const std::string&, int); void remove (const std::string&); diff --git a/src/TDB.cpp b/src/TDB.cpp index 299eda3e6..3621d995b 100644 --- a/src/TDB.cpp +++ b/src/TDB.cpp @@ -342,7 +342,6 @@ bool TDB::writePending (const T& t) delay (0.1); fputs (t.compose ().c_str (), out); - fclose (out); return true; } diff --git a/src/TDB2.cpp b/src/TDB2.cpp index dcb886ee9..4eff05891 100644 --- a/src/TDB2.cpp +++ b/src/TDB2.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include "text.h" #include "util.h" @@ -182,6 +183,8 @@ int TDB2::loadPending (std::vector & tasks, Filter& filter) line_number = 1; file = location->path + "/pending.data"; + + fseek (location->pending, 0, SEEK_SET); while (fgets (line, T_LINE_MAX, location->pending)) { int length = ::strlen (line); @@ -230,6 +233,8 @@ int TDB2::loadCompleted (std::vector & tasks, Filter& filter) line_number = 1; file = location->path + "/completed.data"; + + fseek (location->completed, 0, SEEK_SET); while (fgets (line, T_LINE_MAX, location->completed)) { int length = ::strlen (line); @@ -259,12 +264,14 @@ int TDB2::loadCompleted (std::vector & tasks, Filter& filter) //////////////////////////////////////////////////////////////////////////////// // TODO Write to transaction log. +// Note: mLocations[0] is where all tasks are written. void TDB2::add (Task& after) { - throw std::string ("unimplemented TDB2::add"); + // Seek to end of pending. + fseek (mLocations[0].pending, 0, SEEK_END); - // TODO Seek to end of pending. - // TODO write after.composeFF4 (). + // Write after.composeF4 (). + fputs (after.composeF4 ().c_str (), mLocations[0].pending); } //////////////////////////////////////////////////////////////////////////////// @@ -275,11 +282,11 @@ void TDB2::update (Task& before, Task& after) } //////////////////////////////////////////////////////////////////////////////// -// TODO writes all, including comments +// TODO Writes all, including comments int TDB2::commit () { // TODO Two passes: first the pending file. - // then the compelted file. + // then the completed file. throw std::string ("unimplemented TDB2::commit"); } @@ -300,7 +307,7 @@ FILE* TDB2::openAndLock (const std::string& file) file + "'."; // Open the file. - FILE* in = fopen (file.c_str (), "rw"); + FILE* in = fopen (file.c_str (), "r+"); if (!in) throw std::string ("Could not open '") + file + "'."; diff --git a/src/Task.cpp b/src/Task.cpp index d520a1c91..0428b84af 100644 --- a/src/Task.cpp +++ b/src/Task.cpp @@ -95,6 +95,14 @@ std::string Task::statusToText (Task::status s) return "pending"; } +//////////////////////////////////////////////////////////////////////////////// +void Task::setEntry () +{ + char entryTime[16]; + sprintf (entryTime, "%u", (unsigned int) time (NULL)); + set ("entry", entryTime); +} + //////////////////////////////////////////////////////////////////////////////// Task::status Task::getStatus () { @@ -102,7 +110,7 @@ Task::status Task::getStatus () } //////////////////////////////////////////////////////////////////////////////// -void Task::setSatus (Task::status status) +void Task::setStatus (Task::status status) { set ("status", statusToText (status)); } @@ -422,12 +430,14 @@ void Task::removeTag (const std::string& tag) } //////////////////////////////////////////////////////////////////////////////// -bool Task::valid () const +void Task::validate () const { // TODO Verify until > due // TODO Verify entry < until, due, start, end // TODO If name == "recur", then Duration::valid (value). - return true; + + if (get ("description") == "") + throw std::string ("Cannot add a task that is blank, or contains or characters."); } //////////////////////////////////////////////////////////////////////////////// diff --git a/src/Task.h b/src/Task.h index 50b05614d..12907da7b 100644 --- a/src/Task.h +++ b/src/Task.h @@ -57,8 +57,10 @@ public: static status textToStatus (const std::string&); static std::string statusToText (status); + void setEntry (); + status getStatus (); - void setSatus (status); + void setStatus (status); int getTagCount (); bool hasTag (const std::string&); @@ -72,7 +74,7 @@ public: void addAnnotation (const std::string&); void removeAnnotations (); - bool valid () const; + void validate () const; private: int determineVersion (const std::string&); diff --git a/src/command.cpp b/src/command.cpp index 54d0e6319..8e5fff31f 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -48,44 +48,36 @@ extern Context context; std::string handleAdd () { std::stringstream out; -/* - char entryTime[16]; - sprintf (entryTime, "%u", (unsigned int) time (NULL)); - task.setAttribute ("entry", entryTime); - std::map atts; - task.getAttributes (atts); - foreach (i, atts) - if (i->second == "") - task.removeAttribute (i->first); + context.task.setEntry (); // Recurring tasks get a special status. - if (task.getAttribute ("due") != "" && - task.getAttribute ("recur") != "") + if (context.task.get ("due") != "" && + context.task.get ("recur") != "") { - task.setStatus (T::recurring); - task.setAttribute ("mask", ""); + context.task.setStatus (Task::recurring); + context.task.set ("mask", ""); } // Override with default.project, if not specified. - if (task.getAttribute ("project") == "") - task.setAttribute ("project", context.config.get ("default.project", "")); + if (context.task.get ("project") == "") + context.task.set ("project", context.config.get ("default.project", "")); // Override with default.priority, if not specified. - if (task.getAttribute ("priority") == "") + if (context.task.get ("priority") == "") { std::string defaultPriority = context.config.get ("default.priority", ""); if (validPriority (defaultPriority)) - task.setAttribute ("priority", defaultPriority); + context.task.set ("priority", defaultPriority); } - // Disallow blank descriptions. - if (task.getDescription () == "") - throw std::string ("Cannot add a task that is blank, or contains or characters."); + // Only valid tasks can be added. + context.task.validate (); + + context.tdb.lock (context.config.get ("locking", true)); + context.tdb.add (context.task); + context.tdb.unlock (); - if (!tdb.addT (task)) - throw std::string ("Could not create new task."); -*/ return out.str (); }