From 44ea79b488f758fd04339eedea16d6e9501d8eeb Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Fri, 10 Jun 2016 22:48:03 -0400 Subject: [PATCH] CmdJoin: Implemented 'join' command --- src/commands/CMakeLists.txt | 1 + src/commands/CmdJoin.cpp | 94 +++++++++++++++++++++++++++++++++++++ src/commands/commands.h | 1 + src/init.cpp | 2 + 4 files changed, 98 insertions(+) create mode 100644 src/commands/CmdJoin.cpp diff --git a/src/commands/CMakeLists.txt b/src/commands/CMakeLists.txt index d79ab2bb..88ef8610 100644 --- a/src/commands/CMakeLists.txt +++ b/src/commands/CMakeLists.txt @@ -17,6 +17,7 @@ set (commands_SRCS CmdCancel.cpp CmdGaps.cpp CmdHelp.cpp CmdImport.cpp + CmdJoin.cpp CmdLengthen.cpp CmdMove.cpp CmdReport.cpp diff --git a/src/commands/CmdJoin.cpp b/src/commands/CmdJoin.cpp new file mode 100644 index 00000000..2ae6c832 --- /dev/null +++ b/src/commands/CmdJoin.cpp @@ -0,0 +1,94 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// Copyright 2015 - 2016, Paul Beckingham, Federico Hernandez. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// +// http://www.opensource.org/licenses/mit-license.php +// +//////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include +#include +#include +#include + +//////////////////////////////////////////////////////////////////////////////// +int CmdJoin ( + const CLI& cli, + Rules& rules, + Database& database) +{ + // Gather IDs and TAGs. + std::vector ids; + std::string delta; + for (auto& arg : cli._args) + { + if (arg.hasTag ("ID")) + ids.push_back (strtol (arg.attribute ("value").c_str (), NULL, 10)); + + if (arg.hasTag ("FILTER") && + arg._lextype == Lexer::Type::duration) + delta = arg.attribute ("raw"); + } + + // TODO Support :adjust + + // Load the data. + // Note: There is no filter. + Interval filter; + auto tracked = getTracked (database, rules, filter); + + // Only 2 IDs allowed in a join. + if (ids.size () == 2) + { + if (ids[0] <= static_cast (tracked.size ()) && + ids[1] <= static_cast (tracked.size ())) + { + // Note: It's okay to subtract a one-based number from a zero-based index. + auto first_id = std::max (ids[0], ids[1]); + auto second_id = std::min (ids[0], ids[1]); + Interval first = tracked[tracked.size () - first_id]; + Interval second = tracked[tracked.size () - second_id]; + + std::cout << "# @" << first_id << " first " << first.dump () << "\n"; + std::cout << "# @" << second_id << " second " << second.dump () << "\n"; + + // TODO Require confirmation if intervals are not consecutive. + // TODO Require confirmation if tags don't match. + + auto combined = first; + combined.range.end = second.range.end; + + database.deleteInterval (second); + database.modifyInterval (first, combined); + + // Feedback. + std::cout << "Joined @" << ids[0] << " and @" << ids[1] << '\n'; + } + } + else + std::cout << "Provide two interval IDs to join them.\n"; + + return 0; +} + +//////////////////////////////////////////////////////////////////////////////// diff --git a/src/commands/commands.h b/src/commands/commands.h index 6355b823..8f83ebb5 100644 --- a/src/commands/commands.h +++ b/src/commands/commands.h @@ -44,6 +44,7 @@ int CmdGaps (const CLI&, Rules&, Database& ); int CmdHelpUsage ( ); int CmdHelp (const CLI& ); int CmdImport ( ); +int CmdJoin (const CLI&, Rules&, Database& ); int CmdLengthen (const CLI&, Rules&, Database& ); int CmdMove (const CLI&, Rules&, Database& ); int CmdReport (const CLI&, Rules&, Database&, const Extensions&); diff --git a/src/init.cpp b/src/init.cpp index 700f16eb..37a8fb87 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -67,6 +67,7 @@ void initializeEntities (CLI& cli) cli.entity ("command", "gaps"); cli.entity ("command", "help"); cli.entity ("command", "import"); + cli.entity ("command", "join"); cli.entity ("command", "lengthen"); cli.entity ("command", "move"); cli.entity ("command", "report"); @@ -264,6 +265,7 @@ int dispatchCommand ( else if (command == "gaps") status = CmdGaps (cli, rules, database ); else if (command == "help") status = CmdHelp (cli ); else if (command == "import") status = CmdImport ( ); + else if (command == "join") status = CmdJoin (cli, rules, database ); else if (command == "lengthen") status = CmdLengthen (cli, rules, database ); else if (command == "month") status = CmdChartMonth (cli, rules, database ); else if (command == "move") status = CmdMove (cli, rules, database );