From 6e4a680fddb41f64e189a43e2b4cbfbc57dd9a58 Mon Sep 17 00:00:00 2001
From: Rainer Kartmann <rainer.kartmann@kit.edu>
Date: Mon, 11 Jan 2021 10:16:47 +0100
Subject: [PATCH] Move implementations to cpp

---
 .../RobotAPI/libraries/armem/CMakeLists.txt   |   1 +
 .../libraries/armem/client/QueryBuilder.cpp   |  24 ++++
 .../libraries/armem/client/QueryBuilder.h     |  37 +++--
 .../armem/client/query/NameSelectorOps.h      |  41 ++++++
 .../armem/client/query/SelectorOps.h          |   4 +-
 .../armem/client/query/selectors.cpp          | 129 +++++++++++++++++-
 .../libraries/armem/client/query/selectors.h  | 111 +++++----------
 .../armem/test/ArMemQueryBuilderTest.cpp      |  20 +--
 8 files changed, 252 insertions(+), 115 deletions(-)
 create mode 100644 source/RobotAPI/libraries/armem/client/query/NameSelectorOps.h

diff --git a/source/RobotAPI/libraries/armem/CMakeLists.txt b/source/RobotAPI/libraries/armem/CMakeLists.txt
index 4c168c147..4920ebedd 100644
--- a/source/RobotAPI/libraries/armem/CMakeLists.txt
+++ b/source/RobotAPI/libraries/armem/CMakeLists.txt
@@ -92,6 +92,7 @@ set(LIB_HEADERS
 
     client/QueryBuilder.h
     client/query/SelectorOps.h
+    client/query/NameSelectorOps.h
     client/query/selectors.h
 
     component/IceMemory.h
diff --git a/source/RobotAPI/libraries/armem/client/QueryBuilder.cpp b/source/RobotAPI/libraries/armem/client/QueryBuilder.cpp
index 3a864c3da..d0377a155 100644
--- a/source/RobotAPI/libraries/armem/client/QueryBuilder.cpp
+++ b/source/RobotAPI/libraries/armem/client/QueryBuilder.cpp
@@ -4,5 +4,29 @@
 namespace armarx::armem::client
 {
 
+    data::query::MemoryQuerySeq QueryBuilder::buildQueries() const
+    {
+        data::query::MemoryQuerySeq memoryQueries;
+        for (const query::CoreSegmentSelector& child : _children)
+        {
+            for (const data::query::MemoryQueryPtr& query : child.buildQueries())
+            {
+                memoryQueries.push_back(query);
+            }
+        }
+        return memoryQueries;
+    }
+
+    data::QueryInput QueryBuilder::buildQueryInput() const
+    {
+        data::QueryInput input;
+        input.memoryQueries = buildQueries();
+        return input;
+    }
+
+    query::CoreSegmentSelector& QueryBuilder::coreSegments()
+    {
+        return _addChild();
+    }
 
 }
diff --git a/source/RobotAPI/libraries/armem/client/QueryBuilder.h b/source/RobotAPI/libraries/armem/client/QueryBuilder.h
index c4d485845..96b30f3c9 100644
--- a/source/RobotAPI/libraries/armem/client/QueryBuilder.h
+++ b/source/RobotAPI/libraries/armem/client/QueryBuilder.h
@@ -1,8 +1,7 @@
 #pragma once
 
-#include <vector>
-
 #include <RobotAPI/interface/armem/query.h>
+#include <RobotAPI/interface/armem/ReadingInterface.h>
 
 #include "query/selectors.h"
 
@@ -11,29 +10,27 @@ namespace armarx::armem::client
 {
 
     // ToDo: Make a memory selector (but this level is not in ice, yet)
+    /**
+     * @brief The QueryBuilder class provides a fluent-style specification of
+     * hierarchical queries.
+     *
+     * Syntax:
+     *
+     * @code
+     * TODO
+     * @endcode
+     */
     class QueryBuilder :
         public query::detail::ParentSelectorOps<QueryBuilder, query::CoreSegmentSelector>
     {
     public:
 
-        std::vector<data::query::MemoryQueryPtr> finalize() const
-        {
-            std::vector<data::query::MemoryQueryPtr> childQueries;
-            for (const query::CoreSegmentSelector& child : _children)
-            {
-                for (const data::query::MemoryQueryPtr& query : child.build())
-                {
-                    childQueries.push_back(query);
-                }
-            }
-            return childQueries;
-        }
-
-
-        query::CoreSegmentSelector& coreSegments()
-        {
-            return _addChild();
-        }
+        /// Start specifying core segments.
+        query::CoreSegmentSelector& coreSegments();
+
+
+        data::query::MemoryQuerySeq buildQueries() const;
+        data::QueryInput buildQueryInput() const;
 
     };
 
diff --git a/source/RobotAPI/libraries/armem/client/query/NameSelectorOps.h b/source/RobotAPI/libraries/armem/client/query/NameSelectorOps.h
new file mode 100644
index 000000000..9c6d7d9f6
--- /dev/null
+++ b/source/RobotAPI/libraries/armem/client/query/NameSelectorOps.h
@@ -0,0 +1,41 @@
+#pragma once
+
+#include <string>
+#include <vector>
+
+
+namespace armarx::armem::client::query::detail
+{
+
+    template <class DerivedT>
+    class NameSelectorOps
+    {
+    public:
+
+        virtual DerivedT& withName(const std::string& name) = 0;
+        virtual DerivedT& withNameMatching(const std::string& regex) = 0;
+
+
+        virtual DerivedT& withNames(const std::vector<std::string>& names)
+        {
+            return withNames(names);
+        }
+
+        template <class StringContainerT>
+        DerivedT& withNames(const StringContainerT& names)
+        {
+            return withNames(names.begin(), names.end());
+        }
+        template <class IteratorT>
+        DerivedT& withNames(IteratorT begin, IteratorT end)
+        {
+            for (auto it = begin; it != end; ++it)
+            {
+                this->withName(*it);
+            }
+            return dynamic_cast<DerivedT&>(*this);
+        }
+
+    };
+
+}
diff --git a/source/RobotAPI/libraries/armem/client/query/SelectorOps.h b/source/RobotAPI/libraries/armem/client/query/SelectorOps.h
index 2ba0bbf7b..dda1f6edc 100644
--- a/source/RobotAPI/libraries/armem/client/query/SelectorOps.h
+++ b/source/RobotAPI/libraries/armem/client/query/SelectorOps.h
@@ -64,12 +64,12 @@ namespace armarx::armem::client::query::detail
         {}
 
 
-        virtual std::vector<QueryT> build() const
+        virtual std::vector<QueryT> buildQueries() const
         {
             std::vector<typename ChildT::QueryT> childQueries;
             for (const auto& child : _children)
             {
-                for (const auto& query : child.build())
+                for (const auto& query : child.buildQueries())
                 {
                     childQueries.push_back(query);
                 }
diff --git a/source/RobotAPI/libraries/armem/client/query/selectors.cpp b/source/RobotAPI/libraries/armem/client/query/selectors.cpp
index 6364447a9..e21d812d6 100644
--- a/source/RobotAPI/libraries/armem/client/query/selectors.cpp
+++ b/source/RobotAPI/libraries/armem/client/query/selectors.cpp
@@ -1,22 +1,145 @@
 #include "selectors.h"
 
+#include <RobotAPI/libraries/armem/core/ice_conversions.h>
+
+
+namespace dq = ::armarx::armem::data::query;
+
 
 namespace armarx::armem::client::query
 {
+    dq::EntityQuerySeq SnapshotsSelector::buildQueries() const
+    {
+        return _queries;
+    }
+
+    SnapshotsSelector& SnapshotsSelector::all(bool withData)
+    {
+        auto q = _addQuery<dq::entity::All>(withData);
+        return *this;
+    }
+
+    SnapshotsSelector& SnapshotsSelector::latest(bool withData)
+    {
+        auto q = _addQuery<dq::entity::Single>(withData);
+        q.timestamp = -1;
+        return *this;
+    }
+
+    SnapshotsSelector& SnapshotsSelector::atTime(Time timestamp, bool withData)
+    {
+        auto q = _addQuery<dq::entity::Single>(withData);
+        toIce(q.timestamp, timestamp);
+        return *this;
+    }
+
+    SnapshotsSelector& SnapshotsSelector::timeRange(Time min, Time max, bool withData)
+    {
+        auto q = _addQuery<dq::entity::TimeRange>(withData);
+        toIce(q.minTimestamp, min);
+        toIce(q.maxTimestamp, max);
+        return *this;
+    }
+
+    SnapshotsSelector& SnapshotsSelector::indexRange(long first, long last, bool withData)
+    {
+        auto q = _addQuery<dq::entity::IndexRange>(withData);
+        q.first = first;
+        q.last = last;
+        return *this;
+    }
+
 
-    void EntitiesSelector::_setChildQueries(data::query::ProviderSegmentQueryPtr& query, const data::query::EntityQuerySeq& childQueries) const
+
+    SnapshotsSelector& EntitiesSelector::snapshots()
+    {
+        return _addChild();
+    }
+
+    EntitiesSelector& EntitiesSelector::all()
+    {
+        auto q = _addQuery<dq::provider::All>();
+        return *this;
+    }
+
+    EntitiesSelector& EntitiesSelector::withName(const std::string& name)
+    {
+        auto q = _addQuery<dq::provider::Single>();
+        q.entityName = name;
+        return *this;
+    }
+
+    EntitiesSelector& EntitiesSelector::withNameMatching(const std::string& regex)
+    {
+        auto q = _addQuery<dq::provider::Regex>();
+        q.entityNameRegex = regex;
+        return *this;
+    }
+
+    void EntitiesSelector::_setChildQueries(dq::ProviderSegmentQueryPtr& query, const dq::EntityQuerySeq& childQueries) const
     {
         query->entityQueries = childQueries;
     }
 
 
-    void ProviderSegmentSelector::_setChildQueries(data::query::CoreSegmentQueryPtr& query, const data::query::ProviderSegmentQuerySeq& childQueries) const
+
+    EntitiesSelector& ProviderSegmentSelector::entities()
+    {
+        return _addChild();
+    }
+
+    ProviderSegmentSelector& ProviderSegmentSelector::all()
+    {
+        auto q = _addQuery<dq::core::All>();
+        return *this;
+    }
+
+    ProviderSegmentSelector& ProviderSegmentSelector::withName(const std::string& name)
+    {
+        auto q = _addQuery<dq::core::Single>();
+        q.providerSegmentName = name;
+        return *this;
+    }
+
+    ProviderSegmentSelector& ProviderSegmentSelector::withNameMatching(const std::string& regex)
+    {
+        auto q = _addQuery<dq::core::Regex>();
+        q.providerSegmentNameRegex = regex;
+        return *this;
+    }
+
+    void ProviderSegmentSelector::_setChildQueries(dq::CoreSegmentQueryPtr& query, const dq::ProviderSegmentQuerySeq& childQueries) const
     {
         query->providerSegmentQueries = childQueries;
     }
 
 
-    void CoreSegmentSelector::_setChildQueries(data::query::MemoryQueryPtr& query, const data::query::CoreSegmentQuerySeq& childQueries) const
+
+    ProviderSegmentSelector& CoreSegmentSelector::providerSegments()
+    {
+        return _addChild();
+    }
+
+    CoreSegmentSelector& CoreSegmentSelector::all()
+    {
+        auto q = _addQuery<dq::memory::All>();
+        return *this;
+    }
+
+    CoreSegmentSelector& CoreSegmentSelector::withName(const std::string& name)
+    {
+        auto q = _addQuery<dq::memory::Single>();
+        q.coreSegmentName = name;
+        return *this;
+    }
+    CoreSegmentSelector& CoreSegmentSelector::withNameMatching(const std::string& regex)
+    {
+        auto q = _addQuery<dq::memory::Regex>();
+        q.coreSegmentNameRegex = regex;
+        return *this;
+    }
+
+    void CoreSegmentSelector::_setChildQueries(dq::MemoryQueryPtr& query, const dq::CoreSegmentQuerySeq& childQueries) const
     {
         query->coreSegmentQueries = childQueries;
     }
diff --git a/source/RobotAPI/libraries/armem/client/query/selectors.h b/source/RobotAPI/libraries/armem/client/query/selectors.h
index b1d80f8fc..32cd67a79 100644
--- a/source/RobotAPI/libraries/armem/client/query/selectors.h
+++ b/source/RobotAPI/libraries/armem/client/query/selectors.h
@@ -1,12 +1,10 @@
 #pragma once
 
-#include <vector>
-
 #include <RobotAPI/interface/armem/query.h>
 
 #include <RobotAPI/libraries/armem/core/Time.h>
-#include <RobotAPI/libraries/armem/core/ice_conversions.h>
 
+#include "NameSelectorOps.h"
 #include "SelectorOps.h"
 
 
@@ -18,43 +16,16 @@ namespace armarx::armem::client::query
     {
     public:
 
+        data::query::EntityQuerySeq buildQueries() const;
 
-        std::vector<data::query::EntityQueryPtr> build() const
-        {
-            return _queries;
-        }
 
+        SnapshotsSelector& all(bool withData = true);
 
-        SnapshotsSelector& all(bool withData = true)
-        {
-            auto q = _addQuery<data::query::entity::All>(withData);
-            q.withData = withData;
-            return *this;
-        }
         SnapshotsSelector& latest(bool withData = true);
+        SnapshotsSelector& atTime(Time timestamp, bool withData = true);
 
-        SnapshotsSelector& atTime(Time timestamp, bool withData = true)
-        {
-            auto q = _addQuery<data::query::entity::Single>(withData);
-            toIce(q.timestamp, timestamp);
-            return *this;
-        }
-
-        SnapshotsSelector& timeRange(Time min, Time max, bool withData = true)
-        {
-            auto q = _addQuery<data::query::entity::TimeRange>(withData);
-            toIce(q.minTimestamp, min);
-            toIce(q.maxTimestamp, max);
-            return *this;
-        }
-
-        SnapshotsSelector& indexRange(long first, long last, bool withData = true)
-        {
-            auto q = _addQuery<data::query::entity::IndexRange>(withData);
-            q.first = first;
-            q.last = last;
-            return *this;
-        }
+        SnapshotsSelector& timeRange(Time min, Time max, bool withData = true);
+        SnapshotsSelector& indexRange(long first, long last, bool withData = true);
 
 
     protected:
@@ -70,93 +41,73 @@ namespace armarx::armem::client::query
     };
 
 
+
     class EntitiesSelector :
         public detail::InnerSelectorOps<EntitiesSelector, data::query::ProviderSegmentQueryPtr, SnapshotsSelector>
+        , public detail::NameSelectorOps<EntitiesSelector>
+
     {
     public:
 
-        SnapshotsSelector& snapshots()
-        {
-            return _addChild();
-        }
+        /// Start specifying entity snapshots.
+        SnapshotsSelector& snapshots();
 
 
-        EntitiesSelector& all()
-        {
-            auto q = _addQuery<data::query::provider::All>();
-            return *this;
-        }
-
-        EntitiesSelector& withName(const std::string& name);
-        EntitiesSelector& withNames(const std::vector<std::string>& names);
+        EntitiesSelector& all();
 
-        EntitiesSelector& withNameMatching(const std::string& regex);
+        EntitiesSelector& withName(const std::string& name) override;
+        EntitiesSelector& withNameMatching(const std::string& regex) override;
+        using NameSelectorOps::withNames;
 
 
     protected:
-
         void _setChildQueries(data::query::ProviderSegmentQueryPtr& query, const data::query::EntityQuerySeq& childQueries) const override;
     };
 
 
+
     class ProviderSegmentSelector :
         public detail::InnerSelectorOps<ProviderSegmentSelector, data::query::CoreSegmentQueryPtr, EntitiesSelector>
+        , public detail::NameSelectorOps<ProviderSegmentSelector>
     {
     public:
 
-        EntitiesSelector& entities()
-        {
-            return _addChild();
-        }
+        /// Start specifying entities.
+        EntitiesSelector& entities();
 
-        ProviderSegmentSelector& all()
-        {
-            auto q = _addQuery<data::query::core::All>();
-            return *this;
-        }
 
-        ProviderSegmentSelector& withName(const std::string& name);
-        ProviderSegmentSelector& withNames(const std::vector<std::string>& names);
+        ProviderSegmentSelector& all();
 
-        ProviderSegmentSelector& withNameMatching(const std::string& regex);
+        ProviderSegmentSelector& withName(const std::string& name) override;
+        ProviderSegmentSelector& withNameMatching(const std::string& regex) override;
+        using NameSelectorOps::withNames;
 
-    protected:
 
+    protected:
         void _setChildQueries(data::query::CoreSegmentQueryPtr& query, const data::query::ProviderSegmentQuerySeq& childQueries) const override;
     };
 
 
 
-
-
     class CoreSegmentSelector :
         public detail::InnerSelectorOps<CoreSegmentSelector, data::query::MemoryQueryPtr, ProviderSegmentSelector>
+        , public detail::NameSelectorOps<CoreSegmentSelector>
     {
     public:
 
-        ProviderSegmentSelector& providerSegments()
-        {
-            return _addChild();
-        }
+        /// Start specifying provider segments.
+        ProviderSegmentSelector& providerSegments();
 
-        CoreSegmentSelector& all()
-        {
-            auto q = _addQuery<data::query::memory::All>();
-            return *this;
-        }
 
-        CoreSegmentSelector& withName(const std::string& name);
-        CoreSegmentSelector& withNames(const std::vector<std::string>& names);
+        CoreSegmentSelector& all();
 
-        CoreSegmentSelector& withNameMatching(const std::string& regex);
+        CoreSegmentSelector& withName(const std::string& name) override;
+        CoreSegmentSelector& withNameMatching(const std::string& regex) override;
+        using NameSelectorOps::withNames;
 
 
     protected:
-
         void _setChildQueries(data::query::MemoryQueryPtr& query, const data::query::CoreSegmentQuerySeq& childQueries) const override;
-
     };
 
-
-
 }
diff --git a/source/RobotAPI/libraries/armem/test/ArMemQueryBuilderTest.cpp b/source/RobotAPI/libraries/armem/test/ArMemQueryBuilderTest.cpp
index ba0edf28d..c05a405d1 100644
--- a/source/RobotAPI/libraries/armem/test/ArMemQueryBuilderTest.cpp
+++ b/source/RobotAPI/libraries/armem/test/ArMemQueryBuilderTest.cpp
@@ -32,7 +32,7 @@
 
 
 namespace armem = armarx::armem;
-namespace aron = armarx::aron;
+namespace query = armarx::armem::data::query;
 
 
 namespace ArMemQueryBuilderTest
@@ -62,23 +62,23 @@ BOOST_AUTO_TEST_CASE(test_all_all)
     .entities().all()
     .snapshots().all();
 
-    std::vector<armem::data::query::MemoryQueryPtr> memoryQueries = qb.finalize();
+    query::MemoryQuerySeq memoryQueries = qb.buildQueries();
 
     BOOST_REQUIRE_EQUAL(memoryQueries.size(), 1);
-    armem::data::query::MemoryQueryPtr memoryQuery = memoryQueries.front();
-    BOOST_CHECK(armem::data::query::memory::AllPtr::dynamicCast(memoryQuery));
+    query::MemoryQueryPtr memoryQuery = memoryQueries.front();
+    BOOST_CHECK(query::memory::AllPtr::dynamicCast(memoryQuery));
 
     BOOST_REQUIRE_EQUAL(memoryQuery->coreSegmentQueries.size(), 1);
-    armem::data::query::CoreSegmentQueryPtr coreSegQuery = memoryQuery->coreSegmentQueries.front();
-    BOOST_CHECK(armem::data::query::core::AllPtr::dynamicCast(coreSegQuery));
+    query::CoreSegmentQueryPtr coreSegQuery = memoryQuery->coreSegmentQueries.front();
+    BOOST_CHECK(query::core::AllPtr::dynamicCast(coreSegQuery));
 
     BOOST_REQUIRE_EQUAL(coreSegQuery->providerSegmentQueries.size(), 1);
-    armem::data::query::ProviderSegmentQueryPtr provSegQuery = coreSegQuery->providerSegmentQueries.front();
-    BOOST_CHECK(armem::data::query::provider::AllPtr::dynamicCast(provSegQuery));
+    query::ProviderSegmentQueryPtr provSegQuery = coreSegQuery->providerSegmentQueries.front();
+    BOOST_CHECK(query::provider::AllPtr::dynamicCast(provSegQuery));
 
     BOOST_REQUIRE_EQUAL(provSegQuery->entityQueries.size(), 1);
-    armem::data::query::EntityQueryPtr entityQuery = provSegQuery->entityQueries.front();
-    BOOST_CHECK(armem::data::query::entity::AllPtr::dynamicCast(entityQuery));
+    query::EntityQueryPtr entityQuery = provSegQuery->entityQueries.front();
+    BOOST_CHECK(query::entity::AllPtr::dynamicCast(entityQuery));
 }
 
 
-- 
GitLab