min/max calls replaced with std::min/std::max
[public/netxms.git] / src / server / core / id.cpp
1 /*
2 ** NetXMS - Network Management System
3 ** Copyright (C) 2003-2013 Victor Kirhenshtein
4 **
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.
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
17 ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 **
19 ** File: id.cpp
20 **
21 **/
22
23 #include "nxcore.h"
24
25 /**
26 * Constants
27 */
28 #define NUMBER_OF_GROUPS 25
29
30 /**
31 * Static data
32 */
33 static MUTEX s_mutexTableAccess;
34 static UINT32 s_freeIdTable[NUMBER_OF_GROUPS] = { 100, FIRST_USER_EVENT_ID, 1, 1,
35 1, 1, 0x80000000,
36 1, 1, 0x80000001, 1, 1, 1, 1,
37 10000, 10000, 1, 1, 1, 1, 1, 1, 1
38 };
39 static UINT32 s_idLimits[NUMBER_OF_GROUPS] = { 0xFFFFFFFE, 0x7FFFFFFF, 0x7FFFFFFF,
40 0x7FFFFFFF, 0xFFFFFFFE, 0x7FFFFFFF, 0xFFFFFFFF,
41 0x7FFFFFFF, 0x7FFFFFFF, 0xFFFFFFFE, 0xFFFFFFFE,
42 0xFFFFFFFE, 0xFFFFFFFE, 0xFFFFFFFE, 0xFFFFFFFE,
43 0xFFFFFFFE, 0xFFFFFFFE, 0xFFFFFFFE, 0xFFFFFFFE,
44 0x7FFFFFFE, 0xFFFFFFFE, 0xFFFFFFFE, 0xFFFFFFFE
45 };
46 static UINT64 m_freeEventId = 1;
47 static const TCHAR *m_pszGroupNames[NUMBER_OF_GROUPS] =
48 {
49 _T("Network Objects"),
50 _T("Events"),
51 _T("Data Collection Items"),
52 _T("SNMP Trap"),
53 _T("Jobs"),
54 _T("Actions"),
55 _T("Event Groups"),
56 _T("Data Collection Thresholds"),
57 _T("Users"),
58 _T("User Groups"),
59 _T("Alarms"),
60 _T("Alarm Notes"),
61 _T("Packages"),
62 _T("SLM Ticket"),
63 _T("Object Tools"),
64 _T("Scripts"),
65 _T("Agent Configs"),
66 _T("Graphs"),
67 _T("Certificates"),
68 _T("Table Columns"),
69 _T("Mapping Tables"),
70 _T("DCI Summary Tables"),
71 _T("Scheduled Tasks")
72 _T("Alarm categories")
73 };
74
75 /**
76 * Initialize ID table
77 */
78 BOOL InitIdTable()
79 {
80 DB_RESULT hResult;
81
82 s_mutexTableAccess = MutexCreate();
83
84 DB_HANDLE hdb = DBConnectionPoolAcquireConnection();
85
86 // Get first available network object ID
87 UINT32 id = ConfigReadULong(_T("FirstFreeObjectId"), s_freeIdTable[IDG_NETWORK_OBJECT]);
88 if (id > s_freeIdTable[IDG_NETWORK_OBJECT])
89 s_freeIdTable[IDG_NETWORK_OBJECT] = id;
90 hResult = DBSelect(hdb, _T("SELECT max(id) FROM nodes"));
91 if (hResult != NULL)
92 {
93 if (DBGetNumRows(hResult) > 0)
94 s_freeIdTable[IDG_NETWORK_OBJECT] = std::max(s_freeIdTable[IDG_NETWORK_OBJECT],
95 DBGetFieldULong(hResult, 0, 0) + 1);
96 DBFreeResult(hResult);
97 }
98 hResult = DBSelect(hdb, _T("SELECT max(id) FROM subnets"));
99 if (hResult != NULL)
100 {
101 if (DBGetNumRows(hResult) > 0)
102 s_freeIdTable[IDG_NETWORK_OBJECT] = std::max(s_freeIdTable[IDG_NETWORK_OBJECT],
103 DBGetFieldULong(hResult, 0, 0) + 1);
104 DBFreeResult(hResult);
105 }
106 hResult = DBSelect(hdb, _T("SELECT max(id) FROM interfaces"));
107 if (hResult != NULL)
108 {
109 if (DBGetNumRows(hResult) > 0)
110 s_freeIdTable[IDG_NETWORK_OBJECT] = std::max(s_freeIdTable[IDG_NETWORK_OBJECT],
111 DBGetFieldULong(hResult, 0, 0) + 1);
112 DBFreeResult(hResult);
113 }
114 hResult = DBSelect(hdb, _T("SELECT max(id) FROM object_containers"));
115 if (hResult != NULL)
116 {
117 if (DBGetNumRows(hResult) > 0)
118 s_freeIdTable[IDG_NETWORK_OBJECT] = std::max(s_freeIdTable[IDG_NETWORK_OBJECT],
119 DBGetFieldULong(hResult, 0, 0) + 1);
120 DBFreeResult(hResult);
121 }
122 hResult = DBSelect(hdb, _T("SELECT max(id) FROM templates"));
123 if (hResult != NULL)
124 {
125 if (DBGetNumRows(hResult) > 0)
126 s_freeIdTable[IDG_NETWORK_OBJECT] = std::max(s_freeIdTable[IDG_NETWORK_OBJECT],
127 DBGetFieldULong(hResult, 0, 0) + 1);
128 DBFreeResult(hResult);
129 }
130 hResult = DBSelect(hdb, _T("SELECT max(id) FROM network_services"));
131 if (hResult != NULL)
132 {
133 if (DBGetNumRows(hResult) > 0)
134 s_freeIdTable[IDG_NETWORK_OBJECT] = std::max(s_freeIdTable[IDG_NETWORK_OBJECT],
135 DBGetFieldULong(hResult, 0, 0) + 1);
136 DBFreeResult(hResult);
137 }
138 hResult = DBSelect(hdb, _T("SELECT max(id) FROM conditions"));
139 if (hResult != NULL)
140 {
141 if (DBGetNumRows(hResult) > 0)
142 s_freeIdTable[IDG_NETWORK_OBJECT] = std::max(s_freeIdTable[IDG_NETWORK_OBJECT],
143 DBGetFieldULong(hResult, 0, 0) + 1);
144 DBFreeResult(hResult);
145 }
146 hResult = DBSelect(hdb, _T("SELECT max(id) FROM clusters"));
147 if (hResult != NULL)
148 {
149 if (DBGetNumRows(hResult) > 0)
150 s_freeIdTable[IDG_NETWORK_OBJECT] = std::max(s_freeIdTable[IDG_NETWORK_OBJECT],
151 DBGetFieldULong(hResult, 0, 0) + 1);
152 DBFreeResult(hResult);
153 }
154 hResult = DBSelect(hdb, _T("SELECT max(id) FROM ap_common"));
155 if (hResult != NULL)
156 {
157 if (DBGetNumRows(hResult) > 0)
158 s_freeIdTable[IDG_NETWORK_OBJECT] = std::max(s_freeIdTable[IDG_NETWORK_OBJECT],
159 DBGetFieldULong(hResult, 0, 0) + 1);
160 DBFreeResult(hResult);
161 }
162 hResult = DBSelect(hdb, _T("SELECT max(id) FROM network_maps"));
163 if (hResult != NULL)
164 {
165 if (DBGetNumRows(hResult) > 0)
166 s_freeIdTable[IDG_NETWORK_OBJECT] = std::max(s_freeIdTable[IDG_NETWORK_OBJECT],
167 DBGetFieldULong(hResult, 0, 0) + 1);
168 DBFreeResult(hResult);
169 }
170 hResult = DBSelect(hdb, _T("SELECT max(id) FROM dashboards"));
171 if (hResult != NULL)
172 {
173 if (DBGetNumRows(hResult) > 0)
174 s_freeIdTable[IDG_NETWORK_OBJECT] = std::max(s_freeIdTable[IDG_NETWORK_OBJECT],
175 DBGetFieldULong(hResult, 0, 0) + 1);
176 DBFreeResult(hResult);
177 }
178 hResult = DBSelect(hdb, _T("SELECT max(id) FROM slm_checks"));
179 if (hResult != NULL)
180 {
181 if (DBGetNumRows(hResult) > 0)
182 s_freeIdTable[IDG_NETWORK_OBJECT] = std::max(s_freeIdTable[IDG_NETWORK_OBJECT],
183 DBGetFieldULong(hResult, 0, 0) + 1);
184 DBFreeResult(hResult);
185 }
186 hResult = DBSelect(hdb, _T("SELECT max(id) FROM mobile_devices"));
187 if (hResult != NULL)
188 {
189 if (DBGetNumRows(hResult) > 0)
190 s_freeIdTable[IDG_NETWORK_OBJECT] = std::max(s_freeIdTable[IDG_NETWORK_OBJECT],
191 DBGetFieldULong(hResult, 0, 0) + 1);
192 DBFreeResult(hResult);
193 }
194 hResult = DBSelect(hdb, _T("SELECT max(id) FROM access_points"));
195 if (hResult != NULL)
196 {
197 if (DBGetNumRows(hResult) > 0)
198 s_freeIdTable[IDG_NETWORK_OBJECT] = std::max(s_freeIdTable[IDG_NETWORK_OBJECT],
199 DBGetFieldULong(hResult, 0, 0) + 1);
200 DBFreeResult(hResult);
201 }
202 hResult = DBSelect(hdb, _T("SELECT max(id) FROM vpn_connectors"));
203 if (hResult != NULL)
204 {
205 if (DBGetNumRows(hResult) > 0)
206 s_freeIdTable[IDG_NETWORK_OBJECT] = std::max(s_freeIdTable[IDG_NETWORK_OBJECT],
207 DBGetFieldULong(hResult, 0, 0) + 1);
208 DBFreeResult(hResult);
209 }
210 hResult = DBSelect(hdb, _T("SELECT max(object_id) FROM object_properties"));
211 if (hResult != NULL)
212 {
213 if (DBGetNumRows(hResult) > 0)
214 s_freeIdTable[IDG_NETWORK_OBJECT] = std::max(s_freeIdTable[IDG_NETWORK_OBJECT],
215 DBGetFieldULong(hResult, 0, 0) + 1);
216 DBFreeResult(hResult);
217 }
218
219 // Get first available event code
220 hResult = DBSelect(hdb, _T("SELECT max(event_code) FROM event_cfg"));
221 if (hResult != NULL)
222 {
223 if (DBGetNumRows(hResult) > 0)
224 s_freeIdTable[IDG_EVENT] = std::max(s_freeIdTable[IDG_EVENT], DBGetFieldULong(hResult, 0, 0) + 1);
225 DBFreeResult(hResult);
226 }
227
228 // Get first available data collection object id
229 hResult = DBSelect(hdb, _T("SELECT max(item_id) FROM items"));
230 if (hResult != NULL)
231 {
232 if (DBGetNumRows(hResult) > 0)
233 s_freeIdTable[IDG_ITEM] = std::max(s_freeIdTable[IDG_ITEM], DBGetFieldULong(hResult, 0, 0) + 1);
234 DBFreeResult(hResult);
235 }
236 hResult = DBSelect(hdb, _T("SELECT max(item_id) FROM dc_tables"));
237 if (hResult != NULL)
238 {
239 if (DBGetNumRows(hResult) > 0)
240 s_freeIdTable[IDG_ITEM] = std::max(s_freeIdTable[IDG_ITEM], DBGetFieldULong(hResult, 0, 0) + 1);
241 DBFreeResult(hResult);
242 }
243
244 // Get first available server job id
245 hResult = DBSelect(hdb, _T("SELECT max(id) FROM job_history"));
246 if (hResult != NULL)
247 {
248 if (DBGetNumRows(hResult) > 0)
249 s_freeIdTable[IDG_JOB] = std::max(s_freeIdTable[IDG_JOB], DBGetFieldULong(hResult, 0, 0) + 1);
250 DBFreeResult(hResult);
251 }
252
253 // Get first available SNMP trap configuration record id
254 hResult = DBSelect(hdb, _T("SELECT max(trap_id) FROM snmp_trap_cfg"));
255 if (hResult != NULL)
256 {
257 if (DBGetNumRows(hResult) > 0)
258 s_freeIdTable[IDG_SNMP_TRAP] = std::max(s_freeIdTable[IDG_SNMP_TRAP], DBGetFieldULong(hResult, 0, 0) + 1);
259 DBFreeResult(hResult);
260 }
261
262 // Get first available action id
263 hResult = DBSelect(hdb, _T("SELECT max(action_id) FROM actions"));
264 if (hResult != NULL)
265 {
266 if (DBGetNumRows(hResult) > 0)
267 s_freeIdTable[IDG_ACTION] = std::max(s_freeIdTable[IDG_ACTION], DBGetFieldULong(hResult, 0, 0) + 1);
268 DBFreeResult(hResult);
269 }
270
271 // Get first available event group id
272 hResult = DBSelect(hdb, _T("SELECT max(id) FROM event_groups"));
273 if (hResult != NULL)
274 {
275 if (DBGetNumRows(hResult) > 0)
276 s_freeIdTable[IDG_EVENT_GROUP] = std::max(s_freeIdTable[IDG_EVENT_GROUP], DBGetFieldULong(hResult, 0, 0) + 1);
277 DBFreeResult(hResult);
278 }
279
280 // Get first available threshold id
281 hResult = DBSelect(hdb, _T("SELECT max(threshold_id) FROM thresholds"));
282 if (hResult != NULL)
283 {
284 if (DBGetNumRows(hResult) > 0)
285 s_freeIdTable[IDG_THRESHOLD] = std::max(s_freeIdTable[IDG_THRESHOLD],
286 DBGetFieldULong(hResult, 0, 0) + 1);
287 DBFreeResult(hResult);
288 }
289 hResult = DBSelect(hdb, _T("SELECT max(id) FROM dct_thresholds"));
290 if (hResult != NULL)
291 {
292 if (DBGetNumRows(hResult) > 0)
293 s_freeIdTable[IDG_THRESHOLD] = std::max(s_freeIdTable[IDG_THRESHOLD],
294 DBGetFieldULong(hResult, 0, 0) + 1);
295 DBFreeResult(hResult);
296 }
297
298 // Get first available user id
299 hResult = DBSelect(hdb, _T("SELECT max(id) FROM users"));
300 if (hResult != NULL)
301 {
302 if (DBGetNumRows(hResult) > 0)
303 s_freeIdTable[IDG_USER] = std::max(s_freeIdTable[IDG_USER],
304 DBGetFieldULong(hResult, 0, 0) + 1);
305 DBFreeResult(hResult);
306 }
307
308 // Get first available user group id
309 hResult = DBSelect(hdb, _T("SELECT max(id) FROM user_groups"));
310 if (hResult != NULL)
311 {
312 if (DBGetNumRows(hResult) > 0)
313 s_freeIdTable[IDG_USER_GROUP] = std::max(s_freeIdTable[IDG_USER_GROUP],
314 DBGetFieldULong(hResult, 0, 0) + 1);
315 DBFreeResult(hResult);
316 }
317
318 // Get first available alarm id
319 hResult = DBSelect(hdb, _T("SELECT max(alarm_id) FROM alarms"));
320 if (hResult != NULL)
321 {
322 if (DBGetNumRows(hResult) > 0)
323 s_freeIdTable[IDG_ALARM] = std::max(s_freeIdTable[IDG_ALARM],
324 DBGetFieldULong(hResult, 0, 0) + 1);
325 DBFreeResult(hResult);
326 }
327
328 // Get first available alarm note id
329 hResult = DBSelect(hdb, _T("SELECT max(note_id) FROM alarm_notes"));
330 if (hResult != NULL)
331 {
332 if (DBGetNumRows(hResult) > 0)
333 s_freeIdTable[IDG_ALARM_NOTE] = std::max(s_freeIdTable[IDG_ALARM_NOTE],
334 DBGetFieldULong(hResult, 0, 0) + 1);
335 DBFreeResult(hResult);
336 }
337
338 // Get first available event identifier
339 hResult = DBSelect(hdb, _T("SELECT max(event_id) FROM event_log"));
340 if (hResult != NULL)
341 {
342 if (DBGetNumRows(hResult) > 0)
343 m_freeEventId = std::max(m_freeEventId, DBGetFieldUInt64(hResult, 0, 0) + 1);
344 DBFreeResult(hResult);
345 }
346
347 // Get first available package id
348 hResult = DBSelect(hdb, _T("SELECT max(pkg_id) FROM agent_pkg"));
349 if (hResult != NULL)
350 {
351 if (DBGetNumRows(hResult) > 0)
352 s_freeIdTable[IDG_PACKAGE] = std::max(s_freeIdTable[IDG_PACKAGE],
353 DBGetFieldULong(hResult, 0, 0) + 1);
354 DBFreeResult(hResult);
355 }
356
357 // Get first available object tool id
358 hResult = DBSelect(hdb, _T("SELECT max(tool_id) FROM object_tools"));
359 if (hResult != NULL)
360 {
361 if (DBGetNumRows(hResult) > 0)
362 s_freeIdTable[IDG_OBJECT_TOOL] = std::max(s_freeIdTable[IDG_OBJECT_TOOL],
363 DBGetFieldULong(hResult, 0, 0) + 1);
364 DBFreeResult(hResult);
365 }
366
367 // Get first available script id
368 hResult = DBSelect(hdb, _T("SELECT max(script_id) FROM script_library"));
369 if (hResult != NULL)
370 {
371 if (DBGetNumRows(hResult) > 0)
372 s_freeIdTable[IDG_SCRIPT] = std::max(s_freeIdTable[IDG_SCRIPT],
373 DBGetFieldULong(hResult, 0, 0) + 1);
374 DBFreeResult(hResult);
375 }
376
377 // Get first available agent config id
378 hResult = DBSelect(hdb, _T("SELECT max(config_id) FROM agent_configs"));
379 if (hResult != NULL)
380 {
381 if (DBGetNumRows(hResult) > 0)
382 s_freeIdTable[IDG_AGENT_CONFIG] = std::max(s_freeIdTable[IDG_AGENT_CONFIG],
383 DBGetFieldULong(hResult, 0, 0) + 1);
384 DBFreeResult(hResult);
385 }
386
387 // Get first available graph id
388 hResult = DBSelect(hdb, _T("SELECT max(graph_id) FROM graphs"));
389 if (hResult != NULL)
390 {
391 if (DBGetNumRows(hResult) > 0)
392 s_freeIdTable[IDG_GRAPH] = std::max(s_freeIdTable[IDG_GRAPH],
393 DBGetFieldULong(hResult, 0, 0) + 1);
394 DBFreeResult(hResult);
395 }
396
397 // Get first available certificate id
398 hResult = DBSelect(hdb, _T("SELECT max(cert_id) FROM certificates"));
399 if (hResult != NULL)
400 {
401 if (DBGetNumRows(hResult) > 0)
402 s_freeIdTable[IDG_CERTIFICATE] = std::max(s_freeIdTable[IDG_CERTIFICATE],
403 DBGetFieldULong(hResult, 0, 0) + 1);
404 DBFreeResult(hResult);
405 }
406
407 // Get first available SLM ticket id
408 hResult = DBSelect(hdb, _T("SELECT max(ticket_id) FROM slm_tickets"));
409 if (hResult != NULL)
410 {
411 if (DBGetNumRows(hResult) > 0)
412 s_freeIdTable[IDG_SLM_TICKET] = std::max(s_freeIdTable[IDG_SLM_TICKET],
413 DBGetFieldULong(hResult, 0, 0) + 1);
414 DBFreeResult(hResult);
415 }
416
417 // Get first available data collection table column id
418 hResult = DBSelect(hdb, _T("SELECT max(column_id) FROM dct_column_names"));
419 if (hResult != NULL)
420 {
421 if (DBGetNumRows(hResult) > 0)
422 s_freeIdTable[IDG_DCT_COLUMN] = std::max(s_freeIdTable[IDG_DCT_COLUMN],
423 DBGetFieldULong(hResult, 0, 0) + 1);
424 DBFreeResult(hResult);
425 }
426
427 // Get first available mapping table id
428 hResult = DBSelect(hdb, _T("SELECT max(id) FROM mapping_tables"));
429 if (hResult != NULL)
430 {
431 if (DBGetNumRows(hResult) > 0)
432 s_freeIdTable[IDG_MAPPING_TABLE] = std::max(s_freeIdTable[IDG_MAPPING_TABLE],
433 DBGetFieldULong(hResult, 0, 0) + 1);
434 DBFreeResult(hResult);
435 }
436
437 // Get first available DCI summary table id
438 hResult = DBSelect(hdb, _T("SELECT max(id) FROM dci_summary_tables"));
439 if (hResult != NULL)
440 {
441 if (DBGetNumRows(hResult) > 0)
442 s_freeIdTable[IDG_DCI_SUMMARY_TABLE] = std::max(s_freeIdTable[IDG_DCI_SUMMARY_TABLE],
443 DBGetFieldULong(hResult, 0, 0) + 1);
444 DBFreeResult(hResult);
445 }
446
447 // Get first available scheduled_tasks id
448 hResult = DBSelect(hdb, _T("SELECT max(id) FROM scheduled_tasks"));
449 if (hResult != NULL)
450 {
451 if (DBGetNumRows(hResult) > 0)
452 s_freeIdTable[IDG_SCHEDULED_TASK] = std::max(s_freeIdTable[IDG_SCHEDULED_TASK],
453 DBGetFieldULong(hResult, 0, 0) + 1);
454 DBFreeResult(hResult);
455 }
456
457 // Get first available alarm category id
458 hResult = DBSelect(hdb, _T("SELECT max(id) FROM alarm_categories"));
459 if (hResult != NULL)
460 {
461 if (DBGetNumRows(hResult) > 0)
462 s_freeIdTable[IDG_ALARM_CATEGORY] = std::max(s_freeIdTable[IDG_ALARM_CATEGORY],
463 DBGetFieldULong(hResult, 0, 0) + 1);
464 DBFreeResult(hResult);
465 }
466
467 DBConnectionPoolReleaseConnection(hdb);
468 return TRUE;
469 }
470
471 /**
472 * Create unique ID
473 */
474 UINT32 CreateUniqueId(int iGroup)
475 {
476 UINT32 dwId;
477
478 MutexLock(s_mutexTableAccess);
479 if (s_freeIdTable[iGroup] == s_idLimits[iGroup])
480 {
481 dwId = 0; // ID zero means _T("no unique ID available")
482 nxlog_write(MSG_NO_UNIQUE_ID, EVENTLOG_ERROR_TYPE, "s", m_pszGroupNames[iGroup]);
483 }
484 else
485 {
486 dwId = s_freeIdTable[iGroup];
487 s_freeIdTable[iGroup]++;
488 }
489 MutexUnlock(s_mutexTableAccess);
490 return dwId;
491 }
492
493 /**
494 * Create unique ID for event log record
495 */
496 QWORD CreateUniqueEventId()
497 {
498 QWORD qwId;
499
500 MutexLock(s_mutexTableAccess);
501 qwId = m_freeEventId++;
502 MutexUnlock(s_mutexTableAccess);
503 return qwId;
504 }
505
506 /**
507 * Save current first free IDs
508 */
509 void SaveCurrentFreeId()
510 {
511 MutexLock(s_mutexTableAccess);
512 UINT32 id = s_freeIdTable[IDG_NETWORK_OBJECT];
513 MutexUnlock(s_mutexTableAccess);
514 ConfigWriteULong(_T("FirstFreeObjectId"), id, TRUE, FALSE, TRUE);
515 }