Skip to content

Commit 0312f0d

Browse files
committed
Second try for error logging
1 parent e05aa4b commit 0312f0d

File tree

2 files changed

+108
-0
lines changed

2 files changed

+108
-0
lines changed

hdr/sqlite_modern_cpp/log.h

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
#include "errors.h"
2+
3+
#include <sqlite3.h>
4+
5+
#include <utility>
6+
#include <tuple>
7+
#include <type_traits>
8+
9+
namespace sqlite {
10+
namespace detail {
11+
template<class Functor, class ...Functors>
12+
class FunctorOverload: public Functor, public FunctorOverload<Functors...> {
13+
public:
14+
template<class Functor1, class ...Remaining>
15+
FunctorOverload(Functor1 &&functor, Remaining &&... remaining):
16+
Functor(std::forward<Functor1>(functor)),
17+
FunctorOverload<Functors...>(std::forward<Remaining>(remaining)...) {}
18+
using Functor::operator();
19+
using FunctorOverload<Functors...>::operator();
20+
};
21+
template<class Functor>
22+
class FunctorOverload<Functor>: public Functor {
23+
public:
24+
template<class Functor1>
25+
FunctorOverload(Functor1 &&functor):
26+
Functor(std::forward<Functor1>(functor)) {}
27+
using Functor::operator();
28+
};
29+
}
30+
template<class Handler>
31+
typename std::enable_if<!std::is_callable<Handler(const sqlite_exception&)>::value>::type
32+
error_log(Handler &&handler);
33+
template<class Handler>
34+
typename std::enable_if<std::is_callable<Handler(const sqlite_exception&)>::value>::type
35+
error_log(Handler &&handler);
36+
template<class ...Handler>
37+
typename std::enable_if<sizeof...(Handler)>=2>::type
38+
error_log(Handler &&...handler) {
39+
return error_log(detail::FunctorOverload<typename std::decay<Handler>::type...>(std::forward<Handler>(handler)...));
40+
}
41+
template<class Handler>
42+
typename std::enable_if<!std::is_callable<Handler(const sqlite_exception&)>::value>::type
43+
error_log(Handler &&handler) {
44+
return error_log(std::forward<Handler>(handler), [](const sqlite_exception&) {});
45+
}
46+
template<class Handler>
47+
typename std::enable_if<std::is_callable<Handler(const sqlite_exception&)>::value>::type
48+
error_log(Handler &&handler) {
49+
auto ptr = new auto([handler = std::forward<Handler>(handler)](int error_code, const char *errstr) mutable {
50+
switch(error_code & 0xFF) {
51+
#define SQLITE_MODERN_CPP_ERROR_CODE(NAME,name,derived) \
52+
case SQLITE_ ## NAME: switch(error_code) { \
53+
derived \
54+
default: handler(errors::name(errstr, "", error_code)); \
55+
};break;
56+
#define SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(BASE,SUB,base,sub) \
57+
case SQLITE_ ## BASE ## _ ## SUB: \
58+
handler(errors::base ## _ ## sub(errstr, "", error_code)); \
59+
break;
60+
#include "lists/error_codes.h"
61+
#undef SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED
62+
#undef SQLITE_MODERN_CPP_ERROR_CODE
63+
default: handler(sqlite_exception(errstr, "", error_code)); \
64+
}
65+
});
66+
sqlite3_config(SQLITE_CONFIG_LOG, (void(*)(void*,int,const char*))[](void *functor, int error_code, const char *errstr) {
67+
(*static_cast<decltype(ptr)>(functor))(error_code, errstr);
68+
}, ptr);
69+
}
70+
}

tests/error_log.cc

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#include <iostream>
2+
#include <iomanip>
3+
#include <string>
4+
#include <memory>
5+
#include <stdexcept>
6+
#include <sqlite_modern_cpp.h>
7+
#include <sqlite_modern_cpp/log.h>
8+
using namespace sqlite;
9+
using namespace std;
10+
11+
12+
int main() {
13+
bool error_detected = false;
14+
error_log(
15+
[&](errors::constraint) {
16+
cerr << "Wrong error detected!" << endl;
17+
},
18+
[&](errors::constraint_primarykey e) {
19+
cerr << e.get_code() << '/' << e.get_extended_code() << ": " << e.what() << endl;
20+
error_detected = true;
21+
}
22+
);
23+
database db(":memory:");
24+
db << "CREATE TABLE person (id integer primary key not null, name TEXT);";
25+
26+
try {
27+
db << "INSERT INTO person (id,name) VALUES (?,?)" << 1 << "jack";
28+
// inserting again to produce error
29+
db << "INSERT INTO person (id,name) VALUES (?,?)" << 1 << "jack";
30+
} catch (errors::constraint& e) {
31+
}
32+
33+
if(!error_detected) {
34+
exit(EXIT_FAILURE);
35+
}
36+
37+
exit(EXIT_SUCCESS);
38+
}

0 commit comments

Comments
 (0)