From c967e688c53000519ceb6030e8282296e4846d3c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Pecka?= <tomas.pecka@cesnet.cz>
Date: Mon, 13 Jan 2025 18:29:29 +0100
Subject: [PATCH 22/44] restconf: add RAII datastore switch
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Organization: Wires

Copied from sysrepo-ietf-alarms[1].

[1] https://github.com/CESNET/sysrepo-ietf-alarms/blob/4870dbee30a5ec56135d4f4cb5818f191c089c34/src/utils/sysrepo.cpp

Change-Id: I51738d06187e141ebd662e7b9421ca995380cafc
Signed-off-by: Mattias Walström <lazzer@gmail.com>
---
 CMakeLists.txt                 |  1 +
 src/restconf/utils/sysrepo.cpp | 25 +++++++++++++++++++++++++
 src/restconf/utils/sysrepo.h   | 29 +++++++++++++++++++++++++++++
 3 files changed, 55 insertions(+)
 create mode 100644 src/restconf/utils/sysrepo.cpp
 create mode 100644 src/restconf/utils/sysrepo.h

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 5ae8062..7f3a9c0 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -114,6 +114,7 @@ add_library(rousette-restconf STATIC
     src/restconf/YangSchemaLocations.cpp
     src/restconf/uri.cpp
     src/restconf/utils/dataformat.cpp
+    src/restconf/utils/sysrepo.cpp
     src/restconf/utils/yang.cpp
 )
 target_link_libraries(rousette-restconf PUBLIC rousette-http rousette-sysrepo rousette-auth Boost::system Threads::Threads PRIVATE date::date-tz)
diff --git a/src/restconf/utils/sysrepo.cpp b/src/restconf/utils/sysrepo.cpp
new file mode 100644
index 0000000..622ab27
--- /dev/null
+++ b/src/restconf/utils/sysrepo.cpp
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2020, 2022 CESNET, https://photonics.cesnet.cz/
+ *
+ * Written by Jan Kundrát <jan.kundrat@cesnet.cz>
+ * Written by Tomáš Pecka <tomas.pecka@cesnet.cz>
+ */
+
+#include <sysrepo-cpp/Connection.hpp>
+#include "sysrepo.h"
+
+namespace rousette::restconf {
+
+ScopedDatastoreSwitch::ScopedDatastoreSwitch(sysrepo::Session session, sysrepo::Datastore ds)
+    : m_session(std::move(session))
+    , m_oldDatastore(m_session.activeDatastore())
+{
+    m_session.switchDatastore(ds);
+}
+
+ScopedDatastoreSwitch::~ScopedDatastoreSwitch()
+{
+    m_session.switchDatastore(m_oldDatastore);
+}
+
+}
diff --git a/src/restconf/utils/sysrepo.h b/src/restconf/utils/sysrepo.h
new file mode 100644
index 0000000..da6c359
--- /dev/null
+++ b/src/restconf/utils/sysrepo.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2020, 2022 CESNET, https://photonics.cesnet.cz/
+ *
+ * Written by Jan Kundrát <jan.kundrat@cesnet.cz>
+ * Written by Tomáš Pecka <tomas.pecka@cesnet.cz>
+ */
+
+#pragma once
+
+#include <libyang-cpp/Context.hpp>
+#include <sysrepo-cpp/Session.hpp>
+
+namespace rousette::restconf {
+
+/** @brief Ensures that session switches to provided datastore and when the object gets destroyed the session switches back to the original datastore. */
+class ScopedDatastoreSwitch {
+    sysrepo::Session m_session;
+    sysrepo::Datastore m_oldDatastore;
+
+public:
+    ScopedDatastoreSwitch(sysrepo::Session session, sysrepo::Datastore ds);
+    ~ScopedDatastoreSwitch();
+    ScopedDatastoreSwitch(const ScopedDatastoreSwitch&) = delete;
+    ScopedDatastoreSwitch(ScopedDatastoreSwitch&&) = delete;
+    ScopedDatastoreSwitch& operator=(const ScopedDatastoreSwitch&) = delete;
+    ScopedDatastoreSwitch& operator=(ScopedDatastoreSwitch&&) = delete;
+};
+
+}
-- 
2.43.0

