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