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 <memory>
39#include <span>
40#include <string>
41#include <string_view>
42#include <type_traits>
43#include <utility>
44#include <vector>
45#include <sqlite/connection.hpp>
47
48struct sqlite3_stmt;
49
57namespace sqlite {
58inline namespace v2 {
59 template <typename T> struct named_parameter {
60 std::string name;
62 };
63
64 template <typename T> named_parameter<std::decay_t<T>> named(std::string_view name, T &&value) {
65 return {std::string(name), std::forward<T>(value)};
66 }
67
71 struct null_type {};
72
76 extern null_type nil;
77
81 struct command {
82 struct statement_handle;
83
92 command(connection &con, std::string const &sql);
93 command(command const &) = delete;
94 command &operator=(command const &) = delete;
95
98 virtual ~command();
99
102 void clear();
104
109 bool step_once();
110
115
123 template <typename... Args> bool operator()(Args &&...args) {
124 if constexpr (sizeof...(Args) == 0) {
125 return operator()();
126 }
128 ((void)(*this % std::forward<Args>(args)), ...);
129 auto result = step();
130 last_arg_idx = 0;
131 return result;
132 }
133
137 void bind(int idx);
138
143 void bind(int idx, int v);
144
149 void bind(int idx, std::int64_t v);
150
155 void bind(int idx, double v);
156
161 template <typename Text>
162 requires std::convertible_to<Text, std::string_view>
163 void bind(int idx, Text &&text) {
164 bind_text_impl(idx, std::string_view(std::forward<Text>(text)));
165 }
166
172 void bind(int idx, void const *buf, size_t buf_size);
173
179 void bind(int idx, std::vector<unsigned char> const &v);
180 void bind(int idx, std::span<const unsigned char> v);
181 void bind(int idx, std::span<const std::byte> v);
182
183 template <typename Value> void bind_value(int idx, Value &&value);
184
185 int parameter_index(std::string_view name) const;
186
187 template <typename Value> void bind(std::string_view name, Value &&value) {
188 bind(parameter_index(name), std::forward<Value>(value));
189 }
190
191 template <typename Value>
193 void bind(int idx, Value &&value) {
194 bind_value(idx, std::forward<Value>(value));
195 }
196
205
212
218 command &operator%(std::int64_t p);
219
225 command &operator%(double p);
226
233 template <typename Text>
234 requires std::convertible_to<Text, std::string_view>
235 command &operator%(Text &&p) {
236 bind(++last_arg_idx, std::string_view(std::forward<Text>(p)));
237 return *this;
238 }
239
246 command &operator%(std::vector<unsigned char> const &p);
247 command &operator%(std::span<const unsigned char> p);
248 command &operator%(std::span<const std::byte> p);
249
250 template <typename T> command &operator%(named_parameter<T> param) {
251 bind(param.name, std::move(param.value));
252 return *this;
253 }
254
255 template <typename Value>
257 command &operator%(Value &&value) {
258 bind_value(++last_arg_idx, std::forward<Value>(value));
259 return *this;
260 }
261
262 protected:
263 void access_check() const;
264 bool step();
265 struct sqlite3 *get_handle();
266 std::string const &sql_text() const noexcept;
267 std::shared_ptr<statement_handle> shared_statement() const;
268
269 private:
270 void prepare();
271 void finalize();
272 void bind_text_impl(int idx, std::string_view text);
273
274 private:
276 std::string m_sql;
277
278 protected:
279 sqlite3_stmt *stmt;
280
281 private:
282 std::shared_ptr<statement_handle> stmt_owner_;
284 };
285
286 template <typename Value> void command::bind_value(int idx, Value &&value) {
287 using decayed = detail::decay_t<Value>;
288 if constexpr (detail::is_optional_v<decayed>) {
289 if (!value) {
290 bind(idx);
291 } else {
292 bind_value(idx, *value);
293 }
294 } else if constexpr (detail::is_duration_v<decayed>) {
295 auto micros = std::chrono::duration_cast<std::chrono::microseconds>(value).count();
296 bind(idx, static_cast<std::int64_t>(micros));
297 } else if constexpr (detail::is_time_point_v<decayed>) {
298 auto micros =
299 std::chrono::duration_cast<std::chrono::microseconds>(value.time_since_epoch())
300 .count();
301 bind(idx, static_cast<std::int64_t>(micros));
302 } else if constexpr (std::is_enum_v<decayed>) {
303 bind(idx, static_cast<std::int64_t>(value));
304 } else if constexpr (std::is_integral_v<decayed>) {
305 bind(idx, static_cast<std::int64_t>(value));
306 } else if constexpr (std::is_floating_point_v<decayed>) {
307 bind(idx, static_cast<double>(value));
308 } else if constexpr (detail::is_string_like_v<decayed>) {
309 bind(idx, std::string_view(std::forward<Value>(value)));
310 } else if constexpr (detail::is_byte_vector_v<decayed>) {
311 bind(idx, value);
312 } else if constexpr (detail::is_unsigned_char_span_v<decayed>) {
313 bind(idx, value);
314 } else if constexpr (detail::is_byte_span_v<decayed>) {
315 bind(idx, value);
316 } else {
318 "Unsupported type for sqlite::command::bind_value");
319 }
320 }
321} // namespace v2
322} // namespace sqlite
323
324#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:64
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:81
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:279
command & operator=(command const &)=delete
void access_check() const
command & operator%(Value &&value)
Definition command.hpp:257
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)
std::shared_ptr< statement_handle > stmt_owner_
Definition command.hpp:282
void bind(std::string_view name, Value &&value)
Definition command.hpp:187
std::string m_sql
Definition command.hpp:276
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:123
std::shared_ptr< statement_handle > shared_statement() const
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:250
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...
std::string const & sql_text() const noexcept
void bind(int idx, Text &&text)
binds the text/string v to the given 1 based index
Definition command.hpp:163
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:193
command & operator%(Text &&p)
replacement for void command::bind(int idx,std::string const&); Indexes are given automatically first...
Definition command.hpp:235
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:275
void bind_value(int idx, Value &&value)
Definition command.hpp:286
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:71
Forward-only cursor over the rows produced by a prepared statement.
Definition result.hpp:75