292class DROGON_EXPORT SqlBinder :
public trantor::NonCopyable
294 using self = SqlBinder;
297 SqlBinder(
const std::string &sql,
DbClient &client, ClientType type)
298 : sqlPtr_(std::make_shared<std::string>(sql)),
299 sqlViewPtr_(sqlPtr_->data()),
300 sqlViewLength_(sqlPtr_->length()),
306 SqlBinder(std::string &&sql,
DbClient &client, ClientType type)
307 : sqlPtr_(std::make_shared<std::string>(std::move(sql))),
308 sqlViewPtr_(sqlPtr_->data()),
309 sqlViewLength_(sqlPtr_->length()),
315 SqlBinder(
const char *sql,
320 sqlViewLength_(sqlLength),
326 SqlBinder(SqlBinder &&that) noexcept
327 : sqlPtr_(std::move(that.sqlPtr_)),
328 sqlViewPtr_(that.sqlViewPtr_),
329 sqlViewLength_(that.sqlViewLength_),
330 client_(that.client_),
331 parametersNumber_(that.parametersNumber_),
332 parameters_(std::move(that.parameters_)),
333 lengths_(std::move(that.lengths_)),
334 formats_(std::move(that.formats_)),
335 objs_(std::move(that.objs_)),
337 callbackHolder_(std::move(that.callbackHolder_)),
338 exceptionCallback_(std::move(that.exceptionCallback_)),
339 exceptionPtrCallback_(std::move(that.exceptionPtrCallback_)),
340 execed_(that.execed_),
341 destructed_(that.destructed_),
342 isExceptionPtr_(that.isExceptionPtr_),
349 SqlBinder &operator=(SqlBinder &&that) =
delete;
352 template <
typename CallbackType,
355 self &operator>>(CallbackType &&callback)
357 if constexpr (traits::isExceptCallback)
359 if constexpr (traits::isPtr)
362 isExceptionPtr_ =
true;
363 exceptionPtrCallback_ = std::forward<CallbackType>(callback);
368 isExceptionPtr_ =
false;
369 exceptionCallback_ = std::forward<CallbackType>(callback);
373 else if constexpr (traits::isSqlCallback)
375 callbackHolder_ = std::shared_ptr<CallbackHolderBase>(
377 std::forward<CallbackType>(callback)));
382 template <
typename T>
383 self &operator<<(T &¶meter)
385 using ParaType = std::remove_cv_t<std::remove_reference_t<T>>;
387 std::shared_ptr<void> obj = std::make_shared<ParaType>(parameter);
388 if (type_ == ClientType::PostgreSQL)
393 *std::static_pointer_cast<uint16_t>(obj) =
394 htons((uint16_t)parameter);
397 *std::static_pointer_cast<uint32_t>(obj) =
398 htonl((uint32_t)parameter);
401 *std::static_pointer_cast<uint64_t>(obj) =
402 htonll((uint64_t)parameter);
408 objs_.push_back(obj);
409 parameters_.push_back((
char *)obj.get());
410 lengths_.push_back(
sizeof(T));
411 formats_.push_back(1);
413 else if (type_ == ClientType::Mysql)
415 objs_.push_back(obj);
416 parameters_.push_back((
char *)obj.get());
417 lengths_.push_back(0);
418 formats_.push_back(getMysqlType<ParaType>());
420 else if (type_ == ClientType::Sqlite3)
422 objs_.push_back(obj);
423 parameters_.push_back((
char *)obj.get());
424 lengths_.push_back(0);
428 formats_.push_back(Sqlite3TypeChar);
431 formats_.push_back(Sqlite3TypeShort);
434 formats_.push_back(Sqlite3TypeInt);
437 formats_.push_back(Sqlite3TypeInt64);
456 self &operator<<(
const char str[])
458 return operator<<(std::string(str));
461 self &operator<<(
char str[])
463 return operator<<(std::string(str));
466 self &operator<<(
const std::string_view &str);
468 self &operator<<(std::string_view &&str)
470 return operator<<((
const std::string_view &)str);
473 self &operator<<(std::string_view &str)
475 return operator<<((
const std::string_view &)str);
478 self &operator<<(
const std::string &str);
480 self &operator<<(std::string &str)
482 return operator<<((
const std::string &)str);
485 self &operator<<(std::string &&str);
487 self &operator<<(trantor::Date date)
489 return operator<<(date.toDbStringLocal());
492 self &operator<<(
const std::vector<char> &v);
494 self &operator<<(std::vector<char> &v)
496 return operator<<((
const std::vector<char> &)v);
499 self &operator<<(std::vector<char> &&v);
501 self &operator<<(
float f)
503 if (type_ == ClientType::Sqlite3)
505 return operator<<((
double)f);
507 return operator<<(std::to_string(f));
510 self &operator<<(
double f);
511 self &operator<<(std::nullptr_t);
514 self &operator<<(
const Mode &mode)
520 self &operator<<(Mode &mode)
526 self &operator<<(Mode &&mode)
532 template <
typename T>
533 self &operator<<(
const std::optional<T> ¶meter)
537 return *
this << parameter.value();
539 return *
this <<
nullptr;
542 template <
typename T>
543 self &operator<<(std::optional<T> ¶meter)
547 return *
this << parameter.value();
549 return *
this <<
nullptr;
552 template <
typename T>
553 self &operator<<(std::optional<T> &¶meter)
557 return *
this << std::move(parameter.value());
559 return *
this <<
nullptr;
562 self &operator<<(
const Json::Value &j)
noexcept(
true)
566 case Json::nullValue:
567 return *
this <<
nullptr;
569 return *
this << j.asInt64();
570 case Json::uintValue:
571 return *
this << j.asUInt64();
572 case Json::realValue:
573 return *
this << j.asDouble();
574 case Json::stringValue:
575 return *
this << j.asString();
576 case Json::booleanValue:
577 return *
this << j.asBool();
578 case Json::arrayValue:
579 case Json::objectValue:
581 static Json::StreamWriterBuilder jsonBuilder;
582 std::once_flag once_json;
583 std::call_once(once_json,
584 []() { jsonBuilder[
"indentation"] =
""; });
585 return *
this << Json::writeString(jsonBuilder, j);
589 self &operator<<(Json::Value &j)
noexcept(
true)
591 return *this << static_cast<const Json::Value &>(j);
594 self &operator<<(Json::Value &&j)
noexcept(
true)
596 return *this << static_cast<const Json::Value &>(j);
599 void exec()
noexcept(
false);
602 static int getMysqlTypeBySize(
size_t size);
604 template <
typename T>
605 static int getMysqlType()
607 if constexpr (std::is_same_v<T, bool>)
611 else if constexpr (std::is_same_v<T, int8_t> ||
612 std::is_same_v<T, signed char>)
616 else if constexpr (std::is_same_v<T, uint8_t> ||
617 std::is_same_v<T, unsigned char>)
621 else if constexpr (std::is_same_v<T, int16_t> ||
622 std::is_same_v<T, short>)
626 else if constexpr (std::is_same_v<T, uint16_t> ||
627 std::is_same_v<T, unsigned short>)
631 else if constexpr (std::is_same_v<T, int32_t> ||
632 (std::is_same_v<T, int> &&
sizeof(int) == 4) ||
633 (std::is_same_v<T, long> &&
sizeof(long) == 4))
637 else if constexpr (std::is_same_v<T, uint32_t> ||
638 (std::is_same_v<T, unsigned int> &&
639 sizeof(
unsigned int) == 4) ||
640 (std::is_same_v<T, unsigned long> &&
641 sizeof(
unsigned long) == 4))
645 else if constexpr (std::is_same_v<T, int64_t> ||
646 std::is_same_v<T, long long> ||
647 (std::is_same_v<T, long> &&
sizeof(long) == 8))
649 return MySqlLongLong;
651 else if constexpr (std::is_same_v<T, uint64_t> ||
652 std::is_same_v<T, unsigned long long> ||
653 (std::is_same_v<T, unsigned long> &&
654 sizeof(
unsigned long) == 8))
656 return MySqlULongLong;
658 else if constexpr (std::is_same_v<T, char>)
660 if constexpr (std::is_signed_v<char>)
671 static_assert(
sizeof(T) == 0,
"Unsupported type for MySQL binding");
675 std::shared_ptr<std::string> sqlPtr_;
676 const char *sqlViewPtr_;
677 size_t sqlViewLength_;
679 size_t parametersNumber_{0};
680 std::vector<const char *> parameters_;
681 std::vector<int> lengths_;
682 std::vector<int> formats_;
683 std::vector<std::shared_ptr<void>> objs_;
684 Mode mode_{Mode::NonBlocking};
685 std::shared_ptr<CallbackHolderBase> callbackHolder_;
687 ExceptPtrCallback exceptionPtrCallback_;
689 bool destructed_{
false};
690 bool isExceptionPtr_{
false};