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 
16 #define LOG_TAG "DataQuery"
17 
18 #include "data_query.h"
19 #include "log_print.h"
20 #include "query.h"
21 namespace OHOS {
22 namespace DistributedKv {
23 const char * const DataQuery::EQUAL_TO = "^EQUAL";
24 const char * const DataQuery::NOT_EQUAL_TO = "^NOT_EQUAL";
25 const char * const DataQuery::GREATER_THAN = "^GREATER";
26 const char * const DataQuery::LESS_THAN = "^LESS";
27 const char * const DataQuery::GREATER_THAN_OR_EQUAL_TO = "^GREATER_EQUAL";
28 const char * const DataQuery::LESS_THAN_OR_EQUAL_TO = "^LESS_EQUAL";
29 const char * const DataQuery::IS_NULL = "^IS_NULL";
30 const char * const DataQuery::IN = "^IN";
31 const char * const DataQuery::NOT_IN = "^NOT_IN";
32 const char * const DataQuery::LIKE = "^LIKE";
33 const char * const DataQuery::NOT_LIKE = "^NOT_LIKE";
34 const char * const DataQuery::AND = "^AND";
35 const char * const DataQuery::OR = "^OR";
36 const char * const DataQuery::ORDER_BY_ASC = "^ASC";
37 const char * const DataQuery::ORDER_BY_DESC = "^DESC";
38 const char * const DataQuery::ORDER_BY_WRITE_TIME = "^OrderByWriteTime";
39 const char * const DataQuery::IS_ASC = "^IS_ASC";
40 const char * const DataQuery::IS_DESC = "^IS_DESC";
41 const char * const DataQuery::LIMIT = "^LIMIT";
42 const char * const DataQuery::SPACE = " ";
43 const char * const DataQuery::SPECIAL = "^";
44 const char * const DataQuery::SPECIAL_ESCAPE = "(^)";
45 const char * const DataQuery::SPACE_ESCAPE = "^^";
46 const char * const DataQuery::EMPTY_STRING = "^EMPTY_STRING";
47 const char * const DataQuery::START_IN = "^START";
48 const char * const DataQuery::END_IN = "^END";
49 const char * const DataQuery::BEGIN_GROUP = "^BEGIN_GROUP";
50 const char * const DataQuery::END_GROUP = "^END_GROUP";
51 const char * const DataQuery::KEY_PREFIX = "^KEY_PREFIX";
52 const char * const DataQuery::DEVICE_ID = "^DEVICE_ID";
53 const char * const DataQuery::IS_NOT_NULL = "^IS_NOT_NULL";
54 const char * const DataQuery::TYPE_STRING = "STRING";
55 const char * const DataQuery::TYPE_INTEGER = "INTEGER";
56 const char * const DataQuery::TYPE_LONG = "LONG";
57 const char * const DataQuery::TYPE_DOUBLE = "DOUBLE";
58 const char * const DataQuery::TYPE_BOOLEAN = "BOOL";
59 const char * const DataQuery::VALUE_TRUE = "true";
60 const char * const DataQuery::VALUE_FALSE = "false";
61 const char * const DataQuery::SUGGEST_INDEX = "^SUGGEST_INDEX";
62 const char * const DataQuery::IN_KEYS = "^IN_KEYS";
63 constexpr int MAX_QUERY_LENGTH = 5 * 1024; // Max query string length 5k
64 
DataQuery()65 DataQuery::DataQuery()
66 {
67     query_ = std::make_shared<DistributedDB::Query>();
68 }
69 
Reset()70 DataQuery& DataQuery::Reset()
71 {
72     str_ = "";
73     hasKeys_ = false;
74     hasPrefix_ = false;
75     deviceId_ = "";
76     prefix_ = "";
77     query_ = std::make_shared<DistributedDB::Query>();
78     return *this;
79 }
80 
EqualTo(const std::string & field,const int value)81 DataQuery& DataQuery::EqualTo(const std::string &field, const int value)
82 {
83     std::string myField = field;
84     if (ValidateField(myField)) {
85         AppendCommon(EQUAL_TO, TYPE_INTEGER, myField, value);
86         query_->EqualTo(field, value);
87     }
88     return *this;
89 }
90 
EqualTo(const std::string & field,const int64_t value)91 DataQuery& DataQuery::EqualTo(const std::string &field, const int64_t value)
92 {
93     std::string myField = field;
94     if (ValidateField(myField)) {
95         AppendCommon(EQUAL_TO, TYPE_LONG, myField, value);
96         query_->EqualTo(field, value);
97     }
98     return *this;
99 }
100 
EqualTo(const std::string & field,const double value)101 DataQuery& DataQuery::EqualTo(const std::string &field, const double value)
102 {
103     std::string myField = field;
104     if (ValidateField(myField)) {
105         AppendCommon(EQUAL_TO, TYPE_DOUBLE, myField, value);
106         query_->EqualTo(field, value);
107     }
108     return *this;
109 }
110 
EqualTo(const std::string & field,const std::string & value)111 DataQuery& DataQuery::EqualTo(const std::string &field, const std::string &value)
112 {
113     std::string myField = field;
114     std::string myValue = value;
115     if (ValidateField(myField)) {
116         AppendCommonString(EQUAL_TO, TYPE_STRING, myField, myValue);
117         query_->EqualTo(field, value);
118     }
119     return *this;
120 }
121 
EqualTo(const std::string & field,const bool value)122 DataQuery& DataQuery::EqualTo(const std::string &field, const bool value)
123 {
124     std::string myField = field;
125     if (ValidateField(myField)) {
126         AppendCommonBoolean(EQUAL_TO, TYPE_BOOLEAN, myField, value);
127         query_->EqualTo(field, value);
128     }
129     return *this;
130 }
131 
NotEqualTo(const std::string & field,const int value)132 DataQuery& DataQuery::NotEqualTo(const std::string &field, const int value)
133 {
134     std::string myField = field;
135     if (ValidateField(myField)) {
136         AppendCommon(NOT_EQUAL_TO, TYPE_INTEGER, myField, value);
137         query_->NotEqualTo(field, value);
138     }
139     return *this;
140 }
141 
NotEqualTo(const std::string & field,const int64_t value)142 DataQuery& DataQuery::NotEqualTo(const std::string &field, const int64_t value)
143 {
144     std::string myField = field;
145     if (ValidateField(myField)) {
146         AppendCommon(NOT_EQUAL_TO, TYPE_LONG, myField, value);
147         query_->NotEqualTo(field, value);
148     }
149     return *this;
150 }
151 
NotEqualTo(const std::string & field,const double value)152 DataQuery& DataQuery::NotEqualTo(const std::string &field, const double value)
153 {
154     std::string myField = field;
155     if (ValidateField(myField)) {
156         AppendCommon(NOT_EQUAL_TO, TYPE_DOUBLE, myField, value);
157         query_->NotEqualTo(field, value);
158     }
159     return *this;
160 }
161 
NotEqualTo(const std::string & field,const std::string & value)162 DataQuery& DataQuery::NotEqualTo(const std::string &field, const std::string &value)
163 {
164     std::string myField = field;
165     std::string myValue = value;
166     if (ValidateField(myField)) {
167         AppendCommonString(NOT_EQUAL_TO, TYPE_STRING, myField, myValue);
168         query_->NotEqualTo(field, value);
169     }
170     return *this;
171 }
172 
NotEqualTo(const std::string & field,const bool value)173 DataQuery& DataQuery::NotEqualTo(const std::string &field, const bool value)
174 {
175     std::string myField = field;
176     if (ValidateField(myField)) {
177         AppendCommonBoolean(NOT_EQUAL_TO, TYPE_BOOLEAN, myField, value);
178         query_->NotEqualTo(field, value);
179     }
180     return *this;
181 }
182 
GreaterThan(const std::string & field,const int value)183 DataQuery& DataQuery::GreaterThan(const std::string &field, const int value)
184 {
185     std::string myField = field;
186     if (ValidateField(myField)) {
187         AppendCommon(GREATER_THAN, TYPE_INTEGER, myField, value);
188         query_->GreaterThan(field, value);
189     }
190     return *this;
191 }
192 
GreaterThan(const std::string & field,const int64_t value)193 DataQuery& DataQuery::GreaterThan(const std::string &field, const int64_t value)
194 {
195     std::string myField = field;
196     if (ValidateField(myField)) {
197         AppendCommon(GREATER_THAN, TYPE_LONG, myField, value);
198         query_->GreaterThan(field, value);
199     }
200     return *this;
201 }
202 
GreaterThan(const std::string & field,const double value)203 DataQuery& DataQuery::GreaterThan(const std::string &field, const double value)
204 {
205     std::string myField = field;
206     if (ValidateField(myField)) {
207         AppendCommon(GREATER_THAN, TYPE_DOUBLE, myField, value);
208         query_->GreaterThan(field, value);
209     }
210     return *this;
211 }
212 
GreaterThan(const std::string & field,const std::string & value)213 DataQuery& DataQuery::GreaterThan(const std::string &field, const std::string &value)
214 {
215     std::string myField = field;
216     std::string myValue = value;
217     if (ValidateField(myField)) {
218         AppendCommonString(GREATER_THAN, TYPE_STRING, myField, myValue);
219         query_->GreaterThan(field, value);
220     }
221     return *this;
222 }
223 
LessThan(const std::string & field,const int value)224 DataQuery& DataQuery::LessThan(const std::string &field, const int value)
225 {
226     std::string myField = field;
227     if (ValidateField(myField)) {
228         AppendCommon(LESS_THAN, TYPE_INTEGER, myField, value);
229         query_->LessThan(field, value);
230     }
231     return *this;
232 }
233 
LessThan(const std::string & field,const int64_t value)234 DataQuery& DataQuery::LessThan(const std::string &field, const int64_t value)
235 {
236     std::string myField = field;
237     if (ValidateField(myField)) {
238         AppendCommon(LESS_THAN, TYPE_LONG, myField, value);
239         query_->LessThan(field, value);
240     }
241     return *this;
242 }
243 
LessThan(const std::string & field,const double value)244 DataQuery& DataQuery::LessThan(const std::string &field, const double value)
245 {
246     std::string myField = field;
247     if (ValidateField(myField)) {
248         AppendCommon(LESS_THAN, TYPE_DOUBLE, myField, value);
249         query_->LessThan(field, value);
250     }
251     return *this;
252 }
253 
LessThan(const std::string & field,const std::string & value)254 DataQuery& DataQuery::LessThan(const std::string &field, const std::string &value)
255 {
256     std::string myField = field;
257     std::string myValue = value;
258     if (ValidateField(myField)) {
259         AppendCommonString(LESS_THAN, TYPE_STRING, myField, myValue);
260         query_->LessThan(field, value);
261     }
262     return *this;
263 }
264 
GreaterThanOrEqualTo(const std::string & field,const int value)265 DataQuery& DataQuery::GreaterThanOrEqualTo(const std::string &field, const int value)
266 {
267     std::string myField = field;
268     if (ValidateField(myField)) {
269         AppendCommon(GREATER_THAN_OR_EQUAL_TO, TYPE_INTEGER, myField, value);
270         query_->GreaterThanOrEqualTo(field, value);
271     }
272     return *this;
273 }
274 
GreaterThanOrEqualTo(const std::string & field,const int64_t value)275 DataQuery& DataQuery::GreaterThanOrEqualTo(const std::string &field, const int64_t value)
276 {
277     std::string myField = field;
278     if (ValidateField(myField)) {
279         AppendCommon(GREATER_THAN_OR_EQUAL_TO, TYPE_LONG, myField, value);
280         query_->GreaterThanOrEqualTo(field, value);
281     }
282     return *this;
283 }
284 
GreaterThanOrEqualTo(const std::string & field,const double value)285 DataQuery& DataQuery::GreaterThanOrEqualTo(const std::string &field, const double value)
286 {
287     std::string myField = field;
288     if (ValidateField(myField)) {
289         AppendCommon(GREATER_THAN_OR_EQUAL_TO, TYPE_DOUBLE, myField, value);
290         query_->GreaterThanOrEqualTo(field, value);
291     }
292     return *this;
293 }
294 
GreaterThanOrEqualTo(const std::string & field,const std::string & value)295 DataQuery& DataQuery::GreaterThanOrEqualTo(const std::string &field, const std::string &value)
296 {
297     std::string myField = field;
298     std::string myValue = value;
299     if (ValidateField(myField)) {
300         AppendCommonString(GREATER_THAN_OR_EQUAL_TO, TYPE_STRING, myField, myValue);
301         query_->GreaterThanOrEqualTo(field, value);
302     }
303     return *this;
304 }
305 
LessThanOrEqualTo(const std::string & field,const int value)306 DataQuery& DataQuery::LessThanOrEqualTo(const std::string &field, const int value)
307 {
308     std::string myField = field;
309     if (ValidateField(myField)) {
310         AppendCommon(LESS_THAN_OR_EQUAL_TO, TYPE_INTEGER, myField, value);
311         query_->LessThanOrEqualTo(field, value);
312     }
313     return *this;
314 }
315 
LessThanOrEqualTo(const std::string & field,const int64_t value)316 DataQuery& DataQuery::LessThanOrEqualTo(const std::string &field, const int64_t value)
317 {
318     std::string myField = field;
319     if (ValidateField(myField)) {
320         AppendCommon(LESS_THAN_OR_EQUAL_TO, TYPE_LONG, myField, value);
321         query_->LessThanOrEqualTo(field, value);
322     }
323     return *this;
324 }
325 
LessThanOrEqualTo(const std::string & field,const double value)326 DataQuery& DataQuery::LessThanOrEqualTo(const std::string &field, const double value)
327 {
328     std::string myField = field;
329     if (ValidateField(myField)) {
330         AppendCommon(LESS_THAN_OR_EQUAL_TO, TYPE_DOUBLE, myField, value);
331         query_->LessThanOrEqualTo(field, value);
332     }
333     return *this;
334 }
335 
LessThanOrEqualTo(const std::string & field,const std::string & value)336 DataQuery& DataQuery::LessThanOrEqualTo(const std::string &field, const std::string &value)
337 {
338     std::string myField = field;
339     std::string myValue = value;
340     if (ValidateField(myField)) {
341         AppendCommonString(LESS_THAN_OR_EQUAL_TO, TYPE_STRING, myField, myValue);
342         query_->LessThanOrEqualTo(field, value);
343     }
344     return *this;
345 }
346 
Between(const std::string & valueLow,const std::string & valueHigh)347 DataQuery& DataQuery::Between(const std::string &valueLow, const std::string &valueHigh)
348 {
349     std::vector<uint8_t> keyBegin;
350     keyBegin.assign(valueLow.begin(), valueLow.end());
351     std::vector<uint8_t> keyEnd;
352     keyEnd.assign(valueHigh.begin(), valueHigh.end());
353     query_->Range(keyBegin, keyEnd);
354     return *this;
355 }
356 
IsNull(const std::string & field)357 DataQuery& DataQuery::IsNull(const std::string &field)
358 {
359     std::string myField = field;
360     if (ValidateField(myField)) {
361         str_.append(SPACE);
362         str_.append(IS_NULL);
363         str_.append(SPACE);
364         EscapeSpace(myField);
365         str_.append(myField);
366         query_->IsNull(field);
367     }
368     return *this;
369 }
370 
IsNotNull(const std::string & field)371 DataQuery& DataQuery::IsNotNull(const std::string &field)
372 {
373     std::string myField = field;
374     if (ValidateField(myField)) {
375         str_.append(SPACE);
376         str_.append(IS_NOT_NULL);
377         str_.append(SPACE);
378         EscapeSpace(myField);
379         str_.append(myField);
380         query_->IsNotNull(field);
381     }
382     return *this;
383 }
384 
In(const std::string & field,const std::vector<int> & valueList)385 DataQuery& DataQuery::In(const std::string &field, const std::vector<int> &valueList)
386 {
387     ZLOGD("DataQuery::In int");
388     std::string myField = field;
389     if (ValidateField(myField)) {
390         AppendCommonList(IN, TYPE_INTEGER, myField, valueList);
391         query_->In(field, valueList);
392     }
393     return *this;
394 }
395 
In(const std::string & field,const std::vector<int64_t> & valueList)396 DataQuery& DataQuery::In(const std::string &field, const std::vector<int64_t> &valueList)
397 {
398     ZLOGD("DataQuery::In int64_t");
399     std::string myField = field;
400     if (ValidateField(myField)) {
401         AppendCommonList(IN, TYPE_LONG, myField, valueList);
402         query_->In(field, valueList);
403     }
404     return *this;
405 }
406 
In(const std::string & field,const std::vector<double> & valueList)407 DataQuery& DataQuery::In(const std::string &field, const std::vector<double> &valueList)
408 {
409     ZLOGD("DataQuery::In double");
410     std::string myField = field;
411     if (ValidateField(myField)) {
412         AppendCommonList(IN, TYPE_DOUBLE, myField, valueList);
413         query_->In(field, valueList);
414     }
415     return *this;
416 }
417 
In(const std::string & field,const std::vector<std::string> & valueList)418 DataQuery& DataQuery::In(const std::string &field, const std::vector<std::string> &valueList)
419 {
420     ZLOGD("DataQuery::In string");
421     std::string myField = field;
422     std::vector<std::string> myValueList(valueList);
423     if (ValidateField(myField)) {
424         AppendCommonListString(IN, TYPE_STRING, myField, myValueList);
425         query_->In(field, valueList);
426     }
427     return *this;
428 }
429 
NotIn(const std::string & field,const std::vector<int> & valueList)430 DataQuery& DataQuery::NotIn(const std::string &field, const std::vector<int> &valueList)
431 {
432     ZLOGD("DataQuery::NotIn int");
433     std::string myField = field;
434     if (ValidateField(myField)) {
435         AppendCommonList(NOT_IN, TYPE_INTEGER, myField, valueList);
436         query_->NotIn(field, valueList);
437     }
438     return *this;
439 }
440 
NotIn(const std::string & field,const std::vector<int64_t> & valueList)441 DataQuery& DataQuery::NotIn(const std::string &field, const std::vector<int64_t> &valueList)
442 {
443     ZLOGD("DataQuery::NotIn int64_t");
444     std::string myField = field;
445     if (ValidateField(myField)) {
446         AppendCommonList(NOT_IN, TYPE_LONG, myField, valueList);
447         query_->NotIn(field, valueList);
448     }
449     return *this;
450 }
451 
NotIn(const std::string & field,const std::vector<double> & valueList)452 DataQuery& DataQuery::NotIn(const std::string &field, const std::vector<double> &valueList)
453 {
454     ZLOGD("DataQuery::NotIn double");
455     std::string myField = field;
456     if (ValidateField(myField)) {
457         AppendCommonList(NOT_IN, TYPE_DOUBLE, myField, valueList);
458         query_->NotIn(field, valueList);
459     }
460     return *this;
461 }
462 
NotIn(const std::string & field,const std::vector<std::string> & valueList)463 DataQuery& DataQuery::NotIn(const std::string &field, const std::vector<std::string> &valueList)
464 {
465     ZLOGD("DataQuery::NotIn string");
466     std::string myField = field;
467     std::vector<std::string> myValueList(valueList);
468     if (ValidateField(myField)) {
469         AppendCommonListString(NOT_IN, TYPE_STRING, myField, myValueList);
470         query_->NotIn(field, valueList);
471     }
472     return *this;
473 }
474 
Like(const std::string & field,const std::string & value)475 DataQuery& DataQuery::Like(const std::string &field, const std::string &value)
476 {
477     std::string myField = field;
478     std::string myValue = value;
479     if (ValidateField(myField)) {
480         AppendCommonString(LIKE, myField, myValue);
481         query_->Like(field, value);
482     }
483     return *this;
484 }
485 
Unlike(const std::string & field,const std::string & value)486 DataQuery& DataQuery::Unlike(const std::string &field, const std::string &value)
487 {
488     std::string myField = field;
489     std::string myValue = value;
490     if (ValidateField(myField)) {
491         AppendCommonString(NOT_LIKE, myField, myValue);
492         query_->NotLike(field, value);
493     }
494     return *this;
495 }
496 
And()497 DataQuery& DataQuery::And()
498 {
499     str_.append(SPACE);
500     str_.append(AND);
501     query_->And();
502     return *this;
503 }
504 
Or()505 DataQuery& DataQuery::Or()
506 {
507     str_.append(SPACE);
508     str_.append(OR);
509     query_->Or();
510     return *this;
511 }
512 
OrderByAsc(const std::string & field)513 DataQuery& DataQuery::OrderByAsc(const std::string &field)
514 {
515     std::string myField = field;
516     if (ValidateField(myField)) {
517         str_.append(SPACE);
518         str_.append(ORDER_BY_ASC);
519         str_.append(SPACE);
520         EscapeSpace(myField);
521         str_.append(myField);
522         query_->OrderBy(field);
523     }
524     return *this;
525 }
526 
OrderByDesc(const std::string & field)527 DataQuery& DataQuery::OrderByDesc(const std::string &field)
528 {
529     std::string myField = field;
530     if (ValidateField(myField)) {
531         str_.append(SPACE);
532         str_.append(ORDER_BY_DESC);
533         str_.append(SPACE);
534         EscapeSpace(myField);
535         str_.append(myField);
536         query_->OrderBy(field, false);
537     }
538     return *this;
539 }
540 
OrderByWriteTime(const bool isAsc)541 DataQuery& DataQuery::OrderByWriteTime (const bool isAsc)
542 {
543     str_.append(SPACE);
544     str_.append(ORDER_BY_WRITE_TIME);
545     str_.append(SPACE);
546     str_.append(isAsc?IS_ASC:IS_DESC);
547     query_->OrderByWriteTime(isAsc);
548     return *this;
549 }
550 
Limit(const int number,const int offset)551 DataQuery& DataQuery::Limit(const int number, const int offset)
552 {
553     if (number < 0 || offset < 0) {
554         ZLOGE("Invalid number param");
555         return *this;
556     }
557     str_.append(SPACE);
558     str_.append(LIMIT);
559     str_.append(SPACE);
560     str_.append(BasicToString(number));
561     str_.append(SPACE);
562     str_.append(BasicToString(offset));
563     query_->Limit(number, offset);
564     return *this;
565 }
566 
BeginGroup()567 DataQuery& DataQuery::BeginGroup()
568 {
569     str_.append(SPACE);
570     str_.append(BEGIN_GROUP);
571     query_->BeginGroup();
572     return *this;
573 }
574 
EndGroup()575 DataQuery& DataQuery::EndGroup()
576 {
577     str_.append(SPACE);
578     str_.append(END_GROUP);
579     query_->EndGroup();
580     return *this;
581 }
582 
KeyPrefix(const std::string & prefix)583 DataQuery& DataQuery::KeyPrefix(const std::string &prefix)
584 {
585     std::string myPrefix = prefix;
586     if (ValidateField(myPrefix)) {
587         str_.append(SPACE);
588         str_.append(KEY_PREFIX);
589         str_.append(SPACE);
590         EscapeSpace(myPrefix);
591         str_.append(myPrefix);
592         prefix_ = prefix;
593         hasPrefix_ = true;
594     }
595     return *this;
596 }
597 
DeviceId(const std::string & deviceId)598 DataQuery& DataQuery::DeviceId(const std::string &deviceId)
599 {
600     std::string device = deviceId;
601     if (ValidateField(device)) {
602         std::string start;
603         start.append(SPACE);
604         start.append(DEVICE_ID);
605         start.append(SPACE);
606         EscapeSpace(device);
607         start.append(device);
608         str_ = start + str_; // start with diveceId
609         deviceId_ = deviceId;
610     }
611     return *this;
612 }
613 
SetSuggestIndex(const std::string & index)614 DataQuery& DataQuery::SetSuggestIndex(const std::string &index)
615 {
616     std::string suggestIndex = index;
617     if (ValidateField(suggestIndex)) {
618         str_.append(SPACE);
619         str_.append(SUGGEST_INDEX);
620         str_.append(SPACE);
621         EscapeSpace(suggestIndex);
622         str_.append(suggestIndex);
623         query_->SuggestIndex(index);
624     }
625     return *this;
626 }
627 
InKeys(const std::vector<std::string> & keys)628 DataQuery& DataQuery::InKeys(const std::vector<std::string> &keys)
629 {
630     if (keys.empty()) {
631         ZLOGE("Invalid number param");
632         return *this;
633     }
634     if (hasKeys_) {
635         ZLOGE("cannot set inkeys more than once");
636         return *this;
637     }
638     hasKeys_ = true;
639     str_.append(SPACE);
640     str_.append(IN_KEYS);
641     str_.append(SPACE);
642     str_.append(START_IN);
643     str_.append(SPACE);
644     for (std::string key : keys) {
645         if (ValidateField(key)) {
646             EscapeSpace(key);
647             str_.append(key);
648             str_.append(SPACE);
649         }
650     }
651     str_.append(END_IN);
652     keys_ = keys;
653     return *this;
654 }
655 
ToString() const656 std::string DataQuery::ToString() const
657 {
658     if (str_.length() > MAX_QUERY_LENGTH) {
659         ZLOGE("Query is too long");
660         return std::string();
661     }
662     std::string str(str_.begin(), str_.end());
663     return str;
664 }
665 
666 template<typename T>
AppendCommon(const std::string & keyword,const std::string & fieldType,std::string & field,const T & value)667 void DataQuery::AppendCommon(const std::string &keyword, const std::string &fieldType,
668                              std::string &field, const T &value)
669 {
670     str_.append(SPACE);
671     str_.append(keyword);
672     str_.append(SPACE);
673     str_.append(fieldType);
674     str_.append(SPACE);
675     EscapeSpace(field);
676     str_.append(field);
677     str_.append(SPACE);
678     str_.append(BasicToString(value));
679 }
680 
AppendCommonString(const std::string & keyword,const std::string & fieldType,std::string & field,std::string & value)681 void DataQuery::AppendCommonString(const std::string &keyword, const std::string &fieldType,
682                                    std::string &field, std::string &value)
683 {
684     str_.append(SPACE);
685     str_.append(keyword);
686     str_.append(SPACE);
687     str_.append(fieldType);
688     str_.append(SPACE);
689     EscapeSpace(field);
690     str_.append(field);
691     str_.append(SPACE);
692     EscapeSpace(value);
693     str_.append(value);
694 }
695 
AppendCommonBoolean(const std::string & keyword,const std::string & fieldType,std::string & field,const bool & value)696 void DataQuery::AppendCommonBoolean(const std::string &keyword, const std::string &fieldType,
697                                     std::string &field, const bool &value)
698 {
699     str_.append(SPACE);
700     str_.append(keyword);
701     str_.append(SPACE);
702     str_.append(fieldType);
703     str_.append(SPACE);
704     EscapeSpace(field);
705     str_.append(field);
706     str_.append(SPACE);
707     if (value) {
708         str_.append(VALUE_TRUE);
709     } else {
710         str_.append(VALUE_FALSE);
711     }
712 }
713 
AppendCommonString(const std::string & keyword,std::string & field,std::string & value)714 void DataQuery::AppendCommonString(const std::string &keyword, std::string &field, std::string &value)
715 {
716     str_.append(SPACE);
717     str_.append(keyword);
718     str_.append(SPACE);
719     EscapeSpace(field);
720     str_.append(field);
721     str_.append(SPACE);
722     EscapeSpace(value);
723     str_.append(value);
724 }
725 
726 template<typename T>
AppendCommonList(const std::string & keyword,const std::string & fieldType,std::string & field,const std::vector<T> & valueList)727 void DataQuery::AppendCommonList(const std::string &keyword, const std::string &fieldType,
728                                  std::string &field, const std::vector<T> &valueList)
729 {
730     str_.append(SPACE);
731     str_.append(keyword);
732     str_.append(SPACE);
733     str_.append(fieldType);
734     str_.append(SPACE);
735     EscapeSpace(field);
736     str_.append(field);
737     str_.append(SPACE);
738     str_.append(START_IN);
739     str_.append(SPACE);
740     for (T object : valueList) {
741         str_.append(BasicToString(object));
742         str_.append(SPACE);
743     }
744     str_.append(END_IN);
745 }
746 
AppendCommonListString(const std::string & keyword,const std::string & fieldType,std::string & field,std::vector<std::string> & valueList)747 void DataQuery::AppendCommonListString(const std::string &keyword, const std::string &fieldType,
748                                        std::string &field, std::vector<std::string> &valueList)
749 {
750     str_.append(SPACE);
751     str_.append(keyword);
752     str_.append(SPACE);
753     str_.append(fieldType);
754     str_.append(SPACE);
755     EscapeSpace(field);
756     str_.append(field);
757     str_.append(SPACE);
758     str_.append(START_IN);
759     str_.append(SPACE);
760     for (std::string str : valueList) {
761         EscapeSpace(str);
762         str_.append(str);
763         str_.append(SPACE);
764     }
765     str_.append(END_IN);
766 }
767 
EscapeSpace(std::string & input)768 void DataQuery::EscapeSpace(std::string &input)
769 {
770     if (input.length() == 0) {
771         input = EMPTY_STRING;
772     }
773     size_t index = 0; // search from the beginning of the string
774     while (true) {
775         index = input.find(DataQuery::SPECIAL, index);
776         if (index == std::string::npos) {
777             break;
778         }
779         input.replace(index, 1, DataQuery::SPECIAL_ESCAPE); // 1 char to be replaced
780         index += 3; // replaced with 3 chars, keep searching the remaining string
781     }
782     index = 0; // search from the beginning of the string
783     while (true) {
784         index = input.find(DataQuery::SPACE, index);
785         if (index == std::string::npos) {
786             break;
787         }
788         input.replace(index, 1, DataQuery::SPACE_ESCAPE); // 1 char to be replaced
789         index += 2; // replaced with 2 chars, keep searching the remaining string
790     }
791 }
792 
ValidateField(const std::string & field)793 bool DataQuery::ValidateField(const std::string &field)
794 {
795     if (field.empty() || field.find(DataQuery::SPECIAL) != std::string::npos) {
796         ZLOGE("invalid string argument");
797         return false;
798     }
799     return true;
800 }
801 
802 template<typename T>
BasicToString(const T & value)803 std::string DataQuery::BasicToString(const T &value)
804 {
805     std::ostringstream oss;
806     oss << value;
807     return oss.str();
808 }
809 }  // namespace DistributedKv
810 }  // namespace OHOS
811