- Added transaction support (not all DB drivetrs yet)
authorVictor Kirhenshtein <victor@netxms.org>
Mon, 7 Aug 2006 09:47:04 +0000 (09:47 +0000)
committerVictor Kirhenshtein <victor@netxms.org>
Mon, 7 Aug 2006 09:47:04 +0000 (09:47 +0000)
- Recursive mutexes now used
- Implemented changing of agent config sequence number
- Other minor changes

22 files changed:
include/nms_common.h
include/nms_cscp.h
include/nms_threads.h
include/nms_util.h
include/nxclapi.h
src/console/win32/AgentConfigMgr.cpp
src/console/win32/AgentConfigMgr.h
src/console/win32/nxcon.clw
src/libnetxms/hash.cpp
src/libnetxms/icmp.cpp
src/libnetxms/tools.cpp
src/libnxcl/agentcfg.cpp
src/server/core/dcitem.cpp
src/server/core/hk.cpp
src/server/core/session.cpp
src/server/dbdrv/pgsql/pgsql.cpp
src/server/dbdrv/pgsql/pgsqldrv.h
src/server/include/dbdrv.h
src/server/include/nms_core.h
src/server/include/nxsrvapi.h
src/server/libnxsrv/db.cpp
src/server/libnxsrv/libnxsrv.dsp

index 1ad18fc..6e1c5e4 100644 (file)
@@ -127,6 +127,7 @@ typedef int socklen_t;
 #define SHUT_RDWR    2
 
 #define SetSocketReuseFlag(sd)
+#define SELECT_NFDS(x)  ((int)(x))
 
 #ifdef UNDER_CE
 #define O_RDONLY     0x0004
@@ -209,6 +210,8 @@ typedef int SOCKET;
                        (socklen_t)sizeof(nVal)); \
 }
 
+#define SELECT_NFDS(x)  (x)
+
 #else    /* not _WIN32 and not _NETWARE */
 
 /*********** UNIX *********************/
@@ -323,6 +326,8 @@ typedef int SOCKET;
                        (socklen_t)sizeof(nVal)); \
 }
 
+#define SELECT_NFDS(x)  (x)
+
 #if !(HAVE_SOCKLEN_T)
 typedef int socklen_t;
 #endif
index be18c66..0ff9535 100644 (file)
@@ -414,6 +414,7 @@ typedef struct
 #define CMD_OPEN_AGENT_CONFIG       0x00B1
 #define CMD_SAVE_AGENT_CONFIG       0x00B2
 #define CMD_DELETE_AGENT_CONFIG     0x00B3
+#define CMD_SWAP_AGENT_CONFIGS      0x00B4
 
 
 //
@@ -656,6 +657,7 @@ typedef struct
 #define VID_VERSION_MAJOR           ((DWORD)234)
 #define VID_VERSION_MINOR           ((DWORD)235)
 #define VID_VERSION_RELEASE         ((DWORD)236)
+#define VID_CONFIG_ID_2             ((DWORD)237)
 
 // Variable ranges for object's ACL
 #define VID_ACL_USER_BASE           ((DWORD)0x00001000)
index 3afab47..196edef 100644 (file)
@@ -125,6 +125,11 @@ inline MUTEX MutexCreate(void)
    return CreateMutex(NULL, FALSE, NULL);
 }
 
