Lightweight 0.20251202.0
Loading...
Searching...
No Matches
SqlColumnTypeDefinitions.hpp
1// SPDX-License-Identifier: Apache-2.0
2
3#pragma once
4
5#if defined(_WIN32) || defined(_WIN64)
6 #include <Windows.h>
7#endif
8
9#include <cstdint>
10#include <optional>
11#include <variant>
12
13#include <sql.h>
14#include <sqlext.h>
15
16// Microsoft SQL Server extension for TIME(7) with fractional seconds.
17// This is supported by SQL Server 2008 and later, MariaDB and MySQL ODBC drivers.
18// clang-format off
19#if !defined(SQL_SS_TIME2)
20 #define SQL_SS_TIME2 (-154)
21
22 struct SQL_SS_TIME2_STRUCT
23 {
24 SQLUSMALLINT hour;
25 SQLUSMALLINT minute;
26 SQLUSMALLINT second;
27 SQLUINTEGER fraction;
28 };
29
30 static_assert(
31 sizeof(SQL_SS_TIME2_STRUCT) == 12,
32 "SQL_SS_TIME2_STRUCT size must be padded 12 bytes, as per ODBC extension spec."
33 );
34#endif
35// clang-format on
36
37namespace Lightweight
38{
39
40/// @brief Represents if a column is nullable or not.
41enum class SqlNullable : uint8_t
42{
43 NotNull,
44 Null,
45};
46
47namespace SqlColumnTypeDefinitions
48{
49
50 // clang-format off
51struct Bigint {};
52struct Binary { std::size_t size = 255; };
53struct Bool {};
54struct Char { std::size_t size = 1; };
55struct Date {};
56struct DateTime {};
57struct Decimal { std::size_t precision {}; std::size_t scale {}; };
58struct Guid {};
59struct Integer {};
60struct NChar { std::size_t size = 1; };
61struct NVarchar { std::size_t size = 255; };
62struct Real { std::size_t precision = {}; };
63struct Smallint {};
64struct Text { std::size_t size {}; };
65struct Time {};
66struct Timestamp {};
67struct Tinyint {};
68struct VarBinary { std::size_t size = 255; };
69struct Varchar { std::size_t size = 255; };
70 // clang-format on
71
72} // namespace SqlColumnTypeDefinitions
73
74using SqlColumnTypeDefinition = std::variant<SqlColumnTypeDefinitions::Bigint,
75 SqlColumnTypeDefinitions::Binary,
76 SqlColumnTypeDefinitions::Bool,
77 SqlColumnTypeDefinitions::Char,
78 SqlColumnTypeDefinitions::Date,
79 SqlColumnTypeDefinitions::DateTime,
80 SqlColumnTypeDefinitions::Decimal,
81 SqlColumnTypeDefinitions::Guid,
82 SqlColumnTypeDefinitions::Integer,
83 SqlColumnTypeDefinitions::NChar,
84 SqlColumnTypeDefinitions::NVarchar,
85 SqlColumnTypeDefinitions::Real,
86 SqlColumnTypeDefinitions::Tinyint,
87 SqlColumnTypeDefinitions::Smallint,
88 SqlColumnTypeDefinitions::Text,
89 SqlColumnTypeDefinitions::Time,
90 SqlColumnTypeDefinitions::Timestamp,
91 SqlColumnTypeDefinitions::VarBinary,
92 SqlColumnTypeDefinitions::Varchar>;
93
94/// Maps ODBC data type (with given @p size and @p precision) to SqlColumnTypeDefinition
95///
96/// @return SqlColumnTypeDefinition if the data type is supported, otherwise std::nullopt
97constexpr std::optional<SqlColumnTypeDefinition> MakeColumnTypeFromNative(int value, std::size_t size, std::size_t precision)
98{
99 // Maps ODBC data types to SqlColumnTypeDefinition
100 // See: https://learn.microsoft.com/en-us/sql/odbc/reference/appendixes/sql-data-types?view=sql-server-ver16
101 using namespace SqlColumnTypeDefinitions;
102 // clang-format off
103 switch (value)
104 {
105 case SQL_BIGINT: return Bigint {};
106 case SQL_BINARY: return Binary { size };
107 case SQL_BIT: return Bool {};
108 case SQL_CHAR: return Char { size };
109 case SQL_DATE: return Date {};
110 case SQL_DECIMAL: return Decimal { .precision = size, .scale = precision };
111 case SQL_DOUBLE: return Real { .precision = 53 };
112 case SQL_FLOAT: return Real { . precision = precision };
113 case SQL_GUID: return Guid {};
114 case SQL_INTEGER: return Integer {};
115 case SQL_LONGVARBINARY: return VarBinary { size };
116 case SQL_LONGVARCHAR: return Varchar { size };
117 case SQL_NUMERIC: return Decimal { .precision = size, .scale = precision };
118 case SQL_REAL: return Real { .precision = 24 };
119 case SQL_SMALLINT: return Smallint {};
120 case SQL_TIME: return Time {};
121 case SQL_TIMESTAMP: return DateTime {};
122 case SQL_TINYINT: return Tinyint {};
123 case SQL_TYPE_DATE: return Date {};
124 case SQL_TYPE_TIME: return Time {};
125 case SQL_SS_TIME2: return Time {}; // Microsoft SQL Server extension
126 case SQL_TYPE_TIMESTAMP: return DateTime {};
127 case SQL_VARBINARY: return Binary { size };
128 case SQL_VARCHAR: return Varchar { size };
129 case SQL_WCHAR: return NChar { size };
130 case SQL_WLONGVARCHAR: return NVarchar { size };
131 case SQL_WVARCHAR: return NVarchar { size };
132 case SQL_UNKNOWN_TYPE: return std::nullopt;
133 default: return std::nullopt;
134 }
135 // clang-format on
136}
137
138} // namespace Lightweight