]> granicus.if.org Git - icinga2/blob - lib/livestatus/hoststable.cpp
Merge pull request #6731 from Icinga/bugfix/doc-comment
[icinga2] / lib / livestatus / hoststable.cpp
1 /******************************************************************************
2  * Icinga 2                                                                   *
3  * Copyright (C) 2012-2018 Icinga Development Team (https://icinga.com/)      *
4  *                                                                            *
5  * This program is free software; you can redistribute it and/or              *
6  * modify it under the terms of the GNU General Public License                *
7  * as published by the Free Software Foundation; either version 2             *
8  * of the License, or (at your option) any later version.                     *
9  *                                                                            *
10  * This program is distributed in the hope that it will be useful,            *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of             *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the              *
13  * GNU General Public License for more details.                               *
14  *                                                                            *
15  * You should have received a copy of the GNU General Public License          *
16  * along with this program; if not, write to the Free Software Foundation     *
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.             *
18  ******************************************************************************/
19
20 #include "livestatus/hoststable.hpp"
21 #include "livestatus/hostgroupstable.hpp"
22 #include "livestatus/endpointstable.hpp"
23 #include "icinga/host.hpp"
24 #include "icinga/service.hpp"
25 #include "icinga/hostgroup.hpp"
26 #include "icinga/checkcommand.hpp"
27 #include "icinga/eventcommand.hpp"
28 #include "icinga/timeperiod.hpp"
29 #include "icinga/macroprocessor.hpp"
30 #include "icinga/icingaapplication.hpp"
31 #include "icinga/compatutility.hpp"
32 #include "icinga/pluginutility.hpp"
33 #include "base/configtype.hpp"
34 #include "base/objectlock.hpp"
35 #include "base/json.hpp"
36 #include "base/convert.hpp"
37 #include "base/utility.hpp"
38 #include <boost/tuple/tuple.hpp>
39 #include <boost/algorithm/string/replace.hpp>
40
41 using namespace icinga;
42
43 HostsTable::HostsTable(LivestatusGroupByType type)
44         :Table(type)
45 {
46         AddColumns(this);
47 }
48
49 void HostsTable::AddColumns(Table *table, const String& prefix,
50         const Column::ObjectAccessor& objectAccessor)
51 {
52         table->AddColumn(prefix + "name", Column(&HostsTable::NameAccessor, objectAccessor));
53         table->AddColumn(prefix + "host_name", Column(&HostsTable::NameAccessor, objectAccessor)); //ugly compatibility hack
54         table->AddColumn(prefix + "display_name", Column(&HostsTable::DisplayNameAccessor, objectAccessor));
55         table->AddColumn(prefix + "alias", Column(&HostsTable::DisplayNameAccessor, objectAccessor));
56         table->AddColumn(prefix + "address", Column(&HostsTable::AddressAccessor, objectAccessor));
57         table->AddColumn(prefix + "address6", Column(&HostsTable::Address6Accessor, objectAccessor));
58         table->AddColumn(prefix + "check_command", Column(&HostsTable::CheckCommandAccessor, objectAccessor));
59         table->AddColumn(prefix + "check_command_expanded", Column(&HostsTable::CheckCommandExpandedAccessor, objectAccessor));
60         table->AddColumn(prefix + "event_handler", Column(&HostsTable::EventHandlerAccessor, objectAccessor));
61         table->AddColumn(prefix + "notification_period", Column(&Table::EmptyStringAccessor, objectAccessor));
62         table->AddColumn(prefix + "check_period", Column(&HostsTable::CheckPeriodAccessor, objectAccessor));
63         table->AddColumn(prefix + "notes", Column(&HostsTable::NotesAccessor, objectAccessor));
64         table->AddColumn(prefix + "notes_expanded", Column(&HostsTable::NotesExpandedAccessor, objectAccessor));
65         table->AddColumn(prefix + "notes_url", Column(&HostsTable::NotesUrlAccessor, objectAccessor));
66         table->AddColumn(prefix + "notes_url_expanded", Column(&HostsTable::NotesUrlExpandedAccessor, objectAccessor));
67         table->AddColumn(prefix + "action_url", Column(&HostsTable::ActionUrlAccessor, objectAccessor));
68         table->AddColumn(prefix + "action_url_expanded", Column(&HostsTable::ActionUrlExpandedAccessor, objectAccessor));
69         table->AddColumn(prefix + "plugin_output", Column(&HostsTable::PluginOutputAccessor, objectAccessor));
70         table->AddColumn(prefix + "perf_data", Column(&HostsTable::PerfDataAccessor, objectAccessor));
71         table->AddColumn(prefix + "icon_image", Column(&HostsTable::IconImageAccessor, objectAccessor));
72         table->AddColumn(prefix + "icon_image_expanded", Column(&HostsTable::IconImageExpandedAccessor, objectAccessor));
73         table->AddColumn(prefix + "icon_image_alt", Column(&HostsTable::IconImageAltAccessor, objectAccessor));
74         table->AddColumn(prefix + "statusmap_image", Column(&Table::EmptyStringAccessor, objectAccessor));
75         table->AddColumn(prefix + "long_plugin_output", Column(&HostsTable::LongPluginOutputAccessor, objectAccessor));
76         table->AddColumn(prefix + "initial_state", Column(&Table::EmptyStringAccessor, objectAccessor));
77         table->AddColumn(prefix + "max_check_attempts", Column(&HostsTable::MaxCheckAttemptsAccessor, objectAccessor));
78         table->AddColumn(prefix + "flap_detection_enabled", Column(&HostsTable::FlapDetectionEnabledAccessor, objectAccessor));
79         table->AddColumn(prefix + "check_freshness", Column(&Table::OneAccessor, objectAccessor));
80         table->AddColumn(prefix + "process_performance_data", Column(&HostsTable::ProcessPerformanceDataAccessor, objectAccessor));
81         table->AddColumn(prefix + "accept_passive_checks", Column(&HostsTable::AcceptPassiveChecksAccessor, objectAccessor));
82         table->AddColumn(prefix + "event_handler_enabled", Column(&HostsTable::EventHandlerEnabledAccessor, objectAccessor));
83         table->AddColumn(prefix + "acknowledgement_type", Column(&HostsTable::AcknowledgementTypeAccessor, objectAccessor));
84         table->AddColumn(prefix + "check_type", Column(&HostsTable::CheckTypeAccessor, objectAccessor));
85         table->AddColumn(prefix + "last_state", Column(&HostsTable::LastStateAccessor, objectAccessor));
86         table->AddColumn(prefix + "last_hard_state", Column(&HostsTable::LastHardStateAccessor, objectAccessor));
87         table->AddColumn(prefix + "current_attempt", Column(&HostsTable::CurrentAttemptAccessor, objectAccessor));
88         table->AddColumn(prefix + "last_notification", Column(&HostsTable::LastNotificationAccessor, objectAccessor));
89         table->AddColumn(prefix + "next_notification", Column(&HostsTable::NextNotificationAccessor, objectAccessor));
90         table->AddColumn(prefix + "next_check", Column(&HostsTable::NextCheckAccessor, objectAccessor));
91         table->AddColumn(prefix + "last_hard_state_change", Column(&HostsTable::LastHardStateChangeAccessor, objectAccessor));
92         table->AddColumn(prefix + "has_been_checked", Column(&HostsTable::HasBeenCheckedAccessor, objectAccessor));
93         table->AddColumn(prefix + "current_notification_number", Column(&HostsTable::CurrentNotificationNumberAccessor, objectAccessor));
94         table->AddColumn(prefix + "pending_flex_downtime", Column(&Table::ZeroAccessor, objectAccessor));
95         table->AddColumn(prefix + "total_services", Column(&HostsTable::TotalServicesAccessor, objectAccessor));
96         table->AddColumn(prefix + "checks_enabled", Column(&HostsTable::ChecksEnabledAccessor, objectAccessor));
97         table->AddColumn(prefix + "notifications_enabled", Column(&HostsTable::NotificationsEnabledAccessor, objectAccessor));
98         table->AddColumn(prefix + "acknowledged", Column(&HostsTable::AcknowledgedAccessor, objectAccessor));
99         table->AddColumn(prefix + "state", Column(&HostsTable::StateAccessor, objectAccessor));
100         table->AddColumn(prefix + "state_type", Column(&HostsTable::StateTypeAccessor, objectAccessor));
101         table->AddColumn(prefix + "no_more_notifications", Column(&HostsTable::NoMoreNotificationsAccessor, objectAccessor));
102         table->AddColumn(prefix + "check_flapping_recovery_notification", Column(&Table::ZeroAccessor, objectAccessor));
103         table->AddColumn(prefix + "last_check", Column(&HostsTable::LastCheckAccessor, objectAccessor));
104         table->AddColumn(prefix + "last_state_change", Column(&HostsTable::LastStateChangeAccessor, objectAccessor));
105         table->AddColumn(prefix + "last_time_up", Column(&HostsTable::LastTimeUpAccessor, objectAccessor));
106         table->AddColumn(prefix + "last_time_down", Column(&HostsTable::LastTimeDownAccessor, objectAccessor));
107         table->AddColumn(prefix + "last_time_unreachable", Column(&HostsTable::LastTimeUnreachableAccessor, objectAccessor));
108         table->AddColumn(prefix + "is_flapping", Column(&HostsTable::IsFlappingAccessor, objectAccessor));
109         table->AddColumn(prefix + "scheduled_downtime_depth", Column(&HostsTable::ScheduledDowntimeDepthAccessor, objectAccessor));
110         table->AddColumn(prefix + "is_executing", Column(&Table::ZeroAccessor, objectAccessor));
111         table->AddColumn(prefix + "active_checks_enabled", Column(&HostsTable::ActiveChecksEnabledAccessor, objectAccessor));
112         table->AddColumn(prefix + "check_options", Column(&Table::EmptyStringAccessor, objectAccessor));
113         table->AddColumn(prefix + "obsess_over_host", Column(&Table::ZeroAccessor, objectAccessor));
114         table->AddColumn(prefix + "modified_attributes", Column(&Table::ZeroAccessor, objectAccessor));
115         table->AddColumn(prefix + "modified_attributes_list", Column(&Table::ZeroAccessor, objectAccessor));
116         table->AddColumn(prefix + "check_interval", Column(&HostsTable::CheckIntervalAccessor, objectAccessor));
117         table->AddColumn(prefix + "retry_interval", Column(&HostsTable::RetryIntervalAccessor, objectAccessor));
118         table->AddColumn(prefix + "notification_interval", Column(&HostsTable::NotificationIntervalAccessor, objectAccessor));
119         table->AddColumn(prefix + "first_notification_delay", Column(&Table::EmptyStringAccessor, objectAccessor));
120         table->AddColumn(prefix + "low_flap_threshold", Column(&HostsTable::LowFlapThresholdAccessor, objectAccessor));
121         table->AddColumn(prefix + "high_flap_threshold", Column(&HostsTable::HighFlapThresholdAccessor, objectAccessor));
122         table->AddColumn(prefix + "x_3d", Column(&EmptyStringAccessor, objectAccessor));
123         table->AddColumn(prefix + "y_3d", Column(&EmptyStringAccessor, objectAccessor));
124         table->AddColumn(prefix + "z_3d", Column(&EmptyStringAccessor, objectAccessor));
125         table->AddColumn(prefix + "x_2d", Column(&Table::EmptyStringAccessor, objectAccessor));
126         table->AddColumn(prefix + "y_2d", Column(&Table::EmptyStringAccessor, objectAccessor));
127         table->AddColumn(prefix + "latency", Column(&HostsTable::LatencyAccessor, objectAccessor));
128         table->AddColumn(prefix + "execution_time", Column(&HostsTable::ExecutionTimeAccessor, objectAccessor));
129         table->AddColumn(prefix + "percent_state_change", Column(&HostsTable::PercentStateChangeAccessor, objectAccessor));
130         table->AddColumn(prefix + "in_notification_period", Column(&HostsTable::InNotificationPeriodAccessor, objectAccessor));
131         table->AddColumn(prefix + "in_check_period", Column(&HostsTable::InCheckPeriodAccessor, objectAccessor));
132         table->AddColumn(prefix + "contacts", Column(&HostsTable::ContactsAccessor, objectAccessor));
133         table->AddColumn(prefix + "downtimes", Column(&HostsTable::DowntimesAccessor, objectAccessor));
134         table->AddColumn(prefix + "downtimes_with_info", Column(&HostsTable::DowntimesWithInfoAccessor, objectAccessor));
135         table->AddColumn(prefix + "comments", Column(&HostsTable::CommentsAccessor, objectAccessor));
136         table->AddColumn(prefix + "comments_with_info", Column(&HostsTable::CommentsWithInfoAccessor, objectAccessor));
137         table->AddColumn(prefix + "comments_with_extra_info", Column(&HostsTable::CommentsWithExtraInfoAccessor, objectAccessor));
138         table->AddColumn(prefix + "custom_variable_names", Column(&HostsTable::CustomVariableNamesAccessor, objectAccessor));
139         table->AddColumn(prefix + "custom_variable_values", Column(&HostsTable::CustomVariableValuesAccessor, objectAccessor));
140         table->AddColumn(prefix + "custom_variables", Column(&HostsTable::CustomVariablesAccessor, objectAccessor));
141         table->AddColumn(prefix + "filename", Column(&Table::EmptyStringAccessor, objectAccessor));
142         table->AddColumn(prefix + "parents", Column(&HostsTable::ParentsAccessor, objectAccessor));
143         table->AddColumn(prefix + "childs", Column(&HostsTable::ChildsAccessor, objectAccessor));
144         table->AddColumn(prefix + "num_services", Column(&HostsTable::NumServicesAccessor, objectAccessor));
145         table->AddColumn(prefix + "worst_service_state", Column(&HostsTable::WorstServiceStateAccessor, objectAccessor));
146         table->AddColumn(prefix + "num_services_ok", Column(&HostsTable::NumServicesOkAccessor, objectAccessor));
147         table->AddColumn(prefix + "num_services_warn", Column(&HostsTable::NumServicesWarnAccessor, objectAccessor));
148         table->AddColumn(prefix + "num_services_crit", Column(&HostsTable::NumServicesCritAccessor, objectAccessor));
149         table->AddColumn(prefix + "num_services_unknown", Column(&HostsTable::NumServicesUnknownAccessor, objectAccessor));
150         table->AddColumn(prefix + "num_services_pending", Column(&HostsTable::NumServicesPendingAccessor, objectAccessor));
151         table->AddColumn(prefix + "worst_service_hard_state", Column(&HostsTable::WorstServiceHardStateAccessor, objectAccessor));
152         table->AddColumn(prefix + "num_services_hard_ok", Column(&HostsTable::NumServicesHardOkAccessor, objectAccessor));
153         table->AddColumn(prefix + "num_services_hard_warn", Column(&HostsTable::NumServicesHardWarnAccessor, objectAccessor));
154         table->AddColumn(prefix + "num_services_hard_crit", Column(&HostsTable::NumServicesHardCritAccessor, objectAccessor));
155         table->AddColumn(prefix + "num_services_hard_unknown", Column(&HostsTable::NumServicesHardUnknownAccessor, objectAccessor));
156         table->AddColumn(prefix + "hard_state", Column(&HostsTable::HardStateAccessor, objectAccessor));
157         table->AddColumn(prefix + "pnpgraph_present", Column(&Table::ZeroAccessor, objectAccessor));
158         table->AddColumn(prefix + "staleness", Column(&HostsTable::StalenessAccessor, objectAccessor));
159         table->AddColumn(prefix + "groups", Column(&HostsTable::GroupsAccessor, objectAccessor));
160         table->AddColumn(prefix + "contact_groups", Column(&HostsTable::ContactGroupsAccessor, objectAccessor));
161         table->AddColumn(prefix + "services", Column(&HostsTable::ServicesAccessor, objectAccessor));
162         table->AddColumn(prefix + "services_with_state", Column(&HostsTable::ServicesWithStateAccessor, objectAccessor));
163         table->AddColumn(prefix + "services_with_info", Column(&HostsTable::ServicesWithInfoAccessor, objectAccessor));
164         table->AddColumn(prefix + "check_source", Column(&HostsTable::CheckSourceAccessor, objectAccessor));
165         table->AddColumn(prefix + "is_reachable", Column(&HostsTable::IsReachableAccessor, objectAccessor));
166         table->AddColumn(prefix + "cv_is_json", Column(&HostsTable::CVIsJsonAccessor, objectAccessor));
167         table->AddColumn(prefix + "original_attributes", Column(&HostsTable::OriginalAttributesAccessor, objectAccessor));
168
169         /* add additional group by values received through the object accessor */
170         if (table->GetGroupByType() == LivestatusGroupByHostGroup) {
171                 /* _1 = row, _2 = groupByType, _3 = groupByObject */
172                 Log(LogDebug, "Livestatus")
173                         << "Processing hosts group by hostgroup table.";
174                 HostGroupsTable::AddColumns(table, "hostgroup_", std::bind(&HostsTable::HostGroupAccessor, _1, _2, _3));
175         }
176 }
177
178 String HostsTable::GetName() const
179 {
180         return "hosts";
181 }
182
183 String HostsTable::GetPrefix() const
184 {
185         return "host";
186 }
187
188 void HostsTable::FetchRows(const AddRowFunction& addRowFn)
189 {
190         if (GetGroupByType() == LivestatusGroupByHostGroup) {
191                 for (const HostGroup::Ptr& hg : ConfigType::GetObjectsByType<HostGroup>()) {
192                         for (const Host::Ptr& host : hg->GetMembers()) {
193                                 /* the caller must know which groupby type and value are set for this row */
194                                 if (!addRowFn(host, LivestatusGroupByHostGroup, hg))
195                                         return;
196                         }
197                 }
198         } else {
199                 for (const Host::Ptr& host : ConfigType::GetObjectsByType<Host>()) {
200                         if (!addRowFn(host, LivestatusGroupByNone, Empty))
201                                 return;
202                 }
203         }
204 }
205
206 Object::Ptr HostsTable::HostGroupAccessor(const Value& row, LivestatusGroupByType groupByType, const Object::Ptr& groupByObject)
207 {
208         /* return the current group by value set from within FetchRows()
209          * this is the hostgrouo object used for the table join inside
210          * in AddColumns()
211          */
212         if (groupByType == LivestatusGroupByHostGroup)
213                 return groupByObject;
214
215         return nullptr;
216 }
217
218 Value HostsTable::NameAccessor(const Value& row)
219 {
220         Host::Ptr host = static_cast<Host::Ptr>(row);
221
222         if (!host)
223                 return Empty;
224
225         return host->GetName();
226 }
227
228 Value HostsTable::DisplayNameAccessor(const Value& row)
229 {
230         Host::Ptr host = static_cast<Host::Ptr>(row);
231
232         if (!host)
233                 return Empty;
234
235         return host->GetDisplayName();
236 }
237
238 Value HostsTable::AddressAccessor(const Value& row)
239 {
240         Host::Ptr host = static_cast<Host::Ptr>(row);
241
242         if (!host)
243                 return Empty;
244
245         return host->GetAddress();
246 }
247
248 Value HostsTable::Address6Accessor(const Value& row)
249 {
250         Host::Ptr host = static_cast<Host::Ptr>(row);
251
252         if (!host)
253                 return Empty;
254
255         return host->GetAddress6();
256 }
257
258 Value HostsTable::CheckCommandAccessor(const Value& row)
259 {
260         Host::Ptr host = static_cast<Host::Ptr>(row);
261
262         if (!host)
263                 return Empty;
264
265         CheckCommand::Ptr checkcommand = host->GetCheckCommand();
266         if (checkcommand)
267                 return CompatUtility::GetCommandName(checkcommand) + "!" + CompatUtility::GetCheckableCommandArgs(host);
268
269         return Empty;
270 }
271
272 Value HostsTable::CheckCommandExpandedAccessor(const Value& row)
273 {
274         Host::Ptr host = static_cast<Host::Ptr>(row);
275
276         if (!host)
277                 return Empty;
278
279         CheckCommand::Ptr checkcommand = host->GetCheckCommand();
280         if (checkcommand)
281                 return CompatUtility::GetCommandName(checkcommand) + "!" + CompatUtility::GetCheckableCommandArgs(host);
282
283         return Empty;
284 }
285
286 Value HostsTable::EventHandlerAccessor(const Value& row)
287 {
288         Host::Ptr host = static_cast<Host::Ptr>(row);
289
290         if (!host)
291                 return Empty;
292
293         EventCommand::Ptr eventcommand = host->GetEventCommand();
294         if (eventcommand)
295                 return CompatUtility::GetCommandName(eventcommand);
296
297         return Empty;
298 }
299
300 Value HostsTable::CheckPeriodAccessor(const Value& row)
301 {
302         Host::Ptr host = static_cast<Host::Ptr>(row);
303
304         if (!host)
305                 return Empty;
306
307         TimePeriod::Ptr checkPeriod = host->GetCheckPeriod();
308
309         if (!checkPeriod)
310                 return Empty;
311
312         return checkPeriod->GetName();
313 }
314
315 Value HostsTable::NotesAccessor(const Value& row)
316 {
317         Host::Ptr host = static_cast<Host::Ptr>(row);
318
319         if (!host)
320                 return Empty;
321
322         return host->GetNotes();
323 }
324
325 Value HostsTable::NotesExpandedAccessor(const Value& row)
326 {
327         Host::Ptr host = static_cast<Host::Ptr>(row);
328
329         if (!host)
330                 return Empty;
331
332         MacroProcessor::ResolverList resolvers {
333                 { "host", host },
334                 { "icinga", IcingaApplication::GetInstance() }
335         };
336
337         return MacroProcessor::ResolveMacros(host->GetNotes(), resolvers);
338 }
339
340 Value HostsTable::NotesUrlAccessor(const Value& row)
341 {
342         Host::Ptr host = static_cast<Host::Ptr>(row);
343
344         if (!host)
345                 return Empty;
346
347         return host->GetNotesUrl();
348 }
349
350 Value HostsTable::NotesUrlExpandedAccessor(const Value& row)
351 {
352         Host::Ptr host = static_cast<Host::Ptr>(row);
353
354         if (!host)
355                 return Empty;
356
357         MacroProcessor::ResolverList resolvers {
358                 { "host", host },
359                 { "icinga", IcingaApplication::GetInstance() }
360         };
361
362         return MacroProcessor::ResolveMacros(host->GetNotesUrl(), resolvers);
363 }
364
365 Value HostsTable::ActionUrlAccessor(const Value& row)
366 {
367         Host::Ptr host = static_cast<Host::Ptr>(row);
368
369         if (!host)
370                 return Empty;
371
372         return host->GetActionUrl();
373 }
374
375 Value HostsTable::ActionUrlExpandedAccessor(const Value& row)
376 {
377         Host::Ptr host = static_cast<Host::Ptr>(row);
378
379         if (!host)
380                 return Empty;
381
382         MacroProcessor::ResolverList resolvers {
383                 { "host", host },
384                 { "icinga", IcingaApplication::GetInstance() }
385         };
386
387         return MacroProcessor::ResolveMacros(host->GetActionUrl(), resolvers);
388 }
389
390 Value HostsTable::PluginOutputAccessor(const Value& row)
391 {
392         Host::Ptr host = static_cast<Host::Ptr>(row);
393
394         if (!host)
395                 return Empty;
396
397         String output;
398         CheckResult::Ptr cr = host->GetLastCheckResult();
399
400         if (cr)
401                 output = CompatUtility::GetCheckResultOutput(cr);
402
403         return output;
404 }
405
406 Value HostsTable::PerfDataAccessor(const Value& row)
407 {
408         Host::Ptr host = static_cast<Host::Ptr>(row);
409
410         if (!host)
411                 return Empty;
412
413         String perfdata;
414         CheckResult::Ptr cr = host->GetLastCheckResult();
415
416         if (!cr)
417                 return Empty;
418
419         return PluginUtility::FormatPerfdata(cr->GetPerformanceData());
420 }
421
422 Value HostsTable::IconImageAccessor(const Value& row)
423 {
424         Host::Ptr host = static_cast<Host::Ptr>(row);
425
426         if (!host)
427                 return Empty;
428
429         return host->GetIconImage();
430 }
431
432 Value HostsTable::IconImageExpandedAccessor(const Value& row)
433 {
434         Host::Ptr host = static_cast<Host::Ptr>(row);
435
436         if (!host)
437                 return Empty;
438
439         MacroProcessor::ResolverList resolvers {
440                 { "host", host },
441                 { "icinga", IcingaApplication::GetInstance() }
442         };
443
444         return MacroProcessor::ResolveMacros(host->GetIconImage(), resolvers);
445 }
446
447 Value HostsTable::IconImageAltAccessor(const Value& row)
448 {
449         Host::Ptr host = static_cast<Host::Ptr>(row);
450
451         if (!host)
452                 return Empty;
453
454         return host->GetIconImageAlt();
455 }
456
457 Value HostsTable::LongPluginOutputAccessor(const Value& row)
458 {
459         Host::Ptr host = static_cast<Host::Ptr>(row);
460
461         if (!host)
462                 return Empty;
463
464         String long_output;
465         CheckResult::Ptr cr = host->GetLastCheckResult();
466
467         if (cr)
468                 long_output = CompatUtility::GetCheckResultLongOutput(cr);
469
470         return long_output;
471 }
472
473 Value HostsTable::MaxCheckAttemptsAccessor(const Value& row)
474 {
475         Host::Ptr host = static_cast<Host::Ptr>(row);
476
477         if (!host)
478                 return Empty;
479
480         return host->GetMaxCheckAttempts();
481 }
482
483 Value HostsTable::FlapDetectionEnabledAccessor(const Value& row)
484 {
485         Host::Ptr host = static_cast<Host::Ptr>(row);
486
487         if (!host)
488                 return Empty;
489
490         return Convert::ToLong(host->GetEnableFlapping());
491 }
492
493 Value HostsTable::AcceptPassiveChecksAccessor(const Value& row)
494 {
495         Host::Ptr host = static_cast<Host::Ptr>(row);
496
497         if (!host)
498                 return Empty;
499
500         return Convert::ToLong(host->GetEnablePassiveChecks());
501 }
502
503 Value HostsTable::EventHandlerEnabledAccessor(const Value& row)
504 {
505         Host::Ptr host = static_cast<Host::Ptr>(row);
506
507         if (!host)
508                 return Empty;
509
510         return Convert::ToLong(host->GetEnableEventHandler());
511 }
512
513 Value HostsTable::AcknowledgementTypeAccessor(const Value& row)
514 {
515         Host::Ptr host = static_cast<Host::Ptr>(row);
516
517         if (!host)
518                 return Empty;
519
520         ObjectLock olock(host);
521         return host->GetAcknowledgement();
522 }
523
524 Value HostsTable::CheckTypeAccessor(const Value& row)
525 {
526         Host::Ptr host = static_cast<Host::Ptr>(row);
527
528         if (!host)
529                 return Empty;
530
531         return (host->GetEnableActiveChecks() ? 0 : 1); /* 0 .. active, 1 .. passive */
532 }
533
534 Value HostsTable::LastStateAccessor(const Value& row)
535 {
536         Host::Ptr host = static_cast<Host::Ptr>(row);
537
538         if (!host)
539                 return Empty;
540
541         return host->GetLastState();
542 }
543
544 Value HostsTable::LastHardStateAccessor(const Value& row)
545 {
546         Host::Ptr host = static_cast<Host::Ptr>(row);
547
548         if (!host)
549                 return Empty;
550
551         return host->GetLastHardState();
552 }
553
554 Value HostsTable::CurrentAttemptAccessor(const Value& row)
555 {
556         Host::Ptr host = static_cast<Host::Ptr>(row);
557
558         if (!host)
559                 return Empty;
560
561         return host->GetCheckAttempt();
562 }
563
564 Value HostsTable::LastNotificationAccessor(const Value& row)
565 {
566         Host::Ptr host = static_cast<Host::Ptr>(row);
567
568         if (!host)
569                 return Empty;
570
571         return CompatUtility::GetCheckableNotificationLastNotification(host);
572 }
573
574 Value HostsTable::NextNotificationAccessor(const Value& row)
575 {
576         Host::Ptr host = static_cast<Host::Ptr>(row);
577
578         if (!host)
579                 return Empty;
580
581         return CompatUtility::GetCheckableNotificationNextNotification(host);
582 }
583
584 Value HostsTable::NextCheckAccessor(const Value& row)
585 {
586         Host::Ptr host = static_cast<Host::Ptr>(row);
587
588         if (!host)
589                 return Empty;
590
591         return static_cast<int>(host->GetNextCheck());
592 }
593
594 Value HostsTable::LastHardStateChangeAccessor(const Value& row)
595 {
596         Host::Ptr host = static_cast<Host::Ptr>(row);
597
598         if (!host)
599                 return Empty;
600
601         return static_cast<int>(host->GetLastHardStateChange());
602 }
603
604 Value HostsTable::HasBeenCheckedAccessor(const Value& row)
605 {
606         Host::Ptr host = static_cast<Host::Ptr>(row);
607
608         if (!host)
609                 return Empty;
610
611         return Convert::ToLong(host->HasBeenChecked());
612 }
613
614 Value HostsTable::CurrentNotificationNumberAccessor(const Value& row)
615 {
616         Host::Ptr host = static_cast<Host::Ptr>(row);
617
618         if (!host)
619                 return Empty;
620
621         return CompatUtility::GetCheckableNotificationNotificationNumber(host);
622 }
623
624 Value HostsTable::TotalServicesAccessor(const Value& row)
625 {
626         Host::Ptr host = static_cast<Host::Ptr>(row);
627
628         if (!host)
629                 return Empty;
630
631         return host->GetTotalServices();
632 }
633
634 Value HostsTable::ChecksEnabledAccessor(const Value& row)
635 {
636         Host::Ptr host = static_cast<Host::Ptr>(row);
637
638         if (!host)
639                 return Empty;
640
641         return Convert::ToLong(host->GetEnableActiveChecks());
642 }
643
644 Value HostsTable::NotificationsEnabledAccessor(const Value& row)
645 {
646         Host::Ptr host = static_cast<Host::Ptr>(row);
647
648         if (!host)
649                 return Empty;
650
651         return Convert::ToLong(host->GetEnableNotifications());
652 }
653
654 Value HostsTable::ProcessPerformanceDataAccessor(const Value& row)
655 {
656         Host::Ptr host = static_cast<Host::Ptr>(row);
657
658         if (!host)
659                 return Empty;
660
661         return Convert::ToLong(host->GetEnablePerfdata());
662 }
663
664 Value HostsTable::AcknowledgedAccessor(const Value& row)
665 {
666         Host::Ptr host = static_cast<Host::Ptr>(row);
667
668         if (!host)
669                 return Empty;
670
671         ObjectLock olock(host);
672         return host->IsAcknowledged();
673 }
674
675 Value HostsTable::StateAccessor(const Value& row)
676 {
677         Host::Ptr host = static_cast<Host::Ptr>(row);
678
679         if (!host)
680                 return Empty;
681
682         return host->IsReachable() ? host->GetState() : 2;
683 }
684
685 Value HostsTable::StateTypeAccessor(const Value& row)
686 {
687         Host::Ptr host = static_cast<Host::Ptr>(row);
688
689         if (!host)
690                 return Empty;
691
692         return host->GetStateType();
693 }
694
695 Value HostsTable::NoMoreNotificationsAccessor(const Value& row)
696 {
697         Host::Ptr host = static_cast<Host::Ptr>(row);
698
699         if (!host)
700                 return Empty;
701
702         return (CompatUtility::GetCheckableNotificationNotificationInterval(host) == 0 && !host->GetVolatile()) ? 1 : 0;
703 }
704
705 Value HostsTable::LastCheckAccessor(const Value& row)
706 {
707         Host::Ptr host = static_cast<Host::Ptr>(row);
708
709         if (!host)
710                 return Empty;
711
712         return static_cast<int>(host->GetLastCheck());
713 }
714
715 Value HostsTable::LastStateChangeAccessor(const Value& row)
716 {
717         Host::Ptr host = static_cast<Host::Ptr>(row);
718
719         if (!host)
720                 return Empty;
721
722         return static_cast<int>(host->GetLastStateChange());
723 }
724
725 Value HostsTable::LastTimeUpAccessor(const Value& row)
726 {
727         Host::Ptr host = static_cast<Host::Ptr>(row);
728
729         if (!host)
730                 return Empty;
731
732         return static_cast<int>(host->GetLastStateUp());
733 }
734
735 Value HostsTable::LastTimeDownAccessor(const Value& row)
736 {
737         Host::Ptr host = static_cast<Host::Ptr>(row);
738
739         if (!host)
740                 return Empty;
741
742         return static_cast<int>(host->GetLastStateDown());
743 }
744
745 Value HostsTable::LastTimeUnreachableAccessor(const Value& row)
746 {
747         Host::Ptr host = static_cast<Host::Ptr>(row);
748
749         if (!host)
750                 return Empty;
751
752         return static_cast<int>(host->GetLastStateUnreachable());
753 }
754
755 Value HostsTable::IsFlappingAccessor(const Value& row)
756 {
757         Host::Ptr host = static_cast<Host::Ptr>(row);
758
759         if (!host)
760                 return Empty;
761
762         return host->IsFlapping();
763 }
764
765 Value HostsTable::ScheduledDowntimeDepthAccessor(const Value& row)
766 {
767         Host::Ptr host = static_cast<Host::Ptr>(row);
768
769         if (!host)
770                 return Empty;
771
772         return host->GetDowntimeDepth();
773 }
774
775 Value HostsTable::ActiveChecksEnabledAccessor(const Value& row)
776 {
777         Host::Ptr host = static_cast<Host::Ptr>(row);
778
779         if (!host)
780                 return Empty;
781
782         return Convert::ToLong(host->GetEnableActiveChecks());
783 }
784
785 Value HostsTable::CheckIntervalAccessor(const Value& row)
786 {
787         Host::Ptr host = static_cast<Host::Ptr>(row);
788
789         if (!host)
790                 return Empty;
791
792         return host->GetCheckInterval() / 60.0;
793 }
794
795 Value HostsTable::RetryIntervalAccessor(const Value& row)
796 {
797         Host::Ptr host = static_cast<Host::Ptr>(row);
798
799         if (!host)
800                 return Empty;
801
802         return host->GetRetryInterval() / 60.0;
803 }
804
805 Value HostsTable::NotificationIntervalAccessor(const Value& row)
806 {
807         Host::Ptr host = static_cast<Host::Ptr>(row);
808
809         if (!host)
810                 return Empty;
811
812         return CompatUtility::GetCheckableNotificationNotificationInterval(host);
813 }
814
815 Value HostsTable::LowFlapThresholdAccessor(const Value& row)
816 {
817         Host::Ptr host = static_cast<Host::Ptr>(row);
818
819         if (!host)
820                 return Empty;
821
822         return host->GetFlappingThresholdLow();
823 }
824
825 Value HostsTable::HighFlapThresholdAccessor(const Value& row)
826 {
827         Host::Ptr host = static_cast<Host::Ptr>(row);
828
829         if (!host)
830                 return Empty;
831
832         return host->GetFlappingThresholdHigh();
833 }
834
835 Value HostsTable::LatencyAccessor(const Value& row)
836 {
837         Host::Ptr host = static_cast<Host::Ptr>(row);
838
839         if (!host)
840                 return Empty;
841
842         CheckResult::Ptr cr = host->GetLastCheckResult();
843
844         if (!cr)
845                 return Empty;
846
847         return cr->CalculateLatency();
848 }
849
850 Value HostsTable::ExecutionTimeAccessor(const Value& row)
851 {
852         Host::Ptr host = static_cast<Host::Ptr>(row);
853
854         if (!host)
855                 return Empty;
856
857         CheckResult::Ptr cr = host->GetLastCheckResult();
858
859         if (!cr)
860                 return Empty;
861
862         return cr->CalculateExecutionTime();
863 }
864
865 Value HostsTable::PercentStateChangeAccessor(const Value& row)
866 {
867         Host::Ptr host = static_cast<Host::Ptr>(row);
868
869         if (!host)
870                 return Empty;
871
872         return host->GetFlappingCurrent();
873 }
874
875 Value HostsTable::InNotificationPeriodAccessor(const Value& row)
876 {
877         Host::Ptr host = static_cast<Host::Ptr>(row);
878
879         if (!host)
880                 return Empty;
881
882         for (const Notification::Ptr& notification : host->GetNotifications()) {
883                 TimePeriod::Ptr timeperiod = notification->GetPeriod();
884
885                 if (!timeperiod || timeperiod->IsInside(Utility::GetTime()))
886                         return 1;
887         }
888
889         return 0;
890 }
891
892 Value HostsTable::InCheckPeriodAccessor(const Value& row)
893 {
894         Host::Ptr host = static_cast<Host::Ptr>(row);
895
896         if (!host)
897                 return Empty;
898
899         TimePeriod::Ptr timeperiod = host->GetCheckPeriod();
900
901         /* none set means always checked */
902         if (!timeperiod)
903                 return 1;
904
905         return Convert::ToLong(timeperiod->IsInside(Utility::GetTime()));
906 }
907
908 Value HostsTable::ContactsAccessor(const Value& row)
909 {
910         Host::Ptr host = static_cast<Host::Ptr>(row);
911
912         if (!host)
913                 return Empty;
914
915         ArrayData result;
916
917         for (const User::Ptr& user : CompatUtility::GetCheckableNotificationUsers(host)) {
918                 result.push_back(user->GetName());
919         }
920
921         return new Array(std::move(result));
922 }
923
924 Value HostsTable::DowntimesAccessor(const Value& row)
925 {
926         Host::Ptr host = static_cast<Host::Ptr>(row);
927
928         if (!host)
929                 return Empty;
930
931         ArrayData result;
932
933         for (const Downtime::Ptr& downtime : host->GetDowntimes()) {
934                 if (downtime->IsExpired())
935                         continue;
936
937                 result.push_back(downtime->GetLegacyId());
938         }
939
940         return new Array(std::move(result));
941 }
942
943 Value HostsTable::DowntimesWithInfoAccessor(const Value& row)
944 {
945         Host::Ptr host = static_cast<Host::Ptr>(row);
946
947         if (!host)
948                 return Empty;
949
950         ArrayData result;
951
952         for (const Downtime::Ptr& downtime : host->GetDowntimes()) {
953                 if (downtime->IsExpired())
954                         continue;
955
956                 result.push_back(new Array({
957                         downtime->GetLegacyId(),
958                         downtime->GetAuthor(),
959                         downtime->GetComment()
960                 }));
961         }
962
963         return new Array(std::move(result));
964 }
965
966 Value HostsTable::CommentsAccessor(const Value& row)
967 {
968         Host::Ptr host = static_cast<Host::Ptr>(row);
969
970         if (!host)
971                 return Empty;
972
973         ArrayData result;
974
975         for (const Comment::Ptr& comment : host->GetComments()) {
976                 if (comment->IsExpired())
977                         continue;
978
979                 result.push_back(comment->GetLegacyId());
980         }
981
982         return new Array(std::move(result));
983 }
984
985 Value HostsTable::CommentsWithInfoAccessor(const Value& row)
986 {
987         Host::Ptr host = static_cast<Host::Ptr>(row);
988
989         if (!host)
990                 return Empty;
991
992         ArrayData result;
993
994         for (const Comment::Ptr& comment : host->GetComments()) {
995                 if (comment->IsExpired())
996                         continue;
997
998                 result.push_back(new Array({
999                         comment->GetLegacyId(),
1000                         comment->GetAuthor(),
1001                         comment->GetText()
1002                 }));
1003         }
1004
1005         return new Array(std::move(result));
1006 }
1007
1008 Value HostsTable::CommentsWithExtraInfoAccessor(const Value& row)
1009 {
1010         Host::Ptr host = static_cast<Host::Ptr>(row);
1011
1012         if (!host)
1013                 return Empty;
1014
1015         ArrayData result;
1016
1017         for (const Comment::Ptr& comment : host->GetComments()) {
1018                 if (comment->IsExpired())
1019                         continue;
1020
1021                 result.push_back(new Array({
1022                         comment->GetLegacyId(),
1023                         comment->GetAuthor(),
1024                         comment->GetText(),
1025                         comment->GetEntryType(),
1026                         static_cast<int>(comment->GetEntryTime())
1027                 }));
1028         }
1029
1030         return new Array(std::move(result));
1031 }
1032
1033 Value HostsTable::CustomVariableNamesAccessor(const Value& row)
1034 {
1035         Host::Ptr host = static_cast<Host::Ptr>(row);
1036
1037         if (!host)
1038                 return Empty;
1039
1040         Dictionary::Ptr vars = host->GetVars();
1041
1042         ArrayData result;
1043
1044         if (vars) {
1045                 ObjectLock olock(vars);
1046                 for (const Dictionary::Pair& kv : vars) {
1047                         result.push_back(kv.first);
1048                 }
1049         }
1050
1051         return new Array(std::move(result));
1052 }
1053
1054 Value HostsTable::CustomVariableValuesAccessor(const Value& row)
1055 {
1056         Host::Ptr host = static_cast<Host::Ptr>(row);
1057
1058         if (!host)
1059                 return Empty;
1060
1061         Dictionary::Ptr vars = host->GetVars();
1062
1063         ArrayData result;
1064
1065         if (vars) {
1066                 ObjectLock olock(vars);
1067                 for (const Dictionary::Pair& kv : vars) {
1068                         if (kv.second.IsObjectType<Array>() || kv.second.IsObjectType<Dictionary>())
1069                                 result.push_back(JsonEncode(kv.second));
1070                         else
1071                                 result.push_back(kv.second);
1072                 }
1073         }
1074
1075         return new Array(std::move(result));
1076 }
1077
1078 Value HostsTable::CustomVariablesAccessor(const Value& row)
1079 {
1080         Host::Ptr host = static_cast<Host::Ptr>(row);
1081
1082         if (!host)
1083                 return Empty;
1084
1085         Dictionary::Ptr vars = host->GetVars();
1086
1087         ArrayData result;
1088
1089         if (vars) {
1090                 ObjectLock olock(vars);
1091                 for (const Dictionary::Pair& kv : vars) {
1092                         Value val;
1093
1094                         if (kv.second.IsObjectType<Array>() || kv.second.IsObjectType<Dictionary>())
1095                                 val = JsonEncode(kv.second);
1096                         else
1097                                 val = kv.second;
1098
1099                         result.push_back(new Array({
1100                                 kv.first,
1101                                 val
1102                         }));
1103                 }
1104         }
1105
1106         return new Array(std::move(result));
1107 }
1108
1109 Value HostsTable::CVIsJsonAccessor(const Value& row)
1110 {
1111         Host::Ptr host = static_cast<Host::Ptr>(row);
1112
1113         if (!host)
1114                 return Empty;
1115
1116         Dictionary::Ptr vars = host->GetVars();
1117
1118         if (!vars)
1119                 return Empty;
1120
1121         bool cv_is_json = false;
1122
1123         ObjectLock olock(vars);
1124         for (const Dictionary::Pair& kv : vars) {
1125                 if (kv.second.IsObjectType<Array>() || kv.second.IsObjectType<Dictionary>())
1126                         cv_is_json = true;
1127         }
1128
1129         return cv_is_json;
1130 }
1131
1132 Value HostsTable::ParentsAccessor(const Value& row)
1133 {
1134         Host::Ptr host = static_cast<Host::Ptr>(row);
1135
1136         if (!host)
1137                 return Empty;
1138
1139         ArrayData result;
1140
1141         for (const Checkable::Ptr& parent : host->GetParents()) {
1142                 Host::Ptr parent_host = dynamic_pointer_cast<Host>(parent);
1143
1144                 if (!parent_host)
1145                         continue;
1146
1147                 result.push_back(parent_host->GetName());
1148         }
1149
1150         return new Array(std::move(result));
1151 }
1152
1153 Value HostsTable::ChildsAccessor(const Value& row)
1154 {
1155         Host::Ptr host = static_cast<Host::Ptr>(row);
1156
1157         if (!host)
1158                 return Empty;
1159
1160         ArrayData result;
1161
1162         for (const Checkable::Ptr& child : host->GetChildren()) {
1163                 Host::Ptr child_host = dynamic_pointer_cast<Host>(child);
1164
1165                 if (!child_host)
1166                         continue;
1167
1168                 result.push_back(child_host->GetName());
1169         }
1170
1171         return new Array(std::move(result));
1172 }
1173
1174 Value HostsTable::NumServicesAccessor(const Value& row)
1175 {
1176         /* duplicate of TotalServices */
1177         Host::Ptr host = static_cast<Host::Ptr>(row);
1178
1179         if (!host)
1180                 return Empty;
1181
1182         return host->GetTotalServices();
1183 }
1184
1185 Value HostsTable::WorstServiceStateAccessor(const Value& row)
1186 {
1187         Host::Ptr host = static_cast<Host::Ptr>(row);
1188
1189         if (!host)
1190                 return Empty;
1191
1192         Value worst_service = ServiceOK;
1193
1194         for (const Service::Ptr& service : host->GetServices()) {
1195                 if (service->GetState() > worst_service)
1196                         worst_service = service->GetState();
1197         }
1198
1199         return worst_service;
1200 }
1201
1202 Value HostsTable::NumServicesOkAccessor(const Value& row)
1203 {
1204         Host::Ptr host = static_cast<Host::Ptr>(row);
1205
1206         if (!host)
1207                 return Empty;
1208
1209         int num_services = 0;
1210
1211         for (const Service::Ptr& service : host->GetServices()) {
1212                 if (service->GetState() == ServiceOK)
1213                         num_services++;
1214         }
1215
1216         return num_services;
1217 }
1218
1219 Value HostsTable::NumServicesWarnAccessor(const Value& row)
1220 {
1221         Host::Ptr host = static_cast<Host::Ptr>(row);
1222
1223         if (!host)
1224                 return Empty;
1225
1226         int num_services = 0;
1227
1228         for (const Service::Ptr& service : host->GetServices()) {
1229                 if (service->GetState() == ServiceWarning)
1230                         num_services++;
1231         }
1232
1233         return num_services;
1234 }
1235
1236 Value HostsTable::NumServicesCritAccessor(const Value& row)
1237 {
1238         Host::Ptr host = static_cast<Host::Ptr>(row);
1239
1240         if (!host)
1241                 return Empty;
1242
1243         int num_services = 0;
1244
1245         for (const Service::Ptr& service : host->GetServices()) {
1246                 if (service->GetState() == ServiceCritical)
1247                         num_services++;
1248         }
1249
1250         return num_services;
1251 }
1252
1253 Value HostsTable::NumServicesUnknownAccessor(const Value& row)
1254 {
1255         Host::Ptr host = static_cast<Host::Ptr>(row);
1256
1257         if (!host)
1258                 return Empty;
1259
1260         int num_services = 0;
1261
1262         for (const Service::Ptr& service : host->GetServices()) {
1263                 if (service->GetState() == ServiceUnknown)
1264                         num_services++;
1265         }
1266
1267         return num_services;
1268 }
1269
1270 Value HostsTable::NumServicesPendingAccessor(const Value& row)
1271 {
1272         Host::Ptr host = static_cast<Host::Ptr>(row);
1273
1274         if (!host)
1275                 return Empty;
1276
1277         int num_services = 0;
1278
1279         for (const Service::Ptr& service : host->GetServices()) {
1280                 if (!service->GetLastCheckResult())
1281                         num_services++;
1282         }
1283
1284         return num_services;
1285 }
1286
1287 Value HostsTable::WorstServiceHardStateAccessor(const Value& row)
1288 {
1289         Host::Ptr host = static_cast<Host::Ptr>(row);
1290
1291         if (!host)
1292                 return Empty;
1293
1294         Value worst_service = ServiceOK;
1295
1296         for (const Service::Ptr& service : host->GetServices()) {
1297                 if (service->GetStateType() == StateTypeHard) {
1298                         if (service->GetState() > worst_service)
1299                                 worst_service = service->GetState();
1300                 }
1301         }
1302
1303         return worst_service;
1304 }
1305
1306 Value HostsTable::NumServicesHardOkAccessor(const Value& row)
1307 {
1308         Host::Ptr host = static_cast<Host::Ptr>(row);
1309
1310         if (!host)
1311                 return Empty;
1312
1313         int num_services = 0;
1314
1315         for (const Service::Ptr& service : host->GetServices()) {
1316                 if (service->GetStateType() == StateTypeHard && service->GetState() == ServiceOK)
1317                         num_services++;
1318         }
1319
1320         return num_services;
1321 }
1322
1323 Value HostsTable::NumServicesHardWarnAccessor(const Value& row)
1324 {
1325         Host::Ptr host = static_cast<Host::Ptr>(row);
1326
1327         if (!host)
1328                 return Empty;
1329
1330         int num_services = 0;
1331
1332         for (const Service::Ptr& service : host->GetServices()) {
1333                 if (service->GetStateType() == StateTypeHard && service->GetState() == ServiceWarning)
1334                         num_services++;
1335         }
1336
1337         return num_services;
1338 }
1339
1340 Value HostsTable::NumServicesHardCritAccessor(const Value& row)
1341 {
1342         Host::Ptr host = static_cast<Host::Ptr>(row);
1343
1344         if (!host)
1345                 return Empty;
1346
1347         int num_services = 0;
1348
1349         for (const Service::Ptr& service : host->GetServices()) {
1350                 if (service->GetStateType() == StateTypeHard && service->GetState() == ServiceCritical)
1351                         num_services++;
1352         }
1353
1354         return num_services;
1355 }
1356
1357 Value HostsTable::NumServicesHardUnknownAccessor(const Value& row)
1358 {
1359         Host::Ptr host = static_cast<Host::Ptr>(row);
1360
1361         if (!host)
1362                 return Empty;
1363
1364         int num_services = 0;
1365
1366         for (const Service::Ptr& service : host->GetServices()) {
1367                 if (service->GetStateType() == StateTypeHard && service->GetState() == ServiceUnknown)
1368                         num_services++;
1369         }
1370
1371         return num_services;
1372 }
1373
1374 Value HostsTable::HardStateAccessor(const Value& row)
1375 {
1376         Host::Ptr host = static_cast<Host::Ptr>(row);
1377
1378         if (!host)
1379                 return Empty;
1380
1381         if (host->GetState() == HostUp)
1382                 return HostUp;
1383         else if (host->GetStateType() == StateTypeHard)
1384                 return host->GetState();
1385
1386         return host->GetLastHardState();
1387 }
1388
1389 Value HostsTable::StalenessAccessor(const Value& row)
1390 {
1391         Host::Ptr host = static_cast<Host::Ptr>(row);
1392
1393         if (!host)
1394                 return Empty;
1395
1396         if (host->HasBeenChecked() && host->GetLastCheck() > 0)
1397                 return (Utility::GetTime() - host->GetLastCheck()) / (host->GetCheckInterval() * 3600);
1398
1399         return 0.0;
1400 }
1401
1402 Value HostsTable::GroupsAccessor(const Value& row)
1403 {
1404         Host::Ptr host = static_cast<Host::Ptr>(row);
1405
1406         if (!host)
1407                 return Empty;
1408
1409         Array::Ptr groups = host->GetGroups();
1410
1411         if (!groups)
1412                 return Empty;
1413
1414         return groups;
1415 }
1416
1417 Value HostsTable::ContactGroupsAccessor(const Value& row)
1418 {
1419         Host::Ptr host = static_cast<Host::Ptr>(row);
1420
1421         if (!host)
1422                 return Empty;
1423
1424         ArrayData result;
1425
1426         for (const UserGroup::Ptr& usergroup : CompatUtility::GetCheckableNotificationUserGroups(host)) {
1427                 result.push_back(usergroup->GetName());
1428         }
1429
1430         return new Array(std::move(result));
1431 }
1432
1433 Value HostsTable::ServicesAccessor(const Value& row)
1434 {
1435         Host::Ptr host = static_cast<Host::Ptr>(row);
1436
1437         if (!host)
1438                 return Empty;
1439
1440         std::vector<Service::Ptr> rservices = host->GetServices();
1441
1442         ArrayData result;
1443         result.reserve(rservices.size());
1444
1445         for (const Service::Ptr& service : rservices) {
1446                 result.push_back(service->GetShortName());
1447         }
1448
1449         return new Array(std::move(result));
1450 }
1451
1452 Value HostsTable::ServicesWithStateAccessor(const Value& row)
1453 {
1454         Host::Ptr host = static_cast<Host::Ptr>(row);
1455
1456         if (!host)
1457                 return Empty;
1458
1459         std::vector<Service::Ptr> rservices = host->GetServices();
1460
1461         ArrayData result;
1462         result.reserve(rservices.size());
1463
1464         for (const Service::Ptr& service : rservices) {
1465                 result.push_back(new Array({
1466                         service->GetShortName(),
1467                         service->GetState(),
1468                         service->HasBeenChecked() ? 1 : 0
1469                 }));
1470         }
1471
1472         return new Array(std::move(result));
1473 }
1474
1475 Value HostsTable::ServicesWithInfoAccessor(const Value& row)
1476 {
1477         Host::Ptr host = static_cast<Host::Ptr>(row);
1478
1479         if (!host)
1480                 return Empty;
1481
1482         std::vector<Service::Ptr> rservices = host->GetServices();
1483
1484         ArrayData result;
1485         result.reserve(rservices.size());
1486
1487         for (const Service::Ptr& service : rservices) {
1488                 String output;
1489                 CheckResult::Ptr cr = service->GetLastCheckResult();
1490
1491                 if (cr)
1492                         output = CompatUtility::GetCheckResultOutput(cr);
1493
1494                 result.push_back(new Array({
1495                         service->GetShortName(),
1496                         service->GetState(),
1497                         service->HasBeenChecked() ? 1 : 0,
1498                         output
1499                 }));
1500         }
1501
1502         return new Array(std::move(result));
1503 }
1504
1505 Value HostsTable::CheckSourceAccessor(const Value& row)
1506 {
1507         Host::Ptr host = static_cast<Host::Ptr>(row);
1508
1509         if (!host)
1510                 return Empty;
1511
1512         CheckResult::Ptr cr = host->GetLastCheckResult();
1513
1514         if (cr)
1515                 return cr->GetCheckSource();
1516
1517         return Empty;
1518 }
1519
1520 Value HostsTable::IsReachableAccessor(const Value& row)
1521 {
1522         Host::Ptr host = static_cast<Host::Ptr>(row);
1523
1524         if (!host)
1525                 return Empty;
1526
1527         return host->IsReachable();
1528 }
1529
1530 Value HostsTable::OriginalAttributesAccessor(const Value& row)
1531 {
1532         Host::Ptr host = static_cast<Host::Ptr>(row);
1533
1534         if (!host)
1535                 return Empty;
1536
1537         return JsonEncode(host->GetOriginalAttributes());
1538 }