drogon
C++14/17-based HTTP application framework
Loading...
Searching...
No Matches
Criteria.h
Go to the documentation of this file.
1
14
15#pragma once
16
17#include <drogon/exports.h>
19#include <assert.h>
20#include <memory>
21#include <string>
22#include <tuple>
23#include <type_traits>
24
25namespace Json
26{
27class Value;
28}
29
30namespace drogon
31{
32namespace orm
33{
34enum class CompareOperator
35{
36 EQ,
37 NE,
38 GT,
39 GE,
40 LT,
41 LE,
42 Like,
43 NotLike,
44 In,
45 NotIn,
46 IsNull,
47 IsNotNull
48};
49
53struct CustomSql
54{
55 explicit CustomSql(std::string content) : content_(std::move(content))
56 {
57 }
58
59 std::string content_;
60};
61
65inline CustomSql operator""_sql(const char *str, size_t)
66{
67 return CustomSql(str);
68}
69
73class DROGON_EXPORT Criteria
74{
75 public:
82 explicit operator bool() const
83 {
84 return !conditionString_.empty();
85 }
86
92 std::string criteriaString() const
93 {
94 return conditionString_;
95 }
96
115 template <typename... Arguments>
116 explicit Criteria(const CustomSql &sql, Arguments &&...args)
117 {
118 conditionString_ = sql.content_;
119 outputArgumentsFunc_ =
120 [args = std::make_tuple(std::forward<Arguments>(args)...)](
121 internal::SqlBinder &binder) mutable {
122 return std::apply(
123 [&binder](auto &&...args) {
124 (void)std::initializer_list<int>{
125 (binder << std::forward<Arguments>(args), 0)...};
126 },
127 std::move(args));
128 };
129 }
130
131 template <typename... Arguments>
132 explicit Criteria(CustomSql &&sql, Arguments &&...args)
133 {
134 conditionString_ = std::move(sql.content_);
135 outputArgumentsFunc_ =
136 [args = std::make_tuple(std::forward<Arguments>(args)...)](
137 internal::SqlBinder &binder) mutable {
138 return std::apply(
139 [&binder](auto &&...args) {
140 (void)std::initializer_list<int>{
141 (binder << std::forward<Arguments>(args), 0)...};
142 },
143 std::move(args));
144 };
145 }
146
155 template <typename T>
156 Criteria(const std::string &colName, const CompareOperator &opera, T &&arg)
157 {
158 assert(opera != CompareOperator::IsNotNull &&
159 opera != CompareOperator::IsNull);
160 conditionString_ = colName;
161 switch (opera)
162 {
163 case CompareOperator::EQ:
164 conditionString_ += " = $?";
165 break;
166 case CompareOperator::NE:
167 conditionString_ += " != $?";
168 break;
169 case CompareOperator::GT:
170 conditionString_ += " > $?";
171 break;
172 case CompareOperator::GE:
173 conditionString_ += " >= $?";
174 break;
175 case CompareOperator::LT:
176 conditionString_ += " < $?";
177 break;
178 case CompareOperator::LE:
179 conditionString_ += " <= $?";
180 break;
181 case CompareOperator::Like:
182 conditionString_ += " like $?";
183 break;
184 case CompareOperator::NotLike:
185 conditionString_ += " not like $?";
186 break;
187 default:
188 break;
189 }
190 outputArgumentsFunc_ =
191 [arg = std::forward<T>(arg)](internal::SqlBinder &binder) {
192 binder << arg;
193 };
194 }
195
196 template <typename T>
197 Criteria(const std::string &colName,
198 const CompareOperator &opera,
199 const std::vector<T> &args)
200 {
201 const auto argsSize = args.size();
202 assert(((opera == CompareOperator::In) ||
203 (opera == CompareOperator::NotIn)) &&
204 (argsSize > 0));
205 if (opera == CompareOperator::In)
206 {
207 conditionString_ = colName + " in (";
208 }
209 else if (opera == CompareOperator::NotIn)
210 {
211 conditionString_ = colName + " not in (";
212 }
213 for (size_t i = 0; i < argsSize; ++i)
214 {
215 if (i < (argsSize - 1))
216 conditionString_.append("$?,");
217 else
218 conditionString_.append("$?");
219 }
220 conditionString_.append(")");
221 outputArgumentsFunc_ = [args](internal::SqlBinder &binder) {
222 for (auto &arg : args)
223 {
224 binder << arg;
225 }
226 };
227 }
228
229 template <typename T>
230 Criteria(const std::string &colName,
231 const CompareOperator &opera,
232 std::vector<T> &&args)
233 {
234 const auto argsSize = args.size();
235 assert(((opera == CompareOperator::In) ||
236 (opera == CompareOperator::NotIn)) &&
237 (argsSize > 0));
238 if (opera == CompareOperator::In)
239 {
240 conditionString_ = colName + " in (";
241 }
242 else if (opera == CompareOperator::NotIn)
243 {
244 conditionString_ = colName + " not in (";
245 }
246 for (size_t i = 0; i < argsSize; ++i)
247 {
248 if (i < (argsSize - 1))
249 conditionString_.append("$?,");
250 else
251 conditionString_.append("$?");
252 }
253 conditionString_.append(")");
254 outputArgumentsFunc_ =
255 [args = std::move(args)](internal::SqlBinder &binder) {
256 for (auto &arg : args)
257 {
258 binder << arg;
259 }
260 };
261 }
262
263 template <typename T>
264 Criteria(const std::string &colName,
265 const CompareOperator &opera,
266 std::vector<T> &args)
267 : Criteria(colName, opera, (const std::vector<T> &)args)
268 {
269 }
270
278 template <typename T>
279 Criteria(const std::string &colName, T &&arg)
280 : Criteria(colName, CompareOperator::EQ, std::forward<T>(arg))
281 {
282 }
283
295 Criteria(const std::string &colName, const CompareOperator &opera)
296 {
297 assert(opera == CompareOperator::IsNotNull ||
298 opera == CompareOperator::IsNull);
299 conditionString_ = colName;
300 switch (opera)
301 {
302 case CompareOperator::IsNull:
303 conditionString_ += " is null";
304 break;
305 case CompareOperator::IsNotNull:
306 conditionString_ += " is not null";
307 break;
308 default:
309 break;
310 }
311 }
312
313 Criteria(const std::string &colName, CompareOperator &opera)
314 : Criteria(colName, (const CompareOperator &)opera)
315 {
316 }
317
318 Criteria(const std::string &colName, CompareOperator &&opera)
319 : Criteria(colName, (const CompareOperator &)opera)
320 {
321 }
322
337 explicit Criteria(const Json::Value &json) noexcept(false);
338 Criteria() = default;
339
346 void outputArgs(internal::SqlBinder &binder) const
347 {
348 if (outputArgumentsFunc_)
349 outputArgumentsFunc_(binder);
350 }
351
352 private:
353 friend DROGON_EXPORT const Criteria operator&&(Criteria cond1,
354 Criteria cond2);
355
356 friend DROGON_EXPORT const Criteria operator||(Criteria cond1,
357 Criteria cond2);
358 std::string conditionString_;
359 std::function<void(internal::SqlBinder &)> outputArgumentsFunc_;
360}; // namespace orm
361
362DROGON_EXPORT const Criteria operator&&(Criteria cond1, Criteria cond2);
363DROGON_EXPORT const Criteria operator||(Criteria cond1, Criteria cond2);
364
365} // namespace orm
366} // namespace drogon
this class represents a comparison condition.
Definition Criteria.h:74
std::string criteriaString() const
return the condition string in SQL.
Definition Criteria.h:92
Criteria(const Json::Value &json) noexcept(false)
Construct a new Criteria object.
void outputArgs(internal::SqlBinder &binder) const
Output arguments to the SQL binder object.
Definition Criteria.h:346
Criteria(const std::string &colName, T &&arg)
Construct a new Criteria object presenting a equal expression.
Definition Criteria.h:279
Criteria(const std::string &colName, const CompareOperator &opera)
Construct a new Criteria object presenting a expression without parameters.
Definition Criteria.h:295
Criteria(const CustomSql &sql, Arguments &&...args)
Construct a new custom Criteria object.
Definition Criteria.h:116
Criteria(const std::string &colName, const CompareOperator &opera, T &&arg)
Construct a new Criteria object.
Definition Criteria.h:156
Definition SqlBinder.h:293
Drogon Test is a minimal effort test framework developed because the major C++ test frameworks doesn'...
Definition Attribute.h:23
STL namespace.
Wrapper for custom SQL string.
Definition Criteria.h:54