Lightweight 0.20260617.0
Loading...
Searching...
No Matches
Primitives.hpp
1// SPDX-License-Identifier: Apache-2.0
2
3#pragma once
4
5#include "../SqlColumnTypeDefinitions.hpp"
6#include "Core.hpp"
7
8#include <string>
9
10namespace Lightweight
11{
12
13template <typename T, SQLSMALLINT TheCType, SQLINTEGER TheSqlType, auto TheColumnType>
14struct SqlSimpleDataBinder
15{
16 static constexpr SqlColumnTypeDefinition ColumnType = TheColumnType;
17
18 static LIGHTWEIGHT_FORCE_INLINE SQLRETURN InputParameter(SQLHSTMT stmt,
19 SQLUSMALLINT column,
20 T const& value,
21 SqlDataBinderCallback& /*cb*/) noexcept
22 {
23 return SQLBindParameter(stmt, column, SQL_PARAM_INPUT, TheCType, TheSqlType, 0, 0, (SQLPOINTER) &value, 0, nullptr);
24 }
25
26 /// Binds a contiguous (column-wise) or row-strided (row-wise) array of values as an input parameter.
27 ///
28 /// @param indicators Optional per-row NULL/length indicator array. Passed straight to ODBC as the
29 /// StrLen_or_IndPtr; defaults to nullptr (no NULLs). For row-wise binding the driver strides it by
30 /// the statement's SQL_ATTR_PARAM_BIND_TYPE, matching the value stride.
31 static LIGHTWEIGHT_FORCE_INLINE SQLRETURN BatchInputParameter(SQLHSTMT stmt,
32 SQLUSMALLINT column,
33 T const* values,
34 size_t /*rowCount*/,
35 SqlDataBinderCallback& /*cb*/,
36 SQLLEN* indicators = nullptr) noexcept
37 {
38 return SQLBindParameter(
39 stmt, column, SQL_PARAM_INPUT, TheCType, TheSqlType, 0, 0, (SQLPOINTER) values, sizeof(T), indicators);
40 }
41
42 static LIGHTWEIGHT_FORCE_INLINE SQLRETURN OutputColumn(
43 SQLHSTMT stmt, SQLUSMALLINT column, T* result, SQLLEN* indicator, SqlDataBinderCallback& /*unused*/) noexcept
44 {
45 return SQLBindCol(stmt, column, TheCType, result, 0, indicator);
46 }
47
48 static LIGHTWEIGHT_FORCE_INLINE SQLRETURN
49 GetColumn(SQLHSTMT stmt, SQLUSMALLINT column, T* result, SQLLEN* indicator, SqlDataBinderCallback const& /*cb*/) noexcept
50 {
51 return SQLGetData(stmt, column, TheCType, result, 0, indicator);
52 }
53
54 static LIGHTWEIGHT_FORCE_INLINE std::string Inspect(T value)
55 {
56 return std::to_string(value);
57 }
58};
59
60template <typename Int64Type, SQLSMALLINT TheCType>
61struct Int64DataBinderHelper
62{
63 static constexpr SqlColumnTypeDefinition ColumnType = SqlColumnTypeDefinitions::Bigint {};
64
65 static LIGHTWEIGHT_API SQLRETURN InputParameter(SQLHSTMT stmt,
66 SQLUSMALLINT column,
67 Int64Type const& value,
68 SqlDataBinderCallback& cb) noexcept;
69
70 static LIGHTWEIGHT_API SQLRETURN BatchInputParameter(SQLHSTMT stmt,
71 SQLUSMALLINT column,
72 Int64Type const* values,
73 size_t rowCount,
74 SqlDataBinderCallback& cb,
75 SQLLEN* indicators = nullptr) noexcept;
76
77 static LIGHTWEIGHT_API SQLRETURN OutputColumn(
78 SQLHSTMT stmt, SQLUSMALLINT column, Int64Type* result, SQLLEN* indicator, SqlDataBinderCallback& cb) noexcept;
79
80 static LIGHTWEIGHT_API SQLRETURN GetColumn(
81 SQLHSTMT stmt, SQLUSMALLINT column, Int64Type* result, SQLLEN* indicator, SqlDataBinderCallback const& cb) noexcept;
82
83 static LIGHTWEIGHT_FORCE_INLINE std::string Inspect(Int64Type value)
84 {
85 return std::to_string(value);
86 }
87};
88
89// clang-format off
90template <> struct SqlDataBinder<bool>: SqlSimpleDataBinder<bool, SQL_BIT, SQL_BIT, SqlColumnTypeDefinitions::Bool {}> {};
91template <> struct SqlDataBinder<char>: SqlSimpleDataBinder<char, SQL_C_CHAR, SQL_CHAR, SqlColumnTypeDefinitions::Char {}> {};
92template <> struct SqlDataBinder<int8_t>: SqlSimpleDataBinder<int8_t, SQL_C_STINYINT, SQL_TINYINT, SqlColumnTypeDefinitions::Tinyint {}> {};
93template <> struct SqlDataBinder<uint8_t>: SqlSimpleDataBinder<uint8_t, SQL_C_UTINYINT, SQL_TINYINT, SqlColumnTypeDefinitions::Tinyint {}> {};
94template <> struct SqlDataBinder<int16_t>: SqlSimpleDataBinder<int16_t, SQL_C_SSHORT, SQL_SMALLINT, SqlColumnTypeDefinitions::Smallint {}> {};
95template <> struct SqlDataBinder<uint16_t>: SqlSimpleDataBinder<uint16_t, SQL_C_USHORT, SQL_SMALLINT, SqlColumnTypeDefinitions::Smallint {}> {};
96template <> struct SqlDataBinder<int32_t>: SqlSimpleDataBinder<int32_t, SQL_C_SLONG, SQL_INTEGER, SqlColumnTypeDefinitions::Integer {}> {};
97template <> struct SqlDataBinder<uint32_t>: SqlSimpleDataBinder<uint32_t, SQL_C_ULONG, SQL_INTEGER, SqlColumnTypeDefinitions::Integer {}> {};
98template <> struct SqlDataBinder<int64_t>: Int64DataBinderHelper<int64_t, SQL_C_SBIGINT> {};
99template <> struct SqlDataBinder<uint64_t>: Int64DataBinderHelper<uint64_t, SQL_C_UBIGINT> {};
100//template <> struct SqlDataBinder<uint64_t>: Int64DataBinderHelper<uint64_t, SQL_C_UBIGINT> {};
101template <> struct SqlDataBinder<float>: SqlSimpleDataBinder<float, SQL_C_FLOAT, SQL_REAL, SqlColumnTypeDefinitions::Real {}> {};
102template <> struct SqlDataBinder<double>: SqlSimpleDataBinder<double, SQL_C_DOUBLE, SQL_DOUBLE, SqlColumnTypeDefinitions::Real {}> {};
103#if !defined(_WIN32) && !defined(__APPLE__)
104template <> struct SqlDataBinder<long long>: Int64DataBinderHelper<long long, SQL_C_SBIGINT> {};
105template <> struct SqlDataBinder<unsigned long long>: Int64DataBinderHelper<unsigned long long, SQL_C_UBIGINT> {};
106#endif
107#if defined(__APPLE__) // size_t is a different type on macOS
108// std::size_t is unsigned, so bind it with the unsigned C type (matching SqlDataBinder<uint64_t> above);
109// SQL_C_SBIGINT would sign-corrupt values above INT64_MAX.
110template <> struct SqlDataBinder<std::size_t>: SqlSimpleDataBinder<std::size_t, SQL_C_UBIGINT, SQL_BIGINT, SqlColumnTypeDefinitions::Bigint {}> {};
111#endif
112
113// These fixed-width primitives bind via a plain SQLBindParameter and are eligible for native row-wise
114// batch binding (see SqlIsNativeRowBindableValue in Core.hpp). A single constrained partial
115// specialization, keyed on detail::IsAnyOf, covers them all.
116template <typename T>
117 requires detail::IsAnyOf<T, bool, char, int8_t, uint8_t, int16_t, uint16_t, int32_t, uint32_t, int64_t, uint64_t,
118 float, double
119#if !defined(_WIN32) && !defined(__APPLE__)
120 , long long, unsigned long long
121#endif
122#if defined(__APPLE__)
123 , std::size_t
124#endif
125 >
126inline constexpr bool SqlIsNativeRowBindableValue<T> = true;
127// clang-format on
128
129} // namespace Lightweight