Database: Refactored data I/O

This commit is contained in:
Paul Beckingham 2016-04-11 08:22:27 -04:00
parent 01301dc647
commit cee6ff0c2e
2 changed files with 72 additions and 16 deletions

View file

@ -86,26 +86,22 @@ std::vector <std::string> Database::files () const
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Walk backwards through the files until an interval is found. // Walk backwards through the files until an interval is found.
Interval Database::getLatestInterval () std::string Database::lastLine ()
{ {
std::vector <Datafile>::reverse_iterator ri; std::vector <Datafile>::reverse_iterator ri;
for (ri = _files.rbegin (); ri != _files.rend (); ri++) for (ri = _files.rbegin (); ri != _files.rend (); ri++)
{ return ri->lastLine ();
auto i = ri->getLatestInterval ();
if (! i.empty ())
return i;
}
return Interval (); return "";
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
std::vector <Interval> Database::getAllIntervals () std::vector <std::string> Database::allLines ()
{ {
std::vector <Interval> all; std::vector <std::string> all;
for (auto& file : _files) for (auto& file : _files)
{ {
auto i = file.getAllIntervals (); auto i = file.allLines ();
all.insert (all.end (), all.insert (all.end (),
std::make_move_iterator (i.begin ()), std::make_move_iterator (i.begin ()),
std::make_move_iterator (i.end ())); std::make_move_iterator (i.end ()));
@ -129,13 +125,51 @@ void Database::addExclusion (const std::string& exclusion)
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void Database::addInterval (const Interval& interval) void Database::addInterval (const Interval& interval)
{ {
_files.back ().addInterval (interval); std::vector <Datafile>::reverse_iterator ri;
for (ri = _files.rbegin (); ri != _files.rend (); ri++)
if (ri->addInterval (interval))
return;
// Datafile for this interval does not exist. This means the data file was
// deleted/removed, or the interval is old. Create the file.
createNewDatafile (interval.start ().year (), interval.start ().month ());
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void Database::modifyInterval (const Interval& interval) void Database::deleteInterval (const Interval& interval)
{ {
_files.back ().modifyInterval (interval); std::vector <Datafile>::reverse_iterator ri;
for (ri = _files.rbegin (); ri != _files.rend (); ri++)
if (ri->deleteInterval (interval))
break;
// Datafile for this interval does not exist. This means the data file was
// deleted/removed, or the interval is old. Nothing to do.
}
////////////////////////////////////////////////////////////////////////////////
void Database::modifyInterval (const Interval& from, const Interval& to)
{
// The algorithm to modify an interval is first to find and remove it from the
// Datafile, then add it back to the right Datafile. This is because
// modifїcation may involve changing the start date, which could mean the
// Interval belongs in a different file.
// Delete the interval, if found. If not found, then this means the data file
// was deleted/moved.
std::vector <Datafile>::reverse_iterator ri;
for (ri = _files.rbegin (); ri != _files.rend (); ri++)
if (ri->deleteInterval (from))
break;
// Add the interval to the right file.
for (ri = _files.rbegin (); ri != _files.rend (); ri++)
if (ri->addInterval (to))
return;
// There was no file that accepted the interval, which means the data file was
// deleted/moved. recreate the file.
createNewDatafile (to.start ().year (), to.start ().month ());
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -172,3 +206,23 @@ std::string Database::currentDataFile () const
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void Database::createNewDatafile (int year, int month)
{
std::stringstream file;
file << _location
<< '/'
<< std::setw (4) << std::setfill ('0') << year
<< '-'
<< std::setw (2) << std::setfill ('0') << month
<< ".data";
// Create the Datafile. New files need the set of current exclusions.
Datafile df;
df.initialize (file.str ());
df.setExclusions (_exclusions);
// Insert Datafile into _files. The position is not important.
_files.push_back (df);
}
////////////////////////////////////////////////////////////////////////////////

View file

@ -40,18 +40,20 @@ public:
void commit (); void commit ();
std::vector <std::string> files () const; std::vector <std::string> files () const;
Interval getLatestInterval (); std::string lastLine ();
std::vector <Interval> getAllIntervals (); std::vector <std::string> allLines ();
void clearExclusions (); void clearExclusions ();
void addExclusion (const std::string&); void addExclusion (const std::string&);
void addInterval (const Interval&); void addInterval (const Interval&);
void modifyInterval (const Interval&); void deleteInterval (const Interval&);
void modifyInterval (const Interval&, const Interval&);
std::string dump () const; std::string dump () const;
private: private:
std::string currentDataFile () const; std::string currentDataFile () const;
void createNewDatafile (int, int);
private: private:
std::string _location {"~/.timewarrior/data"}; std::string _location {"~/.timewarrior/data"};