0d8874599c38437af8ed181207b854f2a8bdebf2
[public/netxms.git] / src / agent / subagents / dbquery / conn.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 Lesser General Public License as published
7 ** by the Free Software Foundation; either version 3 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 Lesser 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: direct.cpp
20 **
21 **/
22
23 #include "dbquery.h"
24
25 /**
26 * Database connections
27 */
28 static ObjectArray<DBConnection> s_dbConnections(8, 8, true);
29 static MUTEX s_dbConnectionsLock = MutexCreate();
30
31 /**
32 * DB connection constructor
33 */
34 DBConnection::DBConnection()
35 {
36 m_driver = NULL;
37 m_server = NULL;
38 m_dbName = NULL;
39 m_login = NULL;
40 m_password = NULL;
41 m_hDriver = NULL;
42 m_hdb = NULL;
43 }
44
45 /**
46 * DB connection destructor
47 */
48 DBConnection::~DBConnection()
49 {
50 safe_free(m_id)
51 safe_free(m_driver);
52 safe_free(m_server);
53 safe_free(m_dbName);
54 safe_free(m_login);
55 safe_free(m_password);
56 if (m_hdb != NULL)
57 DBDisconnect(m_hdb);
58 if (m_hDriver != NULL)
59 DBUnloadDriver(m_hDriver);
60 }
61
62 /**
63 * Read attribute from config string
64 */
65 static TCHAR *ReadAttribute(const TCHAR *config, const TCHAR *attribute)
66 {
67 TCHAR buffer[256];
68 if (!ExtractNamedOptionValue(config, attribute, buffer, 256))
69 return NULL;
70 return _tcsdup(buffer);
71 }
72
73 /**
74 * Create DB connection from config
75 */
76 DBConnection *DBConnection::createFromConfig(const TCHAR *config)
77 {
78 DBConnection *conn = new DBConnection();
79 conn->m_id = ReadAttribute(config, _T("id"));
80 conn->m_driver = ReadAttribute(config, _T("driver"));
81 conn->m_server = ReadAttribute(config, _T("server"));
82 conn->m_dbName = ReadAttribute(config, _T("dbname"));
83 conn->m_login = ReadAttribute(config, _T("login"));
84 conn->m_password = ReadAttribute(config, _T("password"));
85
86 if(conn->m_password == NULL)
87 conn->m_password = ReadAttribute(config, _T("encryptedPassword"));
88
89 if (conn->m_password != NULL)
90 DecryptPassword(CHECK_NULL_EX(conn->m_login), conn->m_password, conn->m_password, _tcslen(conn->m_password));
91
92 if ((conn->m_id == NULL) || (conn->m_driver == NULL))
93 {
94 delete conn;
95 return NULL;
96 }
97
98 conn->m_hDriver = DBLoadDriver(conn->m_driver, _T(""), false, NULL, NULL);
99 if (conn->m_hDriver == NULL)
100 {
101 delete conn;
102 return NULL;
103 }
104
105 conn->connect();
106 return conn;
107 }
108
109 /**
110 * Connect to database
111 */
112 bool DBConnection::connect()
113 {
114 if (m_hdb != NULL)
115 DBDisconnect(m_hdb);
116
117 TCHAR errorText[DBDRV_MAX_ERROR_TEXT];
118 m_hdb = DBConnect(m_hDriver, m_server, m_dbName, m_login, m_password, NULL, errorText);
119 if (m_hdb != NULL)
120 {
121 AgentWriteLog(NXLOG_INFO, _T("DBQUERY: connected to database %s"), m_id);
122 }
123 else
124 {
125 AgentWriteLog(NXLOG_WARNING, _T("DBQUERY: cannot connect to database %s (%s)"), m_id, errorText);
126 }
127 return m_hdb != NULL;
128 }
129
130 /**
131 * Add database connection to the list from config
132 */
133 bool AddDatabaseFromConfig(const TCHAR *db)
134 {
135 DBConnection *conn = DBConnection::createFromConfig(db);
136 if (conn == NULL)
137 return false;
138
139 MutexLock(s_dbConnectionsLock);
140 s_dbConnections.add(conn);
141 MutexUnlock(s_dbConnectionsLock);
142 return true;
143 }
144
145 /**
146 * Shutdown all DB connections
147 */
148 void ShutdownConnections()
149 {
150 MutexLock(s_dbConnectionsLock);
151 s_dbConnections.clear();
152 MutexUnlock(s_dbConnectionsLock);
153 }
154
155 /**
156 * Get connection handle for given database
157 */
158 DB_HANDLE GetConnectionHandle(const TCHAR *dbid)
159 {
160 DB_HANDLE hdb = NULL;
161 MutexLock(s_dbConnectionsLock);
162 for(int i = 0; i < s_dbConnections.size(); i++)
163 if (!_tcsicmp(dbid, s_dbConnections.get(i)->getId()))
164 {
165 hdb = s_dbConnections.get(i)->getHandle();
166 if (hdb == NULL)
167 {
168 // Try to (re)connect to database
169 s_dbConnections.get(i)->connect();
170 hdb = s_dbConnections.get(i)->getHandle();
171 }
172 break;
173 }
174 MutexUnlock(s_dbConnectionsLock);
175 return hdb;
176 }