Skip to content

Commit 09893c6

Browse files
committed
Support extended result codes
1 parent 1b956b7 commit 09893c6

File tree

3 files changed

+93
-20
lines changed

3 files changed

+93
-20
lines changed

hdr/sqlite_modern_cpp.h

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@ namespace sqlite {
4343
public:
4444
sqlite_exception(const char* msg, std::string sql, int code = -1): runtime_error(msg), code(code), sql(sql) {}
4545
sqlite_exception(int code, std::string sql): runtime_error(sqlite3_errstr(code)), code(code), sql(sql) {}
46-
int get_code() const {return code;}
46+
int get_code() const {return code & 0xFF;}
47+
int get_extended_code() const {return code;}
4748
std::string get_sql() const {return sql;}
4849
private:
4950
int code;
@@ -57,8 +58,12 @@ namespace sqlite {
5758
//
5859
//Note these names are exact matches to the names of the SQLITE error codes.
5960
#define SQLITE_MODERN_CPP_ERROR_CODE(NAME,name,derived) \
60-
class name: public sqlite_exception { using sqlite_exception::sqlite_exception; };
61+
class name: public sqlite_exception { using sqlite_exception::sqlite_exception; };\
62+
derived
63+
#define SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(BASE,SUB,base,sub) \
64+
class base ## _ ## sub: public base { using base::base; };
6165
#include "sqlite_modern_cpp/lists/error_codes.h"
66+
#undef SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED
6267
#undef SQLITE_MODERN_CPP_ERROR_CODE
6368

6469
//Some additional errors are here for the C++ interface
@@ -68,10 +73,16 @@ namespace sqlite {
6873
class more_statements: public sqlite_exception { using sqlite_exception::sqlite_exception; }; // Prepared statements can only contain one statement
6974

7075
static void throw_sqlite_error(const int& error_code, const std::string &sql = "") {
71-
switch(error_code) {
72-
#define SQLITE_MODERN_CPP_ERROR_CODE(NAME,name,derived) \
73-
case SQLITE_ ## NAME: throw exceptions::name(error_code, sql);
76+
switch(error_code & 0xFF) {
77+
#define SQLITE_MODERN_CPP_ERROR_CODE(NAME,name,derived) \
78+
case SQLITE_ ## NAME: switch(error_code) { \
79+
derived \
80+
default: throw exceptions::name(error_code, sql); \
81+
}
82+
#define SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(BASE,SUB,base,sub) \
83+
case SQLITE_ ## BASE ## _ ## SUB: throw base ## _ ## sub(error_code, sql);
7484
#include "sqlite_modern_cpp/lists/error_codes.h"
85+
#undef SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED
7586
#undef SQLITE_MODERN_CPP_ERROR_CODE
7687
default: throw sqlite_exception(error_code, sql);
7788
}
@@ -428,7 +439,8 @@ namespace sqlite {
428439
sqlite3* tmp = nullptr;
429440
auto ret = sqlite3_open_v2(db_name.data(), &tmp, static_cast<int>(config.flags), config.zVfs);
430441
_db = std::shared_ptr<sqlite3>(tmp, [=](sqlite3* ptr) { sqlite3_close_v2(ptr); }); // this will close the connection eventually when no longer needed.
431-
if(ret != SQLITE_OK) exceptions::throw_sqlite_error(ret);
442+
if(ret != SQLITE_OK) exceptions::throw_sqlite_error(_db ? sqlite3_extended_errcode(_db.get()) : ret);
443+
sqlite3_extended_result_codes(_db.get(), true);
432444
if(config.encoding == Encoding::UTF16)
433445
*this << R"(PRAGMA encoding = "UTF-16";)";
434446
}
@@ -442,7 +454,8 @@ namespace sqlite {
442454
sqlite3* tmp = nullptr;
443455
auto ret = sqlite3_open_v2(db_name_utf8.data(), &tmp, static_cast<int>(config.flags), config.zVfs);
444456
_db = std::shared_ptr<sqlite3>(tmp, [=](sqlite3* ptr) { sqlite3_close_v2(ptr); }); // this will close the connection eventually when no longer needed.
445-
if(ret != SQLITE_OK) exceptions::throw_sqlite_error(ret);
457+
if(ret != SQLITE_OK) exceptions::throw_sqlite_error(_db ? sqlite3_extended_errcode(_db.get()) : ret);
458+
sqlite3_extended_result_codes(_db.get(), true);
446459
if(config.encoding != Encoding::UTF8)
447460
*this << R"(PRAGMA encoding = "UTF-16";)";
448461
}
Lines changed: 71 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,89 @@
11
SQLITE_MODERN_CPP_ERROR_CODE(ERROR,error,)
22
SQLITE_MODERN_CPP_ERROR_CODE(INTERNAL,internal,)
33
SQLITE_MODERN_CPP_ERROR_CODE(PERM,perm,)
4-
SQLITE_MODERN_CPP_ERROR_CODE(ABORT,abort,)
5-
SQLITE_MODERN_CPP_ERROR_CODE(BUSY,busy,)
6-
SQLITE_MODERN_CPP_ERROR_CODE(LOCKED,locked,)
4+
SQLITE_MODERN_CPP_ERROR_CODE(ABORT,abort,
5+
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(ABORT,ROLLBACK,abort,rollback)
6+
)
7+
SQLITE_MODERN_CPP_ERROR_CODE(BUSY,busy,
8+
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(BUSY,RECOVERY,busy,recovery)
9+
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(BUSY,SNAPSHOT,busy,snapshot)
10+
)
11+
SQLITE_MODERN_CPP_ERROR_CODE(LOCKED,locked,
12+
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(LOCKED,SHAREDCACHE,locked,sharedcache)
13+
)
714
SQLITE_MODERN_CPP_ERROR_CODE(NOMEM,nomem,)
815
SQLITE_MODERN_CPP_ERROR_CODE(READONLY,readonly,)
916
SQLITE_MODERN_CPP_ERROR_CODE(INTERRUPT,interrupt,)
10-
SQLITE_MODERN_CPP_ERROR_CODE(IOERR,ioerr,)
11-
SQLITE_MODERN_CPP_ERROR_CODE(CORRUPT,corrupt,)
17+
SQLITE_MODERN_CPP_ERROR_CODE(IOERR,ioerr,
18+
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(IOERR,READ,ioerr,read)
19+
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(IOERR,SHORT_READ,ioerr,short_read)
20+
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(IOERR,WRITE,ioerr,write)
21+
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(IOERR,FSYNC,ioerr,fsync)
22+
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(IOERR,DIR_FSYNC,ioerr,dir_fsync)
23+
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(IOERR,TRUNCATE,ioerr,truncate)
24+
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(IOERR,FSTAT,ioerr,fstat)
25+
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(IOERR,UNLOCK,ioerr,unlock)
26+
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(IOERR,RDLOCK,ioerr,rdlock)
27+
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(IOERR,DELETE,ioerr,delete)
28+
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(IOERR,BLOCKED,ioerr,blocked)
29+
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(IOERR,NOMEM,ioerr,nomem)
30+
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(IOERR,ACCESS,ioerr,access)
31+
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(IOERR,CHECKRESERVEDLOCK,ioerr,checkreservedlock)
32+
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(IOERR,LOCK,ioerr,lock)
33+
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(IOERR,CLOSE,ioerr,close)
34+
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(IOERR,DIR_CLOSE,ioerr,dir_close)
35+
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(IOERR,SHMOPEN,ioerr,shmopen)
36+
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(IOERR,SHMSIZE,ioerr,shmsize)
37+
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(IOERR,SHMLOCK,ioerr,shmlock)
38+
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(IOERR,SHMMAP,ioerr,shmmap)
39+
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(IOERR,SEEK,ioerr,seek)
40+
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(IOERR,DELETE_NOENT,ioerr,delete_noent)
41+
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(IOERR,MMAP,ioerr,mmap)
42+
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(IOERR,GETTEMPPATH,ioerr,gettemppath)
43+
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(IOERR,CONVPATH,ioerr,convpath)
44+
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(IOERR,VNODE,ioerr,vnode)
45+
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(IOERR,AUTH,ioerr,auth)
46+
)
47+
SQLITE_MODERN_CPP_ERROR_CODE(CORRUPT,corrupt,
48+
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(CORRUPT,VTAB,corrupt,vtab)
49+
)
1250
SQLITE_MODERN_CPP_ERROR_CODE(NOTFOUND,notfound,)
1351
SQLITE_MODERN_CPP_ERROR_CODE(FULL,full,)
14-
SQLITE_MODERN_CPP_ERROR_CODE(CANTOPEN,cantopen,)
52+
SQLITE_MODERN_CPP_ERROR_CODE(CANTOPEN,cantopen,
53+
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(CANTOPEN,NOTEMPDIR,cantopen,notempdir)
54+
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(CANTOPEN,ISDIR,cantopen,isdir)
55+
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(CANTOPEN,FULLPATH,cantopen,fullpath)
56+
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(CANTOPEN,CONVPATH,cantopen,convpath)
57+
)
1558
SQLITE_MODERN_CPP_ERROR_CODE(PROTOCOL,protocol,)
1659
SQLITE_MODERN_CPP_ERROR_CODE(EMPTY,empty,)
1760
SQLITE_MODERN_CPP_ERROR_CODE(SCHEMA,schema,)
1861
SQLITE_MODERN_CPP_ERROR_CODE(TOOBIG,toobig,)
19-
SQLITE_MODERN_CPP_ERROR_CODE(CONSTRAINT,constraint,)
62+
SQLITE_MODERN_CPP_ERROR_CODE(CONSTRAINT,constraint,
63+
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(CONSTRAINT,CHECK,constraint,check)
64+
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(CONSTRAINT,COMMITHOOK,constraint,commithook)
65+
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(CONSTRAINT,FOREIGNKEY,constraint,foreignkey)
66+
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(CONSTRAINT,FUNCTION,constraint,function)
67+
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(CONSTRAINT,NOTNULL,constraint,notnull)
68+
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(CONSTRAINT,PRIMARYKEY,constraint,primarykey)
69+
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(CONSTRAINT,TRIGGER,constraint,trigger)
70+
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(CONSTRAINT,UNIQUE,constraint,unique)
71+
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(CONSTRAINT,VTAB,constraint,vtab)
72+
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(CONSTRAINT,ROWID,constraint,rowid)
73+
)
2074
SQLITE_MODERN_CPP_ERROR_CODE(MISMATCH,mismatch,)
2175
SQLITE_MODERN_CPP_ERROR_CODE(MISUSE,misuse,)
2276
SQLITE_MODERN_CPP_ERROR_CODE(NOLFS,nolfs,)
23-
SQLITE_MODERN_CPP_ERROR_CODE(AUTH,auth,)
77+
SQLITE_MODERN_CPP_ERROR_CODE(AUTH,auth,
78+
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(AUTH,USER,auth,user)
79+
)
2480
SQLITE_MODERN_CPP_ERROR_CODE(FORMAT,format,)
2581
SQLITE_MODERN_CPP_ERROR_CODE(RANGE,range,)
2682
SQLITE_MODERN_CPP_ERROR_CODE(NOTADB,notadb,)
83+
SQLITE_MODERN_CPP_ERROR_CODE(NOTICE,notice,
84+
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(NOTICE,RECOVER_WAL,notice,recover_wal)
85+
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(NOTICE,RECOVER_ROLLBACK,notice,recover_rollback)
86+
)
87+
SQLITE_MODERN_CPP_ERROR_CODE(WARNING,warning,
88+
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(WARNING,AUTOINDEX,warning,autoindex)
89+
)

tests/exceptions.cc

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ int main() {
1717
db << "INSERT INTO person (id,name) VALUES (?,?)" << 1 << "jack";
1818
// inserting again to produce error
1919
db << "INSERT INTO person (id,name) VALUES (?,?)" << 1 << "jack";
20-
} catch (sqlite_exception& e) {
21-
cerr << e.get_code() << ": " << e.what() << " during "
20+
} catch (exceptions::constraint_primarykey& e) {
21+
cerr << e.get_code() << '/' << e.get_extended_code() << ": " << e.what() << " during "
2222
<< quoted(e.get_sql()) << endl;
2323
expception_thrown = true;
2424
#if SQLITE_VERSION_NUMBER >= 3014000
@@ -29,9 +29,6 @@ int main() {
2929
cerr << "Wrong statement failed\n";
3030
exit(EXIT_FAILURE);
3131
}
32-
} catch (...) {
33-
cerr << "Ok, we have our excpetion thrown" << endl;
34-
expception_thrown = true;
3532
}
3633

3734
if(!expception_thrown) {

0 commit comments

Comments
 (0)