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