- Initial DCI transformation support on server side
[public/netxms.git] / src / server / core / container.cpp
1 /*
2 ** NetXMS - Network Management System
3 ** Copyright (C) 2003, 2004 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: container.cpp
20 **
21 **/
22
23 #include "nms_core.h"
24
25
26 //
27 // Find container category by id
28 //
29
30 CONTAINER_CATEGORY *FindContainerCategory(DWORD dwId)
31 {
32 DWORD i;
33
34 for(i = 0; i < g_dwNumCategories; i++)
35 if (g_pContainerCatList[i].dwCatId == dwId)
36 return &g_pContainerCatList[i];
37 return NULL;
38 }
39
40
41 //
42 // Default container class constructor
43 //
44
45 Container::Container()
46 :NetObj()
47 {
48 m_pszDescription = NULL;
49 m_pdwChildIdList = NULL;
50 m_dwChildIdListSize = 0;
51 m_dwCategory = 1;
52 }
53
54
55 //
56 // "Normal" container class constructor
57 //
58
59 Container::Container(char *pszName, DWORD dwCategory, char *pszDescription)
60 :NetObj()
61 {
62 strncpy(m_szName, pszName, MAX_OBJECT_NAME);
63 m_pszDescription = strdup(pszDescription);
64 m_pdwChildIdList = NULL;
65 m_dwChildIdListSize = 0;
66 m_dwCategory = dwCategory;
67 }
68
69
70 //
71 // Container class destructor
72 //
73
74 Container::~Container()
75 {
76 safe_free(m_pszDescription);
77 safe_free(m_pdwChildIdList);
78 }
79
80
81 //
82 // Create object from database data
83 //
84
85 BOOL Container::CreateFromDB(DWORD dwId)
86 {
87 char szQuery[256];
88 DB_RESULT hResult;
89 DWORD i;
90
91 sprintf(szQuery, "SELECT id,name,status,category,description,image_id,is_deleted FROM containers WHERE id=%d", dwId);
92 hResult = DBSelect(g_hCoreDB, szQuery);
93 if (hResult == NULL)
94 return FALSE; // Query failed
95
96 if (DBGetNumRows(hResult) == 0)
97 {
98 // No object with given ID in database
99 DBFreeResult(hResult);
100 return FALSE;
101 }
102
103 m_dwId = dwId;
104 strncpy(m_szName, DBGetField(hResult, 0, 1), MAX_OBJECT_NAME);
105 m_iStatus = DBGetFieldLong(hResult, 0, 2);
106 m_dwCategory = DBGetFieldULong(hResult, 0, 3);
107 m_pszDescription = strdup(CHECK_NULL(DBGetField(hResult, 0, 4)));
108 m_dwImageId = DBGetFieldULong(hResult, 0, 5);
109 m_bIsDeleted = DBGetFieldLong(hResult, 0, 6);
110
111 DBFreeResult(hResult);
112
113 // Load access list
114 LoadACLFromDB();
115
116 // Load child list for later linkage
117 if (!m_bIsDeleted)
118 {
119 sprintf(szQuery, "SELECT object_id FROM container_members WHERE container_id=%d", m_dwId);
120 hResult = DBSelect(g_hCoreDB, szQuery);
121 if (hResult != NULL)
122 {
123 m_dwChildIdListSize = DBGetNumRows(hResult);
124 if (m_dwChildIdListSize > 0)
125 {
126 m_pdwChildIdList = (DWORD *)malloc(sizeof(DWORD) * m_dwChildIdListSize);
127 for(i = 0; i < m_dwChildIdListSize; i++)
128 m_pdwChildIdList[i] = DBGetFieldULong(hResult, i, 0);
129 }
130 DBFreeResult(hResult);
131 }
132 }
133
134 return TRUE;
135 }
136
137
138 //
139 // Save object to database
140 //
141
142 BOOL Container::SaveToDB(void)
143 {
144 char szQuery[1024];
145 DB_RESULT hResult;
146 DWORD i;
147 BOOL bNewObject = TRUE;
148
149 // Lock object's access
150 Lock();
151
152 // Check for object's existence in database
153 sprintf(szQuery, "SELECT id FROM containers WHERE id=%ld", m_dwId);
154 hResult = DBSelect(g_hCoreDB, szQuery);
155 if (hResult != 0)
156 {
157 if (DBGetNumRows(hResult) > 0)
158 bNewObject = FALSE;
159 DBFreeResult(hResult);
160 }
161
162 // Form and execute INSERT or UPDATE query
163 if (bNewObject)
164 sprintf(szQuery, "INSERT INTO containers (id,name,status,is_deleted,category,description,image_id)"
165 " VALUES (%ld,'%s',%d,%d,%ld,'%s',%ld)",
166 m_dwId, m_szName, m_iStatus, m_bIsDeleted, m_dwCategory,
167 CHECK_NULL(m_pszDescription), m_dwImageId);
168 else
169 sprintf(szQuery, "UPDATE containers SET name='%s',status=%d,is_deleted=%d,category=%ld,"
170 "description='%s',image_id=%ld WHERE id=%ld",
171 m_szName, m_iStatus, m_bIsDeleted, m_dwCategory,
172 CHECK_NULL(m_pszDescription), m_dwImageId, m_dwId);
173 DBQuery(g_hCoreDB, szQuery);
174
175 // Update members list
176 sprintf(szQuery, "DELETE FROM container_members WHERE container_id=%d", m_dwId);
177 DBQuery(g_hCoreDB, szQuery);
178 for(i = 0; i < m_dwChildCount; i++)
179 {
180 sprintf(szQuery, "INSERT INTO container_members (container_id,object_id) VALUES (%ld,%ld)", m_dwId, m_pChildList[i]->Id());
181 DBQuery(g_hCoreDB, szQuery);
182 }
183
184 // Save access list
185 SaveACLToDB();
186
187 // Clear modifications flag and unlock object
188 m_bIsModified = FALSE;
189 Unlock();
190
191 return TRUE;
192 }
193
194
195 //
196 // Delete object from database
197 //
198
199 BOOL Container::DeleteFromDB(void)
200 {
201 char szQuery[256];
202 BOOL bSuccess;
203
204 bSuccess = NetObj::DeleteFromDB();
205 if (bSuccess)
206 {
207 sprintf(szQuery, "DELETE FROM containers WHERE id=%d", m_dwId);
208 QueueSQLRequest(szQuery);
209 sprintf(szQuery, "DELETE FROM container_members WHERE container_id=%d", m_dwId);
210 QueueSQLRequest(szQuery);
211 }
212 return bSuccess;
213 }
214
215
216 //
217 // Link child objects after loading from database
218 //
219
220 void Container::LinkChildObjects(void)
221 {
222 NetObj *pObject;
223 DWORD i;
224
225 if (m_dwChildIdListSize > 0)
226 {
227 // Find and link child objects
228 for(i = 0; i < m_dwChildIdListSize; i++)
229 {
230 pObject = FindObjectById(m_pdwChildIdList[i]);
231 if (pObject != NULL)
232 LinkObject(pObject);
233 else
234 WriteLog(MSG_INVALID_CONTAINER_MEMBER, EVENTLOG_ERROR_TYPE, "dd", m_dwId, m_pdwChildIdList[i]);
235 }
236
237 // Cleanup
238 free(m_pdwChildIdList);
239 m_pdwChildIdList = NULL;
240 m_dwChildIdListSize = 0;
241 }
242 }
243
244
245 //
246 // Create CSCP message with object's data
247 //
248
249 void Container::CreateMessage(CSCPMessage *pMsg)
250 {
251 NetObj::CreateMessage(pMsg);
252 pMsg->SetVariable(VID_CATEGORY, m_dwCategory);
253 pMsg->SetVariable(VID_DESCRIPTION, CHECK_NULL(m_pszDescription));
254 }