Lightweight 0.20250904.0
Loading...
Searching...
No Matches
SqlBinary.hpp
1#pragma once
2
3#include "../SqlColumnTypeDefinitions.hpp"
4#include "BasicStringBinder.hpp"
5#include "Core.hpp"
6
7#include <cassert>
8#include <cstdint>
9#include <utility>
10#include <vector>
11
12namespace Lightweight
13{
14
15/// @brief Represents a binary data type.
16///
17/// This class is a thin wrapper around std::vector<uint8_t> to represent binary data types efficiently.
18///
19/// @ingroup DataTypes
20class SqlBinary final: public std::vector<uint8_t>
21{
22 public:
23 using std::vector<uint8_t>::vector;
24
25 constexpr auto operator<=>(SqlBinary const&) const noexcept = default;
26
27 private:
28 friend struct SqlDataBinder<SqlBinary>;
29
30 mutable SQLLEN _indicator = 0;
31};
32
33template <>
34struct SqlDataBinder<SqlBinary>
35{
36 static constexpr auto ColumnType = SqlColumnTypeDefinitions::Binary { 255 };
37
38 static LIGHTWEIGHT_FORCE_INLINE SQLRETURN InputParameter(SQLHSTMT stmt,
39 SQLUSMALLINT column,
40 SqlBinary const& value,
41 SqlDataBinderCallback& /*cb*/) noexcept
42 {
43 value._indicator = static_cast<SQLLEN>(value.size());
44 return SQLBindParameter(stmt,
45 column,
46 SQL_PARAM_INPUT,
47 SQL_C_BINARY,
48 SQL_LONGVARBINARY,
49 value.size(),
50 0,
51 (SQLPOINTER) value.data(),
52 0,
53 &value._indicator);
54 }
55
56 static LIGHTWEIGHT_FORCE_INLINE SQLRETURN OutputColumn(
57 SQLHSTMT stmt, SQLUSMALLINT column, SqlBinary* result, SQLLEN* indicator, SqlDataBinderCallback& cb) noexcept
58 {
59 if (result->empty())
60 result->resize(255);
61
62 cb.PlanPostProcessOutputColumn([stmt, column, result, indicator]() {
63 if (*indicator == SQL_NULL_DATA)
64 // The data is NULL.
65 result->clear();
66 else if (*indicator == SQL_NO_TOTAL)
67 // We have a truncation and the server does not know how much data is left.
68 result->resize(result->size() - 1);
69 else if (std::cmp_less_equal(*indicator, static_cast<SQLLEN>(result->size())))
70 result->resize(*indicator);
71 else
72 {
73 // We have a truncation and the server knows how much data is left.
74 // Extend the buffer and fetch the rest via SQLGetData.
75
76 auto const totalCharsRequired = *indicator;
77 result->resize(totalCharsRequired + 1);
78 auto const sqlResult =
79 SQLGetData(stmt, column, SQL_C_BINARY, (SQLPOINTER) result->data(), totalCharsRequired + 1, indicator);
80 (void) sqlResult;
81 assert(SQL_SUCCEEDED(sqlResult));
82 assert(*indicator == totalCharsRequired);
83 result->resize(totalCharsRequired);
84 }
85 });
86
87 return SQLBindCol(stmt, column, SQL_C_BINARY, (SQLPOINTER) result->data(), 255, indicator);
88 }
89
90 static LIGHTWEIGHT_FORCE_INLINE SQLRETURN GetColumn(SQLHSTMT stmt,
91 SQLUSMALLINT column,
92 SqlBinary* result,
93 SQLLEN* indicator,
94 SqlDataBinderCallback const& /*cb*/) noexcept
95 {
96 if (result->empty())
97 result->resize(255);
98
99 return detail::GetRawColumnArrayData<SQL_C_BINARY>(stmt, column, result, indicator);
100 }
101
102 static LIGHTWEIGHT_FORCE_INLINE std::string Inspect(SqlBinary const& value)
103 {
104 return std::format("SqlBinary(size={})", value.size());
105 }
106};
107
108} // namespace Lightweight
Represents a binary data type.
Definition SqlBinary.hpp:21