- Started work on DCT export
authorVictor Kirhenshtein <victor@netxms.org>
Mon, 11 Oct 2004 15:36:45 +0000 (15:36 +0000)
committerVictor Kirhenshtein <victor@netxms.org>
Mon, 11 Oct 2004 15:36:45 +0000 (15:36 +0000)
- "Description" field added to template and node objects
- Minor bugfixes

15 files changed:
include/netxmsdb.h
include/nms_cscp.h
include/nxclapi.h
sql/dbinit.in
sql/schema.in
sql/setup.in
src/console/win32/DataCollectionEditor.cpp
src/console/win32/DataCollectionEditor.h
src/console/win32/nxcon.clw
src/libnxcl/objects.cpp
src/server/core/nms_objects.h
src/server/core/node.cpp
src/server/core/objects.cpp
src/server/core/session.cpp
src/server/core/template.cpp

index b07441b..e088596 100644 (file)
@@ -23,6 +23,6 @@
 #ifndef _netxms_db_h
 #define _netxms_db_h
 
-#define DB_FORMAT_VERSION      10
+#define DB_FORMAT_VERSION      11
 
 #endif
index ed553d2..31c1dab 100644 (file)
@@ -373,6 +373,7 @@ typedef struct
 #define VID_NUM_ITEMS               ((DWORD)111)
 #define VID_ITEM_LIST               ((DWORD)112)
 #define VID_MAC_ADDR                ((DWORD)113)
+#define VID_TEMPLATE_VERSION        ((DWORD)114)
 
 // Variable ranges for object's ACL
 #define VID_ACL_USER_BASE           ((DWORD)0x00001000)
index c40487e..2a40aa6 100644 (file)
@@ -246,15 +246,16 @@ typedef unsigned long HREQUEST;
 // Mask bits (flags) for NXCModifyObject()
 //
 
-#define OBJ_UPDATE_NAME             ((DWORD)0x01)
-#define OBJ_UPDATE_AGENT_PORT       ((DWORD)0x02)
-#define OBJ_UPDATE_AGENT_AUTH       ((DWORD)0x04)
-#define OBJ_UPDATE_AGENT_SECRET     ((DWORD)0x08)
-#define OBJ_UPDATE_SNMP_VERSION     ((DWORD)0x10)
-#define OBJ_UPDATE_SNMP_COMMUNITY   ((DWORD)0x20)
-#define OBJ_UPDATE_ACL              ((DWORD)0x40)
-#define OBJ_UPDATE_IMAGE            ((DWORD)0x80)
-#define OBJ_UPDATE_ALL              ((DWORD)0xFF)
+#define OBJ_UPDATE_NAME             ((DWORD)0x0001)
+#define OBJ_UPDATE_AGENT_PORT       ((DWORD)0x0002)
+#define OBJ_UPDATE_AGENT_AUTH       ((DWORD)0x0004)
+#define OBJ_UPDATE_AGENT_SECRET     ((DWORD)0x0008)
+#define OBJ_UPDATE_SNMP_VERSION     ((DWORD)0x0010)
+#define OBJ_UPDATE_SNMP_COMMUNITY   ((DWORD)0x0020)
+#define OBJ_UPDATE_ACL              ((DWORD)0x0040)
+#define OBJ_UPDATE_IMAGE            ((DWORD)0x0080)
+#define OBJ_UPDATE_DESCRIPTION      ((DWORD)0x0100)
+#define OBJ_UPDATE_ALL              ((DWORD)0x01FF)
 
 
 //
@@ -552,6 +553,7 @@ typedef struct
          TCHAR szObjectId[MAX_OID_LENGTH];
          WORD wAgentPort;     // Listening TCP port for native agent
          WORD wAuthMethod;    // Native agent's authentication method
+         TCHAR *pszDescription;
       } node;
       struct
       {
@@ -562,6 +564,11 @@ typedef struct
          DWORD dwCategory;
          TCHAR *pszDescription;
       } container;
+      struct
+      {
+         DWORD dwVersion;
+         TCHAR *pszDescription;
+      } dct;
    };
 } NXC_OBJECT;
 
@@ -575,6 +582,7 @@ typedef struct
    DWORD dwObjectId;
    DWORD dwFlags;
    TCHAR *pszName;
+   TCHAR *pszDescription;
    int iAgentPort;
    int iAuthType;
    TCHAR *pszSecret;
index 6f17cc2..e6af1b1 100644 (file)
 #include <netxmsdb.h>
 
 // Define common macros for uncommon data types
-#ifdef DB_MSSQL
-# define DT_TEXT               text
+// and database syntax type
+#if defined(DB_MSSQL)
+
+#define DB_SYNTAX      'MSSQL'
+#define DT_TEXT                text
+
+#elif defined(DB_POSTGRESQL)
+
+#define DB_SYNTAX      'PGSQL'
+#define DT_TEXT                varchar // change it to oid?
+
 #else
-# ifdef DB_POSTGRESQL
-#  define DT_TEXT              varchar // change it to oid?
-# else
-#  define DT_TEXT              blob
-# endif
+
+#define DB_SYNTAX      'MYSQL'
+#define DT_TEXT                blob
+
 #endif
 
 // String concatenation for multi-line texts
index 1140e4e..feff165 100644 (file)
@@ -111,6 +111,7 @@ CREATE TABLE nodes
        status_poll_type integer,
        inherit_access_rights integer,
        image_id integer,
+       description TEXT,
        PRIMARY KEY(id)
 );
 
@@ -181,6 +182,8 @@ CREATE TABLE templates
        name varchar(63),
        is_deleted integer not null,
        image_id integer,
+       version integer,
+       description TEXT,
        PRIMARY KEY(id)
 );
 
index dc75d1b..2f7a9c2 100644 (file)
@@ -7,6 +7,8 @@
 INSERT INTO config (var_name,var_value,is_visible,need_server_restart)
        VALUES ('DBFormatVersion',DB_FORMAT_VERSION,0,1);
 INSERT INTO config (var_name,var_value,is_visible,need_server_restart)
+       VALUES ('DBSyntax',DB_SYNTAX,0,1);
+INSERT INTO config (var_name,var_value,is_visible,need_server_restart)
        VALUES ('SyncInterval','60',1,1);
 INSERT INTO config (var_name,var_value,is_visible,need_server_restart)
        VALUES ('NewNodePollingInterval','60',1,1);
index 9d081f5..a65d2c9 100644 (file)
@@ -53,6 +53,8 @@ BEGIN_MESSAGE_MAP(CDataCollectionEditor, CMDIChildWnd)
        ON_COMMAND(ID_ITEM_GRAPH, OnItemGraph)
        ON_UPDATE_COMMAND_UI(ID_ITEM_GRAPH, OnUpdateItemGraph)
        ON_COMMAND(ID_ITEM_COPY, OnItemCopy)
+       ON_COMMAND(ID_FILE_EXPORT, OnFileExport)
+       ON_UPDATE_COMMAND_UI(ID_FILE_EXPORT, OnUpdateFileExport)
        //}}AFX_MSG_MAP
        ON_NOTIFY(NM_DBLCLK, IDC_LIST_VIEW, OnListViewDblClk)
 END_MESSAGE_MAP()
@@ -379,6 +381,17 @@ void CDataCollectionEditor::OnUpdateItemGraph(CCmdUI* pCmdUI)
    pCmdUI->Enable(m_wndListCtrl.GetSelectedCount() == 1);
 }
 
+void CDataCollectionEditor::OnUpdateFileExport(CCmdUI* pCmdUI) 
+{
+   NXC_OBJECT *pObject;
+
+   pObject = NXCFindObjectById(m_pItemList->dwNodeId);
+   if (pObject != NULL)
+      pCmdUI->Enable(pObject->iClass == OBJECT_TEMPLATE);
+   else
+      pCmdUI->Enable(FALSE);
+}
+
 
 //
 // Clear list view selection and select specified item
@@ -547,3 +560,21 @@ void CDataCollectionEditor::OnItemCopy()
       free(pdwItemList);
    }
 }
