#include #include "strutil.h" #include "mysqlwrap.h" #include "remvar.h" #include "debug.h" ///////////////////////////////////////////////////////////////////////////// #define LOGS_FIELDNAME_VALUE "value" #define TAGS_FIELDNAME_TAGID "tagid" #define TAGS_FIELDNAME_PATH "path" ///////////////////////////////////////////////////////////////////////////// CDbPersist::CDbPersist(const char *pszDatabaseName, const char *pszTagsTableName, const char *pszLogsTableName, const char *pszDbUser, const char *pszDbPass) : m_sDatabaseName(pszDatabaseName), m_sTagsTableName(pszTagsTableName), m_sLogsTableName(pszLogsTableName), m_sUser(pszDbUser), m_sPass(pszDbPass) { } CDbPersist::~CDbPersist(void) { } ///////////////////////////////////////////////////////////////////////////// bool CDbPersist::Init(CMySqlDB &db) { if(!db.Options(MYSQL_SET_CHARSET_NAME, "utf8")) { m_lastError = db.LastError(); return false; } if(!db.Options(MYSQL_INIT_COMMAND, "SET NAMES utf8")) { m_lastError = db.LastError(); return false; } if(!db.Connect("localhost", m_sUser.c_str(), m_sPass.c_str(), NULL)) { m_lastError = db.LastError(); return false; } if(db.SelectDB(m_sDatabaseName.c_str())) { m_lastError = db.LastError(); return false; } std::string sql = formatString("SELECT * FROM `%s` WHERE `logType` IN ('ICR', 'IUR', 'VCR', 'VUR');", m_sTagsTableName.c_str()); CMySqlResult res = db.Query(sql.c_str()); if(!res.error()) { CMySqlRow row; while(res.FetchRow(row)) { CFieldMap fields([](const std::string &s1, const std::string &s2) { return s1.compare(s2) < 0; }); for(const auto &field : row) { fields[field.first] = field.second.StrVal(); } m_tags.push_back(fields); } return true; } else { m_lastError = db.LastError(); } return false; } ///////////////////////////////////////////////////////////////////////////// int CDbPersist::RestoreValues(const CRemVarTable &map, CLogfile &rlf) { int nRet = 0; CMySqlDB db; if(!Init(db)) { TRACE("Failed to initialize Datalogger Database: %s!\nNo Database-persistant values restored!\n", m_lastError.c_str()); rlf.Error("Failed to initialize Datalogger Database: %s! No Database-persistant values restored!\n", m_lastError.c_str()); return -1; } for(auto &fields : m_tags) { std::string tagID = fields[TAGS_FIELDNAME_TAGID]; std::string path = fields[TAGS_FIELDNAME_PATH]; CRemanent *pVar = map.Find(path.c_str()); if(pVar) { std::string sql = formatString("SELECT `%s` FROM `%s` WHERE `%s` = %s AND `value` IS NOT NULL ORDER BY `tslog` DESC LIMIT 1;", LOGS_FIELDNAME_VALUE, m_sLogsTableName.c_str(), TAGS_FIELDNAME_TAGID, tagID.c_str()); CMySqlResult res = db.Query(sql.c_str()); if(!res.error()) { CMySqlRow row; if(res.FetchRow(row)) { const CMySqlVar &var = row[LOGS_FIELDNAME_VALUE]; if(var.IsValid() && var.IsReal()) { // TRACE("Restoring value %s (%s) from Database: %.2f!\n", tagID.c_str(), path.c_str(), (double)var); if(pVar->SetDoubleValue(var, true)) ++nRet; else { } } else { m_lastError = db.LastError(); TRACE("Unable to retrieve value %s (%s) from Database: %s!\n", tagID.c_str(), path.c_str(), m_lastError.c_str()); rlf.Warning("Unable to retrieve value %s (%s) from Database: %s!\n", tagID.c_str(), path.c_str(), m_lastError.c_str()); } } } else { m_lastError = db.LastError(); TRACE("Error retrieving value %s (%s) from Database: %s!\n", tagID.c_str(), path.c_str(), m_lastError.c_str()); rlf.Error("Error retrieving value %s (%s) from Database: %s!\n", tagID.c_str(), path.c_str(), m_lastError.c_str()); } } else { TRACE("Unable to find %s (%s) in VarTable!\n", tagID.c_str(), path.c_str()); rlf.Warning("Unable to find %s (%s) in VarTable!\n", tagID.c_str(), path.c_str()); } } return nRet; }