mirror of
https://github.com/GothenburgBitFactory/taskwarrior.git
synced 2025-06-26 10:54:26 +02:00
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:
parent
8728312da6
commit
7b9cb12308
8 changed files with 70 additions and 55 deletions
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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&);
|
||||
|
|
|
@ -342,7 +342,6 @@ bool TDB::writePending (const T& t)
|
|||
delay (0.1);
|
||||
|
||||
fputs (t.compose ().c_str (), out);
|
||||
|
||||
fclose (out);
|
||||
return true;
|
||||
}
|
||||
|
|
19
src/TDB2.cpp
19
src/TDB2.cpp
|
@ -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 + "'.";
|
||||
|
||||
|
|
16
src/Task.cpp
16
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 <CR> or <LF> characters.");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -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&);
|
||||
|
|
|
@ -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 ();
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue