]> granicus.if.org Git - icinga2/commitdiff
Implement support for the 'Limit' column in Livestatus
authorGunnar Beutner <gunnar@beutner.name>
Wed, 4 Mar 2015 11:03:35 +0000 (12:03 +0100)
committerGunnar Beutner <gunnar@beutner.name>
Wed, 4 Mar 2015 11:18:04 +0000 (12:18 +0100)
fixes #8529

16 files changed:
lib/livestatus/commandstable.cpp
lib/livestatus/commentstable.cpp
lib/livestatus/contactgroupstable.cpp
lib/livestatus/contactstable.cpp
lib/livestatus/downtimestable.cpp
lib/livestatus/endpointstable.cpp
lib/livestatus/hostgroupstable.cpp
lib/livestatus/hoststable.cpp
lib/livestatus/livestatusquery.cpp
lib/livestatus/livestatusquery.hpp
lib/livestatus/servicegroupstable.cpp
lib/livestatus/servicestable.cpp
lib/livestatus/statehisttable.cpp
lib/livestatus/table.cpp
lib/livestatus/table.hpp
lib/livestatus/timeperiodstable.cpp

index b36a8bd0d3d59b80209cbe4682b50aac9f80bfcd..349d6068bd73e0a0925ab931c31c3403442b57f8 100644 (file)
@@ -61,13 +61,18 @@ String CommandsTable::GetPrefix(void) const
 void CommandsTable::FetchRows(const AddRowFunction& addRowFn)
 {
        BOOST_FOREACH(const DynamicObject::Ptr& object, DynamicType::GetObjectsByType<CheckCommand>()) {
-               addRowFn(object, LivestatusGroupByNone, Empty);
+               if (!addRowFn(object, LivestatusGroupByNone, Empty))
+                       return;
        }
+
        BOOST_FOREACH(const DynamicObject::Ptr& object, DynamicType::GetObjectsByType<EventCommand>()) {
-               addRowFn(object, LivestatusGroupByNone, Empty);
+               if (!addRowFn(object, LivestatusGroupByNone, Empty))
+                       return;
        }
+
        BOOST_FOREACH(const DynamicObject::Ptr& object, DynamicType::GetObjectsByType<NotificationCommand>()) {
-               addRowFn(object, LivestatusGroupByNone, Empty);
+               if (!addRowFn(object, LivestatusGroupByNone, Empty))
+                       return;
        }
 }
 
index 4feb6b53414ebc67d137650f5955ad982d39d9dd..a9b297864dad694fabe70fc19031d0197c17c9a5 100644 (file)
@@ -73,8 +73,10 @@ void CommentsTable::FetchRows(const AddRowFunction& addRowFn)
                String id;
                Comment::Ptr comment;
                BOOST_FOREACH(tie(id, comment), comments) {
-                       if (Host::GetOwnerByCommentID(id) == host)
-                               addRowFn(comment, LivestatusGroupByNone, Empty);
+                       if (Host::GetOwnerByCommentID(id) == host) {
+                               if (!addRowFn(comment, LivestatusGroupByNone, Empty))
+                                       return;
+                       }
                }
        }
 
@@ -86,8 +88,10 @@ void CommentsTable::FetchRows(const AddRowFunction& addRowFn)
                String id;
                Comment::Ptr comment;
                BOOST_FOREACH(tie(id, comment), comments) {
-                       if (Service::GetOwnerByCommentID(id) == service)
-                               addRowFn(comment, LivestatusGroupByNone, Empty);
+                       if (Service::GetOwnerByCommentID(id) == service) {
+                               if (!addRowFn(comment, LivestatusGroupByNone, Empty))
+                                       return;
+                       }
                }
        }
 }
index 604aa73b7bdff30443e0d004b61184a887ce4430..c1f9b6c030bd2068ebb5479faad7af30f2b18c59 100644 (file)
@@ -50,7 +50,8 @@ String ContactGroupsTable::GetPrefix(void) const
 void ContactGroupsTable::FetchRows(const AddRowFunction& addRowFn)
 {
        BOOST_FOREACH(const UserGroup::Ptr& ug, DynamicType::GetObjectsByType<UserGroup>()) {
-               addRowFn(ug, LivestatusGroupByNone, Empty);
+               if (!addRowFn(ug, LivestatusGroupByNone, Empty))
+                       return;
        }
 }
 
