76 std::ostringstream oss;
78 joins_.push_back(oss.str());
93 std::ostringstream oss;
153 std::ostringstream oss;
162 if (i > 0) oss <<
", ";
177 for (
const auto& pair : first_row) {
178 if (!first) oss <<
", ";
184 if (i > 0) oss <<
", ";
186 bool first_val =
true;
188 if (!first_val) oss <<
", ";
198 if (!first) oss <<
", ";
205 if (!first) oss <<
", ";
218 if (!first) oss <<
", ";
230 throw std::runtime_error(
"Invalid query type");
234 for (
const auto& join :
joins_) {
242 if (i > 0) oss <<
" AND ";
251 if (i > 0) oss <<
", ";
265 if (i > 0) oss <<
", ";
307 return "\"" + identifier +
"\"";
309 return "[" + identifier +
"]";
317 std::ostringstream oss;
318 std::visit([&oss](
const auto& val) {
319 using T = std::decay_t<
decltype(val)>;
320 if constexpr (std::is_same_v<T, std::string>) {
323 escaped.reserve(val.size() + 10);
331 oss <<
"'" << escaped <<
"'";
332 }
else if constexpr (std::is_same_v<T, int64_t>) {
334 }
else if constexpr (std::is_same_v<T, double>) {
336 }
else if constexpr (std::is_same_v<T, bool>) {
337 oss << (val ?
"TRUE" :
"FALSE");
338 }
else if constexpr (std::is_same_v<T, std::monostate> || std::is_same_v<T, std::nullptr_t>) {
353 default:
return "INNER";
359 mongodb_dialect::mongodb_dialect()
360 : op_type_(operation_type::
none)
366 void mongodb_dialect::set_query_type(query_type type)
369 case query_type::select:
370 op_type_ = operation_type::find;
372 case query_type::insert:
373 op_type_ = operation_type::insert;
375 case query_type::update:
376 op_type_ = operation_type::update;
378 case query_type::delete_query:
379 op_type_ = operation_type::delete_op;
382 op_type_ = operation_type::none;
390 case operation_type::find:
391 return query_type::select;
392 case operation_type::insert:
393 return query_type::insert;
394 case operation_type::update:
395 return query_type::update;
396 case operation_type::delete_op:
397 return query_type::delete_query;
399 return query_type::none;
403 void mongodb_dialect::set_select_columns(
const std::vector<std::string>& columns)
405 op_type_ = operation_type::find;
407 for (
const auto& field : columns) {
412 void mongodb_dialect::set_from_table(
const std::string& table)
414 collection_name_ = table;
417 void mongodb_dialect::add_where_condition(
const query_condition& )
422 void mongodb_dialect::add_where_condition(
const std::string& field,
const std::string& op,
const core::database_value& value)
425 filter_[field] = value;
429 filter_[field] = value;
433 void mongodb_dialect::add_join(
const std::string& ,
const std::string& ,
join_type )
439 void mongodb_dialect::set_group_by(
const std::vector<std::string>& )
442 op_type_ = operation_type::aggregate;
445 void mongodb_dialect::set_having(
const std::string& )
450 void mongodb_dialect::add_order_by(
const std::string& column,
sort_order order)
455 void mongodb_dialect::set_limit(
size_t count)
457 limit_count_ = count;
460 void mongodb_dialect::set_offset(
size_t count)
465 void mongodb_dialect::set_insert_table(
const std::string& table)
467 op_type_ = operation_type::insert;
468 collection_name_ = table;
471 void mongodb_dialect::set_insert_data(
const std::map<std::string, core::database_value>& data)
473 op_type_ = operation_type::insert;
477 void mongodb_dialect::set_insert_rows(
const std::vector<std::map<std::string, core::database_value>>& rows)
479 op_type_ = operation_type::insert;
483 void mongodb_dialect::set_update_table(
const std::string& table)
485 op_type_ = operation_type::update;
486 collection_name_ = table;
489 void mongodb_dialect::set_update_data(
const std::map<std::string, core::database_value>& data)
491 op_type_ = operation_type::update;
495 void mongodb_dialect::set_delete_table(
const std::string& table)
497 op_type_ = operation_type::delete_op;
498 collection_name_ = table;
501 void mongodb_dialect::set_collection(
const std::string& name)
503 collection_name_ = name;
506 void mongodb_dialect::set_key(
const std::string& )
511 std::string mongodb_dialect::build()
const
513 std::ostringstream oss;
516 case operation_type::find:
517 oss <<
"db." << collection_name_ <<
".find(";
518 oss << to_json(filter_);
519 if (!projection_.empty()) {
520 oss <<
", " << to_json(projection_);
523 if (!sort_spec_.empty()) {
526 for (
const auto& pair : sort_spec_) {
527 if (!first) oss <<
", ";
528 oss <<
"\"" << pair.first <<
"\": " << pair.second;
533 if (skip_count_ > 0) {
534 oss <<
".skip(" << skip_count_ <<
")";
536 if (limit_count_ > 0) {
537 oss <<
".limit(" << limit_count_ <<
")";
541 case operation_type::insert:
542 if (documents_.empty()) {
543 oss <<
"db." << collection_name_ <<
".insertOne(" << to_json(document_) <<
")";
545 oss <<
"db." << collection_name_ <<
".insertMany([";
546 for (
size_t i = 0; i < documents_.size(); ++i) {
547 if (i > 0) oss <<
", ";
548 oss << to_json(documents_[i]);
554 case operation_type::update:
555 oss <<
"db." << collection_name_ <<
".updateOne(";
556 oss << to_json(filter_) <<
", { \"$set\": " << to_json(update_spec_) <<
" })";
559 case operation_type::delete_op:
560 if (limit_count_ == 1) {
561 oss <<
"db." << collection_name_ <<
".deleteOne(" << to_json(filter_) <<
")";
563 oss <<
"db." << collection_name_ <<
".deleteMany(" << to_json(filter_) <<
")";
567 case operation_type::aggregate:
568 oss <<
"db." << collection_name_ <<
".aggregate([";
569 for (
size_t i = 0; i < pipeline_.size(); ++i) {
570 if (i > 0) oss <<
", ";
571 oss << to_json(pipeline_[i]);
577 throw std::runtime_error(
"Invalid MongoDB operation type");
583 void mongodb_dialect::reset()
585 op_type_ = operation_type::none;
586 collection_name_.clear();
594 update_spec_.clear();
603 std::string mongodb_dialect::to_json(
const std::map<std::string, core::database_value>& data)
const
609 std::ostringstream oss;
612 for (
const auto& pair : data) {
613 if (!first) oss <<
", ";
614 oss <<
"\"" << pair.first <<
"\": " << value_to_json(pair.second);
623 std::ostringstream oss;
624 std::visit([&oss](
const auto& val) {
625 using T = std::decay_t<
decltype(val)>;
626 if constexpr (std::is_same_v<T, std::string>) {
627 oss <<
"\"" << val <<
"\"";
628 }
else if constexpr (std::is_same_v<T, int64_t>) {
630 }
else if constexpr (std::is_same_v<T, double>) {
632 }
else if constexpr (std::is_same_v<T, bool>) {
633 oss << (val ?
"true" :
"false");
634 }
else if constexpr (std::is_same_v<T, std::monostate> || std::is_same_v<T, std::nullptr_t>) {
644 redis_dialect::redis_dialect()
648 void redis_dialect::set_query_type(query_type )
655 return query_type::none;
658 void redis_dialect::set_select_columns(
const std::vector<std::string>& )
663 void redis_dialect::set_from_table(
const std::string& )
668 void redis_dialect::add_where_condition(
const query_condition& )
673 void redis_dialect::add_where_condition(
const std::string& ,
const std::string& ,
const core::database_value& )
678 void redis_dialect::add_join(
const std::string& ,
const std::string& ,
join_type )
683 void redis_dialect::set_group_by(
const std::vector<std::string>& )
688 void redis_dialect::set_having(
const std::string& )
693 void redis_dialect::add_order_by(
const std::string& ,
sort_order )
698 void redis_dialect::set_limit(
size_t )
703 void redis_dialect::set_offset(
size_t )
708 void redis_dialect::set_insert_table(
const std::string& )
713 void redis_dialect::set_insert_data(
const std::map<std::string, core::database_value>& data)
719 args_.push_back(key_);
720 for (
const auto& pair : data) {
721 args_.push_back(pair.first);
722 std::visit([
this](
const auto& val) {
723 using T = std::decay_t<
decltype(val)>;
724 if constexpr (std::is_same_v<T, std::string>) {
725 args_.push_back(val);
726 }
else if constexpr (std::is_same_v<T, int64_t>) {
727 args_.push_back(std::to_string(val));
728 }
else if constexpr (std::is_same_v<T, double>) {
729 args_.push_back(std::to_string(val));
730 }
else if constexpr (std::is_same_v<T, bool>) {
731 args_.push_back(val ?
"1" :
"0");
740 void redis_dialect::set_insert_rows(
const std::vector<std::map<std::string, core::database_value>>& )
745 void redis_dialect::set_update_table(
const std::string& )
750 void redis_dialect::set_update_data(
const std::map<std::string, core::database_value>& data)
752 set_insert_data(data);
755 void redis_dialect::set_delete_table(
const std::string& )
759 args_.push_back(key_);
762 void redis_dialect::set_collection(
const std::string& )
767 void redis_dialect::set_key(
const std::string& key)
772 args_.push_back(key);
775 std::string redis_dialect::build()
const
777 std::ostringstream oss;
779 for (
const auto& arg : args_) {
785 void redis_dialect::reset()
798 std::vector<std::string> redis_dialect::build_args()
const
800 std::vector<std::string> result;
801 result.push_back(command_);
802 result.insert(result.end(), args_.begin(), args_.end());