+
+
+//
+// WM_COMMAND::ID_FILE_EXPORT message handler
+//
+
+void CDataCollectionEditor::OnFileExport() 
+{
+   CFileDialog dlg(FALSE);
+
+   dlg.m_ofn.lpstrDefExt = _T("dct");
+   dlg.m_ofn.Flags |= OFN_HIDEREADONLY | OFN_NOCHANGEDIR | OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST;
+   dlg.m_ofn.lpstrFilter = _T("Data Collection Templates (*.dct)\0*.dct\0XML Files (*.xml)\0*.xml\0All Files (*.*)\0*.*\0");
+   if (dlg.DoModal() == IDOK)
+   {
+      MessageBox(dlg.m_ofn.lpstrFile,"FILE");
+   }
+}
index 41c89dd..91b48fb 100644 (file)
@@ -58,6 +58,8 @@ protected:
        afx_msg void OnItemGraph();
        afx_msg void OnUpdateItemGraph(CCmdUI* pCmdUI);
        afx_msg void OnItemCopy();
+       afx_msg void OnFileExport();
+       afx_msg void OnUpdateFileExport(CCmdUI* pCmdUI);
        //}}AFX_MSG
    afx_msg void OnListViewDblClk(LPNMITEMACTIVATE pNMHDR, LRESULT *pResult);
        DECLARE_MESSAGE_MAP()
index ea93e61..833bc5e 100644 (file)
@@ -17,20 +17,20 @@ Class9=CMapView
 
 ResourceCount=86
 Resource1=IDD_THRESHOLD (English (U.S.))
-Resource2=IDD_THRESHOLD
+Resource2=IDD_CREATE_NODE
 Resource3=IDM_VIEW_SPECIFIC (English (U.S.))
-Resource4=IDD_REQUEST_PROCESSING
-Resource5=IDD_ABOUTBOX
+Resource4=IDD_EDIT_RULE_COMMENT
+Resource5=IDD_DCI_COLLECTION
 Class2=CChildView
 Class5=CAboutDlg
 Class6=CControlPanel
 Class8=CMapFrame
 Class10=CLoginDialog
-Resource6=IDD_CREATE_TG
+Resource6=IDD_OBJECT_GENERAL
 Class11=CProgressDialog
-Resource7=IDD_OBJECT_GENERAL
+Resource7=IDD_SELECT_EVENT
 Class12=CObjectBrowser
-Resource8=IDA_NETMAP
+Resource8=IDD_SET_PASSWORD
 Class13=CObjectPropDlg
 Resource9=IDD_CP_GENERAL (English (U.S.))
 Resource10=IDA_OBJECT_BROWSER (English (U.S.))
@@ -46,7 +46,7 @@ Resource17=IDD_SET_PASSWORD (English (U.S.))
 Class16=CDebugFrame
 Resource18=IDD_OBJECT_SECURITY (English (U.S.))
 Resource19=IDD_OBJECT_PROPERTIES (English (U.S.))
-Resource20=IDD_CREATE_NODE
+Resource20=IDD_OBJECT_CAPS
 Class17=CObjectPreview
 Resource21=IDD_DCI_TRANSFORM (English (U.S.))
 Class18=CToolBox
@@ -59,32 +59,32 @@ Class23=CNodePropsGeneral
 Resource23=IDD_LOGIN (English (U.S.))
 Class24=CObjectPropCaps
 Class25=CObjectPropSheet
-Resource24=IDD_SELECT_EVENT
+Resource24=IDA_MDI_DEFAULT
 Class26=CRequestProcessingDlg
 Resource25=IDD_EDIT_EVENT (English (U.S.))
 Resource26=IDD_PROGRESS (English (U.S.))
-Resource27=IDD_DCI_COLLECTION
+Resource27=IDD_SELECT_ACTION
 Resource28=IDD_USER_PROPERTIES (English (U.S.))
 Class27=CObjectPropsGeneral
 Resource29=IDA_ALARM_BROWSER (English (U.S.))
 Class28=CObjectPropsSecurity
 Resource30=IDD_CREATE_NODE (English (U.S.))
-Resource31=IDA_OBJECT_BROWSER
-Resource32=IDD_LOGIN
+Resource31=IDD_NEW_USER
+Resource32=IDD_DCI_THRESHOLDS
 Class29=CUserSelectDlg
