- Changes in logging and debug output
[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 signed long
223 //
224
225 long DBGetFieldLong(DB_RESULT hResult, int iRow, int iColumn)
226 {
227 char *szVal;
228
229 szVal = DBGetField(hResult, iRow, iColumn);
230 return szVal == NULL ? 0 : strtol(szVal, NULL, 10);
231 }
232
233
234 //
235 // Get field's value as double
236 //
237
238 double DBGetFieldDouble(DB_RESULT hResult, int iRow, int iColumn)
239 {
240 char *szVal;
241
242 szVal = DBGetField(hResult, iRow, iColumn);
243 return szVal == NULL ? 0 : strtod(szVal, NULL);
244 }
245
246
247 //
248 // Get number of rows in result
249 //
250
251 int DBGetNumRows(DB_RESULT hResult)
252 {
253 return m_fpDrvGetNumRows(hResult);
254 }
255
256
257 //
258 // Free result
259 //
260
261 void DBFreeResult(DB_RESULT hResult)
262 {
263 m_fpDrvFreeResult(hResult);
264 }
265
266
267 //
268 // Asyncronous SELECT query
269 //
270
271 DB_ASYNC_RESULT DBAsyncSelect(DB_HANDLE hConn, char *szQuery)
272 {
273 DB_RESULT hResult;
274
275 hResult = m_fpDrvAsyncSelect(hConn, szQuery);
276 DbgPrintf(AF_DEBUG_SQL, "%s async query: \"%s\"", (hResult != NULL) ? "Successful" : "Failed", szQuery);
277 if ((!hResult) && (g_dwFlags & AF_LOG_SQL_ERRORS))
278 WriteLog(MSG_SQL_ERROR, EVENTLOG_ERROR_TYPE, "s", szQuery);
279 return hResult;
280 }
281
282
283 //
284 // Fetch next row from asynchronous SELECT result
285 //
286
287 BOOL DBFetch(DB_ASYNC_RESULT hResult)
288 {
289 return m_fpDrvFetch(hResult);
290 }
291
292
293 //
294 // Get field's value from asynchronous SELECT result
295 //
296
297 char *DBGetFieldAsync(DB_ASYNC_RESULT hResult, int iColumn, char *pBuffer, int iBufSize)
298 {
299 return m_fpDrvGetFieldAsync(hResult, iColumn, pBuffer, iBufSize);
300 }
301
302
303 //
304 // Get field's value as unsigned long from asynchronous SELECT result
305 //
306
307 DWORD DBGetFieldAsyncULong(DB_ASYNC_RESULT hResult, int iColumn)
308 {
309 long iVal;
310 DWORD dwVal;
311 char szBuffer[64];
312
313 if (DBGetFieldAsync(hResult, iColumn, szBuffer, 64) == NULL)
314 return 0;
315 iVal = strtol(szBuffer, NULL, 10);
316 memcpy(&dwVal, &iVal, sizeof(long)); // To prevent possible conversion
317 return dwVal;
318 }
319
320
321 //
322 // Get field's value as signed long from asynchronous SELECT result
323 //
324
325 long DBGetFieldAsyncLong(DB_RESULT hResult, int iColumn)
326 {
327 char szBuffer[64];
328
329 return DBGetFieldAsync(hResult, iColumn, szBuffer, 64) == NULL ? 0 : strtol(szBuffer, NULL, 10);
330 }
331
332
333 //
334 // Get field's value as signed long from asynchronous SELECT result
335 //
336
337 double DBGetFieldAsyncDouble(DB_RESULT hResult, int iColumn)
338 {
339 char szBuffer[64];
340
341 return DBGetFieldAsync(hResult, iColumn, szBuffer, 64) == NULL ? 0 : strtod(szBuffer, NULL);
342 }
343
344
345 //
346 // Free asynchronous SELECT result
347 //
348
349 void DBFreeAsyncResult(DB_ASYNC_RESULT hResult)
350 {
351 m_fpDrvFreeAsyncResult(hResult);
352 }