Cosmetic changes
[public/netxms.git] / src / server / core / db.cpp
1 /*
2 ** Project X - Network Management System
3 ** Copyright (C) 2003 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 ** $module: db.cpp
20 **
21 **/
22
23 #include "nms_core.h"
24
25
26 //
27 // Global variables
28 //
29
30 char g_szDbDriver[MAX_PATH] = "";
31 char g_szDbDrvParams[MAX_PATH] = "";
32 char g_szDbServer[MAX_PATH] = "127.0.0.1";
33 char g_szDbLogin[MAX_DB_LOGIN] = "netxms";
34 char g_szDbPassword[MAX_DB_PASSWORD] = "";
35 char g_szDbName[MAX_DB_NAME] = "netxms_db";
36
37
38 //
39 // Static data
40 //
41
42 static HMODULE m_hDriver = NULL;
43 static DB_HANDLE (* m_fpDrvConnect)(char *, char *, char *, char *) = NULL;
44 static void (* m_fpDrvDisconnect)(DB_HANDLE) = NULL;
45 static BOOL (* m_fpDrvQuery)(DB_HANDLE, char *) = NULL;
46 static DB_RESULT (* m_fpDrvSelect)(DB_HANDLE, char *) = NULL;
47 static DB_ASYNC_RESULT (* m_fpDrvAsyncSelect)(DB_HANDLE, char *) = NULL;
48 static BOOL (* m_fpDrvFetch)(DB_ASYNC_RESULT) = NULL;
49 static char* (* m_fpDrvGetField)(DB_RESULT, int, int) = NULL;
50 static char* (* m_fpDrvGetFieldAsync)(DB_ASYNC_RESULT, int, char *, int) = NULL;
51 static int (* m_fpDrvGetNumRows)(DB_RESULT) = NULL;
52 static void (* m_fpDrvFreeResult)(DB_RESULT) = NULL;
53 static void (* m_fpDrvFreeAsyncResult)(DB_ASYNC_RESULT) = NULL;
54 static void (* m_fpDrvUnload)(void) = NULL;
55
56
57 //
58 // Get symbol address and log errors
59 //
60
61 static void *DLGetSymbolAddrEx(HMODULE hModule, char *pszSymbol)
62 {
63 void *pFunc;
64 char szErrorText[256];
65
66 pFunc = DLGetSymbolAddr(hModule, pszSymbol, szErrorText);
67 if (pFunc == NULL)
68 WriteLog(MSG_DLSYM_FAILED, EVENTLOG_WARNING_TYPE, "ss", pszSymbol, szErrorText);
69 return pFunc;
70 }
71
72
73 //
74 // Load and initialize database driver
75 //
76
77 BOOL DBInit(void)
78 {
79 BOOL (* fpDrvInit)(char *);
80 char szErrorText[256];
81
82 // Load driver's module
83 m_hDriver = DLOpen(g_szDbDriver, szErrorText);
84 if (m_hDriver == NULL)
85 {
86 WriteLog(MSG_DLOPEN_FAILED, EVENTLOG_ERROR_TYPE, "ss", g_szDbDriver, szErrorText);
87 return FALSE;
88 }
89
90 // Import symbols
91 fpDrvInit = (BOOL (*)(char *))DLGetSymbolAddrEx(m_hDriver, "DrvInit");
92 m_fpDrvConnect = (DB_HANDLE (*)(char *, char *, char *, char *))DLGetSymbolAddrEx(m_hDriver, "DrvConnect");
93 m_fpDrvDisconnect = (void (*)(DB_HANDLE))DLGetSymbolAddrEx(m_hDriver, "DrvDisconnect");
94 m_fpDrvQuery = (BOOL (*)(DB_HANDLE, char *))DLGetSymbolAddrEx(m_hDriver, "DrvQuery");
95 m_fpDrvSelect = (DB_RESULT (*)(DB_HANDLE, char *))DLGetSymbolAddrEx(m_hDriver, "DrvSelect");
96 m_fpDrvAsyncSelect = (DB_ASYNC_RESULT (*)(DB_HANDLE, char *))DLGetSymbolAddrEx(m_hDriver, "DrvAsyncSelect");
97 m_fpDrvFetch = (BOOL (*)(DB_ASYNC_RESULT))DLGetSymbolAddrEx(m_hDriver, "DrvFetch");
98 m_fpDrvGetField = (char* (*)(DB_RESULT, int, int))DLGetSymbolAddrEx(m_hDriver, "DrvGetField");
99 m_fpDrvGetFieldAsync = (char* (*)(DB_ASYNC_RESULT, int, char *, int))DLGetSymbolAddrEx(m_hDriver, "DrvGetFieldAsync");
100 m_fpDrvGetNumRows = (int (*)(DB_RESULT))DLGetSymbolAddrEx(m_hDriver, "DrvGetNumRows");
101 m_fpDrvFreeResult = (void (*)(DB_RESULT))DLGetSymbolAddrEx(m_hDriver, "DrvFreeResult");
102 m_fpDrvFreeAsyncResult = (void (*)(DB_ASYNC_RESULT))DLGetSymbolAddrEx(m_hDriver, "DrvFreeAsyncResult");
103 m_fpDrvUnload = (void (*)(void))DLGetSymbolAddrEx(m_hDriver, "DrvUnload");
104 if ((fpDrvInit == NULL) || (m_fpDrvConnect == NULL) || (m_fpDrvDisconnect == NULL) ||
105 (m_fpDrvQuery == NULL) || (m_fpDrvSelect == NULL) || (m_fpDrvGetField == NULL) ||
106 (m_fpDrvGetNumRows == NULL) || (m_fpDrvFreeResult == NULL) ||
107 (m_fpDrvUnload == NULL) || (m_fpDrvAsyncSelect == NULL) || (m_fpDrvFetch == NULL) ||
108 (m_fpDrvFreeAsyncResult == NULL) || (m_fpDrvGetFieldAsync == NULL))
109 {
110 WriteLog(MSG_DBDRV_NO_ENTRY_POINTS, EVENTLOG_ERROR_TYPE, "s", g_szDbDriver);
111 return FALSE;
112 }
113
114 // Initialize driver
115 if (!fpDrvInit(g_szDbDrvParams))
116 {
117 WriteLog(MSG_DBDRV_INIT_FAILED, EVENTLOG_ERROR_TYPE, "s", g_szDbDriver);
118 DLClose(m_hDriver);
119 m_hDriver = NULL;
120 return FALSE;
121 }
122
123 // Success
124 WriteLog(MSG_DBDRV_LOADED, EVENTLOG_INFORMATION_TYPE, "s", g_szDbDriver);
125 return TRUE;
126 }
127
128
129 //
130 // Notify driver of unload
131 //
132
133 void DBUnloadDriver(void)
134 {
135 m_fpDrvUnload();
136 DLClose(m_hDriver);
137 }
138
139
140 //
141 // Connect to database
142 //
143
144 DB_HANDLE DBConnect(void)
145 {
146 return m_fpDrvConnect(g_szDbServer, g_szDbLogin, g_szDbPassword, g_szDbName);
147 }
148
149
150 //
151 // Disconnect from database
152 //
153
154 void DBDisconnect(DB_HANDLE hConn)
155 {
156 m_fpDrvDisconnect(hConn);
157 }
158
159
160 //
161 // Perform a non-SELECT SQL query
162 //
163
164 BOOL DBQuery(DB_HANDLE hConn, char *szQuery)
165 {
166 BOOL bResult;
167
168 bResult = m_fpDrvQuery(hConn, szQuery);
169 DbgPrintf(AF_DEBUG_SQL, "%s sync query: \"%s\"", bResult ? "Successful" : "Failed", szQuery);
170 if ((!bResult) && (g_dwFlags & AF_LOG_SQL_ERRORS))
171 WriteLog(MSG_SQL_ERROR, EVENTLOG_ERROR_TYPE, "s", szQuery);
172 return bResult;
173 }
174
175
176 //
177 // Perform SELECT query
178 //
179
180 DB_RESULT DBSelect(DB_HANDLE hConn, char *szQuery)
181 {
182 DB_RESULT hResult;
183
184 hResult = m_fpDrvSelect(hConn, szQuery);
185 DbgPrintf(AF_DEBUG_SQL, "%s sync query: \"%s\"", (hResult != NULL) ? "Successful" : "Failed", szQuery);
186 if ((!hResult) && (g_dwFlags & AF_LOG_SQL_ERRORS))
187 WriteLog(MSG_SQL_ERROR, EVENTLOG_ERROR_TYPE, "s", szQuery);
188 return hResult;
189 }
190
191
192 //
193 // Get field's value
194 //
195
196 char *DBGetField(DB_RESULT hResult, int iRow, int iColumn)
197 {
198 return m_fpDrvGetField(hResult, iRow, iColumn);
199 }
200
201
202 //
203 // Get field's value as unsigned long
204 //
205
206 DWORD DBGetFieldULong(DB_RESULT hResult, int iRow, int iColumn)
207 {
208 long iVal;
209 DWORD dwVal;
210 char *szVal;
211
212 szVal = DBGetField(hResult, iRow, iColumn);
213 if (szVal == NULL)
214 return 0;
215 iVal = strtol(szVal, NULL, 10);
216 memcpy(&dwVal, &iVal, sizeof(long)); // To prevent possible conversion
217 return dwVal;
218 }
219
220
221 //
222 // Get field's value as unsigned 64-bit int
223 //
224
225 QWORD DBGetFieldUQuad(DB_RESULT hResult, int iRow, int iColumn)
226 {
227 INT64 iVal;
228 QWORD qwVal;
229 char *szVal;
230
231 szVal = DBGetField(hResult, iRow, iColumn);
232 if (szVal == NULL)
233 return 0;
234 iVal = strtoll(szVal, NULL, 10);
235 memcpy(&qwVal, &iVal, sizeof(INT64)); // To prevent possible conversion
236 return qwVal;
237 }
238
239
240 //
241 // Get field's value as signed long
242 //
243
244 long DBGetFieldLong(DB_RESULT hResult, int iRow, int iColumn)
245 {
246 char *szVal;
247
248 szVal = DBGetField(hResult, iRow, iColumn);
249 return szVal == NULL ? 0 : strtol(szVal, NULL, 10);
250 }
251
252
253 //
254 // Get field's value as signed 64-bit int
255 //
256
257 INT64 DBGetFieldQuad(DB_RESULT hResult, int iRow, int iColumn)
258 {
259 char *szVal;
260
261 szVal = DBGetField(hResult, iRow, iColumn);
262 return szVal == NULL ? 0 : strtoll(szVal, NULL, 10);
263 }
264
265
266 //
267 // Get field's value as double
268 //
269
270 double DBGetFieldDouble(DB_RESULT hResult, int iRow, int iColumn)
271 {
272 char *szVal;
273
274 szVal = DBGetField(hResult, iRow, iColumn);
275 return szVal == NULL ? 0 : strtod(szVal, NULL);
276 }
277
278
279 //
280 // Get field's value as IP address
281 //
282
283 DWORD DBGetFieldIPAddr(DB_RESULT hResult, int iRow, int iColumn)
284 {
285 char *szVal;
286
287 szVal = DBGetField(hResult, iRow, iColumn);
288 return szVal == NULL ? INADDR_NONE : ntohl(inet_addr(szVal));
289 }
290
291
292 //
293 // Get number of rows in result
294 //
295
296 int DBGetNumRows(DB_RESULT hResult)
297 {
298 return m_fpDrvGetNumRows(hResult);
299 }
300
301
302 //
303 // Free result
304 //
305
306 void DBFreeResult(DB_RESULT hResult)
307 {
308 m_fpDrvFreeResult(hResult);
309 }
310
311
312 //
313 // Asyncronous SELECT query
314 //
315
316 DB_ASYNC_RESULT DBAsyncSelect(DB_HANDLE hConn, char *szQuery)
317 {
318 DB_RESULT hResult;
319
320 hResult = m_fpDrvAsyncSelect(hConn, szQuery);
321 DbgPrintf(AF_DEBUG_SQL, "%s async query: \"%s\"", (hResult != NULL) ? "Successful" : "Failed", szQuery);
322 if ((!hResult) && (g_dwFlags & AF_LOG_SQL_ERRORS))
323 WriteLog(MSG_SQL_ERROR, EVENTLOG_ERROR_TYPE, "s", szQuery);
324 return hResult;
325 }
326
327
328 //
329 // Fetch next row from asynchronous SELECT result
330 //
331
332 BOOL DBFetch(DB_ASYNC_RESULT hResult)
333 {
334 return m_fpDrvFetch(hResult);
335 }
336
337
338 //
339 // Get field's value from asynchronous SELECT result
340 //
341
342 char *DBGetFieldAsync(DB_ASYNC_RESULT hResult, int iColumn, char *pBuffer, int iBufSize)
343 {
344 return m_fpDrvGetFieldAsync(hResult, iColumn, pBuffer, iBufSize);
345 }
346
347
348 //
349 // Get field's value as unsigned long from asynchronous SELECT result
350 //
351
352 DWORD DBGetFieldAsyncULong(DB_ASYNC_RESULT hResult, int iColumn)
353 {
354 long iVal;
355 DWORD dwVal;
356 char szBuffer[64];
357
358 if (DBGetFieldAsync(hResult, iColumn, szBuffer, 64) == NULL)
359 return 0;
360 iVal = strtol(szBuffer, NULL, 10);
361 memcpy(&dwVal, &iVal, sizeof(long)); // To prevent possible conversion
362 return dwVal;
363 }
364
365
366 //
367 // Get field's value as unsigned 64-bit int from asynchronous SELECT result
368 //
369
370 QWORD DBGetFieldAsyncUQuad(DB_ASYNC_RESULT hResult, int iColumn)
371 {
372 INT64 iVal;
373 QWORD qwVal;
374 char szBuffer[64];
375
376 if (DBGetFieldAsync(hResult, iColumn, szBuffer, 64) == NULL)
377 return 0;
378 iVal = strtoll(szBuffer, NULL, 10);
379 memcpy(&qwVal, &iVal, sizeof(INT64)); // To prevent possible conversion
380 return qwVal;
381 }
382
383
384 //
385 // Get field's value as signed long from asynchronous SELECT result
386 //
387
388 long DBGetFieldAsyncLong(DB_RESULT hResult, int iColumn)
389 {
390 char szBuffer[64];
391
392 return DBGetFieldAsync(hResult, iColumn, szBuffer, 64) == NULL ? 0 : strtol(szBuffer, NULL, 10);
393 }
394
395
396 //
397 // Get field's value as signed 64-bit int from asynchronous SELECT result
398 //
399
400 INT64 DBGetFieldAsyncQuad(DB_RESULT hResult, int iColumn)
401 {
402 char szBuffer[64];
403
404 return DBGetFieldAsync(hResult, iColumn, szBuffer, 64) == NULL ? 0 : strtoll(szBuffer, NULL, 10);
405 }
406
407
408 //
409 // Get field's value as signed long from asynchronous SELECT result
410 //
411
412 double DBGetFieldAsyncDouble(DB_RESULT hResult, int iColumn)
413 {
414 char szBuffer[64];
415
416 return DBGetFieldAsync(hResult, iColumn, szBuffer, 64) == NULL ? 0 : strtod(szBuffer, NULL);
417 }
418
419
420 //
421 // Get field's value as IP address from asynchronous SELECT result
422 //
423
424 DWORD DBGetFieldAsyncIPAddr(DB_RESULT hResult, int iColumn)
425 {
426 char szBuffer[64];
427
428 return DBGetFieldAsync(hResult, iColumn, szBuffer, 64) == NULL ? INADDR_NONE :
429 ntohl(inet_addr(szBuffer));
430 }
431
432
433 //
434 // Free asynchronous SELECT result
435 //
436
437 void DBFreeAsyncResult(DB_ASYNC_RESULT hResult)
438 {
439 m_fpDrvFreeAsyncResult(hResult);
440 }