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