object save optimization - object properties divided into groups and anly modified...
[public/netxms.git] / src / server / core / zone.cpp
CommitLineData
e83d726c 1/*
5039dede 2** NetXMS - Network Management System
a191c634 3** Copyright (C) 2003-2017 Victor Kirhenshtein
5039dede
AK
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**
52c31148 19** File: zone.cpp
5039dede
AK
20**
21**/
22
23#include "nxcore.h"
24
fe400f32 25/**
a1286d8b
VK
26 * Dump index to console
27 */
28void DumpIndex(CONSOLE_CTX pCtx, InetAddressIndex *index);
29
30/**
fe400f32
VK
31 * Zone class default constructor
32 */
33Zone::Zone() : NetObj()
5039dede 34{
c42b4551 35 m_id = 0;
a191c634 36 m_uin = 0;
c42b4551 37 _tcscpy(m_name, _T("Default"));
43b62436 38 m_proxyNodeId = 0;
c75e9ee4
VK
39 m_idxNodeByAddr = new InetAddressIndex;
40 m_idxInterfaceByAddr = new InetAddressIndex;
41 m_idxSubnetByAddr = new InetAddressIndex;
5039dede
AK
42}
43
fe400f32
VK
44/**
45 * Constructor for new zone object
46 */
a191c634 47Zone::Zone(UINT32 uin, const TCHAR *name) : NetObj()
dc25b21c 48{
c42b4551 49 m_id = 0;
a191c634 50 m_uin = uin;
c42b4551 51 nx_strncpy(m_name, name, MAX_OBJECT_NAME);
43b62436 52 m_proxyNodeId = 0;
c75e9ee4
VK
53 m_idxNodeByAddr = new InetAddressIndex;
54 m_idxInterfaceByAddr = new InetAddressIndex;
55 m_idxSubnetByAddr = new InetAddressIndex;
dc25b21c
VK
56}
57
fe400f32
VK
58/**
59 * Zone class destructor
60 */
5039dede
AK
61Zone::~Zone()
62{
16d6f798 63 delete m_idxNodeByAddr;
5e39b8a3
VK
64 delete m_idxInterfaceByAddr;
65 delete m_idxSubnetByAddr;
5039dede
AK
66}
67
fe400f32
VK
68/**
69 * Create object from database data
70 */
9bd1bace 71bool Zone::loadFromDatabase(DB_HANDLE hdb, UINT32 dwId)
5039dede 72{
c42b4551 73 m_id = dwId;
5039dede 74
9bd1bace
VK
75 if (!loadCommonProperties(hdb))
76 return false;
5039dede 77
9bd1bace 78 TCHAR szQuery[256];
43b62436 79 _sntprintf(szQuery, 256, _T("SELECT zone_guid,proxy_node FROM zones WHERE id=%d"), dwId);
9bd1bace 80 DB_RESULT hResult = DBSelect(hdb, szQuery);
5039dede 81 if (hResult == NULL)
9bd1bace 82 return false; // Query failed
5039dede
AK
83
84 if (DBGetNumRows(hResult) == 0)
85 {
86 DBFreeResult(hResult);
87 if (dwId == BUILTIN_OID_ZONE0)
88 {
a191c634 89 m_uin = 0;
9bd1bace 90 return true;
5039dede
AK
91 }
92 else
93 {
c42b4551 94 DbgPrintf(4, _T("Cannot load zone object %ld - missing record in \"zones\" table"), (long)m_id);
9bd1bace 95 return false;
5039dede
AK
96 }
97 }
98
a191c634 99 m_uin = DBGetFieldULong(hResult, 0, 0);
43b62436 100 m_proxyNodeId = DBGetFieldULong(hResult, 0, 1);
5039dede
AK
101
102 DBFreeResult(hResult);
103
5039dede 104 // Load access list
9bd1bace 105 loadACLFromDB(hdb);
5039dede 106
9bd1bace 107 return true;
5039dede
AK
108}
109
22ee6d97
VK
110/**
111 * Save object to database
112 */
b4277312 113bool Zone::saveToDatabase(DB_HANDLE hdb)
5039dede 114{
c42b4551 115 lockProperties();
5039dede 116
241541f4 117 bool success = saveCommonProperties(hdb);
3d48d1b4 118 if (success && (m_modified & MODIFY_OTHER))
5039dede 119 {
241541f4
VK
120 DB_STATEMENT hStmt;
121 if (IsDatabaseRecordExist(hdb, _T("zones"), _T("id"), m_id))
122 {
43b62436 123 hStmt = DBPrepare(hdb, _T("UPDATE zones SET zone_guid=?,proxy_node=? WHERE id=?"));
241541f4
VK
124 }
125 else
126 {
43b62436 127 hStmt = DBPrepare(hdb, _T("INSERT INTO zones (zone_guid,proxy_node,id) VALUES (?,?,?)"));
241541f4
VK
128 }
129 if (hStmt != NULL)
130 {
a191c634 131 DBBind(hStmt, 1, DB_SQLTYPE_INTEGER, m_uin);
43b62436
VK
132 DBBind(hStmt, 2, DB_SQLTYPE_INTEGER, m_proxyNodeId);
133 DBBind(hStmt, 3, DB_SQLTYPE_INTEGER, m_id);
241541f4
VK
134 success = DBExecute(hStmt);
135 DBFreeStatement(hStmt);
136 }
137 else
138 {
139 success = false;
140 }
241541f4 141 }
3d48d1b4
VK
142
143 if (success)
144 success = saveACLToDB(hdb);
145
5039dede 146 // Unlock object and clear modification flag
3d48d1b4 147 m_modified = 0;
c42b4551 148 unlockProperties();
241541f4 149 return success;
5039dede
AK
150}
151
22ee6d97
VK
152/**
153 * Delete zone object from database
154 */
c42b4551 155bool Zone::deleteFromDatabase(DB_HANDLE hdb)
5039dede 156{
c42b4551 157 bool success = NetObj::deleteFromDatabase(hdb);
22ee6d97
VK
158 if (success)
159 success = executeQueryOnObject(hdb, _T("DELETE FROM zones WHERE id=?"));
160 return success;
5039dede
AK
161}
162
22ee6d97
VK
163/**
164 * Create NXCP message with object's data
165 */
241541f4 166void Zone::fillMessageInternal(NXCPMessage *msg)
5039dede 167{
241541f4 168 NetObj::fillMessageInternal(msg);
a191c634 169 msg->setField(VID_ZONE_UIN, m_uin);
43b62436 170 msg->setField(VID_ZONE_PROXY, m_proxyNodeId);
5039dede
AK
171}
172
5c44534b
VK
173/**
174 * Modify object from message
175 */
241541f4 176UINT32 Zone::modifyFromMessageInternal(NXCPMessage *request)
5039dede 177{
43b62436
VK
178 if (request->isFieldExist(VID_ZONE_PROXY))
179 m_proxyNodeId = request->getFieldAsUInt32(VID_ZONE_PROXY);
52c31148 180
241541f4 181 return NetObj::modifyFromMessageInternal(request);
5039dede 182}
89135050
VK
183
184/**
185 * Update interface index
186 */
c75e9ee4 187void Zone::updateInterfaceIndex(const InetAddress& oldIp, const InetAddress& newIp, Interface *iface)
89135050
VK
188{
189 m_idxInterfaceByAddr->remove(oldIp);
190 m_idxInterfaceByAddr->put(newIp, iface);
191}
27bbb906
VK
192
193/**
194 * Called by client session handler to check if threshold summary should be shown for this object.
195 */
196bool Zone::showThresholdSummary()
197{
198 return true;
199}
c30c0c0f
VK
200
201/**
202 * Remove interface from index
203 */
204void Zone::removeFromIndex(Interface *iface)
205{
206 const ObjectArray<InetAddress> *list = iface->getIpAddressList()->getList();
207 for(int i = 0; i < list->size(); i++)
208 {
209 InetAddress *addr = list->get(i);
210 if (addr->isValidUnicast())
211 {
212 NetObj *o = m_idxInterfaceByAddr->get(*addr);
213 if ((o != NULL) && (o->getId() == iface->getId()))
214 {
215 m_idxInterfaceByAddr->remove(*addr);
216 }
217 }
218 }
219}
297a88eb
VK
220
221/**
222 * Create NXSL object for this object
223 */
224NXSL_Value *Zone::createNXSLObject()
225{
226 return new NXSL_Value(new NXSL_Object(&g_nxslZoneClass, this));
227}
a1286d8b
VK
228
229/**
230 * Dump interface index to console
231 */
232void Zone::dumpInterfaceIndex(CONSOLE_CTX console)
233{
234 DumpIndex(console, m_idxInterfaceByAddr);
235}
236
237/**
238 * Dump node index to console
239 */
240void Zone::dumpNodeIndex(CONSOLE_CTX console)
241{
242 DumpIndex(console, m_idxNodeByAddr);
243}
244
245/**
246 * Dump subnet index to console
247 */
248void Zone::dumpSubnetIndex(CONSOLE_CTX console)
249{
250 DumpIndex(console, m_idxSubnetByAddr);
251}
950b229b
VK
252
253/**
254 * Serialize object to JSON
255 */
256json_t *Zone::toJson()
257{
258 json_t *root = NetObj::toJson();
a191c634 259 json_object_set_new(root, "uin", json_integer(m_uin));
950b229b
VK
260 json_object_set_new(root, "proxyNodeId", json_integer(m_proxyNodeId));
261 return root;
262}