Add commit command

Change-Id: If8ff0ec34f5a187b3585ac0ff98e06fba699f809
diff --git a/src/ast_commands.hpp b/src/ast_commands.hpp
index a27b09c..3a92e10 100644
--- a/src/ast_commands.hpp
+++ b/src/ast_commands.hpp
@@ -55,7 +55,12 @@
     leaf_data_ m_data;
 };
 
-using command_ = boost::variant<ls_, cd_, create_, delete_, set_>;
+struct commit_ : x3::position_tagged {
+    bool operator==(const set_& b) const;
+};
+
+
+using command_ = boost::variant<ls_, cd_, create_, delete_, set_, commit_>;
 
 BOOST_FUSION_ADAPT_STRUCT(ls_, m_path)
 BOOST_FUSION_ADAPT_STRUCT(cd_, m_path)
@@ -63,3 +68,4 @@
 BOOST_FUSION_ADAPT_STRUCT(delete_, m_path)
 BOOST_FUSION_ADAPT_STRUCT(enum_, m_value)
 BOOST_FUSION_ADAPT_STRUCT(set_, m_path, m_data)
+BOOST_FUSION_ADAPT_STRUCT(commit_)
diff --git a/src/ast_handlers.hpp b/src/ast_handlers.hpp
index 2953dad..7099542 100644
--- a/src/ast_handlers.hpp
+++ b/src/ast_handlers.hpp
@@ -383,6 +383,8 @@
     }
 };
 
+struct commit_class;
+
 struct command_class {
     template <typename Iterator, typename Exception, typename Context>
     x3::error_handler_result on_error(Iterator&, Iterator const&, Exception const& x, Context const& context)
diff --git a/src/datastore_access.hpp b/src/datastore_access.hpp
index c7a7ee7..7259273 100644
--- a/src/datastore_access.hpp
+++ b/src/datastore_access.hpp
@@ -23,4 +23,6 @@
     virtual void setLeaf(const std::string& path, leaf_data_ value) = 0;
     virtual void createPresenceContainer(const std::string& path) = 0;
     virtual void deletePresenceContainer(const std::string& path) = 0;
+
+    virtual void commitChanges() = 0;
 };
diff --git a/src/grammars.hpp b/src/grammars.hpp
index 06e1bf8..4980e3a 100644
--- a/src/grammars.hpp
+++ b/src/grammars.hpp
@@ -39,6 +39,7 @@
 x3::rule<set_class, set_> const set = "set";
 x3::rule<create_class, create_> const create = "create";
 x3::rule<delete_class, delete_> const delete_rule = "delete_rule";
+x3::rule<commit_class, commit_> const commit = "commit";
 x3::rule<command_class, command_> const command = "command";
 
 #if __clang__
@@ -141,8 +142,11 @@
 auto const set_def =
         lit("set") >> space_separator > leafPath > leaf_data;
 
+auto const commit_def =
+        lit("commit") >> x3::attr(commit_());
+
 auto const command_def =
-        x3::expect[cd | create | delete_rule | set | ls] >> x3::eoi;
+        x3::expect[cd | create | delete_rule | set | commit | ls] >> x3::eoi;
 
 #if __clang__
 #pragma GCC diagnostic pop
@@ -169,6 +173,7 @@
 BOOST_SPIRIT_DEFINE(leaf_data_uint)
 BOOST_SPIRIT_DEFINE(leaf_data_string)
 BOOST_SPIRIT_DEFINE(set)
+BOOST_SPIRIT_DEFINE(commit)
 BOOST_SPIRIT_DEFINE(ls)
 BOOST_SPIRIT_DEFINE(cd)
 BOOST_SPIRIT_DEFINE(create)
diff --git a/src/interpreter.cpp b/src/interpreter.cpp
index 24c48c4..436ca34 100644
--- a/src/interpreter.cpp
+++ b/src/interpreter.cpp
@@ -24,6 +24,11 @@
     }
 };
 
+void Interpreter::operator()(const commit_&) const
+{
+    m_datastore.commitChanges();
+}
+
 void Interpreter::operator()(const set_& set) const
 {
     m_datastore.setLeaf(absolutePathFromCommand(set), set.m_data);
@@ -59,6 +64,7 @@
 }
 
 Interpreter::Interpreter(Parser& parser, DatastoreAccess& datastore)
-    : m_parser(parser), m_datastore(datastore)
+    : m_parser(parser)
+    , m_datastore(datastore)
 {
 }
diff --git a/src/interpreter.hpp b/src/interpreter.hpp
index 87f12f1..fd14ffe 100644
--- a/src/interpreter.hpp
+++ b/src/interpreter.hpp
@@ -9,12 +9,13 @@
 #pragma once
 
 #include <boost/variant/static_visitor.hpp>
-#include "parser.hpp"
 #include "datastore_access.hpp"
+#include "parser.hpp"
 
 struct Interpreter : boost::static_visitor<void> {
     Interpreter(Parser& parser, DatastoreAccess& datastore);
 
+    void operator()(const commit_&) const;
     void operator()(const set_&) const;
     void operator()(const cd_&) const;
     void operator()(const create_&) const;
diff --git a/src/sysrepo_access.cpp b/src/sysrepo_access.cpp
index 09eb35d..54fa1fd 100644
--- a/src/sysrepo_access.cpp
+++ b/src/sysrepo_access.cpp
@@ -61,10 +61,7 @@
     }
 };
 
-SysrepoAccess::~SysrepoAccess()
-{
-    m_session->commit();
-}
+SysrepoAccess::~SysrepoAccess() = default;
 
 SysrepoAccess::SysrepoAccess(const std::string& appname)
     : m_connection(new Connection(appname.c_str()))
@@ -101,3 +98,8 @@
 {
     m_session->delete_item(path.c_str());
 }
+
+void SysrepoAccess::commitChanges()
+{
+    m_session->commit();
+}
diff --git a/src/sysrepo_access.hpp b/src/sysrepo_access.hpp
index 0a9f57b..3630961 100644
--- a/src/sysrepo_access.hpp
+++ b/src/sysrepo_access.hpp
@@ -28,6 +28,8 @@
     void createPresenceContainer(const std::string& path) override;
     void deletePresenceContainer(const std::string& path) override;
 
+    void commitChanges() override;
+
 private:
     std::shared_ptr<Connection> m_connection;
     std::shared_ptr<Session> m_session;