-Resource33=IDD_DCI_TRANSFORM
+Resource33=IDD_REQUEST_PROCESSING
 Class30=CUserEditor
 Resource34=IDD_DCI_PROPERTIES
 Class31=CNewUserDlg
-Resource35=IDD_MIB_BROWSER
-Resource36=IDD_DCI_THRESHOLDS
+Resource35=IDD_DCI_TRANSFORM
+Resource36=IDD_CREATE_CONTAINER
 Class32=CUserPropDlg
 Resource37=IDM_CONTEXT (English (U.S.))
-Resource38=IDD_NEW_USER
+Resource38=IDD_EDIT_RULE_ALARM
 Class33=CGroupPropDlg
-Resource39=IDD_OBJECT_CAPS
-Resource40=IDD_SELECT_OBJECT
-Resource41=IDD_SET_PASSWORD
+Resource39=IDD_SELECT_OBJECT
+Resource40=IDD_CREATE_TG
+Resource41=IDD_ACTION_PROPERTIES
 Resource42=IDD_SELECT_OBJECT (English (U.S.))
 Class34=CPasswordChangeDlg
 Class35=CNodeSummary
@@ -100,55 +100,55 @@ Class41=CGraphFrame
 Class42=CDCIThresholdsPage
 Resource46=IDA_MDI_DEFAULT (English (U.S.))
 Resource47=IDD_OBJECT_CAPS (English (U.S.))
-Resource48=IDD_ACTION_PROPERTIES
+Resource48=IDD_LOGIN
 Class43=CThresholdDlg
 Resource49=IDD_SELECT_USER (English (U.S.))
-Resource50=IDA_MDI_DEFAULT
+Resource50=IDD_SELECT_USER
 Class44=CMIBBrowserDlg
 Class45=CEventPolicyEditor
 Class46=CRuleList
 Class47=CRuleHeader
 Resource51=IDR_MAINFRAME (English (U.S.))
-Resource52=IDD_EDIT_RULE_SEVERITY
+Resource52=IDA_EPP
 Class48=CObjectSelDlg
-Resource53=IDD_OBJECT_PRESENTATION
-Resource54=IDM_VIEW_SPECIFIC
+Resource53=IDA_OBJECT_BROWSER
+Resource54=IDM_CONTEXT
 Class49=CRuleCommentDlg
-Resource55=IDD_SELECT_ACTION
+Resource55=IDD_EDIT_EVENT
 Class50=CEventSelDlg
-Resource56=IDD_EDIT_EVENT
+Resource56=IDD_THRESHOLD
 Resource57=IDD_REQUEST_PROCESSING (English (U.S.))
-Resource58=IDA_EPP
+Resource58=IDD_USER_PROPERTIES
 Resource59=IDD_ABOUTBOX (English (U.S.))
 Resource60=IDD_MIB_BROWSER (English (U.S.))
 Class51=CObjectPropsPresentation
 Resource61=IDD_OBJECT_PRESENTATION (English (U.S.))
-Resource62=IDD_NEW_ACTION
+Resource62=IDD_ABOUTBOX
 Class52=CRuleSeverityDlg
-Resource63=IDM_CONTEXT
+Resource63=IDM_VIEW_SPECIFIC
 Class53=CRuleAlarmDlg
 Class54=CAlarmBrowser
 Resource64=IDD_SELECT_EVENT (English (U.S.))
-Resource65=IDR_MAINFRAME
+Resource65=IDD_OBJECT_SECURITY
 Resource66=IDD_NEW_ACTION (English (U.S.))
 Resource67=IDD_DCI_COLLECTION (English (U.S.))
 Resource68=IDD_NEW_USER (English (U.S.))
 Class55=CConsolePropsGeneral
 Class56=CActionEditor
-Resource69=IDD_EDIT_RULE_ALARM
-Resource70=IDD_GROUP_PROPERTIES
+Resource69=IDA_ALARM_BROWSER
+Resource70=IDD_NEW_ACTION
 Class57=CNewActionDlg
-Resource71=IDD_OBJECT_SECURITY
+Resource71=IDD_OBJECT_PRESENTATION
 Class58=CEditActionDlg
