2 ** nxdbmgr - NetXMS database manager
3 ** Copyright (C) 2004-2016 Victor Kirhenshtein
5 ** This program is free software; you can redistribute it and/or modify
6 ** it under the terms of the GNU General Public License as published by
7 ** the Free Software Foundation; either version 2 of the License, or
8 ** (at your option) any later version.
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.
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
17 ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
30 static int m_iNumErrors
= 0;
31 static int m_iNumFixes
= 0;
32 static int m_iStageErrors
;
33 static int m_iStageFixes
;
34 static TCHAR
*m_pszStageMsg
= NULL
;
39 static void StartStage(const TCHAR
*pszMsg
)
43 safe_free(m_pszStageMsg
);
44 m_pszStageMsg
= _tcsdup(pszMsg
);
46 WriteToTerminalEx(_T("\x1b[1m*\x1b[0m %-67s"), m_pszStageMsg
);
50 m_iStageErrors
= m_iNumErrors
;
51 m_iStageFixes
= m_iNumFixes
;
57 static void EndStage()
59 static const TCHAR
*pszStatus
[] = { _T("PASSED"), _T("FIXED "), _T("ERROR ") };
60 static int nColor
[] = { 32, 33, 31 };
63 nErrors
= m_iNumErrors
- m_iStageErrors
;
66 nCode
= (m_iNumFixes
- m_iStageFixes
== nErrors
) ? 1 : 2;
67 StartStage(NULL
); // redisplay stage message
73 WriteToTerminalEx(_T(" \x1b[37;1m[\x1b[%d;1m%s\x1b[37;1m]\x1b[0m\n"), nColor
[nCode
], pszStatus
[nCode
]);
77 * Get object name from object_properties table
79 static TCHAR
*GetObjectName(DWORD dwId
, TCHAR
*pszBuffer
)
84 _sntprintf(szQuery
, 256, _T("SELECT name FROM object_properties WHERE object_id=%d"), dwId
);
85 hResult
= SQLSelect(szQuery
);
88 if (DBGetNumRows(hResult
) > 0)
90 DBGetField(hResult
, 0, 0, pszBuffer
, MAX_OBJECT_NAME
);
94 _tcscpy(pszBuffer
, _T("<unknown>"));
99 _tcscpy(pszBuffer
, _T("<unknown>"));
105 * Check that given node is inside at least one container or cluster
107 static bool NodeInContainer(DWORD id
)
113 _sntprintf(query
, 256, _T("SELECT container_id FROM container_members WHERE object_id=%d"), id
);
114 hResult
= SQLSelect(query
);
117 result
= (DBGetNumRows(hResult
) > 0);
118 DBFreeResult(hResult
);
123 _sntprintf(query
, 256, _T("SELECT cluster_id FROM cluster_members WHERE node_id=%d"), id
);
124 hResult
= SQLSelect(query
);
127 result
= (DBGetNumRows(hResult
) > 0);
128 DBFreeResult(hResult
);
136 * Find subnet for unlinked node
138 static BOOL
FindSubnetForNode(DWORD id
, const TCHAR
*name
)
140 DB_RESULT hResult
, hResult2
;
141 TCHAR query
[256], buffer
[32];
143 BOOL success
= FALSE
;
145 // Read list of interfaces of given node
146 _sntprintf(query
, 256, _T("SELECT l.ip_addr,l.ip_netmask FROM interfaces i INNER JOIN interface_address_list l ON l.iface_id = i.id WHERE node_id=%d"), id
);
147 hResult
= SQLSelect(query
);
150 count
= DBGetNumRows(hResult
);
151 for(i
= 0; i
< count
; i
++)
153 InetAddress addr
= DBGetFieldInetAddr(hResult
, i
, 0);
154 addr
.setMaskBits(DBGetFieldLong(hResult
, i
, 1));
155 InetAddress subnet
= addr
.getSubnetAddress();
157 _sntprintf(query
, 256, _T("SELECT id FROM subnets WHERE ip_addr='%s'"), subnet
.toString(buffer
));
158 hResult2
= SQLSelect(query
);
159 if (hResult2
!= NULL
)
161 if (DBGetNumRows(hResult2
) > 0)
163 UINT32 subnetId
= DBGetFieldULong(hResult2
, 0, 0);
165 if (GetYesNo(_T("\rUnlinked node object %d (\"%s\") can be linked to subnet %d (%s). Link?"), id
, name
, subnetId
, buffer
))
167 _sntprintf(query
, 256, _T("INSERT INTO nsmap (subnet_id,node_id) VALUES (%d,%d)"), subnetId
, id
);
176 // Node remains unlinked, so error count will be
177 // incremented again by node deletion code or next iteration
183 // Node remains unlinked, so error count will be
184 // incremented again by node deletion code
188 DBFreeResult(hResult2
);
191 DBFreeResult(hResult
);
199 static void CheckZones()
201 DB_RESULT hResult
, hResult2
;
202 DWORD i
, dwNumObjects
, dwId
;
205 StartStage(_T("Checking zone objects..."));
206 hResult
= SQLSelect(_T("SELECT id FROM zones"));
209 dwNumObjects
= DBGetNumRows(hResult
);
210 for(i
= 0; i
< dwNumObjects
; i
++)
212 dwId
= DBGetFieldULong(hResult
, i
, 0);
214 // Check appropriate record in object_properties table
215 _sntprintf(szQuery
, 256, _T("SELECT name,is_deleted FROM object_properties WHERE object_id=%d"), (int)dwId
);
216 hResult2
= SQLSelect(szQuery
);
217 if (hResult2
!= NULL
)
219 if ((DBGetNumRows(hResult2
) == 0) && (dwId
!= 4)) // Properties for built-in zone can be missing
222 if (GetYesNo(_T("\rMissing zone object %d properties. Create?"), dwId
))
227 _uuid_generate(guid
);
228 _sntprintf(szQuery
, 1024,
229 _T("INSERT INTO object_properties (object_id,guid,name,")
230 _T("status,is_deleted,is_system,inherit_access_rights,")
231 _T("last_modified,status_calc_alg,status_prop_alg,")
232 _T("status_fixed_val,status_shift,status_translation,")
233 _T("status_single_threshold,status_thresholds,location_type,")
234 _T("latitude,longitude,image,maint_mode,maint_event_id) VALUES ")
235 _T("(%d,'%s','lost_zone_%d',5,0,0,1,") TIME_T_FMT
_T(",0,0,0,0,0,0,'00000000',0,")
236 _T("'0.000000','0.000000','00000000-0000-0000-0000-000000000000','0',0)"),
237 (int)dwId
, _uuid_to_string(guid
, guidText
), (int)dwId
, TIME_T_FCAST(time(NULL
)));
238 if (SQLQuery(szQuery
))
242 DBFreeResult(hResult2
);
245 DBFreeResult(hResult
);
253 static void CheckNodes()
255 DB_RESULT hResult
, hResult2
;
256 DWORD i
, dwNumObjects
, dwId
;
257 TCHAR szQuery
[1024], szName
[MAX_OBJECT_NAME
];
258 BOOL bResult
, bIsDeleted
= FALSE
;
260 StartStage(_T("Checking node objects..."));
261 hResult
= SQLSelect(_T("SELECT id,primary_ip FROM nodes"));
264 dwNumObjects
= DBGetNumRows(hResult
);
265 for(i
= 0; i
< dwNumObjects
; i
++)
267 dwId
= DBGetFieldULong(hResult
, i
, 0);
269 // Check appropriate record in object_properties table
270 _sntprintf(szQuery
, 256, _T("SELECT name,is_deleted FROM object_properties WHERE object_id=%d"), dwId
);
271 hResult2
= SQLSelect(szQuery
);
272 if (hResult2
!= NULL
)
274 if (DBGetNumRows(hResult2
) == 0)
277 if (GetYesNo(_T("\rMissing node object %d properties. Create?"), dwId
))
282 _uuid_generate(guid
);
283 _sntprintf(szQuery
, 1024,
284 _T("INSERT INTO object_properties (object_id,guid,name,")
285 _T("status,is_deleted,is_system,inherit_access_rights,")
286 _T("last_modified,status_calc_alg,status_prop_alg,")
287 _T("status_fixed_val,status_shift,status_translation,")
288 _T("status_single_threshold,status_thresholds,location_type,")
289 _T("latitude,longitude,location_accuracy,location_timestamp,")
290 _T("image,submap_id,maint_mode,maint_event_id) VALUES ")
291 _T("(%d,'%s','lost_node_%d',5,0,0,1,") TIME_T_FMT
_T(",0,0,0,0,0,0,'00000000',0,")
292 _T("'0.000000','0.000000',0,0,'00000000-0000-0000-0000-000000000000',0,'0',0)"),
293 (int)dwId
, _uuid_to_string(guid
, guidText
), (int)dwId
, TIME_T_FCAST(time(NULL
)));
294 if (SQLQuery(szQuery
))
300 DBGetField(hResult2
, 0, 0, szName
, MAX_OBJECT_NAME
);
301 bIsDeleted
= DBGetFieldLong(hResult2
, 0, 1) ? TRUE
: FALSE
;
303 DBFreeResult(hResult2
);
308 _sntprintf(szQuery
, 1024, _T("SELECT subnet_id FROM nsmap WHERE node_id=%d"), dwId
);
309 hResult2
= SQLSelect(szQuery
);
310 if (hResult2
!= NULL
)
312 if ((DBGetNumRows(hResult2
) == 0) && (!NodeInContainer(dwId
)))
314 if ((DBGetFieldIPAddr(hResult
, i
, 1) == 0) || (!FindSubnetForNode(dwId
, szName
)))
317 if (GetYesNo(_T("\rUnlinked node object %d (\"%s\"). Delete it?"), dwId
, szName
))
319 _sntprintf(szQuery
, 1024, _T("DELETE FROM nodes WHERE id=%d"), dwId
);
320 bResult
= SQLQuery(szQuery
);
321 _sntprintf(szQuery
, 1024, _T("DELETE FROM acl WHERE object_id=%d"), dwId
);
322 bResult
= bResult
&& SQLQuery(szQuery
);
323 _sntprintf(szQuery
, 1024, _T("DELETE FROM object_properties WHERE object_id=%d"), dwId
);
324 if (SQLQuery(szQuery
) && bResult
)
329 DBFreeResult(hResult2
);
333 DBFreeResult(hResult
);
339 * Check node component objects
341 static void CheckComponents(const TCHAR
*pszDisplayName
, const TCHAR
*pszTable
)
343 DB_RESULT hResult
, hResult2
;
344 DWORD i
, dwNumObjects
, dwId
;
345 TCHAR szQuery
[1024], szName
[MAX_OBJECT_NAME
];
347 _sntprintf(szQuery
, 1024, _T("Checking %s objects..."), pszDisplayName
);
350 _sntprintf(szQuery
, 1024, _T("SELECT id,node_id FROM %s"), pszTable
);
351 hResult
= SQLSelect(szQuery
);
354 dwNumObjects
= DBGetNumRows(hResult
);
355 for(i
= 0; i
< dwNumObjects
; i
++)
357 dwId
= DBGetFieldULong(hResult
, i
, 0);
359 // Check appropriate record in object_properties table
360 _sntprintf(szQuery
, 1024, _T("SELECT name,is_deleted FROM object_properties WHERE object_id=%d"), dwId
);
361 hResult2
= SQLSelect(szQuery
);
362 if (hResult2
!= NULL
)
364 if (DBGetNumRows(hResult2
) == 0)
367 if (GetYesNo(_T("\rMissing %s object %d properties. Create?"), pszDisplayName
, dwId
))
372 _uuid_generate(guid
);
373 _sntprintf(szQuery
, 1024,
374 _T("INSERT INTO object_properties (object_id,guid,name,")
375 _T("status,is_deleted,is_system,inherit_access_rights,")
376 _T("last_modified,status_calc_alg,status_prop_alg,")
377 _T("status_fixed_val,status_shift,status_translation,")
378 _T("status_single_threshold,status_thresholds,location_type,")
379 _T("latitude,longitude,image,maint_mode,maint_event_id) VALUES ")
380 _T("(%d,'%s','lost_%s_%d',5,0,0,1,") TIME_T_FMT
_T(",0,0,0,0,0,0,'00000000',0,")
381 _T("'0.000000','0.000000','00000000-0000-0000-0000-000000000000','0',0)"),
382 (int)dwId
, _uuid_to_string(guid
, guidText
), pszDisplayName
, (int)dwId
, TIME_T_FCAST(time(NULL
)));
383 if (SQLQuery(szQuery
))
390 DBGetField(hResult2
, 0, 0, szName
, MAX_OBJECT_NAME
);
392 DBFreeResult(hResult2
);
399 // Check if referred node exists
400 _sntprintf(szQuery
, 256, _T("SELECT name FROM object_properties WHERE object_id=%d AND is_deleted=0"),
401 DBGetFieldULong(hResult
, i
, 1));
402 hResult2
= SQLSelect(szQuery
);
403 if (hResult2
!= NULL
)
405 if (DBGetNumRows(hResult2
) == 0)
408 dwId
= DBGetFieldULong(hResult
, i
, 0);
409 if (GetYesNo(_T("\rUnlinked %s object %d (\"%s\"). Delete it?"), pszDisplayName
, dwId
, szName
))
411 _sntprintf(szQuery
, 256, _T("DELETE FROM %s WHERE id=%d"), pszTable
, dwId
);
412 if (SQLQuery(szQuery
))
414 _sntprintf(szQuery
, 256, _T("DELETE FROM object_properties WHERE object_id=%d"), dwId
);
420 DBFreeResult(hResult2
);
423 DBFreeResult(hResult
);
429 * Check common object properties
431 static void CheckObjectProperties()
435 DWORD i
, dwNumRows
, dwObjectId
;
437 StartStage(_T("Checking object properties..."));
438 hResult
= SQLSelect(_T("SELECT object_id,name,last_modified FROM object_properties"));
441 dwNumRows
= DBGetNumRows(hResult
);
442 for(i
= 0; i
< dwNumRows
; i
++)
444 dwObjectId
= DBGetFieldULong(hResult
, i
, 0);
446 // Check last change time
447 if (DBGetFieldULong(hResult
, i
, 2) == 0)
450 if (GetYesNo(_T("\rObject %d [%s] has invalid timestamp. Fix it?"),
451 dwObjectId
, DBGetField(hResult
, i
, 1, szQuery
, 1024)))
453 _sntprintf(szQuery
, 1024, _T("UPDATE object_properties SET last_modified=") TIME_T_FMT
_T(" WHERE object_id=%d"),
454 TIME_T_FCAST(time(NULL
)), (int)dwObjectId
);
455 if (SQLQuery(szQuery
))
460 DBFreeResult(hResult
);
466 * Check cluster objects
468 static void CheckClusters()
471 TCHAR szQuery
[256], szName
[MAX_OBJECT_NAME
];
472 DWORD i
, dwNumRows
, dwObjectId
, dwId
;
474 StartStage(_T("Checking cluster objects..."));
475 hResult
= SQLSelect(_T("SELECT cluster_id,node_id FROM cluster_members"));
478 dwNumRows
= DBGetNumRows(hResult
);
479 for(i
= 0; i
< dwNumRows
; i
++)
481 dwObjectId
= DBGetFieldULong(hResult
, i
, 1);
482 if (!IsDatabaseRecordExist(_T("nodes"), _T("id"), dwObjectId
))
485 dwId
= DBGetFieldULong(hResult
, i
, 0);
486 if (GetYesNo(_T("\rCluster object %s [%d] refers to non-existing node %d. Dereference?"),
487 GetObjectName(dwId
, szName
), dwId
, dwObjectId
))
489 _sntprintf(szQuery
, 256, _T("DELETE FROM cluster_members WHERE cluster_id=%d AND node_id=%d"),dwId
, dwObjectId
);
490 if (SQLQuery(szQuery
))
497 DBFreeResult(hResult
);
503 * Returns TRUE if SELECT returns non-empty set
505 static BOOL
CheckResultSet(TCHAR
*pszQuery
)
508 BOOL bResult
= FALSE
;
510 hResult
= SQLSelect(pszQuery
);
513 bResult
= (DBGetNumRows(hResult
) > 0);
514 DBFreeResult(hResult
);
520 * Check event processing policy
522 static void CheckEPP()
529 StartStage(_T("Checking event processing policy..."));
531 // Check source object ID's
532 hResult
= SQLSelect(_T("SELECT object_id FROM policy_source_list"));
535 iNumRows
= DBGetNumRows(hResult
);
536 for(i
= 0; i
< iNumRows
; i
++)
538 dwId
= DBGetFieldULong(hResult
, i
, 0);
539 _sntprintf(szQuery
, 1024, _T("SELECT object_id FROM object_properties WHERE object_id=%d"), dwId
);
540 if (!CheckResultSet(szQuery
))
543 if (GetYesNo(_T("\rInvalid object ID %d used in policy. Delete it from policy?"), dwId
))
545 _sntprintf(szQuery
, 1024, _T("DELETE FROM policy_source_list WHERE object_id=%d"), dwId
);
546 if (SQLQuery(szQuery
))
551 DBFreeResult(hResult
);
555 hResult
= SQLSelect(_T("SELECT event_code FROM policy_event_list"));
558 iNumRows
= DBGetNumRows(hResult
);
559 for(i
= 0; i
< iNumRows
; i
++)
561 dwId
= DBGetFieldULong(hResult
, i
, 0);
562 if (dwId
& GROUP_FLAG
)
563 _sntprintf(szQuery
, 1024, _T("SELECT id FROM event_groups WHERE id=%d"), dwId
);
565 _sntprintf(szQuery
, 1024, _T("SELECT event_code FROM event_cfg WHERE event_code=%d"), dwId
);
566 if (!CheckResultSet(szQuery
))
569 if (GetYesNo(_T("\rInvalid event%s ID 0x%08X referenced in policy. Delete this reference?"), (dwId
& GROUP_FLAG
) ? _T(" group") : _T(""), dwId
))
571 _sntprintf(szQuery
, 1024, _T("DELETE FROM policy_event_list WHERE event_code=%d"), dwId
);
572 if (SQLQuery(szQuery
))
577 DBFreeResult(hResult
);
581 hResult
= SQLSelect(_T("SELECT action_id FROM policy_action_list"));
584 iNumRows
= DBGetNumRows(hResult
);
585 for(i
= 0; i
< iNumRows
; i
++)
587 dwId
= DBGetFieldULong(hResult
, i
, 0);
588 _sntprintf(szQuery
, 1024, _T("SELECT action_id FROM actions WHERE action_id=%d"), dwId
);
589 if (!CheckResultSet(szQuery
))
592 if (GetYesNo(_T("\rInvalid action ID %d referenced in policy. Delete this reference?"), dwId
))
594 _sntprintf(szQuery
, 1024, _T("DELETE FROM policy_action_list WHERE action_id=%d"), dwId
);
595 if (SQLQuery(szQuery
))
600 DBFreeResult(hResult
);
607 * Create idata_xx table
609 BOOL
CreateIDataTable(DWORD nodeId
)
611 TCHAR szQuery
[256], szQueryTemplate
[256];
614 MetaDataReadStr(_T("IDataTableCreationCommand"), szQueryTemplate
, 255, _T(""));
615 _sntprintf(szQuery
, 256, szQueryTemplate
, nodeId
);
616 if (!SQLQuery(szQuery
))
619 for(i
= 0; i
< 10; i
++)
621 _sntprintf(szQuery
, 256, _T("IDataIndexCreationCommand_%d"), i
);
622 MetaDataReadStr(szQuery
, szQueryTemplate
, 255, _T(""));
623 if (szQueryTemplate
[0] != 0)
625 _sntprintf(szQuery
, 256, szQueryTemplate
, nodeId
, nodeId
);
626 if (!SQLQuery(szQuery
))
635 * Create tdata_xx table - pre V281 version
637 BOOL
CreateTDataTable_preV281(DWORD nodeId
)
639 TCHAR szQuery
[256], szQueryTemplate
[256];
642 MetaDataReadStr(_T("TDataTableCreationCommand"), szQueryTemplate
, 255, _T(""));
643 _sntprintf(szQuery
, 256, szQueryTemplate
, nodeId
);
644 if (!SQLQuery(szQuery
))
647 for(i
= 0; i
< 10; i
++)
649 _sntprintf(szQuery
, 256, _T("TDataIndexCreationCommand_%d"), i
);
650 MetaDataReadStr(szQuery
, szQueryTemplate
, 255, _T(""));
651 if (szQueryTemplate
[0] != 0)
653 _sntprintf(szQuery
, 256, szQueryTemplate
, nodeId
, nodeId
);
654 if (!SQLQuery(szQuery
))
663 * Create tdata_xx table
665 BOOL
CreateTDataTable(DWORD nodeId
)
667 TCHAR szQuery
[256], szQueryTemplate
[256];
670 for(i
= 0; i
< 10; i
++)
672 _sntprintf(szQuery
, 256, _T("TDataTableCreationCommand_%d"), i
);
673 MetaDataReadStr(szQuery
, szQueryTemplate
, 255, _T(""));
674 if (szQueryTemplate
[0] != 0)
676 _sntprintf(szQuery
, 256, szQueryTemplate
, nodeId
, nodeId
);
677 if (!SQLQuery(szQuery
))
682 for(i
= 0; i
< 10; i
++)
684 _sntprintf(szQuery
, 256, _T("TDataIndexCreationCommand_%d"), i
);
685 MetaDataReadStr(szQuery
, szQueryTemplate
, 255, _T(""));
686 if (szQueryTemplate
[0] != 0)
688 _sntprintf(szQuery
, 256, szQueryTemplate
, nodeId
, nodeId
);
689 if (!SQLQuery(szQuery
))
698 * Check collected data
700 static void CheckIData()
706 DB_RESULT hResultNodes
, hResult
;
708 StartStage(_T("Checking collected data..."));
711 hResultNodes
= SQLSelect(_T("SELECT id FROM nodes"));
712 if (hResultNodes
!= NULL
)
714 nodeCount
= DBGetNumRows(hResultNodes
);
715 for(i
= 0; i
< nodeCount
; i
++)
717 nodeId
= DBGetFieldULong(hResultNodes
, i
, 0);
718 _sntprintf(query
, 1024, _T("SELECT count(*) FROM idata_%d WHERE idata_timestamp>") TIME_T_FMT
, nodeId
, TIME_T_FCAST(now
));
719 hResult
= SQLSelect(query
);
722 if (DBGetFieldLong(hResult
, 0, 0) > 0)
725 if (GetYesNo(_T("\rFound collected data for node [%d] with timestamp in the future. Delete them?"), nodeId
))
727 _sntprintf(query
, 1024, _T("DELETE FROM idata_%d WHERE idata_timestamp>") TIME_T_FMT
, nodeId
, TIME_T_FCAST(now
));
732 DBFreeResult(hResult
);
735 DBFreeResult(hResultNodes
);
738 _sntprintf(query
, 1024, _T("SELECT count(*) FROM raw_dci_values WHERE last_poll_time>") TIME_T_FMT
, TIME_T_FCAST(now
));
739 hResult
= SQLSelect(query
);
742 if (DBGetFieldLong(hResult
, 0, 0) > 0)
745 if (GetYesNo(_T("\rFound DCIs with last poll timestamp in the future. Fix it?")))
747 _sntprintf(query
, 1024, _T("UPDATE raw_dci_values SET last_poll_time=") TIME_T_FMT
_T(" WHERE last_poll_time>") TIME_T_FMT
, TIME_T_FCAST(now
), TIME_T_FCAST(now
));
752 DBFreeResult(hResult
);
759 * Check if given data table exist
761 bool IsDataTableExist(const TCHAR
*format
, UINT32 id
)
764 _sntprintf(table
, 256, format
, id
);
765 int rc
= DBIsTableExist(g_hCoreDB
, table
);
766 if (rc
== DBIsTableExist_Failure
)
768 _tprintf(_T("WARNING: call to DBIsTableExist(\"%s\") failed\n"), table
);
770 return rc
!= DBIsTableExist_NotFound
;
774 * Check data tables for given o bject class
776 static void CheckDataTablesForClass(const TCHAR
*className
, const TCHAR
*classDescr
)
779 _sntprintf(query
, 256, _T("SELECT id FROM %s"), className
);
780 DB_RESULT hResult
= SQLSelect(query
);
783 int count
= DBGetNumRows(hResult
);
784 for(int i
= 0; i
< count
; i
++)
786 DWORD id
= DBGetFieldULong(hResult
, i
, 0);
789 if (!IsDataTableExist(_T("idata_%d"), id
))
792 if (GetYesNo(_T("\rData collection table (IDATA) for %s [%d] not found. Create? (Y/N) "), classDescr
, id
))
794 if (CreateIDataTable(id
))
800 if (!IsDataTableExist(_T("tdata_%d"), id
))
803 if (GetYesNo(_T("\rData collection table (TDATA) for %s [%d] not found. Create? (Y/N) "), classDescr
, id
))
805 if (CreateTDataTable(id
))
810 DBFreeResult(hResult
);
817 static void CheckDataTables()
819 StartStage(_T("Checking data tables..."));
821 CheckDataTablesForClass(_T("nodes"), _T("node"));
822 CheckDataTablesForClass(_T("clusters"), _T("cluster"));
823 CheckDataTablesForClass(_T("mobile_devices"), _T("mobile device"));
824 CheckDataTablesForClass(_T("access_points"), _T("access point"));
825 CheckDataTablesForClass(_T("chassis"), _T("chassis"));
831 * Check template to node mapping
833 static void CheckTemplateNodeMapping()
836 TCHAR name
[256], query
[256];
837 DWORD i
, dwNumRows
, dwTemplateId
, dwNodeId
;
839 StartStage(_T("Checking template to node mapping..."));
840 hResult
= SQLSelect(_T("SELECT template_id,node_id FROM dct_node_map ORDER BY template_id"));
843 dwNumRows
= DBGetNumRows(hResult
);
844 for(i
= 0; i
< dwNumRows
; i
++)
846 dwTemplateId
= DBGetFieldULong(hResult
, i
, 0);
847 dwNodeId
= DBGetFieldULong(hResult
, i
, 1);
849 // Check node existence
850 if (!IsDatabaseRecordExist(_T("nodes"), _T("id"), dwNodeId
) &&
851 !IsDatabaseRecordExist(_T("clusters"), _T("id"), dwNodeId
) &&
852 !IsDatabaseRecordExist(_T("mobile_devices"), _T("id"), dwNodeId
))
855 GetObjectName(dwTemplateId
, name
);
856 if (GetYesNo(_T("\rTemplate %d [%s] mapped to non-existent node %d. Delete this mapping?"), dwTemplateId
, name
, dwNodeId
))
858 _sntprintf(query
, 256, _T("DELETE FROM dct_node_map WHERE template_id=%d AND node_id=%d"),
859 dwTemplateId
, dwNodeId
);
865 DBFreeResult(hResult
);
871 * Check network map links
873 static void CheckMapLinks()
875 StartStage(_T("Checking network map links..."));
877 for(int pass
= 1; pass
<= 2; pass
++)
880 _sntprintf(query
, 1024,
881 _T("SELECT network_map_links.map_id,network_map_links.element1,network_map_links.element2 ")
882 _T("FROM network_map_links ")
883 _T("LEFT OUTER JOIN network_map_elements ON ")
884 _T(" network_map_links.map_id = network_map_elements.map_id AND ")
885 _T(" network_map_links.element%d = network_map_elements.element_id ")
886 _T("WHERE network_map_elements.element_id IS NULL"), pass
);
888 DB_RESULT hResult
= SQLSelect(query
);
891 int count
= DBGetNumRows(hResult
);
892 for(int i
= 0; i
< count
; i
++)
895 DWORD mapId
= DBGetFieldULong(hResult
, i
, 0);
896 TCHAR name
[MAX_OBJECT_NAME
];
897 GetObjectName(mapId
, name
);
898 if (GetYesNo(_T("\rInvalid link on network map %s [%d]. Delete?"), name
, mapId
))
900 _sntprintf(query
, 256, _T("DELETE FROM network_map_links WHERE map_id=%d AND element1=%d AND element2=%d"),
901 mapId
, DBGetFieldLong(hResult
, i
, 1), DBGetFieldLong(hResult
, i
, 2));
906 DBFreeResult(hResult
);
913 * Check database for errors
919 BOOL bCompleted
= FALSE
;
921 if (g_checkDataTablesOnly
)
922 _tprintf(_T("Checking database (data tables only):\n"));
924 _tprintf(_T("Checking database (%s collected data):\n"), g_checkData
? _T("including") : _T("excluding"));
926 // Get database format version
927 iVersion
= DBGetSchemaVersion(g_hCoreDB
);
928 if ((iVersion
< DB_FORMAT_VERSION
) && !g_checkDataTablesOnly
)
930 _tprintf(_T("Your database has format version %d, this tool is compiled for version %d.\nUse \"upgrade\" command to upgrade your database first.\n"),
931 iVersion
, DB_FORMAT_VERSION
);
933 else if (iVersion
> DB_FORMAT_VERSION
)
935 _tprintf(_T("Your database has format version %d, this tool is compiled for version %d.\n")
936 _T("You need to upgrade your server before using this database.\n"),
937 iVersion
, DB_FORMAT_VERSION
);
942 TCHAR szLockStatus
[MAX_DB_STRING
], szLockInfo
[MAX_DB_STRING
];
943 BOOL bLocked
= FALSE
;
945 // Check if database is locked
946 hResult
= DBSelect(g_hCoreDB
, _T("SELECT var_value FROM config WHERE var_name='DBLockStatus'"));
949 if (DBGetNumRows(hResult
) > 0)
951 DBGetField(hResult
, 0, 0, szLockStatus
, MAX_DB_STRING
);
952 DecodeSQLString(szLockStatus
);
953 bLocked
= _tcscmp(szLockStatus
, _T("UNLOCKED"));
955 DBFreeResult(hResult
);
959 hResult
= DBSelect(g_hCoreDB
, _T("SELECT var_value FROM config WHERE var_name='DBLockInfo'"));
962 if (DBGetNumRows(hResult
) > 0)
964 DBGetField(hResult
, 0, 0, szLockInfo
, MAX_DB_STRING
);
965 DecodeSQLString(szLockInfo
);
967 DBFreeResult(hResult
);
973 if (GetYesNo(_T("Database is locked by server %s [%s]\nDo you wish to force database unlock?"), szLockStatus
, szLockInfo
))
975 if (SQLQuery(_T("UPDATE config SET var_value='UNLOCKED' where var_name='DBLockStatus'")))
978 _tprintf(_T("Database lock removed\n"));
987 if (g_checkDataTablesOnly
)
995 CheckComponents(_T("interface"), _T("interfaces"));
996 CheckComponents(_T("network service"), _T("network_services"));
998 CheckTemplateNodeMapping();
999 CheckObjectProperties();
1007 if (m_iNumErrors
== 0)
1009 _tprintf(_T("Database doesn't contain any errors\n"));
1010 DBCommit(g_hCoreDB
);
1014 _tprintf(_T("%d errors was found, %d errors was corrected\n"), m_iNumErrors
, m_iNumFixes
);
1015 if (m_iNumFixes
== m_iNumErrors
)
1016 _tprintf(_T("All errors in database was fixed\n"));
1018 _tprintf(_T("Database still contain errors\n"));
1019 if (m_iNumFixes
> 0)
1021 if (GetYesNo(_T("Commit changes?")))
1023 _tprintf(_T("Committing changes...\n"));
1024 if (DBCommit(g_hCoreDB
))
1025 _tprintf(_T("Changes was successfully committed to database\n"));
1029 _tprintf(_T("Rolling back changes...\n"));
1030 if (DBRollback(g_hCoreDB
))
1031 _tprintf(_T("All changes made to database was cancelled\n"));
1036 DBRollback(g_hCoreDB
);
1044 _tprintf(_T("Unable to get database lock status\n"));
1048 _tprintf(_T("Database check %s\n"), bCompleted
? _T("completed") : _T("aborted"));