From 0826cc6f287050f3ac75d09d074cd8f6253bf769 Mon Sep 17 00:00:00 2001
From: Cyrille Berger <cyrille.berger@liu.se>
Date: Fri, 5 May 2023 17:34:38 +0200
Subject: [PATCH] set if actions are owned by the query engine or not,and allow
 to remove them

---
 kDB/SMQuery/CMakeLists.txt       |  4 ++--
 kDB/SMQuery/Engine.cpp           | 21 +++++++++++++++++++--
 kDB/SMQuery/Engine.h             |  8 +++++++-
 kDB/SMQuery/tests/TestEngine.cpp | 11 +++++++++--
 4 files changed, 37 insertions(+), 7 deletions(-)

diff --git a/kDB/SMQuery/CMakeLists.txt b/kDB/SMQuery/CMakeLists.txt
index 33c98b59..bd494b17 100644
--- a/kDB/SMQuery/CMakeLists.txt
+++ b/kDB/SMQuery/CMakeLists.txt
@@ -17,8 +17,8 @@ set(PROJECT_EXPORTED_TARGETS kDBSMQuery  ${PROJECT_EXPORTED_TARGETS} CACHE INTER
 
 install( FILES
   Engine.h
-  DESTINATION ${INSTALL_INCLUDE_DIR}/kDBSMQuery )
+  DESTINATION ${INSTALL_INCLUDE_DIR}/kDB/SMQuery )
 
   install( FILES
   Interfaces/Action.h
-  DESTINATION ${INSTALL_INCLUDE_DIR}/kDBSMQuery/Interfaces )
+  DESTINATION ${INSTALL_INCLUDE_DIR}/kDB/SMQuery/Interfaces )
diff --git a/kDB/SMQuery/Engine.cpp b/kDB/SMQuery/Engine.cpp
index 8a923092..77e9f60a 100644
--- a/kDB/SMQuery/Engine.cpp
+++ b/kDB/SMQuery/Engine.cpp
@@ -24,15 +24,32 @@ Engine::~Engine()
   delete d;
 }
 
-void Engine::add(const QStringList& _keys, Interfaces::Action* _action)
+void Engine::add(const QStringList& _keys, Interfaces::Action* _action, bool _action_owned_by_engine)
 {
-  d->actions.append(_action);
+  if(_action_owned_by_engine)
+  {
+    d->actions.append(_action);
+  }
   for(const QString& key : _keys)
   {
     d->key2action[key.toUpper()] = _action;
   }
 }
 
+void Engine::remove(Interfaces::Action* _action)
+{
+  d->actions.removeAll(_action);
+  for(QHash<QString, Interfaces::Action*>::iterator it = d->key2action.begin(); it != d->key2action.end();)
+  {
+    if(it.value() == _action)
+    {
+      it = d->key2action.erase(it);
+    } else {
+      ++it;
+    }
+  }
+}
+
 knowCore::ReturnVoid Engine::execute(const QString& _text)
 {
   KNOWCORE_RETURN_VALUE_TRY(query, Parser::parse(_text));
diff --git a/kDB/SMQuery/Engine.h b/kDB/SMQuery/Engine.h
index 86c390e2..c8e2db3c 100644
--- a/kDB/SMQuery/Engine.h
+++ b/kDB/SMQuery/Engine.h
@@ -17,9 +17,15 @@ namespace kDB::SMQuery
     /**
      * Add an \ref _action for the list of \ref _keys.
      * 
+     * @param _action_owned_by_engine set to true if the action should be deleted by the engine
+     * 
      * _keys take the form of "SOME ACTION" and will react to query with "SOME ACTION".
      */
-    void add(const QStringList& _keys, Interfaces::Action* _action);
+    void add(const QStringList& _keys, Interfaces::Action* _action, bool _action_owned_by_engine);
+    /**
+     * Remove the action. Do note that if the action will not be owned anymore by the engine.
+     */
+    void remove(Interfaces::Action* _action);
     /**
      * Execute a query.
      */
diff --git a/kDB/SMQuery/tests/TestEngine.cpp b/kDB/SMQuery/tests/TestEngine.cpp
index 568edae8..59a8173e 100644
--- a/kDB/SMQuery/tests/TestEngine.cpp
+++ b/kDB/SMQuery/tests/TestEngine.cpp
@@ -51,8 +51,9 @@ public:
 void TestEngine::testQuery()
 {
   kDB::SMQuery::Engine e;
-  e.add({"TRIGGER FAIL"}, new TestFailAction);
-  e.add({"ALSO FAIL", "DO SUCCEED"}, new TestAction);
+  e.add({"TRIGGER FAIL"}, new TestFailAction, true);
+  TestAction ta;
+  e.add({"ALSO FAIL", "DO SUCCEED"}, &ta, false);
 
   KNOWCORE_TEST_VERIFY_FAILURE_VOID(e.execute("RANDOM ACTION"));
   KNOWCORE_TEST_VERIFY_FAILURE_VOID(e.execute("TRIGGER FAIL"));
@@ -64,6 +65,12 @@ void TestEngine::testQuery()
   KNOWCORE_TEST_VERIFY_FAILURE_VOID(e.execute("DO SUCCEED uri: <hello>"));
   KNOWCORE_TEST_VERIFY_FAILURE_VOID(e.execute("DO SUCCEED value: 121"));
   KNOWCORE_TEST_VERIFY_FAILURE_VOID(e.execute("DO SUCCEED text: \"some wrong text\""));
+
+  e.remove(&ta);
+
+  KNOWCORE_TEST_VERIFY_FAILURE_VOID(e.execute("DO SUCCEED uri: <hello world>"));
+  KNOWCORE_TEST_VERIFY_FAILURE_VOID(e.execute("DO SUCCEED uri: <hello world> value: 12"));
+  KNOWCORE_TEST_VERIFY_FAILURE_VOID(e.execute("DO SUCCEED uri: <hello world> value: 12 text: \"some text\""));
 }
 
 QTEST_MAIN(TestEngine)
-- 
GitLab