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 == "calendar") { out = handleReportCalendar (); }
|
||||||
else if (command == "summary") { out = handleReportSummary (); }
|
else if (command == "summary") { out = handleReportSummary (); }
|
||||||
else if (command == "timesheet") { out = handleReportTimesheet (); }
|
else if (command == "timesheet") { out = handleReportTimesheet (); }
|
||||||
|
*/
|
||||||
|
|
||||||
// Commands that cause updates.
|
// 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 == "" && 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 == "append") { cmdMod = true; out = handleAppend (); }
|
||||||
else if (command == "annotate") { cmdMod = true; out = handleAnnotate (); }
|
else if (command == "annotate") { cmdMod = true; out = handleAnnotate (); }
|
||||||
else if (command == "done") { cmdMod = true; out = handleDone (); }
|
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 == "import") { cmdMod = true; out = handleImport (); }
|
||||||
else if (command == "duplicate") { cmdMod = true; out = handleDuplicate (); }
|
else if (command == "duplicate") { cmdMod = true; out = handleDuplicate (); }
|
||||||
else if (command == "edit") { cmdMod = true; out = handleEdit (); }
|
else if (command == "edit") { cmdMod = true; out = handleEdit (); }
|
||||||
|
*/
|
||||||
|
|
||||||
// Command that display IDs and therefore need TDB::gc first.
|
// Command that display IDs and therefore need TDB::gc first.
|
||||||
|
/*
|
||||||
else if (command == "completed") { if (gc) gcMod = tdb.gc (); out = handleCompleted (); }
|
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 == "next") { if (gc) gcMod = tdb.gc (); out = handleReportNext (); }
|
||||||
else if (command == "active") { if (gc) gcMod = tdb.gc (); out = handleReportActive (); }
|
else if (command == "active") { if (gc) gcMod = tdb.gc (); out = handleReportActive (); }
|
||||||
else if (command == "overdue") { if (gc) gcMod = tdb.gc (); out = handleReportOverdue (); }
|
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.
|
// If the command is not recognized, display usage.
|
||||||
*/
|
|
||||||
else { out = shortUsage (); }
|
else { out = shortUsage (); }
|
||||||
|
|
||||||
/*
|
|
||||||
// Only update the shadow file if such an update was not suppressed (shadow),
|
// Only update the shadow file if such an update was not suppressed (shadow),
|
||||||
// and if an actual change occurred (gcMod || cmdMod).
|
// and if an actual change occurred (gcMod || cmdMod).
|
||||||
if (shadow && (gcMod || cmdMod))
|
// if (shadow && (gcMod || cmdMod))
|
||||||
updateShadowFile (tdb);
|
// updateShadowFile (tdb);
|
||||||
*/
|
|
||||||
|
|
||||||
std::cout << out;
|
std::cout << out;
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,12 +62,13 @@ std::string Record::composeF4 ()
|
||||||
std::string ff4 = "[";
|
std::string ff4 = "[";
|
||||||
|
|
||||||
bool first = true;
|
bool first = true;
|
||||||
foreach (r, (*this))
|
foreach (att, (*this))
|
||||||
{
|
{
|
||||||
if (r->second.value () != "")
|
if (att->second.value () != "")
|
||||||
ff4 += (first ? "" : " ") + r->second.composeF4 ();
|
{
|
||||||
|
ff4 += (first ? "" : " ") + att->second.composeF4 ();
|
||||||
first = false;
|
first = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ff4 += "]";
|
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 ())
|
Record::const_iterator i = this->find (name);
|
||||||
return (*this)[name].value ();
|
if (i != this->end ())
|
||||||
|
return i->second.value ();
|
||||||
|
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
int Record::get_int (const std::string& name)
|
int Record::get_int (const std::string& name) const
|
||||||
{
|
{
|
||||||
if (this->find (name) != this->end ())
|
Record::const_iterator i = this->find (name);
|
||||||
return ::atoi ((*this)[name].value ().c_str ());
|
if (i != this->end ())
|
||||||
|
return ::atoi (i->second.value ().c_str ());
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,8 +44,8 @@ public:
|
||||||
void parse (const std::string&);
|
void parse (const std::string&);
|
||||||
|
|
||||||
std::vector <Att> all ();
|
std::vector <Att> all ();
|
||||||
const std::string get (const std::string&);
|
const std::string get (const std::string&) const;
|
||||||
int get_int (const std::string&);
|
int get_int (const std::string&) const;
|
||||||
void set (const std::string&, const std::string&);
|
void set (const std::string&, const std::string&);
|
||||||
void set (const std::string&, int);
|
void set (const std::string&, int);
|
||||||
void remove (const std::string&);
|
void remove (const std::string&);
|
||||||
|
|
|
@ -342,7 +342,6 @@ bool TDB::writePending (const T& t)
|
||||||
delay (0.1);
|
delay (0.1);
|
||||||
|
|
||||||
fputs (t.compose ().c_str (), out);
|
fputs (t.compose ().c_str (), out);
|
||||||
|
|
||||||
fclose (out);
|
fclose (out);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
19
src/TDB2.cpp
19
src/TDB2.cpp
|
@ -28,6 +28,7 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include <sys/file.h>
|
#include <sys/file.h>
|
||||||
#include "text.h"
|
#include "text.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
@ -182,6 +183,8 @@ int TDB2::loadPending (std::vector <Task>& tasks, Filter& filter)
|
||||||
|
|
||||||
line_number = 1;
|
line_number = 1;
|
||||||
file = location->path + "/pending.data";
|
file = location->path + "/pending.data";
|
||||||
|
|
||||||
|
fseek (location->pending, 0, SEEK_SET);
|
||||||
while (fgets (line, T_LINE_MAX, location->pending))
|
while (fgets (line, T_LINE_MAX, location->pending))
|
||||||
{
|
{
|
||||||
int length = ::strlen (line);
|
int length = ::strlen (line);
|
||||||
|
@ -230,6 +233,8 @@ int TDB2::loadCompleted (std::vector <Task>& tasks, Filter& filter)
|
||||||
|
|
||||||
line_number = 1;
|
line_number = 1;
|
||||||
file = location->path + "/completed.data";
|
file = location->path + "/completed.data";
|
||||||
|
|
||||||
|
fseek (location->completed, 0, SEEK_SET);
|
||||||
while (fgets (line, T_LINE_MAX, location->completed))
|
while (fgets (line, T_LINE_MAX, location->completed))
|
||||||
{
|
{
|
||||||
int length = ::strlen (line);
|
int length = ::strlen (line);
|
||||||
|
@ -259,12 +264,14 @@ int TDB2::loadCompleted (std::vector <Task>& tasks, Filter& filter)
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// TODO Write to transaction log.
|
// TODO Write to transaction log.
|
||||||
|
// Note: mLocations[0] is where all tasks are written.
|
||||||
void TDB2::add (Task& after)
|
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.
|
// Write after.composeF4 ().
|
||||||
// TODO write after.composeFF4 ().
|
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 ()
|
int TDB2::commit ()
|
||||||
{
|
{
|
||||||
// TODO Two passes: first the pending file.
|
// TODO Two passes: first the pending file.
|
||||||
// then the compelted file.
|
// then the completed file.
|
||||||
|
|
||||||
throw std::string ("unimplemented TDB2::commit");
|
throw std::string ("unimplemented TDB2::commit");
|
||||||
}
|
}
|
||||||
|
@ -300,7 +307,7 @@ FILE* TDB2::openAndLock (const std::string& file)
|
||||||
file + "'.";
|
file + "'.";
|
||||||
|
|
||||||
// Open the file.
|
// Open the file.
|
||||||
FILE* in = fopen (file.c_str (), "rw");
|
FILE* in = fopen (file.c_str (), "r+");
|
||||||
if (!in)
|
if (!in)
|
||||||
throw std::string ("Could not open '") + file + "'.";
|
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";
|
return "pending";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
void Task::setEntry ()
|
||||||
|
{
|
||||||
|
char entryTime[16];
|
||||||
|
sprintf (entryTime, "%u", (unsigned int) time (NULL));
|
||||||
|
set ("entry", entryTime);
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
Task::status Task::getStatus ()
|
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));
|
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 until > due
|
||||||
// TODO Verify entry < until, due, start, end
|
// TODO Verify entry < until, due, start, end
|
||||||
// TODO If name == "recur", then Duration::valid (value).
|
// 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 status textToStatus (const std::string&);
|
||||||
static std::string statusToText (status);
|
static std::string statusToText (status);
|
||||||
|
|
||||||
|
void setEntry ();
|
||||||
|
|
||||||
status getStatus ();
|
status getStatus ();
|
||||||
void setSatus (status);
|
void setStatus (status);
|
||||||
|
|
||||||
int getTagCount ();
|
int getTagCount ();
|
||||||
bool hasTag (const std::string&);
|
bool hasTag (const std::string&);
|
||||||
|
@ -72,7 +74,7 @@ public:
|
||||||
void addAnnotation (const std::string&);
|
void addAnnotation (const std::string&);
|
||||||
void removeAnnotations ();
|
void removeAnnotations ();
|
||||||
|
|
||||||
bool valid () const;
|
void validate () const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int determineVersion (const std::string&);
|
int determineVersion (const std::string&);
|
||||||
|
|
|
@ -48,44 +48,36 @@ extern Context context;
|
||||||
std::string handleAdd ()
|
std::string handleAdd ()
|
||||||
{
|
{
|
||||||
std::stringstream out;
|
std::stringstream out;
|
||||||
/*
|
|
||||||
char entryTime[16];
|
|
||||||
sprintf (entryTime, "%u", (unsigned int) time (NULL));
|
|
||||||
task.setAttribute ("entry", entryTime);
|
|
||||||
|
|
||||||
std::map <std::string, std::string> atts;
|
context.task.setEntry ();
|
||||||
task.getAttributes (atts);
|
|
||||||
foreach (i, atts)
|
|
||||||
if (i->second == "")
|
|
||||||
task.removeAttribute (i->first);
|
|
||||||
|
|
||||||
// Recurring tasks get a special status.
|
// Recurring tasks get a special status.
|
||||||
if (task.getAttribute ("due") != "" &&
|
if (context.task.get ("due") != "" &&
|
||||||
task.getAttribute ("recur") != "")
|
context.task.get ("recur") != "")
|
||||||
{
|
{
|
||||||
task.setStatus (T::recurring);
|
context.task.setStatus (Task::recurring);
|
||||||
task.setAttribute ("mask", "");
|
context.task.set ("mask", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Override with default.project, if not specified.
|
// Override with default.project, if not specified.
|
||||||
if (task.getAttribute ("project") == "")
|
if (context.task.get ("project") == "")
|
||||||
task.setAttribute ("project", context.config.get ("default.project", ""));
|
context.task.set ("project", context.config.get ("default.project", ""));
|
||||||
|
|
||||||
// Override with default.priority, if not specified.
|
// Override with default.priority, if not specified.
|
||||||
if (task.getAttribute ("priority") == "")
|
if (context.task.get ("priority") == "")
|
||||||
{
|
{
|
||||||
std::string defaultPriority = context.config.get ("default.priority", "");
|
std::string defaultPriority = context.config.get ("default.priority", "");
|
||||||
if (validPriority (defaultPriority))
|
if (validPriority (defaultPriority))
|
||||||
task.setAttribute ("priority", defaultPriority);
|
context.task.set ("priority", defaultPriority);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Disallow blank descriptions.
|
// Only valid tasks can be added.
|
||||||
if (task.getDescription () == "")
|
context.task.validate ();
|
||||||
throw std::string ("Cannot add a task that is blank, or contains <CR> or <LF> characters.");
|
|
||||||
|
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 ();
|
return out.str ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue