boost_sqlite 1
A sqlite C++ library
Loading...
Searching...
No Matches
catch.hpp
1//
2// Copyright (c) 2022 Klemens Morgenstern (klemens.morgenstern@gmx.net)
3//
4// Distributed under the Boost Software License, Version 1.0. (See accompanying
5// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6//
7
8#ifndef BOOST_SQLITE_DETAIL_CATCH_HPP
9#define BOOST_SQLITE_DETAIL_CATCH_HPP
10
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>
15
16#include <boost/system/system_error.hpp>
17
18#include <stdexcept>
19
20
21BOOST_SQLITE_BEGIN_NAMESPACE
22namespace detail
23{
24
25template<typename Func, typename ... Args>
26void execute_context_function_impl(std::false_type /* is_void */,
27 sqlite3_context * ctx,
28 Func && func, Args && ... args)
29 noexcept(noexcept(std::forward<Func>(func)(std::forward<Args>(args)...)))
30{
31 set_result(ctx, std::forward<Func>(func)(std::forward<Args>(args)...));
32}
33
34template<typename Func, typename ... Args>
35void execute_context_function_impl(std::true_type /* is_void */,
36 sqlite3_context * ctx,
37 Func && func, Args && ... args)
38 noexcept(noexcept(std::forward<Func>(func)(std::forward<Args>(args)...)))
39{
40 std::forward<Func>(func)(std::forward<Args>(args)...);
41}
42
43template<typename T>
44int extract_error(char * &errMsg, result<T> & res)
45{
46 error err = std::move(res).error();
47 if (err.info)
48 errMsg = err.info.release();
49 return err.code;
50}
51
52
53template<typename Func, typename ... Args>
54void execute_context_function(sqlite3_context * ctx,
55 Func && func, Args && ... args) noexcept
56{
57 using return_type = decltype(func(std::forward<Args>(args)...));
58#if !defined(BOOST_NO_EXCEPTIONS)
59 try
60 {
61#endif
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)
66 }
67 catch(boost::system::system_error & se)
68 {
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);
72 if (!msg.empty())
73 sqlite3_result_error(ctx, msg.data(), msg.size());
74 }
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)
79 {
80 sqlite3_result_error_code(ctx, SQLITE_MISUSE);
81 sqlite3_result_error(ctx, le.what(), std::strlen(le.what()));
82 }
83 catch(std::exception & ex)
84 {
85 sqlite3_result_error(ctx, ex.what(), std::strlen(ex.what()));
86 }
87 catch(...) {sqlite3_result_error_code(ctx, SQLITE_ERROR); }
88#endif
89}
90
91}
92BOOST_SQLITE_END_NAMESPACE
93
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()
99
100#else
101
102#define BOOST_SQLITE_TRY try
103#define BOOST_SQLITE_CATCH_RESULT(ctx) \
104catch(boost::system::system_error & se) \
105{ \
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); \
109 if (!msg.empty()) \
110 sqlite3_result_error(ctx, msg.data(), msg.size()); \
111} \
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) \
116{ \
117 sqlite3_result_error_code(ctx, SQLITE_MISUSE); \
118 sqlite3_result_error(ctx, le.what(), std::strlen(le.what())); \
119} \
120catch(std::exception & ex) \
121{ \
122 sqlite3_result_error(ctx, ex.what(), std::strlen(ex.what())); \
123} \
124catch(...) {sqlite3_result_error_code(ctx, SQLITE_ERROR); }
125
126
127#define BOOST_SQLITE_CATCH_ASSIGN_STR_AND_RETURN(msg) \
128catch (boost::system::system_error & se) \
129{ \
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(); \
135 return code; \
136} \
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) \
141{ \
142 msg = boost::sqlite::error_info(le.what()).release(); \
143 return SQLITE_MISUSE; \
144} \
145catch(std::exception & ex) \
146{ \
147 msg = boost::sqlite::error_info(ex.what()).release(); \
148 return SQLITE_ERROR; \
149} \
150catch(...) {return SQLITE_ERROR; } \
151
152
153#define BOOST_SQLITE_CATCH_AND_RETURN() \
154catch (boost::system::system_error & se) \
155{ \
156 auto code = SQLITE_ERROR; \
157 if (se.code().category() == boost::sqlite::sqlite_category()) \
158 code = se.code().value(); \
159 return code; \
160} \
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; } \
166
167#endif
168
169#endif //BOOST_SQLITE_DETAIL_CATCH_HPP