Lightweight 0.20261105.1
Loading...
Searching...
No Matches
StdStringView.hpp
1// SPDX-License-Identifier: Apache-2.0
2
3#pragma once
4
5#include "Core.hpp"
6#include "UnicodeConverter.hpp"
7
8#include <concepts>
9#include <memory>
10#include <string_view>
11
12namespace Lightweight
13{
14
15namespace detail
16{
17 /// @brief Returns @p text's data, or an empty string's when the view has none (ODBC rejects a null value pointer).
18 template <typename CharT>
19 [[nodiscard]] constexpr CharT const* NonNullTextData(std::basic_string_view<CharT> text) noexcept
20 {
21 static constexpr CharT emptyText {};
22 return text.data() != nullptr ? text.data() : &emptyText;
23 }
24} // namespace detail
25
26template <>
27struct SqlDataBinder<std::basic_string_view<char>>
28{
29 static constexpr SQLSMALLINT CType = SQL_C_CHAR;
30 static constexpr SQLSMALLINT SqlType = SQL_VARCHAR;
31
32 static LIGHTWEIGHT_FORCE_INLINE SQLRETURN InputParameter(SQLHSTMT stmt,
33 SQLUSMALLINT column,
34 std::basic_string_view<char> value,
35 SqlDataBinderCallback& cb) noexcept
36 {
37 SQLLEN* indicator = cb.ProvideInputIndicator();
38 *indicator = static_cast<SQLLEN>(value.size());
39 return SQLBindParameter(stmt,
40 column,
41 SQL_PARAM_INPUT,
42 CType,
43 SqlType,
44 detail::NonZeroColumnSize(value.size()),
45 0,
46 (SQLPOINTER) detail::NonNullTextData(value),
47 0,
48 indicator);
49 }
50
51 static LIGHTWEIGHT_FORCE_INLINE std::string_view Inspect(std::basic_string_view<char> value) noexcept
52 {
53 return { value.data(), value.size() };
54 }
55};
56
57template <typename Char16Type>
58 requires std::same_as<Char16Type, char16_t> || (std::same_as<Char16Type, wchar_t> && sizeof(wchar_t) == 2)
59struct SqlDataBinder<std::basic_string_view<Char16Type>>
60{
61 static constexpr SQLSMALLINT CType = SQL_C_WCHAR;
62 static constexpr SQLSMALLINT SqlType = SQL_WVARCHAR;
63
64 static LIGHTWEIGHT_FORCE_INLINE SQLRETURN InputParameter(SQLHSTMT stmt,
65 SQLUSMALLINT column,
66 std::basic_string_view<Char16Type> value,
67 SqlDataBinderCallback& cb) noexcept
68 {
69 auto const sizeInBytes = static_cast<SQLLEN>(value.size() * sizeof(Char16Type));
70 SQLLEN* indicator = cb.ProvideInputIndicator();
71 *indicator = sizeInBytes;
72 return SQLBindParameter(stmt,
73 column,
74 SQL_PARAM_INPUT,
75 CType,
76 SqlType,
77 detail::NonZeroColumnSize(value.size()),
78 0,
79 (SQLPOINTER) detail::NonNullTextData(value),
80 sizeInBytes,
81 indicator);
82 }
83
84 static LIGHTWEIGHT_FORCE_INLINE std::string Inspect(std::basic_string_view<Char16Type> value) noexcept
85 {
86 auto u8String = ToUtf8(value);
87 return std::string((char const*) u8String.data(), u8String.size());
88 }
89};
90
91template <typename Char32Type>
92 requires std::same_as<Char32Type, char32_t> || (std::same_as<Char32Type, wchar_t> && sizeof(wchar_t) == 4)
93struct SqlDataBinder<std::basic_string_view<Char32Type>>
94{
95 static constexpr SQLSMALLINT CType = SQL_C_WCHAR;
96 static constexpr SQLSMALLINT SqlType = SQL_WVARCHAR;
97
98 static LIGHTWEIGHT_FORCE_INLINE SQLRETURN InputParameter(SQLHSTMT stmt,
99 SQLUSMALLINT column,
100 std::basic_string_view<Char32Type> value,
101 SqlDataBinderCallback& cb) noexcept
102 {
103 auto u16String = std::make_shared<std::u16string>(ToUtf16(value));
104 cb.PlanPostExecuteCallback([u16String = u16String]() {}); // Keep the string alive
105 auto const* data = u16String->data();
106 auto const sizeInBytes = u16String->size() * sizeof(Char32Type);
107 return SQLBindParameter(stmt,
108 column,
109 SQL_PARAM_INPUT,
110 CType,
111 SqlType,
112 detail::NonZeroColumnSize(sizeInBytes),
113 0,
114 (SQLPOINTER) data,
115 0,
116 nullptr);
117 }
118
119 static LIGHTWEIGHT_FORCE_INLINE std::string Inspect(std::basic_string_view<Char32Type> value) noexcept
120 {
121 auto u8String = ToUtf8(value);
122 return std::string((char const*) u8String.data(), u8String.size());
123 }
124};
125
126template <>
127struct SqlDataBinder<std::u8string_view>
128{
129 static constexpr SQLSMALLINT CType = SQL_C_WCHAR;
130 static constexpr SQLSMALLINT SqlType = SQL_WVARCHAR;
131
132 static LIGHTWEIGHT_FORCE_INLINE SQLRETURN InputParameter(SQLHSTMT stmt,
133 SQLUSMALLINT column,
134 std::u8string_view value,
135 SqlDataBinderCallback& cb) noexcept
136 {
137 auto u16String = std::make_shared<std::u16string>(ToUtf16(value));
138 cb.PlanPostExecuteCallback([u16String = u16String]() {}); // Keep the string alive
139 auto const* data = u16String->data();
140 auto const sizeInBytes = u16String->size() * sizeof(char8_t);
141 return SQLBindParameter(stmt,
142 column,
143 SQL_PARAM_INPUT,
144 CType,
145 SqlType,
146 detail::NonZeroColumnSize(sizeInBytes),
147 0,
148 (SQLPOINTER) data,
149 0,
150 nullptr);
151 }
152
153 static LIGHTWEIGHT_FORCE_INLINE std::string Inspect(std::basic_string_view<char8_t> value) noexcept
154 {
155 return std::string { (char const*) value.data(), value.size() };
156 }
157};
158
159} // namespace Lightweight
LIGHTWEIGHT_API std::u8string ToUtf8(std::u32string_view u32InputString)
std::u16string ToUtf16(std::basic_string_view< T > const u32InputString)