-Resource72=IDD_EDIT_RULE_COMMENT
+Resource72=IDR_MAINFRAME
 Class59=CActionSelDlg
-Resource73=IDD_USER_PROPERTIES
+Resource73=IDD_CP_GENERAL
 Resource74=IDD_EDIT_RULE_COMMENT (English (U.S.))
 Resource75=IDD_EDIT_RULE_ALARM (English (U.S.))
-Resource76=IDD_OBJECT_NODE_GENERAL
+Resource76=IDD_MIB_BROWSER
 Class60=CCreateObjectDlg
 Class61=CCreateContainerDlg
-Resource77=IDD_CP_GENERAL
+Resource77=IDA_NETMAP
 Class62=CCreateNodeDlg
 Resource78=IDA_EPP (English (U.S.))
 Resource79=IDD_CREATE_CONTAINER (English (U.S.))
@@ -158,11 +158,11 @@ Resource81=IDD_ACTION_PROPERTIES (English (U.S.))
 Class64=CPollNodeDlg
 Resource82=IDD_POLL_NODE (English (U.S.))
 Class65=CNodePoller
-Resource83=IDD_CREATE_CONTAINER
-Resource84=IDA_ALARM_BROWSER
+Resource83=IDD_OBJECT_NODE_GENERAL
+Resource84=IDD_GROUP_PROPERTIES
 Class66=CCreateTemplateDlg
 Class67=CCreateTGDlg
-Resource85=IDD_SELECT_USER
+Resource85=IDD_EDIT_RULE_SEVERITY
 Resource86=IDD_CREATE_TEMPLATE
 
 [CLS:CConsoleApp]
index a4bee17..52da3d1 100644 (file)
@@ -130,8 +130,18 @@ static void ReplaceObject(NXC_OBJECT *pObject, NXC_OBJECT *pNewObject)
 static void DestroyObject(NXC_OBJECT *pObject)
 {
    DebugPrintf(_T("DestroyObject(id:%ld, name:\"%s\")"), pObject->dwId, pObject->szName);
-   if (pObject->iClass == OBJECT_CONTAINER)
-      safe_free(pObject->container.pszDescription);
+   switch(pObject->iClass)
+   {
+      case OBJECT_CONTAINER:
+         safe_free(pObject->container.pszDescription);
+         break;
+      case OBJECT_NODE:
+         safe_free(pObject->node.pszDescription);
+         break;
+      case OBJECT_TEMPLATE:
+         safe_free(pObject->dct.pszDescription);
+         break;
+   }
    safe_free(pObject->pdwChildList);
    safe_free(pObject->pdwParentList);
    safe_free(pObject->pAccessList);
@@ -201,6 +211,7 @@ static NXC_OBJECT *NewObjectFromMsg(CSCPMessage *pMsg)
          pMsg->GetVariableStr(VID_SHARED_SECRET, pObject->node.szSharedSecret, MAX_SECRET_LENGTH);
          pMsg->GetVariableStr(VID_COMMUNITY_STRING, pObject->node.szCommunityString, MAX_COMMUNITY_LENGTH);
          pMsg->GetVariableStr(VID_SNMP_OID, pObject->node.szObjectId, MAX_OID_LENGTH);
+         pObject->node.pszDescription = pMsg->GetVariableStr(VID_DESCRIPTION);
          break;
       case OBJECT_SUBNET:
          pObject->subnet.dwIpNetMask = pMsg->GetVariableLong(VID_IP_NETMASK);
@@ -209,6 +220,10 @@ static NXC_OBJECT *NewObjectFromMsg(CSCPMessage *pMsg)
          pObject->container.dwCategory = pMsg->GetVariableLong(VID_CATEGORY);
          pObject->container.pszDescription = pMsg->GetVariableStr(VID_DESCRIPTION);
          break;
+      case OBJECT_TEMPLATE:
+         pObject->dct.dwVersion = pMsg->GetVariableLong(VID_TEMPLATE_VERSION);
+         pObject->dct.pszDescription = pMsg->GetVariableStr(VID_DESCRIPTION);
+         break;
       default:
          break;
    }
