$(top_builddir)/tools/mkembedconfig/mkembedconfig $< $@
liblivestatus_la_SOURCES = \
+ aggregator.cpp \
+ aggregator.h \
attributefilter.cpp \
attributefilter.h \
andfilter.cpp \
contactgroupstable.h \
contactstable.cpp \
contactstable.h \
+ countaggregator.cpp \
+ countaggregator.h \
downtimestable.cpp \
downtimestable.h \
filter.cpp \
--- /dev/null
+/******************************************************************************
+ * Icinga 2 *
+ * Copyright (C) 2012 Icinga Development Team (http://www.icinga.org/) *
+ * *
+ * This program is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU General Public License *
+ * as published by the Free Software Foundation; either version 2 *
+ * of the License, or (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the Free Software Foundation *
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ******************************************************************************/
+
+#include "livestatus/aggregator.h"
+
+using namespace livestatus;
+
+Aggregator::Aggregator(void)
+{ }
+
+void Aggregator::SetFilter(const Filter::Ptr& filter)
+{
+ m_Filter = filter;
+}
+
+Filter::Ptr Aggregator::GetFilter(void) const
+{
+ return m_Filter;
+}
--- /dev/null
+/******************************************************************************
+ * Icinga 2 *
+ * Copyright (C) 2012 Icinga Development Team (http://www.icinga.org/) *
+ * *
+ * This program is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU General Public License *
+ * as published by the Free Software Foundation; either version 2 *
+ * of the License, or (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the Free Software Foundation *
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ******************************************************************************/
+
+#ifndef AGGREGATOR_H
+#define AGGREGATOR_H
+
+#include "livestatus/table.h"
+#include "livestatus/filter.h"
+
+namespace livestatus
+{
+
+/**
+ * @ingroup livestatus
+ */
+class Aggregator : public Object
+{
+public:
+ DECLARE_PTR_TYPEDEFS(Aggregator);
+
+ virtual void Apply(const Table::Ptr& table, const Value& row) = 0;
+ virtual double GetResult(void) const = 0;
+ void SetFilter(const Filter::Ptr& filter);
+
+protected:
+ Aggregator(void);
+
+ Filter::Ptr GetFilter(void) const;
+
+private:
+ Filter::Ptr m_Filter;
+};
+
+}
+
+#endif /* AGGREGATOR_H */
--- /dev/null
+/******************************************************************************
+ * Icinga 2 *
+ * Copyright (C) 2012 Icinga Development Team (http://www.icinga.org/) *
+ * *
+ * This program is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU General Public License *
+ * as published by the Free Software Foundation; either version 2 *
+ * of the License, or (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the Free Software Foundation *
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ******************************************************************************/
+
+#include "livestatus/countaggregator.h"
+
+using namespace livestatus;
+
+CountAggregator::CountAggregator(void)
+ : m_Count(0)
+{ }
+
+void CountAggregator::Apply(const Table::Ptr& table, const Value& row)
+{
+ if (GetFilter()->Apply(table, row))
+ m_Count++;
+}
+
+double CountAggregator::GetResult(void) const
+{
+ return m_Count;
+}
--- /dev/null
+/******************************************************************************
+ * Icinga 2 *
+ * Copyright (C) 2012 Icinga Development Team (http://www.icinga.org/) *
+ * *
+ * This program is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU General Public License *
+ * as published by the Free Software Foundation; either version 2 *
+ * of the License, or (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the Free Software Foundation *
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ******************************************************************************/
+
+#ifndef COUNTAGGREGATOR_H
+#define COUNTAGGREGATOR_H
+
+#include "livestatus/table.h"
+#include "livestatus/aggregator.h"
+
+namespace livestatus
+{
+
+/**
+ * @ingroup livestatus
+ */
+class CountAggregator : public Aggregator
+{
+public:
+ DECLARE_PTR_TYPEDEFS(CountAggregator);
+
+ CountAggregator(void);
+
+ virtual void Apply(const Table::Ptr& table, const Value& row);
+ virtual double GetResult(void) const;
+
+private:
+ int m_Count;
+};
+
+}
+
+#endif /* COUNTAGGREGATOR_H */
******************************************************************************/
#include "livestatus/query.h"
+#include "livestatus/countaggregator.h"
#include "livestatus/attributefilter.h"
#include "livestatus/negatefilter.h"
#include "livestatus/orfilter.h"
}
std::deque<Filter::Ptr> filters, stats;
+ std::deque<Aggregator::Ptr> aggregators;
for (unsigned int i = 1; i < lines.size(); i++) {
line = lines[i];
else if (header == "ColumnHeaders")
m_ColumnHeaders = (params == "on");
else if (header == "Filter" || header == "Stats") {
- std::vector<String> tokens;
- boost::algorithm::split(tokens, params, boost::is_any_of(" "));
- if (tokens.size() == 2)
- tokens.push_back("");
-
- if (tokens.size() < 3) {
+ Filter::Ptr filter = ParseFilter(params);
+
+ if (!filter) {
m_Verb = "ERROR";
m_ErrorCode = 452;
- m_ErrorMessage = "Expected 3 parameters in the filter specification.";
+ m_ErrorMessage = "Invalid filter specification.";
return;
}
- String op = tokens[1];
- bool negate = false;
-
- if (op == "!=") {
- op = "=";
- negate = true;
- } else if (op == "!~") {
- op = "~";
- negate = true;
- } else if (op == "!=~") {
- op = "=~";
- negate = true;
- } else if (op == "!~~") {
- op = "~~";
- negate = true;
- }
-
- Filter::Ptr filter = boost::make_shared<AttributeFilter>(tokens[0], op, tokens[2]);
-
- if (negate)
- filter = boost::make_shared<NegateFilter>(filter);
-
std::deque<Filter::Ptr>& deq = (header == "Filter") ? filters : stats;
deq.push_back(filter);
+
+ if (deq == stats) {
+ Aggregator::Ptr aggregator = boost::make_shared<CountAggregator>();
+ aggregator->SetFilter(filter);
+ aggregators.push_back(aggregator);
+ }
} else if (header == "Or" || header == "And") {
std::deque<Filter::Ptr>& deq = (header == "Or" || header == "And") ? filters : stats;
filters.pop_back();
deq.push_back(boost::make_shared<NegateFilter>(filter));
+
+ if (deq == stats) {
+ Aggregator::Ptr aggregator = aggregators.back();
+ aggregator->SetFilter(filter);
+ }
}
}
}
m_Filter = top_filter;
- m_Stats.swap(stats);
+ m_Aggregators.swap(aggregators);
+}
+
+Filter::Ptr Query::ParseFilter(const String& params)
+{
+ std::vector<String> tokens;
+ boost::algorithm::split(tokens, params, boost::is_any_of(" "));
+
+ if (tokens.size() == 2)
+ tokens.push_back("");
+
+ if (tokens.size() < 3)
+ return Filter::Ptr();
+
+ String op = tokens[1];
+ bool negate = false;
+
+ if (op == "!=") {
+ op = "=";
+ negate = true;
+ } else if (op == "!~") {
+ op = "~";
+ negate = true;
+ } else if (op == "!=~") {
+ op = "=~";
+ negate = true;
+ } else if (op == "!~~") {
+ op = "~~";
+ negate = true;
+ }
+
+ Filter::Ptr filter = boost::make_shared<AttributeFilter>(tokens[0], op, tokens[2]);
+
+ if (negate)
+ filter = boost::make_shared<NegateFilter>(filter);
+
+ return filter;
}
void Query::PrintResultSet(std::ostream& fp, const std::vector<String>& columns, const Array::Ptr& rs)
Array::Ptr rs = boost::make_shared<Array>();
- if (m_Stats.empty()) {
+ if (m_Aggregators.empty()) {
BOOST_FOREACH(const Value& object, objects) {
Array::Ptr row = boost::make_shared<Array>();
rs->Add(row);
}
} else {
- std::vector<int> stats(m_Stats.size(), 0);
-
- BOOST_FOREACH(const Value& object, objects) {
- int index = 0;
- BOOST_FOREACH(const Filter::Ptr filter, m_Stats) {
- if (filter->Apply(table, object))
- stats[index]++;
+ std::vector<double> stats(m_Aggregators.size(), 0);
- index++;
+ int index = 0;
+ BOOST_FOREACH(const Aggregator::Ptr aggregator, m_Aggregators) {
+ BOOST_FOREACH(const Value& object, objects) {
+ aggregator->Apply(table, object);
}
+
+ stats[index] = aggregator->GetResult();
+ index++;
}
Array::Ptr row = boost::make_shared<Array>();
- for (int i = 0; i < m_Stats.size(); i++)
+ for (int i = 0; i < m_Aggregators.size(); i++)
row->Add(stats[i]);
rs->Add(row);
#define QUERY_H
#include "livestatus/filter.h"
+#include "livestatus/aggregator.h"
#include "base/object.h"
#include "base/array.h"
#include "base/stream.h"
std::vector<String> m_Columns;
Filter::Ptr m_Filter;
- std::deque<Filter::Ptr> m_Stats;
+ std::deque<Aggregator::Ptr> m_Aggregators;
String m_OutputFormat;
bool m_ColumnHeaders;
void SendResponse(const Stream::Ptr& stream, int code, const String& data);
void PrintFixed16(const Stream::Ptr& stream, int code, const String& data);
+
+ static Filter::Ptr ParseFilter(const String& params);
};
}