Implement SysrepoAccess

The class is currently only able to set leaf values and create and
delete presence containers.

Change-Id: I3b187fa359a766a7bec2da5772e50ebb6bde7b15
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 3d71ccd..702ccb8 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -53,6 +53,7 @@
 
 find_package(PkgConfig)
 pkg_check_modules(LIBYANG REQUIRED libyang-cpp>=0.15.111)
+pkg_check_modules(SYSREPO REQUIRED libSysrepo-cpp>=0.7.3)
 
 # we don't need filename tracking, and we prefer to use header-only Boost
 add_definitions(-DBOOST_SPIRIT_X3_NO_FILESYSTEM)
@@ -68,6 +69,13 @@
     )
 target_link_libraries(datastoreaccess PUBLIC Boost::boost)
 
+add_library(sysrepoaccess STATIC
+    src/sysrepo_access.cpp
+    )
+target_link_libraries(sysrepoaccess datastoreaccess ${SYSREPO_LIBRARIES})
+link_directories(${SYSREPO_LIBRARY_DIRS})
+target_include_directories(sysrepoaccess SYSTEM PRIVATE ${SYSREPO_INCLUDE_DIRS})
+
 add_library(yangschema STATIC
     src/yang_schema.cpp
     )
@@ -89,7 +97,7 @@
 add_executable(netconf-cli
     src/main.cpp
     )
-target_link_libraries(netconf-cli yangschema docopt parser)
+target_link_libraries(netconf-cli sysrepoaccess yangschema docopt parser)
 if(CMAKE_CXX_FLAGS MATCHES "-stdlib=libc\\+\\+")
     target_link_libraries(netconf-cli c++experimental)
 else()
diff --git a/src/sysrepo_access.cpp b/src/sysrepo_access.cpp
new file mode 100644
index 0000000..f7799b0
--- /dev/null
+++ b/src/sysrepo_access.cpp
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2018 CESNET, https://photonics.cesnet.cz/
+ * Copyright (C) 2018 FIT CVUT, https://fit.cvut.cz/
+ *
+ * Written by Václav Kubernát <kubervac@fit.cvut.cz>
+ *
+*/
+
+#include <sysrepo-cpp/Session.h>
+#include "sysrepo_access.hpp"
+
+
+struct valFromValue : boost::static_visitor<S_Val> {
+    S_Val operator()(const enum_& value) const
+    {
+        return std::make_shared<Val>(value.m_value.c_str(), SR_ENUM_T);
+    }
+
+    S_Val operator()(const std::string& value) const
+    {
+        return std::make_shared<Val>(value.c_str());
+    }
+
+    S_Val operator()(const uint32_t& value) const
+    {
+        return std::make_shared<Val>(value, SR_UINT32_T);
+    }
+
+    S_Val operator()(const int32_t& value) const
+    {
+        return std::make_shared<Val>(value, SR_INT32_T);
+    }
+
+    S_Val operator()(const bool& value) const
+    {
+        return std::make_shared<Val>(value, SR_BOOL_T);
+    }
+
+    S_Val operator()(const double& value) const
+    {
+        return std::make_shared<Val>(value);
+    }
+};
+
+SysrepoAccess::~SysrepoAccess()
+{
+    m_session->commit();
+}
+
+SysrepoAccess::SysrepoAccess(const std::string& appname)
+    : m_connection(new Connection(appname.c_str()))
+{
+    m_session = std::make_shared<Session>(m_connection);
+}
+
+std::map<std::string, leaf_data_> SysrepoAccess::getItems(const std::string& path)
+{
+    std::map<std::string, leaf_data_> res;
+    auto iterator = m_session->get_items_iter(path.c_str());
+
+    // TODO: implement this (and make use of it somehow)
+
+    return res;
+}
+
+void SysrepoAccess::setLeaf(const std::string& path, leaf_data_ value)
+{
+    m_session->set_item(path.c_str(), boost::apply_visitor(valFromValue(), value));
+}
+
+void SysrepoAccess::createPresenceContainer(const std::string& path)
+{
+    m_session->set_item(path.c_str());
+}
+
+void SysrepoAccess::deletePresenceContainer(const std::string& path)
+{
+    m_session->delete_item(path.c_str());
+}
diff --git a/src/sysrepo_access.hpp b/src/sysrepo_access.hpp
new file mode 100644
index 0000000..0a9f57b
--- /dev/null
+++ b/src/sysrepo_access.hpp
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2018 CESNET, https://photonics.cesnet.cz/
+ * Copyright (C) 2018 FIT CVUT, https://fit.cvut.cz/
+ *
+ * Written by Václav Kubernát <kubervac@fit.cvut.cz>
+ *
+*/
+
+#pragma once
+
+#include <string>
+#include "ast_commands.hpp"
+#include "datastore_access.hpp"
+
+/*! \class DatastoreAccess
+ *     \brief Abstract class for accessing a datastore
+ */
+
+class Connection;
+class Session;
+
+class SysrepoAccess : public DatastoreAccess {
+public:
+    ~SysrepoAccess() override;
+    SysrepoAccess(const std::string& appname);
+    std::map<std::string, leaf_data_> getItems(const std::string& path) override;
+    void setLeaf(const std::string& path, leaf_data_ value) override;
+    void createPresenceContainer(const std::string& path) override;
+    void deletePresenceContainer(const std::string& path) override;
+
+private:
+    std::shared_ptr<Connection> m_connection;
+    std::shared_ptr<Session> m_session;
+};