@@ -446,6 +461,8 @@ DWORD LIBNXCL_EXPORTABLE NXCModifyObject(NXC_OBJECT_UPDATE *pUpdate)
       msg.SetVariable(VID_COMMUNITY_STRING, pUpdate->pszCommunity);
    if (pUpdate->dwFlags & OBJ_UPDATE_IMAGE)
       msg.SetVariable(VID_IMAGE_ID, pUpdate->dwImage);
+   if (pUpdate->dwFlags & OBJ_UPDATE_DESCRIPTION)
+      msg.SetVariable(VID_DESCRIPTION, pUpdate->pszDescription);
    if (pUpdate->dwFlags & OBJ_UPDATE_ACL)
    {
       DWORD i, dwId1, dwId2;
index 9dbd336..170cb64 100644 (file)
@@ -172,6 +172,9 @@ protected:
    DWORD m_dwNumItems;     // Number of data collection items
    DCItem **m_ppItems;     // Data collection items
    DWORD m_dwDCILockStatus;
+   DWORD m_dwVersion;
+   TCHAR *m_pszDescription;
+   BOOL m_bDCIListModified;
 
    void LoadItemsFromDB(void);
    void DestroyItems(void);
@@ -186,8 +189,15 @@ public:
    virtual BOOL DeleteFromDB(void);
    virtual BOOL CreateFromDB(DWORD dwId);
 
+   virtual void CreateMessage(CSCPMessage *pMsg);
+   virtual DWORD ModifyFromMessage(CSCPMessage *pRequest, BOOL bAlreadyLocked = FALSE);
+
    virtual void CalculateCompoundStatus(void);
 
+   int VersionMajor(void) { return m_dwVersion >> 16; }
+   int VersionMinor(void) { return m_dwVersion & 0xFFFF; }
+   const TCHAR *Description(void) { return CHECK_NULL(m_pszDescription); }
+
    BOOL AddItem(DCItem *pItem);
    BOOL UpdateItem(DWORD dwItemId, CSCPMessage *pMsg, DWORD *pdwNumMaps, 
                    DWORD **ppdwMapIndex, DWORD **ppdwMapId);
@@ -196,6 +206,7 @@ public:
    const DCItem *GetItemById(DWORD dwItemId);
    BOOL LockDCIList(DWORD dwSessionId);
    BOOL UnlockDCIList(DWORD dwSessionId);
+   void SetDCIModificationFlag(void) { m_bDCIListModified = TRUE; }
    void SendItemsToClient(ClientSession *pSession, DWORD dwRqId);
    BOOL IsLockedBySession(DWORD dwSessionId) { return m_dwDCILockStatus == dwSessionId; }
 };
@@ -468,7 +479,7 @@ public:
    virtual void CreateMessage(CSCPMessage *pMsg);
 
    DWORD Category(void) { return m_dwCategory; }
-   const char *Description(void) { return CHECK_NULL(m_pszDescription); }
+   const TCHAR *Description(void) { return CHECK_NULL(m_pszDescription); }
 
    void LinkChildObjects(void);
    void LinkObject(NetObj *pObject) { AddChild(pObject); pObject->AddParent(this); }
index 4d1c765..55786c0 100644 (file)
@@ -856,7 +856,7 @@ void Node::QueueItemsForPolling(Queue *pPollerQueue)
 
 void Node::CreateMessage(CSCPMessage *pMsg)
 {
-   NetObj::CreateMessage(pMsg);
+   Template::CreateMessage(pMsg);
    pMsg->SetVariable(VID_FLAGS, m_dwFlags);
    pMsg->SetVariable(VID_DISCOVERY_FLAGS, m_dwDiscoveryFlags);
    pMsg->SetVariable(VID_AGENT_PORT, m_wAgentPort);
@@ -892,5 +892,5 @@ DWORD Node::ModifyFromMessage(CSCPMessage *pRequest, BOOL bAlreadyLocked)
    if (pRequest->IsVariableExist(VID_COMMUNITY_STRING))
       pRequest->GetVariableStr(VID_COMMUNITY_STRING, m_szCommunityString, MAX_COMMUNITY_LENGTH);
 
-   return NetObj::ModifyFromMessage(pRequest, TRUE);
+   return Template::ModifyFromMessage(pRequest, TRUE);
 }
