1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
|
== `sqlite/statement.hpp`
=== `param_ref`
A reference to a value to temporary bind for an execute statement. Most values are captures by reference.
[source,cpp]
----
struct param_ref
{
// Default construct a parameter, gives `null`.
param_ref() = default;
// Bind null
param_ref(variant2::monostate);
// Bind null
param_ref(std::nullptr_t);
// Bind an integer.
template<typename I>
param_ref(I value);
// Bind a blob.
param_ref(blob_view blob);
// Bind a string.
param_ref(string_view text);
template<typename StringLike>
param_ref(StringLike && text);
template<typename BlobLike>
param_ref(BlobLike && text);
// Bind a floating point value.
param_ref(double value) : impl_(value) { }
// Bind a zero_blob value, i.e. a blob that initialized by zero.
param_ref(zero_blob zb) : impl_(zb) { }
// Bind pointer value to the parameter. @see https://www.sqlite.org/bindptr.html
// Requires sqlite 3.20
// Deleter must a function pointer or trivially constructible.
template<typename T, typename Deleter>
param_ref(std::unique_ptr<T, Deleter> ptr);
// Apply the param_ref to a statement.
int apply(sqlite3_stmt * stmt, int c) const;
// Construct param_ref from a variant
template<typename T>
param_ref(T && t);
----
=== `statement`
A statement used for a prepared-statement.
[source,cpp]
----
struct statement
{
// execute the prepared statement once. This transfers ownership to the resultset
template <typename ArgRange = std::initializer_list<param_ref>>
resultset execute(ArgRange && params, system::error_code& ec, error_info& info) &&; // <1>
template <typename ArgRange = std::initializer_list<param_ref>
resultset execute(ArgRange && params) &&; // <1>
resultset execute(
std::initializer_list<std::pair<string_view, param_ref>> params,
system::error_code& ec,
error_info& info) &&; // <2>
resultset execute(std::initializer_list<std::pair<string_view, param_ref>> params) &&;
template<typename T, bool Strict = false, typename ArgRange = std::initializer_list<param_ref>>
static_resultset<T, Strict> execute(
ArgRange && params,
system::error_code & ec,
error_info & ei) &&; // <1>
template<typename T, bool Strict = false, typename ArgRange = std::initializer_list<param_ref>>
static_resultset<T, Strict> execute(ArgRange && params) &&; // <1>
template<typename T, bool Strict = false>
static_resultset<T, Strict> execute(
std::initializer_list<std::pair<string_view, param_ref>> params,
system::error_code & ec,
error_info & ei) &&; // <2>
template<typename T, bool Strict = false>
static_resultset<T, Strict> execute(std::initializer_list<std::pair<string_view, param_ref>> params) &&; // <2>
template <typename ArgRange = std::initializer_list<param_ref>>
resultset execute(
ArgRange && params,
system::error_code& ec,
error_info& info) &; // <1>
template <typename ArgRange = std::initializer_list<param_ref>>
resultset execute(ArgRange && params) &; // <1>
resultset execute(
std::initializer_list<std::pair<string_view, param_ref>> params,
system::error_code& ec,
error_info& info) &; // <2>
resultset execute(std::initializer_list<std::pair<string_view, param_ref>> params) &; // <2>
template<typename T, bool Strict = false, typename ArgRange = std::initializer_list<param_ref>>
static_resultset<T, Strict> execute(
ArgRange && params,
system::error_code & ec,
error_info & ei) &; // <1>
template<typename T, bool Strict = false, typename ArgRange = std::initializer_list<param_ref>>
static_resultset<T, Strict> execute(ArgRange && params) &; // <1>
template<typename T, bool Strict = false>
static_resultset<T, Strict> execute(
std::initializer_list<std::pair<string_view, param_ref>> params,
system::error_code & ec,
error_info & ei) &; // <2>
template<typename T, bool Strict = false>
static_resultset<T, Strict> execute(std::initializer_list<std::pair<string_view, param_ref>> params) &; // <2>
// Returns the sql used to construct the prepared statement.
stringe_view sql();
// Returns the expanded sql used to construct the prepared statement. Requires sqlite 3.14
stringe_view expanded_sql();
// Returns the expanded sql used to construct the prepared statement. requiers sqlite to be compiles with SQLITE_ENABLE_NORMALIZE.
stringe_view normalized_sql();
// Returns the declared type of the column
string_view declared_type(int id) const;
};
----
<1> Executes a query with positional arguments
<2> Executes a query with named arguments (from a map-like object)
WARNING: The `&&` overloads transfer ownership to the resultset, while the `&` keep them in the statement.
That is, this is UB:
[source,cpp]
----
resultset get_users(sqlite::connection & conn)
{
auto s = conn.prepare("SELECT * from users where name = ?");
return s.execute({"allen"}); // UB, because result set points into s
}
resultset get_users(sqlite::connection & conn)
{
// correct, because resultset takes ownershipo
return conn.prepare("SELECT * from users where name = ?").execute({"allen"});
}
----
|