future where support
	
		
			
	
		
	
	
		
	
		
			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:
		| @@ -268,40 +268,52 @@ struct comp_t final { | ||||
|   db::db_types_t data; | ||||
| }; | ||||
|  | ||||
| template <typename c_t, typename w_t, typename wn_t> struct next_t final { | ||||
| template <typename cn_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 { | ||||
|   [[nodiscard]] auto column(std::string column_name) -> cn_t { | ||||
|     return next.column(column_name); | ||||
|   } | ||||
|  | ||||
|   [[nodiscard]] auto dump() const -> std::string { return parent.dump(); } | ||||
|   [[nodiscard]] auto dump(std::int64_t &idx) const -> std::string { | ||||
|     return parent.dump(idx); | ||||
|   } | ||||
|  | ||||
|   [[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 { | ||||
| template <typename cn_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>; | ||||
|   using n_t = next_t<cn_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 and_() -> n_t & { | ||||
|     owner.actions.emplace_back(n_t{ | ||||
|         "AND", | ||||
|         parent, | ||||
|     }); | ||||
|  | ||||
|     return std::get<n_t>(*std::prev(owner.actions.end())); | ||||
|   } | ||||
|  | ||||
|   [[nodiscard]] auto dump() const -> std::string { return parent.dump(); } | ||||
|   [[nodiscard]] auto dump(std::int64_t &idx) const -> std::string { | ||||
|     return parent.dump(idx); | ||||
|   } | ||||
|  | ||||
|   [[nodiscard]] auto or_() -> next_t { | ||||
|     owner.actions.emplace_back(next_t{"OR", parent}); | ||||
|     return std::get<next_t>(*std::prev(owner.actions.end())); | ||||
|   [[nodiscard]] auto or_() -> n_t & { | ||||
|     owner.actions.emplace_back(n_t{ | ||||
|         "OR", | ||||
|         parent, | ||||
|     }); | ||||
|  | ||||
|     return std::get<n_t>(*std::prev(owner.actions.end())); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| @@ -310,56 +322,50 @@ template <typename w_t> struct comp_next_t final { | ||||
|   w_t &parent; | ||||
|   std::string column_name; | ||||
|  | ||||
|   using where_next_t = where_next_t<comp_next_t, w_t>; | ||||
|   using wn_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 create(std::string operation, db::db_types_t value) { | ||||
|     owner.actions.emplace_back(comp_t{ | ||||
|         column_name, | ||||
|         operation, | ||||
|         value, | ||||
|     }); | ||||
|  | ||||
|     return wn_t{ | ||||
|         owner, | ||||
|         parent, | ||||
|     }; | ||||
|   } | ||||
|  | ||||
|   [[nodiscard]] auto equals(db::db_types_t value) -> where_next_t { | ||||
|     return create("=", value); | ||||
|   }; | ||||
|   auto equals(db::db_types_t value) -> wn_t { return create("=", value); }; | ||||
|  | ||||
|   [[nodiscard]] auto gt(db::db_types_t value) -> where_next_t { | ||||
|     return create(">", value); | ||||
|   } | ||||
|   auto gt(db::db_types_t value) -> wn_t { return create(">", value); } | ||||
|  | ||||
|   [[nodiscard]] auto gte(db::db_types_t value) -> where_next_t { | ||||
|     return create(">=", value); | ||||
|   } | ||||
|   auto gte(db::db_types_t value) -> wn_t { return create(">=", value); } | ||||
|  | ||||
|   [[nodiscard]] auto like(db::db_types_t value) -> where_next_t { | ||||
|     return create("LIKE", value); | ||||
|   } | ||||
|   auto like(db::db_types_t value) -> wn_t { return create("LIKE", value); } | ||||
|  | ||||
|   [[nodiscard]] auto lt(db::db_types_t value) -> where_next_t { | ||||
|     return create("<", value); | ||||
|   } | ||||
|   auto lt(db::db_types_t value) -> wn_t { return create("<", value); } | ||||
|  | ||||
|   [[nodiscard]] auto lte(db::db_types_t value) -> where_next_t { | ||||
|     return create("<=", value); | ||||
|   } | ||||
|   auto lte(db::db_types_t value) -> wn_t { return create("<=", value); } | ||||
|  | ||||
|   [[nodiscard]] auto not_equals(db::db_types_t value) -> where_next_t { | ||||
|     return create("!=", value); | ||||
|   }; | ||||
|   auto not_equals(db::db_types_t value) -> wn_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 cn_t = comp_next_t<where_t>; | ||||
|   using wn_t = where_next_t<cn_t, where_t>; | ||||
|   using n_t = next_t<cn_t, where_t, wn_t>; | ||||
|  | ||||
|   using group_func_t = std::function<void(where_t &)>; | ||||
|  | ||||
|   using action_t = std::variant<comp_t, next_t, where_t>; | ||||
|   using action_t = std::variant<comp_t, n_t, where_t>; | ||||
|  | ||||
|   std::vector<action_t> actions{}; | ||||
|  | ||||
|   [[nodiscard]] auto column(std::string column_name) -> comp_next_t { | ||||
|   [[nodiscard]] auto column(std::string column_name) -> cn_t { | ||||
|     return comp_next_t{ | ||||
|         *this, | ||||
|         *parent, | ||||
| @@ -367,53 +373,65 @@ struct where_t final { | ||||
|     }; | ||||
|   } | ||||
|  | ||||
|   [[nodiscard]] auto dump() const -> std::string { | ||||
|     std::stringstream ss; | ||||
|     ss << '('; | ||||
|     for (auto &&action : actions) { | ||||
|   [[nodiscard]] static auto dump(std::int64_t &idx, | ||||
|                                  auto &&data) -> std::string { | ||||
|     std::stringstream stream; | ||||
|  | ||||
|     for (auto &&action : data.actions) { | ||||
|       std::visit(overloaded{ | ||||
|                      [&ss](const comp_t &comp) { | ||||
|                        ss << comp.column_name << comp.comparison << '?'; | ||||
|                      [&idx, &stream](const comp_t &comp) { | ||||
|                        stream << comp.column_name << comp.comparison | ||||
|                               << '?' + std::to_string(++idx); | ||||
|                      }, | ||||
|                      [&ss](const next_t &next) { | ||||
|                        ss << ' ' << next.action << ' ' << next.next.dump(); | ||||
|                      [&idx, &stream](const n_t &next) { | ||||
|                        stream << ' ' << next.action << ' ' | ||||
|                               << dump(idx, next.next); | ||||
|                      }, | ||||
|                      [&idx, &stream](const where_t &where) { | ||||
|                        stream << '(' << dump(idx, where) << ')'; | ||||
|                      }, | ||||
|                      [&ss](const where_t &where) { ss << where.dump(); }, | ||||
|                  }, | ||||
|                  action); | ||||
|     } | ||||
|     ss << ')'; | ||||
|  | ||||
|     return ss.str(); | ||||
|     return stream.str(); | ||||
|   } | ||||
|  | ||||
|   [[nodiscard]] auto group(group_func_t func) -> where_next_t { | ||||
|   [[nodiscard]] auto dump(std::int64_t &idx) const -> std::string { | ||||
|     return dump(idx, *this); | ||||
|   } | ||||
|  | ||||
|   [[nodiscard]] auto group(group_func_t func) -> wn_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())), | ||||
|     actions.emplace_back(std::move(where)); | ||||
|     return wn_t{ | ||||
|         *this, | ||||
|         *parent, | ||||
|     }; | ||||
|   } | ||||
| }; | ||||
|  | ||||
| TEST(database, groups) { | ||||
|   // "(s=a and r=t)" | ||||
|   // "s=a and r=t" | ||||
|   std::int64_t idx{0U}; | ||||
|   auto str = | ||||
|       where_t().column("s").equals("a").and_().column("r").equals("t").dump(); | ||||
|       where_t().column("s").equals("a").and_().column("r").equals("t").dump( | ||||
|           idx); | ||||
|   std::cout << str << std::endl; | ||||
|  | ||||
|   // "(s=a and r=t) OR (s=c or s=x)" | ||||
|   idx = 0U; | ||||
|   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(idx); | ||||
|   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 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user