Collected DCI data recalculation based on stored raw values and current transformatio...
[public/netxms.git] / src / server / core / dci_recalc.cpp
1 /*
2 ** NetXMS - Network Management System
3 ** Copyright (C) 2003-2017 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 ** File: dci_recalc.cpp
20 **
21 **/
22
23 #include "nxcore.h"
24
25 /**
26 * Recalculation job constructor
27 */
28 DCIRecalculationJob::DCIRecalculationJob(DataCollectionTarget *object, DCItem *dci, UINT32 userId)
29 : ServerJob(_T("DCI_RECALC"), _T("Recalculate DCI values"), object->getId(), userId, false)
30 {
31 m_object = object;
32 m_object->incRefCount();
33 m_dci = new DCItem(dci);
34 m_cancelled = false;
35
36 TCHAR buffer[1024];
37 _sntprintf(buffer, 1024, _T("Recalculate values for DCI \"%s\" on %s"), dci->getDescription(), object->getName());
38 setDescription(buffer);
39 }
40
41 /**
42 * Recalculation job destructor
43 */
44 DCIRecalculationJob::~DCIRecalculationJob()
45 {
46 m_object->decRefCount();
47 delete m_dci;
48 }
49
50 /**
51 * Run job
52 */
53 ServerJobResult DCIRecalculationJob::run()
54 {
55 DB_HANDLE hdb = DBConnectionPoolAcquireConnection();
56
57 TCHAR query[256];
58 _sntprintf(query, 256, _T("SELECT idata_timestamp,raw_value FROM idata_%d WHERE item_id=%d ORDER BY idata_timestamp"), m_object->getId(), m_dci->getId());
59 DB_RESULT hResult = DBSelect(hdb, query);
60 if (hResult == NULL)
61 {
62 DBConnectionPoolReleaseConnection(hdb);
63 return JOB_RESULT_FAILED;
64 }
65
66 bool success = true;
67 int count = DBGetNumRows(hResult);
68 if (count > 0)
69 {
70 _sntprintf(query, 256, _T("UPDATE idata_%d SET idata_value=? WHERE item_id=? AND idata_timestamp=?"), m_object->getId());
71 DB_STATEMENT hStmt = DBPrepare(hdb, query);
72 if (hStmt != NULL)
73 {
74 m_dci->prepareForRecalc();
75 DBBegin(hdb);
76 for(int i = 0; (i < count) && !m_cancelled; i++)
77 {
78 time_t timestamp = static_cast<time_t>(DBGetFieldInt64(hResult, i, 0));
79 TCHAR data[MAX_RESULT_LENGTH];
80 DBGetField(hResult, i, 1, data, MAX_RESULT_LENGTH);
81 ItemValue value(data, timestamp);
82 m_dci->recalculateValue(value);
83
84 DBBind(hStmt, 1, DB_SQLTYPE_VARCHAR, value.getString(), DB_BIND_STATIC);
85 DBBind(hStmt, 2, DB_SQLTYPE_INTEGER, m_dci->getId());
86 DBBind(hStmt, 3, DB_SQLTYPE_INTEGER, (UINT32)value.getTimeStamp());
87 DBExecute(hStmt);
88
89 if (i % 10 == 0)
90 {
91 markProgress(i * 100 / count);
92 }
93
94 if (i % 1000 == 0)
95 {
96 DBCommit(hdb);
97 DBBegin(hdb);
98 }
99 }
100 DBCommit(hdb);
101 DBFreeStatement(hStmt);
102 }
103 else
104 {
105 success = false;
106 }
107 }
108
109 DBFreeResult(hResult);
110 DBConnectionPoolReleaseConnection(hdb);
111
112 if (success)
113 {
114 m_object->reloadDCItemCache(m_dci->getId());
115 markProgress(100);
116 }
117 return success ? JOB_RESULT_SUCCESS : JOB_RESULT_FAILED;
118 }
119
120 /**
121 * Cancel job
122 */
123 bool DCIRecalculationJob::onCancel()
124 {
125 m_cancelled = true;
126 return true;
127 }