#pragma once #include #include #include namespace sqlite { class sqlite_exception : public std::runtime_error { public: sqlite_exception(const char *msg, std::string sql, int code = -1) : runtime_error(msg), code(code), sql(sql) { } sqlite_exception(int code, std::string sql) : runtime_error(sqlite3_errstr(code)), code(code), sql(sql) { } int get_code() const { return code & 0xFF; } int get_extended_code() const { return code; } std::string get_sql() const { return sql; } private: int code; std::string sql; }; namespace errors { // One more or less trivial derived error class for each SQLITE error. // Note the following are not errors so have no classes: // SQLITE_OK, SQLITE_NOTICE, SQLITE_WARNING, SQLITE_ROW, SQLITE_DONE // // Note these names are exact matches to the names of the SQLITE error codes. #define SQLITE_MODERN_CPP_ERROR_CODE(NAME, name, derived) \ class name : public sqlite_exception \ { \ using sqlite_exception::sqlite_exception; \ }; \ derived #define SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(BASE, SUB, base, sub) \ class base##_##sub : public base \ { \ using base::base; \ }; #include "lists/error_codes.h" #undef SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED #undef SQLITE_MODERN_CPP_ERROR_CODE // Some additional errors are here for the C++ interface class more_rows : public sqlite_exception { using sqlite_exception::sqlite_exception; }; class no_rows : public sqlite_exception { using sqlite_exception::sqlite_exception; }; class more_statements : public sqlite_exception { using sqlite_exception::sqlite_exception; }; // Prepared statements can only contain one statement class invalid_utf16 : public sqlite_exception { using sqlite_exception::sqlite_exception; }; static void throw_sqlite_error(const int &error_code, const std::string &sql = "") { switch(error_code & 0xFF) { #define SQLITE_MODERN_CPP_ERROR_CODE(NAME, name, derived) \ case SQLITE_##NAME: \ switch(error_code) \ { \ derived default : throw name(error_code, sql); \ } #define SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(BASE, SUB, base, sub) \ case SQLITE_##BASE##_##SUB: \ throw base##_##sub(error_code, sql); #include "lists/error_codes.h" #undef SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED #undef SQLITE_MODERN_CPP_ERROR_CODE default: throw sqlite_exception(error_code, sql); } } } // namespace errors namespace exceptions = errors; } // namespace sqlite