VSQLite++ 0.3
Loading...
Searching...
No Matches
command.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 modification,
8 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_COMMAND_HPP_INCLUDED
33#define GUARD_SQLITE_COMMAND_HPP_INCLUDED
34
35#include <concepts>
36#include <cstddef>
37#include <cstdint>
38#include <span>
39#include <string>
40#include <string_view>
41#include <type_traits>
42#include <utility>
43#include <vector>
44#include <sqlite/connection.hpp>
46
47struct sqlite3_stmt;
48
56namespace sqlite {
57inline namespace v2 {
58 template <typename T> struct named_parameter {
59 std::string name;
61 };
62
63 template <typename T> named_parameter<std::decay_t<T>> named(std::string_view name, T &&value) {
64 return {std::string(name), std::forward<T>(value)};
65 }
66
70 struct null_type {};
71
75 extern null_type nil;
76
80 struct command {
89 command(connection &con, std::string const &sql);
90 command(command const &) = delete;
91 command &operator=(command const &) = delete;
92
95 virtual ~command();
96
99 void clear();
101
106 bool step_once();
107
112
120 template <typename... Args> bool operator()(Args &&...args) {
121 if constexpr (sizeof...(Args) == 0) {
122 return operator()();
123 }
125 ((void)(*this % std::forward<Args>(args)), ...);
126 auto result = step();
127 last_arg_idx = 0;
128 return result;
129 }
130
134 void bind(int idx);
135
140 void bind(int idx, int v);
141
146 void bind(int idx, std::int64_t v);
147
152 void bind(int idx, double v);
153
158 template <typename Text>
159 requires std::convertible_to<Text, std::string_view>
160 void bind(int idx, Text &&text) {
161 bind_text_impl(idx, std::string_view(std::forward<Text>(text)));
162 }
163
169 void bind(int idx, void const *buf, size_t buf_size);
170
176 void bind(int idx, std::vector<unsigned char> const &v);
177 void bind(int idx, std::span<const unsigned char> v);
178 void bind(int idx, std::span<const std::byte> v);
179
180 template <typename Value> void bind_value(int idx, Value &&value);
181
182 int parameter_index(std::string_view name) const;
183
184 template <typename Value> void bind(std::string_view name, Value &&value) {
185 bind(parameter_index(name), std::forward<Value>(value));
186 }
187
188 template <typename Value>
190 void bind(int idx, Value &&value) {
191 bind_value(idx, std::forward<Value>(value));
192 }
193
202
209
215 command &operator%(std::int64_t p);
216
222 command &operator%(double p);
223
230 template <typename Text>
231 requires std::convertible_to<Text, std::string_view>
232 command &operator%(Text &&p) {
233 bind(++last_arg_idx, std::string_view(std::forward<Text>(p)));
234 return *this;
235 }
236
243 command &operator%(std::vector<unsigned char> const &p);
244 command &operator%(std::span<const unsigned char> p);
245 command &operator%(std::span<const std::byte> p);
246
247 template <typename T> command &operator%(named_parameter<T> param) {
248 bind(param.name, std::move(param.value));
249 return *this;
250 }
251
252 template <typename Value>
254 command &operator%(Value &&value) {
255 bind_value(++last_arg_idx, std::forward<Value>(value));
256 return *this;
257 }
258
259 protected:
260 void access_check() const;
261 bool step();
262 struct sqlite3 *get_handle();
263
264 private:
265 void prepare();
266 void finalize();
267 void bind_text_impl(int idx, std::string_view text);
268
269 private:
271 std::string m_sql;
272
273 protected:
274 sqlite3_stmt *stmt;
275
276 private:
278 };
279
280 template <typename Value> void command::bind_value(int idx, Value &&value) {
281 using decayed = detail::decay_t<Value>;
282 if constexpr (detail::is_optional_v<decayed>) {
283 if (!value) {
284 bind(idx);
285 } else {
286 bind_value(idx, *value);
287 }
288 } else if constexpr (detail::is_duration_v<decayed>) {
289 auto micros = std::chrono::duration_cast<std::chrono::microseconds>(value).count();
290 bind(idx, static_cast<std::int64_t>(micros));
291 } else if constexpr (detail::is_time_point_v<decayed>) {
292 auto micros =
293 std::chrono::duration_cast<std::chrono::microseconds>(value.time_since_epoch())
294 .count();
295 bind(idx, static_cast<std::int64_t>(micros));
296 } else if constexpr (std::is_enum_v<decayed>) {
297 bind(idx, static_cast<std::int64_t>(value));
298 } else if constexpr (std::is_integral_v<decayed>) {
299 bind(idx, static_cast<std::int64_t>(value));
300 } else if constexpr (std::is_floating_point_v<decayed>) {
301 bind(idx, static_cast<double>(value));
302 } else if constexpr (detail::is_string_like_v<decayed>) {
303 bind(idx, std::string_view(std::forward<Value>(value)));
304 } else if constexpr (detail::is_byte_vector_v<decayed>) {
305 bind(idx, value);
306 } else if constexpr (detail::is_unsigned_char_span_v<decayed>) {
307 bind(idx, value);
308 } else if constexpr (detail::is_byte_span_v<decayed>) {
309 bind(idx, value);
310 } else {
312 "Unsupported type for sqlite::command::bind_value");
313 }
314 }
315} // namespace v2
316} // namespace sqlite
317
318#endif // GUARD_SQLITE_COMMAND_HPP_INCLUDED
Owning RAII wrapper for sqlite3* handles plus attachment helpers and statement caching.
std::remove_cvref_t< T > decay_t
constexpr bool needs_generic_binding_v
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_string_like_v
constexpr bool is_duration_v
constexpr bool is_byte_span_v
named_parameter< std::decay_t< T > > named(std::string_view name, T &&value)
Definition command.hpp:63
null_type nil
nil is used instead of NULL within the operator % syntax in this wrapper
command is the base class of all sql command classes An object of this class is not copyable
Definition command.hpp:80
void bind(int idx, void const *buf, size_t buf_size)
binds the binary/blob buf to the given 1 based index
void bind_text_impl(int idx, std::string_view text)
command & operator%(double p)
replacement for void command::bind(int idx,double); Indexes are given automatically first call uses 1...
command & operator%(std::span< const unsigned char > p)
sqlite3_stmt * stmt
Definition command.hpp:274
command & operator=(command const &)=delete
void access_check() const
command & operator%(Value &&value)
Definition command.hpp:254
command & operator%(std::int64_t p)
replacement for void command::bind(int idx,std::int64_t); Indexes are given automatically first call ...
command & operator%(std::span< const std::byte > p)
void bind(int idx, double v)
binds the double v to the given 1 based index
void bind(int idx, int v)
binds the 32-Bit integer v to the given 1 based index
struct sqlite3 * get_handle()
void bind(int idx, std::int64_t v)
binds the 64-Bit integer v to the given 1 based index
void bind(int idx, std::span< const unsigned char > v)
void bind(std::string_view name, Value &&value)
Definition command.hpp:184
std::string m_sql
Definition command.hpp:271
bool step_once()
step_once executes the sql command a single time. If you have used placeholders you must have replace...
bool operator()(Args &&...args)
Binds all supplied arguments (if any) and executes the statement.
Definition command.hpp:120
command & operator%(null_type const &p)
replacement for void command::bind(int idx); To use this operator% you have to use the global object ...
command & operator%(int p)
replacement for void command::bind(int idx,int); Indexes are given automatically first call uses 1 as...
command & operator%(named_parameter< T > param)
Definition command.hpp:247
void bind(int idx, std::span< const std::byte > v)
void clear()
clear is used if you'd like to reuse a command object
command & operator%(std::vector< unsigned char > const &p)
replacement for void command::bind(int idx,std::vector<unsigned char> const&); Indexes are given auto...
void bind(int idx, Text &&text)
binds the text/string v to the given 1 based index
Definition command.hpp:160
command(connection &con, std::string const &sql)
command constructor
void bind(int idx, std::vector< unsigned char > const &v)
binds the binary/blob v to the given 1 based index
virtual ~command()
command destructor
command(command const &)=delete
bool operator()()
works exactly like command::step_once
void bind(int idx, Value &&value)
Definition command.hpp:190
command & operator%(Text &&p)
replacement for void command::bind(int idx,std::string const&); Indexes are given automatically first...
Definition command.hpp:232
int parameter_index(std::string_view name) const
void bind(int idx)
binds NULL to the given 1 based index
connection & m_con
Definition command.hpp:270
void bind_value(int idx, Value &&value)
Definition command.hpp:280
connection is used to open, close, attach and detach a database. Further it has to be passed to all c...
null_type is an empty type used to represent NULL values
Definition command.hpp:70
Forward-only cursor over the rows produced by a prepared statement.
Definition result.hpp:75