Skip to content

Commit 8439e54

Browse files
authored
Feature/cppclient table redirection (apache#15439)
* Implement high availability CPP client under table model * Implement high availability CPP client under table model; Refactored the CPP client codebase * Implement high availability CPP client under table model;Refactored the CPP client codebase * Refactored the CPP client codebase * Refactored the CPP client codebase * fix compilation error * Extended data type support to cover STRING, BLOB, DATE, and TIMESTAMP; Fixed memory leaks in test cases (Valgrind verified) * fix compilation error on ubuntu14.04/boost1.60 * Implement high availability CPP client under table&tree model;Refactored the CPP client codebase;Extended data type support to cover STRING, BLOB, DATE, and TIMESTAMP
1 parent 29a6836 commit 8439e54

File tree

13 files changed

+3502
-1920
lines changed

13 files changed

+3502
-1920
lines changed

iotdb-client/client-cpp/pom.xml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,18 @@
203203
<sourceFile>${project.basedir}/src/main/AbstractSessionBuilder.h</sourceFile>
204204
<destinationFile>${project.build.directory}/build/main/generated-sources-cpp/AbstractSessionBuilder.h</destinationFile>
205205
</fileSet>
206+
<fileSet>
207+
<sourceFile>${project.basedir}/src/main/Common.h</sourceFile>
208+
<destinationFile>${project.build.directory}/build/main/generated-sources-cpp/Common.h</destinationFile>
209+
</fileSet>
210+
<fileSet>
211+
<sourceFile>${project.basedir}/src/main/Common.cc</sourceFile>
212+
<destinationFile>${project.build.directory}/build/main/generated-sources-cpp/Common.cc</destinationFile>
213+
</fileSet>
214+
<fileSet>
215+
<sourceFile>${project.basedir}/src/main/DeviceID.h</sourceFile>
216+
<destinationFile>${project.build.directory}/build/main/generated-sources-cpp/DeviceID.h</destinationFile>
217+
</fileSet>
206218
</fileSets>
207219
</configuration>
208220
</execution>
Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
/**
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
#include "Common.h"
21+
#include <boost/date_time/gregorian/gregorian.hpp>
22+
23+
int32_t parseDateExpressionToInt(const boost::gregorian::date& date) {
24+
if(date.is_not_a_date()) {
25+
throw IoTDBException("Date expression is null or empty.");
26+
}
27+
28+
const int year = date.year();
29+
if(year < 1000 || year > 9999) {
30+
throw DateTimeParseException(
31+
"Year must be between 1000 and 9999.",
32+
boost::gregorian::to_iso_extended_string(date),
33+
0
34+
);
35+
}
36+
37+
const int64_t result = static_cast<int64_t>(year) * 10000 +
38+
date.month() * 100 +
39+
date.day();
40+
if(result > INT32_MAX || result < INT32_MIN) {
41+
throw DateTimeParseException(
42+
"Date value overflow. ",
43+
boost::gregorian::to_iso_extended_string(date),
44+
0
45+
);
46+
}
47+
return static_cast<int32_t>(result);
48+
}
49+
50+
boost::gregorian::date parseIntToDate(int32_t dateInt) {
51+
if (dateInt == EMPTY_DATE_INT) {
52+
return boost::gregorian::date(boost::date_time::not_a_date_time);
53+
}
54+
int year = dateInt / 10000;
55+
int month = (dateInt % 10000) / 100;
56+
int day = dateInt % 100;
57+
return boost::gregorian::date(year, month, day);
58+
}
59+
60+
void RpcUtils::verifySuccess(const TSStatus &status) {
61+
if (status.code == TSStatusCode::MULTIPLE_ERROR) {
62+
verifySuccess(status.subStatus);
63+
return;
64+
}
65+
if (status.code != TSStatusCode::SUCCESS_STATUS
66+
&& status.code != TSStatusCode::REDIRECTION_RECOMMEND) {
67+
throw ExecutionException(to_string(status.code) + ": " + status.message, status);
68+
}
69+
}
70+
71+
void RpcUtils::verifySuccessWithRedirection(const TSStatus &status) {
72+
verifySuccess(status);
73+
if (status.__isset.redirectNode) {
74+
throw RedirectException(to_string(status.code) + ": " + status.message, status.redirectNode);
75+
}
76+
if (status.__isset.subStatus) {
77+
auto statusSubStatus = status.subStatus;
78+
vector<TEndPoint> endPointList(statusSubStatus.size());
79+
int count = 0;
80+
for (TSStatus subStatus : statusSubStatus) {
81+
if (subStatus.__isset.redirectNode) {
82+
endPointList[count++] = subStatus.redirectNode;
83+
} else {
84+
TEndPoint endPoint;
85+
endPointList[count++] = endPoint;
86+
}
87+
}
88+
if (!endPointList.empty()) {
89+
throw RedirectException(to_string(status.code) + ": " + status.message, endPointList);
90+
}
91+
}
92+
}
93+
94+
void RpcUtils::verifySuccessWithRedirectionForMultiDevices(const TSStatus &status, vector<string> devices) {
95+
verifySuccess(status);
96+
97+
if (status.code == TSStatusCode::MULTIPLE_ERROR
98+
|| status.code == TSStatusCode::REDIRECTION_RECOMMEND) {
99+
map<string, TEndPoint> deviceEndPointMap;
100+
vector<TSStatus> statusSubStatus;
101+
for (int i = 0; i < statusSubStatus.size(); i++) {
102+
TSStatus subStatus = statusSubStatus[i];
103+
if (subStatus.__isset.redirectNode) {
104+
deviceEndPointMap.insert(make_pair(devices[i], subStatus.redirectNode));
105+
}
106+
}
107+
throw RedirectException(to_string(status.code) + ": " + status.message, deviceEndPointMap);
108+
}
109+
110+
if (status.__isset.redirectNode) {
111+
throw RedirectException(to_string(status.code) + ": " + status.message, status.redirectNode);
112+
}
113+
if (status.__isset.subStatus) {
114+
auto statusSubStatus = status.subStatus;
115+
vector<TEndPoint> endPointList(statusSubStatus.size());
116+
int count = 0;
117+
for (TSStatus subStatus : statusSubStatus) {
118+
if (subStatus.__isset.redirectNode) {
119+
endPointList[count++] = subStatus.redirectNode;
120+
} else {
121+
TEndPoint endPoint;
122+
endPointList[count++] = endPoint;
123+
}
124+
}
125+
if (!endPointList.empty()) {
126+
throw RedirectException(to_string(status.code) + ": " + status.message, endPointList);
127+
}
128+
}
129+
}
130+
131+
void RpcUtils::verifySuccess(const vector<TSStatus> &statuses) {
132+
for (const TSStatus &status: statuses) {
133+
if (status.code != TSStatusCode::SUCCESS_STATUS) {
134+
throw BatchExecutionException(status.message, statuses);
135+
}
136+
}
137+
}
138+
139+
TSStatus RpcUtils::getStatus(TSStatusCode::TSStatusCode tsStatusCode) {
140+
TSStatus status;
141+
status.__set_code(tsStatusCode);
142+
return status;
143+
}
144+
145+
TSStatus RpcUtils::getStatus(int code, const string &message) {
146+
TSStatus status;
147+
status.__set_code(code);
148+
status.__set_message(message);
149+
return status;
150+
}
151+
152+
shared_ptr<TSExecuteStatementResp> RpcUtils::getTSExecuteStatementResp(TSStatusCode::TSStatusCode tsStatusCode) {
153+
TSStatus status = getStatus(tsStatusCode);
154+
return getTSExecuteStatementResp(status);
155+
}
156+
157+
shared_ptr<TSExecuteStatementResp>
158+
RpcUtils::getTSExecuteStatementResp(TSStatusCode::TSStatusCode tsStatusCode, const string &message) {
159+
TSStatus status = getStatus(tsStatusCode, message);
160+
return getTSExecuteStatementResp(status);
161+
}
162+
163+
shared_ptr<TSExecuteStatementResp> RpcUtils::getTSExecuteStatementResp(const TSStatus &status) {
164+
shared_ptr<TSExecuteStatementResp> resp(new TSExecuteStatementResp());
165+
TSStatus tsStatus(status);
166+
resp->__set_status(status);
167+
return resp;
168+
}
169+
170+
shared_ptr<TSFetchResultsResp> RpcUtils::getTSFetchResultsResp(TSStatusCode::TSStatusCode tsStatusCode) {
171+
TSStatus status = getStatus(tsStatusCode);
172+
return getTSFetchResultsResp(status);
173+
}
174+
175+
shared_ptr<TSFetchResultsResp>
176+
RpcUtils::getTSFetchResultsResp(TSStatusCode::TSStatusCode tsStatusCode, const string &appendMessage) {
177+
TSStatus status = getStatus(tsStatusCode, appendMessage);
178+
return getTSFetchResultsResp(status);
179+
}
180+
181+
shared_ptr<TSFetchResultsResp> RpcUtils::getTSFetchResultsResp(const TSStatus &status) {
182+
shared_ptr<TSFetchResultsResp> resp(new TSFetchResultsResp());
183+
TSStatus tsStatus(status);
184+
resp->__set_status(tsStatus);
185+
return resp;
186+
}

0 commit comments

Comments
 (0)