5#include "../SqlColumnTypeDefinitions.hpp"
6#include "BasicStringBinder.hpp"
22template <std::
size_t N>
25 using BaseType = std::vector<uint8_t>;
38#if defined(_MSVC_STL_VERSION)
39 using ByteView = std::basic_string_view<value_type>;
45 static constexpr auto ColumnType = SqlColumnTypeDefinitions::VarBinary { N };
69 template <std::
size_t SourceSize>
71 _base { text, text + SourceSize }
73 static_assert(SourceSize <= N + 1,
"RHS string size must not exceed target string's capacity.");
77 template <std::
size_t SourceSize>
81 static_assert(SourceSize <= N + 1,
"RHS string size must not exceed target string's capacity.");
89#if !defined(LIGHTWEIGHT_CXX26_REFLECTION)
92 _base { s.data(), s.data() + s.size() }
97 [[nodiscard]] LIGHTWEIGHT_FORCE_INLINE
constexpr ByteView Bytes() const noexcept
99 return { _base.data(), _base.size() };
104 [[deprecated(
"use Bytes(); SqlDynamicBinary stores raw bytes, not text")]] [[nodiscard]]
115 return _base <=> other._base;
121 return _base == other._base;
125 [[nodiscard]] LIGHTWEIGHT_FORCE_INLINE
constexpr std::size_t
size() const noexcept
131 void LIGHTWEIGHT_FORCE_INLINE
resize(std::size_t newSize)
133 _base.resize(newSize);
137 [[nodiscard]] LIGHTWEIGHT_FORCE_INLINE
constexpr bool empty() const noexcept
139 return _base.empty();
151 [[nodiscard]] LIGHTWEIGHT_FORCE_INLINE
constexpr value_type const*
data() const noexcept
153 if (_base.data() !=
nullptr)
156 static constexpr value_type emptySentinel = 0;
157 return &emptySentinel;
163 if (_base.data() ==
nullptr)
172 LIGHTWEIGHT_FORCE_INLINE
void clear() noexcept
179 mutable SQLLEN _indicator = 0;
188 struct IsSqlDynamicBinaryImpl: std::false_type
193 struct IsSqlDynamicBinaryImpl<SqlDynamicBinary<T>>: std::true_type
198 struct IsSqlDynamicBinaryImpl<std::optional<SqlDynamicBinary<T>>>: std::true_type
205constexpr bool IsSqlDynamicBinary = detail::IsSqlDynamicBinaryImpl<T>::value;
209template <std::
size_t N>
210struct std::formatter<Lightweight::SqlDynamicBinary<N>>: std::formatter<std::string>
217 std::string humanReadableText;
218 for (
auto const byte: std::span { text.data(), text.size() })
220 if (
byte >= 0x20 &&
byte <= 0x7E)
221 humanReadableText +=
static_cast<char>(byte);
223 humanReadableText += std::format(
"\\x{:02X}",
byte);
225 return std::formatter<std::string>::format(humanReadableText.data(), ctx);
232template <std::
size_t N>
233struct SqlDataBinder<SqlDynamicBinary<N>>
235 using ValueType = SqlDynamicBinary<N>;
237 static constexpr auto ColumnType = SqlColumnTypeDefinitions::VarBinary { N };
239 static LIGHTWEIGHT_FORCE_INLINE SQLRETURN InputParameter(SQLHSTMT stmt,
241 ValueType
const& value,
242 SqlDataBinderCallback& )
noexcept
244 value._indicator =
static_cast<SQLLEN
>(value.size());
246 auto const sqlType =
static_cast<SQLSMALLINT
>(value.size() > 8000 ? SQL_LONGVARBINARY : SQL_VARBINARY);
247 auto const bufferSize =
static_cast<SQLULEN
>(value.size());
248 auto*
const ptr = (SQLPOINTER) value.data();
250 return SQLBindParameter(
251 stmt, column, SQL_PARAM_INPUT, SQL_C_BINARY, sqlType, bufferSize, 0, ptr, 0, &value._indicator);
254 static LIGHTWEIGHT_FORCE_INLINE SQLRETURN OutputColumn(
255 SQLHSTMT stmt, SQLUSMALLINT column, ValueType* result, SQLLEN* indicator, SqlDataBinderCallback& cb)
noexcept
260 cb.PlanPostProcessOutputColumn([stmt, column, result, indicator]() {
261 if (*indicator == SQL_NULL_DATA)
264 else if (*indicator == SQL_NO_TOTAL)
266 result->resize(result->size() - 1);
267 else if (*indicator <=
static_cast<SQLLEN
>(result->size()))
268 result->resize(
static_cast<size_t>(*indicator));
274 auto const totalCharsRequired = *indicator;
275 result->resize(
static_cast<size_t>(totalCharsRequired + 1));
276 auto const sqlResult =
277 SQLGetData(stmt, column, SQL_C_BINARY, (SQLPOINTER) result->data(), totalCharsRequired + 1, indicator);
279 assert(SQL_SUCCEEDED(sqlResult));
280 assert(*indicator == totalCharsRequired);
281 result->resize(
static_cast<size_t>(totalCharsRequired));
285 return SQLBindCol(stmt, column, SQL_C_BINARY, (SQLPOINTER) result->data(), 255, indicator);
288 static LIGHTWEIGHT_FORCE_INLINE SQLRETURN GetColumn(SQLHSTMT stmt,
292 SqlDataBinderCallback
const& )
noexcept
297 return detail::GetRawColumnArrayData<SQL_C_BINARY>(stmt, column, result, indicator);
300 static LIGHTWEIGHT_FORCE_INLINE std::string Inspect(ValueType
const& value)
302 return std::format(
"SqlBinary<{}>(size={})", N, value.size());
LIGHTWEIGHT_FORCE_INLINE constexpr SqlDynamicBinary(value_type const *s, value_type const *e) noexcept
Constructs a fixed-size string from a string pointer and end pointer.
static constexpr auto ColumnType
The SQL column type definition for this binary type.
LIGHTWEIGHT_FORCE_INLINE constexpr bool empty() const noexcept
Tests if the stored data is empty.
LIGHTWEIGHT_FORCE_INLINE constexpr SqlDynamicBinary(ByteView s) noexcept
Constructs the binary payload from a contiguous view of bytes.
LIGHTWEIGHT_FORCE_INLINE void clear() noexcept
Clears the storad data.
LIGHTWEIGHT_FORCE_INLINE constexpr std::size_t size() const noexcept
Retrieves the size of the string.
LIGHTWEIGHT_FORCE_INLINE constexpr ByteView Bytes() const noexcept
Retrieves a read-only view over the stored bytes.
LIGHTWEIGHT_FORCE_INLINE constexpr ByteView ToStringView() const noexcept
void LIGHTWEIGHT_FORCE_INLINE resize(std::size_t newSize)
Resizes the underlying data storage to the given size.
LIGHTWEIGHT_FORCE_INLINE constexpr value_type const * data() const noexcept
uint8_t value_type
The element type of the binary data.
constexpr bool operator==(SqlDynamicBinary< N > const &other) const noexcept
Equality operator derived from the spaceship comparison above.
LIGHTWEIGHT_FORCE_INLINE constexpr SqlDynamicBinary() noexcept=default
Default constructor, creates an empty object.
static constexpr std::size_t DynamicCapacity
The maximum size of the underlying data storage.
LIGHTWEIGHT_FORCE_INLINE constexpr value_type * data() noexcept
Retrieves the pointer to the string data.
constexpr LIGHTWEIGHT_FORCE_INLINE SqlDynamicBinary(std::initializer_list< value_type > data)
Constructs the object from an initializer list of bytes.
std::span< value_type const > ByteView
constexpr auto operator<=>(SqlDynamicBinary< N > const &other) const noexcept