index e6400e5ee23b40349db5e94a2c1603a1a384ba93..e557ae89f3e09921792ff3e4f4cf680bdd0a1362 100644 (file)
@@ -71,7 +71,8 @@ String ContactsTable::GetPrefix(void) const
 void ContactsTable::FetchRows(const AddRowFunction& addRowFn)
 {
        BOOST_FOREACH(const User::Ptr& user, DynamicType::GetObjectsByType<User>()) {
-               addRowFn(user, LivestatusGroupByNone, Empty);
+               if (!addRowFn(user, LivestatusGroupByNone, Empty))
+                       return;
        }
 }
 
index 49bdd3933ca1b6b9561e17923f05c0d636d04089..e9b8ed7c9eb3e13461c60bc0528fc58028e07d00 100644 (file)
@@ -73,8 +73,10 @@ void DowntimesTable::FetchRows(const AddRowFunction& addRowFn)
                String id;
                Downtime::Ptr downtime;
                BOOST_FOREACH(boost::tie(id, downtime), downtimes) {
-                       if (Host::GetOwnerByDowntimeID(id) == host)
-                               addRowFn(downtime, LivestatusGroupByNone, Empty);
+                       if (Host::GetOwnerByDowntimeID(id) == host) {
+                               if (!addRowFn(downtime, LivestatusGroupByNone, Empty))
+                                       return;
+                       }
                }
        }
 
@@ -86,8 +88,10 @@ void DowntimesTable::FetchRows(const AddRowFunction& addRowFn)
                String id;
                Downtime::Ptr downtime;
                BOOST_FOREACH(boost::tie(id, downtime), downtimes) {
-                       if (Service::GetOwnerByDowntimeID(id) == service)
-                               addRowFn(downtime, LivestatusGroupByNone, Empty);
+                       if (Service::GetOwnerByDowntimeID(id) == service) {
+                               if (!addRowFn(downtime, LivestatusGroupByNone, Empty))
+                                       return;
+                       }
                }
        }
 }
index be546685ff70bcb5a4022276fc43c3241d271c19..a5cece345e5b1a6268a11969d687d259ca2176df 100644 (file)
@@ -61,7 +61,8 @@ String EndpointsTable::GetPrefix(void) const
 void EndpointsTable::FetchRows(const AddRowFunction& addRowFn)
 {
        BOOST_FOREACH(const Endpoint::Ptr& endpoint, DynamicType::GetObjectsByType<Endpoint>()) {
-               addRowFn(endpoint, LivestatusGroupByNone, Empty);
+               if (!addRowFn(endpoint, LivestatusGroupByNone, Empty))
+                       return;
        }
 }
 
index ee1f6c4c085a51ee25d631d264a30efe227a0d0a..01782aa9ad33b6f5b19391b577c92348647cc07d 100644 (file)
@@ -74,7 +74,8 @@ String HostGroupsTable::GetPrefix(void) const
 void HostGroupsTable::FetchRows(const AddRowFunction& addRowFn)
 {
        BOOST_FOREACH(const HostGroup::Ptr& hg, DynamicType::GetObjectsByType<HostGroup>()) {
-               addRowFn(hg, LivestatusGroupByNone, Empty);
+               if (!addRowFn(hg, LivestatusGroupByNone, Empty))
+                       return;
        }
 }
 
index f99549034c4e423fe1859d9495e3e376950e90ad..bff1b7de0955a13eae0408b5b9f0d26000c201e8 100644 (file)
@@ -190,12 +190,14 @@ void HostsTable::FetchRows(const AddRowFunction& addRowFn)
                BOOST_FOREACH(const HostGroup::Ptr& hg, DynamicType::GetObjectsByType<HostGroup>()) {
                        BOOST_FOREACH(const Host::Ptr& host, hg->GetMembers()) {
                                /* the caller must know which groupby type and value are set for this row */
-                               addRowFn(host, LivestatusGroupByHostGroup, hg);
+                               if (!addRowFn(host, LivestatusGroupByHostGroup, hg))
+                                       return;
                        }
                }
        } else {
                BOOST_FOREACH(const Host::Ptr& host, DynamicType::GetObjectsByType<Host>()) {
-                       addRowFn(host, LivestatusGroupByNone, Empty);
+                       if (!addRowFn(host, LivestatusGroupByNone, Empty))
+                               return;
                }
        }
 }
index 70c707f3b5db967df7e781be89ca499bc927bdd7..9d904805ebbe8069c8f1bd17a1c1703a5da35aa3 100644 (file)
@@ -84,7 +84,7 @@ static void InitScriptFrameCleanup(void)
 INITIALIZE_ONCE(InitScriptFrameCleanup);
 
 LivestatusQuery::LivestatusQuery(const std::vector<String>& lines, const String& compat_log_path)
