mirror of
https://github.com/GothenburgBitFactory/taskwarrior.git
synced 2025-06-26 10:54:26 +02:00
Integration - TDB write operations
- TDB::gc rewritten. - TDB::commit fixed. - Corrected usage of handleRecurringTasks wrt TDB. - Unit tests for TDB.
This commit is contained in:
parent
314ce572e1
commit
7ff178cecc
12 changed files with 211 additions and 125 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -5,7 +5,7 @@ config.h.in
|
|||
config.status
|
||||
src/.deps
|
||||
src/Makefile
|
||||
*/task
|
||||
*/*task
|
||||
stamp-h1
|
||||
Makefile
|
||||
Makefile.in
|
||||
|
|
|
@ -57,16 +57,17 @@ Record::~Record ()
|
|||
//
|
||||
// [ Att::composeF4 ... ] \n
|
||||
//
|
||||
std::string Record::composeF4 ()
|
||||
std::string Record::composeF4 () const
|
||||
{
|
||||
std::string ff4 = "[";
|
||||
|
||||
bool first = true;
|
||||
foreach (att, (*this))
|
||||
std::map <std::string, Att>::const_iterator it;
|
||||
for (it = this->begin (); it != this->end (); ++it)
|
||||
{
|
||||
if (att->second.value () != "")
|
||||
if (it->second.value () != "")
|
||||
{
|
||||
ff4 += (first ? "" : " ") + att->second.composeF4 ();
|
||||
ff4 += (first ? "" : " ") + it->second.composeF4 ();
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,8 +39,8 @@ public:
|
|||
Record (const std::string&); // Copy constructor
|
||||
virtual ~Record (); // Destructor
|
||||
|
||||
std::string composeF4 ();
|
||||
std::string composeCSV ();
|
||||
std::string composeF4 () const;
|
||||
std::string composeCSV () const;
|
||||
void parse (const std::string&);
|
||||
|
||||
bool has (const std::string&) const;
|
||||
|
|
86
src/TDB.cpp
86
src/TDB.cpp
|
@ -27,6 +27,7 @@
|
|||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/file.h>
|
||||
|
@ -53,7 +54,7 @@
|
|||
// | | |
|
||||
// | | +- TDB::add (T)
|
||||
// | | |
|
||||
// | | +- TDB::update (T, T')
|
||||
// | | +- TDB::update (T)
|
||||
// | | |
|
||||
// | | +- TDB::commit
|
||||
// | | write all
|
||||
|
@ -133,8 +134,11 @@ void TDB::unlock ()
|
|||
|
||||
foreach (location, mLocations)
|
||||
{
|
||||
fflush (location->pending);
|
||||
fclose (location->pending);
|
||||
location->pending = NULL;
|
||||
|
||||
fflush (location->completed);
|
||||
fclose (location->completed);
|
||||
location->completed = NULL;
|
||||
}
|
||||
|
@ -257,16 +261,16 @@ int TDB::loadCompleted (std::vector <Task>& tasks, Filter& filter)
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// TODO Write to transaction log.
|
||||
// Note: mLocations[0] is where all tasks are written.
|
||||
void TDB::add (Task& task)
|
||||
void TDB::add (const Task& task)
|
||||
{
|
||||
mNew.push_back (task);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// TODO Write to transaction log.
|
||||
void TDB::update (Task& before, Task& after)
|
||||
void TDB::update (const Task& task)
|
||||
{
|
||||
mModified.push_back (after);
|
||||
mModified.push_back (task);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -308,9 +312,7 @@ int TDB::commit ()
|
|||
mNew.clear ();
|
||||
|
||||
// Write out all pending.
|
||||
fseek (mLocations[0].pending, 0, SEEK_SET);
|
||||
// TODO Do I need to truncate the file? Does file I/O even work that way
|
||||
// any more? I forget.
|
||||
if (fseek (mLocations[0].pending, 0, SEEK_SET) == 0)
|
||||
foreach (task, mPending)
|
||||
fputs (task->composeF4 ().c_str (), mLocations[0].pending);
|
||||
}
|
||||
|
@ -337,50 +339,70 @@ void TDB::upgrade ()
|
|||
int TDB::gc ()
|
||||
{
|
||||
int count = 0;
|
||||
/*
|
||||
// Read everything from the pending file.
|
||||
std::vector <T> all;
|
||||
allPendingT (all);
|
||||
|
||||
// A list of the truly pending tasks.
|
||||
std::vector <T> pending;
|
||||
// Set up a second TDB.
|
||||
Filter filter;
|
||||
TDB tdb;
|
||||
tdb.location (mLocations[0].path);
|
||||
tdb.lock ();
|
||||
|
||||
std::vector<T>::iterator it;
|
||||
for (it = all.begin (); it != all.end (); ++it)
|
||||
{
|
||||
// Some tasks stay in the pending file.
|
||||
if (it->getStatus () == T::pending ||
|
||||
it->getStatus () == T::recurring)
|
||||
{
|
||||
pending.push_back (*it);
|
||||
}
|
||||
std::vector <Task> pending;
|
||||
tdb.loadPending (pending, filter);
|
||||
|
||||
// Others are transferred to the completed file.
|
||||
else
|
||||
std::vector <Task> completed;
|
||||
tdb.loadCompleted (completed, filter);
|
||||
|
||||
// Now move completed and deleted tasks from the pending list to the
|
||||
// completed list. Isn't garbage collection easy?
|
||||
foreach (task, pending)
|
||||
{
|
||||
writeCompleted (*it);
|
||||
if (task->getStatus () == Task::completed ||
|
||||
task->getStatus () == Task::deleted)
|
||||
{
|
||||
completed.push_back (*task);
|
||||
pending.erase (task);
|
||||
++count;
|
||||
}
|
||||
}
|
||||
|
||||
// Dump all clean tasks into pending. But don't bother unless at least one
|
||||
// task was transferred.
|
||||
if (count)
|
||||
overwritePending (pending);
|
||||
*/
|
||||
// No commit - all updates performed manually.
|
||||
if (count > 0)
|
||||
{
|
||||
if (fseek (tdb.mLocations[0].pending, 0, SEEK_SET) == 0)
|
||||
{
|
||||
ftruncate (fileno (tdb.mLocations[0].pending), 0);
|
||||
foreach (task, pending)
|
||||
fputs (task->composeF4 ().c_str (), tdb.mLocations[0].pending);
|
||||
}
|
||||
|
||||
if (fseek (tdb.mLocations[0].completed, 0, SEEK_SET) == 0)
|
||||
{
|
||||
ftruncate (fileno (tdb.mLocations[0].completed), 0);
|
||||
foreach (task, completed)
|
||||
fputs (task->composeF4 ().c_str (), tdb.mLocations[0].completed);
|
||||
}
|
||||
}
|
||||
|
||||
// Close files.
|
||||
tdb.unlock ();
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
FILE* TDB::openAndLock (const std::string& file)
|
||||
{
|
||||
// TODO Need provision here for read-only locations.
|
||||
|
||||
// Check for access.
|
||||
if (access (file.c_str (), F_OK | R_OK | W_OK))
|
||||
bool exists = access (file.c_str (), F_OK) ? false : true;
|
||||
if (exists)
|
||||
if (access (file.c_str (), R_OK | W_OK))
|
||||
throw std::string ("Task does not have the correct permissions for '") +
|
||||
file + "'.";
|
||||
|
||||
// Open the file.
|
||||
FILE* in = fopen (file.c_str (), "r+");
|
||||
FILE* in = fopen (file.c_str (), (exists ? "r+" : "w+"));
|
||||
if (!in)
|
||||
throw std::string ("Could not open '") + file + "'.";
|
||||
|
||||
|
|
|
@ -53,8 +53,8 @@ public:
|
|||
int loadPending (std::vector <Task>&, Filter&);
|
||||
int loadCompleted (std::vector <Task>&, Filter&);
|
||||
|
||||
void add (Task&); // Single task add to pending
|
||||
void update (Task&, Task&); // Single task update to pending
|
||||
void add (const Task&); // Single task add to pending
|
||||
void update (const Task&); // Single task update to pending
|
||||
int commit (); // Write out all tasks
|
||||
void upgrade (); // Convert both files to FF4
|
||||
int gc (); // Clean up pending
|
||||
|
|
23
src/Task.cpp
23
src/Task.cpp
|
@ -40,6 +40,25 @@ Task::Task ()
|
|||
set ("uuid", uuid ());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
Task::Task (const Task& other)
|
||||
: Record (other)
|
||||
, id (other.id)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
Task& Task::operator= (const Task& other)
|
||||
{
|
||||
if (this != &other)
|
||||
{
|
||||
Record::operator= (other);
|
||||
id = other.id;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Attempt an FF4 parse first, using Record::parse, and in the event of an error
|
||||
// try a legacy parse (F3, FF2). Note that FF1 is no longer supported.
|
||||
|
@ -296,7 +315,7 @@ void Task::legacyParse (const std::string& line)
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
std::string Task::composeCSV ()
|
||||
std::string Task::composeCSV () const
|
||||
{
|
||||
std::stringstream out;
|
||||
|
||||
|
@ -421,7 +440,7 @@ void Task::addTags (const std::vector <std::string>& tags)
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void Task::getTags (std::vector<std::string>& tags)
|
||||
void Task::getTags (std::vector<std::string>& tags) const
|
||||
{
|
||||
split (tags, get ("tags"), ',');
|
||||
}
|
||||
|
|
|
@ -36,11 +36,13 @@ class Task : public Record
|
|||
{
|
||||
public:
|
||||
Task (); // Default constructor
|
||||
Task (const Task&); // Copy constructor
|
||||
Task& operator= (const Task&); // Assignment operator
|
||||
Task (const std::string&); // Parse
|
||||
~Task (); // Destructor
|
||||
|
||||
void parse (const std::string&);
|
||||
std::string composeCSV ();
|
||||
std::string composeCSV () const;
|
||||
|
||||
// Status values.
|
||||
enum status {pending, completed, deleted, recurring /* , retired, deferred */};
|
||||
|
@ -61,7 +63,7 @@ public:
|
|||
bool hasTag (const std::string&);
|
||||
void addTag (const std::string&);
|
||||
void addTags (const std::vector <std::string>&);
|
||||
void getTags (std::vector<std::string>&);
|
||||
void getTags (std::vector<std::string>&) const;
|
||||
void removeTag (const std::string&);
|
||||
|
||||
void getAnnotations (std::vector <Att>&) const;
|
||||
|
|
|
@ -82,6 +82,7 @@ std::string handleAdd ()
|
|||
|
||||
context.tdb.lock (context.config.get ("locking", true));
|
||||
context.tdb.add (context.task);
|
||||
context.tdb.commit ();
|
||||
context.tdb.unlock ();
|
||||
|
||||
return out.str ();
|
||||
|
@ -97,6 +98,8 @@ std::string handleProjects ()
|
|||
std::vector <Task> tasks;
|
||||
context.tdb.lock (context.config.get ("locking", true));
|
||||
int quantity = context.tdb.loadPending (tasks, context.filter);
|
||||
handleRecurrence (tasks);
|
||||
context.tdb.commit ();
|
||||
context.tdb.unlock ();
|
||||
|
||||
// Scan all the tasks for their project name, building a map using project
|
||||
|
@ -154,6 +157,8 @@ std::string handleTags ()
|
|||
std::vector <Task> tasks;
|
||||
context.tdb.lock (context.config.get ("locking", true));
|
||||
int quantity = context.tdb.loadPending (tasks, context.filter);
|
||||
handleRecurrence (tasks);
|
||||
context.tdb.commit ();
|
||||
context.tdb.unlock ();
|
||||
|
||||
// Scan all the tasks for their project name, building a map using project
|
||||
|
@ -663,8 +668,9 @@ std::string handleExport ()
|
|||
std::vector <Task> tasks;
|
||||
context.tdb.lock (context.config.get ("locking", true));
|
||||
context.tdb.loadPending (tasks, context.filter);
|
||||
handleRecurrence (tasks);
|
||||
context.tdb.commit ();
|
||||
context.tdb.unlock ();
|
||||
// TODO handleRecurrence (tdb, tasks);
|
||||
|
||||
foreach (task, tasks)
|
||||
{
|
||||
|
|
|
@ -86,9 +86,12 @@ std::string handleCustomReport (const std::string& report)
|
|||
context.tdb.lock (context.config.get ("locking", true));
|
||||
// TODO Include filter from custom report.
|
||||
context.tdb.load (tasks, context.filter);
|
||||
handleRecurrence (tasks);
|
||||
context.tdb.commit ();
|
||||
context.tdb.unlock ();
|
||||
|
||||
// TODO handleRecurrence (tdb, tasks);
|
||||
// Filter sequence.
|
||||
context.filter.applySequence (tasks, context.sequence);
|
||||
|
||||
// Initialize colorization for subsequent auto colorization.
|
||||
initializeColorRules ();
|
||||
|
|
|
@ -45,7 +45,7 @@ void gatherNextTasks (std::vector <Task>&, std::vector <int>&);
|
|||
void onChangeCallback ();
|
||||
|
||||
// recur.cpp
|
||||
void handleRecurrence ();
|
||||
void handleRecurrence (std::vector <Task>&);
|
||||
Date getNextRecurrence (Date&, std::string&);
|
||||
bool generateDueDates (Task&, std::vector <Date>&);
|
||||
void updateRecurrenceMask (/*TDB&,*/ std::vector <Task>&, Task&);
|
||||
|
|
|
@ -271,8 +271,9 @@ std::string handleInfo ()
|
|||
std::vector <Task> tasks;
|
||||
context.tdb.lock (context.config.get ("locking", true));
|
||||
context.tdb.loadPending (tasks, context.filter);
|
||||
handleRecurrence (tasks);
|
||||
context.tdb.commit ();
|
||||
context.tdb.unlock ();
|
||||
// TODO handleRecurrence (tdb, tasks);
|
||||
|
||||
// Filter sequence.
|
||||
context.filter.applySequence (tasks, context.sequence);
|
||||
|
@ -487,8 +488,9 @@ std::string handleReportSummary ()
|
|||
std::vector <Task> tasks;
|
||||
context.tdb.lock (context.config.get ("locking", true));
|
||||
context.tdb.load (tasks, context.filter);
|
||||
handleRecurrence (tasks);
|
||||
context.tdb.commit ();
|
||||
context.tdb.unlock ();
|
||||
// TODO handleRecurrence (tdb, tasks);
|
||||
|
||||
// Generate unique list of project names from all pending tasks.
|
||||
std::map <std::string, bool> allProjects;
|
||||
|
@ -651,8 +653,9 @@ std::string handleReportNext ()
|
|||
std::vector <Task> tasks;
|
||||
context.tdb.lock (context.config.get ("locking", true));
|
||||
context.tdb.loadPending (tasks, context.filter);
|
||||
handleRecurrence (tasks);
|
||||
context.tdb.commit ();
|
||||
context.tdb.unlock ();
|
||||
// TODO handleRecurrence (tdb, tasks);
|
||||
|
||||
// Restrict to matching subset.
|
||||
std::vector <int> matching;
|
||||
|
@ -814,8 +817,9 @@ std::string handleReportHistory ()
|
|||
std::vector <Task> tasks;
|
||||
context.tdb.lock (context.config.get ("locking", true));
|
||||
context.tdb.load (tasks, context.filter);
|
||||
handleRecurrence (tasks);
|
||||
context.tdb.commit ();
|
||||
context.tdb.unlock ();
|
||||
// TODO handleRecurrence (tdb, tasks);
|
||||
|
||||
foreach (task, tasks)
|
||||
{
|
||||
|
@ -967,8 +971,9 @@ std::string handleReportGHistory ()
|
|||
std::vector <Task> tasks;
|
||||
context.tdb.lock (context.config.get ("locking", true));
|
||||
context.tdb.load (tasks, context.filter);
|
||||
handleRecurrence (tasks);
|
||||
context.tdb.commit ();
|
||||
context.tdb.unlock ();
|
||||
// TODO handleRecurrence (tdb, tasks);
|
||||
|
||||
foreach (task, tasks)
|
||||
{
|
||||
|
@ -1157,8 +1162,9 @@ std::string handleReportTimesheet ()
|
|||
std::vector <Task> tasks;
|
||||
context.tdb.lock (context.config.get ("locking", true));
|
||||
context.tdb.load (tasks, context.filter);
|
||||
handleRecurrence (tasks);
|
||||
context.tdb.commit ();
|
||||
context.tdb.unlock ();
|
||||
// TODO handleRecurrence (tdb, tasks);
|
||||
|
||||
// Just do this once.
|
||||
int width = context.getWidth ();
|
||||
|
@ -1487,8 +1493,9 @@ std::string handleReportCalendar ()
|
|||
std::vector <Task> tasks;
|
||||
context.tdb.lock (context.config.get ("locking", true));
|
||||
context.tdb.loadPending (tasks, context.filter);
|
||||
handleRecurrence (tasks);
|
||||
context.tdb.commit ();
|
||||
context.tdb.unlock ();
|
||||
// TODO handleRecurrence (tdb, tasks);
|
||||
|
||||
// Find the oldest pending due date.
|
||||
Date oldest;
|
||||
|
@ -1594,8 +1601,9 @@ std::string handleReportStats ()
|
|||
std::vector <Task> tasks;
|
||||
context.tdb.lock (context.config.get ("locking", true));
|
||||
context.tdb.load (tasks, context.filter);
|
||||
handleRecurrence (tasks);
|
||||
context.tdb.commit ();
|
||||
context.tdb.unlock ();
|
||||
// TODO handleRecurrence (tdb, tasks);
|
||||
|
||||
Date now;
|
||||
time_t earliest = time (NULL);
|
||||
|
|
|
@ -32,88 +32,111 @@
|
|||
|
||||
Context context;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void get (std::vector <Task>& pending, std::vector <Task>& completed)
|
||||
{
|
||||
TDB tdb;
|
||||
tdb.location (".");
|
||||
tdb.lock ();
|
||||
tdb.loadPending (pending, context.filter);
|
||||
tdb.loadCompleted (completed, context.filter);
|
||||
tdb.unlock ();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
int main (int argc, char** argv)
|
||||
{
|
||||
UnitTest t (38);
|
||||
UnitTest t (22);
|
||||
|
||||
try
|
||||
{
|
||||
/*
|
||||
// Remove any residual test file.
|
||||
unlink ("./pending.data");
|
||||
unlink ("./completed.data");
|
||||
|
||||
// Try reading an empty database.
|
||||
Filter filter;
|
||||
std::vector <Task> all;
|
||||
std::vector <Task> pending;
|
||||
std::vector <Task> completed;
|
||||
get (pending, completed);
|
||||
t.ok (pending.size () == 0, "TDB Read empty pending");
|
||||
t.ok (completed.size () == 0, "TDB Read empty completed");
|
||||
|
||||
// Add without commit.
|
||||
TDB tdb;
|
||||
tdb.dataDirectory (".");
|
||||
std::vector <T> all;
|
||||
t.ok (!tdb.pendingT (all), "TDB::pendingT read empty db");
|
||||
t.is ((int) all.size (), 0, "empty db");
|
||||
t.ok (!tdb.allPendingT (all), "TDB::allPendingT read empty db");
|
||||
t.is ((int) all.size (), 0, "empty db");
|
||||
t.ok (!tdb.completedT (all), "TDB::completedT read empty db");
|
||||
t.is ((int) all.size (), 0, "empty db");
|
||||
t.ok (!tdb.allCompletedT (all), "TDB::allCompletedT read empty db");
|
||||
t.is ((int) all.size (), 0, "empty db");
|
||||
tdb.location (".");
|
||||
tdb.lock ();
|
||||
Task task ("[name:\"value\"]");
|
||||
tdb.add (task);
|
||||
tdb.unlock ();
|
||||
|
||||
// Add a new task.
|
||||
T t1;
|
||||
t1.setId (1);
|
||||
t1.setStatus (T::pending);
|
||||
t1.setAttribute ("project", "p1");
|
||||
t1.setDescription ("task 1");
|
||||
t.diag (t1.compose ());
|
||||
t.ok (tdb.addT (t1), "TDB::addT t1");
|
||||
pending.clear ();
|
||||
completed.clear ();
|
||||
get (pending, completed);
|
||||
t.ok (pending.size () == 0, "TDB add -> no commit -> empty");
|
||||
t.ok (completed.size () == 0, "TDB add -> no commit -> empty");
|
||||
|
||||
// Verify as above.
|
||||
t.ok (tdb.pendingT (all), "TDB::pendingT read db");
|
||||
t.is ((int) all.size (), 1, "empty db");
|
||||
t.ok (tdb.allPendingT (all), "TDB::allPendingT read db");
|
||||
t.is ((int) all.size (), 1, "empty db");
|
||||
t.ok (!tdb.completedT (all), "TDB::completedT read empty db");
|
||||
t.is ((int) all.size (), 0, "empty db");
|
||||
t.ok (!tdb.allCompletedT (all), "TDB::allCompletedT read empty db");
|
||||
t.is ((int) all.size (), 0, "empty db");
|
||||
// Add with commit.
|
||||
tdb.lock ();
|
||||
tdb.add (task);
|
||||
tdb.commit ();
|
||||
tdb.unlock ();
|
||||
|
||||
// TODO Modify task.
|
||||
get (pending, completed);
|
||||
t.ok (pending.size () == 1, "TDB add -> commit -> saved");
|
||||
t.is (pending[0].get ("name"), "value", "TDB load name=value");
|
||||
t.is (pending[0].id, 1, "TDB load verification id=1");
|
||||
t.ok (completed.size () == 0, "TDB add -> commit -> saved");
|
||||
|
||||
// Complete task.
|
||||
t1.setStatus (T::completed);
|
||||
t.ok (tdb.modifyT (t1), "TDB::modifyT (completed) t1");;
|
||||
t.ok (tdb.pendingT (all), "TDB::pendingT read db");
|
||||
t.is ((int) all.size (), 0, "empty db");
|
||||
t.ok (tdb.allPendingT (all), "TDB::allPendingT read db");
|
||||
t.is ((int) all.size (), 1, "empty db");
|
||||
t.ok (!tdb.completedT (all), "TDB::completedT read empty db");
|
||||
t.is ((int) all.size (), 0, "empty db");
|
||||
t.ok (!tdb.allCompletedT (all), "TDB::allCompletedT read empty db");
|
||||
t.is ((int) all.size (), 0, "empty db");
|
||||
// Update with commit.
|
||||
tdb.lock ();
|
||||
pending.clear ();
|
||||
completed.clear ();
|
||||
tdb.load (all, context.filter);
|
||||
all[0].set ("name", "value2");
|
||||
tdb.update (all[0]);
|
||||
tdb.commit ();
|
||||
tdb.unlock ();
|
||||
|
||||
t.is (tdb.gc (), 1, "TDB::gc");
|
||||
t.ok (tdb.pendingT (all), "TDB::pendingT read empty db");
|
||||
t.is ((int) all.size (), 0, "empty db");
|
||||
t.ok (tdb.allPendingT (all), "TDB::allPendingT read empty db");
|
||||
t.is ((int) all.size (), 0, "empty db");
|
||||
t.ok (tdb.completedT (all), "TDB::completedT read db");
|
||||
t.is ((int) all.size (), 1, "empty db");
|
||||
t.ok (tdb.allCompletedT (all), "TDB::allCompletedT read db");
|
||||
t.is ((int) all.size (), 1, "empty db");
|
||||
pending.clear ();
|
||||
completed.clear ();
|
||||
get (pending, completed);
|
||||
t.ok (all.size () == 1, "TDB update -> commit -> saved");
|
||||
t.is (all[0].get ("name"), "value2", "TDB load name=value2");
|
||||
t.is (all[0].id, 1, "TDB load verification id=1");
|
||||
|
||||
// Add a new task.
|
||||
T t2;
|
||||
t2.setId (1);
|
||||
t2.setAttribute ("project", "p2");
|
||||
t2.setDescription ("task 2");
|
||||
t.ok (tdb.addT (t2), "TDB::addT t2");
|
||||
// GC.
|
||||
tdb.lock ();
|
||||
all.clear ();
|
||||
tdb.loadPending (all, context.filter);
|
||||
all[0].setStatus (Task::completed);
|
||||
tdb.update (all[0]);
|
||||
Task t2 ("[foo:\"bar\" status:\"pending\"]");
|
||||
tdb.add (t2);
|
||||
tdb.commit ();
|
||||
tdb.unlock ();
|
||||
|
||||
// Delete task.
|
||||
t2.setStatus (T::deleted);
|
||||
t.ok (tdb.modifyT (t2), "TDB::modifyT (deleted) t2");
|
||||
pending.clear ();
|
||||
completed.clear ();
|
||||
get (pending, completed);
|
||||
t.is (pending.size (), (size_t)2, "TDB before gc pending #2");
|
||||
t.is (pending[0].id, 1, "TDB before gc pending id 1");
|
||||
t.is (pending[0].getStatus (), Task::completed, "TDB before gc pending status completed");
|
||||
t.is (pending[1].id, 2, "TDB before gc pending id 2");
|
||||
t.is (pending[1].getStatus (), Task::pending, "TDB before gc pending status pending");
|
||||
t.is (completed.size (), (size_t)0, "TDB before gc completed 0");
|
||||
|
||||
// GC the files.
|
||||
t.is (tdb.gc (), 1, "1 <- TDB::gc");
|
||||
*/
|
||||
tdb.gc ();
|
||||
|
||||
pending.clear ();
|
||||
completed.clear ();
|
||||
get (pending, completed);
|
||||
t.is (pending.size (), (size_t)1, "TDB after gc pending #1");
|
||||
t.is (pending[0].id, 1, "TDB after gc pending id 2");
|
||||
t.is (pending[0].getStatus (), Task::pending, "TDB after gc pending status pending");
|
||||
t.is (completed.size (), (size_t)1, "TDB after gc completed #1");
|
||||
t.is (completed[0].getStatus (), Task::completed, "TDB after gc completed status completed");
|
||||
}
|
||||
|
||||
catch (std::string& error)
|
||||
|
@ -128,8 +151,10 @@ int main (int argc, char** argv)
|
|||
return -2;
|
||||
}
|
||||
|
||||
/*
|
||||
unlink ("./pending.data");
|
||||
unlink ("./completed.data");
|
||||
*/
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue