5#ifndef ANNADB_DRIVER_QUERY_HPP
6#define ANNADB_DRIVER_QUERY_HPP
12#include "query_comparision.hpp"
32 virtual std::string data()
const = 0;
46 explicit Asc(std::string_view field) noexcept : field_(field) {}
48 [[nodiscard]] std::string data()
const override
50 return "asc(value|" + field_ +
"|)";
65 explicit Desc(std::string_view field) noexcept : field_(field) {}
67 [[nodiscard]] std::string data()
const override
69 return "desc(value|" + field_ +
"|)";
78 bool start_cmd_ =
false;
79 [[nodiscard]]
virtual std::string annadb_query() = 0;
80 [[nodiscard]]
virtual std::vector<std::string> previous_steps_() = 0;
81 [[nodiscard]]
virtual std::vector<std::string> next_steps_() = 0;
85 explicit QueryCmd(std::string_view name,
bool start_cmd) : name_(name), start_cmd_(start_cmd) {}
88 [[nodiscard]] std::string name()
noexcept
93 [[nodiscard]]
bool can_start_pipeline()
const noexcept
98 [[nodiscard]]
virtual std::string query()
noexcept
100 return this->annadb_query();
103 [[nodiscard]]
bool next_step_allowed(
const std::string &cmdName)
noexcept
105 if (next_steps_().empty())
110 auto res = std::find(next_steps_().begin(), next_steps_().end(), cmdName);
111 return res != next_steps_().end();
114 [[nodiscard]]
bool previous_step_allowed(
const std::string &cmdName)
noexcept
116 if (previous_steps_().empty())
121 auto res = std::find(previous_steps_().begin(), previous_steps_().end(), cmdName);
122 return res != next_steps_().end();
129 std::vector<tyson::TySonObject> values_;
131 std::string annadb_query()
override
133 std::stringstream sstream;
134 sstream <<
"insert[";
135 std::for_each(values_.begin(), values_.end(),
136 [&sstream](
auto &val){ sstream << val <<
",";});
138 return sstream.str();
141 [[nodiscard]] std::vector<std::string> previous_steps_()
noexcept override
145 [[nodiscard]] std::vector<std::string> next_steps_()
noexcept override
160 values_.emplace_back(std::move(obj));
163 template<
typename ...T>
164 explicit Insert(T&& ...values) noexcept :
QueryCmd(
"insert",
true)
166 std::vector<tyson::TySonObject> objs {};
167 objs.reserve(
sizeof...(values));
168 (objs.emplace_back(values), ...);
170 values_ = std::move(objs);
179 explicit Insert(std::vector<tyson::TySonObject> &objs) noexcept :
QueryCmd(
"insert",
true), values_(std::move(objs)) {}
186 std::vector<tyson::TySonObject> values_;
188 std::string annadb_query()
override
190 std::stringstream sstream;
192 std::for_each(values_.begin(), values_.end(),
193 [&sstream](
auto &val){ sstream << val <<
",";});
195 return sstream.str();
198 [[nodiscard]] std::vector<std::string> previous_steps_()
noexcept override
200 return {
"find",
"get",
"sort",
"limit",
"offset"};
202 [[nodiscard]] std::vector<std::string> next_steps_()
noexcept override
204 return {
"find",
"get",
"sort",
"limit",
"offset",
"update",
"delete"};
219 if (obj.
type() != tyson::TySonType::Link)
221 throw std::invalid_argument(
".get can only be used with a TySonObject of TySonType::Link.");
224 values_.emplace_back(obj);
235 Get(std::vector<tyson::TySonObject> &objs) :
QueryCmd(
"get", true)
237 auto all_Links = std::all_of(objs.cbegin(), objs.cend(), [](
const tyson::TySonObject val)
239 return val.type() == tyson::TySonType::Link;
244 throw std::invalid_argument(
".get can only be used with a TySonObject of TySonType::Link.");
247 values_ = std::move(objs);
250 template<
typename ...T>
251 explicit Get(T &&...values) :
QueryCmd(
"get", true)
253 std::vector<tyson::TySonObject> objs {};
254 objs.reserve(
sizeof...(values));
255 (objs.emplace_back(values), ...);
257 auto all_Links = std::all_of(objs.cbegin(), objs.cend(), [](
const tyson::TySonObject val)
259 return val.type() == tyson::TySonType::Link;
264 throw std::invalid_argument(
".get can only be used with a TySonObject of TySonType::Link.");
267 values_ = std::move(objs);
274 std::vector<std::unique_ptr<Comparison>> comparators_;
275 std::string annadb_query()
override
277 std::stringstream sstream;
279 for (
auto &val : comparators_)
281 sstream << val->str() <<
",";
284 return sstream.str();
287 [[nodiscard]] std::vector<std::string> previous_steps_()
noexcept override
289 return {
"find",
"get",
"sort",
"limit",
"offset"};
291 [[nodiscard]] std::vector<std::string> next_steps_()
noexcept override
293 return {
"find",
"get",
"sort",
"limit",
"offset",
"update",
"delete"};
302 comparators_.emplace_back(std::make_unique<Eq>(value));
308 comparators_.emplace_back(std::make_unique<Eq>(path_to_field, value));
327 comparators_.emplace_back(std::make_unique<Neq>(value));
333 comparators_.emplace_back(std::make_unique<Neq>(path_to_field, value));
350 template<std::convertible_to<tyson::TySonObject> T>
351 Find& gt(T &&value)
noexcept
353 comparators_.emplace_back(std::make_unique<Gt>(std::forward<tyson::TySonObject>(value)));
359 comparators_.emplace_back(std::make_unique<Gt>(value));
363 template<std::convertible_to<tyson::TySonObject> T>
364 Find& gt(std::string_view path_to_field, T &&value)
noexcept
366 comparators_.emplace_back(std::make_unique<Gt>(path_to_field, std::forward<tyson::TySonObject>(value)));
372 comparators_.emplace_back(std::make_unique<Gt>(path_to_field, value));
382 template<std::convertible_to<tyson::TySonObject> T>
390 template<std::convertible_to<tyson::TySonObject> T>
391 Find& gte(T &&value)
noexcept
393 comparators_.emplace_back(std::make_unique<Gte>(std::forward<tyson::TySonObject>(value)));
397 template<std::convertible_to<tyson::TySonObject> T>
398 Find& gte(std::string_view path_to_field, T &&value)
noexcept
400 comparators_.emplace_back(std::make_unique<Gte>(path_to_field, std::forward<tyson::TySonObject>(value)));
410 template<std::convertible_to<tyson::TySonObject> T>
414 find.gte(std::forward<tyson::TySonObject>(value));
418 template<std::convertible_to<tyson::TySonObject> T>
419 Find& lt(T value)
noexcept
421 comparators_.emplace_back(std::make_unique<Lt>(std::forward<tyson::TySonObject>(value)));
425 template<std::convertible_to<tyson::TySonObject> T>
426 Find& lt(std::string_view path_to_field, T value)
noexcept
428 comparators_.emplace_back(std::make_unique<Lt>(path_to_field, std::forward<tyson::TySonObject>(value)));
438 template<std::convertible_to<tyson::TySonObject> T>
442 find.lt(std::forward<tyson::TySonObject>(value));
446 template<std::convertible_to<tyson::TySonObject> T>
447 Find& lte(T value)
noexcept
449 comparators_.emplace_back(std::make_unique<Lte>(std::forward<tyson::TySonObject>(value)));
453 template<std::convertible_to<tyson::TySonObject> T>
454 Find& lte(std::string_view path_to_field, T value)
noexcept
456 comparators_.emplace_back(std::make_unique<Lte>(path_to_field, std::forward<tyson::TySonObject>(value)));
475 comparators_.emplace_back(std::make_unique<And>(value));
486 template<std::convertible_to<Comparison> ...Comps>
489 And and_ {comps ...};
495 Find& q(
Or &value)
noexcept
497 comparators_.emplace_back(std::make_unique<Or>(value));
507 template<std::convertible_to<Comparison> ...Comps>
518 comparators_.emplace_back(std::make_unique<Not>(value));
528 static Find NOT(std::string_view field)
noexcept
541 std::vector<std::unique_ptr<annadb::Query::SortCmd>> cmds_ {};
543 std::string annadb_query()
override
545 std::string query =
"sort[";
546 std::for_each(cmds_.begin(), cmds_.end(), [&query](std::unique_ptr<annadb::Query::SortCmd> &val)
548 query += val->data() +
",";
555 [[nodiscard]] std::vector<std::string> previous_steps_()
noexcept override
557 return {
"find",
"get",
"sort",
"limit",
"offset"};
559 [[nodiscard]] std::vector<std::string> next_steps_()
noexcept override
561 return {
"find",
"get",
"sort",
"limit",
"offset",
"update",
"delete"};
565 explicit Sort(std::vector<std::unique_ptr<annadb::Query::SortCmd>> &&cmds) noexcept :
QueryCmd(
"sort",
false), cmds_(std::move(cmds)) {}
567 template<std::convertible_to<std::
string> ...T>
568 static Sort ASC(T&& ...fields)
noexcept
570 std::vector<std::unique_ptr<annadb::Query::SortCmd>> cmds {};
571 cmds.reserve(
sizeof...(fields));
577 return Sort(std::move(cmds));
580 template<std::convertible_to<std::
string> ...T>
581 static Sort DESC(T&& ...fields)
noexcept
583 std::vector<std::unique_ptr<annadb::Query::SortCmd>> cmds = {};
590 return Sort(std::move(cmds));
598 std::string annadb_query()
override
600 return "limit(n|" + data_ +
"|)";
603 [[nodiscard]] std::vector<std::string> previous_steps_()
noexcept override
605 return {
"find",
"get",
"sort",
"limit",
"offset"};
607 [[nodiscard]] std::vector<std::string> next_steps_()
noexcept override
609 return {
"find",
"get",
"sort",
"limit",
"offset",
"update",
"delete"};
615 explicit Limit(
short data) :
QueryCmd(
"limit",
false), data_(std::to_string(data)) {}
616 explicit Limit(
unsigned short data) :
QueryCmd(
"limit",
false), data_(std::to_string(data)) {}
617 explicit Limit(
int data) :
QueryCmd(
"limit",
false), data_(std::to_string(data)) {}
618 explicit Limit(
unsigned int data) :
QueryCmd(
"limit",
false), data_(std::to_string(data)) {}
619 explicit Limit(
long data) :
QueryCmd(
"limit",
false), data_(std::to_string(data)) {}
620 explicit Limit(
unsigned long data) :
QueryCmd(
"limit",
false), data_(std::to_string(data)) {}
621 explicit Limit(
long long data) :
QueryCmd(
"limit",
false), data_(std::to_string(data)) {}
622 explicit Limit(
unsigned long long data) :
QueryCmd(
"limit",
false), data_(std::to_string(data)) {}
631 std::string annadb_query()
override
633 return "offset(n|" + data_ +
"|)";
636 [[nodiscard]] std::vector<std::string> previous_steps_()
noexcept override
638 return {
"find",
"get",
"sort",
"limit",
"offset"};
640 [[nodiscard]] std::vector<std::string> next_steps_()
noexcept override
642 return {
"find",
"get",
"sort",
"limit",
"offset",
"update",
"delete"};
648 explicit Offset(
short data) :
QueryCmd(
"offset",
false), data_(std::to_string(data)) {}
649 explicit Offset(
unsigned short data) :
QueryCmd(
"offset",
false), data_(std::to_string(data)) {}
650 explicit Offset(
int data) :
QueryCmd(
"offset",
false), data_(std::to_string(data)) {}
651 explicit Offset(
unsigned int data) :
QueryCmd(
"offset",
false), data_(std::to_string(data)) {}
652 explicit Offset(
long data) :
QueryCmd(
"offset",
false), data_(std::to_string(data)) {}
653 explicit Offset(
unsigned long data) :
QueryCmd(
"offset",
false), data_(std::to_string(data)) {}
654 explicit Offset(
long long data) :
QueryCmd(
"offset",
false), data_(std::to_string(data)) {}
655 explicit Offset(
unsigned long long data) :
QueryCmd(
"offset",
false), data_(std::to_string(data)) {}
662 std::vector<std::tuple<UpdateType, tyson::TySonObject>> values_ {};
664 std::string annadb_query()
override
666 std::stringstream sstream;
667 sstream <<
"update[";
668 for (
auto &val : values_)
670 auto type = std::get<0>(val);
671 auto obj = std::get<1>(val);
673 if (type == UpdateType::Set)
675 sstream <<
"set{" << obj <<
"},";
679 sstream <<
"inc{" << obj <<
"},";
685 return sstream.str();
688 [[nodiscard]] std::vector<std::string> previous_steps_()
noexcept override
690 return {
"find",
"get",
"sort",
"limit",
"offset"};
692 [[nodiscard]] std::vector<std::string> next_steps_()
noexcept override
701 values_.emplace_back(type, val);
705 std::for_each(values.begin(), values.end(),
706 [
this, &type](
auto val)
708 this->values_.emplace_back(type, val);
711 Update(std::vector<std::tuple<UpdateType, tyson::TySonObject>> &&values) noexcept :
QueryCmd(
"update",
false), values_(values) {}
717 std::string annadb_query()
override
722 [[nodiscard]] std::vector<std::string> previous_steps_()
noexcept override
724 return {
"find",
"get",
"sort",
"limit",
"offset"};
726 [[nodiscard]] std::vector<std::string> next_steps_()
noexcept override
738 std::vector<std::pair<std::string, tyson::TySonObject>> values_;
740 std::string annadb_query()
override
742 std::stringstream sstream;
743 sstream <<
"project{";
744 std::for_each(values_.begin(), values_.end(),
745 [&sstream](
auto &val)
747 sstream <<
"s|" <<std::get<0>(val) <<
"|:" << std::get<1>(val) <<
",";
750 return sstream.str();
753 [[nodiscard]] std::vector<std::string> previous_steps_()
noexcept override
755 return {
"get",
"find",
"sort",
"limit",
"offset"};
758 [[nodiscard]] std::vector<std::string> next_steps_()
noexcept override
765 template<std::convertible_to<std::pair<std::
string, tyson::TySonObject>> ...T>
766 explicit Project(T && ... objs)
768 values_.reserve(
sizeof...(objs));
769 (values_.emplace_back(objs), ...);
776 std::string collection_name_;
777 std::vector<std::unique_ptr<annadb::Query::QueryCmd>> cmds_ {};
778 void add_to_cmds(std::unique_ptr<QueryCmd> queryCmd)
780 if (cmds_.empty() && !queryCmd->can_start_pipeline())
782 throw std::invalid_argument(queryCmd->name() +
" can not be used to start a new query pipeline.");
787 this->cmds_.emplace_back(std::move(queryCmd));
791 auto latest_cmd = cmds_.size() - 1;
792 if (cmds_.at(latest_cmd)->next_step_allowed(queryCmd->name()) &&
793 queryCmd->previous_step_allowed(cmds_.at(latest_cmd)->name()))
795 this->cmds_.emplace_back(std::move(queryCmd));
799 throw std::invalid_argument(queryCmd->name() +
" can not be used before/after " + cmds_.at(latest_cmd)->name());
804 friend std::ostream& operator<<(std::ostream &out,
Query &query)
noexcept
806 std::stringstream sstream;
807 sstream <<
"collection|" << query.collection_name_ <<
"|";
809 if (query.cmds_.size() == 1)
811 sstream <<
":" << query.cmds_[0]->query() <<
";";
816 for (
auto &cmd: query.cmds_)
818 sstream << cmd->query() <<
",";
822 return out << sstream.str();
831 explicit Query(std::string collection_name) : collection_name_(std::move(collection_name)) {};
841 this->add_to_cmds(std::make_unique<Insert>(std::move(
insert)));
851 this->add_to_cmds(std::make_unique<Insert>(
insert));
861 this->add_to_cmds(std::make_unique<Insert>(
insert));
869 template<
typename ...T>
872 this->add_to_cmds(std::make_unique<Insert>(
insert...));
883 this->add_to_cmds(std::make_unique<Get>(std::move(
get)));
895 this->add_to_cmds(std::make_unique<Get>(
get));
907 this->add_to_cmds(std::make_unique<Get>(
get));
917 template<std::convertible_to<tyson::TySonObject> ...T>
920 this->add_to_cmds(std::make_unique<Get>(values...));
932 this->add_to_cmds(std::make_unique<Find>(std::move(
find)));
944 this->add_to_cmds(std::make_unique<Sort>(std::move(
sort)));
956 this->add_to_cmds(std::make_unique<Limit>(std::move(
limit)));
968 requires std::is_integral_v<T>
971 this->add_to_cmds(std::make_unique<Limit>(
limit));
983 this->add_to_cmds(std::make_unique<Offset>(
offset));
995 requires std::is_integral_v<T>
998 this->add_to_cmds(std::make_unique<Offset>(
offset));
1010 if (value.
type() == tyson::TySonType::Value)
1012 this->add_to_cmds(std::make_unique<Update>(value, kind));
1016 throw std::invalid_argument(
"Only `tyson::TySonType::Value` are allowed.");
1028 if (std::all_of(values.begin(), values.end(),
1029 [](
const auto &val){ return val.type() == tyson::TySonType::Value;}))
1031 this->add_to_cmds(std::make_unique<Update>(values, kind));
1035 throw std::invalid_argument(
"Only `tyson::TySonType::Values` are allowed.");
1039 template<std::convertible_to<tyson::TySonObject> ...T>
1042 std::vector<tyson::TySonObject> objects {};
1043 objects.reserve(
sizeof...(values));
1044 (objects.emplace_back(values), ...);
1046 if (std::all_of(objects.begin(), objects.end(),
1047 [](
const auto &val){ return val.type() == tyson::TySonType::Value;}))
1049 this->add_to_cmds(std::make_unique<Update>(objects, kind));
1053 throw std::invalid_argument(
"Only `tyson::TySonType::Values` are allowed.");
1064 void update(std::vector<std::tuple<UpdateType, tyson::TySonObject>> &values)
1066 if (std::all_of(values.begin(), values.end(),
1067 [](
const auto &val){ return std::get<1>(val).type() == tyson::TySonType::Value;}))
1069 this->add_to_cmds(std::make_unique<Update>(std::move(values)));
1073 throw std::invalid_argument(
"Only `tyson::TySonType::Values` are allowed.");
1083 this->add_to_cmds(std::make_unique<Delete>(
Delete()));
1093 template<std::convertible_to<std::pair<std::
string, tyson::TySonObject>> ...T>
1096 this->add_to_cmds(std::make_unique<Project>(values...));
Definition: query_comparision.hpp:231
Asc(std::string_view field) noexcept
Definition: query.hpp:46
Definition: query.hpp:716
Desc(std::string_view field) noexcept
Definition: query.hpp:65
Definition: query.hpp:273
static Find AND(Comps ...comps) noexcept
Definition: query.hpp:487
static Find GTE(T value) noexcept
Definition: query.hpp:411
static Find OR(Comps ...comps) noexcept
Definition: query.hpp:508
static Find LTE(tyson::TySonObject &value) noexcept
Definition: query.hpp:466
static Find GT(T &&value) noexcept
Definition: query.hpp:383
static Find NEQ(tyson::TySonObject &value) noexcept
Definition: query.hpp:343
static Find LT(T value) noexcept
Definition: query.hpp:439
static Find EQ(tyson::TySonObject &value) noexcept
Definition: query.hpp:318
static Find NOT(std::string_view field) noexcept
Definition: query.hpp:528
Definition: query.hpp:185
Get(tyson::TySonObject &obj)
Definition: query.hpp:217
Get(std::vector< tyson::TySonObject > &objs)
Definition: query.hpp:235
Definition: query.hpp:128
Insert(std::vector< tyson::TySonObject > &objs) noexcept
Definition: query.hpp:179
Insert(tyson::TySonObject &obj) noexcept
Definition: query.hpp:158
Definition: query.hpp:596
Definition: query_comparision.hpp:291
Definition: query.hpp:628
Definition: query_comparision.hpp:261
Definition: query.hpp:737
Definition: query.hpp:775
void update(UpdateType &&kind, tyson::TySonObject &value)
Definition: query.hpp:1008
void delete_q() noexcept
Definition: query.hpp:1081
void insert(std::vector< tyson::TySonObject > &insert) noexcept
Definition: query.hpp:859
Query & find(Find &&find) noexcept
Definition: query.hpp:930
Query & offset(T &&offset) noexcept
Definition: query.hpp:996
void update(std::vector< std::tuple< UpdateType, tyson::TySonObject > > &values)
Definition: query.hpp:1064
Query & get(tyson::TySonObject &get) noexcept
Definition: query.hpp:893
Query & get(std::vector< tyson::TySonObject > &get) noexcept
Definition: query.hpp:905
void insert(Insert &insert) noexcept
Definition: query.hpp:839
Query(std::string collection_name)
Definition: query.hpp:831
Query & get(Get &get) noexcept
Definition: query.hpp:881
Query & offset(Offset &offset) noexcept
Definition: query.hpp:981
Query & project(T &&...values) noexcept
Definition: query.hpp:1094
void insert(tyson::TySonObject &insert) noexcept
Definition: query.hpp:849
Query & limit(Limit &limit) noexcept
Definition: query.hpp:954
void update(UpdateType &kind, std::vector< tyson::TySonObject > &values)
Definition: query.hpp:1026
Query & limit(T &&limit) noexcept
Definition: query.hpp:969
Query & get(T &&...values) noexcept
Definition: query.hpp:918
Query & sort(Sort &&sort) noexcept
Definition: query.hpp:942
void insert(T &&...insert) noexcept
Definition: query.hpp:870
Definition: query.hpp:540
Definition: query.hpp:661
TySonType type() const noexcept
Definition: TySON.hpp:576
UpdateType
Definition: query.hpp:24