1 /*
2 * Copyright (c) 2022 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 #define LOG_TAG "RdbPredicates"
16 #include "rdb_predicates.h"
17
18 #include "logger.h"
19 #include "string_utils.h"
20
21 namespace OHOS {
22 namespace NativeRdb {
23 using namespace OHOS::Rdb;
24
RdbPredicates(const std::string & tableName)25 RdbPredicates::RdbPredicates(const std::string &tableName) : AbsRdbPredicates(tableName)
26 {
27 InitialParam();
28 }
29
GetJoinClause() const30 std::string RdbPredicates::GetJoinClause() const
31 {
32 return joinTableNames.empty() ? "" : ProcessJoins();
33 }
34
35 /**
36 * Adds a {@code cross join} condition to a SQL statement.
37 */
CrossJoin(const std::string & tableName)38 RdbPredicates *RdbPredicates::CrossJoin(const std::string &tableName)
39 {
40 return Join(JoinType::CROSS, tableName);
41 }
42
43 /**
44 * Adds an {@code inner join} condition to a SQL statement.
45 */
InnerJoin(const std::string & tableName)46 RdbPredicates *RdbPredicates::InnerJoin(const std::string &tableName)
47 {
48 return Join(JoinType::INNER, tableName);
49 }
50
51 /**
52 * Adds a {@code left outer join} condition to a SQL statement.
53 */
LeftOuterJoin(const std::string & tableName)54 RdbPredicates *RdbPredicates::LeftOuterJoin(const std::string &tableName)
55 {
56 return Join(JoinType::LEFT, tableName);
57 }
58 /**
59 * Adds a condition to a SQL statement.
60 */
Join(int join,const std::string & tableName)61 RdbPredicates *RdbPredicates::Join(int join, const std::string &tableName)
62 {
63 if (tableName.empty()) {
64 LOG_WARN("RdbPredicates join failed: table name is null or empty.");
65 return this;
66 }
67
68 joinTypes.push_back(GetGrammar(join));
69 joinTableNames.push_back(tableName);
70 joinCount++;
71 return this;
72 }
73
74 /**
75 * Adds a {@code using} condition to the predicate. This method is similar to {@code using} of the SQL statement.
76 */
Using(const std::vector<std::string> & fields)77 RdbPredicates *RdbPredicates::Using(const std::vector<std::string> &fields)
78 {
79 if (fields.size() == 0) {
80 LOG_WARN("RdbPredicates Using failed : clauses is null.");
81 return this;
82 }
83 if (joinCount <= 0) {
84 LOG_WARN("No active join operation before using.");
85 return this;
86 }
87 while (joinCount > 1) {
88 joinConditions.push_back("");
89 joinCount--;
90 }
91 joinCount--;
92 joinConditions.push_back(StringUtils::SurroundWithFunction("USING", ",", fields));
93 return this;
94 }
95
96 /**
97 * Adds an {@code on} condition to the predicate.
98 */
On(const std::vector<std::string> & clauses)99 RdbPredicates *RdbPredicates::On(const std::vector<std::string> &clauses)
100 {
101 if (clauses.size() == 0) {
102 LOG_WARN("RdbPredicates on failed : clauses is null.");
103 return this;
104 }
105 if (joinCount <= 0) {
106 LOG_WARN("No active join operation before on.");
107 return this;
108 }
109 while (joinCount > 1) {
110 joinConditions.push_back("");
111 joinCount--;
112 }
113 joinCount--;
114 joinConditions.push_back(StringUtils::SurroundWithFunction("ON", "AND", clauses));
115 return this;
116 }
117
ProcessJoins() const118 std::string RdbPredicates::ProcessJoins() const
119 {
120 std::string builder;
121 size_t size = joinTableNames.size();
122 for (size_t i = 0; i < size; i++) {
123 if (i != 0) {
124 builder = builder + " ";
125 }
126 builder = builder + joinTypes[i] + " " + joinTableNames[i];
127 if (joinConditions[i] != "") {
128 builder = builder + " " + joinConditions[i];
129 }
130 }
131 return builder;
132 }
133
GetGrammar(int type) const134 std::string RdbPredicates::GetGrammar(int type) const
135 {
136 if (type == INNER) {
137 return "INNER JOIN";
138 }
139 if (type == LEFT) {
140 return "LEFT OUTER JOIN";
141 }
142 return "CROSS JOIN";
143 }
144 } // namespace NativeRdb
145 } // namespace OHOS