8#ifndef BOOST_SQLITE_DETAIL_CATCH_HPP
9#define BOOST_SQLITE_DETAIL_CATCH_HPP
11#include <boost/sqlite/detail/config.hpp>
12#include <boost/sqlite/detail/exception.hpp>
13#include <boost/sqlite/error.hpp>
14#include <boost/sqlite/result.hpp>
16#include <boost/system/system_error.hpp>
21BOOST_SQLITE_BEGIN_NAMESPACE
25template<
typename Func,
typename ... Args>
26void execute_context_function_impl(std::false_type ,
27 sqlite3_context * ctx,
28 Func && func, Args && ... args)
29 noexcept(
noexcept(std::forward<Func>(func)(std::forward<Args>(args)...)))
31 set_result(ctx, std::forward<Func>(func)(std::forward<Args>(args)...));
34template<
typename Func,
typename ... Args>
35void execute_context_function_impl(std::true_type ,
36 sqlite3_context * ctx,
37 Func && func, Args && ... args)
38 noexcept(
noexcept(std::forward<Func>(func)(std::forward<Args>(args)...)))
40 std::forward<Func>(func)(std::forward<Args>(args)...);
44int extract_error(
char * &errMsg, result<T> & res)
46 error err = std::move(res).error();
48 errMsg = err.info.release();
53template<
typename Func,
typename ... Args>
54void execute_context_function(sqlite3_context * ctx,
55 Func && func, Args && ... args)
noexcept
57 using return_type =
decltype(func(std::forward<Args>(args)...));
58#if !defined(BOOST_NO_EXCEPTIONS)
62 execute_context_function_impl(std::is_void<return_type>{}, ctx,
63 std::forward<Func>(func),
64 std::forward<Args>(args)...);
65#if !defined(BOOST_NO_EXCEPTIONS)
67 catch(boost::system::system_error & se)
69 if (se.code().category() == boost::sqlite::sqlite_category())
70 sqlite3_result_error_code(ctx, se.code().value());
71 const auto msg = boost::sqlite::detail::get_message(se);
73 sqlite3_result_error(ctx, msg.data(), msg.size());
75 catch(std::bad_alloc &) { sqlite3_result_error_nomem(ctx); }
76 catch(std::length_error &) { sqlite3_result_error_toobig(ctx); }
77 catch(std::out_of_range &) { sqlite3_result_error_code(ctx, SQLITE_RANGE);}
78 catch(std::logic_error &le)
80 sqlite3_result_error_code(ctx, SQLITE_MISUSE);
81 sqlite3_result_error(ctx, le.what(), std::strlen(le.what()));
83 catch(std::exception & ex)
85 sqlite3_result_error(ctx, ex.what(), std::strlen(ex.what()));
87 catch(...) {sqlite3_result_error_code(ctx, SQLITE_ERROR); }
92BOOST_SQLITE_END_NAMESPACE
94#if defined(BOOST_NO_EXCEPTIONS)
95#define BOOST_SQLITE_TRY
96#define BOOST_SQLITE_CATCH_RESULT(ctx)
97#define BOOST_SQLITE_CATCH_ASSIGN_STR_AND_RETURN(msg)
98#define BOOST_SQLITE_CATCH_AND_RETURN()
102#define BOOST_SQLITE_TRY try
103#define BOOST_SQLITE_CATCH_RESULT(ctx) \
104catch(boost::system::system_error & se) \
106 if (se.code().category() == boost::sqlite::sqlite_category()) \
107 sqlite3_result_error_code(ctx, se.code().value()); \
108 const auto msg = boost::sqlite::detail::get_message(se); \
110 sqlite3_result_error(ctx, msg.data(), msg.size()); \
112catch(std::bad_alloc &) { sqlite3_result_error_nomem(ctx); } \
113catch(std::length_error &) { sqlite3_result_error_toobig(ctx); } \
114catch(std::out_of_range &) { sqlite3_result_error_code(ctx, SQLITE_RANGE);} \
115catch(std::logic_error &le) \
117 sqlite3_result_error_code(ctx, SQLITE_MISUSE); \
118 sqlite3_result_error(ctx, le.what(), std::strlen(le.what())); \
120catch(std::exception & ex) \
122 sqlite3_result_error(ctx, ex.what(), std::strlen(ex.what())); \
124catch(...) {sqlite3_result_error_code(ctx, SQLITE_ERROR); }
127#define BOOST_SQLITE_CATCH_ASSIGN_STR_AND_RETURN(msg) \
128catch (boost::system::system_error & se) \
130 auto code = SQLITE_ERROR; \
131 if (se.code().category() == boost::sqlite::sqlite_category()) \
132 code = se.code().value(); \
133 const auto pre = boost::sqlite::detail::get_message(se); \
134 msg = boost::sqlite::error_info(pre).release(); \
137catch(std::bad_alloc &) { return SQLITE_NOMEM; } \
138catch(std::length_error &) { return SQLITE_TOOBIG; } \
139catch(std::out_of_range &) { return SQLITE_RANGE;} \
140catch(std::logic_error &le) \
142 msg = boost::sqlite::error_info(le.what()).release(); \
143 return SQLITE_MISUSE; \
145catch(std::exception & ex) \
147 msg = boost::sqlite::error_info(ex.what()).release(); \
148 return SQLITE_ERROR; \
150catch(...) {return SQLITE_ERROR; } \
153#define BOOST_SQLITE_CATCH_AND_RETURN() \
154catch (boost::system::system_error & se) \
156 auto code = SQLITE_ERROR; \
157 if (se.code().category() == boost::sqlite::sqlite_category()) \
158 code = se.code().value(); \
161catch(std::bad_alloc &) { return SQLITE_NOMEM; } \
162catch(std::length_error &) { return SQLITE_TOOBIG; } \
163catch(std::out_of_range &) { return SQLITE_RANGE;} \
164catch(std::logic_error &) { return SQLITE_MISUSE;} \
165catch(...) { return SQLITE_ERROR; } \