future where handling
	
		
			
	
		
	
	
		
	
		
			All checks were successful
		
		
	
	
		
			
				
	
				BlockStorage/repertory/pipeline/head This commit looks good
				
			
		
		
	
	
				
					
				
			
		
			All checks were successful
		
		
	
	BlockStorage/repertory/pipeline/head This commit looks good
				
			This commit is contained in:
		| @@ -27,6 +27,7 @@ | |||||||
| #include "database/db_select.hpp" | #include "database/db_select.hpp" | ||||||
| #include "database/db_update.hpp" | #include "database/db_update.hpp" | ||||||
| #include "utils/path.hpp" | #include "utils/path.hpp" | ||||||
|  | #include <variant> | ||||||
|  |  | ||||||
| namespace repertory { | namespace repertory { | ||||||
| class database_test : public ::testing::Test { | class database_test : public ::testing::Test { | ||||||
| @@ -260,4 +261,159 @@ TEST_F(database_test, insert_or_replace_and_delete) { | |||||||
|  |  | ||||||
|   common_delete(*db3.get()); |   common_delete(*db3.get()); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | struct comp_t final { | ||||||
|  |   std::string column_name; | ||||||
|  |   std::string comparison; | ||||||
|  |   db::db_types_t data; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | template <typename c_t, typename w_t, typename wn_t> struct next_t final { | ||||||
|  |   std::string action; | ||||||
|  |   w_t &parent; | ||||||
|  |   w_t next{&parent}; | ||||||
|  |  | ||||||
|  |   using group_func_t = std::function<void(w_t &)>; | ||||||
|  |  | ||||||
|  |   [[nodiscard]] auto column(std::string column_name) -> c_t { | ||||||
|  |     return next.column(column_name); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   [[nodiscard]] auto dump() const -> std::string { return parent.dump(); } | ||||||
|  |  | ||||||
|  |   [[nodiscard]] auto group(group_func_t func) -> wn_t { | ||||||
|  |     return next.group(std::move(func)); | ||||||
|  |   } | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | template <typename c_t, typename w_t> struct where_next_t final { | ||||||
|  |   w_t &owner; | ||||||
|  |   w_t &parent; | ||||||
|  |  | ||||||
|  |   using next_t = next_t<c_t, w_t, where_next_t>; | ||||||
|  |  | ||||||
|  |   [[nodiscard]] auto and_() -> next_t { | ||||||
|  |     owner.actions.emplace_back(next_t{"AND", parent}); | ||||||
|  |     return std::get<next_t>(*std::prev(owner.actions.end())); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   [[nodiscard]] auto dump() const -> std::string { return parent.dump(); } | ||||||
|  |  | ||||||
|  |   [[nodiscard]] auto or_() -> next_t { | ||||||
|  |     owner.actions.emplace_back(next_t{"OR", parent}); | ||||||
|  |     return std::get<next_t>(*std::prev(owner.actions.end())); | ||||||
|  |   } | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | template <typename w_t> struct comp_next_t final { | ||||||
|  |   w_t &owner; | ||||||
|  |   w_t &parent; | ||||||
|  |   std::string column_name; | ||||||
|  |  | ||||||
|  |   using where_next_t = where_next_t<comp_next_t, w_t>; | ||||||
|  |  | ||||||
|  |   [[nodiscard]] auto create(std::string op, db::db_types_t value) { | ||||||
|  |     owner.actions.emplace_back(comp_t{column_name, op, value}); | ||||||
|  |     return where_next_t{owner, parent}; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   [[nodiscard]] auto equals(db::db_types_t value) -> where_next_t { | ||||||
|  |     return create("=", value); | ||||||
|  |   }; | ||||||
|  |  | ||||||
|  |   [[nodiscard]] auto gt(db::db_types_t value) -> where_next_t { | ||||||
|  |     return create(">", value); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   [[nodiscard]] auto gte(db::db_types_t value) -> where_next_t { | ||||||
|  |     return create(">=", value); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   [[nodiscard]] auto like(db::db_types_t value) -> where_next_t { | ||||||
|  |     return create("LIKE", value); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   [[nodiscard]] auto lt(db::db_types_t value) -> where_next_t { | ||||||
|  |     return create("<", value); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   [[nodiscard]] auto lte(db::db_types_t value) -> where_next_t { | ||||||
|  |     return create("<=", value); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   [[nodiscard]] auto not_equals(db::db_types_t value) -> where_next_t { | ||||||
|  |     return create("!=", value); | ||||||
|  |   }; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | struct where_t final { | ||||||
|  |   where_t *parent{this}; | ||||||
|  |  | ||||||
|  |   using comp_next_t = comp_next_t<where_t>; | ||||||
|  |   using where_next_t = where_next_t<comp_next_t, where_t>; | ||||||
|  |   using next_t = next_t<comp_next_t, where_t, where_next_t>; | ||||||
|  |  | ||||||
|  |   using group_func_t = std::function<void(where_t &)>; | ||||||
|  |  | ||||||
|  |   using action_t = std::variant<comp_t, next_t, where_t>; | ||||||
|  |  | ||||||
|  |   std::vector<action_t> actions{}; | ||||||
|  |  | ||||||
|  |   [[nodiscard]] auto column(std::string column_name) -> comp_next_t { | ||||||
|  |     return comp_next_t{ | ||||||
|  |         *this, | ||||||
|  |         *parent, | ||||||
|  |         column_name, | ||||||
|  |     }; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   [[nodiscard]] auto dump() const -> std::string { | ||||||
|  |     std::stringstream ss; | ||||||
|  |     ss << '('; | ||||||
|  |     for (auto &&action : actions) { | ||||||
|  |       std::visit(overloaded{ | ||||||
|  |                      [&ss](const comp_t &comp) { | ||||||
|  |                        ss << comp.column_name << comp.comparison << '?'; | ||||||
|  |                      }, | ||||||
|  |                      [&ss](const next_t &next) { | ||||||
|  |                        ss << ' ' << next.action << ' ' << next.next.dump(); | ||||||
|  |                      }, | ||||||
|  |                      [&ss](const where_t &where) { ss << where.dump(); }, | ||||||
|  |                  }, | ||||||
|  |                  action); | ||||||
|  |     } | ||||||
|  |     ss << ')'; | ||||||
|  |  | ||||||
|  |     return ss.str(); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   [[nodiscard]] auto group(group_func_t func) -> where_next_t { | ||||||
|  |     where_t where{parent}; | ||||||
|  |     func(where); | ||||||
|  |  | ||||||
|  |     actions.push_back(std::move(where)); | ||||||
|  |     return where_next_t{ | ||||||
|  |         std::get<where_t>(*std::prev(actions.end())), | ||||||
|  |         *parent, | ||||||
|  |     }; | ||||||
|  |   } | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | TEST(database, groups) { | ||||||
|  |   // "(s=a and r=t)" | ||||||
|  |   auto str = | ||||||
|  |       where_t().column("s").equals("a").and_().column("r").equals("t").dump(); | ||||||
|  |   std::cout << str << std::endl; | ||||||
|  |   // "((s=a and r=t) OR (s=c or s=x))" | ||||||
|  |   // auto str = where_t() | ||||||
|  |   //                .group([](where_t &where) { | ||||||
|  |   //                  where.column("s").equals("a").and_().column("r").equals("t"); | ||||||
|  |   //                }) | ||||||
|  |   //                .or_() | ||||||
|  |   //                .group([](where_t &where) { | ||||||
|  |   //                  where.column("s").equals("c").or_().column("s").equals("x"); | ||||||
|  |   //                }) | ||||||
|  |   //                .dump(); | ||||||
|  |   // std::cout << str << std::endl; | ||||||
|  | } | ||||||
| } // namespace repertory | } // namespace repertory | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user