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
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 if (!joinTableNames.empty()) {
33 return ProcessJoins();
34 }
35 return GetTableName();
36 }
37
38 /**
39 * Adds a {@code cross join} condition to a SQL statement.
40 */
CrossJoin(const std::string & tableName)41 RdbPredicates *RdbPredicates::CrossJoin(const std::string &tableName)
42 {
43 return Join(JoinType::CROSS, tableName);
44 }
45
46 /**
47 * Adds an {@code inner join} condition to a SQL statement.
48 */
InnerJoin(const std::string & tableName)49 RdbPredicates *RdbPredicates::InnerJoin(const std::string &tableName)
50 {
51 return Join(JoinType::INNER, tableName);
52 }
53
54 /**
55 * Adds a {@code left outer join} condition to a SQL statement.
56 */
LeftOuterJoin(const std::string & tableName)57 RdbPredicates *RdbPredicates::LeftOuterJoin(const std::string &tableName)
58 {
59 return Join(JoinType::LEFT, tableName);
60 }
61 /**
62 * Adds a condition to a SQL statement.
63 */
Join(int join,const std::string & tableName)64 RdbPredicates *RdbPredicates::Join(int join, const std::string &tableName)
65 {
66 if (tableName.empty()) {
67 LOG_WARN("RdbPredicates join failed: table name is null or empty.");
68 return this;
69 }
70
71 joinTypes.push_back(GetGrammar(join));
72 joinTableNames.push_back(tableName);
73 joinCount++;
74 return this;
75 }
76
77 /**
78 * Adds a {@code using} condition to the predicate. This method is similar to {@code using} of the SQL statement.
79 */
Using(const std::vector<std::string> & fields)80 RdbPredicates *RdbPredicates::Using(const std::vector<std::string> &fields)
81 {
82 if (fields.size() == 0) {
83 LOG_WARN("RdbPredicates Using failed : clauses is null.");
84 return this;
85 }
86 if (joinCount <= 0) {
87 LOG_WARN("No active join operation before using.");
88 return this;
89 }
90 while (joinCount > 1) {
91 joinConditions.push_back("");
92 joinCount--;
93 }
94 joinCount--;
95 joinConditions.push_back(StringUtils::SurroundWithFunction("USING", ",", fields));
96 return this;
97 }
98
99 /**
100 * Adds an {@code on} condition to the predicate.
101 */
On(const std::vector<std::string> & clauses)102 RdbPredicates *RdbPredicates::On(const std::vector<std::string> &clauses)
103 {
104 if (clauses.size() == 0) {
105 LOG_WARN("RdbPredicates on failed : clauses is null.");
106 return this;
107 }
108 if (joinCount <= 0) {
109 LOG_WARN("No active join operation before on.");
110 return this;
111 }
112 while (joinCount > 1) {
113 joinConditions.push_back("");
114 joinCount--;
115 }
116 joinCount--;
117 joinConditions.push_back(StringUtils::SurroundWithFunction("ON", "AND", clauses));
118 return this;
119 }
120
ProcessJoins() const121 std::string RdbPredicates::ProcessJoins() const
122 {
123 std::string builder = GetTableName();
124 size_t size = joinTableNames.size();
125 for (size_t i = 0; i < size; i++) {
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