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 #ifndef DISTRIBUTEDDB_QUERY_H
17 #define DISTRIBUTEDDB_QUERY_H
18 
19 #include <list>
20 #include <set>
21 #include <string>
22 #include <vector>
23 
24 #include "query_expression.h"
25 #include "types_export.h"
26 
27 namespace DistributedDB {
28 class GetQueryInfo;
29 class Query {
30 public:
31 
32     // Do not support concurrent use of query objects
33     DB_API static Query Select();
34     DB_API static Query Select(const std::string &tableName);
35 
36     DB_API Query &FromTable(const std::vector<std::string> &tableNames);
37 
38     DB_API Query &From(const std::string &tableName);
39 
40     template<typename T>
EqualTo(const std::string & field,const T & value)41     DB_API Query &EqualTo(const std::string &field, const T &value)
42     {
43         FieldValue fieldValue;
44         QueryValueType type = GetFieldTypeAndValue(value, fieldValue);
45         ExecuteCompareOperation(QueryObjType::EQUALTO, field, type, fieldValue);
46         return *this;
47     }
48 
49     template<typename T>
NotEqualTo(const std::string & field,const T & value)50     DB_API Query &NotEqualTo(const std::string &field, const T &value)
51     {
52         FieldValue fieldValue;
53         QueryValueType type = GetFieldTypeAndValue(value, fieldValue);
54         ExecuteCompareOperation(QueryObjType::NOT_EQUALTO, field, type, fieldValue);
55         return *this;
56     }
57 
58     template<typename T>
GreaterThan(const std::string & field,const T & value)59     DB_API Query &GreaterThan(const std::string &field, const T &value)
60     {
61         FieldValue fieldValue;
62         QueryValueType type = GetFieldTypeAndValue(value, fieldValue);
63         ExecuteCompareOperation(QueryObjType::GREATER_THAN, field, type, fieldValue);
64         return *this;
65     }
66 
67     template<typename T>
LessThan(const std::string & field,const T & value)68     DB_API Query &LessThan(const std::string &field, const T &value)
69     {
70         FieldValue fieldValue;
71         QueryValueType type = GetFieldTypeAndValue(value, fieldValue);
72         ExecuteCompareOperation(QueryObjType::LESS_THAN, field, type, fieldValue);
73         return *this;
74     }
75 
76     template<typename T>
GreaterThanOrEqualTo(const std::string & field,const T & value)77     DB_API Query &GreaterThanOrEqualTo(const std::string &field, const T &value)
78     {
79         FieldValue fieldValue;
80         QueryValueType type = GetFieldTypeAndValue(value, fieldValue);
81         ExecuteCompareOperation(QueryObjType::GREATER_THAN_OR_EQUALTO, field, type, fieldValue);
82         return *this;
83     }
84 
85     template<typename T>
LessThanOrEqualTo(const std::string & field,const T & value)86     DB_API Query &LessThanOrEqualTo(const std::string &field, const T &value)
87     {
88         FieldValue fieldValue;
89         QueryValueType type = GetFieldTypeAndValue(value, fieldValue);
90         ExecuteCompareOperation(QueryObjType::LESS_THAN_OR_EQUALTO, field, type, fieldValue);
91         return *this;
92     }
93 
94     DB_API Query &OrderBy(const std::string &field, bool isAsc = true);
95 
96     DB_API Query &OrderByWriteTime(bool isAsc = true);
97 
98     DB_API Query &Limit(int number, int offset = 0);
99 
100     DB_API Query &Like(const std::string &field, const std::string &value);
101 
102     DB_API Query &NotLike(const std::string &field, const std::string &value);
103 
104     template<typename T>
In(const std::string & field,const std::vector<T> & values)105     DB_API Query &In(const std::string &field, const std::vector<T> &values)
106     {
107         std::vector<FieldValue> fieldValues;
108         QueryValueType type = QueryValueType::VALUE_TYPE_NULL;
109         for (const auto &value : values) {
110             FieldValue fieldValue;
111             type = GetFieldTypeAndValue(value, fieldValue);
112             fieldValues.push_back(fieldValue);
113         }
114 
115         ExecuteCompareOperation(QueryObjType::IN, field, type, fieldValues);
116         return *this;
117     }
118 
119     template<typename T>
NotIn(const std::string & field,const std::vector<T> & values)120     DB_API Query &NotIn(const std::string &field, const std::vector<T> &values)
121     {
122         std::vector<FieldValue> fieldValues;
123         QueryValueType type = QueryValueType::VALUE_TYPE_NULL;
124         for (const auto &value : values) {
125             FieldValue fieldValue;
126             type = GetFieldTypeAndValue(value, fieldValue);
127             fieldValues.push_back(fieldValue);
128         }
129 
130         ExecuteCompareOperation(QueryObjType::NOT_IN, field, type, fieldValues);
131         return *this;
132     }
133 
134     DB_API Query &IsNull(const std::string &field);
135 
136     DB_API Query &And();
137 
138     DB_API Query &Or();
139 
140     DB_API Query &IsNotNull(const std::string &field);
141 
142     DB_API Query &BeginGroup();
143 
144     DB_API Query &EndGroup();
145 
146     DB_API Query &PrefixKey(const std::vector<uint8_t> &key);
147 
148     DB_API Query &SuggestIndex(const std::string &indexName);
149 
150     DB_API Query &InKeys(const std::set<Key> &keys);
151 
152     DB_API Query &Range(const std::vector<uint8_t> &keyBegin, const std::vector<uint8_t> &keyEnd);
153 
154     friend class GetQueryInfo;
155     DB_API ~Query() = default;
156     DB_API Query() = default;
157 private:
158     explicit Query(const std::string &tableName);
159 
160     DB_SYMBOL void ExecuteCompareOperation(QueryObjType operType, const std::string &field,
161         const QueryValueType type, const FieldValue &fieldValue);
162     DB_SYMBOL void ExecuteCompareOperation(QueryObjType operType, const std::string &field,
163         const QueryValueType type, const std::vector<FieldValue> &fieldValue);
164 
165     template<typename T>
GetFieldTypeAndValue(const T & queryValue,FieldValue & fieldValue)166     QueryValueType GetFieldTypeAndValue(const T &queryValue, FieldValue &fieldValue)
167     {
168         return GetQueryValueType::GetFieldTypeAndValue(queryValue, fieldValue);
169     }
170 
171     QueryExpression queryExpression_;
172 };
173 } // namespace DistributedDB
174 #endif // DISTRIBUTEDDB_QUERY_H
175