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