6#include "SqlNullValue.hpp"
25 concept SqlHasOptionalRowWiseBatchBinder =
requires(
26 SQLHSTMT stmt, SQLUSMALLINT column, std::optional<T>
const* elem0, std::size_t rowCount, SqlDataBinderCallback& cb) {
27 SqlDataBinder<T>::BatchRowWiseInputParameterOptional(stmt, column, elem0, rowCount, rowCount, cb);
32struct SqlDataBinder<std::optional<T>>
34 using OptionalValue = std::optional<T>;
36 static constexpr auto ColumnType = SqlDataBinder<T>::ColumnType;
38 static LIGHTWEIGHT_FORCE_INLINE SQLRETURN InputParameter(SQLHSTMT stmt,
40 OptionalValue
const& value,
41 SqlDataBinderCallback& cb)
noexcept
43 if (value.has_value())
44 return SqlDataBinder<T>::InputParameter(stmt, column, *value, cb);
46 return SqlDataBinder<SqlNullType>::InputParameter(stmt, column,
SqlNullValue, cb);
72 static SQLRETURN BatchRowWiseInputParameter(SQLHSTMT stmt,
74 OptionalValue
const* elem0,
75 std::size_t rowStride,
77 SqlDataBinderCallback& cb)
noexcept
79 if constexpr (detail::SqlHasOptionalRowWiseBatchBinder<T>)
83 return SqlDataBinder<T>::BatchRowWiseInputParameterOptional(stmt, column, elem0, rowStride, rowCount, cb);
88 auto const valueOffset = detail::OptionalValueOffset<T>();
93 auto const* sourceBytes =
reinterpret_cast<std::byte const*
>(elem0);
94 auto*
const indicatorBytes = cb.ProvideBatchStagingBuffer(((rowCount - 1) * rowStride) +
sizeof(SQLLEN));
95 for (
auto const i: std::views::iota(std::size_t { 0 }, rowCount))
98 auto const& optional = *
reinterpret_cast<OptionalValue const*
>(sourceBytes + (i * rowStride));
99 auto*
const indicatorSlot =
reinterpret_cast<SQLLEN*
>(indicatorBytes + (i * rowStride));
100 *indicatorSlot = optional.has_value() ? SQLLEN { 0 } : SQLLEN { SQL_NULL_DATA };
105 auto const* valueBase =
reinterpret_cast<T const*
>(
reinterpret_cast<std::byte const*
>(elem0) + valueOffset);
106 return SqlDataBinder<T>::BatchInputParameter(
107 stmt, column, valueBase, rowCount, cb,
reinterpret_cast<SQLLEN*
>(indicatorBytes));
111 static LIGHTWEIGHT_FORCE_INLINE SQLRETURN OutputColumn(
112 SQLHSTMT stmt, SQLUSMALLINT column, OptionalValue* result, SQLLEN* indicator, SqlDataBinderCallback& cb)
noexcept
117 auto const sqlReturn = SqlDataBinder<T>::OutputColumn(stmt, column, &result->emplace(), indicator, cb);
118 cb.PlanPostProcessOutputColumn([result, indicator]() {
119 if (indicator && *indicator == SQL_NULL_DATA)
120 *result = std::nullopt;
125 static LIGHTWEIGHT_FORCE_INLINE SQLRETURN GetColumn(SQLHSTMT stmt,
127 OptionalValue* result,
129 SqlDataBinderCallback
const& cb)
noexcept
131 auto const sqlReturn = SqlDataBinder<T>::GetColumn(stmt, column, &result->emplace(), indicator, cb);
132 if (indicator && *indicator == SQL_NULL_DATA)
133 *result = std::nullopt;
137 static LIGHTWEIGHT_FORCE_INLINE std::string Inspect(OptionalValue
const& value)
noexcept
142 return std::string(SqlDataBinder<T>::Inspect(*value));
constexpr auto SqlNullValue