Add ProxyDatastore

This class will be used to intercept certain commands from the cli, like
entering RPC input. Right now, it works just as a pass-through.

Change-Id: I2d252609c1354005a0ccf4a1f26399dc895a73e8
diff --git a/src/cli.cpp b/src/cli.cpp
index 8a3536f..1f62f78 100644
--- a/src/cli.cpp
+++ b/src/cli.cpp
@@ -12,6 +12,7 @@
 #include <sstream>
 #include "NETCONF_CLI_VERSION.h"
 #include "interpreter.hpp"
+#include "proxy_datastore.hpp"
 #if defined(SYSREPO_CLI)
 #include "sysrepo_access.hpp"
 #define PROGRAM_NAME "sysrepo-cli"
@@ -72,10 +73,10 @@
             return 1;
         }
     }
-    SysrepoAccess datastore(PROGRAM_NAME, datastoreType);
+    auto datastore = std::make_shared<SysrepoAccess>(PROGRAM_NAME, datastoreType);
     std::cout << "Connected to sysrepo [datastore: " << (datastoreType == Datastore::Startup ? "startup" : "running") << "]" << std::endl;
 #elif defined(YANG_CLI)
-    YangAccess datastore;
+    auto datastore = std::make_shared<YangAccess>();
     if (args["--configonly"].asBool()) {
         writableOps = WritableOps::No;
     } else {
@@ -83,13 +84,13 @@
         std::cout << "ops is writable" << std::endl;
     }
     if (const auto& search_dir = args["-s"]) {
-        datastore.addSchemaDir(search_dir.asString());
+        datastore->addSchemaDir(search_dir.asString());
     }
     for (const auto& schemaFile : args["<schema_file_or_module_name>"].asStringList()) {
         if (std::filesystem::exists(schemaFile)) {
-            datastore.addSchemaFile(schemaFile);
+            datastore->addSchemaFile(schemaFile);
         } else if (schemaFile.find('/') == std::string::npos) { // Module names cannot have a slash
-            datastore.loadModule(schemaFile);
+            datastore->loadModule(schemaFile);
         } else {
             std::cerr << "Cannot load YANG module " << schemaFile << "\n";
         }
@@ -106,7 +107,7 @@
                 return 1;
             }
             try {
-                datastore.enableFeature(parsed.first, parsed.second);
+                datastore->enableFeature(parsed.first, parsed.second);
             } catch (std::runtime_error& ex) {
                 std::cerr << ex.what() << "\n";
                 return 1;
@@ -116,15 +117,16 @@
     }
     if (const auto& dataFiles = args["-i"]) {
         for (const auto& dataFile : dataFiles.asStringList()) {
-            datastore.addDataFile(dataFile);
+            datastore->addDataFile(dataFile);
         }
     }
 #else
 #error "Unknown CLI backend"
 #endif
 
-    auto dataQuery = std::make_shared<DataQuery>(datastore);
-    Parser parser(datastore.schema(), writableOps, dataQuery);
+    ProxyDatastore proxyDatastore(datastore);
+    auto dataQuery = std::make_shared<DataQuery>(*datastore);
+    Parser parser(datastore->schema(), writableOps, dataQuery);
 
     using replxx::Replxx;
 
@@ -182,7 +184,7 @@
 
         try {
             command_ cmd = parser.parseCommand(line, std::cout);
-            boost::apply_visitor(Interpreter(parser, datastore), cmd);
+            boost::apply_visitor(Interpreter(parser, proxyDatastore), cmd);
         } catch (InvalidCommandException& ex) {
             std::cerr << ex.what() << std::endl;
         } catch (DatastoreException& ex) {