Implement support for the 'Limit' column in Livestatus

fixes #8529
This commit is contained in:
Gunnar Beutner 2015-03-04 12:03:35 +01:00
parent afd1927a98
commit f41f9b085d
16 changed files with 65 additions and 31 deletions

View 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;
}
}

View 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;
}
}
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}
}

View 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)

View File

@ -81,6 +81,7 @@ private:
String m_OutputFormat;
bool m_ColumnHeaders;
int m_Limit;
String m_ResponseHeader;

View 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;
}
}

View 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;
}
}
}

View 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;
}
}
}

View 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&)

View 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);
};
}

View 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;
}
}