-       : m_KeepAlive(false), m_OutputFormat("csv"), m_ColumnHeaders(true), m_ErrorCode(0),
+       : m_KeepAlive(false), m_OutputFormat("csv"), m_ColumnHeaders(true), m_Limit(-1), m_ErrorCode(0),
          m_LogTimeFrom(0), m_LogTimeUntil(static_cast<long>(Utility::GetTime()))
 {
        if (lines.size() == 0) {
@@ -182,6 +182,8 @@ LivestatusQuery::LivestatusQuery(const std::vector<String>& lines, const String&
                                m_Separators[3] = String(1, static_cast<char>(Convert::ToLong(separators[3])));
                } else if (header == "ColumnHeaders")
                        m_ColumnHeaders = (params == "on");
+               else if (header == "Limit")
+                       m_Limit = Convert::ToLong(params);
                else if (header == "Filter") {
                        Filter::Ptr filter = ParseFilter(params, m_LogTimeFrom, m_LogTimeUntil);
 
@@ -495,7 +497,7 @@ void LivestatusQuery::ExecuteGetHelper(const Stream::Ptr& stream)
                return;
        }
 
-       std::vector<LivestatusRowValue> objects = table->FilterRows(m_Filter);
+       std::vector<LivestatusRowValue> objects = table->FilterRows(m_Filter, m_Limit);
        std::vector<String> columns;
 
        if (m_Columns.size() > 0)
index a7f991637fcde6f7d0d79921013df8475afaf0d6..9b5c4ad093f8c65b5eb4148823e6dc21581fc360 100644 (file)
@@ -81,6 +81,7 @@ private:
 
        String m_OutputFormat;
        bool m_ColumnHeaders;
+       int m_Limit;
 
        String m_ResponseHeader;
 
index a7c4ac64c98f5336fc5fda9cf28108e577ea7f70..c1f81af2bf6f5ee9f6426145e2acaf1751164d0e 100644 (file)
@@ -65,7 +65,8 @@ String ServiceGroupsTable::GetPrefix(void) const
 void ServiceGroupsTable::FetchRows(const AddRowFunction& addRowFn)
 {
        BOOST_FOREACH(const ServiceGroup::Ptr& sg, DynamicType::GetObjectsByType<ServiceGroup>()) {
-               addRowFn(sg, LivestatusGroupByNone, Empty);
+               if (!addRowFn(sg, LivestatusGroupByNone, Empty))
+                       return;
        }
 }
 
index b4576c52743374a534b97e1135f16ba0d44a4e85..729141143dca96a5d26edafb4f2e2db5f98b96d8 100644 (file)
@@ -170,7 +170,8 @@ void ServicesTable::FetchRows(const AddRowFunction& addRowFn)
                BOOST_FOREACH(const ServiceGroup::Ptr& sg, DynamicType::GetObjectsByType<ServiceGroup>()) {
                        BOOST_FOREACH(const Service::Ptr& service, sg->GetMembers()) {
                                /* the caller must know which groupby type and value are set for this row */
-                               addRowFn(service, LivestatusGroupByServiceGroup, sg);
+                               if (!addRowFn(service, LivestatusGroupByServiceGroup, sg))
+                                       return;
                        }
                }
        } else if (GetGroupByType() == LivestatusGroupByHostGroup) {
@@ -180,13 +181,15 @@ void ServicesTable::FetchRows(const AddRowFunction& addRowFn)
                                ObjectLock ylock(host);
                                BOOST_FOREACH(const Service::Ptr& service, host->GetServices()) {
                                        /* the caller must know which groupby type and value are set for this row */
-                                       addRowFn(service, LivestatusGroupByHostGroup, hg);
+                                       if (!addRowFn(service, LivestatusGroupByHostGroup, hg))
+                                               return;
                                }
                        }
                }
        } else {
                BOOST_FOREACH(const Service::Ptr& service, DynamicType::GetObjectsByType<Service>()) {
-                       addRowFn(service, LivestatusGroupByNone, Empty);
+                       if (!addRowFn(service, LivestatusGroupByNone, Empty))
+                               return;
                }
        }
 }
