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