Support multiple condition on where clause ref/drafts/tizen
authorsangwan.kwon <sangwan.kwon@samsung.com>
Mon, 15 Jan 2018 06:51:42 +0000 (15:51 +0900)
committersangwan.kwon <sangwan.kwon@samsung.com>
Mon, 15 Jan 2018 06:51:42 +0000 (15:51 +0900)
Change-Id: I0adc9d253389e64a4cc8679684793df444746343
Signed-off-by: sangwan.kwon <sangwan.kwon@samsung.com>
include/klay/db/query-builder/expression.hxx
include/klay/db/query-builder/table.hxx
include/klay/db/query-builder/test-main.cpp

index 2957ef8820eb989fc38d6418b0ff6d5cde5375ac..2606efd16447781721508c92ddd9f22f4cb69da9 100644 (file)
@@ -3,8 +3,34 @@
 namespace qxx {
 namespace condition {
 
-template<class L, class R>
-struct Binary {
+struct Base {};
+  
+template<typename L, typename R>
+struct And : public Base {
+       L l;
+       R r;
+
+       And(L l, R r) : l(l), r(r) {}
+       operator std::string() const
+       {
+               return "AND";
+       } 
+};
+
+template<typename L, typename R>
+struct Or : public Base {
+       L l;
+       R r;
+
+       Or(L l, R r) : l(l), r(r) {}
+       operator std::string() const
+       {
+               return "OR";
+       } 
+};
+
+template<typename L, typename R>
+struct Binary : public Base {
        L l;
        R r;
 
@@ -13,32 +39,36 @@ struct Binary {
 
 } // namespace condition
 
-template<class Type>
+template<typename Type>
 struct Expression {
        Type value;
 };
 
-template<class Type>
-Expression<Type> expr(Type value) {
+template<typename Type>
+Expression<Type> expr(Type value)
+{
        return {value};
 }
 
-template<class L, class R>
+template<typename L, typename R>
 struct Lesser : public condition::Binary<L, R> {
        using condition::Binary<L, R>::Binary;
 
-       operator std::string() const {
+       operator std::string() const
+       {
                return "<";
        }
 };
 
-template<class L, class R>
-Lesser<L, R> operator<(Expression<L> expr, R r) {
+template<typename L, typename R>
+Lesser<L, R> operator<(Expression<L> expr, R r)
+{
        return {expr.value, r};
 }
 
-template<class L, class R>
-struct Equal : public condition::Binary<L, R> {
+template<typename L, typename R>
+struct Equal : public condition::Binary<L, R>
+{
        using condition::Binary<L, R>::Binary;
 
        operator std::string() const {
@@ -46,13 +76,15 @@ struct Equal : public condition::Binary<L, R> {
        }
 };
 
-template<class L, class R>
-Equal<L, R> operator==(Expression<L> expr, R r) {
+template<typename L, typename R>
+Equal<L, R> operator==(Expression<L> expr, R r)
+{
        return {expr.value, r};
 }
 
-template<class L, class R>
-struct Greater : public condition::Binary<L, R> {
+template<typename L, typename R>
+struct Greater : public condition::Binary<L, R>
+{
        using condition::Binary<L, R>::Binary;
 
        operator std::string() const {
@@ -60,9 +92,28 @@ struct Greater : public condition::Binary<L, R> {
        }
 };
 
-template<class L, class R>
-Greater<L, R> operator>(Expression<L> expr, R r) {
+template<typename L, typename R>
+Greater<L, R> operator>(Expression<L> expr, R r)
+{
        return {expr.value, r};
 }
 
+template<typename L,
+                typename R,
+                typename = typename std::enable_if<std::is_base_of<condition::Base, L>::value
+                                                        && std::is_base_of<condition::Base, R>::value>::type>
+condition::And<L, R> operator &&(const L& l, const R& r)
+{
+       return {l, r};
+}
+
+template<typename L,
+                typename R,
+                typename = typename std::enable_if<std::is_base_of<condition::Base, L>::value
+                                                        && std::is_base_of<condition::Base, R>::value>::type>
+condition::Or<L, R> operator ||(const L& l, const R& r)
+{
+       return {l, r};
+}
+
 } // namespace qxx
index bd7cebbf236c5efbc3351bc22d498f5e52d596cf..d08f7d25692fcd506f3711ea0c076a67c27f877e 100644 (file)
@@ -3,6 +3,7 @@
 #include "column.hxx"
 #include "table-impl.hxx"
 #include "tuple-helper.hxx"
+#include "expression.hxx"
 
 #include <vector>
 #include <string>
@@ -58,6 +59,35 @@ private:
                }
        };
 
+       template<typename L, typename R>
+       std::string processWhere(condition::And<L,R>& expr) {
+               std::stringstream ss;
+               ss << this->processWhere(expr.l) << " ";
+               ss << static_cast<std::string>(expr) << " ";
+               ss << this->processWhere(expr.r);
+
+               return ss.str();
+       }
+
+       template<typename L, typename R>
+       std::string processWhere(condition::Or<L,R>& expr) {
+               std::stringstream ss;
+               ss << this->processWhere(expr.l) << " ";
+               ss << static_cast<std::string>(expr) << " ";
+               ss << this->processWhere(expr.r);
+
+               return ss.str();
+       }
+
+       template<typename Expr>
+       std::string processWhere(Expr expr) {
+               std::stringstream ss;
+               ss << this->impl.getColumnName(expr.l);
+               ss << " = ?";
+
+               return ss.str();
+       }
+
        std::string name;
        ImplType impl;
 
@@ -114,10 +144,8 @@ template<typename... Columns>
 template<typename Expr>
 Table<Columns...> Table<Columns...>::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());
 
index 1741ec4ba636104302a89309082bac655fd98b64..1b93640d4505691444c9de52f755581423eacfe2 100644 (file)
@@ -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;
 }