From: sangwan.kwon Date: Mon, 15 Jan 2018 06:51:42 +0000 (+0900) Subject: Support AND, OR conditions on where clause X-Git-Tag: submit/tizen_4.0/20180119.042851^2~5 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=9399a1c137ae65743b4bcae5ddcc46cceb5b355e;p=platform%2Fcore%2Fsecurity%2Fklay.git Support AND, OR conditions on where clause Change-Id: I0adc9d253389e64a4cc8679684793df444746343 Signed-off-by: sangwan.kwon --- diff --git a/include/klay/db/query-builder/expression.hxx b/include/klay/db/query-builder/expression.hxx index adc6c27..ea3ba25 100644 --- a/include/klay/db/query-builder/expression.hxx +++ b/include/klay/db/query-builder/expression.hxx @@ -1,10 +1,38 @@ #pragma once +#include + namespace qxx { namespace condition { -template -struct Binary { +struct Base {}; + +template +struct And : public Base { + L l; + R r; + + And(L l, R r) : l(l), r(r) {} + operator std::string() const + { + return "AND"; + } +}; + +template +struct Or : public Base { + L l; + R r; + + Or(L l, R r) : l(l), r(r) {} + operator std::string() const + { + return "OR"; + } +}; + +template +struct Binary : public Base { L l; R r; @@ -13,32 +41,36 @@ struct Binary { } // namespace condition -template +template struct Expression { Type value; }; -template -Expression expr(Type value) { +template +Expression expr(Type value) +{ return {value}; } -template +template struct Lesser : public condition::Binary { using condition::Binary::Binary; - operator std::string() const { + operator std::string() const + { return "<"; } }; -template -Lesser operator<(Expression expr, R r) { +template +Lesser operator<(Expression expr, R r) +{ return {expr.value, r}; } -template -struct Equal : public condition::Binary { +template +struct Equal : public condition::Binary +{ using condition::Binary::Binary; operator std::string() const { @@ -46,13 +78,15 @@ struct Equal : public condition::Binary { } }; -template -Equal operator==(Expression expr, R r) { +template +Equal operator==(Expression expr, R r) +{ return {expr.value, r}; } -template -struct Greater : public condition::Binary { +template +struct Greater : public condition::Binary +{ using condition::Binary::Binary; operator std::string() const { @@ -60,9 +94,34 @@ struct Greater : public condition::Binary { } }; -template -Equal operator>(Expression expr, R r) { +template +Greater operator>(Expression expr, R r) +{ return {expr.value, r}; } +template +using enable_if_t = typename std::enable_if::type; + +template +using is_condition = typename std::is_base_of; + +template::value + && qxx::is_condition::value>> +condition::And operator&&(const L& l, const R& r) +{ + return {l, r}; +} + +template::value + && qxx::is_condition::value>> +condition::Or operator||(const L& l, const R& r) +{ + return {l, r}; +} + } // namespace qxx diff --git a/include/klay/db/query-builder/table.hxx b/include/klay/db/query-builder/table.hxx index d236eda..f54c3c1 100644 --- a/include/klay/db/query-builder/table.hxx +++ b/include/klay/db/query-builder/table.hxx @@ -3,6 +3,7 @@ #include "column.hxx" #include "table-impl.hxx" #include "tuple-helper.hxx" +#include "expression.hxx" #include #include @@ -58,6 +59,15 @@ private: } }; + template + std::string processWhere(condition::And& expr); + + template + std::string processWhere(condition::Or& expr); + + template + std::string processWhere(Expr expr); + std::string name; ImplType impl; @@ -114,10 +124,8 @@ template template Table Table::where(Expr expr) { - auto name = this->impl.getColumnName(expr.l); - std::stringstream ss; - ss << "WHERE " << name << " " << std::string(expr) << " ?"; + ss << "WHERE " << this->processWhere(expr); this->cache.emplace_back(ss.str()); @@ -164,4 +172,36 @@ std::string Table::getColumnName(ColumnType&& type) const noexcept return this->impl.getColumnName(std::forward(type)); } +template +template +std::string Table::processWhere(condition::And& expr) { + std::stringstream ss; + ss << this->processWhere(expr.l) << " "; + ss << static_cast(expr) << " "; + ss << this->processWhere(expr.r); + + return ss.str(); +} + +template +template +std::string Table::processWhere(condition::Or& expr) { + std::stringstream ss; + ss << this->processWhere(expr.l) << " "; + ss << static_cast(expr) << " "; + ss << this->processWhere(expr.r); + + return ss.str(); +} + +template +template +std::string Table::processWhere(Expr expr) { + std::stringstream ss; + ss << this->impl.getColumnName(expr.l); + ss << " = ?"; + + return ss.str(); +} + } // namespace qxx diff --git a/include/klay/db/query-builder/test-main.cpp b/include/klay/db/query-builder/test-main.cpp index 30dd09b..d24c087 100644 --- a/include/klay/db/query-builder/test-main.cpp +++ b/include/klay/db/query-builder/test-main.cpp @@ -25,11 +25,15 @@ int main() { std::string select2 = admin.select(&Admin::id, &Admin::uid, &Admin::key); std::string select3 = admin.select(&Admin::uid, &Admin::key).where(expr(&Admin::id) > 3); std::string select4 = admin.selectAll().where(expr(&Admin::uid) > 3); + std::string select5 = admin.selectAll().where(expr(&Admin::uid) > 3 && expr(&Admin::pkg) == "dpm"); + std::string select6 = admin.selectAll().where(expr(&Admin::uid) > 3 || expr(&Admin::pkg) == "dpm"); std::cout << select1 << '\n'; // SELECT id pkg uid key FROM admin std::cout << select2 << '\n'; // SELECT id uid key FROM admin std::cout << select3 << '\n'; // SELECT uid key FROM admin WHERE id = ? std::cout << select4 << '\n'; // SELECT * FROM admin WHERE uid = ? + std::cout << select5 << '\n'; // SELECT * FROM admin WHERE uid = ? AND pkg = ? + std::cout << select6 << '\n'; // SELECT * FROM admin WHERE uid = ? OR pkg = ? return 0; }