-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathPostgreSQLClient.cpp
161 lines (131 loc) · 5.44 KB
/
PostgreSQLClient.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
#include "PostgreSQLClient.h"
#include "loggerpp/include/LoggerPP.h"
PostgreSQLClient::PostgreSQLClient() : SOCIDBClient(SqlDBMS::PostgreSQL)
{
}
PostgreSQLClient::~PostgreSQLClient()
{
}
bool PostgreSQLClient::connect(DBSettings &dbSets)
{
m_lastDbSets = dbSets;
std::string conStr = "dbname="+dbSets.nameDB+
" host="+dbSets.host+
" port="+std::to_string(dbSets.port)+
" user="+dbSets.userName+
" password="+dbSets.password+
" connect_timeout="+std::to_string(dbSets.conTimeout)+
" singlerows=false";
bool retOK = _connect(conStr);
return retOK;
}
IDBClient::ErrStatus PostgreSQLClient::createFunction(std::string text)
{
if(!checkConnectToDB()) {
return ErrStatus::ErrConnectDB;
}
std::string queryStr = text;
LOG(DEBUG) << queryStr;
try
{
m_sqlSession << queryStr;
LOG(DEBUG) << "CREATE FUNCTION success!";
}
catch (const soci::soci_error& e) {
LOG(WARNING) << "Ошибка запроса " << queryStr;
LOG(ERROR) << "SOCI Error: " << e.what() << std::endl;
return ErrStatus::ErrSendQuery;
}
return ErrStatus::NoError;
}
IDBClient::ErrStatus PostgreSQLClient::getTimeLine(std::vector<JSON> &resultVarMap,
std::string &timeBegin, std::string &timeEnd, std::string &camSource)
{
if(!checkConnectToDB()) {
return ErrStatus::ErrConnectDB;
}
std::string filterWhereRow = "(\"timestamp-begin\" between beginT and endT) and \"source\"=camSource";
std::string inputFuncArgs = "beginT timestamp, endT timestamp, camSource text";
// ********* PREPARE SQL FUNCTION **************
std::string funcText = "CREATE OR REPLACE FUNCTION continue_time_frame("+inputFuncArgs+") \
RETURNS table(\"timestamp-begin-sub\" timestamp, \"timestamp-end-sub\" timestamp, grp bigint) \
AS \
$$ \
SELECT \"timestamp-begin\", \"timestamp-end\", count(*) FILTER (WHERE step) \
OVER (ORDER BY \"timestamp-begin\") AS grp \
FROM ( SELECT \"timestamp-begin\", \"timestamp-end\", \
(lag(\"timestamp-begin\") OVER (ORDER BY \"timestamp-begin\") <= \"timestamp-begin\" - interval '1.5 min') \
AS step FROM archivewriter where "+filterWhereRow+" ) sub ORDER BY \"timestamp-begin\" \
$$ language sql; ";
auto retErr = createFunction(funcText);
if(retErr != IDBClient::NoError) {
LOG(ERROR) << "ERROR Create FUNCTION continue_time_frame!";
return ErrStatus::ErrSendQuery;
}
std::string inputArgRow = "'"+timeBegin+"','"+timeEnd+"','"+camSource+"'";
std::string queryStr = "SELECT DISTINCT FIRST_VALUE(\"timestamp-begin-sub\") \
OVER(PARTITION BY grp ORDER BY \"timestamp-begin-sub\") AS \"begin-sub\", \
FIRST_VALUE(\"timestamp-end-sub\") OVER(PARTITION BY grp ORDER BY \"timestamp-end-sub\" desc) \
AS \"end-sub\", grp \
FROM continue_time_frame("+inputArgRow+") LIMIT " +std::to_string(MAX_LIMIT)+ ";";
LOG(DEBUG) << queryStr;
try
{
// Создаем объект rowset для хранения результатов запроса
soci::rowset<soci::row> rows = (m_sqlSession.prepare << queryStr);
LOG(DEBUG) << "Get row from continue_time_frame is ok! " ;
for (const auto& row : rows) {
// Получаем количество столбцов в текущей строке
std::size_t numColumns = row.size();
LOG(DEBUG) << "Получено колонок: " << numColumns;
JSON oneResultMap;
// Обрабатываем каждый столбец
for (std::size_t i = 0; i < numColumns; ++i) {
// Используем get без указания типа для динамического получения значения
soci::column_properties props = row.get_properties(i);
std::string columnName = props.get_name();
LOG(DEBUG) << "Column " << columnName << " before oneResultMap[columnName] =";
// if(Strings::toLower(columnName) == "timestamp_cast")
// columnName = "timestamp";
oneResultMap[columnName] = getAsJsonValue(row, i);
LOG(DEBUG) << "Column " << columnName << ": " << oneResultMap[columnName];
}
if(!oneResultMap.empty())
resultVarMap.push_back(oneResultMap);
}
if(resultVarMap.empty()) {
LOG(DEBUG) << "resultVarMap пуст :(";
return ErrStatus::NotExists;
}
}
catch (const soci::soci_error& e) {
LOG(WARNING) << "Ошибка запроса " << queryStr;
LOG(ERROR) << "SOCI Error: " << e.what() << std::endl;
return ErrStatus::ErrSendQuery;
}
return ErrStatus::NoError;
}
std::string PostgreSQLClient::nameTypeForTimestamp()
{
return "timestamp";
}
std::string PostgreSQLClient::nameTypeForText()
{
return "text";
}
std::string PostgreSQLClient::nameTypeForJson()
{
return "jsonb";
}
std::string PostgreSQLClient::nameTypeForBool()
{
return "int4";
}
std::string PostgreSQLClient::nameTypeForInt()
{
return "int4";
}
std::string PostgreSQLClient::nameTypeForDouble()
{
return "real";
}