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