hikyuu2/hikyuu_cpp/hikyuu/utilities/db_connect/DBCondition.h

248 lines
7.1 KiB
C++
Raw Normal View History

2021-05-21 02:09:54 +08:00
/*
* Copyright(C) 2021 hikyuu.org
*
* Create on: 2021-05-20
* Author: fasiondog
*/
#pragma once
#include <string>
2021-05-22 01:51:10 +08:00
#include <ostream>
2021-05-22 21:06:08 +08:00
#include <sstream>
2021-05-22 01:51:10 +08:00
#include <vector>
2021-05-21 02:09:54 +08:00
#include <fmt/format.h>
2021-05-22 01:51:10 +08:00
#include <fmt/ranges.h>
2021-05-22 21:06:08 +08:00
#include "../../Log.h"
2021-05-21 02:09:54 +08:00
#ifndef HKU_API
#define HKU_API
#endif
namespace hku {
2021-05-22 01:51:10 +08:00
struct ASC {
2023-10-22 04:27:04 +08:00
explicit ASC(const char* name) : name(name) {}
explicit ASC(const std::string& name) : name(name) {}
2021-05-22 01:51:10 +08:00
std::string name;
};
struct DESC {
2023-10-22 04:27:04 +08:00
explicit DESC(const char* name) : name(name) {}
explicit DESC(const std::string& name) : name(name) {}
2021-05-22 01:51:10 +08:00
std::string name;
};
2023-10-22 04:27:04 +08:00
struct LIMIT {
explicit LIMIT(int limit) : limit(limit) {}
int limit = 1;
};
2021-05-21 02:09:54 +08:00
class HKU_API DBCondition {
public:
2021-05-24 02:04:57 +08:00
DBCondition() = default;
DBCondition(const DBCondition&) = default;
DBCondition(DBCondition&& rv) : m_condition(std::move(rv.m_condition)) {}
2021-05-21 02:09:54 +08:00
2021-05-24 02:04:57 +08:00
explicit DBCondition(const char* cond) : m_condition(cond) {}
explicit DBCondition(const std::string& cond) : m_condition(cond) {}
DBCondition& operator=(const DBCondition&) = default;
DBCondition& operator=(DBCondition&& rv) {
if (this != &rv) {
m_condition = std::move(rv.m_condition);
}
return *this;
}
2021-05-21 02:09:54 +08:00
DBCondition& operator&(const DBCondition& other);
DBCondition& operator|(const DBCondition& other);
2021-05-22 01:51:10 +08:00
enum ORDERBY { ORDER_ASC, ORDER_DESC };
2021-05-21 02:09:54 +08:00
void orderBy(const std::string& field, ORDERBY order) {
2021-05-22 01:51:10 +08:00
m_condition = order == ORDERBY::ORDER_ASC
2021-05-21 02:09:54 +08:00
? fmt::format("{} order by {} ASC", m_condition, field)
: fmt::format("{} order by {} DESC", m_condition, field);
}
2021-05-22 01:51:10 +08:00
DBCondition& operator+(const ASC& asc) {
orderBy(asc.name, ORDER_ASC);
return *this;
}
DBCondition& operator+(const DESC& desc) {
2023-10-22 04:27:04 +08:00
orderBy(desc.name, ORDER_DESC);
return *this;
}
DBCondition& operator+(const LIMIT& limit) {
m_condition = fmt::format("{} limit {}", m_condition, limit.limit);
2021-05-22 01:51:10 +08:00
return *this;
}
2021-05-21 02:09:54 +08:00
const std::string& str() const {
return m_condition;
}
private:
std::string m_condition;
};
2021-05-22 01:51:10 +08:00
struct Field {
2023-10-22 04:27:04 +08:00
explicit Field(const char* name) : name(name) {}
explicit Field(const std::string& name) : name(name) {}
2021-05-22 01:51:10 +08:00
// in 和 not_in 不支持 字符串,一般不会用到 in ("stra", "strb") 的 SQL 操作
template <typename T>
2021-05-26 01:51:49 +08:00
DBCondition in(const std::vector<T>& vals) {
HKU_CHECK(!vals.empty(), "input vals can't be empty!");
return DBCondition(fmt::format("({} in ({}))", name, fmt::join(vals, ",")));
}
2021-05-22 21:06:08 +08:00
2021-05-22 01:51:10 +08:00
template <typename T>
2021-05-26 01:51:49 +08:00
DBCondition not_in(const std::vector<T>& vals) {
HKU_CHECK(!vals.empty(), "input vals can't be empty!");
return DBCondition(fmt::format("({} not in ({}))", name, fmt::join(vals, ",")));
}
2021-05-22 21:06:08 +08:00
2021-05-22 01:51:10 +08:00
DBCondition like(const std::string& pattern) {
2021-05-22 21:06:08 +08:00
return DBCondition(fmt::format(R"(({} like "{}"))", name, pattern));
}
DBCondition like(const char* pattern) {
return DBCondition(fmt::format(R"(({} like "{}"))", name, pattern));
2021-05-22 01:51:10 +08:00
}
std::string name;
};
// linux下类成员函数模板特化必须放在类外实现
// 否则编译时会报explicit specialization in non-namespace scope
template <>
2021-05-26 01:51:49 +08:00
inline DBCondition Field::in<std::string>(const std::vector<std::string>& vals) {
HKU_CHECK(!vals.empty(), "input vals can't be empty!");
std::ostringstream out;
out << "(" << name << " in (";
size_t total = vals.size();
for (size_t i = 0; i < total - 1; i++) {
out << "\"" << vals[i] << "\",";
}
out << "\"" << vals[total - 1] << "\"))";
return DBCondition(out.str());
}
template <>
2021-05-26 01:51:49 +08:00
inline DBCondition Field::not_in<std::string>(const std::vector<std::string>& vals) {
HKU_CHECK(!vals.empty(), "input vals can't be empty!");
std::ostringstream out;
out << "(" << name << " not in (";
size_t total = vals.size();
for (size_t i = 0; i < total - 1; i++) {
out << "\"" << vals[i] << "\",";
}
out << "\"" << vals[total - 1] << "\"))";
return DBCondition(out.str());
}
2021-05-22 01:51:10 +08:00
inline std::ostream& operator<<(std::ostream& out, const DBCondition& d) {
out << d.str();
return out;
}
template <typename T>
inline DBCondition operator==(const Field& field, T val) {
2023-07-28 23:50:26 +08:00
std::ostringstream out;
out << "(" << field.name << "=" << val << ")";
return DBCondition(out.str());
2021-05-22 01:51:10 +08:00
}
template <typename T>
inline DBCondition operator!=(const Field& field, T val) {
2023-07-28 23:50:26 +08:00
std::ostringstream out;
out << "(" << field.name << "<>" << val << ")";
return DBCondition(out.str());
2021-05-22 01:51:10 +08:00
}
template <typename T>
inline DBCondition operator>(const Field& field, T val) {
2023-07-28 23:50:26 +08:00
std::ostringstream out;
out << "(" << field.name << ">" << val << ")";
return DBCondition(out.str());
2021-05-22 01:51:10 +08:00
}
template <typename T>
inline DBCondition operator>=(const Field& field, T val) {
2023-07-28 23:50:26 +08:00
std::ostringstream out;
out << "(" << field.name << ">=" << val << ")";
return DBCondition(out.str());
2021-05-22 01:51:10 +08:00
}
template <typename T>
inline DBCondition operator<(const Field& field, T val) {
2023-07-28 23:50:26 +08:00
std::ostringstream out;
out << "(" << field.name << "<" << val << ")";
return DBCondition(out.str());
2021-05-22 01:51:10 +08:00
}
template <typename T>
inline DBCondition operator<=(const Field& field, T val) {
2023-07-28 23:50:26 +08:00
std::ostringstream out;
out << "(" << field.name << "<=" << val << ")";
return DBCondition(out.str());
2021-05-22 01:51:10 +08:00
}
template <>
2021-05-24 23:16:04 +08:00
inline DBCondition operator!=(const Field& field, const char* val) {
2021-05-22 01:51:10 +08:00
return DBCondition(fmt::format(R"(({}<>"{}"))", field.name, val));
}
template <>
2021-05-24 23:16:04 +08:00
inline DBCondition operator>(const Field& field, const char* val) {
2021-05-22 01:51:10 +08:00
return DBCondition(fmt::format(R"(({}>"{}"))", field.name, val));
}
template <>
2021-05-24 23:16:04 +08:00
inline DBCondition operator<(const Field& field, const char* val) {
2021-05-22 01:51:10 +08:00
return DBCondition(fmt::format(R"(({}<"{}"))", field.name, val));
}
template <>
2021-05-24 23:16:04 +08:00
inline DBCondition operator>=(const Field& field, const char* val) {
2021-05-22 01:51:10 +08:00
return DBCondition(fmt::format(R"(({}>="{}"))", field.name, val));
}
template <>
2021-05-24 23:16:04 +08:00
inline DBCondition operator<=(const Field& field, const char* val) {
2021-05-22 01:51:10 +08:00
return DBCondition(fmt::format(R"(({}<="{}"))", field.name, val));
}
2021-05-24 23:16:04 +08:00
inline DBCondition operator==(const Field& field, const std::string& val) {
2021-05-22 21:06:08 +08:00
return DBCondition(fmt::format(R"(({}="{}"))", field.name, val));
}
2021-05-24 23:16:04 +08:00
inline DBCondition operator!=(const Field& field, const std::string& val) {
2021-05-22 21:06:08 +08:00
return DBCondition(fmt::format(R"(({}<>"{}"))", field.name, val));
}
2021-05-24 23:16:04 +08:00
inline DBCondition operator>(const Field& field, const std::string& val) {
2021-05-22 21:06:08 +08:00
return DBCondition(fmt::format(R"(({}>"{}"))", field.name, val));
}
2021-05-24 23:16:04 +08:00
inline DBCondition operator<(const Field& field, const std::string& val) {
2021-05-22 21:06:08 +08:00
return DBCondition(fmt::format(R"(({}<"{}"))", field.name, val));
}
2021-05-24 23:16:04 +08:00
inline DBCondition operator>=(const Field& field, const std::string& val) {
2021-05-22 21:06:08 +08:00
return DBCondition(fmt::format(R"(({}>="{}"))", field.name, val));
}
2021-05-24 23:16:04 +08:00
inline DBCondition operator<=(const Field& field, const std::string& val) {
2021-05-22 21:06:08 +08:00
return DBCondition(fmt::format(R"(({}<="{}"))", field.name, val));
}
2021-05-24 23:16:04 +08:00
inline DBCondition operator==(const Field& field, const char* val) {
return DBCondition(fmt::format(R"(({}="{}"))", field.name, val));
}
2021-05-21 02:09:54 +08:00
} // namespace hku