diff --git a/DataStorage/DataStorageClient.cpp b/DataStorage/DataStorageClient.cpp index 4b4c613..7e238bf 100644 --- a/DataStorage/DataStorageClient.cpp +++ b/DataStorage/DataStorageClient.cpp @@ -1,14 +1,11 @@ #include "DataStorageClient.h" -#include "DataId.h" -#include -#include +#include "DataStorageClientImpl.h" namespace DataStorage { DataStorageClient::DataStorageClient(const std::shared_ptr& pMySQLClient, const std::string& table) : - m_pMySQLClient(pMySQLClient), - m_table(table) + m_pDataStorageClientImpl(new DataStorageClientImpl(pMySQLClient, table)) { } @@ -18,29 +15,32 @@ DataStorageClient::~DataStorageClient() void DataStorageClient::LogValue(int deviceId, const std::string& dataName, int timestamp, int value) { - int dataId = DataId(dataName).Id(); - - std::stringstream query; - query << "INSERT INTO `" << m_table << "` (device_id, data_id, timestamp, value) VALUES (" << deviceId << "," << dataId << ",FROM_UNIXTIME(" << timestamp << ")," << value << ");"; - m_pMySQLClient->Execute(query.str()); + m_pDataStorageClientImpl->LogValue(deviceId, dataName, timestamp, value); } void DataStorageClient::LogValue(int deviceId, const std::string& dataName, int timestamp, double value) { - int dataId = DataId(dataName).Id(); - - std::stringstream query; - query << "INSERT INTO `" << m_table << "` (device_id, data_id, timestamp, value) VALUES (" << deviceId << "," << dataId << ",FROM_UNIXTIME(" << timestamp << ")," << value << ");"; - m_pMySQLClient->Execute(query.str()); + m_pDataStorageClientImpl->LogValue(deviceId, dataName, timestamp, value); } void DataStorageClient::LogValue(int deviceId, const std::string& dataName, int timestamp, const std::string& value) { - int dataId = DataId(dataName).Id(); - - std::stringstream query; - query << "INSERT INTO `" << m_table << "` (device_id, data_id, timestamp, value) VALUES (" << deviceId << "," << dataId << ",FROM_UNIXTIME(" << timestamp << "),\"" << value << "\");"; - m_pMySQLClient->Execute(query.str()); + m_pDataStorageClientImpl->LogValue(deviceId, dataName, timestamp, value); } -} // namespace DataStorageClientImpl +void DataStorageClient::LogValueTimed(int deviceId, const std::string& dataName, int value) +{ + m_pDataStorageClientImpl->LogValueTimed(deviceId, dataName, value); +} + +void DataStorageClient::LogValueTimed(int deviceId, const std::string& dataName, double value) +{ + m_pDataStorageClientImpl->LogValueTimed(deviceId, dataName, value); +} + +void DataStorageClient::LogValueTimed(int deviceId, const std::string& dataName, const std::string& value) +{ + m_pDataStorageClientImpl->LogValueTimed(deviceId, dataName, value); +} + +} // namespace DataStorage diff --git a/DataStorage/DataStorageClientImpl.cpp b/DataStorage/DataStorageClientImpl.cpp new file mode 100644 index 0000000..53f345e --- /dev/null +++ b/DataStorage/DataStorageClientImpl.cpp @@ -0,0 +1,89 @@ +#include "DataStorageClientImpl.h" +#include "DataId.h" +#include +#include +#include + + +namespace DataStorage { + +DataStorageClientImpl::DataStorageClientImpl(const std::shared_ptr& pMySQLClient, const std::string& table) : + m_pMySQLClient(pMySQLClient), + m_table(table), + m_metronome(Timer::Metronome::Quantity::Minutes, 5) +{ + m_metronome.Connect(std::bind(&DataStorageClientImpl::MetronomeCallback, this)); +} + +DataStorageClientImpl::~DataStorageClientImpl() +{ +} + +void DataStorageClientImpl::LogValue(int deviceId, const std::string& dataName, int timestamp, int value) +{ + int dataId = DataId(dataName).Id(); + WriteValue(Device_Data(deviceId, dataId), timestamp, value); +} + +void DataStorageClientImpl::LogValue(int deviceId, const std::string& dataName, int timestamp, double value) +{ + int dataId = DataId(dataName).Id(); + WriteValue(Device_Data(deviceId, dataId), timestamp, value); +} + +void DataStorageClientImpl::LogValue(int deviceId, const std::string& dataName, int timestamp, const std::string& value) +{ + int dataId = DataId(dataName).Id(); + WriteValue(Device_Data(deviceId, dataId), timestamp, value); +} + +void DataStorageClientImpl::LogValueTimed(int deviceId, const std::string& dataName, int value) +{ + std::unique_lock lock(m_mutex); + m_integerValues[Device_Data(deviceId, DataId(dataName).Id())] = value; +} + +void DataStorageClientImpl::LogValueTimed(int deviceId, const std::string& dataName, double value) +{ + std::unique_lock lock(m_mutex); + m_doubleValues[Device_Data(deviceId, DataId(dataName).Id())] = value; +} + +void DataStorageClientImpl::LogValueTimed(int deviceId, const std::string& dataName, const std::string& value) +{ + std::unique_lock lock(m_mutex); + m_stringValues[Device_Data(deviceId, DataId(dataName).Id())] = value; +} + +void DataStorageClientImpl::MetronomeCallback() +{ + int timestamp = DateTime::GetTimestamp(); + + std::unique_lock lock(m_mutex); + ProcessValueMap(m_integerValues, timestamp); + ProcessValueMap(m_doubleValues, timestamp); + ProcessValueMap(m_stringValues, timestamp); +} + +void DataStorageClientImpl::WriteValue(const Device_Data& device_data, int timestamp, int value) +{ + std::stringstream query; + query << "INSERT INTO `" << m_table << "` (device_id, data_id, timestamp, value) VALUES (" << device_data.DeviceId() << "," << device_data.DataId() << ",FROM_UNIXTIME(" << timestamp << ")," << value << ");"; + m_pMySQLClient->Execute(query.str()); +} + +void DataStorageClientImpl::WriteValue(const Device_Data& device_data, int timestamp, double value) +{ + std::stringstream query; + query << "INSERT INTO `" << m_table << "` (device_id, data_id, timestamp, value) VALUES (" << device_data.DeviceId() << "," << device_data.DataId() << ",FROM_UNIXTIME(" << timestamp << ")," << value << ");"; + m_pMySQLClient->Execute(query.str()); +} + +void DataStorageClientImpl::WriteValue(const Device_Data& device_data, int timestamp, const std::string& value) +{ + std::stringstream query; + query << "INSERT INTO `" << m_table << "` (device_id, data_id, timestamp, value) VALUES (" << device_data.DeviceId() << "," << device_data.DataId() << ",FROM_UNIXTIME(" << timestamp << "),\"" << value << "\");"; + m_pMySQLClient->Execute(query.str()); +} + +} // namespace DataStorage diff --git a/DataStorage/DataStorageClientImpl.h b/DataStorage/DataStorageClientImpl.h new file mode 100644 index 0000000..145060c --- /dev/null +++ b/DataStorage/DataStorageClientImpl.h @@ -0,0 +1,101 @@ +#ifndef DATASTORAGE_DATASTORAGECLIENTIMPL_H +#define DATASTORAGE_DATASTORAGECLIENTIMPL_H + +#include +#include +#include +#include +#include + + +namespace MySQL { + +class MySQLClient; + +} // namespace MySQL + +namespace DataStorage { + +class DataStorageClientImpl +{ +public: + DataStorageClientImpl(const std::shared_ptr& pMySQLClient, const std::string& table); + ~DataStorageClientImpl(); + +public: + void LogValue(int deviceId, const std::string& dataName, int timestamp, int value); + void LogValue(int deviceId, const std::string& dataName, int timestamp, double value); + void LogValue(int deviceId, const std::string& dataName, int timestamp, const std::string& value); + + void LogValueTimed(int deviceId, const std::string& dataName, int value); + void LogValueTimed(int deviceId, const std::string& dataName, double value); + void LogValueTimed(int deviceId, const std::string& dataName, const std::string& value); + +public: + void MetronomeCallback(); + +private: + class Device_Data { + public: + Device_Data(int deviceId, int dataId) : + m_deviceId(deviceId), + m_dataId(dataId) + { + } + + public: + int DeviceId() const + { + return m_deviceId; + } + + int DataId() const + { + return m_dataId; + } + + public: + bool operator=(const Device_Data& other) const + { + return m_deviceId == other.DeviceId() && m_dataId == other.DataId(); + } + + bool operator<(const Device_Data& other) const + { + return m_deviceId < other.DeviceId() || (m_deviceId == other.DeviceId() && m_dataId < other.DataId()); + } + + private: + int m_deviceId; + int m_dataId; + }; + +private: + void WriteValue(const Device_Data& device_data, int timestamp, int value); + void WriteValue(const Device_Data& device_data, int timestamp, double value); + void WriteValue(const Device_Data& device_data, int timestamp, const std::string& value); + +private: + template + void ProcessValueMap(std::map& map, int timestamp) + { + for (const auto& keyValue : map) + WriteValue(keyValue.first, timestamp, keyValue.second); + map.clear(); + } + +private: + std::mutex m_mutex; + + std::shared_ptr m_pMySQLClient; + std::string m_table; + Timer::Metronome m_metronome; + + std::map m_integerValues; + std::map m_doubleValues; + std::map m_stringValues; +}; + +} // namespace DataStorage + +#endif // DATASTORAGE_DATASTORAGECLIENTIMPL_H diff --git a/Libraries/DateTime b/Libraries/DateTime new file mode 120000 index 0000000..e4fb5f1 --- /dev/null +++ b/Libraries/DateTime @@ -0,0 +1 @@ +../../DateTime \ No newline at end of file diff --git a/Libraries/Timer b/Libraries/Timer new file mode 120000 index 0000000..ee40699 --- /dev/null +++ b/Libraries/Timer @@ -0,0 +1 @@ +../../Timer \ No newline at end of file diff --git a/Makefile.conf b/Makefile.conf index ecfd4d1..9283278 100644 --- a/Makefile.conf +++ b/Makefile.conf @@ -14,6 +14,14 @@ LFLAGS += -lMySQL -lmysqlclient -lmysqlcppconn LFLAGS += -L$(ROOTPATH)/Libraries/MySQL/lib/$(ARCH) CFLAGS += -I$(ROOTPATH)/Libraries/MySQL/include +LFLAGS += -lTimer +LFLAGS += -L$(ROOTPATH)/Libraries/Timer/lib/$(ARCH) +CFLAGS += -I$(ROOTPATH)/Libraries/Timer/include + +LFLAGS += -lDateTime +LFLAGS += -L$(ROOTPATH)/Libraries/DateTime/lib/$(ARCH) +CFLAGS += -I$(ROOTPATH)/Libraries/DateTime/include + LFLAGS += -lDataStorage LFLAGS += -L$(ROOTPATH)/lib/$(ARCH) CFLAGS += -I$(ROOTPATH) -I$(ROOTPATH)/include diff --git a/include/DataStorageClient.h b/include/DataStorageClient.h index dbd61d0..16f5b06 100644 --- a/include/DataStorageClient.h +++ b/include/DataStorageClient.h @@ -1,7 +1,6 @@ #ifndef DATASTORAGECLIENT_H #define DATASTORAGECLIENT_H -#include "Timespan.h" #include #include @@ -27,9 +26,15 @@ public: void LogValue(int deviceId, const std::string& dataName, int timestamp, double value); void LogValue(int deviceId, const std::string& dataName, int timestamp, const std::string& value); + void LogValueTimed(int deviceId, const std::string& dataName, int value); + void LogValueTimed(int deviceId, const std::string& dataName, double value); + void LogValueTimed(int deviceId, const std::string& dataName, const std::string& value); + +public: + void MetronomeCallback(); + private: - std::shared_ptr m_pMySQLClient; - std::string m_table; + std::unique_ptr m_pDataStorageClientImpl; }; } // namespace DataStorage