index a9008512c971ee6e1b3c5df2e2c18f6ad96a3dd4..e0fd0659bf6256ce7b3bfe686eb9a06055c3b580 100644 (file)
@@ -271,7 +271,8 @@ void StateHistTable::FetchRows(const AddRowFunction& addRowFn)
        BOOST_FOREACH(boost::tie(checkable, boost::tuples::ignore), m_CheckablesCache) {
                BOOST_FOREACH(const Dictionary::Ptr& state_hist_bag, m_CheckablesCache[checkable]) {
                        /* pass a dictionary from state history array */
-                       addRowFn(state_hist_bag, LivestatusGroupByNone, Empty);
+                       if (!addRowFn(state_hist_bag, LivestatusGroupByNone, Empty))
+                               return;
                }
        }
 }
index 15e5e3c38e0fd7a4e7de1abf7c5db1673d69e4a5..0f8e0408f512d5f8e87d50d7fd1c539dd55abd5f 100644 (file)
@@ -124,17 +124,20 @@ std::vector<String> Table::GetColumnNames(void) const
        return names;
 }
 
-std::vector<LivestatusRowValue> Table::FilterRows(const Filter::Ptr& filter)
+std::vector<LivestatusRowValue> Table::FilterRows(const Filter::Ptr& filter, int limit)
 {
        std::vector<LivestatusRowValue> rs;
 
-       FetchRows(boost::bind(&Table::FilteredAddRow, this, boost::ref(rs), filter, _1, _2, _3));
+       FetchRows(boost::bind(&Table::FilteredAddRow, this, boost::ref(rs), filter, limit, _1, _2, _3));
 
        return rs;
 }
 
-void Table::FilteredAddRow(std::vector<LivestatusRowValue>& rs, const Filter::Ptr& filter, const Value& row, LivestatusGroupByType groupByType, const Object::Ptr& groupByObject)
+bool Table::FilteredAddRow(std::vector<LivestatusRowValue>& rs, const Filter::Ptr& filter, int limit, const Value& row, LivestatusGroupByType groupByType, const Object::Ptr& groupByObject)
 {
+       if (limit != -1 && rs.size() == limit)
+               return false;
+
        if (!filter || filter->Apply(this, row)) {
                LivestatusRowValue rval;
                rval.Row = row;
@@ -142,7 +145,10 @@ void Table::FilteredAddRow(std::vector<LivestatusRowValue>& rs, const Filter::Pt
                rval.GroupByObject = groupByObject;
 
                rs.push_back(rval);
+
        }
+
+       return true;
 }
 
 Value Table::ZeroAccessor(const Value&)
index ee86bbd84d1e4d948c24afb52a783d6cfe23bf64..e69cdc21ba34b823a650a926940245ff39dd68a9 100644 (file)
@@ -36,7 +36,7 @@ struct LivestatusRowValue {
 };
 
 
-typedef boost::function<void (const Value&, LivestatusGroupByType, const Object::Ptr&)> AddRowFunction;
+typedef boost::function<bool (const Value&, LivestatusGroupByType, const Object::Ptr&)> AddRowFunction;
 
 class Filter;
 
@@ -53,7 +53,7 @@ public:
        virtual String GetName(void) const = 0;
        virtual String GetPrefix(void) const = 0;
 
-       std::vector<LivestatusRowValue> FilterRows(const intrusive_ptr<Filter>& filter);
+       std::vector<LivestatusRowValue> FilterRows(const intrusive_ptr<Filter>& filter, int limit = -1);
 
        void AddColumn(const String& name, const Column& column);
        Column GetColumn(const String& name) const;
@@ -78,7 +78,7 @@ protected:
 private:
        std::map<String, Column> m_Columns;
 
-       void FilteredAddRow(std::vector<LivestatusRowValue>& rs, const intrusive_ptr<Filter>& filter, const Value& row, LivestatusGroupByType groupByType, const Object::Ptr& groupByObject);
+       bool FilteredAddRow(std::vector<LivestatusRowValue>& rs, const intrusive_ptr<Filter>& filter, int limit, const Value& row, LivestatusGroupByType groupByType, const Object::Ptr& groupByObject);
 };
 
 }
index 66de70bb2d39839188add11da3a2bda920ea7795..31e1ed5ab1bb5ace0bf2c88eba029f7327273b00 100644 (file)
@@ -55,7 +55,8 @@ String TimePeriodsTable::GetPrefix(void) const
 void TimePeriodsTable::FetchRows(const AddRowFunction& addRowFn)
 {
        BOOST_FOREACH(const TimePeriod::Ptr& tp, DynamicType::GetObjectsByType<TimePeriod>()) {
-               addRowFn(tp, LivestatusGroupByNone, Empty);
+               if (!addRowFn(tp, LivestatusGroupByNone, Empty))
+                       return;
        }
 }