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