1 /*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #define LOG_TAG "QueryHelper"
16 #include "query_helper.h"
17 #include <regex>
18 #include <sstream>
19 #include "data_query.h"
20 #include "device_manager_adapter.h"
21 #include "kvstore_utils.h"
22 #include "log_print.h"
23 #include "types.h"
24 namespace OHOS::DistributedKv {
25 constexpr int QUERY_SKIP_SIZE = 1;
26 constexpr int QUERY_WORD_SIZE = 2;
27 constexpr int MAX_QUERY_LENGTH = 5 * 1024; // Max query string length 5k
28 constexpr int MAX_QUERY_COMPLEXITY = 500; // Max query complexity 500
29 bool QueryHelper::hasPrefixKey_ = false;
30 std::string QueryHelper::deviceId_;
31
StringToDbQuery(const std::string & query,bool & isSuccess)32 DistributedDB::Query QueryHelper::StringToDbQuery(const std::string &query, bool &isSuccess)
33 {
34 ZLOGI("query string length:%{public}zu", query.length());
35 DBQuery dbQuery = DBQuery::Select();
36 if (query.empty()) {
37 ZLOGD("Query string is empty.");
38 isSuccess = true;
39 return dbQuery;
40 }
41 if (query.size() > MAX_QUERY_LENGTH) {
42 ZLOGE("Query string is too long.");
43 isSuccess = false;
44 return dbQuery;
45 }
46 deviceId_.clear();
47 hasPrefixKey_ = (query.find(DataQuery::KEY_PREFIX) != std::string::npos);
48 size_t pos = query.find_first_not_of(DataQuery::SPACE);
49 std::string inputTrim = (pos == std::string::npos) ? "" : query.substr(pos);
50 std::regex regex(" ");
51 // regex split string by space
52 std::vector<std::string> words(std::sregex_token_iterator(inputTrim.begin(), inputTrim.end(), regex, -1),
53 std::sregex_token_iterator());
54
55 if (words.empty()) {
56 ZLOGE("not enough params.");
57 return dbQuery;
58 }
59 int pointer = 0; // Read pointer starts at 0
60 int end = words.size() - 1; // Read pointer ends at size - 1
61 // Counts how many keywords has been handled
62 for (int count = 0; pointer <= end && count <= MAX_QUERY_COMPLEXITY; ++count) {
63 std::string keyword = words.at(pointer);
64 if (keyword == DataQuery::EQUAL_TO) {
65 isSuccess = HandleEqualTo(words, pointer, end, dbQuery);
66 } else if (keyword == DataQuery::NOT_EQUAL_TO) {
67 isSuccess = HandleNotEqualTo(words, pointer, end, dbQuery);
68 } else if (keyword == DataQuery::GREATER_THAN) {
69 isSuccess = HandleGreaterThan(words, pointer, end, dbQuery);
70 } else if (keyword == DataQuery::LESS_THAN) {
71 isSuccess = HandleLessThan(words, pointer, end, dbQuery);
72 } else if (keyword == DataQuery::GREATER_THAN_OR_EQUAL_TO) {
73 isSuccess = HandleGreaterThanOrEqualTo(words, pointer, end, dbQuery);
74 } else if (keyword == DataQuery::LESS_THAN_OR_EQUAL_TO) {
75 isSuccess = HandleLessThanOrEqualTo(words, pointer, end, dbQuery);
76 } else {
77 isSuccess = Handle(words, pointer, end, dbQuery);
78 }
79 if (!isSuccess) {
80 ZLOGE("Invalid params.");
81 return DBQuery::Select();
82 }
83 }
84 return dbQuery;
85 }
86
Handle(const std::vector<std::string> & words,int & pointer,int end,DBQuery & dbQuery)87 bool QueryHelper::Handle(const std::vector<std::string> &words, int &pointer, int end, DBQuery &dbQuery)
88 {
89 std::string keyword = words.at(pointer);
90 if (keyword == DataQuery::IS_NULL) {
91 return HandleIsNull(words, pointer, end, dbQuery);
92 } else if (keyword == DataQuery::IN) {
93 return HandleIn(words, pointer, end, dbQuery);
94 } else if (keyword == DataQuery::NOT_IN) {
95 return HandleNotIn(words, pointer, end, dbQuery);
96 } else if (keyword == DataQuery::LIKE) {
97 return HandleLike(words, pointer, end, dbQuery);
98 } else if (keyword == DataQuery::NOT_LIKE) {
99 return HandleNotLike(words, pointer, end, dbQuery);
100 } else if (keyword == DataQuery::AND) {
101 return HandleAnd(words, pointer, end, dbQuery);
102 } else if (keyword == DataQuery::OR) {
103 return HandleOr(words, pointer, end, dbQuery);
104 } else if (keyword == DataQuery::ORDER_BY_ASC) {
105 return HandleOrderByAsc(words, pointer, end, dbQuery);
106 } else if (keyword == DataQuery::ORDER_BY_DESC) {
107 return HandleOrderByDesc(words, pointer, end, dbQuery);
108 } else if (keyword == DataQuery::ORDER_BY_WRITE_TIME) {
109 return HandleOrderByWriteTime(words, pointer, end, dbQuery);
110 } else if (keyword == DataQuery::LIMIT) {
111 return HandleLimit(words, pointer, end, dbQuery);
112 } else {
113 return HandleExtra(words, pointer, end, dbQuery);
114 }
115 }
116
HandleExtra(const std::vector<std::string> & words,int & pointer,int end,DBQuery & dbQuery)117 bool QueryHelper::HandleExtra(const std::vector<std::string> &words, int &pointer, int end, DBQuery &dbQuery)
118 {
119 std::string keyword = words.at(pointer);
120 if (keyword == DataQuery::BEGIN_GROUP) {
121 return HandleBeginGroup(words, pointer, end, dbQuery);
122 } else if (keyword == DataQuery::END_GROUP) {
123 return HandleEndGroup(words, pointer, end, dbQuery);
124 } else if (keyword == DataQuery::KEY_PREFIX) {
125 return HandleKeyPrefix(words, pointer, end, dbQuery);
126 } else if (keyword == DataQuery::IS_NOT_NULL) {
127 return HandleIsNotNull(words, pointer, end, dbQuery);
128 } else if (keyword == DataQuery::DEVICE_ID) {
129 return HandleDeviceId(words, pointer, end, dbQuery);
130 } else if (keyword == DataQuery::SUGGEST_INDEX) {
131 return HandleSetSuggestIndex(words, pointer, end, dbQuery);
132 } else if (keyword == DataQuery::IN_KEYS) {
133 return HandleInKeys(words, pointer, end, dbQuery);
134 }
135 ZLOGE("Invalid keyword.");
136 return false;
137 }
138
HandleEqualTo(const std::vector<std::string> & words,int & pointer,int end,DBQuery & dbQuery)139 bool QueryHelper::HandleEqualTo(const std::vector<std::string> &words, int &pointer, int end, DBQuery &dbQuery)
140 {
141 if (pointer + 3 > end) { // This keyword has 3 following params
142 ZLOGE("EqualTo not enough params.");
143 return false;
144 }
145 const std::string &fieldType = words.at(pointer + 1); // fieldType
146 const std::string &fieldName = words.at(pointer + 2); // fieldName
147 const std::string &fieldValue = words.at(pointer + 3); // fieldValue
148 if (fieldType == DataQuery::TYPE_INTEGER) {
149 dbQuery.EqualTo(StringToString(fieldName), StringToInt(fieldValue));
150 } else if (fieldType == DataQuery::TYPE_LONG) {
151 dbQuery.EqualTo(StringToString(fieldName), StringToLong(fieldValue));
152 } else if (fieldType == DataQuery::TYPE_DOUBLE) {
153 dbQuery.EqualTo(StringToString(fieldName), StringToDouble(fieldValue));
154 } else if (fieldType == DataQuery::TYPE_BOOLEAN) {
155 dbQuery.EqualTo(StringToString(fieldName), StringToBoolean(fieldValue));
156 } else if (fieldType == DataQuery::TYPE_STRING) {
157 dbQuery.EqualTo(StringToString(fieldName), StringToString(fieldValue));
158 } else {
159 ZLOGE("EqualTo wrong type.");
160 return false;
161 }
162 pointer += 4; // 4 Pointer goes to next keyword
163 return true;
164 }
165
HandleNotEqualTo(const std::vector<std::string> & words,int & pointer,int end,DBQuery & dbQuery)166 bool QueryHelper::HandleNotEqualTo(const std::vector<std::string> &words, int &pointer, int end, DBQuery &dbQuery)
167 {
168 if (pointer + 3 > end) { // This keyword has 3 following params
169 ZLOGE("NotEqualTo not enough params.");
170 return false;
171 }
172 const std::string &fieldType = words.at(pointer + 1); // fieldType
173 const std::string &fieldName = words.at(pointer + 2); // fieldName
174 const std::string &fieldValue = words.at(pointer + 3); // fieldValue
175 if (fieldType == DataQuery::TYPE_INTEGER) {
176 dbQuery.NotEqualTo(StringToString(fieldName), StringToInt(fieldValue));
177 } else if (fieldType == DataQuery::TYPE_LONG) {
178 dbQuery.NotEqualTo(StringToString(fieldName), StringToLong(fieldValue));
179 } else if (fieldType == DataQuery::TYPE_DOUBLE) {
180 dbQuery.NotEqualTo(StringToString(fieldName), StringToDouble(fieldValue));
181 } else if (fieldType == DataQuery::TYPE_BOOLEAN) {
182 dbQuery.NotEqualTo(StringToString(fieldName), StringToBoolean(fieldValue));
183 } else if (fieldType == DataQuery::TYPE_STRING) {
184 dbQuery.NotEqualTo(StringToString(fieldName), StringToString(fieldValue));
185 } else {
186 ZLOGE("NotEqualTo wrong type.");
187 return false;
188 }
189 pointer += 4; // 4 Pointer goes to next keyword
190 return true;
191 }
192
HandleGreaterThan(const std::vector<std::string> & words,int & pointer,int end,DBQuery & dbQuery)193 bool QueryHelper::HandleGreaterThan(const std::vector<std::string> &words, int &pointer, int end, DBQuery &dbQuery)
194 {
195 if (pointer + 3 > end) { // This keyword has 3 following params
196 ZLOGE("GreaterThan not enough params.");
197 return false;
198 }
199 const std::string &fieldType = words.at(pointer + 1); // fieldType
200 const std::string &fieldName = words.at(pointer + 2); // fieldName
201 const std::string &fieldValue = words.at(pointer + 3); // fieldValue
202 if (fieldType == DataQuery::TYPE_INTEGER) {
203 dbQuery.GreaterThan(StringToString(fieldName), StringToInt(fieldValue));
204 } else if (fieldType == DataQuery::TYPE_LONG) {
205 dbQuery.GreaterThan(StringToString(fieldName), StringToLong(fieldValue));
206 } else if (fieldType == DataQuery::TYPE_DOUBLE) {
207 dbQuery.GreaterThan(StringToString(fieldName), StringToDouble(fieldValue));
208 } else if (fieldType == DataQuery::TYPE_STRING) {
209 dbQuery.GreaterThan(StringToString(fieldName), StringToString(fieldValue));
210 } else {
211 ZLOGE("GreaterThan wrong type.");
212 return false;
213 }
214 pointer += 4; // 4 Pointer goes to next keyword
215 return true;
216 }
217
HandleLessThan(const std::vector<std::string> & words,int & pointer,int end,DBQuery & dbQuery)218 bool QueryHelper::HandleLessThan(const std::vector<std::string> &words, int &pointer, int end, DBQuery &dbQuery)
219 {
220 if (pointer + 3 > end) { // This keyword has 3 following params
221 ZLOGE("LessThan not enough params.");
222 return false;
223 }
224 const std::string &fieldType = words.at(pointer + 1); // fieldType
225 const std::string &fieldName = words.at(pointer + 2); // fieldName
226 const std::string &fieldValue = words.at(pointer + 3); // fieldValue
227 if (fieldType == DataQuery::TYPE_INTEGER) {
228 dbQuery.LessThan(StringToString(fieldName), StringToInt(fieldValue));
229 } else if (fieldType == DataQuery::TYPE_LONG) {
230 dbQuery.LessThan(StringToString(fieldName), StringToLong(fieldValue));
231 } else if (fieldType == DataQuery::TYPE_DOUBLE) {
232 dbQuery.LessThan(StringToString(fieldName), StringToDouble(fieldValue));
233 } else if (fieldType == DataQuery::TYPE_STRING) {
234 dbQuery.LessThan(StringToString(fieldName), StringToString(fieldValue));
235 } else {
236 ZLOGE("LessThan wrong type.");
237 return false;
238 }
239 pointer += 4; // 4 Pointer goes to next keyword
240 return true;
241 }
242
HandleGreaterThanOrEqualTo(const std::vector<std::string> & words,int & pointer,int end,DBQuery & dbQuery)243 bool QueryHelper::HandleGreaterThanOrEqualTo(
244 const std::vector<std::string> &words, int &pointer, int end, DBQuery &dbQuery)
245 {
246 if (pointer + 3 > end) { // This keyword has 3 following params
247 ZLOGE("GreaterThanOrEqualTo not enough params.");
248 return false;
249 }
250 const std::string &fieldType = words.at(pointer + 1); // fieldType
251 const std::string &fieldName = words.at(pointer + 2); // fieldName
252 const std::string &fieldValue = words.at(pointer + 3); // fieldValue
253 if (fieldType == DataQuery::TYPE_INTEGER) {
254 dbQuery.GreaterThanOrEqualTo(StringToString(fieldName), StringToInt(fieldValue));
255 } else if (fieldType == DataQuery::TYPE_LONG) {
256 dbQuery.GreaterThanOrEqualTo(StringToString(fieldName), StringToLong(fieldValue));
257 } else if (fieldType == DataQuery::TYPE_DOUBLE) {
258 dbQuery.GreaterThanOrEqualTo(StringToString(fieldName), StringToDouble(fieldValue));
259 } else if (fieldType == DataQuery::TYPE_STRING) {
260 dbQuery.GreaterThanOrEqualTo(StringToString(fieldName), StringToString(fieldValue));
261 } else {
262 ZLOGE("GreaterThanOrEqualTo wrong type.");
263 return false;
264 }
265 pointer += 4; // 4 Pointer goes to next keyword
266 return true;
267 }
268
HandleLessThanOrEqualTo(const std::vector<std::string> & words,int & pointer,int end,DBQuery & dbQuery)269 bool QueryHelper::HandleLessThanOrEqualTo(
270 const std::vector<std::string> &words, int &pointer, int end, DBQuery &dbQuery)
271 {
272 if (pointer + 3 > end) { // This keyword has 3 following params
273 ZLOGE("LessThanOrEqualTo not enough params.");
274 return false;
275 }
276 const std::string &fieldType = words.at(pointer + 1); // fieldType
277 const std::string &fieldName = words.at(pointer + 2); // fieldName
278 const std::string &fieldValue = words.at(pointer + 3); // fieldValue
279 if (fieldType == DataQuery::TYPE_INTEGER) {
280 dbQuery.LessThanOrEqualTo(StringToString(fieldName), StringToInt(fieldValue));
281 } else if (fieldType == DataQuery::TYPE_LONG) {
282 dbQuery.LessThanOrEqualTo(StringToString(fieldName), StringToLong(fieldValue));
283 } else if (fieldType == DataQuery::TYPE_DOUBLE) {
284 dbQuery.LessThanOrEqualTo(StringToString(fieldName), StringToDouble(fieldValue));
285 } else if (fieldType == DataQuery::TYPE_STRING) {
286 dbQuery.LessThanOrEqualTo(StringToString(fieldName), StringToString(fieldValue));
287 } else {
288 ZLOGE("LessThanOrEqualTo wrong type.");
289 return false;
290 }
291 pointer += 4; // 4 Pointer goes to next keyword
292 return true;
293 }
294
HandleIsNull(const std::vector<std::string> & words,int & pointer,int end,DBQuery & dbQuery)295 bool QueryHelper::HandleIsNull(const std::vector<std::string> &words, int &pointer, int end, DBQuery &dbQuery)
296 {
297 if (pointer + 1 > end) { // This keyword has 1 following params
298 ZLOGE("IsNull not enough params.");
299 return false;
300 }
301 const std::string &fieldName = words.at(pointer + 1); // fieldName
302 dbQuery.IsNull(StringToString(fieldName));
303 pointer += 2; // 2 Pointer goes to next keyword
304 return true;
305 }
306
HandleIsNotNull(const std::vector<std::string> & words,int & pointer,int end,DBQuery & dbQuery)307 bool QueryHelper::HandleIsNotNull(const std::vector<std::string> &words, int &pointer, int end, DBQuery &dbQuery)
308 {
309 if (pointer + 1 > end) { // This keyword has 1 following params
310 ZLOGE("IsNotNull not enough params.");
311 return false;
312 }
313 const std::string &fieldName = words.at(pointer + 1); // fieldName
314 dbQuery.IsNotNull(StringToString(fieldName));
315 pointer += 2; // 2 Pointer goes to next keyword
316 return true;
317 }
318
HandleIn(const std::vector<std::string> & words,int & pointer,int end,DBQuery & dbQuery)319 bool QueryHelper::HandleIn(const std::vector<std::string> &words, int &pointer, int end, DBQuery &dbQuery)
320 {
321 // | <-------------------------4---------------------------->|
322 // words [ DataQuery::IN, fieldType, fieldName, DataQuery::START_IN, ...valueList, DataQuery::END_IN ]
323 // index [ -------0-----, ----1----, ----2----, ---------3---------, ... , ---------n--------]
324 // ^ ^
325 // | |
326 // pointer end
327 // first fieldValue, or END if list is empty
328 if (pointer + 4 > end || words.at(pointer + 3) != DataQuery::START_IN) {
329 ZLOGE("In not enough params.");
330 return false;
331 }
332 const std::string &fieldType = words.at(pointer + 1); // fieldType
333 const std::string &fieldName = words.at(pointer + 2); // fieldName
334 int elementPointer = pointer + 4; // first fieldValue, or END if list is empty
335 if (fieldType == DataQuery::TYPE_INTEGER) {
336 const std::vector<int> intValueList = GetIntegerList(words, elementPointer, end);
337 dbQuery.In(StringToString(fieldName), intValueList);
338 } else if (fieldType == DataQuery::TYPE_LONG) {
339 const std::vector<int64_t> longValueList = GetLongList(words, elementPointer, end);
340 dbQuery.In(StringToString(fieldName), longValueList);
341 } else if (fieldType == DataQuery::TYPE_DOUBLE) {
342 const std::vector<double> doubleValueList = GetDoubleList(words, elementPointer, end);
343 dbQuery.In(StringToString(fieldName), doubleValueList);
344 } else if (fieldType == DataQuery::TYPE_STRING) {
345 const std::vector<std::string> stringValueList = GetStringList(words, elementPointer, end);
346 dbQuery.In(StringToString(fieldName), stringValueList);
347 } else {
348 ZLOGE("In wrong type.");
349 return false;
350 }
351 pointer = elementPointer + 1; // Pointer goes to next keyword
352 return true;
353 }
354
HandleNotIn(const std::vector<std::string> & words,int & pointer,int end,DBQuery & dbQuery)355 bool QueryHelper::HandleNotIn(const std::vector<std::string> &words, int &pointer, int end, DBQuery &dbQuery)
356 {
357 // |<--------------------------4-------------------------------->|
358 // words [ DataQuery::NOT_IN, fieldType, fieldName, DataQuery::START_IN, ...valueList, DataQuery::END_IN ]
359 // index [ --------0--------, ----1----, ----2----, ---------3---------, ... , ---------n--------]
360 // ^ ^
361 // | |
362 // pointer end
363 // first fieldValue, or END if list is empty
364 if (pointer + 4 > end || words.at(pointer + 3) != DataQuery::START_IN) {
365 ZLOGE("NotIn not enough params.");
366 return false;
367 }
368 const std::string &fieldType = words.at(pointer + 1); // fieldType
369 const std::string &fieldName = words.at(pointer + 2); // fieldName
370 int elementPointer = pointer + 4; // first fieldValue, or END if list is empty
371 if (fieldType == DataQuery::TYPE_INTEGER) {
372 const std::vector<int> intValueList = GetIntegerList(words, elementPointer, end);
373 dbQuery.NotIn(StringToString(fieldName), intValueList);
374 } else if (fieldType == DataQuery::TYPE_LONG) {
375 const std::vector<int64_t> longValueList = GetLongList(words, elementPointer, end);
376 dbQuery.NotIn(StringToString(fieldName), longValueList);
377 } else if (fieldType == DataQuery::TYPE_DOUBLE) {
378 const std::vector<double> doubleValueList = GetDoubleList(words, elementPointer, end);
379 dbQuery.NotIn(StringToString(fieldName), doubleValueList);
380 } else if (fieldType == DataQuery::TYPE_STRING) {
381 const std::vector<std::string> stringValueList = GetStringList(words, elementPointer, end);
382 dbQuery.NotIn(StringToString(fieldName), stringValueList);
383 } else {
384 ZLOGE("NotIn wrong type.");
385 return false;
386 }
387 pointer = elementPointer + 1; // Pointer goes to next keyword
388 return true;
389 }
390
HandleLike(const std::vector<std::string> & words,int & pointer,int end,DBQuery & dbQuery)391 bool QueryHelper::HandleLike(const std::vector<std::string> &words, int &pointer, int end, DBQuery &dbQuery)
392 {
393 if (pointer + 2 > end) { // This keyword has 2 following params
394 ZLOGE("Like not enough params.");
395 return false;
396 }
397 const std::string &fieldName = words.at(pointer + 1); // fieldName
398 const std::string &fieldValue = words.at(pointer + 2); // fieldValue
399 dbQuery.Like(StringToString(fieldName), StringToString(fieldValue));
400 pointer += 3; // 3 Pointer goes to next keyword
401 return true;
402 }
403
HandleNotLike(const std::vector<std::string> & words,int & pointer,int end,DBQuery & dbQuery)404 bool QueryHelper::HandleNotLike(const std::vector<std::string> &words, int &pointer, int end, DBQuery &dbQuery)
405 {
406 if (pointer + 2 > end) { // This keyword has 2 following params
407 ZLOGE("NotLike not enough params.");
408 return false;
409 }
410 const std::string &fieldName = words.at(pointer + 1); // fieldName
411 const std::string &fieldValue = words.at(pointer + 2); // fieldValue
412 dbQuery.NotLike(StringToString(fieldName), StringToString(fieldValue));
413 pointer += 3; // 3 Pointer goes to next keyword
414 return true;
415 }
416
HandleAnd(const std::vector<std::string> & words,int & pointer,int end,DBQuery & dbQuery)417 bool QueryHelper::HandleAnd(const std::vector<std::string> &words, int &pointer, int end, DBQuery &dbQuery)
418 {
419 dbQuery.And();
420 pointer += 1; // Pointer goes to next keyword
421 return true;
422 }
423
HandleOr(const std::vector<std::string> & words,int & pointer,int end,DBQuery & dbQuery)424 bool QueryHelper::HandleOr(const std::vector<std::string> &words, int &pointer, int end, DBQuery &dbQuery)
425 {
426 dbQuery.Or();
427 pointer += 1; // Pointer goes to next keyword
428 return true;
429 }
430
HandleOrderByAsc(const std::vector<std::string> & words,int & pointer,int end,DBQuery & dbQuery)431 bool QueryHelper::HandleOrderByAsc(const std::vector<std::string> &words, int &pointer, int end, DBQuery &dbQuery)
432 {
433 if (pointer + 1 > end) { // This keyword has 1 following params
434 ZLOGE("OrderByAsc not enough params.");
435 return false;
436 }
437 const std::string &fieldName = words.at(pointer + 1); // fieldName
438 dbQuery.OrderBy(StringToString(fieldName), true);
439 pointer += 2; // 2 Pointer goes to next keyword
440 return true;
441 }
442
HandleOrderByDesc(const std::vector<std::string> & words,int & pointer,int end,DBQuery & dbQuery)443 bool QueryHelper::HandleOrderByDesc(const std::vector<std::string> &words, int &pointer, int end, DBQuery &dbQuery)
444 {
445 if (pointer + 1 > end) { // This keyword has 1 following params
446 ZLOGE("OrderByDesc not enough params.");
447 return false;
448 }
449 const std::string &fieldName = words.at(pointer + 1); // fieldName
450 dbQuery.OrderBy(StringToString(fieldName), false);
451 pointer += 2; // 2 Pointer goes to next keyword
452 return true;
453 }
454
HandleOrderByWriteTime(const std::vector<std::string> & words,int & pointer,int end,DBQuery & dbQuery)455 bool QueryHelper::HandleOrderByWriteTime(const std::vector<std::string> &words, int &pointer, int end, DBQuery &dbQuery)
456 {
457 if (pointer + 1 > end) { // This keyword has 1 following params
458 ZLOGE("HandleOrderByWriteTime not enough params.");
459 return false;
460 }
461 const std::string isAsc = words.at(pointer + 1); // isASC
462
463 dbQuery.OrderByWriteTime(isAsc == DataQuery::IS_ASC);
464 pointer += 2; // 2 Pointer goes to next keyword
465 return true;
466 }
467
HandleLimit(const std::vector<std::string> & words,int & pointer,int end,DBQuery & dbQuery)468 bool QueryHelper::HandleLimit(const std::vector<std::string> &words, int &pointer, int end, DBQuery &dbQuery)
469 {
470 if (pointer + 2 > end) { // This keyword has 2 following params
471 ZLOGE("Limit not enough params.");
472 return false;
473 }
474 const int number = StringToInt(words.at(pointer + 1)); // number
475 const int offset = StringToInt(words.at(pointer + 2)); // offset
476 dbQuery.Limit(number, offset);
477 pointer += 3; // 3 Pointer goes to next keyword
478 return true;
479 }
480
HandleBeginGroup(const std::vector<std::string> & words,int & pointer,int end,DBQuery & dbQuery)481 bool QueryHelper::HandleBeginGroup(const std::vector<std::string> &words, int &pointer, int end, DBQuery &dbQuery)
482 {
483 dbQuery.BeginGroup();
484 pointer += 1; // Pointer goes to next keyword
485 return true;
486 }
487
HandleEndGroup(const std::vector<std::string> & words,int & pointer,int end,DBQuery & dbQuery)488 bool QueryHelper::HandleEndGroup(const std::vector<std::string> &words, int &pointer, int end, DBQuery &dbQuery)
489 {
490 dbQuery.EndGroup();
491 pointer += 1; // Pointer goes to next keyword
492 return true;
493 }
494
HandleKeyPrefix(const std::vector<std::string> & words,int & pointer,int end,DBQuery & dbQuery)495 bool QueryHelper::HandleKeyPrefix(const std::vector<std::string> &words, int &pointer, int end, DBQuery &dbQuery)
496 {
497 if (pointer + 1 > end) { // This keyword has 1 following params
498 ZLOGE("KeyPrefix not enough params.");
499 return false;
500 }
501 const std::string &prefix = deviceId_ + StringToString(words.at(pointer + 1)); // prefix
502 const std::vector<uint8_t> prefixVector(prefix.begin(), prefix.end());
503 dbQuery.PrefixKey(prefixVector);
504 pointer += 2; // 2 Pointer goes to next keyword
505 return true;
506 }
507
HandleInKeys(const std::vector<std::string> & words,int & pointer,int end,DBQuery & dbQuery)508 bool QueryHelper::HandleInKeys(const std::vector<std::string> &words, int &pointer, int end, DBQuery &dbQuery)
509 {
510 // pointer points at keyword "IN_KEYS", (pointer + 1) points at keyword "START_IN"
511 int startInOffSet = pointer + 1;
512 int queryLen = end - pointer;
513 if (queryLen < 2 || words.at(startInOffSet) != DataQuery::START_IN) { // This keyword has at least 2 params
514 ZLOGE("In not enough params.");
515 return false;
516 }
517 int inkeyOffSet = startInOffSet + 1; // inkeyOffSet points at the first inkey value
518 const std::vector<std::string> inKeys = GetStringList(words, inkeyOffSet, end);
519 std::set<std::vector<uint8_t>> inDbKeys;
520 for (const std::string &inKey : inKeys) {
521 ZLOGI("inKey=%{public}s", inKey.c_str());
522 std::vector<uint8_t> dbKey;
523 dbKey.assign(inKey.begin(), inKey.end());
524 inDbKeys.insert(dbKey);
525 }
526 int size = inDbKeys.size();
527 ZLOGI("size of inKeys=%{public}d", size);
528 dbQuery.InKeys(inDbKeys);
529 int endOffSet = inkeyOffSet;
530 pointer = endOffSet + 1; // endOffSet points at keyword "END", Pointer goes to next keyword
531 return true;
532 }
533
HandleSetSuggestIndex(const std::vector<std::string> & words,int & pointer,int end,DBQuery & dbQuery)534 bool QueryHelper::HandleSetSuggestIndex(const std::vector<std::string> &words, int &pointer, int end, DBQuery &dbQuery)
535 {
536 if (pointer + QUERY_SKIP_SIZE > end) {
537 ZLOGE("HandleSetSuggestIndex not enough params.");
538 return false;
539 }
540 std::string index = StringToString(words.at(pointer + QUERY_SKIP_SIZE));
541 dbQuery.SuggestIndex(index);
542 pointer += QUERY_WORD_SIZE;
543 return true;
544 }
545
HandleDeviceId(const std::vector<std::string> & words,int & pointer,int end,DBQuery & dbQuery)546 bool QueryHelper::HandleDeviceId(const std::vector<std::string> &words, int &pointer, int end, DBQuery &dbQuery)
547 {
548 if (pointer + 1 > end) { // This keyword has 1 following params
549 ZLOGE("DeviceId not enough params.");
550 return false;
551 }
552 deviceId_ = StringToString(words.at(pointer + 1)); // deviceId
553 ZLOGI("query devId string length:%zu", deviceId_.length());
554 deviceId_ = DistributedData::DeviceManagerAdapter::GetInstance().GetUuidByNetworkId(deviceId_); // convert to UUId
555 ZLOGI("query converted devId string length:%zu", deviceId_.length());
556 if (!hasPrefixKey_) {
557 ZLOGD("DeviceId as the only prefixKey.");
558 const std::vector<uint8_t> prefixVector(deviceId_.begin(), deviceId_.end());
559 dbQuery.PrefixKey(prefixVector);
560 } else {
561 ZLOGD("Join deviceId with user specified prefixkey later.");
562 }
563 pointer += 2; // 2 Pointer goes to next keyword
564 return true;
565 }
566
StringToInt(const std::string & word)567 int QueryHelper::StringToInt(const std::string &word)
568 {
569 int result;
570 std::istringstream(word) >> result;
571 return result;
572 }
573
StringToLong(const std::string & word)574 int64_t QueryHelper::StringToLong(const std::string &word)
575 {
576 int64_t result;
577 std::istringstream(word) >> result;
578 return result;
579 }
580
StringToDouble(const std::string & word)581 double QueryHelper::StringToDouble(const std::string &word)
582 {
583 double result;
584 std::istringstream(word) >> result;
585 return result;
586 }
587
StringToBoolean(const std::string & word)588 bool QueryHelper::StringToBoolean(const std::string &word)
589 {
590 if (word == DataQuery::VALUE_TRUE) {
591 return true;
592 } else if (word == DataQuery::VALUE_FALSE) {
593 return false;
594 } else {
595 ZLOGE("StringToBoolean wrong value.");
596 return false;
597 }
598 }
599
StringToString(const std::string & word)600 std::string QueryHelper::StringToString(const std::string &word)
601 {
602 std::string result = word;
603 if (result.compare(DataQuery::EMPTY_STRING) == 0) {
604 result = "";
605 return result;
606 }
607 size_t index = 0; // search from the beginning of the string
608 while (true) {
609 index = result.find(DataQuery::SPACE_ESCAPE, index);
610 if (index == std::string::npos) {
611 break;
612 }
613 result.replace(index, 2, DataQuery::SPACE); // 2 chars to be replaced
614 index += 1; // replaced with 1 char, keep searching the remaining string
615 }
616 index = 0; // search from the beginning of the string
617 while (true) {
618 index = result.find(DataQuery::SPECIAL_ESCAPE, index);
619 if (index == std::string::npos) {
620 break;
621 }
622 result.replace(index, 3, DataQuery::SPECIAL); // 3 chars to be replaced
623 index += 1; // replaced with 1 char, keep searching the remaining string
624 }
625 return result;
626 }
627
GetIntegerList(const std::vector<std::string> & words,int & elementPointer,int end)628 std::vector<int> QueryHelper::GetIntegerList(const std::vector<std::string> &words, int &elementPointer, int end)
629 {
630 std::vector<int> valueList;
631 bool isEndFound = false;
632 while (elementPointer <= end) {
633 if (words.at(elementPointer) == DataQuery::END_IN) {
634 isEndFound = true;
635 break;
636 }
637 valueList.push_back(StringToInt(words.at(elementPointer)));
638 elementPointer++;
639 }
640 if (isEndFound) {
641 return valueList;
642 } else {
643 ZLOGE("GetIntegerList failed.");
644 return std::vector<int>();
645 }
646 }
647
GetLongList(const std::vector<std::string> & words,int & elementPointer,int end)648 std::vector<int64_t> QueryHelper::GetLongList(const std::vector<std::string> &words, int &elementPointer, int end)
649 {
650 std::vector<int64_t> valueList;
651 bool isEndFound = false;
652 while (elementPointer <= end) {
653 if (words.at(elementPointer) == DataQuery::END_IN) {
654 isEndFound = true;
655 break;
656 }
657 valueList.push_back(StringToLong(words.at(elementPointer)));
658 elementPointer++;
659 }
660 if (isEndFound) {
661 return valueList;
662 } else {
663 ZLOGE("GetLongList failed.");
664 return std::vector<int64_t>();
665 }
666 }
667
GetDoubleList(const std::vector<std::string> & words,int & elementPointer,int end)668 std::vector<double> QueryHelper::GetDoubleList(const std::vector<std::string> &words, int &elementPointer, int end)
669 {
670 std::vector<double> valueList;
671 bool isEndFound = false;
672 while (elementPointer <= end) {
673 if (words.at(elementPointer) == DataQuery::END_IN) {
674 isEndFound = true;
675 break;
676 }
677 valueList.push_back(StringToDouble(words.at(elementPointer)));
678 elementPointer++;
679 }
680 if (isEndFound) {
681 return valueList;
682 } else {
683 ZLOGE("GetDoubleList failed.");
684 return std::vector<double>();
685 }
686 }
687
GetStringList(const std::vector<std::string> & words,int & elementPointer,int end)688 std::vector<std::string> QueryHelper::GetStringList(const std::vector<std::string> &words, int &elementPointer, int end)
689 {
690 std::vector<std::string> valueList;
691 bool isEndFound = false;
692 while (elementPointer <= end) {
693 if (words.at(elementPointer) == DataQuery::END_IN) {
694 isEndFound = true;
695 break;
696 }
697 valueList.push_back(StringToString(words.at(elementPointer)));
698 elementPointer++;
699 }
700 if (isEndFound) {
701 return valueList;
702 } else {
703 ZLOGE("GetStringList failed.");
704 return std::vector<std::string>();
705 }
706 }
707 } // namespace OHOS::DistributedKv
708