+inline MUTEX MutexCreateRecursive(void)
+{
+   return CreateMutex(NULL, FALSE, NULL);
+}
+
 inline void MutexDestroy(MUTEX mutex)
 {
    CloseHandle(mutex);
@@ -185,15 +190,23 @@ inline BOOL ConditionWait(CONDITION hCond, DWORD dwTimeOut)
 //
 
 typedef pthread_t THREAD;
-typedef pthread_mutex_t * MUTEX;
-struct condition_t
+struct netxms_mutex_t
+{
+   pthread_mutex_t mutex;
+#ifndef HAVE_RECURSIVE_MUTEXES
+   BOOL isRecursive;
+   pthread_t owner;
+#endif
+};
+typedef netxms_mutex_t * MUTEX;
+struct netxms_condition_t
 {
        pthread_cond_t cond;
        pthread_mutex_t mutex;
        BOOL broadcast;
    BOOL isSet;
 };
-typedef struct condition_t * CONDITION;
+typedef struct netxms_condition_t * CONDITION;
 
 #define INVALID_MUTEX_HANDLE        (NULL)
 #define INVALID_CONDITION_HANDLE    (NULL)
@@ -277,16 +290,38 @@ inline MUTEX MutexCreate(void)
 {
    MUTEX mutex;
 
-   mutex = (MUTEX)malloc(sizeof(pthread_mutex_t));
+   mutex = (MUTEX)malloc(sizeof(netxms_mutex_t));
    if (mutex != NULL)
-      pthread_mutex_init(mutex, NULL);
+      pthread_mutex_init(mutex->mutex, NULL);
+   return mutex;
+}
+
+inline MUTEX MutexCreateRecursive(void)
+{
+   MUTEX mutex;
+
+   mutex = (MUTEX)malloc(sizeof(netxms_mutex_t));
+   if (mutex != NULL)
+   {
+#ifdef HAVE_RECURSIVE_MUTEXES
+      pthread_mutexattr_t a;
+
+      pthread_mutexattr_init(&a);
+      pthread_mutexattr_settype(&a, PTHREAD_MUTEX_RECURSIVE);
+      pthread_mutex_init(&mutex->mutex, &a);
+      pthread_mutexattr_destroy(&a);
+#else
+#error FIXME: implement recursive mutexes
+#endif
+   }
    return mutex;
 }
 
 inline void MutexDestroy(MUTEX mutex)
 {
-   if (mutex != NULL) {
-      pthread_mutex_destroy(mutex);
+   if (mutex != NULL)
+   {
+      pthread_mutex_destroy(&mutex->mutex);
       free(mutex);
    }
 }
@@ -296,17 +331,20 @@ inline BOOL MutexLock(MUTEX mutex, DWORD dwTimeOut)
        int i;
        int ret = FALSE;
 
-   if (mutex != NULL) {
+   if (mutex != NULL)
+   {
                if (dwTimeOut == INFINITE)
                {
-                       if (pthread_mutex_lock(mutex) == 0) {
+                       if (pthread_mutex_lock(&mutex->mutex) == 0)
+         {
                                ret = TRUE;
                        }
                }
                else
                {
-                       for (i = (dwTimeOut / 50) + 1; i > 0; i--) {
-                               if (pthread_mutex_trylock(mutex) == 0) 
+                       for (i = (dwTimeOut / 50) + 1; i > 0; i--)
+         {
+                               if (pthread_mutex_trylock(&mutex->mutex) == 0) 
             {
                                        ret = TRUE;
                                        break;
@@ -322,7 +360,7 @@ inline void MutexUnlock(MUTEX mutex)
 {
    if (mutex != NULL) 
    {
-      pthread_mutex_unlock(mutex);
+      pthread_mutex_unlock(&mutex->mutex);
        }
 }
 
@@ -330,7 +368,7 @@ inline CONDITION ConditionCreate(BOOL bBroadcast)
 {
        CONDITION cond;
 
-   cond = (CONDITION)malloc(sizeof(struct condition_t));
+   cond = (CONDITION)malloc(sizeof(struct netxms_condition_t));
    if (cond != NULL) 
    {
       pthread_cond_init(&cond->cond, NULL);
index 8b2cc53..33e390a 100644 (file)
@@ -286,8 +286,8 @@ extern "C"
    void LIBNETXMS_EXPORTABLE GetOSVersionString(TCHAR *pszBuffer);
    
    DWORD LIBNETXMS_EXPORTABLE CalculateCRC32(const unsigned char *pData, DWORD dwSize, DWORD dwCRC);
-   void LIBNETXMS_EXPORTABLE CalculateMD5Hash(const unsigned char *data, int nbytes, unsigned char *hash);
-   void LIBNETXMS_EXPORTABLE CalculateSHA1Hash(unsigned char *data, int nbytes, unsigned char *hash);
+   void LIBNETXMS_EXPORTABLE CalculateMD5Hash(const unsigned char *data, size_t nbytes, unsigned char *hash);
+   void LIBNETXMS_EXPORTABLE CalculateSHA1Hash(unsigned char *data, size_t nbytes, unsigned char *hash);
    BOOL LIBNETXMS_EXPORTABLE CalculateFileMD5Hash(TCHAR *pszFileName, BYTE *pHash);
    BOOL LIBNETXMS_EXPORTABLE CalculateFileSHA1Hash(TCHAR *pszFileName, BYTE *pHash);
    BOOL LIBNETXMS_EXPORTABLE CalculateFileCRC32(TCHAR *pszFileName, DWORD *pResult);
index b7adedc..50f1d7e 100644 (file)
@@ -1666,6 +1666,7 @@ DWORD LIBNXCL_EXPORTABLE NXCOpenAgentConfig(NXC_SESSION hSession, DWORD dwCfgId,
                                             NXC_AGENT_CONFIG *pConfig);
 DWORD LIBNXCL_EXPORTABLE NXCSaveAgentConfig(NXC_SESSION hSession, NXC_AGENT_CONFIG *pConfig);
 DWORD LIBNXCL_EXPORTABLE NXCDeleteAgentConfig(NXC_SESSION hSession, DWORD dwCfgId);
+DWORD LIBNXCL_EXPORTABLE NXCSwapAgentConfigs(NXC_SESSION hSession, DWORD dwCfgId1, DWORD dwCfgId2);
 
 #ifdef __cplusplus
 }
index 29a49e4..36351e9 100644 (file)
@@ -45,6 +45,8 @@ BEGIN_MESSAGE_MAP(CAgentConfigMgr, CMDIChildWnd)
        ON_COMMAND(ID_CONFIG_NEW, OnConfigNew)
        ON_COMMAND(ID_CONFIG_EDIT, OnConfigEdit)
        ON_COMMAND(ID_CONFIG_DELETE, OnConfigDelete)
+       ON_COMMAND(ID_CONFIG_MOVEUP, OnConfigMoveup)
+       ON_COMMAND(ID_CONFIG_MOVEDOWN, OnConfigMovedown)
        //}}AFX_MSG_MAP
        ON_NOTIFY(NM_DBLCLK, ID_LIST_VIEW, OnListViewDblClk)
        ON_NOTIFY(LVN_COLUMNCLICK, ID_LIST_VIEW, OnListViewColumnClick)
@@ -405,3 +407,72 @@ void CAgentConfigMgr::OnListViewColumnClick(LPNMLISTVIEW pNMHDR, LRESULT *pResul
    
    *pResult = 0;
 }
+
+
+//
+// Handler for "Config->Move up" menu
+//
+
+void CAgentConfigMgr::OnConfigMoveup() 
+{
+   int nItem;
+
+   nItem = m_wndListCtrl.GetSelectionMark();
+   if (nItem > 0)
+      SwapItems(nItem, nItem - 1);
+}
+
+
+//
+// Handler for "Config->Move down" menu
+//
+
+void CAgentConfigMgr::OnConfigMovedown() 
+{
+   int nItem;
+
+   nItem = m_wndListCtrl.GetSelectionMark();
+   if (nItem < m_wndListCtrl.GetItemCount() - 1)
+      SwapItems(nItem, nItem + 1);
+}
+
+
+//
+// Swap sequence numbers for two items
+//
+
+void CAgentConfigMgr::SwapItems(int nItem1, int nItem2)
+{
+   DWORD dwResult, dwId1, dwId2;
+   TCHAR szBuffer[32], szBuf1[256], szBuf2[256];
+   int nItem;
+
+   dwId1 = m_wndListCtrl.GetItemData(nItem1);
+   dwId2 = m_wndListCtrl.GetItemData(nItem2);
+   dwResult = DoRequestArg3(NXCSwapAgentConfigs, g_hSession, (void *)dwId1,
+                            (void *)dwId2, _T("Changing sequence of agent config..."));
+   if (dwResult == RCC_SUCCESS)
+   {
+      m_wndListCtrl.GetItemText(nItem1, 1, szBuf1, 256);
+      m_wndListCtrl.GetItemText(nItem2, 1, szBuf2, 256);
+      m_wndListCtrl.SetItemText(nItem1, 1, szBuf2);
+      if (m_iSortMode == 1)
+      {
+         m_wndListCtrl.GetItemText(nItem2, 2, szBuf2, 256);
+         m_wndListCtrl.DeleteItem(nItem2);
+
+         _stprintf(szBuffer, _T("%d"), dwId2);
+         nItem = m_wndListCtrl.InsertItem(nItem1, szBuffer, -1);
+         m_wndListCtrl.SetItemText(nItem, 1, szBuf1);
+         m_wndListCtrl.SetItemText(nItem, 2, szBuf2);
+         m_wndListCtrl.SetItemData(nItem, dwId2);
+      }
+      else
+      {
+      }
+   }
+   else
+   {
+      theApp.ErrorBox(dwResult, _T("Cannot change sequence number of agent config: %s"));
+   }
+}
index 5e3a894..a970ce6 100644 (file)
@@ -31,6 +31,7 @@ public:
 
 // Implementation
 protected:
+       void SwapItems(int nItem1, int nItem2);
        void EditConfig(NXC_AGENT_CONFIG *pConfig);
        int m_iSortMode;
        int m_iSortDir;
@@ -53,6 +54,8 @@ protected:
        afx_msg void OnConfigNew();
        afx_msg void OnConfigEdit();
        afx_msg void OnConfigDelete();
+       afx_msg void OnConfigMoveup();
+       afx_msg void OnConfigMovedown();
        //}}AFX_MSG
    afx_msg void OnListViewDblClk(LPNMITEMACTIVATE pNMHDR, LRESULT *pResult);
    afx_msg void OnListViewColumnClick(LPNMLISTVIEW pNMHDR, LRESULT *pResult);
index c14fc32..bc960de 100644 (file)
@@ -17,20 +17,20 @@ Class9=CMapView
 
 ResourceCount=179
 Resource1=IDD_CP_GENERAL (English (U.S.))
-Resource2=IDD_OBJECT_PRESENTATION
+Resource2=IDD_SELECT_EVENT
 Resource3=IDD_DCI_DATA_EXPORT (English (U.S.))
-Resource4=IDD_SET_PASSWORD
-Resource5=IDD_CP_GENERAL
+Resource4=IDD_GROUP_PROPERTIES
+Resource5=IDD_EDIT_RULE_ALARM
 Class2=CChildView
 Class5=CAboutDlg
 Class6=CControlPanel
 Class8=CMapFrame
 Class10=CLoginDialog
-Resource6=IDD_OBJECT_COND_SCRIPT
+Resource6=IDD_OBJECT_COND_GENERAL
 Class11=CProgressDialog
-Resource7=IDA_AGENT_CONFIG_MANAGER
+Resource7=IDA_DATA_VIEW
 Class12=CObjectBrowser
-Resource8=IDA_ACTION_EDITOR
+Resource8=IDA_EVENT_EDITOR
 Class13=CObjectPropDlg
 Resource9=IDD_THRESHOLD (English (U.S.))
 Resource10=IDD_SELECT_OBJECT (English (U.S.))
@@ -46,45 +46,45 @@ Resource17=IDD_NEW_USER (English (U.S.))
 Class16=CDebugFrame
 Resource18=IDD_NEW_ACTION (English (U.S.))
 Resource19=IDD_OBJECT_PROPERTIES (English (U.S.))
-Resource20=IDD_GRAPH_PROP_SETTINGS
+Resource20=IDD_DESKTOP_SAVE_AS
 Class17=CObjectPreview
 Resource21=IDA_OBJECT_BROWSER (English (U.S.))
 Class18=CToolBox
 Class19=CObjectInfoBox
 Class20=CObjectSearchBox
-Resource22=IDD_CREATE_TEMPLATE
+Resource22=IDD_CREATE_TG
 Class21=CEditBox
 Class22=COPGeneral
 Class23=CNodePropsGeneral
 Resource23=IDD_GRAPH_PROPERTIES (English (U.S.))
 Class24=CObjectPropCaps
 Class25=CObjectPropSheet
-Resource24=IDD_SELECT_INTERNAL_ITEM
+Resource24=IDD_EDIT_TRAP_ARG
 Class26=CRequestProcessingDlg
 Resource25=IDD_SELECT_USER (English (U.S.))
 Resource26=IDD_PROGRESS (English (U.S.))
-Resource27=IDD_EDIT_RULE_SEVERITY
+Resource27=IDD_OBJECT_PRESENTATION
 Resource28=IDD_DCI_COLLECTION (English (U.S.))
 Class27=CObjectPropsGeneral
 Resource29=IDR_MAINFRAME (English (U.S.))
 Class28=CObjectPropsSecurity
 Resource30=IDD_SAVE_AGENT_CFG (English (U.S.))
-Resource31=IDA_DATA_VIEW
-Resource32=IDD_SUBMAP_BKGND
+Resource31=IDA_SCRIPT_MANAGER
+Resource32=IDD_SNMP_WALK
 Class29=CUserSelectDlg
-Resource33=IDD_USER_PROPERTIES
+Resource33=IDD_NEW_USER
 Class30=CUserEditor
 Resource34=IDD_DCI_PROPERTIES
 Class31=CNewUserDlg
-Resource35=IDD_OBJECT_GENERAL
-Resource36=IDD_COND_DCI_PROP
+Resource35=IDD_REQUEST_PROCESSING
+Resource36=IDD_ADD_DCI
 Class32=CUserPropDlg
 Resource37=IDD_EDIT_VARIABLE (English (U.S.))
-Resource38=IDA_AGENT_CFG_EDITOR
+Resource38=IDA_SERVER_CFG_EDITOR
 Class33=CGroupPropDlg
-Resource39=IDD_SELECT_EVENT
-Resource40=IDA_EPP
-Resource41=IDD_GROUP_PROPERTIES
+Resource39=IDD_EDIT_RULE_COMMENT
+Resource40=IDA_OBJECT_BROWSER
+Resource41=IDD_USER_PROPERTIES
 Resource42=IDA_ACTION_EDITOR (English (U.S.))
 Class34=CPasswordChangeDlg
 Class35=CNodeSummary
@@ -100,55 +100,55 @@ Class41=CGraphFrame
 Class42=CDCIThresholdsPage
 Resource46=IDA_OBJECT_TOOLS_EDITOR (English (U.S.))
 Resource47=IDM_CONTEXT (English (U.S.))
-Resource48=IDD_ADD_DCI
+Resource48=IDD_OBJECT_COND_DATA
 Class43=CThresholdDlg
 Resource49=IDD_DESKTOP_SAVE_AS (English (U.S.))
-Resource50=IDD_EDIT_TRAP
+Resource50=IDD_DATA_QUERY
 Class44=CMIBBrowserDlg
 Class45=CEventPolicyEditor
 Class46=CRuleList
 Class47=CRuleHeader
 Resource51=IDD_SELECT_AGENT_PARAM (English (U.S.))
-Resource52=IDD_EDIT_TRAP_ARG
+Resource52=IDD_EDIT_TRAP
 Class48=CObjectSelDlg
-Resource53=IDA_EVENT_EDITOR
-Resource54=IDD_DESKTOP_SAVE_AS
+Resource53=IDA_NETMAP
+Resource54=IDD_OBJECT_RELATIONS
 Class49=CRuleCommentDlg
-Resource55=IDD_OBJECT_NODE_POLL
+Resource55=IDD_OBJECT_NETSRV_GENERAL
 Class50=CEventSelDlg
-Resource56=IDD_DCI_TRANSFORM
+Resource56=IDD_CREATE_NODE
 Resource57=IDA_EPP (English (U.S.))
-Resource58=IDA_LAST_VALUES
+Resource58=IDA_PACKAGE_MGR
 Resource59=IDA_PACKAGE_MGR (English (U.S.))
 Resource60=IDD_OBJTOOL_GENERAL (English (U.S.))
 Class51=CObjectPropsPresentation
 Resource61=IDD_CREATE_TEMPLATE (English (U.S.))
-Resource62=IDD_DCI_THRESHOLDS
+Resource62=IDD_DCI_COLLECTION
 Class52=CRuleSeverityDlg
-Resource63=IDD_EDIT_IP_SUBNET
+Resource63=IDD_OBJECT_VPNC_GENERAL
 Class53=CRuleAlarmDlg
 Class54=CAlarmBrowser
 Resource64=IDA_MDI_DEFAULT (English (U.S.))
-Resource65=IDD_ABOUTBOX
+Resource65=IDA_AGENT_CONFIG_MANAGER
 Resource66=IDD_EDIT_IP_SUBNET (English (U.S.))
 Resource67=IDD_EDIT_RULE_SEVERITY (English (U.S.))
 Resource68=IDD_ACTION_PROPERTIES (English (U.S.))
 Class55=CConsolePropsGeneral
 Class56=CActionEditor
-Resource69=IDA_MDI_DEFAULT
-Resource70=IDD_ACTION_PROPERTIES
+Resource69=IDR_MAINFRAME
+Resource70=IDD_NEW_ACTION
 Class57=CNewActionDlg
-Resource71=IDA_SCRIPT_MANAGER
+Resource71=IDA_OBJECT_TOOLS_EDITOR
 Class58=CEditActionDlg
-Resource72=IDA_DC_EDITOR
+Resource72=IDA_AGENT_CFG_EDITOR
 Class59=CActionSelDlg
-Resource73=IDD_THRESHOLD
+Resource73=IDD_DCI_THRESHOLDS
 Resource74=IDD_EDIT_TRAP (English (U.S.))
 Resource75=IDD_USER_PROPERTIES (English (U.S.))
-Resource76=IDD_SELECT_AGENT_PARAM
+Resource76=IDD_SELECT_INTERNAL_ITEM
 Class60=CCreateObjectDlg
 Class61=CCreateContainerDlg
-Resource77=IDD_OBJECT_COND_GENERAL
+Resource77=IDD_CREATE_CONDITION
 Class62=CCreateNodeDlg
 Resource78=IDD_OBJECT_NODE_GENERAL (English (U.S.))
 Resource79=IDT_MAP (English (U.S.))
@@ -158,31 +158,31 @@ Resource81=IDD_LASTVAL_PROP (English (U.S.))
 Class64=CPollNodeDlg
 Resource82=IDD_POLL_NODE (English (U.S.))
 Class65=CNodePoller
-Resource83=IDD_MIB_BROWSER
-Resource84=IDD_EDIT_EVENT
+Resource83=IDD_THRESHOLD
+Resource84=IDD_ABOUTBOX
 Class66=CCreateTemplateDlg
 Class67=CCreateTGDlg
-Resource85=IDM_CONTEXT
-Resource86=IDA_OBJECT_TOOLS_EDITOR
+Resource85=IDM_VIEW_SPECIFIC
+Resource86=IDA_DC_EDITOR
 Class68=CTrapEditor
-Resource87=IDD_OBJECT_COND_DATA
-Resource88=IDD_SELECT_USER
-Resource89=IDD_OBJTOOL_GENERAL
+Resource87=IDD_OBJECT_COND_SCRIPT
+Resource88=IDD_OBJECT_SECURITY
+Resource89=IDD_OBJECT_STATUS
 Class69=CDataQueryDlg
-Resource90=IDD_SELECT_OBJECT
+Resource90=IDD_MIB_BROWSER
 Class70=CTrapEditDlg
 Resource91=IDM_VIEW_SPECIFIC (English (U.S.))
 Class71=CTrapParamDlg
-Resource92=IDA_SERVER_CFG_EDITOR
-Resource93=IDA_ALARM_BROWSER
+Resource92=IDA_LAST_VALUES
+Resource93=IDA_EPP
 Class72=CGraphPropDlg
 Class73=CColorSelector
 Class74=CPackageMgr
-Resource94=IDD_NEW_OBJECT_TOOL
+Resource94=IDD_OBJTOOL_GENERAL
 Resource95=IDA_SCRIPT_MANAGER (English (U.S.))
 Resource96=IDD_SET_PASSWORD (English (U.S.))
 Resource97=IDD_DCI_TRANSFORM (English (U.S.))
-Resource98=IDD_CREATE_CONTAINER
+Resource98=IDD_SELECT_ACTION
 Resource99=IDD_OBJECT_NETSRV_GENERAL (English (U.S.))
 Resource100=IDD_OBJTOOL_OPTIONS (English (U.S.))
 Resource101=IDA_LAST_VALUES (English (U.S.))
@@ -244,7 +244,7 @@ Class102=CWaitView
 Class103=CWebBrowser
 Class104=CSyslogBrowser
 Class105=CLPPList
-Resource129=IDD_CREATE_NODE
+Resource129=IDD_CREATE_CONTAINER
 Class106=CDCISchedulePage
 Resource130=IDD_OBJECT_CAPS (English (U.S.))
 Class107=CObjectPropsStatus
@@ -270,54 +270,54 @@ Class119=CMapControlBox
 Resource138=IDD_OBJECT_GENERAL (English (U.S.))
 Class120=CSubmapBkgndDlg
 Resource139=IDD_SUBMAP_BKGND (English (U.S.))
-Resource140=IDD_EDIT_RULE_COMMENT
-Resource141=IDD_GRAPH_PROP_DATA
-Resource142=IDD_OBJECT_SECURITY
-Resource143=IDA_PACKAGE_MGR
-Resource144=IDA_GRAPH
-Resource145=IDD_OBJECT_STATUS
-Resource146=IDD_INPUT_BOX
-Resource147=IDD_REQUEST_PROCESSING
-Resource148=IDD_CREATE_NETSRV
-Resource149=IDD_NEW_USER
-Resource150=IDR_MAINFRAME
-Resource151=IDD_REMOVE_TEMPLATE
-Resource152=IDD_CHANGE_PASSWORD
-Resource153=IDD_OBJTOOL_OPTIONS
-Resource154=IDA_OBJECT_BROWSER
-Resource155=IDD_DCI_COLLECTION
-Resource156=IDA_NETMAP
-Resource157=IDD_EDIT_VARIABLE
-Resource158=IDD_DCI_DATA_EXPORT
-Resource159=IDD_LASTVAL_PROP
-Resource160=IDD_CREATE_TG
-Resource161=IDD_NEW_ACTION
-Resource162=IDD_OBJECT_VPNC_GENERAL
-Resource163=IDD_SELECT_ACTION
-Resource164=IDD_DCI_SCHEDULE
-Resource165=IDD_OBJECT_RELATIONS
-Resource166=IDD_SAVE_AGENT_CFG
-Resource167=IDD_CREATE_VPNC
-Resource168=IDD_OBJTOOL_COLUMNS
-Resource169=IDD_DATA_QUERY
-Resource170=IDD_SNMP_WALK
-Resource171=IDD_CREATE_CONDITION
+Resource140=IDD_SELECT_OBJECT
+Resource141=IDD_GRAPH_PROP_SETTINGS
+Resource142=IDD_OBJECT_GENERAL
+Resource143=IDA_GRAPH
+Resource144=IDA_TRAP_EDITOR
+Resource145=IDD_DCI_SCHEDULE
+Resource146=IDD_SELECT_AGENT_PARAM
+Resource147=IDD_OBJECT_CAPS
+Resource148=IDD_INPUT_BOX
+Resource149=IDD_SELECT_USER
+Resource150=IDD_COND_DCI_PROP
+Resource151=IDD_CHANGE_IP
+Resource152=IDD_SUBMAP_BKGND
+Resource153=IDD_NEW_OBJECT_TOOL
+Resource154=IDA_MDI_DEFAULT
+Resource155=IDD_SET_PASSWORD
+Resource156=IDA_ALARM_BROWSER
+Resource157=IDD_DCI_DATA_EXPORT
+Resource158=IDD_LASTVAL_PROP
+Resource159=IDD_GRAPH_PROP_DATA
+Resource160=IDD_DCI_TRANSFORM
+Resource161=IDD_CP_GENERAL
+Resource162=IDD_CREATE_VPNC
+Resource163=IDD_ACTION_PROPERTIES
+Resource164=IDD_SAVE_AGENT_CFG
+Resource165=IDD_OBJECT_NODE_POLL
+Resource166=IDD_EDIT_IP_SUBNET
+Resource167=IDD_EDIT_VARIABLE
+Resource168=IDD_REMOVE_TEMPLATE
+Resource169=IDD_CREATE_TEMPLATE
+Resource170=IDD_OBJTOOL_COLUMNS
+Resource171=IDD_CHANGE_PASSWORD
 Class121=CModuleManager
 Class122=CDesktopManager
-Resource172=IDD_OBJECT_CAPS
-Resource173=IDA_TRAP_EDITOR
+Resource172=IDD_OBJECT_NODE_GENERAL
+Resource173=IDA_ACTION_EDITOR
 Class123=CCreateCondDlg
 Class124=CCondPropsGeneral
 Class125=CCondPropsScript
 Class126=CCondPropsData
-Resource174=IDM_VIEW_SPECIFIC
+Resource174=IDM_CONTEXT
 Class127=CAddDCIDlg
-Resource175=IDD_OBJECT_NODE_GENERAL
+Resource175=IDD_EDIT_EVENT
 Class128=CCondDCIPropDlg
-Resource176=IDD_OBJECT_NETSRV_GENERAL
+Resource176=IDD_CREATE_NETSRV
 Class129=CAgentConfigMgr
-Resource177=IDD_CHANGE_IP
-Resource178=IDD_EDIT_RULE_ALARM
+Resource177=IDD_OBJTOOL_OPTIONS
+Resource178=IDD_EDIT_RULE_SEVERITY
 Class130=CAgentCfgDlg
 Resource179=IDD_AGENT_CONFIG
 
index 3d0d3d2..d400356 100644 (file)
@@ -120,12 +120,12 @@ DWORD LIBNETXMS_EXPORTABLE CalculateCRC32(const unsigned char *pData,
 // Calculate MD5 hash for array of bytes
 //
 
-void LIBNETXMS_EXPORTABLE CalculateMD5Hash(const unsigned char *data, int nbytes, BYTE *hash)
+void LIBNETXMS_EXPORTABLE CalculateMD5Hash(const unsigned char *data, size_t nbytes, BYTE *hash)
 {
        md5_state_t state;
 
        I_md5_init(&state);
-       I_md5_append(&state, (const md5_byte_t *)data, nbytes);
+       I_md5_append(&state, (const md5_byte_t *)data, (int)nbytes);
        I_md5_finish(&state, (md5_byte_t *)hash);
 }
 
@@ -134,12 +134,12 @@ void LIBNETXMS_EXPORTABLE CalculateMD5Hash(const unsigned char *data, int nbytes
 // Calculate SHA1 hash for array of bytes
 //
 
-void LIBNETXMS_EXPORTABLE CalculateSHA1Hash(unsigned char *data, int nbytes, BYTE *hash)
+void LIBNETXMS_EXPORTABLE CalculateSHA1Hash(unsigned char *data, size_t nbytes, BYTE *hash)
 {
    SHA1_CTX context;
 
    I_SHA1Init(&context);
-   I_SHA1Update(&context, data, nbytes);
+   I_SHA1Update(&context, data, (uint32)nbytes);
    I_SHA1Final(hash, &context);
 }
 
index 2c864b0..0dbd0ca 100644 (file)
@@ -212,11 +212,7 @@ DWORD LIBNETXMS_EXPORTABLE IcmpPing(DWORD dwAddr, int iNumRetries,
 #if HAVE_POLL
                 if (poll(&fds, 1, dwTimeLeft) > 0)
 #else
-#ifdef _WIN32
-                if (select(0, &rdfs, NULL, NULL, &timeout) > 0)
-#else
-                if (select(sock + 1, &rdfs, NULL, NULL, &timeout) > 0)
-#endif
+                if (select(SELECT_NFDS(sock + 1), &rdfs, NULL, NULL, &timeout) > 0)
 #endif
 
 #endif   /* USE_KQUEUE */
index 7091065..de6b549 100644 (file)
@@ -728,14 +728,14 @@ int LIBNETXMS_EXPORTABLE RecvEx(SOCKET nSocket, const void *pBuff,
 #ifdef _WIN32
       tv.tv_sec = dwTimeout / 1000;
       tv.tv_usec = (dwTimeout % 1000) * 1000;
-      iErr = select(0, &rdfs, NULL, NULL, &tv);
+      iErr = select(SELECT_NFDS(nSocket + 1), &rdfs, NULL, NULL, &tv);
 #else
       do
       {
          tv.tv_sec = dwTimeout / 1000;
          tv.tv_usec = (dwTimeout % 1000) * 1000;
          qwStartTime = GetCurrentTimeMs();
-         iErr = select(nSocket + 1, &rdfs, NULL, NULL, &tv);
+         iErr = select(SELECT_NFDS(nSocket + 1), &rdfs, NULL, NULL, &tv);
          if ((iErr != -1) || (errno != EINTR))
             break;
          dwElapsed = GetCurrentTimeMs() - qwStartTime;
index 67e04d8..e0989dc 100644 (file)
@@ -167,3 +167,24 @@ DWORD LIBNXCL_EXPORTABLE NXCDeleteAgentConfig(NXC_SESSION hSession, DWORD dwCfgI
 
    return ((NXCL_Session *)hSession)->WaitForRCC(dwRqId);
 }
+
+
+//
+// Swap sequence numbers of two agent configs
+//
+
+DWORD LIBNXCL_EXPORTABLE NXCSwapAgentConfigs(NXC_SESSION hSession, DWORD dwCfgId1, DWORD dwCfgId2)
+{
+   CSCPMessage msg;
+   DWORD dwRqId;
+
+   dwRqId = ((NXCL_Session *)hSession)->CreateRqId();
+
+   msg.SetCode(CMD_SWAP_AGENT_CONFIGS);
+   msg.SetId(dwRqId);
+   msg.SetVariable(VID_CONFIG_ID, dwCfgId1);
+   msg.SetVariable(VID_CONFIG_ID_2, dwCfgId2);
+   ((NXCL_Session *)hSession)->SendMsg(&msg);
+
+   return ((NXCL_Session *)hSession)->WaitForRCC(dwRqId);
+}
index 303e6bc..d319743 100644 (file)
@@ -1009,7 +1009,7 @@ void DCItem::UpdateCacheSize(DWORD dwCondId)
             for(; i < dwRequiredSize; i++)
                m_ppValueCache[i] = new ItemValue(_T(""), 1);
 
-            DBFreeAsyncResult(hResult);
+            DBFreeAsyncResult(g_hCoreDB, hResult);
          }
          else
          {
index 30765fd..fcc5598 100644 (file)
@@ -63,7 +63,7 @@ static void CleanDeletedObjects(void)
                QueueSQLRequest(szQuery);
                DbgPrintf(AF_DEBUG_HOUSEKEEPER, "*HK* Deleted object with id %d was purged", dwObjectId);
             }
-            DBFreeAsyncResult(hAsyncResult);
+            DBFreeAsyncResult(m_hdb, hAsyncResult);
          }
       }
       DBFreeResult(hResult);
index ad4cd05..9ddf900 100644 (file)
@@ -978,6 +978,9 @@ void ClientSession::ProcessingThread(void)
          case CMD_DELETE_AGENT_CONFIG:
             DeleteAgentConfig(pMsg);
             break;
+         case CMD_SWAP_AGENT_CONFIGS:
+            SwapAgentConfigs(pMsg);
+            break;
          default:
             // Pass message to loaded modules
             for(i = 0; i < g_dwNumModules; i++)
@@ -1179,7 +1182,7 @@ void ClientSession::SendEventDB(DWORD dwRqId)
             SendMessage(&msg);
             msg.DeleteAllVariables();
          }
-         DBFreeAsyncResult(hResult);
+         DBFreeAsyncResult(g_hCoreDB, hResult);
       }
 
       // Send end-of-list indicator
@@ -1577,7 +1580,7 @@ void ClientSession::SendAllEvents(CSCPMessage *pRequest)
          m_pSendQueue->Put(CreateRawCSCPMessage(CMD_EVENT, dwRqId, wFlags,
                                                 sizeof(NXC_EVENT), &event, NULL));
       }
-      DBFreeAsyncResult(hResult);
+      DBFreeAsyncResult(g_hCoreDB, hResult);
    }
 
    // Send end of list notification
@@ -2729,7 +2732,7 @@ void ClientSession::GetCollectedData(CSCPMessage *pRequest)
                }
                pCurr = (DCI_DATA_ROW *)(((char *)pCurr) + m_dwRowSize[iType]);
             }
-            DBFreeAsyncResult(hResult);
+            DBFreeAsyncResult(g_hCoreDB, hResult);
             pData->dwNumRows = htonl(dwNumRows);
 
             // Prepare and send raw message with fetched data
@@ -4199,7 +4202,7 @@ void ClientSession::SendAllPackages(DWORD dwRqId)
             msg.SetVariable(VID_PACKAGE_ID, (DWORD)0);
             SendMessage(&msg);
 
-            DBFreeAsyncResult(hResult);
+            DBFreeAsyncResult(g_hCoreDB, hResult);
          }
          else
          {
@@ -6391,7 +6394,7 @@ void ClientSession::SendSyslog(CSCPMessage *pRequest)
          DecodeSQLString(szBuffer);
          msg.SetVariable(dwId++, szBuffer);
       }
-      DBFreeAsyncResult(hResult);
+      DBFreeAsyncResult(g_hCoreDB, hResult);
 
       // Send remaining records with End-Of-Sequence notification
       msg.SetVariable(VID_NUM_RECORDS, dwNumRows);
@@ -6517,7 +6520,7 @@ void ClientSession::SendTrapLog(CSCPMessage *pRequest)
             DecodeSQLString(szBuffer);
             msg.SetVariable(dwId++, szBuffer);
          }
-         DBFreeAsyncResult(hResult);
+         DBFreeAsyncResult(g_hCoreDB, hResult);
 
          // Send remaining records with End-Of-Sequence notification
          msg.SetVariable(VID_NUM_RECORDS, dwNumRows);
@@ -7331,6 +7334,77 @@ void ClientSession::DeleteAgentConfig(CSCPMessage *pRequest)
 }
 
 
+//
+// Swap sequence numbers of two agent configs
+//
+
+void ClientSession::SwapAgentConfigs(CSCPMessage *pRequest)
+{
+   CSCPMessage msg;
+   DB_RESULT hResult;
+   TCHAR szQuery[256];
+   BOOL bRet;
+
+   msg.SetCode(CMD_REQUEST_COMPLETED);
+   msg.SetId(pRequest->GetId());
+
+   if (m_dwSystemAccess & SYSTEM_ACCESS_MANAGE_AGENT_CFG)
+   {
+      _sntprintf(szQuery, 256, _T("SELECT config_id,sequence_number FROM agent_configs WHERE config_id=%d OR config_id=%d"),
+                 pRequest->GetVariableLong(VID_CONFIG_ID), pRequest->GetVariableLong(VID_CONFIG_ID_2));
+      hResult = DBSelect(g_hCoreDB, szQuery);
+      if (hResult != NULL)
+      {
+         if (DBGetNumRows(hResult) >= 2)
+         {
+            if (DBBegin(g_hCoreDB))
+            {
+               _sntprintf(szQuery, 256, _T("UPDATE agent_configs SET sequence_number=%d WHERE config_id=%d"),
+                          DBGetFieldULong(hResult, 1, 1), DBGetFieldULong(hResult, 0, 0));
+               bRet = DBQuery(g_hCoreDB, szQuery);
+               if (bRet)
+               {
+                  _sntprintf(szQuery, 256, _T("UPDATE agent_configs SET sequence_number=%d WHERE config_id=%d"),
+                             DBGetFieldULong(hResult, 0, 1), DBGetFieldULong(hResult, 1, 0));
+                  bRet = DBQuery(g_hCoreDB, szQuery);
+               }
+
+               if (bRet)
+               {
+                  DBCommit(g_hCoreDB);
+                  msg.SetVariable(VID_RCC, RCC_SUCCESS);
+               }
+               else
+               {
+                  DBRollback(g_hCoreDB);
+                  msg.SetVariable(VID_RCC, RCC_DB_FAILURE);
+               }
+            }
+            else
+            {
+               msg.SetVariable(VID_RCC, RCC_DB_FAILURE);
+            }
+         }
+         else
+         {
+            msg.SetVariable(VID_RCC, RCC_INVALID_CONFIG_ID);
+         }
+         DBFreeResult(hResult);
+      }
+      else
+      {
+         msg.SetVariable(VID_RCC, RCC_DB_FAILURE);
+      }
+   }
+   else
+   {
+      msg.SetVariable(VID_RCC, RCC_ACCESS_DENIED);
+   }
+
+   SendMessage(&msg);
+}
+
+
 //
 // Send config to agent on request
 //
index f3d6208..766f516 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: pgsql.cpp,v 1.11 2006-03-23 08:00:09 victor Exp $ */
+/* $Id: pgsql.cpp,v 1.12 2006-08-07 09:47:02 victor Exp $ */
 /* 
 ** PostgreSQL Database Driver
 ** Copyright (C) 2003, 2005 Victor Kirhenshtein and Alex Kirhenshtein
@@ -46,7 +46,7 @@ extern "C" void EXPORT DrvUnload(void)
 // Connect to database
 //
 
-extern "C" DB_HANDLE EXPORT DrvConnect(
+extern "C" DB_CONNECTION EXPORT DrvConnect(
                char *szHost,
                char *szLogin,
                char *szPassword,
@@ -78,7 +78,7 @@ extern "C" DB_HANDLE EXPORT DrvConnect(
                }
        }
 
-   return (DB_HANDLE)pConn;
+   return (DB_CONNECTION)pConn;
 }
 
 
@@ -86,7 +86,7 @@ extern "C" DB_HANDLE EXPORT DrvConnect(
 // Disconnect from database
 //
 
-extern "C" void EXPORT DrvDisconnect(DB_HANDLE pConn)
+extern "C" void EXPORT DrvDisconnect(DB_CONNECTION pConn)
 {
        if (pConn != NULL)
        {
@@ -101,7 +101,7 @@ extern "C" void EXPORT DrvDisconnect(DB_HANDLE pConn)
 // Perform non-SELECT query
 //
 
-static BOOL UnsafeDrvQuery(DB_HANDLE pConn, char *szQuery)
+static BOOL UnsafeDrvQuery(DB_CONNECTION pConn, char *szQuery)
 {
        PGresult        *pResult;
 
@@ -127,7 +127,7 @@ static BOOL UnsafeDrvQuery(DB_HANDLE pConn, char *szQuery)
    return TRUE;
 }
 
-extern "C" BOOL EXPORT DrvQuery(DB_HANDLE pConn, char *szQuery)
+extern "C" BOOL EXPORT DrvQuery(DB_CONNECTION pConn, char *szQuery)
 {
        BOOL bRet = FALSE;
 
@@ -146,7 +146,7 @@ extern "C" BOOL EXPORT DrvQuery(DB_HANDLE pConn, char *szQuery)
 // Perform SELECT query
 //
 
-static DB_RESULT UnsafeDrvSelect(DB_HANDLE pConn, char *szQuery)
+static DB_RESULT UnsafeDrvSelect(DB_CONNECTION pConn, char *szQuery)
 {
        PGresult        *pResult;
 
@@ -167,7 +167,7 @@ static DB_RESULT UnsafeDrvSelect(DB_HANDLE pConn, char *szQuery)
    return (DB_RESULT)pResult;
 }
 
-extern "C" DB_RESULT EXPORT DrvSelect(DB_HANDLE pConn, char *szQuery)
+extern "C" DB_RESULT EXPORT DrvSelect(DB_CONNECTION pConn, char *szQuery)
 {
        DB_RESULT pResult;
 
@@ -226,16 +226,14 @@ extern "C" void EXPORT DrvFreeResult(DB_RESULT pResult)
 // Perform asynchronous SELECT query
 //
 
-extern "C" DB_ASYNC_RESULT EXPORT DrvAsyncSelect(DB_HANDLE pConn, char *szQuery)
+extern "C" DB_ASYNC_RESULT EXPORT DrvAsyncSelect(DB_CONNECTION pConn, char *szQuery)
 {
        BOOL bSuccess = FALSE;
    char *pszReq;
    static char szDeclareCursor[] = "DECLARE cur1 CURSOR FOR ";
 
        if (pConn == NULL)
-       {
                return NULL;
-       }
 
        MutexLock(((PG_CONN *)pConn)->mutexQueryLock, INFINITE);
 
@@ -365,13 +363,67 @@ extern "C" void EXPORT DrvFreeAsyncResult(DB_ASYNC_RESULT pConn)
                   PQclear(((PG_CONN *)pConn)->pFetchBuffer);
          ((PG_CONN *)pConn)->pFetchBuffer = NULL;
       }
-               UnsafeDrvQuery((DB_HANDLE)pConn, "CLOSE cur1");
-               UnsafeDrvQuery((DB_HANDLE)pConn, "COMMIT");
+               UnsafeDrvQuery((DB_CONNECTION)pConn, "CLOSE cur1");
+               UnsafeDrvQuery((DB_CONNECTION)pConn, "COMMIT");
    }
        MutexUnlock(((PG_CONN *)pConn)->mutexQueryLock);
 }
 
 
+//
+// Begin transaction
+//
+
+extern "C" BOOL EXPORT DrvBegin(DB_CONNECTION pConn)
+{
+   BOOL bRet;
+
+       if (pConn == NULL)
+      return FALSE;
+
+       MutexLock(((PG_CONN *)pConn)->mutexQueryLock, INFINITE);
+       bRet = UnsafeDrvQuery(pConn, "BEGIN");
+       MutexUnlock(((PG_CONN *)pConn)->mutexQueryLock);
+   return bRet;
+}
+
+
+//
+// Commit transaction
+//
+
+extern "C" BOOL EXPORT DrvCommit(DB_CONNECTION pConn)
+{
+   BOOL bRet;
+
+       if (pConn == NULL)
+      return FALSE;
+
+       MutexLock(((PG_CONN *)pConn)->mutexQueryLock, INFINITE);
+       bRet = UnsafeDrvQuery(pConn, "COMMIT");
+       MutexUnlock(((PG_CONN *)pConn)->mutexQueryLock);
+   return bRet;
+}
+
+
+//
+// Rollback transaction
+//
+
+extern "C" BOOL EXPORT DrvRollback(DB_CONNECTION pConn)
+{
+   BOOL bRet;
+
+       if (pConn == NULL)
+      return FALSE;
+
+       MutexLock(((PG_CONN *)pConn)->mutexQueryLock, INFINITE);
+       bRet = UnsafeDrvQuery(pConn, "ROLLBACK");
+       MutexUnlock(((PG_CONN *)pConn)->mutexQueryLock);
+   return bRet;
+}
+
+
 //
 // DLL Entry point
 //
index 50ef098..8348f01 100644 (file)
@@ -1,6 +1,6 @@
 /* 
 ** PostgreSQL Database Driver
-** Copyright (C) 2003 Victor Kirhenshtein
+** Copyright (C) 2003, 2004, 2005, 2006 Victor Kirhenshtein
 **
 ** This program is free software; you can redistribute it and/or modify
 ** it under the terms of the GNU General Public License as published by
index 251ef3b..c6f60ae 100644 (file)
@@ -30,7 +30,7 @@
 // Datatypes
 //
 
-typedef void * DB_HANDLE;
+typedef void * DB_CONNECTION;
 typedef void * DB_RESULT;
 typedef void * DB_ASYNC_RESULT;
 
index e2f29b8..fdb8e5c 100644 (file)
@@ -488,6 +488,7 @@ private:
    void OpenAgentConfig(CSCPMessage *pRequest);
    void SaveAgentConfig(CSCPMessage *pRequest);
    void DeleteAgentConfig(CSCPMessage *pRequest);
+   void SwapAgentConfigs(CSCPMessage *pRequest);
 
 public:
    ClientSession(SOCKET hSocket, DWORD dwHostAddr);
index fbeeaf1..683850f 100644 (file)
 #define MAX_DB_NAME           32
 
 
+//
+// Database connection structure
+//
+
+struct db_handle_t
+{
+   DB_CONNECTION hConn;
+   MUTEX mutexTransLock;      // Transaction lock
+   int nTransactionLevel;
+};
+typedef db_handle_t * DB_HANDLE;
+
+
 //
 // Win32 service constants
 //
@@ -324,7 +337,10 @@ double LIBNXSRV_EXPORTABLE DBGetFieldAsyncDouble(DB_RESULT hResult, int iColumn)
 DWORD LIBNXSRV_EXPORTABLE DBGetFieldAsyncIPAddr(DB_RESULT hResult, int iColumn);
 int LIBNXSRV_EXPORTABLE DBGetNumRows(DB_RESULT hResult);
 void LIBNXSRV_EXPORTABLE DBFreeResult(DB_RESULT hResult);
-void LIBNXSRV_EXPORTABLE DBFreeAsyncResult(DB_ASYNC_RESULT hResult);
+void LIBNXSRV_EXPORTABLE DBFreeAsyncResult(DB_HANDLE hConn, DB_ASYNC_RESULT hResult);
+BOOL LIBNXSRV_EXPORTABLE DBBegin(DB_HANDLE hConn);
+BOOL LIBNXSRV_EXPORTABLE DBCommit(DB_HANDLE hConn);
+BOOL LIBNXSRV_EXPORTABLE DBRollback(DB_HANDLE hConn);
 void LIBNXSRV_EXPORTABLE DBUnloadDriver(void);
 
 TCHAR LIBNXSRV_EXPORTABLE *EncodeSQLString(const TCHAR *pszIn);
index c788da5..b1d7070 100644 (file)
@@ -1,6 +1,6 @@
 /* 
-** Project X - Network Management System
-** Copyright (C) 2003 Victor Kirhenshtein
+** NetXMS - Network Management System
+** Copyright (C) 2003, 2004, 2005, 2006 Victor Kirhenshtein
 **
 ** This program is free software; you can redistribute it and/or modify
 ** it under the terms of the GNU General Public License as published by
@@ -16,7 +16,7 @@
 ** along with this program; if not, write to the Free Software
 ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 **
-** $module: db.cpp
+** File: db.cpp
 **
 **/
 
@@ -43,17 +43,20 @@ static BOOL m_bWriteLog = FALSE;
 static BOOL m_bLogSQLErrors = FALSE;
 static BOOL m_bDumpSQL = FALSE;
 static HMODULE m_hDriver = NULL;
-static DB_HANDLE (* m_fpDrvConnect)(char *, char *, char *, char *) = NULL;
-static void (* m_fpDrvDisconnect)(DB_HANDLE) = NULL;
-static BOOL (* m_fpDrvQuery)(DB_HANDLE, char *) = NULL;
-static DB_RESULT (* m_fpDrvSelect)(DB_HANDLE, char *) = NULL;
-static DB_ASYNC_RESULT (* m_fpDrvAsyncSelect)(DB_HANDLE, char *) = NULL;
+static DB_CONNECTION (* m_fpDrvConnect)(char *, char *, char *, char *) = NULL;
+static void (* m_fpDrvDisconnect)(DB_CONNECTION) = NULL;
+static BOOL (* m_fpDrvQuery)(DB_CONNECTION, char *) = NULL;
+static DB_RESULT (* m_fpDrvSelect)(DB_CONNECTION, char *) = NULL;
+static DB_ASYNC_RESULT (* m_fpDrvAsyncSelect)(DB_CONNECTION, char *) = NULL;
 static BOOL (* m_fpDrvFetch)(DB_ASYNC_RESULT) = NULL;
 static char* (* m_fpDrvGetField)(DB_RESULT, int, int) = NULL;
 static char* (* m_fpDrvGetFieldAsync)(DB_ASYNC_RESULT, int, char *, int) = NULL;
 static int (* m_fpDrvGetNumRows)(DB_RESULT) = NULL;
 static void (* m_fpDrvFreeResult)(DB_RESULT) = NULL;
 static void (* m_fpDrvFreeAsyncResult)(DB_ASYNC_RESULT) = NULL;
+static BOOL (* m_fpDrvBegin)(DB_CONNECTION) = NULL;
+static BOOL (* m_fpDrvCommit)(DB_CONNECTION) = NULL;
+static BOOL (* m_fpDrvRollback)(DB_CONNECTION) = NULL;
 static void (* m_fpDrvUnload)(void) = NULL;
 
 
@@ -97,23 +100,27 @@ BOOL LIBNXSRV_EXPORTABLE DBInit(BOOL bWriteLog, BOOL bLogErrors, BOOL bDumpSQL)
 
    // Import symbols
    fpDrvInit = (BOOL (*)(char *))DLGetSymbolAddrEx(m_hDriver, "DrvInit");
-   m_fpDrvConnect = (DB_HANDLE (*)(char *, char *, char *, char *))DLGetSymbolAddrEx(m_hDriver, "DrvConnect");
-   m_fpDrvDisconnect = (void (*)(DB_HANDLE))DLGetSymbolAddrEx(m_hDriver, "DrvDisconnect");
-   m_fpDrvQuery = (BOOL (*)(DB_HANDLE, char *))DLGetSymbolAddrEx(m_hDriver, "DrvQuery");
-   m_fpDrvSelect = (DB_RESULT (*)(DB_HANDLE, char *))DLGetSymbolAddrEx(m_hDriver, "DrvSelect");
-   m_fpDrvAsyncSelect = (DB_ASYNC_RESULT (*)(DB_HANDLE, char *))DLGetSymbolAddrEx(m_hDriver, "DrvAsyncSelect");
+   m_fpDrvConnect = (DB_CONNECTION (*)(char *, char *, char *, char *))DLGetSymbolAddrEx(m_hDriver, "DrvConnect");
+   m_fpDrvDisconnect = (void (*)(DB_CONNECTION))DLGetSymbolAddrEx(m_hDriver, "DrvDisconnect");
+   m_fpDrvQuery = (BOOL (*)(DB_CONNECTION, char *))DLGetSymbolAddrEx(m_hDriver, "DrvQuery");
+   m_fpDrvSelect = (DB_RESULT (*)(DB_CONNECTION, char *))DLGetSymbolAddrEx(m_hDriver, "DrvSelect");
+   m_fpDrvAsyncSelect = (DB_ASYNC_RESULT (*)(DB_CONNECTION, char *))DLGetSymbolAddrEx(m_hDriver, "DrvAsyncSelect");
    m_fpDrvFetch = (BOOL (*)(DB_ASYNC_RESULT))DLGetSymbolAddrEx(m_hDriver, "DrvFetch");
    m_fpDrvGetField = (char* (*)(DB_RESULT, int, int))DLGetSymbolAddrEx(m_hDriver, "DrvGetField");
    m_fpDrvGetFieldAsync = (char* (*)(DB_ASYNC_RESULT, int, char *, int))DLGetSymbolAddrEx(m_hDriver, "DrvGetFieldAsync");
    m_fpDrvGetNumRows = (int (*)(DB_RESULT))DLGetSymbolAddrEx(m_hDriver, "DrvGetNumRows");
    m_fpDrvFreeResult = (void (*)(DB_RESULT))DLGetSymbolAddrEx(m_hDriver, "DrvFreeResult");
    m_fpDrvFreeAsyncResult = (void (*)(DB_ASYNC_RESULT))DLGetSymbolAddrEx(m_hDriver, "DrvFreeAsyncResult");
+   m_fpDrvBegin = (BOOL (*)(DB_CONNECTION))DLGetSymbolAddrEx(m_hDriver, "DrvBegin");
+   m_fpDrvCommit = (BOOL (*)(DB_CONNECTION))DLGetSymbolAddrEx(m_hDriver, "DrvCommit");
+   m_fpDrvRollback = (BOOL (*)(DB_CONNECTION))DLGetSymbolAddrEx(m_hDriver, "DrvRollback");
    m_fpDrvUnload = (void (*)(void))DLGetSymbolAddrEx(m_hDriver, "DrvUnload");
    if ((fpDrvInit == NULL) || (m_fpDrvConnect == NULL) || (m_fpDrvDisconnect == NULL) ||
        (m_fpDrvQuery == NULL) || (m_fpDrvSelect == NULL) || (m_fpDrvGetField == NULL) ||
        (m_fpDrvGetNumRows == NULL) || (m_fpDrvFreeResult == NULL) || 
        (m_fpDrvUnload == NULL) || (m_fpDrvAsyncSelect == NULL) || (m_fpDrvFetch == NULL) ||
-       (m_fpDrvFreeAsyncResult == NULL) || (m_fpDrvGetFieldAsync == NULL))
+       (m_fpDrvFreeAsyncResult == NULL) || (m_fpDrvGetFieldAsync == NULL) ||
+       (m_fpDrvBegin == NULL) || (m_fpDrvCommit == NULL) || (m_fpDrvRollback == NULL))
    {
       if (m_bWriteLog)
          WriteLog(MSG_DBDRV_NO_ENTRY_POINTS, EVENTLOG_ERROR_TYPE, "s", g_szDbDriver);
@@ -156,7 +163,7 @@ void LIBNXSRV_EXPORTABLE DBUnloadDriver(void)
 
 DB_HANDLE LIBNXSRV_EXPORTABLE DBConnect(void)
 {
-   return m_fpDrvConnect(g_szDbServer, g_szDbLogin, g_szDbPassword, g_szDbName);
+   return DBConnectEx(g_szDbServer, g_szDbName, g_szDbLogin, g_szDbPassword);
 }
 
 
@@ -167,7 +174,25 @@ DB_HANDLE LIBNXSRV_EXPORTABLE DBConnect(void)
 DB_HANDLE LIBNXSRV_EXPORTABLE DBConnectEx(TCHAR *pszServer, TCHAR *pszDBName,
                                           TCHAR *pszLogin, TCHAR *pszPassword)
 {
-   return m_fpDrvConnect(pszServer, pszLogin, pszPassword, pszDBName);
+   DB_CONNECTION hDrvConn;
+   DB_HANDLE hConn = NULL;
+
+   hDrvConn = m_fpDrvConnect(pszServer, pszLogin, pszPassword, pszDBName);
+   if (hDrvConn != NULL)
+   {
+      hConn = (DB_HANDLE)malloc(sizeof(struct db_handle_t));
+      if (hConn != NULL)
+      {
+         hConn->hConn = hDrvConn;
+         hConn->mutexTransLock = MutexCreateRecursive();
+         hConn->nTransactionLevel = 0;
+      }
+      else
+      {
+         m_fpDrvDisconnect(hDrvConn);
+      }
+   }
+   return hConn;
 }
 
 
@@ -177,7 +202,12 @@ DB_HANDLE LIBNXSRV_EXPORTABLE DBConnectEx(TCHAR *pszServer, TCHAR *pszDBName,
 
 void LIBNXSRV_EXPORTABLE DBDisconnect(DB_HANDLE hConn)
 {
-   m_fpDrvDisconnect(hConn);
+   if (hConn == NULL)
+      return;
+
+   m_fpDrvDisconnect(hConn->hConn);
+   MutexDestroy(hConn->mutexTransLock);
+   free(hConn);
 }
 
 
@@ -190,14 +220,16 @@ BOOL LIBNXSRV_EXPORTABLE DBQuery(DB_HANDLE hConn, char *szQuery)
    BOOL bResult;
    INT64 ms;
    
+   MutexLock(hConn->mutexTransLock, INFINITE);
    if (m_bDumpSQL)
       ms = GetCurrentTimeMs();
-   bResult = m_fpDrvQuery(hConn, szQuery);
+   bResult = m_fpDrvQuery(hConn->hConn, szQuery);
    if (m_bDumpSQL)
    {
       ms = GetCurrentTimeMs() - ms;
       printf("%s sync query: \"%s\" [%d ms]\n", bResult ? "Successful" : "Failed", szQuery, ms);
    }
+   MutexUnlock(hConn->mutexTransLock);
    if ((!bResult) && m_bLogSQLErrors)
       WriteLog(MSG_SQL_ERROR, EVENTLOG_ERROR_TYPE, "s", szQuery);
    return bResult;
@@ -213,14 +245,16 @@ DB_RESULT LIBNXSRV_EXPORTABLE DBSelect(DB_HANDLE hConn, char *szQuery)
    DB_RESULT hResult;
    INT64 ms;
    
+   MutexLock(hConn->mutexTransLock, INFINITE);
    if (m_bDumpSQL)
       ms = GetCurrentTimeMs();
-   hResult = m_fpDrvSelect(hConn, szQuery);
+   hResult = m_fpDrvSelect(hConn->hConn, szQuery);
    if (m_bDumpSQL)
    {
       ms = GetCurrentTimeMs() - ms;
       printf("%s sync query: \"%s\" [%d ms]\n", (hResult != NULL) ? "Successful" : "Failed", szQuery, (DWORD)ms);
    }
+   MutexUnlock(hConn->mutexTransLock);
    if ((!hResult) && m_bLogSQLErrors)
       WriteLog(MSG_SQL_ERROR, EVENTLOG_ERROR_TYPE, "s", szQuery);
    return hResult;
@@ -423,16 +457,21 @@ DB_ASYNC_RESULT LIBNXSRV_EXPORTABLE DBAsyncSelect(DB_HANDLE hConn, char *szQuery
    DB_RESULT hResult;
    INT64 ms;
    
+   MutexLock(hConn->mutexTransLock, INFINITE);
    if (m_bDumpSQL)
       ms = GetCurrentTimeMs();
-   hResult = m_fpDrvAsyncSelect(hConn, szQuery);
+   hResult = m_fpDrvAsyncSelect(hConn->hConn, szQuery);
    if (m_bDumpSQL)
    {
       ms = GetCurrentTimeMs() - ms;
       printf("%s async query: \"%s\" [%d ms]\n", (hResult != NULL) ? "Successful" : "Failed", szQuery, (DWORD)ms);
    }
-   if ((!hResult) && m_bLogSQLErrors)
-      WriteLog(MSG_SQL_ERROR, EVENTLOG_ERROR_TYPE, "s", szQuery);
+   if (hResult == NULL)
+   {
+      MutexUnlock(hConn->mutexTransLock);
+      if (m_bLogSQLErrors)
+        WriteLog(MSG_SQL_ERROR, EVENTLOG_ERROR_TYPE, "s", szQuery);
+   }
    return hResult;
 }
 
@@ -546,9 +585,71 @@ DWORD LIBNXSRV_EXPORTABLE DBGetFieldAsyncIPAddr(DB_RESULT hResult, int iColumn)
 // Free asynchronous SELECT result
 //
 
-void LIBNXSRV_EXPORTABLE DBFreeAsyncResult(DB_ASYNC_RESULT hResult)
+void LIBNXSRV_EXPORTABLE DBFreeAsyncResult(DB_HANDLE hConn, DB_ASYNC_RESULT hResult)
 {
    m_fpDrvFreeAsyncResult(hResult);
+   MutexUnlock(hConn->mutexTransLock);
+}
+
+
+//
+// Begin transaction
+//
+
+BOOL LIBNXSRV_EXPORTABLE DBBegin(DB_HANDLE hConn)
+{
+   BOOL bRet;
+
+   MutexLock(hConn->mutexTransLock, INFINITE);
+   if (bRet = m_fpDrvBegin(hConn->hConn))
+   {
+      hConn->nTransactionLevel++;
+   }
+   else
+   {
+      MutexUnlock(hConn->mutexTransLock);
+   }
+   return bRet;
+}
+
+
+//
+// Commit transaction
+//
+
+BOOL LIBNXSRV_EXPORTABLE DBCommit(DB_HANDLE hConn)
+{
+   BOOL bRet = FALSE;
+
+   MutexLock(hConn->mutexTransLock, INFINITE);
+   if (hConn->nTransactionLevel > 0)
+   {
+      bRet = m_fpDrvCommit(hConn->hConn);
+      hConn->nTransactionLevel--;
+      MutexUnlock(hConn->mutexTransLock);
+   }
+   MutexUnlock(hConn->mutexTransLock);
+   return bRet;
+}
+
+
+//
+// Begin transaction
+//
+
+BOOL LIBNXSRV_EXPORTABLE DBRollback(DB_HANDLE hConn)
+{
+   BOOL bRet = FALSE;
+
+   MutexLock(hConn->mutexTransLock, INFINITE);
+   if (hConn->nTransactionLevel > 0)
+   {
+      bRet = m_fpDrvRollback(hConn->hConn);
+      hConn->nTransactionLevel--;
+      MutexUnlock(hConn->mutexTransLock);
+   }
+   MutexUnlock(hConn->mutexTransLock);
+   return bRet;
 }
 
 
index 949a757..11cdaaf 100644 (file)
@@ -198,6 +198,10 @@ SOURCE=.\rwlock.cpp
 # PROP Default_Filter "h;hpp;hxx;hm;inl"
 # Begin Source File
 
+SOURCE=..\include\dbdrv.h
+# End Source File
+# Begin Source File
+
 SOURCE=.\libnxsrv.h
 # End Source File
 # Begin Source File