index 27914a8..ee8b939 100644 (file)
@@ -666,6 +666,12 @@ void DumpObjects(void)
             printf("   Category: %s\n   Description: %s\n", pCat ? pCat->szName : "<unknown>",
                    ((Container *)g_pIndexById[i].pObject)->Description());
             break;
+         case OBJECT_TEMPLATE:
+            printf("   Version: %d.%d\n   Description: %s\n", 
+                   ((Template *)(g_pIndexById[i].pObject))->VersionMajor(),
+                   ((Template *)(g_pIndexById[i].pObject))->VersionMinor(),
+                   ((Template *)(g_pIndexById[i].pObject))->Description());
+            break;
       }
    }
    MutexUnlock(g_hMutexIdIndex);
index 8e9b356..0cc70a3 100644 (file)
@@ -1630,6 +1630,8 @@ void ClientSession::ModifyNodeDCI(CSCPMessage *pRequest)
                      msg.SetVariable(VID_RCC, bSuccess ? RCC_SUCCESS : RCC_INVALID_DCI_ID);
                      break;
                }
+               if (bSuccess)
+                  ((Template *)pObject)->SetDCIModificationFlag();
             }
             else  // User doesn't have MODIFY rights on object
             {
index aee5337..4c29e5b 100644 (file)
@@ -32,6 +32,8 @@ Template::Template()
    m_dwNumItems = 0;
    m_ppItems = NULL;
    m_dwDCILockStatus = INVALID_INDEX;
+   m_pszDescription = NULL;
+   m_dwVersion = 0x00010000;  // Initial version is 1.0
 }
 
 
@@ -42,6 +44,7 @@ Template::Template()
 Template::~Template()
 {
    DestroyItems();
+   safe_free(m_pszDescription);
 }
 
 
