VSQLite++ 0.3
Loading...
Searching...
No Matches
result.hpp
Go to the documentation of this file.
1/*##############################################################################
2 VSQLite++ - virtuosic bytes SQLite3 C++ wrapper
3
4 Copyright (c) 2006-2014 Vinzenz Feenstra vinzenz.feenstra@gmail.com
5 All rights reserved.
6
7 Redistribution and use in source and binary forms, with or without
8modification, are permitted provided that the following conditions are met:
9
10 * Redistributions of source code must retain the above copyright notice,
11 this list of conditions and the following disclaimer.
12 * Redistributions in binary form must reproduce the above copyright notice,
13 this list of conditions and the following disclaimer in the documentation
14 and/or other materials provided with the distribution.
15 * Neither the name of virtuosic bytes nor the names of its contributors may
16 be used to endorse or promote products derived from this software without
17 specific prior written permission.
18
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 POSSIBILITY OF SUCH DAMAGE.
30
31##############################################################################*/
32#ifndef GUARD_SQLITE_RESULT_HPP_INCLUDED
33#define GUARD_SQLITE_RESULT_HPP_INCLUDED
34
35#include <chrono>
36#include <cstdint>
37#include <memory>
38#include <optional>
39#include <stdexcept>
40#include <string>
41#include <string_view>
42#include <tuple>
43#include <type_traits>
44#include <vector>
45
47#include <sqlite/deprecated.hpp>
50
58namespace sqlite {
59inline namespace v2 {
60 struct query;
62 namespace detail {
65 } // namespace detail
66
75 struct result {
76 private:
77 typedef std::shared_ptr<result_construct_params_private> construct_params;
78 friend struct query;
80 result(result const &) = delete;
81 result &operator=(result const &) = delete;
82
83 public:
86
93 bool next_row();
94
101 inline bool end() const {
102 if (!m_params)
103 throw std::runtime_error("Invalid memory access");
104 return detail::end(*m_params);
105 }
106
113 void reset() {
114 if (!m_params)
115 throw std::runtime_error("Invalid memory access");
117 }
118
127
134
143
150 std::string get_column_decltype(int idx);
151
159
168 size_t get_binary_size(int idx);
169
178 void get_binary(int idx, void *buf, size_t buf_size);
179
186 void get_binary(int idx, std::vector<unsigned char> &vec);
187
193 std::span<const unsigned char> get_binary_span(int idx);
194
200 std::string get_column_name(int idx);
201
207 bool is_null(int idx);
208
226 template <typename T> T get(int idx);
227
236 template <typename... Ts> std::tuple<Ts...> get_tuple(int start_column = 0);
237
238 private:
239 void access_check(int);
240 int get_int(int idx);
241 std::int64_t get_int64(int idx);
242 std::string get_string(int idx);
243 std::string_view get_string_view(int idx);
244 double get_double(int idx);
245
246 private:
249 };
250
252 typedef std::shared_ptr<result> result_type;
253
254 namespace detail {
255 template <typename... Ts, std::size_t... Index>
256 std::tuple<Ts...> tuple_from_row(result &res, int start, std::index_sequence<Index...>) {
257 return std::tuple<Ts...>(res.template get<Ts>(start + static_cast<int>(Index))...);
258 }
259 } // namespace detail
260
261 template <typename T> T result::get(int idx) {
262 using decayed = detail::decay_t<T>;
263 if constexpr (detail::is_optional_v<decayed>) {
264 if (is_null(idx)) {
265 return std::nullopt;
266 }
267 using value_type = typename detail::optional_value<decayed>::type;
268 return get<value_type>(idx);
269 } else if constexpr (detail::is_duration_v<decayed>) {
270 auto micros = std::chrono::microseconds{get_int64(idx)};
271 return std::chrono::duration_cast<decayed>(micros);
272 } else if constexpr (detail::is_time_point_v<decayed>) {
273 auto micros = std::chrono::microseconds{get_int64(idx)};
274 auto duration = std::chrono::duration_cast<typename decayed::duration>(micros);
275 return decayed(duration);
276 } else if constexpr (std::is_enum_v<decayed>) {
277 return static_cast<decayed>(get_int64(idx));
278 } else if constexpr (std::is_integral_v<decayed> && !std::is_same_v<decayed, bool>) {
279 return static_cast<decayed>(get_int64(idx));
280 } else if constexpr (std::is_same_v<decayed, bool>) {
281 return get_int(idx) != 0;
282 } else if constexpr (std::is_floating_point_v<decayed>) {
283 return static_cast<decayed>(get_double(idx));
284 } else if constexpr (std::is_same_v<decayed, std::string>) {
285 return get_string(idx);
286 } else if constexpr (std::is_same_v<decayed, std::string_view>) {
287 return get_string_view(idx);
288 } else if constexpr (detail::is_byte_vector_v<decayed>) {
289 std::vector<unsigned char> buffer;
290 get_binary(idx, buffer);
291 return buffer;
292 } else if constexpr (detail::is_unsigned_char_span_v<decayed>) {
293 return get_binary_span(idx);
294 } else if constexpr (detail::is_byte_span_v<decayed>) {
295 auto blob = get_binary_span(idx);
296 auto ptr = reinterpret_cast<std::byte const *>(blob.data());
297 return std::span<const std::byte>(ptr, blob.size());
298 } else {
300 "Unsupported type for sqlite::result::get<T>");
301 }
302 }
303
304 template <typename... Ts> std::tuple<Ts...> result::get_tuple(int start_column) {
305 if (start_column < 0 || start_column + static_cast<int>(sizeof...(Ts)) > m_columns) {
306 throw database_exception("Tuple columns exceed result column count.");
307 }
308 return detail::tuple_from_row<Ts...>(*this, start_column, std::index_sequence_for<Ts...>{});
309 }
310} // namespace v2
311} // namespace sqlite
312
313#endif // GUARD_SQLITE_RESULT_HPP_INCLUDED
Exception hierarchy mirroring common SQLite failure categories.
Defines the VSQLITE_DEPRECATED attribute for compilers supported by VSQLite++.
void reset(result_construct_params_private &)
std::remove_cvref_t< T > decay_t
bool end(result_construct_params_private const &)
constexpr bool is_time_point_v
constexpr bool is_byte_vector_v
constexpr bool is_optional_v
constexpr bool is_unsigned_char_span_v
constexpr bool always_false_v
constexpr bool is_duration_v
std::tuple< Ts... > tuple_from_row(result &res, int start, std::index_sequence< Index... >)
Definition result.hpp:256
constexpr bool is_byte_span_v
std::shared_ptr< result > result_type
Shared-pointer alias used by legacy APIs that transfer result ownership.
Definition result.hpp:252
std::variant< unknown_t, int, std::int64_t, long double, std::string, null_t, blob_ref_t > variant_t
Definition variant.hpp:52
Generic runtime failure raised for most SQLite errors.
query should be used to execute SQL queries An object of this class is not copyable
Definition query.hpp:61
Forward-only cursor over the rows produced by a prepared statement.
Definition result.hpp:75
result(construct_params)
bool end() const
Checks whether next_row already consumed the last row.
Definition result.hpp:101
std::string_view get_string_view(int idx)
void access_check(int)
int get_changes()
Returns the number of rows affected by the statement.
double get_double(int idx)
void get_binary(int idx, void *buf, size_t buf_size)
Copies a blob column into the caller-provided buffer.
friend struct query
Definition result.hpp:78
variant_t get_variant(int index)
Materializes the current value as variant_t.
~result()
Destroys the cursor but leaves the underlying statement intact if it is still shared.
T get(int idx)
Extracts the column at idx into an arbitrary C++ type.
Definition result.hpp:261
type get_column_type(int idx)
Reports the SQLite storage class for the value at index idx.
bool is_null(int idx)
Tests whether the value at column idx is SQL NULL.
result(result const &)=delete
std::string get_column_decltype(int idx)
Returns the declared type of the column at index idx.
void get_binary(int idx, std::vector< unsigned char > &vec)
Retrieves a blob column into a std::vector<unsigned char>.
bool next_row()
Advances to the next row.
std::span< const unsigned char > get_binary_span(int idx)
Returns a span that references the blob contents without copying.
int get_column_count()
Returns the number of columns exposed by the current statement.
std::string get_column_name(int idx)
Returns the UTF-8 column name declared in the statement.
std::string get_string(int idx)
std::tuple< Ts... > get_tuple(int start_column=0)
Collects a contiguous slice of columns into a std::tuple.
Definition result.hpp:304
int get_int(int idx)
size_t get_binary_size(int idx)
Reports the number of bytes stored in column idx.
result & operator=(result const &)=delete
void reset()
Resets the cursor to the beginning without re-binding parameters.
Definition result.hpp:113
construct_params m_params
Definition result.hpp:247
std::int64_t get_int64(int idx)
std::shared_ptr< result_construct_params_private > construct_params
Definition result.hpp:77