Rework datastores

DatastoreAccess now has "targets". The target determines what datastores
are used for writing and reading data. There are three targets:
  Operational:
  - reads from operational, writes to running
  Startup:
  - reads from startup, writes to startup
  Running:
  - reads from running, writes to running

(the datastores types above correspond to the NMDA datastore types)

The need to define targets instead of just calling them "datastores" is
that the operational target doesn't actually use the operational
datastore for both writing and reading.

Change-Id: Iffb7034c27aba42d10d715e23a2c970031b9bd1b
diff --git a/src/datastore_access.hpp b/src/datastore_access.hpp
index b29e152..3012a7e 100644
--- a/src/datastore_access.hpp
+++ b/src/datastore_access.hpp
@@ -37,6 +37,12 @@
     std::string m_what;
 };
 
+enum class DatastoreTarget {
+    Startup,
+    Running,
+    Operational
+};
+
 class Schema;
 
 struct dataPath_;
@@ -51,6 +57,7 @@
     virtual void deleteItem(const std::string& path) = 0;
     virtual void moveItem(const std::string& path, std::variant<yang::move::Absolute, yang::move::Relative> move) = 0;
     virtual Tree execute(const std::string& path, const Tree& input) = 0;
+    void setTarget(const DatastoreTarget target);
 
     virtual std::shared_ptr<Schema> schema() = 0;
 
@@ -59,6 +66,9 @@
     virtual void copyConfig(const Datastore source, const Datastore destination) = 0;
     [[nodiscard]] virtual std::string dump(const DataFormat format) const = 0;
 
+protected:
+    DatastoreTarget m_target = DatastoreTarget::Operational;
+
 private:
     friend class DataQuery;
     virtual std::vector<ListInstance> listInstances(const std::string& path) = 0;