• 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 
16 #include "abs_predicates.h"
17 
18 #include <algorithm>
19 #include <initializer_list>
20 
21 #include "logger.h"
22 #include "rdb_trace.h"
23 #include "string_utils.h"
24 #include "sqlite_sql_builder.h"
25 
26 namespace OHOS {
27 namespace NativeRdb {
AbsPredicates()28 AbsPredicates::AbsPredicates()
29 {
30     Initial();
31 }
32 
~AbsPredicates()33 AbsPredicates::~AbsPredicates()
34 {
35 }
36 
Clear()37 void AbsPredicates::Clear()
38 {
39     Initial();
40 }
41 
IsNeedAnd() const42 bool AbsPredicates::IsNeedAnd() const
43 {
44     return isNeedAnd;
45 }
46 
47 /**
48  * Restricts the value of the field to be greater than the specified value.
49  */
EqualTo(std::string field,std::string value)50 AbsPredicates *AbsPredicates::EqualTo(std::string field, std::string value)
51 {
52     bool chekParaFlag = CheckParameter("equalTo", field, { value });
53     if (!chekParaFlag) {
54         LOG_WARN("AbsPredicates: EqualTo() fails because Invalid parameter.");
55         return this;
56     }
57     if (isNeedAnd) {
58         whereClause += "AND ";
59     } else {
60         isNeedAnd = true;
61     }
62     int errorCode = 0;
63     std::string normalizedField = SqliteSqlBuilder::PredicatesNormalize(field, errorCode);
64     whereClause += normalizedField + " = ? ";
65     whereArgs.push_back(value);
66     return this;
67 }
68 
69 /**
70  * Restricts the value of the field to be unequal to the specified value.
71  */
NotEqualTo(std::string field,std::string value)72 AbsPredicates *AbsPredicates::NotEqualTo(std::string field, std::string value)
73 {
74     bool chekParaFlag = CheckParameter("notEqualTo", field, { value });
75     if (!chekParaFlag) {
76         LOG_WARN("AbsPredicates: NotEqualTo() fails because Invalid parameter.");
77         return this;
78     }
79     CheckIsNeedAnd();
80     int errorCode = 0;
81     std::string normalizedField = SqliteSqlBuilder::Normalize(field, errorCode);
82     whereClause = whereClause + normalizedField + " <> ? ";
83     whereArgs.push_back(value);
84     return this;
85 }
86 
BeginWrap()87 AbsPredicates *AbsPredicates::BeginWrap()
88 {
89     if (isNeedAnd) {
90         whereClause += "AND ";
91         isNeedAnd = false;
92     }
93     whereClause += " ( ";
94     return this;
95 }
96 
EndWrap()97 AbsPredicates *AbsPredicates::EndWrap()
98 {
99     if (!isNeedAnd) {
100         LOG_WARN("AbsPredicates.endGroup(): you cannot use function or() before end parenthesis,\
101             start a AbsPredicates with endGroup(), or use endGroup() right after beginGroup().");
102         return this;
103     }
104     whereClause += " ) ";
105     return this;
106 }
107 
Or()108 AbsPredicates *AbsPredicates::Or()
109 {
110     if (!isNeedAnd) {
111         LOG_WARN("QueryImpl.or(): you are starting a sql request with predicate \"or\" or \
112             using function or() immediately after another or(). that is ridiculous.");
113         return this;
114     }
115     whereClause += " OR ";
116     isNeedAnd = false;
117     return this;
118 }
119 
And()120 AbsPredicates *AbsPredicates::And()
121 {
122     if (!isNeedAnd) {
123         LOG_WARN("QueryImpl.and(): you should not start a request with \"and\" or use or() before this function.");
124         return this;
125     }
126     return this;
127 }
128 
129 /**
130  * Restricts the value of the field to contain the specified string.
131  */
Contains(std::string field,std::string value)132 AbsPredicates *AbsPredicates::Contains(std::string field, std::string value)
133 {
134     bool chekParaFlag = CheckParameter("contains", field, { value });
135     if (!chekParaFlag) {
136         LOG_WARN("AbsPredicates: Contains() fails because Invalid parameter.");
137         return this;
138     }
139     CheckIsNeedAnd();
140     int errorCode = 0;
141     std::string normalizedField = SqliteSqlBuilder::Normalize(field, errorCode);
142     whereClause = whereClause + normalizedField + " LIKE ? ";
143     whereArgs.push_back("%" + value + "%");
144     return this;
145 }
146 
147 /**
148  * Restricts the field to start with the specified string.
149  */
BeginsWith(std::string field,std::string value)150 AbsPredicates *AbsPredicates::BeginsWith(std::string field, std::string value)
151 {
152     bool chekParaFlag = CheckParameter("beginsWith", field, { value });
153     if (!chekParaFlag) {
154         LOG_WARN("AbsPredicates: BeginsWith() fails because Invalid parameter.");
155         return this;
156     }
157     CheckIsNeedAnd();
158     int errorCode = 0;
159     std::string normalizedField = SqliteSqlBuilder::Normalize(field, errorCode);
160     whereClause = whereClause + normalizedField + " LIKE ? ";
161     whereArgs.push_back(value + "%");
162     return this;
163 }
164 
165 /**
166  * Restricts the field to end with the specified string.
167  */
EndsWith(std::string field,std::string value)168 AbsPredicates *AbsPredicates::EndsWith(std::string field, std::string value)
169 {
170     bool chekParaFlag = CheckParameter("endsWith", field, { value });
171     if (!chekParaFlag) {
172         LOG_WARN("AbsPredicates: EndsWith() fails because Invalid parameter.");
173         return this;
174     }
175     CheckIsNeedAnd();
176     int errorCode = 0;
177     std::string normalizedField = SqliteSqlBuilder::Normalize(field, errorCode);
178     whereClause = whereClause + normalizedField + " LIKE ? ";
179     whereArgs.push_back("%" + value);
180     return this;
181 }
182 
183 /**
184  * Restricts the value of the field to be null.
185  */
IsNull(std::string field)186 AbsPredicates *AbsPredicates::IsNull(std::string field)
187 {
188     bool chekParaFlag = CheckParameter("isNull", field, {});
189     if (!chekParaFlag) {
190         LOG_WARN("AbsPredicates: IsNull() fails because Invalid parameter.");
191         return this;
192     }
193     CheckIsNeedAnd();
194     int errorCode = 0;
195     std::string normalizedField = SqliteSqlBuilder::Normalize(field, errorCode);
196     whereClause = whereClause + normalizedField + " is null ";
197     return this;
198 }
199 
200 /**
201  * estricts the value of the field not to be null.
202  */
IsNotNull(std::string field)203 AbsPredicates *AbsPredicates::IsNotNull(std::string field)
204 {
205     bool chekParaFlag = CheckParameter("isNotNull", field, {});
206     if (!chekParaFlag) {
207         LOG_WARN("AbsPredicates: IsNotNull() fails because Invalid parameter.");
208         return this;
209     }
210     CheckIsNeedAnd();
211     int errorCode = 0;
212     std::string normalizedField = SqliteSqlBuilder::Normalize(field, errorCode);
213     whereClause = whereClause + normalizedField + " is not null ";
214     return this;
215 }
216 
217 /**
218  * Restricts the value of the field to have a pattern like field.
219  */
Like(std::string field,std::string value)220 AbsPredicates *AbsPredicates::Like(std::string field, std::string value)
221 {
222     bool chekParaFlag = CheckParameter("like", field, { value });
223     if (!chekParaFlag) {
224         LOG_WARN("AbsPredicates: Like() fails because Invalid parameter.");
225         return this;
226     }
227     CheckIsNeedAnd();
228     int errorCode = 0;
229     std::string normalizedField = SqliteSqlBuilder::Normalize(field, errorCode);
230     whereClause = whereClause + normalizedField + " LIKE ? ";
231     whereArgs.push_back(value);
232     return this;
233 }
234 
235 /**
236  * Configures to match the specified field whose data type is String and the value contains a wildcard.
237  */
Glob(std::string field,std::string value)238 AbsPredicates *AbsPredicates::Glob(std::string field, std::string value)
239 {
240     bool chekParaFlag = CheckParameter("glob", field, { value });
241     if (!chekParaFlag) {
242         LOG_WARN("AbsPredicates: Glob() fails because Invalid parameter.");
243         return this;
244     }
245     CheckIsNeedAnd();
246     int errorCode = 0;
247     std::string normalizedField = SqliteSqlBuilder::Normalize(field, errorCode);
248     whereClause = whereClause + normalizedField + " GLOB ? ";
249     whereArgs.push_back(value);
250     return this;
251 }
252 
253 /**
254  * Restricts the value of the field to be unequal to the specified value.
255  */
Between(std::string field,std::string low,std::string high)256 AbsPredicates *AbsPredicates::Between(std::string field, std::string low, std::string high)
257 {
258     bool chekParaFlag = CheckParameter("between", field, { low, high });
259     if (!chekParaFlag) {
260         LOG_WARN("AbsPredicates: Between() fails because Invalid parameter.");
261         return this;
262     }
263     CheckIsNeedAnd();
264     int errorCode = 0;
265     std::string normalizedField = SqliteSqlBuilder::Normalize(field, errorCode);
266     whereClause = whereClause + normalizedField + " BETWEEN ? AND ? ";
267     whereArgs.push_back(low);
268     whereArgs.push_back(high);
269     return this;
270 }
271 
272 /**
273  * Configures to match the specified field whose data type is String and value is out of a given range.
274  */
NotBetween(std::string field,std::string low,std::string high)275 AbsPredicates *AbsPredicates::NotBetween(std::string field, std::string low, std::string high)
276 {
277     bool chekParaFlag = CheckParameter("notBetween", field, { low, high });
278     if (!chekParaFlag) {
279         LOG_WARN("AbsPredicates: NotBetween() fails because Invalid parameter.");
280         return this;
281     }
282     CheckIsNeedAnd();
283     int errorCode = 0;
284     std::string normalizedField = SqliteSqlBuilder::Normalize(field, errorCode);
285     whereClause = whereClause + normalizedField + " NOT BETWEEN ? AND ? ";
286     whereArgs.push_back(low);
287     whereArgs.push_back(high);
288     return this;
289 }
290 
291 /**
292  * Restricts the value of the field to be greater than the specified value.
293  */
GreaterThan(std::string field,std::string value)294 AbsPredicates *AbsPredicates::GreaterThan(std::string field, std::string value)
295 {
296     bool chekParaFlag = CheckParameter("greaterThan", field, { value });
297     if (!chekParaFlag) {
298         LOG_WARN("AbsPredicates: GreaterThan() fails because Invalid parameter.");
299         return this;
300     }
301     CheckIsNeedAnd();
302     int errorCode = 0;
303     std::string normalizedField = SqliteSqlBuilder::Normalize(field, errorCode);
304     whereClause = whereClause + normalizedField + " > ? ";
305     whereArgs.push_back(value);
306     return this;
307 }
308 
309 /**
310  * Restricts the value of the field to be smaller than the specified value.
311  */
LessThan(std::string field,std::string value)312 AbsPredicates *AbsPredicates::LessThan(std::string field, std::string value)
313 {
314     bool chekParaFlag = CheckParameter("lessThan", field, { value });
315     if (!chekParaFlag) {
316         LOG_WARN("AbsPredicates: LessThan() fails because Invalid parameter.");
317         return this;
318     }
319     CheckIsNeedAnd();
320     int errorCode = 0;
321     std::string normalizedField = SqliteSqlBuilder::Normalize(field, errorCode);
322     whereClause = whereClause + normalizedField + " < ? ";
323     whereArgs.push_back(value);
324     return this;
325 }
326 
327 /**
328  * Restricts the value of the field to be greater than or equal to the specified value.
329  */
GreaterThanOrEqualTo(std::string field,std::string value)330 AbsPredicates *AbsPredicates::GreaterThanOrEqualTo(std::string field, std::string value)
331 {
332     bool chekParaFlag = CheckParameter("greaterThanOrEqualTo", field, { value });
333     if (!chekParaFlag) {
334         LOG_WARN("AbsPredicates: GreaterThanOrEqualTo() fails because Invalid parameter.");
335         return this;
336     }
337     CheckIsNeedAnd();
338     int errorCode = 0;
339     std::string normalizedField = SqliteSqlBuilder::Normalize(field, errorCode);
340     whereClause = whereClause + normalizedField + " >= ? ";
341     whereArgs.push_back(value);
342     return this;
343 }
344 
345 /**
346  * Restricts the value of the field to be smaller than or equal to the specified value.
347  */
LessThanOrEqualTo(std::string field,std::string value)348 AbsPredicates *AbsPredicates::LessThanOrEqualTo(std::string field, std::string value)
349 {
350     bool chekParaFlag = CheckParameter("greaterThanOrEqualTo", field, { value });
351     if (!chekParaFlag) {
352         LOG_WARN("AbsPredicates: LessThanOrEqualTo() fails because Invalid parameter.");
353         return this;
354     }
355     CheckIsNeedAnd();
356     int errorCode = 0;
357     std::string normalizedField = SqliteSqlBuilder::Normalize(field, errorCode);
358     whereClause = whereClause + normalizedField + " <= ? ";
359     whereArgs.push_back(value);
360     return this;
361 }
362 
363 /**
364  * Restricts the ascending order of the return list. When there are several orders,
365  * the one close to the head has the highest priority.
366  */
OrderByAsc(std::string field)367 AbsPredicates *AbsPredicates::OrderByAsc(std::string field)
368 {
369     bool chekParaFlag = CheckParameter("orderByAsc", field, {});
370     if (!chekParaFlag) {
371         LOG_WARN("AbsPredicates: OrderByAsc() fails because Invalid parameter.");
372         return this;
373     }
374     if (isSorted) {
375         order += ',';
376     }
377     int errorCode = 0;
378     std::string normalizedField = SqliteSqlBuilder::Normalize(field, errorCode);
379     order = order + normalizedField + " ASC ";
380     isSorted = true;
381     return this;
382 }
383 
384 /**
385  * Restricts the descending order of the return list. When there are several orders,
386  * the one close to the head has the highest priority.
387  */
OrderByDesc(std::string field)388 AbsPredicates *AbsPredicates::OrderByDesc(std::string field)
389 {
390     bool chekParaFlag = CheckParameter("orderByDesc", field, {});
391     if (!chekParaFlag) {
392         LOG_WARN("AbsPredicates: OrderByDesc() fails because Invalid parameter.");
393         return this;
394     }
395     if (isSorted) {
396         order += ',';
397     }
398     int errorCode = 0;
399     std::string normalizedField = SqliteSqlBuilder::PredicatesNormalize(field, errorCode);
400     order += normalizedField + " DESC ";
401     isSorted = true;
402     return this;
403 }
404 
Distinct()405 AbsPredicates *AbsPredicates::Distinct()
406 {
407     distinct = true;
408     return this;
409 }
410 
411 /**
412  * Restricts the max number of return records.
413  */
Limit(int value)414 AbsPredicates *AbsPredicates::Limit(int value)
415 {
416     if (limit != -1) {
417         LOG_WARN("AbsPredicates limit(): limit cannot be set twice.");
418         return this;
419     }
420     if (value < 1) {
421         LOG_WARN("AbsPredicates limit(): limit cannot be less than or equal to zero.");
422         return this;
423     }
424     limit = value;
425     return this;
426 }
427 
428 /**
429  * Configures to specify the start position of the returned result.
430  */
Offset(int rowOffset)431 AbsPredicates *AbsPredicates::Offset(int rowOffset)
432 {
433     if (offset != -1) {
434         LOG_WARN("AbsPredicates offset(): offset cannot be set twice.");
435         return this;
436     }
437     if (rowOffset < 1) {
438         LOG_WARN("AbsPredicates offset(): the value of offset can't be less than or equal to zero.");
439         return this;
440     }
441     offset = rowOffset;
442     return this;
443 }
444 
445 /**
446  * Configures {@code AbsPredicates} to group query results by specified columns.
447  */
GroupBy(std::vector<std::string> fields)448 AbsPredicates *AbsPredicates::GroupBy(std::vector<std::string> fields)
449 {
450     if (fields.empty()) {
451         LOG_WARN("AbsPredicates: groupBy() fails because fields can't be null.");
452         return this;
453     }
454     for (auto field : fields) {
455         bool chekParaFlag = CheckParameter("GroupBy", field, {});
456         if (!chekParaFlag) {
457             LOG_WARN("AbsPredicates: GroupBy() fails because Invalid parameter.");
458             return this;
459         }
460         int errorCode = 0;
461         std::string normalizedField = SqliteSqlBuilder::Normalize(field, errorCode);
462         group = group + normalizedField + ",";
463     }
464     size_t pos = group.find_last_of(",");
465     if (pos != group.npos) {
466         group.erase(pos, 1);
467     }
468     return this;
469 }
470 
471 /**
472  * Configures {@code AbsPredicates} to specify the index column.
473  */
IndexedBy(std::string indexName)474 AbsPredicates *AbsPredicates::IndexedBy(std::string indexName)
475 {
476     bool chekParaFlag = CheckParameter("indexedBy", indexName, {});
477     if (!chekParaFlag) {
478         LOG_WARN("AbsPredicates: IndexedBy() fails because Invalid parameter.");
479         return this;
480     }
481     index = RemoveQuotes(indexName);
482     return this;
483 }
484 
485 /**
486  * Configures to match the specified field whose data type is String array and values are within a given range.
487  */
In(std::string field,std::vector<std::string> values)488 AbsPredicates *AbsPredicates::In(std::string field, std::vector<std::string> values)
489 {
490     bool chekParaFlag = CheckParameter("in", field, {});
491     if (!chekParaFlag) {
492         LOG_WARN("AbsPredicates: In() fails because Invalid parameter.");
493         return this;
494     }
495     if (values.empty()) {
496         LOG_WARN("AbsPredicates: in() fails because values can't be null.");
497         return this;
498     }
499 
500     CheckIsNeedAnd();
501 
502     std::vector<std::string> replaceValues;
503     for (auto i : values) {
504         replaceValues.push_back("?");
505         whereArgs.push_back(i);
506     }
507     AppendWhereClauseWithInOrNotIn(" IN ", field, replaceValues);
508     return this;
509 }
510 
511 /**
512  * Configures to match the specified field whose data type is String array and values are out of a given range.
513  */
NotIn(std::string field,std::vector<std::string> values)514 AbsPredicates *AbsPredicates::NotIn(std::string field, std::vector<std::string> values)
515 {
516     bool chekParaFlag = CheckParameter("notIn", field, {});
517     if (!chekParaFlag) {
518         LOG_WARN("AbsPredicates: NotIn() fails because Invalid parameter.");
519         return this;
520     }
521     if (values.empty()) {
522         LOG_WARN("AbsPredicates: notIn() fails because values is null.");
523         return this;
524     }
525     CheckIsNeedAnd();
526     std::vector<std::string> replaceValues;
527     for (auto i : values) {
528         replaceValues.push_back("?");
529         whereArgs.push_back(i);
530     }
531     AppendWhereClauseWithInOrNotIn(" NOT IN ", field, replaceValues);
532     return this;
533 }
534 
Initial()535 void AbsPredicates::Initial()
536 {
537     distinct = false;
538     isNeedAnd = false;
539     isSorted = false;
540     whereArgs.clear();
541     whereClause.clear();
542     order.clear();
543     group.clear();
544     index.clear();
545     limit = -1;
546     offset = -1;
547 }
548 
549 /**
550  * Check the parameter validity.
551  */
CheckParameter(std::string methodName,std::string field,std::initializer_list<std::string> args) const552 bool AbsPredicates::CheckParameter(
553     std::string methodName, std::string field, std::initializer_list<std::string> args) const
554 {
555     if (field.empty()) {
556         LOG_WARN("QueryImpl(): string 'field' is empty.");
557         return false;
558     }
559     if (args.size() != 0) {
560         for (auto i : args) {
561             if (i.empty()) {
562                 LOG_WARN("QueryImpl(): value is empty.");
563                 return false;
564             }
565         }
566     }
567     return true;
568 }
569 
RemoveQuotes(std::string source) const570 std::string AbsPredicates::RemoveQuotes(std::string source) const
571 {
572     if (source.empty()) {
573         return source;
574     }
575     source.erase(std::remove(source.begin(), source.end(), '\''), source.end());
576     source.erase(std::remove(source.begin(), source.end(), '\"'), source.end());
577     source.erase(std::remove(source.begin(), source.end(), '`'), source.end());
578     return source;
579 }
580 
Normalized(std::string source)581 std::string AbsPredicates::Normalized(std::string source)
582 {
583     // split contains className, attributeName
584     const int splitSize = 2;
585     if (source.empty()) {
586         return source;
587     }
588     if (source.find(".") == source.npos) {
589         return StringUtils::SurroundWithQuote(source, "`");
590     }
591     size_t pos = source.find(".");
592     size_t left = 0;
593     std::vector<std::string> split;
594     while (pos != source.npos) {
595         split.push_back(source.substr(left, pos - left));
596         left = pos + 1;
597         pos = source.find(".", left);
598     }
599     if (left < source.length()) {
600         split.push_back(source.substr(left));
601     }
602     if (split.size() != splitSize) {
603         return source;
604     }
605     source = StringUtils::SurroundWithQuote(split[0], "`") + "." + StringUtils::SurroundWithQuote(split[1], "`");
606     return source;
607 }
608 
CheckIsNeedAnd()609 void AbsPredicates::CheckIsNeedAnd()
610 {
611     if (isNeedAnd) {
612         whereClause += " AND ";
613     } else {
614         isNeedAnd = true;
615     }
616 }
617 
AppendWhereClauseWithInOrNotIn(std::string methodName,std::string field,std::vector<std::string> replaceValues)618 void AbsPredicates::AppendWhereClauseWithInOrNotIn(
619     std::string methodName, std::string field, std::vector<std::string> replaceValues)
620 {
621     int errorCode = 0;
622     std::string normalizedField = SqliteSqlBuilder::Normalize(field, errorCode);
623     whereClause = whereClause + normalizedField + StringUtils::SurroundWithFunction(methodName, ",", replaceValues);
624 }
625 
GetWhereClause() const626 std::string AbsPredicates::GetWhereClause() const
627 {
628     return whereClause;
629 }
630 
SetWhereClause(std::string whereClause)631 void AbsPredicates::SetWhereClause(std::string whereClause)
632 {
633     if (whereClause.empty()) {
634         return;
635     }
636     this->whereClause = whereClause;
637 }
638 
GetWhereArgs() const639 std::vector<std::string> AbsPredicates::GetWhereArgs() const
640 {
641     return whereArgs;
642 }
643 
SetWhereArgs(std::vector<std::string> whereArgs)644 void AbsPredicates::SetWhereArgs(std::vector<std::string> whereArgs)
645 {
646     this->whereArgs = whereArgs;
647 }
648 
GetOrder() const649 std::string AbsPredicates::GetOrder() const
650 {
651     return order;
652 }
653 
SetOrder(std::string order)654 void AbsPredicates::SetOrder(std::string order)
655 {
656     if (order.empty()) {
657         return;
658     }
659     this->order = order;
660 }
661 
GetLimit() const662 int AbsPredicates::GetLimit() const
663 {
664     return limit;
665 }
666 
GetOffset() const667 int AbsPredicates::GetOffset() const
668 {
669     return offset;
670 }
671 
IsDistinct() const672 bool AbsPredicates::IsDistinct() const
673 {
674     return distinct;
675 }
676 
IsSorted() const677 bool AbsPredicates::IsSorted() const
678 {
679     return isSorted;
680 }
681 
GetGroup() const682 std::string AbsPredicates::GetGroup() const
683 {
684     return group;
685 }
686 
GetIndex() const687 std::string AbsPredicates::GetIndex() const
688 {
689     return index;
690 }
691 } // namespace NativeRdb
692 } // namespace OHOS