1 #ifndef __SQLITEXX_SQLITE_FUNCTIONS_H__
2 #define __SQLITEXX_SQLITE_FUNCTIONS_H__
15 template<std::
size_t N>
16 struct placeholder_template {
17 static placeholder_template pt;
20 template<std::
size_t N>
21 placeholder_template<N> placeholder_template<N>::pt;
25 template<std::
size_t N>
26 struct is_placeholder<sqlite::placeholder_template<N> > : std::integral_constant<std::size_t, N> {
32 enum class textencoding: int {
34 utf16le = SQLITE_UTF16LE,
35 utf16be = SQLITE_UTF16BE,
43 sqlite3_result_int(context, value);
46 inline void return_result(sqlite3_context *context, int64_t value) {
47 sqlite3_result_int64(context, value);
50 inline void return_result(sqlite3_context *context,
double value) {
51 sqlite3_result_double(context, value);
54 inline void return_result(sqlite3_context *context,
const std::string &value) {
55 sqlite3_result_text(context, value.c_str(), value.size(), SQLITE_TRANSIENT);
58 inline void return_result(sqlite3_context *context,
const std::u16string &value) {
59 sqlite3_result_text16(context, value.c_str(), value.size() *
sizeof(char16_t), SQLITE_TRANSIENT);
62 inline void return_result(sqlite3_context *context,
const value &value) {
63 sqlite3_result_value(context, value.handle());
66 inline void return_result(sqlite3_context *context,
const blob &value) {
67 sqlite3_result_blob(context, value.data(), value.size(), SQLITE_TRANSIENT);
71 struct function_traits :
public function_traits<decltype(&T::operator())>
74 template <
typename C,
typename R,
typename... Args>
75 struct function_traits<R(C::*)(Args...)> {
76 typedef std::function<R(Args...)> f_type;
77 static const size_t nargs =
sizeof...(Args);
79 typedef R result_type;
84 typedef typename std::tuple_element<i, std::tuple<Args...>>::type type;
88 template <
typename C,
typename R,
typename... Args>
89 struct function_traits<R(C::*)(Args...) const> {
90 typedef std::function<R(Args...)> f_type;
91 static const size_t nargs =
sizeof...(Args);
93 typedef R result_type;
98 typedef typename std::tuple_element<i, std::tuple<Args...>>::type type;
102 template <
typename R,
typename... Args>
103 struct function_traits<R(*)(Args...)> {
104 typedef std::function<R(Args...)> f_type;
105 static const size_t nargs =
sizeof...(Args);
107 typedef R result_type;
112 typedef typename std::tuple_element<i, std::tuple<Args...>>::type type;
116 template <
typename R,
typename... Args>
117 struct function_traits<R(&)(Args...)> {
118 typedef std::function<R(Args...)> f_type;
119 static const size_t nargs =
sizeof...(Args);
121 typedef R result_type;
126 typedef typename std::tuple_element<i, std::tuple<Args...>>::type type;
130 template <
typename T>
131 struct SQLiteFunctionTraits :
public SQLiteFunctionTraits<decltype(&T::operator())>
134 template <
typename C,
typename R>
135 struct SQLiteFunctionTraits<R(C::*)(const std::vector<value> &)> {
136 typedef std::function<R(const std::vector<value> &)> f_type;
139 template <
typename C,
typename R>
140 struct SQLiteFunctionTraits<R(C::*)(const std::vector<value> &) const> {
141 typedef std::function<R(const std::vector<value> &)> f_type;
144 template <
typename R>
145 struct SQLiteFunctionTraits<R(*)(
const std::vector<value> &)> {
146 typedef std::function<R(const std::vector<value> &)> f_type;
149 template <
typename R>
150 struct SQLiteFunctionTraits<R(&)(
const std::vector<value> &)> {
151 typedef std::function<R(const std::vector<value> &)> f_type;
154 template <
typename T>
155 struct collation_traits :
public collation_traits<decltype(&T::operator())>
158 template <
typename C>
159 struct collation_traits<int(C::*)(const std::string&, const std::string&)> {
160 typedef std::function<int(const std::string&, const std::string&)> f_type;
163 template <
typename C>
164 struct collation_traits<int(C::*)(const std::string&, const std::string&) const> {
165 typedef std::function<int(const std::string&, const std::string&)> f_type;
169 struct collation_traits<int(*)(
const std::string&,
const std::string&)> {
170 typedef std::function<int(const std::string&, const std::string&)> f_type;
174 struct collation_traits<int(&)(
const std::string&,
const std::string&)> {
175 typedef std::function<int(const std::string&, const std::string&)> f_type;
179 typename std::remove_reference<T>::type
get(sqlite3_value **values,
const std::size_t index) {
180 return value(values[index]);
183 template<
typename F,
typename C, std::size_t... Is>
184 typename function_traits<F>::f_type
185 bind_class_method(F method, C* classObject, std::index_sequence<Is...>) {
186 return std::bind(method, classObject, placeholder_template<Is+1>::pt...);
189 template<
typename F,
typename C>
190 typename function_traits<F>::f_type
191 bind_class_method(F method, C* classObject) {
192 return bind_class_method(method, classObject, std::make_index_sequence<function_traits<F>::nargs>{});
195 template<
typename R,
typename... Args, std::size_t... Is>
196 R invoke(std::function<R(Args...)> func, sqlite3_value **values, std::index_sequence<Is...>) {
200 return func(
get<
typename function_traits<decltype(func)>::
template arg<Is>::type>(values, Is) ...);
203 template<
typename R,
typename... Args>
204 R invoke(std::function<R(Args...)> func, sqlite3_value **values) {
205 return invoke(func, values, std::index_sequence_for<Args...>{});
208 template <
typename F>
209 void internal_scalar_function(sqlite3_context* context,
int argc, sqlite3_value **values) {
213 F* userScalarFunction =
static_cast<F*
>(sqlite3_user_data(context));
214 assert(userScalarFunction != 0);
217 auto result = invoke(*userScalarFunction, values);
219 }
catch (
const std::bad_alloc&) {
220 sqlite3_result_error_nomem(context);
222 sqlite3_result_error(context, e.what(), e.errcode);
223 }
catch (
const std::exception& e) {
224 sqlite3_result_error(context, e.what(), SQLITE_ABORT);
226 sqlite3_result_error_code(context, SQLITE_ABORT);
230 template <
typename F>
231 void internal_general_scalar_function(sqlite3_context* context,
int argc, sqlite3_value **values) {
232 F* userScalarFunction =
static_cast<F*
>(sqlite3_user_data(context));
233 assert(userScalarFunction != 0);
236 std::vector<value> argValues;
237 for (
int i = 0; i < argc; ++i) {
238 argValues.push_back(value(values[i]));
241 auto result = (*userScalarFunction)(argValues);
243 }
catch (
const std::bad_alloc&) {
244 sqlite3_result_error_nomem(context);
246 sqlite3_result_error(context, e.what(), e.errcode);
247 }
catch (
const std::exception& e) {
248 sqlite3_result_error(context, e.what(), SQLITE_ABORT);
250 sqlite3_result_error_code(context, SQLITE_ABORT);
254 template <
typename F>
255 int internal_collation_function(
void* context,
int bytes1,
const void* string_bytes1,
int bytes2,
const void* string_bytes2) {
256 F* userCollationFunction =
static_cast<F*
>(context);
257 assert(userCollationFunction != 0);
259 const std::string string1(static_cast<const char*>(string_bytes1), bytes1);
260 const std::string string2(static_cast<const char*>(string_bytes2), bytes2);
262 int result = (*userCollationFunction)(string1, string2);
267 template<
typename Call>
268 void internal_delete(
void *user_data) {
269 Call *callback =
static_cast<Call *
>(user_data);
270 assert(callback != 0);
276 class aggregate_wrapper {
278 aggregate_wrapper() :
282 void step(sqlite3_context* context,
int argc, sqlite3_value **values) {
285 invoke(bind_class_method(&T::step, &m_implementation), values);
288 void finalize(sqlite3_context* context) {
293 m_implementation = T();
300 template <
typename T>
301 void internal_step(sqlite3_context* context,
int argc, sqlite3_value **values) {
302 T* wrapper =
static_cast<T*
>(sqlite3_user_data(context));
303 assert(wrapper != 0);
306 wrapper->step(context, argc, values);
307 }
catch (
const std::bad_alloc&) {
308 sqlite3_result_error_nomem(context);
310 sqlite3_result_error(context, e.what(), e.errcode);
311 }
catch (
const std::exception& e) {
312 sqlite3_result_error(context, e.what(), SQLITE_ABORT);
314 sqlite3_result_error_code(context, SQLITE_ABORT);
318 template <
typename T>
319 void internal_final(sqlite3_context* context) {
320 T* wrapper =
static_cast<T*
>(sqlite3_user_data(context));
321 assert(wrapper != 0);
324 wrapper->finalize(context);
326 }
catch (
const std::bad_alloc&) {
327 sqlite3_result_error_nomem(context);
329 sqlite3_result_error(context, e.what(), e.errcode);
330 }
catch (
const std::exception& e) {
331 sqlite3_result_error(context, e.what(), SQLITE_ABORT);
333 sqlite3_result_error_code(context, SQLITE_ABORT);
337 template <
typename T>
338 void internal_dispose(
void *user_data) {
339 T* wrapper =
static_cast<T *
>(user_data);
340 assert(wrapper != 0);
A SQLite dynamically typed value object, aka "sqlite3_value".
Encapsulation of the error code and message from SQLite3, based on std::runtime_error.
void return_result(sqlite3_context *context, int value)
Helpers for setting result of scalar functions.