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+".
This commit is contained in:
Paul Beckingham 2009-06-11 00:11:11 -04:00
parent 8728312da6
commit 7b9cb12308
8 changed files with 70 additions and 55 deletions

View file

@ -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;
}

View file

@ -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 <Att> 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;
}

View file

@ -44,8 +44,8 @@ public:
void parse (const std::string&);
std::vector <Att> 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&);

View file

@ -342,7 +342,6 @@ bool TDB::writePending (const T& t)
delay (0.1);
fputs (t.compose ().c_str (), out);
fclose (out);
return true;
}

View file

@ -28,6 +28,7 @@
#include <iostream>
#include <sstream>
#include <string.h>
#include <stdio.h>
#include <sys/file.h>
#include "text.h"
#include "util.h"
@ -182,6 +183,8 @@ int TDB2::loadPending (std::vector <Task>& 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 <Task>& 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 <Task>& 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 + "'.";

View file

@ -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 <CR> or <LF> characters.");
}
////////////////////////////////////////////////////////////////////////////////

View file

@ -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&);

View file

@ -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 <std::string, std::string> 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 <CR> or <LF> 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 ();
}