Zserio C++17 runtime library 1.3.0
Built for Zserio 2.20.0
Loading...
Searching...
No Matches
SqliteUtil.h
Go to the documentation of this file.
1#ifndef ZSERIO_SQLITE_UTIL_H_INC
2#define ZSERIO_SQLITE_UTIL_H_INC
3
4#include "zserio/Bitmasks.h"
5#include "zserio/Enums.h"
6#include "zserio/Optional.h"
8#include "zserio/Span.h"
9#include "zserio/Traits.h"
10
11#include "sqlite3.h"
12
13namespace zserio
14{
15namespace detail
16{
17
21template <typename T>
22struct SqlRow;
23
24template <typename T, typename = void>
25struct ColumnTraits;
26
27template <typename T>
28struct ColumnTraits<T, std::enable_if_t<is_complete_v<View<T>>>>
29{
30 static constexpr std::string_view TYPE_NAME = "BLOB";
31 static constexpr int TYPE = SQLITE_BLOB;
32};
33
34template <typename T>
35struct ColumnTraits<T, std::enable_if_t<std::is_enum_v<T> || is_bitmask_v<T>>>
36{
37 static constexpr std::string_view TYPE_NAME = "INTEGER";
38 static constexpr int TYPE = SQLITE_INTEGER;
39};
40
41template <typename T>
42struct ColumnTraits<T, std::enable_if_t<is_numeric_wrapper_v<T> && std::is_integral_v<typename T::ValueType>>>
43{
44 static constexpr std::string_view TYPE_NAME = "INTEGER";
45 static constexpr int TYPE = SQLITE_INTEGER;
46};
47
48template <typename T>
49struct ColumnTraits<T,
50 std::enable_if_t<is_numeric_wrapper_v<T> && std::is_floating_point_v<typename T::ValueType>>>
51{
52 static constexpr std::string_view TYPE_NAME = "REAL";
53 static constexpr int TYPE = SQLITE_FLOAT;
54};
55
56template <typename ALLOC>
57struct ColumnTraits<BasicString<ALLOC>>
58{
59 static constexpr std::string_view TYPE_NAME = "TEXT";
60 static constexpr int TYPE = SQLITE_TEXT;
61};
62
63template <typename ALLOC, typename T, typename... ARGS>
64std::enable_if_t<is_complete_v<View<T>>> readColumn(
65 BasicOptional<ALLOC, T>& column, sqlite3_stmt& stmt, int index, const ARGS&... args)
66{
67 // blob
68 const void* blobDataPtr = sqlite3_column_blob(&stmt, index);
69 const int blobDataLength = sqlite3_column_bytes(&stmt, index);
70 Span<const uint8_t> blobData(static_cast<const uint8_t*>(blobDataPtr), static_cast<size_t>(blobDataLength));
71 column.emplace();
72 deserializeFromBytes(blobData, *column, args...);
73}
74
75template <typename ALLOC, typename T>
76std::enable_if_t<std::is_enum_v<T>> readColumn(BasicOptional<ALLOC, T>& column, sqlite3_stmt& stmt, int index)
77{
78 const int64_t intValue = sqlite3_column_int64(&stmt, index);
79 column = valueToEnum<T>(static_cast<std::underlying_type_t<T>>(intValue));
80}
81
82template <typename ALLOC, typename T>
83std::enable_if_t<is_bitmask_v<T>> readColumn(BasicOptional<ALLOC, T>& column, sqlite3_stmt& stmt, int index)
84{
85 const int64_t intValue = sqlite3_column_int64(&stmt, index);
86 column = T(static_cast<typename T::ZserioType::ValueType>(intValue));
87}
88
89template <typename ALLOC>
90void readColumn(BasicOptional<ALLOC, Bool>& column, sqlite3_stmt& stmt, int index)
91{
92 const int64_t intValue = sqlite3_column_int64(&stmt, index);
93 column = intValue != 0;
94}
95
96template <typename ALLOC, BitSize BIT_SIZE, bool IS_SIGNED>
97void readColumn(
98 BasicOptional<ALLOC, FixedIntWrapper<BIT_SIZE, IS_SIGNED>>& column, sqlite3_stmt& stmt, int index)
99{
100 const int64_t intValue = sqlite3_column_int64(&stmt, index);
101 column = static_cast<typename FixedIntWrapper<BIT_SIZE, IS_SIGNED>::ValueType>(intValue);
102}
103
104template <typename ALLOC, typename T>
105void readColumn(BasicOptional<ALLOC, DynIntWrapper<T>>& column, sqlite3_stmt& stmt, int index)
106{
107 const int64_t intValue = sqlite3_column_int64(&stmt, index);
108 column = static_cast<T>(intValue);
109}
110
111template <typename ALLOC, typename VALUE_TYPE, VarIntType VAR_TYPE>
112void readColumn(
113 BasicOptional<ALLOC, VarIntWrapper<VALUE_TYPE, VAR_TYPE>>& column, sqlite3_stmt& stmt, int index)
114{
115 const int64_t intValue = sqlite3_column_int64(&stmt, index);
116 column = static_cast<VALUE_TYPE>(intValue);
117}
118
119template <typename ALLOC, typename VALUE_TYPE, FloatType FLOAT_TYPE>
120void readColumn(
121 BasicOptional<ALLOC, FloatWrapper<VALUE_TYPE, FLOAT_TYPE>>& column, sqlite3_stmt& stmt, int index)
122{
123 const double doubleValue = sqlite3_column_double(&stmt, index);
124 column = static_cast<VALUE_TYPE>(doubleValue);
125}
126
127template <typename ALLOC>
128void readColumn(
129 BasicOptional<ALLOC, BasicString<RebindAlloc<ALLOC, char>>>& column, sqlite3_stmt& stmt, int index)
130{
131 const unsigned char* textValue = sqlite3_column_text(&stmt, index);
132 column.emplace(reinterpret_cast<const char*>(textValue));
133}
134
135template <typename T>
136BitSize prepareColumn(const View<T>& view)
137{
138 validate(view);
139 return initializeOffsets(view, 0);
140}
141
142template <typename T>
143BitSize prepareColumn(const T&)
144{
145 return 0;
146}
147
148template <typename ALLOC, typename T>
149int bindColumn(sqlite3_stmt& stmt, int index, const View<T>& view, BitSize bitSize, const ALLOC& allocator)
150{
151 BasicBitBuffer<ALLOC> bitBuffer(bitSize, allocator);
152 BitStreamWriter writer(bitBuffer);
153 write(writer, view);
154 return sqlite3_bind_blob(
155 &stmt, index, bitBuffer.getBuffer(), static_cast<int>(bitBuffer.getByteSize()), SQLITE_TRANSIENT);
156}
157
158template <typename ALLOC, typename T>
159std::enable_if_t<std::is_enum_v<T>, int> bindColumn(
160 sqlite3_stmt& stmt, int index, T value, BitSize, const ALLOC&)
161{
162 return sqlite3_bind_int64(&stmt, index, static_cast<int64_t>(value));
163}
164
165template <typename ALLOC, typename T>
166std::enable_if_t<is_bitmask_v<T>, int> bindColumn(sqlite3_stmt& stmt, int index, T value, BitSize, const ALLOC&)
167{
168 return sqlite3_bind_int64(&stmt, index, static_cast<int64_t>(value.getValue()));
169}
170
171template <typename ALLOC>
172int bindColumn(sqlite3_stmt& stmt, int index, Bool value, BitSize, const ALLOC&)
173{
174 return sqlite3_bind_int64(&stmt, index, static_cast<int64_t>(value));
175}
176
177template <typename ALLOC, BitSize BIT_SIZE, bool IS_SIGNED>
178int bindColumn(sqlite3_stmt& stmt, int index, FixedIntWrapper<BIT_SIZE, IS_SIGNED> value, BitSize, const ALLOC&)
179{
180 return sqlite3_bind_int64(&stmt, index, static_cast<int64_t>(value));
181}
182
183template <typename ALLOC, typename T>
184int bindColumn(sqlite3_stmt& stmt, DynIntWrapper<T> value, BitSize, int index, const ALLOC&)
185{
186 return sqlite3_bind_int64(&stmt, index, static_cast<int64_t>(value));
187}
188
189template <typename ALLOC, typename VALUE_TYPE, VarIntType VAR_TYPE>
190int bindColumn(sqlite3_stmt& stmt, int index, VarIntWrapper<VALUE_TYPE, VAR_TYPE> value, BitSize, const ALLOC&)
191{
192 return sqlite3_bind_int64(&stmt, index, static_cast<int64_t>(value));
193}
194
195template <typename ALLOC, typename VALUE_TYPE, FloatType FLOAT_TYPE>
196int bindColumn(sqlite3_stmt& stmt, int index, FloatWrapper<VALUE_TYPE, FLOAT_TYPE> value, BitSize, const ALLOC&)
197{
198 return sqlite3_bind_double(&stmt, index, static_cast<double>(value));
199}
200
201template <typename ALLOC>
202int bindColumn(sqlite3_stmt& stmt, int index, std::string_view value, BitSize, const ALLOC&)
203{
204 return sqlite3_bind_text(&stmt, index, value.data(), static_cast<int>(value.size()), SQLITE_TRANSIENT);
205}
206
207} // namespace detail
208} // namespace zserio
209
210#endif // ZSERIO_SQLITE_UTIL_H_INC
detail::BoolWrapper Bool
Definition Types.h:732
unsigned int BitSize
Definition BitSize.h:8
std::basic_string< char, std::char_traits< char >, ALLOC > BasicString
Definition String.h:17
View< T > deserializeFromBytes(Span< const uint8_t > buffer, ArrayPreallocation maxArrayPrealloc, T &data, ARGS &&... arguments)