@@ -67,12 +70,12 @@ void Template::DestroyItems(void)
 
 BOOL Template::CreateFromDB(DWORD dwId)
 {
-   char szQuery[256];
+   TCHAR *pszStr, szQuery[256];
    DB_RESULT hResult;
    DWORD i, dwNumNodes, dwNodeId;
    NetObj *pObject;
 
-   sprintf(szQuery, "SELECT id,name,is_deleted,image_id FROM templates WHERE id=%d", dwId);
+   _stprintf(szQuery, _T("SELECT id,name,is_deleted,image_id,version,description FROM templates WHERE id=%d"), dwId);
    hResult = DBSelect(g_hCoreDB, szQuery);
    if (hResult == NULL)
       return FALSE;     // Query failed
@@ -88,6 +91,10 @@ BOOL Template::CreateFromDB(DWORD dwId)
    strncpy(m_szName, DBGetField(hResult, 0, 1), MAX_OBJECT_NAME);
    m_bIsDeleted = DBGetFieldLong(hResult, 0, 2);
    m_dwImageId = DBGetFieldULong(hResult, 0, 3);
+   m_dwVersion = DBGetFieldULong(hResult, 0, 4);
+   pszStr = DBGetField(hResult, 0, 5);
+   m_pszDescription = _tcsdup(CHECK_NULL_EX(pszStr));
+   DecodeSQLString(m_pszDescription);
 
    DBFreeResult(hResult);
 
@@ -97,7 +104,7 @@ BOOL Template::CreateFromDB(DWORD dwId)
    // Load related nodes list
    if (!m_bIsDeleted)
    {
-      sprintf(szQuery, "SELECT node_id FROM dct_node_map WHERE template_id=%d", m_dwId);
+      _stprintf(szQuery, _T("SELECT node_id FROM dct_node_map WHERE template_id=%d"), m_dwId);
       hResult = DBSelect(g_hCoreDB, szQuery);
       if (hResult != NULL)
       {
@@ -137,7 +144,7 @@ BOOL Template::CreateFromDB(DWORD dwId)
 
 BOOL Template::SaveToDB(void)
 {
-   char szQuery[1024];
+   TCHAR *pszEscDescr, szQuery[1024];
    DB_RESULT hResult;
    DWORD i;
    BOOL bNewObject = TRUE;
@@ -146,7 +153,7 @@ BOOL Template::SaveToDB(void)
    Lock();
 
    // Check for object's existence in database
-   sprintf(szQuery, "SELECT id FROM templates WHERE id=%ld", m_dwId);
+   _stprintf(szQuery, _T("SELECT id FROM templates WHERE id=%ld"), m_dwId);
    hResult = DBSelect(g_hCoreDB, szQuery);
    if (hResult != 0)
    {
@@ -156,13 +163,17 @@ BOOL Template::SaveToDB(void)
    }
 
    // Form and execute INSERT or UPDATE query
+   pszEscDescr = EncodeSQLString(CHECK_NULL_EX(m_pszDescription));
    if (bNewObject)
-      sprintf(szQuery, "INSERT INTO templates (id,name,is_deleted,image_id) VALUES (%ld,'%s',%d,%ld)",
-              m_dwId, m_szName, m_bIsDeleted, m_dwImageId);
+      sprintf(szQuery, "INSERT INTO templates (id,name,is_deleted,image_id,version,"
+                       "description) VALUES (%ld,'%s',%d,%ld,%ld,'%s')",
+              m_dwId, m_szName, m_bIsDeleted, m_dwImageId, m_dwVersion, pszEscDescr);
    else
-      sprintf(szQuery, "UPDATE templates SET name='%s',is_deleted=%d,image_id=%ld WHERE id=%ld",
-              m_szName, m_bIsDeleted, m_dwImageId, m_dwId);
+      sprintf(szQuery, "UPDATE templates SET name='%s',is_deleted=%d,image_id=%ld,"
+                       "version=%ld,description='%s' WHERE id=%ld",
+              m_szName, m_bIsDeleted, m_dwImageId, m_dwVersion, pszEscDescr, m_dwId);
    DBQuery(g_hCoreDB, szQuery);
+   free(pszEscDescr);
 
    // Update members list
    sprintf(szQuery, "DELETE FROM dct_node_map WHERE template_id=%d", m_dwId);
@@ -346,6 +357,7 @@ BOOL Template::LockDCIList(DWORD dwSessionId)
    if (m_dwDCILockStatus == INVALID_INDEX)
    {
       m_dwDCILockStatus = dwSessionId;
+      m_bDCIListModified = FALSE;
       bSuccess = TRUE;
    }
    Unlock();
@@ -365,6 +377,12 @@ BOOL Template::UnlockDCIList(DWORD dwSessionId)
    if (m_dwDCILockStatus == dwSessionId)
    {
       m_dwDCILockStatus = INVALID_INDEX;
+      if (m_bDCIListModified && (Type() == OBJECT_TEMPLATE))
+      {
+         m_dwVersion++;
+         Modify();
+      }
+      m_bDCIListModified = FALSE;
       bSuccess = TRUE;
    }
    Unlock();
@@ -453,3 +471,39 @@ void Template::CalculateCompoundStatus(void)
 {
    m_iStatus = STATUS_UNMANAGED;
 }
+
+
+//
+// Create CSCP message with object's data
+//
+
+void Template::CreateMessage(CSCPMessage *pMsg)
+{
+   NetObj::CreateMessage(pMsg);
+   pMsg->SetVariable(VID_TEMPLATE_VERSION, m_dwVersion);
+   pMsg->SetVariable(VID_DESCRIPTION, CHECK_NULL_EX(m_pszDescription));
+}
+
+
+//
+// Modify object from message
+//
+
+DWORD Template::ModifyFromMessage(CSCPMessage *pRequest, BOOL bAlreadyLocked)
+{
+   if (!bAlreadyLocked)
+      Lock();
+
+   // Change template version
+   if (pRequest->IsVariableExist(VID_TEMPLATE_VERSION))
+      m_dwVersion = pRequest->GetVariableLong(VID_TEMPLATE_VERSION);
+
+   // Change description
+   if (pRequest->IsVariableExist(VID_DESCRIPTION))
+   {
+      safe_free(m_pszDescription);
+      m_pszDescription = pRequest->GetVariableStr(VID_DESCRIPTION);
+   }
+
+   return NetObj::ModifyFromMessage(pRequest, TRUE);
+}